Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Index correct ghost content when deleting the locale of an article #652

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Document/Index/ArticleIndexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use ONGR\ElasticsearchBundle\Collection\Collection;
use ONGR\ElasticsearchBundle\Service\Manager;
use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery;
use ONGR\ElasticsearchDSL\Query\MatchAllQuery;
use ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery;
use Sulu\Bundle\ArticleBundle\Document\ArticleDocument;
Expand Down Expand Up @@ -453,6 +454,17 @@ public function replaceWithGhostData(ArticleDocument $document, string $locale):
$article = $this->createOrUpdateArticle($document, $locale);
$article->setLocalizationState(new LocalizationStateViewObject(LocalizationState::GHOST, $document->getOriginalLocale()));

$repository = $this->manager->getRepository($this->documentFactory->getClass('article'));
$search = $repository->createSearch();
$search->addQuery(new TermQuery('localization_state.state', 'ghost'), BoolQuery::MUST);
$search->addQuery(new TermQuery('localization_state.locale', $locale), BoolQuery::MUST);

/** @var array<array{locale: string}> $searchResult */
$searchResult = $repository->findArray($search);
foreach ($searchResult as $result) {
$this->replaceWithGhostData($document, $result['locale']);
}

$this->manager->persist($article);
}

Expand Down
11 changes: 11 additions & 0 deletions Document/Subscriber/ArticleSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,17 @@ public function handleRemoveLocale(RemoveLocaleEvent $event)
return;
}

$concreteLocales = $this->documentInspector->getConcreteLocales($document);
$ghostLocale = $document->getOriginalLocale();
if (!\in_array($ghostLocale, $concreteLocales, true)) {
$ghostLocale = $concreteLocales[0] ?? null;
}

if (null !== $ghostLocale) {
/** @var ArticleDocument $document */
$document = $this->documentManager->find($document->getUuid(), $ghostLocale);
}

$this->indexer->replaceWithGhostData($document, $event->getLocale());
$this->indexer->flush();
}
Expand Down
2 changes: 1 addition & 1 deletion Tests/Application/.env
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
APP_ENV=test
DATABASE_URL=mysql://root:@127.0.0.1:3306/su_article_test?serverVersion=5.7
DATABASE_URL=mysql://root:ChangeMe@127.0.0.1:3306/sulu_test?serverVersion=5.7
DATABASE_CHARSET=utf8mb4
DATABASE_COLLATE=utf8mb4_unicode_ci
ELASTICSEARCH_HOST=127.0.0.1:9200
166 changes: 115 additions & 51 deletions Tests/Functional/Document/Index/ArticleIndexerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Sulu\Bundle\PageBundle\Document\PageDocument;
use Sulu\Bundle\RouteBundle\Entity\RouteRepositoryInterface;
use Sulu\Bundle\TestBundle\Testing\SuluTestCase;
use Sulu\Component\Content\Document\LocalizationState;
use Sulu\Component\DocumentManager\DocumentManagerInterface;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;

Expand All @@ -35,11 +36,21 @@ class ArticleIndexerTest extends SuluTestCase
*/
private $documentManager;

/**
* @var Manager
*/
private $liveManager;

/**
* @var Manager
*/
private $manager;

/**
* @var ArticleIndexer
*/
private $liveIndexer;

/**
* @var ArticleIndexer
*/
Expand All @@ -58,9 +69,12 @@ public function setUp(): void
$this->initPhpcr();
$this->purgeDatabase();

$this->manager = $this->getContainer()->get('es.manager.live');
$this->liveManager = $this->getContainer()->get('es.manager.live');
$this->manager = $this->getContainer()->get('es.manager.default');
$this->documentManager = $this->getContainer()->get('sulu_document_manager.document_manager');
$this->indexer = $this->getContainer()->get('sulu_article.elastic_search.article_live_indexer');
$this->liveIndexer = $this->getContainer()->get('sulu_article.elastic_search.article_live_indexer');
$this->liveIndexer->clear();
$this->indexer = $this->getContainer()->get('sulu_article.elastic_search.article_indexer');
$this->indexer->clear();
}

