From c2ccf4d15a69e61782795450ea2d226738da7768 Mon Sep 17 00:00:00 2001 From: Marijan Klaric Date: Tue, 23 Jul 2024 13:50:57 +0200 Subject: [PATCH] NGSTACK-811 assing tag to content in batches --- bundle/Command/TagContentByTypesCommand.php | 88 ++++++++++++--------- 1 file changed, 51 insertions(+), 37 deletions(-) diff --git a/bundle/Command/TagContentByTypesCommand.php b/bundle/Command/TagContentByTypesCommand.php index f72dc0be..882f8bad 100644 --- a/bundle/Command/TagContentByTypesCommand.php +++ b/bundle/Command/TagContentByTypesCommand.php @@ -64,59 +64,73 @@ protected function execute(InputInterface $input, OutputInterface $output): int new Criterion\ContentTypeIdentifier($this->getContentTypes()), ]); - $searchResults = $this->repository->getSearchService()->findContent($query); - $totalCount = $searchResults->totalCount; + $batchSize = 50; - if ($this->input->getOption('field-identifiers') === null) { - $fieldIdentifiers = $this->configResolver->getParameter('tag_command_default_field_identifiers', 'ngsite'); - } else { - $fieldIdentifiers = $this->getFieldIdentifiers(); - } + $searchResults = $this->repository->getSearchService()->findContent($query); + $totalResults = $searchResults->totalCount; $this->style->newLine(); - $this->style->progressStart($totalCount); + $this->style->progressStart($totalResults); - foreach ($searchResults->searchHits as $searchHit) { - $result = $this->repository->sudo( - function () use ($searchHit, $fieldIdentifiers): ?int { - /** @var \Ibexa\Contracts\Core\Repository\Values\Content\Content $content */ - $content = $searchHit->valueObject; + $this->repository->beginTransaction(); - $contentDraft = $this->repository->getContentService()->createContentDraft($content->contentInfo); - $contentUpdateStruct = $this->repository->getContentService()->newContentUpdateStruct(); + for ($offset = 0; $offset < $totalResults; $offset += $batchSize) { + $query->offset = $offset; + $query->limit = $batchSize; + $searchResults = $this->repository->getSearchService()->findContent($query); - foreach ($fieldIdentifiers as $fieldIdentifier) { - if (!$this->hasField($content, $fieldIdentifier)) { - continue; - } + if ($this->input->getOption('field-identifiers') === null) { + $fieldIdentifiers = $this->configResolver->getParameter('tag_command_default_field_identifiers', 'ngsite'); + } else { + $fieldIdentifiers = $this->getFieldIdentifiers(); + } - if (!$content->getField($fieldIdentifier)->value instanceof TagFieldValue) { - $this->style->error(sprintf('Field with identifier %s must be a type of eztags', $fieldIdentifier)); - return Command::FAILURE; - } + $this->repository->beginTransaction(); - $alreadyAssignedTags = $content->getFieldValue($fieldIdentifier)->tags; - $tagsToAssign = array_filter($alreadyAssignedTags, fn ($alreadyAssignedTag) => $this->getTag()->id !== $alreadyAssignedTag->id); - $tagsToAssign[] = $this->getTag(); - $contentUpdateStruct->setField($fieldIdentifier, new TagFieldValue($tagsToAssign)); + foreach ($searchResults->searchHits as $searchHit) { + $result = $this->repository->sudo( + function () use ($searchHit, $fieldIdentifiers): ?int { + /** @var \Ibexa\Contracts\Core\Repository\Values\Content\Content $content */ + $content = $searchHit->valueObject; - break; - } + $contentDraft = $this->repository->getContentService()->createContentDraft($content->contentInfo); + $contentUpdateStruct = $this->repository->getContentService()->newContentUpdateStruct(); - $this->repository->getContentService()->updateContent($contentDraft->versionInfo, $contentUpdateStruct); - $this->repository->getContentService()->publishVersion($contentDraft->versionInfo); + foreach ($fieldIdentifiers as $fieldIdentifier) { + if (!$this->hasField($content, $fieldIdentifier)) { + continue; + } - $this->style->progressAdvance(); + if (!$content->getField($fieldIdentifier)->value instanceof TagFieldValue) { + $this->style->error(sprintf('Field with identifier %s must be a type of eztags', $fieldIdentifier)); + return Command::FAILURE; + } - return null; - } - ); + $alreadyAssignedTags = $content->getFieldValue($fieldIdentifier)->tags; + $tagsToAssign = array_filter($alreadyAssignedTags, fn ($alreadyAssignedTag) => $this->getTag()->id !== $alreadyAssignedTag->id); + $tagsToAssign[] = $this->getTag(); + $contentUpdateStruct->setField($fieldIdentifier, new TagFieldValue($tagsToAssign)); - if ($result === Command::FAILURE) { - return Command::FAILURE; + break; + } + + $this->repository->getContentService()->updateContent($contentDraft->versionInfo, $contentUpdateStruct); + $this->repository->getContentService()->publishVersion($contentDraft->versionInfo); + + $this->style->progressAdvance(); + + return null; + } + ); + + if ($result === Command::FAILURE) { + return Command::FAILURE; + } } } + $this->repository->commit(); + $this->style->progressFinish(); $this->style->success('Tags assigned successfully');