Expand Down Expand Up @@ -90,14 +104,14 @@ public function testRemove()

/** @var ArticleDocument $articleDocument */
$articleDocument = $this->documentManager->find($article['id']);
$this->indexer->remove($articleDocument);
$this->indexer->flush();
$this->liveIndexer->remove($articleDocument);
$this->liveIndexer->flush();

self::assertNull($this->findViewDocument($articleDocument->getUuid(), 'de'));
self::assertNull($this->findViewDocument($articleDocument->getUuid(), 'en'));
self::assertNull($this->findLiveViewDocument($articleDocument->getUuid(), 'de'));
self::assertNull($this->findLiveViewDocument($articleDocument->getUuid(), 'en'));
}

public function testRemoveLocale()
public function testReplaceWithGhostData()
{
$article = $this->createArticle(
[
Expand All @@ -123,29 +137,32 @@ public function testRemoveLocale()

/** @var ArticleDocument $articleDocument */
$articleDocument = $this->documentManager->find($article['id']);
$this->indexer->remove($articleDocument, 'en');
$this->indexer->replaceWithGhostData($articleDocument, 'de');
$this->indexer->flush();

self::assertNotNull($this->findViewDocument($articleDocument->getUuid(), 'de'));
self::assertNull($this->findViewDocument($articleDocument->getUuid(), 'en'));
$documentDE = $this->findViewDocument($articleDocument->getUuid(), 'de');
$documentEN = $this->findViewDocument($articleDocument->getUuid(), 'en');

$this->assertSame('Test Article', $documentDE->getTitle());
$this->assertSame('ghost', $documentDE->getLocalizationState()->state);
$this->assertSame('en', $documentDE->getLocalizationState()->locale);

$this->assertSame('Test Article', $documentEN->getTitle());
}

public function testReplaceWithGhostData()
public function testReplaceWithGhostDataUpdateExistingGhosts()
{
$article = $this->createArticle(
[
'article' => 'Test content',
],
'Test Article',
'Test Article English',
'default_with_route'
);

$secondLocale = 'de';

// now add second locale
$this->updateArticle(
$article['id'],
$secondLocale,
'de',
[
'id' => $article['id'],
'article' => 'Test Inhalt',
Expand All @@ -154,19 +171,50 @@ public function testReplaceWithGhostData()
'default_with_route'
);

$this->updateArticle(
$article['id'],
'fr',
[
'id' => $article['id'],
'article' => 'Test Inhalt',
],
'Test Artikel French',
'default_with_route'
);

$documentEN = $this->findViewDocument($article['id'], 'en');
$this->assertSame(LocalizationState::LOCALIZED, $documentEN->getLocalizationState()->state);
$documentDE = $this->findViewDocument($article['id'], 'de');
$this->assertSame(LocalizationState::LOCALIZED, $documentDE->getLocalizationState()->state);
$documentFR = $this->findViewDocument($article['id'], 'fr');
$this->assertSame(LocalizationState::LOCALIZED, $documentFR->getLocalizationState()->state);

/** @var ArticleDocument $articleDocument */
$articleDocument = $this->documentManager->find($article['id']);
$this->indexer->replaceWithGhostData($articleDocument, 'de');
$articleDocument = $this->documentManager->find($article['id'], 'en');
$this->indexer->replaceWithGhostData($articleDocument, 'fr');
$this->indexer->flush();

$documentDE = $this->findViewDocument($articleDocument->getUuid(), 'de');
$documentEN = $this->findViewDocument($articleDocument->getUuid(), 'en');
$documentEN = $this->findViewDocument($article['id'], 'en');
$this->assertSame(LocalizationState::LOCALIZED, $documentEN->getLocalizationState()->state);
$documentDE = $this->findViewDocument($article['id'], 'de');
$this->assertSame(LocalizationState::LOCALIZED, $documentDE->getLocalizationState()->state);
$documentFR = $this->findViewDocument($article['id'], 'fr');
$this->assertSame(LocalizationState::GHOST, $documentFR->getLocalizationState()->state);
$this->assertSame('en', $documentFR->getLocalizationState()->locale);

$this->assertSame('Test Article', $documentDE->getTitle());
$this->assertSame('ghost', $documentDE->getLocalizationState()->state);
$this->assertSame('en', $documentDE->getLocalizationState()->locale);
/** @var ArticleDocument $articleDocument */
$articleDocument = $this->documentManager->find($article['id'], 'de');
$this->indexer->replaceWithGhostData($articleDocument, 'en');
$this->indexer->flush();

$this->assertSame('Test Article', $documentEN->getTitle());
$documentEN = $this->findViewDocument($article['id'], 'en');
$this->assertSame(LocalizationState::GHOST, $documentEN->getLocalizationState()->state);
$this->assertSame('de', $documentEN->getLocalizationState()->locale);
$documentDE = $this->findViewDocument($article['id'], 'de');
$this->assertSame(LocalizationState::LOCALIZED, $documentDE->getLocalizationState()->state);
$documentFR = $this->findViewDocument($article['id'], 'fr');
$this->assertSame(LocalizationState::GHOST, $documentFR->getLocalizationState()->state);
$this->assertSame('de', $documentFR->getLocalizationState()->locale);
}

public function testIndexDefaultWithRoute()
Expand All @@ -179,12 +227,12 @@ public function testIndexDefaultWithRoute()
'default_with_route'
);

$this->indexer = $this->getContainer()->get('sulu_article.elastic_search.article_live_indexer');
$this->liveIndexer = $this->getContainer()->get('sulu_article.elastic_search.article_live_indexer');

$document = $this->documentManager->find($article['id'], $this->locale);
$this->indexer->index($document);
$this->liveIndexer->index($document);

$viewDocument = $this->findViewDocument($article['id']);
$viewDocument = $this->findLiveViewDocument($article['id']);
$this->assertEquals($document->getUuid(), $viewDocument->getUuid());
$this->assertEquals('/articles/test-article', $viewDocument->getRoutePath());
$this->assertInstanceOf('\DateTime', $viewDocument->getPublished());
Expand Down Expand Up @@ -230,7 +278,7 @@ public function testIndexShadow()
null
);

$viewDocument = $this->findViewDocument($article['id'], $secondLocale);
$viewDocument = $this->findLiveViewDocument($article['id'], $secondLocale);

$this->assertEquals($article['id'], $viewDocument->getUuid());
$this->assertEquals('/articles/test-artikel-deutsch', $viewDocument->getRoutePath());
Expand All @@ -257,7 +305,7 @@ public function testIndexShadow()
'default_with_route'
);

$viewDocument = $this->findViewDocument($article['id'], $secondLocale);
$viewDocument = $this->findLiveViewDocument($article['id'], $secondLocale);
$this->assertEquals('Test Article - CHANGED!', $viewDocument->getTitle());

$contentData = \json_decode($viewDocument->getContentData(), true);
Expand Down Expand Up @@ -320,17 +368,17 @@ public function testUnpublishedShadows(): void
null
);

self::assertNotNull($this->findViewDocument($article['id'], $this->locale));
self::assertNotNull($this->findViewDocument($article['id'], $secondLocale));
self::assertNotNull($this->findViewDocument($article['id'], $thirdLocale));
self::assertNotNull($this->findLiveViewDocument($article['id'], $this->locale));
self::assertNotNull($this->findLiveViewDocument($article['id'], $secondLocale));
self::assertNotNull($this->findLiveViewDocument($article['id'], $thirdLocale));

$this->unpublishArticle($article['id'], $this->locale);
$this->unpublishArticle($article['id'], $secondLocale);
$this->unpublishArticle($article['id'], $thirdLocale);

self::assertNull($this->findViewDocument($article['id'], $this->locale));
self::assertNull($this->findViewDocument($article['id'], $secondLocale));
self::assertNull($this->findViewDocument($article['id'], $thirdLocale));
self::assertNull($this->findLiveViewDocument($article['id'], $this->locale));
self::assertNull($this->findLiveViewDocument($article['id'], $secondLocale));
self::assertNull($this->findLiveViewDocument($article['id'], $thirdLocale));

// publish the shadow
$this->updateArticle(
Expand All @@ -344,9 +392,9 @@ public function testUnpublishedShadows(): void
);

// only the DE shadow should be published
self::assertNull($this->findViewDocument($article['id'], $this->locale));
self::assertNotNull($this->findViewDocument($article['id'], $secondLocale));
self::assertNull($this->findViewDocument($article['id'], $thirdLocale));
self::assertNull($this->findLiveViewDocument($article['id'], $this->locale));
self::assertNotNull($this->findLiveViewDocument($article['id'], $secondLocale));
self::assertNull($this->findLiveViewDocument($article['id'], $thirdLocale));
}

public function testIndexPageTreeRoute()
Expand All @@ -364,17 +412,17 @@ public function testIndexPageTreeRoute()
);

$document = $this->documentManager->find($article['id'], $this->locale);
$this->indexer->index($document);
$this->liveIndexer->index($document);

$viewDocument = $this->findViewDocument($article['id']);
$viewDocument = $this->findLiveViewDocument($article['id']);
$this->assertEquals($page->getUuid(), $viewDocument->getParentPageUuid());
}

public function testSetUnpublished()
{
$article = $this->createArticle();

$viewDocument = $this->indexer->setUnpublished($article['id'], $this->locale);
$viewDocument = $this->liveIndexer->setUnpublished($article['id'], $this->locale);
$this->assertNull($viewDocument->getPublished());
$this->assertFalse($viewDocument->getPublishedState());
}
Expand Down Expand Up @@ -411,10 +459,10 @@ public function testIndexTaggedProperties()
$this->documentManager->clear();

$document = $this->documentManager->find($article['id'], $this->locale);
$this->indexer->index($document);
$this->indexer->flush();
$this->liveIndexer->index($document);
$this->liveIndexer->flush();

$viewDocument = $this->findViewDocument($article['id']);
$viewDocument = $this->findLiveViewDocument($article['id']);
$contentFields = $viewDocument->getContentFields();

$this->assertSame($article['id'], $viewDocument->getUuid());
Expand Down Expand Up @@ -496,10 +544,10 @@ public function testIndexTaggedPropertiesBlocksInBlocks(): void
$this->documentManager->clear();

$document = $this->documentManager->find($article['id'], $this->locale);
$this->indexer->index($document);
$this->indexer->flush();
$this->liveIndexer->index($document);
$this->liveIndexer->flush();

$viewDocument = $this->findViewDocument($article['id']);
$viewDocument = $this->findLiveViewDocument($article['id']);
$contentFields = $viewDocument->getContentFields();

$this->assertEquals($article['id'], $viewDocument->getUuid());
Expand Down Expand Up @@ -532,10 +580,10 @@ public function testIndexContentData()
$this->documentManager->clear();

$document = $this->documentManager->find($article['id'], $this->locale);
$this->indexer->index($document);
$this->indexer->flush();
$this->liveIndexer->index($document);
$this->liveIndexer->flush();

$viewDocument = $this->findViewDocument($article['id']);
$viewDocument = $this->findLiveViewDocument($article['id']);
$this->assertEquals($article['id'], $viewDocument->getUuid());
$this->assertEquals($data, \json_decode($viewDocument->getContentData(), true));

Expand Down Expand Up @@ -694,7 +742,23 @@ private function createPage($title = 'Test Page', $resourceSegment = '/test-page
}

/**
* Find view-document.
* Find view-document in live index.
*
* @param string $uuid
* @param string $locale
*
* @return ArticleViewDocument
*/
private function findLiveViewDocument($uuid, $locale = null)
{
return $this->liveManager->find(
$this->getContainer()->getParameter('sulu_article.view_document.article.class'),
$uuid . '-' . ($locale ? $locale : $this->locale)
);
}

/**
* Find view-document in live index.
*
* @param string $uuid
* @param string $locale
Expand Down
Loading
Loading