diff --git a/src/Console/AppInstallCommand.php b/src/Console/AppInstallCommand.php index 859a6e16..06599c29 100644 --- a/src/Console/AppInstallCommand.php +++ b/src/Console/AppInstallCommand.php @@ -82,39 +82,40 @@ protected function importAppData(string $themeConfigPath): void { $data = $this->getAppConfig($themeConfigPath); - if (isset($data["importFiles"])) { - if (isset($data["importFiles"]['groups'])) { - foreach ($data["importFiles"]['groups'] as $filename) { - $this->importFile($filename, $this->groupsImporter); - } + if (!isset($data["importFiles"]) || !is_array($data["importFiles"])) { + $this->io->warning('Config file "' . $themeConfigPath . '" has no data to import.'); + return; + } + + if (isset($data["importFiles"]['groups'])) { + foreach ($data["importFiles"]['groups'] as $filename) { + $this->importFile($filename, $this->groupsImporter); } - if (isset($data["importFiles"]['roles'])) { - foreach ($data["importFiles"]['roles'] as $filename) { - $this->importFile($filename, $this->rolesImporter); - } + } + if (isset($data["importFiles"]['roles'])) { + foreach ($data["importFiles"]['roles'] as $filename) { + $this->importFile($filename, $this->rolesImporter); } - if (isset($data["importFiles"]['settings'])) { - foreach ($data["importFiles"]['settings'] as $filename) { - $this->importFile($filename, $this->settingsImporter); - } + } + if (isset($data["importFiles"]['settings'])) { + foreach ($data["importFiles"]['settings'] as $filename) { + $this->importFile($filename, $this->settingsImporter); } - if (isset($data["importFiles"]['nodetypes'])) { - foreach ($data["importFiles"]['nodetypes'] as $filename) { - $this->importFile($filename, $this->nodeTypesImporter); - } + } + if (isset($data["importFiles"]['nodetypes'])) { + foreach ($data["importFiles"]['nodetypes'] as $filename) { + $this->importFile($filename, $this->nodeTypesImporter); } - if (isset($data["importFiles"]['tags'])) { - foreach ($data["importFiles"]['tags'] as $filename) { - $this->importFile($filename, $this->tagsImporter); - } + } + if (isset($data["importFiles"]['tags'])) { + foreach ($data["importFiles"]['tags'] as $filename) { + $this->importFile($filename, $this->tagsImporter); } - if (isset($data["importFiles"]['attributes'])) { - foreach ($data["importFiles"]['attributes'] as $filename) { - $this->importFile($filename, $this->attributeImporter); - } + } + if (isset($data["importFiles"]['attributes'])) { + foreach ($data["importFiles"]['attributes'] as $filename) { + $this->importFile($filename, $this->attributeImporter); } - } else { - $this->io->warning('Config file "' . $themeConfigPath . '" has no data to import.'); } } @@ -129,24 +130,30 @@ protected function importFile(string $filename, EntityImporterInterface $importe } else { throw new \RuntimeException($filename . ' is not a valid file'); } - if (!$this->dryRun) { - try { - if (false === $fileContent = file_get_contents($file->getPathname())) { - throw new \RuntimeException($file->getPathname() . ' file is not readable'); - } - $importer->import($fileContent); - $this->managerRegistry->getManager()->flush(); - $this->io->writeln( - '* ' . $file->getPathname() . ' file has been imported.' - ); - return; - } catch (EntityAlreadyExistsException $e) { - $this->io->writeln( - '* ' . $file->getPathname() . '' . - ' has NOT been imported (' . $e->getMessage() . ').' - ); + if ($this->dryRun) { + $this->io->writeln( + '* ' . $file->getPathname() . ' file would be imported.' + ); + return; + } + + try { + if (false === $fileContent = file_get_contents($file->getPathname())) { + throw new \RuntimeException($file->getPathname() . ' file is not readable'); } + $importer->import($fileContent); + $this->managerRegistry->getManager()->flush(); + $this->io->writeln( + '* ' . $file->getPathname() . ' file has been imported.' + ); + return; + } catch (EntityAlreadyExistsException $e) { + $this->io->writeln( + '* ' . $file->getPathname() . '' . + ' has NOT been imported (' . $e->getMessage() . ').' + ); } + $this->io->writeln( '* ' . $file->getPathname() . ' file has been imported.' ); diff --git a/src/Console/CustomFormAnswerPurgeCommand.php b/src/Console/CustomFormAnswerPurgeCommand.php index 07270a01..186cb33f 100644 --- a/src/Console/CustomFormAnswerPurgeCommand.php +++ b/src/Console/CustomFormAnswerPurgeCommand.php @@ -44,74 +44,85 @@ protected function execute(InputInterface $input, OutputInterface $output): int ->findAllWithRetentionTime(); foreach ($customForms as $customForm) { - if (null !== $interval = $customForm->getRetentionTimeInterval()) { - $purgeBefore = (new \DateTime())->sub($interval); - $customFormAnswers = $this->managerRegistry - ->getRepository(CustomFormAnswer::class) - ->findByCustomFormSubmittedBefore($customForm, $purgeBefore); - $count = count($customFormAnswers); - - $documents = $this->managerRegistry - ->getRepository(Document::class) - ->findByCustomFormSubmittedBefore($customForm, $purgeBefore); - $documentsCount = count($documents); + $this->purgeCustomFormAnswers($customForm, $input, $output); + } - if ($output->isVeryVerbose()) { - $io->info(\sprintf( - 'Checking if “%s” custom-form has answers before %s', - $customForm->getName(), - $purgeBefore->format('Y-m-d H:i') - )); - } + return 0; + } + + protected function purgeCustomFormAnswers(CustomForm $customForm, InputInterface $input, OutputInterface $output): void + { + $io = new SymfonyStyle($input, $output); + + if (null === $interval = $customForm->getRetentionTimeInterval()) { + return; + } - if ($count > 0) { + $purgeBefore = (new \DateTime())->sub($interval); + $customFormAnswers = $this->managerRegistry + ->getRepository(CustomFormAnswer::class) + ->findByCustomFormSubmittedBefore($customForm, $purgeBefore); + $count = count($customFormAnswers); + + $documents = $this->managerRegistry + ->getRepository(Document::class) + ->findByCustomFormSubmittedBefore($customForm, $purgeBefore); + $documentsCount = count($documents); + + if ($output->isVeryVerbose()) { + $io->info(\sprintf( + 'Checking if “%s” custom-form has answers before %s', + $customForm->getName(), + $purgeBefore->format('Y-m-d H:i') + )); + } + + if ($count <= 0) { + return; + } + + $io->info(\sprintf( + 'Purge %d custom-form answer(s) with %d documents(s) from “%s” before %s', + $count, + $documentsCount, + $customForm->getName(), + $purgeBefore->format('Y-m-d H:i') + )); + + if ( + !$input->getOption('dry-run') && + (!$input->isInteractive() || $io->confirm(\sprintf( + 'Are you sure you want to delete %d custom-form answer(s) and %d document(s) from “%s” before %s', + $count, + $documentsCount, + $customForm->getName(), + $purgeBefore->format('Y-m-d H:i') + ), false)) + ) { + $this->managerRegistry + ->getRepository(CustomFormAnswer::class) + ->deleteByCustomFormSubmittedBefore($customForm, $purgeBefore); + + foreach ($documents as $document) { + $this->eventDispatcher->dispatch( + new DocumentDeletedEvent($document) + ); + if ($output->isVeryVerbose()) { $io->info(\sprintf( - 'Purge %d custom-form answer(s) with %d documents(s) from “%s” before %s', - $count, - $documentsCount, - $customForm->getName(), - $purgeBefore->format('Y-m-d H:i') + '“%s” document has been deleted', + $document->getRelativePath() )); - - if ( - !$input->getOption('dry-run') && - (!$input->isInteractive() || $io->confirm(\sprintf( - 'Are you sure you want to delete %d custom-form answer(s) and %d document(s) from “%s” before %s', - $count, - $documentsCount, - $customForm->getName(), - $purgeBefore->format('Y-m-d H:i') - ), false)) - ) { - $this->managerRegistry - ->getRepository(CustomFormAnswer::class) - ->deleteByCustomFormSubmittedBefore($customForm, $purgeBefore); - - foreach ($documents as $document) { - $this->eventDispatcher->dispatch( - new DocumentDeletedEvent($document) - ); - if ($output->isVeryVerbose()) { - $io->info(\sprintf( - '“%s” document has been deleted', - $document->getRelativePath() - )); - } - $this->managerRegistry->getManager()->remove($document); - } - $this->managerRegistry->getManager()->flush(); - $this->logger->info(\sprintf( - '%d answer(s) and %d document(s) were deleted from “%s” custom-form before %s', - $count, - $documentsCount, - $customForm->getName(), - $purgeBefore->format('Y-m-d H:i') - )); - } } + $this->managerRegistry->getManager()->remove($document); } + $this->managerRegistry->getManager()->flush(); + $this->logger->info(\sprintf( + '%d answer(s) and %d document(s) were deleted from “%s” custom-form before %s', + $count, + $documentsCount, + $customForm->getName(), + $purgeBefore->format('Y-m-d H:i') + )); } - - return 0; } } diff --git a/src/Console/FilesExportCommand.php b/src/Console/FilesExportCommand.php index adf93e2d..db8d1d3e 100644 --- a/src/Console/FilesExportCommand.php +++ b/src/Console/FilesExportCommand.php @@ -100,14 +100,15 @@ protected function zipFolder(ZipArchive $zip, string $folder, string $prefix = " */ foreach ($files as $file) { // Skip directories (they would be added automatically) - if (!$file->isDir()) { - // Get real and relative path for current file - $filePath = $file->getRealPath(); - $relativePath = \mb_substr($filePath, \mb_strlen($folder) + 1); - - // Add current file to archive - $zip->addFile($filePath, $prefix . '/' . $relativePath); + if ($file->isDir()) { + continue; } + // Get real and relative path for current file + $filePath = $file->getRealPath(); + $relativePath = \mb_substr($filePath, \mb_strlen($folder) + 1); + + // Add current file to archive + $zip->addFile($filePath, $prefix . '/' . $relativePath); } } } diff --git a/src/Console/FilesImportCommand.php b/src/Console/FilesImportCommand.php index 4b910575..4e92136c 100644 --- a/src/Console/FilesImportCommand.php +++ b/src/Console/FilesImportCommand.php @@ -63,34 +63,32 @@ protected function execute(InputInterface $input, OutputInterface $output): int $zipArchivePath = $input->getArgument('input'); $zip = new ZipArchive(); - if (true === $zip->open($zipArchivePath)) { - if ( - $io->askQuestion( - $confirmation - ) - ) { - $zip->extractTo($tempDir); - - $fs = new Filesystem(); - if ($fs->exists($tempDir . $this->getPublicFolderName())) { - $fs->mirror($tempDir . $this->getPublicFolderName(), $this->fileAware->getPublicFilesPath()); - $io->success('Public files have been imported.'); - } - if ($fs->exists($tempDir . $this->getPrivateFolderName())) { - $fs->mirror($tempDir . $this->getPrivateFolderName(), $this->fileAware->getPrivateFilesPath()); - $io->success('Private files have been imported.'); - } - if ($fs->exists($tempDir . $this->getFontsFolderName())) { - $fs->mirror($tempDir . $this->getFontsFolderName(), $this->fileAware->getFontsFilesPath()); - $io->success('Font files have been imported.'); - } - - $fs->remove($tempDir); - } - return 0; - } else { + if (true !== $zip->open($zipArchivePath)) { $io->error('Zip archive does not exist or is invalid.'); return 1; } + + if (!$io->askQuestion($confirmation)) { + return 0; + } + + $zip->extractTo($tempDir); + + $fs = new Filesystem(); + if ($fs->exists($tempDir . $this->getPublicFolderName())) { + $fs->mirror($tempDir . $this->getPublicFolderName(), $this->fileAware->getPublicFilesPath()); + $io->success('Public files have been imported.'); + } + if ($fs->exists($tempDir . $this->getPrivateFolderName())) { + $fs->mirror($tempDir . $this->getPrivateFolderName(), $this->fileAware->getPrivateFilesPath()); + $io->success('Private files have been imported.'); + } + if ($fs->exists($tempDir . $this->getFontsFolderName())) { + $fs->mirror($tempDir . $this->getFontsFolderName(), $this->fileAware->getFontsFilesPath()); + $io->success('Font files have been imported.'); + } + + $fs->remove($tempDir); + return 0; } } diff --git a/src/Console/GenerateApiResourceCommand.php b/src/Console/GenerateApiResourceCommand.php index 87ae30e3..f9e78104 100644 --- a/src/Console/GenerateApiResourceCommand.php +++ b/src/Console/GenerateApiResourceCommand.php @@ -38,17 +38,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int ->getRepository(NodeType::class) ->findAll(); - if (count($nodeTypes) > 0) { - foreach ($nodeTypes as $nt) { - $resourcePath = $this->apiResourceGenerator->generate($nt); - if (null !== $resourcePath) { - $io->writeln("* API resource " . $resourcePath . " has been generated."); - } - } - return 0; - } else { + if (count($nodeTypes) === 0) { $io->error('No available node-types…'); return 1; } + + foreach ($nodeTypes as $nt) { + $resourcePath = $this->apiResourceGenerator->generate($nt); + if (null !== $resourcePath) { + $io->writeln("* API resource " . $resourcePath . " has been generated."); + } + } + return 0; } } diff --git a/src/Console/GenerateNodeSourceEntitiesCommand.php b/src/Console/GenerateNodeSourceEntitiesCommand.php index 04c3b8dc..98e0dcf8 100644 --- a/src/Console/GenerateNodeSourceEntitiesCommand.php +++ b/src/Console/GenerateNodeSourceEntitiesCommand.php @@ -39,27 +39,27 @@ protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); - $nodetypes = $this->managerRegistry + $nodeTypes = $this->managerRegistry ->getRepository(NodeType::class) ->findAll(); - if (count($nodetypes) > 0) { - /** @var NodeType $nt */ - foreach ($nodetypes as $nt) { - /** @var NodeTypeHandler $handler */ - $handler = $this->handlerFactory->getHandler($nt); - $handler->removeSourceEntityClass(); - $handler->generateSourceEntityClass(); - $io->writeln("* Source class " . $nt->getSourceEntityClassName() . " has been generated."); - - if ($output->isVeryVerbose()) { - $io->writeln("\t" . $handler->getSourceClassPath() . ""); - } - } - return 0; - } else { + if (count($nodeTypes) === 0) { $io->error('No available node-types…'); return 1; } + + /** @var NodeType $nt */ + foreach ($nodeTypes as $nt) { + /** @var NodeTypeHandler $handler */ + $handler = $this->handlerFactory->getHandler($nt); + $handler->removeSourceEntityClass(); + $handler->generateSourceEntityClass(); + $io->writeln("* Source class " . $nt->getSourceEntityClassName() . " has been generated."); + + if ($output->isVeryVerbose()) { + $io->writeln("\t" . $handler->getSourceClassPath() . ""); + } + } + return 0; } } diff --git a/src/Console/NodeTypesAddFieldCommand.php b/src/Console/NodeTypesAddFieldCommand.php index e8651e30..554f5e0d 100644 --- a/src/Console/NodeTypesAddFieldCommand.php +++ b/src/Console/NodeTypesAddFieldCommand.php @@ -38,23 +38,23 @@ protected function execute(InputInterface $input, OutputInterface $output): int ->getRepository(NodeType::class) ->findOneBy(['name' => $name]); - if ($nodeType !== null) { - $latestPosition = $this->managerRegistry - ->getRepository(NodeTypeField::class) - ->findLatestPositionInNodeType($nodeType); - $this->addNodeTypeField($nodeType, $latestPosition + 1, $io); - $this->managerRegistry->getManagerForClass(NodeTypeField::class)->flush(); - - /** @var NodeTypeHandler $handler */ - $handler = $this->handlerFactory->getHandler($nodeType); - $handler->regenerateEntityClass(); - $this->schemaUpdater->updateNodeTypesSchema(); - - $io->success('Node type ' . $nodeType->getName() . ' has been updated.'); - return 0; - } else { + if ($nodeType === null) { $io->error('Node-type "' . $name . '" does not exist.'); return 1; } + + $latestPosition = $this->managerRegistry + ->getRepository(NodeTypeField::class) + ->findLatestPositionInNodeType($nodeType); + $this->addNodeTypeField($nodeType, $latestPosition + 1, $io); + $this->managerRegistry->getManagerForClass(NodeTypeField::class)->flush(); + + /** @var NodeTypeHandler $handler */ + $handler = $this->handlerFactory->getHandler($nodeType); + $handler->regenerateEntityClass(); + $this->schemaUpdater->updateNodeTypesSchema(); + + $io->success('Node type ' . $nodeType->getName() . ' has been updated.'); + return 0; } } diff --git a/src/Console/NodeTypesCommand.php b/src/Console/NodeTypesCommand.php index 262bcaa6..6be399c2 100644 --- a/src/Console/NodeTypesCommand.php +++ b/src/Console/NodeTypesCommand.php @@ -43,50 +43,49 @@ protected function execute(InputInterface $input, OutputInterface $output): int ->getRepository(NodeType::class) ->findOneByName($name); - if ($nodetype !== null) { - /** @var array $fields */ - $fields = $this->managerRegistry->getRepository(NodeTypeField::class) - ->findBy([ - 'nodeType' => $nodetype, - ], ['position' => 'ASC']); - - $tableContent = []; - foreach ($fields as $field) { - $tableContent[] = [ - $field->getId(), - $field->getLabel(), - $field->getName(), - str_replace('.type', '', $field->getTypeName()), - ($field->isVisible() ? 'X' : ''), - ($field->isIndexed() ? 'X' : ''), - ]; - } - $io->table(['Id', 'Label', 'Name', 'Type', 'Visible', 'Index'], $tableContent); - } else { + if ($nodetype === null) { $io->note($name . ' node type does not exist.'); return 0; } + /** @var array $fields */ + $fields = $this->managerRegistry->getRepository(NodeTypeField::class) + ->findBy([ + 'nodeType' => $nodetype, + ], ['position' => 'ASC']); + + $tableContent = []; + foreach ($fields as $field) { + $tableContent[] = [ + $field->getId(), + $field->getLabel(), + $field->getName(), + str_replace('.type', '', $field->getTypeName()), + ($field->isVisible() ? 'X' : ''), + ($field->isIndexed() ? 'X' : ''), + ]; + } + $io->table(['Id', 'Label', 'Name', 'Type', 'Visible', 'Index'], $tableContent); } else { /** @var array $nodetypes */ $nodetypes = $this->managerRegistry ->getRepository(NodeType::class) ->findBy([], ['name' => 'ASC']); - if (count($nodetypes) > 0) { - $tableContent = []; + if (count($nodetypes) === 0) { + $io->note('No available node-types…'); + } - foreach ($nodetypes as $nt) { - $tableContent[] = [ - $nt->getId(), - $nt->getName(), - ($nt->isVisible() ? 'X' : ''), - ]; - } + $tableContent = []; - $io->table(['Id', 'Title', 'Visible'], $tableContent); - } else { - $io->note('No available node-types…'); + foreach ($nodetypes as $nt) { + $tableContent[] = [ + $nt->getId(), + $nt->getName(), + ($nt->isVisible() ? 'X' : ''), + ]; } + + $io->table(['Id', 'Title', 'Visible'], $tableContent); } return 0; } diff --git a/src/Console/NodeTypesDeleteCommand.php b/src/Console/NodeTypesDeleteCommand.php index 6e9d47c0..795c829e 100644 --- a/src/Console/NodeTypesDeleteCommand.php +++ b/src/Console/NodeTypesDeleteCommand.php @@ -55,33 +55,33 @@ protected function execute(InputInterface $input, OutputInterface $output): int ->getRepository(NodeType::class) ->findOneByName($name); - if ($nodeType !== null) { - $io->note('///////////////////////////////' . PHP_EOL . - '/////////// WARNING ///////////' . PHP_EOL . - '///////////////////////////////' . PHP_EOL . - 'This operation cannot be undone.' . PHP_EOL . - 'Deleting a node-type, you will automatically delete every nodes of this type.'); - $question = new ConfirmationQuestion( - 'Are you sure to delete ' . $nodeType->getName() . ' node-type?', - false - ); - if ( - $io->askQuestion( - $question - ) - ) { - /** @var NodeTypeHandler $handler */ - $handler = $this->handlerFactory->getHandler($nodeType); - $handler->removeSourceEntityClass(); - $this->managerRegistry->getManagerForClass(NodeType::class)->remove($nodeType); - $this->managerRegistry->getManagerForClass(NodeType::class)->flush(); - $this->schemaUpdater->updateNodeTypesSchema(); - $io->success('Node-type deleted.'); - } - } else { + if ($nodeType === null) { $io->error('"' . $name . '" node type does not exist'); return 1; } + + $io->note('///////////////////////////////' . PHP_EOL . + '/////////// WARNING ///////////' . PHP_EOL . + '///////////////////////////////' . PHP_EOL . + 'This operation cannot be undone.' . PHP_EOL . + 'Deleting a node-type, you will automatically delete every nodes of this type.'); + $question = new ConfirmationQuestion( + 'Are you sure to delete ' . $nodeType->getName() . ' node-type?', + false + ); + if ( + $io->askQuestion( + $question + ) + ) { + /** @var NodeTypeHandler $handler */ + $handler = $this->handlerFactory->getHandler($nodeType); + $handler->removeSourceEntityClass(); + $this->managerRegistry->getManagerForClass(NodeType::class)->remove($nodeType); + $this->managerRegistry->getManagerForClass(NodeType::class)->flush(); + $this->schemaUpdater->updateNodeTypesSchema(); + $io->success('Node-type deleted.'); + } return 0; } } diff --git a/src/Console/NodesCleanNamesCommand.php b/src/Console/NodesCleanNamesCommand.php index 394a55de..4a420a16 100644 --- a/src/Console/NodesCleanNamesCommand.php +++ b/src/Console/NodesCleanNamesCommand.php @@ -71,78 +71,76 @@ protected function execute(InputInterface $input, OutputInterface $output): int $question1 = new ConfirmationQuestion('Are you sure to proceed? This could break many page URLs!', false); - if ($io->askQuestion($question1)) { - $io->note('Renaming ' . count($nodes) . ' nodes…'); - $renameCount = 0; - $names = []; - - /** @var Node $node */ - foreach ($nodes as $node) { - $nodeSource = $node->getNodeSources()->first() ?: null; - if ($nodeSource !== null) { - $prefixName = $nodeSource->getTitle() != "" ? - $nodeSource->getTitle() : - $node->getNodeName(); - - $prefixNameSlug = $this->nodeNamePolicy->getCanonicalNodeName($nodeSource); - /* - * Proceed to rename only if best name is not the current - * node-name AND if it is not ALREADY suffixed with a unique ID. - */ + if (!$io->askQuestion($question1)) { + $io->warning('Renaming cancelled…'); + return 1; + } + + $io->note('Renaming ' . count($nodes) . ' nodes…'); + $renameCount = 0; + $names = []; + + /** @var Node $node */ + foreach ($nodes as $node) { + $nodeSource = $node->getNodeSources()->first() ?: null; + if ($nodeSource === null) { + continue; + } + + $prefixNameSlug = $this->nodeNamePolicy->getCanonicalNodeName($nodeSource); + /* + * Proceed to rename only if best name is not the current + * node-name AND if it is not ALREADY suffixed with a unique ID. + */ + if ( + $prefixNameSlug != $node->getNodeName() && + $this->nodeNamePolicy->isNodeNameValid($prefixNameSlug) && + !$this->nodeNamePolicy->isNodeNameWithUniqId($prefixNameSlug, $nodeSource->getNode()->getNodeName()) + ) { + $alreadyUsed = $this->nodeNamePolicy->isNodeNameAlreadyUsed($prefixNameSlug); + if (!$alreadyUsed) { + $names[] = [ + $node->getNodeName(), + $prefixNameSlug + ]; + $node->setNodeName($prefixNameSlug); + } else { if ( - $prefixNameSlug != $node->getNodeName() && - $this->nodeNamePolicy->isNodeNameValid($prefixNameSlug) && - !$this->nodeNamePolicy->isNodeNameWithUniqId($prefixNameSlug, $nodeSource->getNode()->getNodeName()) + $input->getOption('use-date') && + null !== $nodeSource->getPublishedAt() ) { - $alreadyUsed = $this->nodeNamePolicy->isNodeNameAlreadyUsed($prefixNameSlug); - if (!$alreadyUsed) { - $names[] = [ - $node->getNodeName(), - $prefixNameSlug - ]; - $node->setNodeName($prefixNameSlug); - } else { - if ( - $input->getOption('use-date') && - null !== $nodeSource->getPublishedAt() - ) { - $suffixedNameSlug = $this->nodeNamePolicy->getDatestampedNodeName($nodeSource); - } else { - $suffixedNameSlug = $this->nodeNamePolicy->getSafeNodeName($nodeSource); - } - if (!$this->nodeNamePolicy->isNodeNameAlreadyUsed($suffixedNameSlug)) { - $names[] = [ - $node->getNodeName(), - $suffixedNameSlug - ]; - $node->setNodeName($suffixedNameSlug); - } else { - $suffixedNameSlug = $this->nodeNamePolicy->getSafeNodeName($nodeSource); - $names[] = [ - $node->getNodeName(), - $suffixedNameSlug - ]; - $node->setNodeName($suffixedNameSlug); - } - } - if (!$input->getOption('dry-run')) { - $entityManager->flush(); - } - $renameCount++; + $suffixedNameSlug = $this->nodeNamePolicy->getDatestampedNodeName($nodeSource); + } else { + $suffixedNameSlug = $this->nodeNamePolicy->getSafeNodeName($nodeSource); } + if (!$this->nodeNamePolicy->isNodeNameAlreadyUsed($suffixedNameSlug)) { + $names[] = [ + $node->getNodeName(), + $suffixedNameSlug + ]; + $node->setNodeName($suffixedNameSlug); + } else { + $suffixedNameSlug = $this->nodeNamePolicy->getSafeNodeName($nodeSource); + $names[] = [ + $node->getNodeName(), + $suffixedNameSlug + ]; + $node->setNodeName($suffixedNameSlug); + } + } + if (!$input->getOption('dry-run')) { + $entityManager->flush(); } + $renameCount++; } + } - $io->table(['Old name', 'New name'], $names); + $io->table(['Old name', 'New name'], $names); - if (!$input->getOption('dry-run')) { - $io->success('Renaming done! ' . $renameCount . ' nodes have been affected. Do not forget to reindex your Solr documents if you are using it.'); - } else { - $io->success($renameCount . ' nodes would have been affected. Nothing was saved to database.'); - } + if (!$input->getOption('dry-run')) { + $io->success('Renaming done! ' . $renameCount . ' nodes have been affected. Do not forget to reindex your Solr documents if you are using it.'); } else { - $io->warning('Renaming cancelled…'); - return 1; + $io->success($renameCount . ' nodes would have been affected. Nothing was saved to database.'); } } diff --git a/src/Console/NodesEmptyTrashCommand.php b/src/Console/NodesEmptyTrashCommand.php index 8e21028b..9beea3c6 100644 --- a/src/Console/NodesEmptyTrashCommand.php +++ b/src/Console/NodesEmptyTrashCommand.php @@ -43,45 +43,49 @@ protected function execute(InputInterface $input, OutputInterface $output): int ->andWhere($countQb->expr()->eq('n.status', Node::DELETED)) ->getQuery(); $emptiedCount = $countQuery->getSingleScalarResult(); - if ($emptiedCount > 0) { - $confirmation = new ConfirmationQuestion( - sprintf('Are you sure to empty nodes trashcan, %d nodes will be lost forever? [y/N]: ', $emptiedCount), - false - ); - if ($io->askQuestion($confirmation) || !$input->isInteractive()) { - $i = 0; - $batchSize = 100; - $io->progressStart((int) $emptiedCount); + if ($emptiedCount == 0) { + $io->success('Nodes trashcan is already empty.'); + return 0; + } - $qb = $this->createNodeQueryBuilder(); - $q = $qb->select('n') - ->andWhere($countQb->expr()->eq('n.status', Node::DELETED)) - ->getQuery(); + $confirmation = new ConfirmationQuestion( + sprintf('Are you sure to empty nodes trashcan, %d nodes will be lost forever? [y/N]: ', $emptiedCount), + false + ); - foreach ($q->toIterable() as $row) { - /** @var NodeHandler $nodeHandler */ - $nodeHandler = $this->handlerFactory->getHandler($row); - $nodeHandler->removeWithChildrenAndAssociations(); - $io->progressAdvance(); - ++$i; - // Call flush time to times - if (($i % $batchSize) === 0) { - $em->flush(); - $em->clear(); - } - } + if ($input->isInteractive() && !$io->askQuestion($confirmation)) { + return 0; + } - /* - * Final flush - */ + $i = 0; + $batchSize = 100; + $io->progressStart((int) $emptiedCount); + + $qb = $this->createNodeQueryBuilder(); + $q = $qb->select('n') + ->andWhere($countQb->expr()->eq('n.status', Node::DELETED)) + ->getQuery(); + + foreach ($q->toIterable() as $row) { + /** @var NodeHandler $nodeHandler */ + $nodeHandler = $this->handlerFactory->getHandler($row); + $nodeHandler->removeWithChildrenAndAssociations(); + $io->progressAdvance(); + ++$i; + // Call flush time to times + if (($i % $batchSize) === 0) { $em->flush(); - $io->progressFinish(); - $io->success('Nodes trashcan has been emptied.'); + $em->clear(); } - } else { - $io->success('Nodes trashcan is already empty.'); } + /* + * Final flush + */ + $em->flush(); + $io->progressFinish(); + $io->success('Nodes trashcan has been emptied.'); + return 0; } diff --git a/src/Console/NodesOrphansCommand.php b/src/Console/NodesOrphansCommand.php index e3a68598..2be332d9 100644 --- a/src/Console/NodesOrphansCommand.php +++ b/src/Console/NodesOrphansCommand.php @@ -59,36 +59,37 @@ protected function execute(InputInterface $input, OutputInterface $output): int } catch (NoResultException $e) { } - if (count($orphans) > 0) { - $io->note(sprintf('You have %s orphan node(s)!', count($orphans))); - $tableContent = []; + if (count($orphans) === 0) { + $io->success('That’s OK, you don’t have any orphan node.'); + return 0; + } - /** @var Node $node */ - foreach ($orphans as $node) { - $tableContent[] = [ - $node->getId(), - $node->getNodeName(), - null !== $node->getNodeType() ? $node->getNodeType()->getName() : '', - (!$node->isVisible() ? 'X' : ''), - ($node->isPublished() ? 'X' : ''), - ]; - } + $io->note(sprintf('You have %s orphan node(s)!', count($orphans))); + $tableContent = []; - $io->table(['Id', 'Name', 'Type', 'Hidden', 'Published'], $tableContent); + /** @var Node $node */ + foreach ($orphans as $node) { + $tableContent[] = [ + $node->getId(), + $node->getNodeName(), + null !== $node->getNodeType() ? $node->getNodeType()->getName() : '', + (!$node->isVisible() ? 'X' : ''), + ($node->isPublished() ? 'X' : ''), + ]; + } - if ($input->getOption('delete')) { - /** @var Node $orphan */ - foreach ($orphans as $orphan) { - $entityManager->remove($orphan); - } - $entityManager->flush(); + $io->table(['Id', 'Name', 'Type', 'Hidden', 'Published'], $tableContent); - $io->success('Orphan nodes have been removed from your database.'); - } else { - $io->note('Use --delete option to actually remove these nodes.'); + if ($input->getOption('delete')) { + /** @var Node $orphan */ + foreach ($orphans as $orphan) { + $entityManager->remove($orphan); } + $entityManager->flush(); + + $io->success('Orphan nodes have been removed from your database.'); } else { - $io->success('That’s OK, you don’t have any orphan node.'); + $io->note('Use --delete option to actually remove these nodes.'); } return 0; } diff --git a/src/Console/RunningCommandsTrait.php b/src/Console/RunningCommandsTrait.php index 9ea95c07..94badc9b 100644 --- a/src/Console/RunningCommandsTrait.php +++ b/src/Console/RunningCommandsTrait.php @@ -5,7 +5,7 @@ namespace RZ\Roadiz\CoreBundle\Console; use Symfony\Component\Console\Style\SymfonyStyle; -use Symfony\Component\Process\Process; +use Symfony\Component\Process\PhpSubprocess; trait RunningCommandsTrait { @@ -22,9 +22,11 @@ protected function runCommand( $args .= $quiet ? ' --quiet ' : ' -v '; $args .= is_string($environment) ? (' --env ' . $environment) : ''; - $process = Process::fromShellCommandline( - 'php bin/console ' . $command . ' ' . $args - ); + $process = new PhpSubprocess([ + 'bin/console', + $command, + ...array_filter(explode(' ', trim($args))), + ]); $process->setWorkingDirectory($this->getProjectDir()); $process->setTty($interactive); $process->run(); diff --git a/src/Console/SolrCommand.php b/src/Console/SolrCommand.php index 32396f2b..55977a44 100644 --- a/src/Console/SolrCommand.php +++ b/src/Console/SolrCommand.php @@ -5,6 +5,7 @@ namespace RZ\Roadiz\CoreBundle\Console; use RZ\Roadiz\CoreBundle\SearchEngine\ClientRegistry; +use Solarium\Core\Client\Client; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -27,31 +28,44 @@ protected function configure(): void ->setDescription('Check Solr search engine server'); } - protected function execute(InputInterface $input, OutputInterface $output): int + protected function validateSolrState(SymfonyStyle $io): ?Client { $client = $this->clientRegistry->getClient(); - $this->io = new SymfonyStyle($input, $output); - if (null !== $client) { - if (true === $this->clientRegistry->isClientReady($client)) { - $this->io->writeln('Solr search engine server is running…'); - } else { - $this->io->error('Solr search engine server does not respond…'); - $this->io->note('See your config.yml file to correct your Solr connexion settings.'); - return 1; - } - } else { + if (null === $client) { $this->displayBasicConfig(); + return null; + } + + if (true !== $this->clientRegistry->isClientReady($client)) { + $io->error('Solr search engine server does not respond…'); + $io->note('See your `config/packages/roadiz_core.yaml` file to correct your Solr connection settings.'); + return null; } + + return $client; + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $this->io = new SymfonyStyle($input, $output); + if (null === $this->validateSolrState($this->io)) { + return 1; + } + + $this->io->success('Solr search engine server is running.'); return 0; } protected function displayBasicConfig(): void { - if (null !== $this->io) { - $this->io->error('No Solr search engine server has been configured…'); - $this->io->note(<<io) { + return; + } + + $this->io->error('No Solr search engine server has been configured…'); + $this->io->note(<<clientRegistry->getClient(); $this->io = new SymfonyStyle($input, $output); - if (null !== $solr) { - if (true === $this->clientRegistry->isClientReady($solr)) { - $documentIndexer = $this->indexerFactory->getIndexerFor(Document::class); - if ($documentIndexer instanceof CliAwareIndexer) { - $documentIndexer->setIo($this->io); - } - $documentIndexer->optimizeSolr(); - $this->io->success('Solr core has been optimized.'); - } else { - $this->io->error('Solr search engine server does not respond…'); - $this->io->note('See your config.yml file to correct your Solr connexion settings.'); - return 1; - } - } else { - $this->displayBasicConfig(); + if (null === $this->validateSolrState($this->io)) { + return 1; } + + $documentIndexer = $this->indexerFactory->getIndexerFor(Document::class); + if ($documentIndexer instanceof CliAwareIndexer) { + $documentIndexer->setIo($this->io); + } + $documentIndexer->optimizeSolr(); + $this->io->success('Solr core has been optimized.'); return 0; } } diff --git a/src/Console/SolrReindexCommand.php b/src/Console/SolrReindexCommand.php index 041a22fb..5576c0ab 100644 --- a/src/Console/SolrReindexCommand.php +++ b/src/Console/SolrReindexCommand.php @@ -40,37 +40,30 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { - $solr = $this->clientRegistry->getClient(); $this->io = new SymfonyStyle($input, $output); - if (null !== $solr) { - if (true === $this->clientRegistry->isClientReady($solr)) { - if ( - $this->io->confirm( - 'Are you sure to reindex your Node and Document database?', - !$input->isInteractive() - ) - ) { - $stopwatch = new Stopwatch(); - $stopwatch->start('global'); - - if ($input->getOption('documents')) { - $this->executeForDocuments($stopwatch); - } elseif ($input->getOption('nodes')) { - $batchCount = (int) ($input->getOption('batch-count') ?? 1); - $batchNumber = (int) ($input->getOption('batch-number') ?? 0); - $this->executeForNodes($stopwatch, $batchCount, $batchNumber); - } else { - $this->executeForAll($stopwatch); - } - } + if (null === $this->validateSolrState($this->io)) { + return 1; + } + + if ( + $this->io->confirm( + 'Are you sure to reindex your Node and Document database?', + !$input->isInteractive() + ) + ) { + $stopwatch = new Stopwatch(); + $stopwatch->start('global'); + + if ($input->getOption('documents')) { + $this->executeForDocuments($stopwatch); + } elseif ($input->getOption('nodes')) { + $batchCount = (int) ($input->getOption('batch-count') ?? 1); + $batchNumber = (int) ($input->getOption('batch-number') ?? 0); + $this->executeForNodes($stopwatch, $batchCount, $batchNumber); } else { - $this->io->error('Solr search engine server does not respond…'); - $this->io->note('See your config.yml file to correct your Solr connexion settings.'); - return 1; + $this->executeForAll($stopwatch); } - } else { - $this->displayBasicConfig(); } return 0; } diff --git a/src/Console/SolrResetCommand.php b/src/Console/SolrResetCommand.php index ac48d1f3..ba0b94b4 100644 --- a/src/Console/SolrResetCommand.php +++ b/src/Console/SolrResetCommand.php @@ -31,30 +31,22 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { - $solr = $this->clientRegistry->getClient(); $this->io = new SymfonyStyle($input, $output); - if (null !== $solr) { - if (true === $this->clientRegistry->isClientReady($solr)) { - $confirmation = new ConfirmationQuestion( - 'Are you sure to reset Solr index?', - false - ); - if ($this->io->askQuestion($confirmation)) { - $indexer = $this->indexerFactory->getIndexerFor(NodesSources::class); - if ($indexer instanceof CliAwareIndexer) { - $indexer->setIo($this->io); - } - $indexer->emptySolr(); - $this->io->success('Solr index resetted.'); - } - } else { - $this->io->error('Solr search engine server does not respond…'); - $this->io->note('See your config.yml file to correct your Solr connexion settings.'); - return 1; + if (null === $this->validateSolrState($this->io)) { + return 1; + } + $confirmation = new ConfirmationQuestion( + 'Are you sure to reset Solr index?', + false + ); + if ($this->io->askQuestion($confirmation)) { + $indexer = $this->indexerFactory->getIndexerFor(NodesSources::class); + if ($indexer instanceof CliAwareIndexer) { + $indexer->setIo($this->io); } - } else { - $this->displayBasicConfig(); + $indexer->emptySolr(); + $this->io->success('Solr index resetted.'); } return 0; } diff --git a/src/Console/TranslationsCommand.php b/src/Console/TranslationsCommand.php index e3781525..5f557c74 100644 --- a/src/Console/TranslationsCommand.php +++ b/src/Console/TranslationsCommand.php @@ -33,22 +33,23 @@ protected function execute(InputInterface $input, OutputInterface $output): int ->getRepository(Translation::class) ->findAll(); - if (count($translations) > 0) { - $tableContent = []; - /** @var Translation $trans */ - foreach ($translations as $trans) { - $tableContent[] = [ - $trans->getId(), - $trans->getName(), - $trans->getLocale(), - (!$trans->isAvailable() ? 'X' : ''), - ($trans->isDefaultTranslation() ? 'X' : ''), - ]; - } - $io->table(['Id', 'Name', 'Locale', 'Disabled', 'Default'], $tableContent); - } else { + if (count($translations) === 0) { $io->error('No available translations.'); + return 1; } + + $tableContent = []; + /** @var Translation $trans */ + foreach ($translations as $trans) { + $tableContent[] = [ + $trans->getId(), + $trans->getName(), + $trans->getLocale(), + (!$trans->isAvailable() ? 'X' : ''), + ($trans->isDefaultTranslation() ? 'X' : ''), + ]; + } + $io->table(['Id', 'Name', 'Locale', 'Disabled', 'Default'], $tableContent); return 0; } } diff --git a/src/Console/TranslationsCreationCommand.php b/src/Console/TranslationsCreationCommand.php index 9d0f8b90..387801e0 100644 --- a/src/Console/TranslationsCreationCommand.php +++ b/src/Console/TranslationsCreationCommand.php @@ -38,41 +38,43 @@ protected function execute(InputInterface $input, OutputInterface $output): int $name = $input->getArgument('name'); $locale = $input->getArgument('locale'); - if ($name) { - $translationByName = $this->managerRegistry - ->getRepository(Translation::class) - ->findOneByName($name); - $translationByLocale = $this->managerRegistry - ->getRepository(Translation::class) - ->findOneByLocale($locale); + if (!$name) { + return 1; + } - $confirmation = new ConfirmationQuestion( - 'Are you sure to create ' . $name . ' (' . $locale . ') translation?', - false - ); + $translationByName = $this->managerRegistry + ->getRepository(Translation::class) + ->findOneByName($name); + $translationByLocale = $this->managerRegistry + ->getRepository(Translation::class) + ->findOneByLocale($locale); + + $confirmation = new ConfirmationQuestion( + 'Are you sure to create ' . $name . ' (' . $locale . ') translation?', + false + ); - if (null !== $translationByName) { - $io->error('Translation ' . $name . ' already exists.'); - return 1; - } elseif (null !== $translationByLocale) { - $io->error('Translation locale ' . $locale . ' is already used.'); - return 1; - } else { - if ( - $io->askQuestion( - $confirmation - ) - ) { - $newTrans = new Translation(); - $newTrans->setName($name) - ->setLocale($locale); + if (null !== $translationByName) { + $io->error('Translation ' . $name . ' already exists.'); + return 1; + } elseif (null !== $translationByLocale) { + $io->error('Translation locale ' . $locale . ' is already used.'); + return 1; + } + + if ( + $io->askQuestion( + $confirmation + ) + ) { + $newTrans = new Translation(); + $newTrans->setName($name) + ->setLocale($locale); - $this->managerRegistry->getManagerForClass(Translation::class)->persist($newTrans); - $this->managerRegistry->getManagerForClass(Translation::class)->flush(); + $this->managerRegistry->getManagerForClass(Translation::class)->persist($newTrans); + $this->managerRegistry->getManagerForClass(Translation::class)->flush(); - $io->success('New ' . $newTrans->getName() . ' translation for ' . $newTrans->getLocale() . ' locale.'); - } - } + $io->success('New ' . $newTrans->getName() . ' translation for ' . $newTrans->getLocale() . ' locale.'); } return 0; } diff --git a/src/Console/TranslationsDeleteCommand.php b/src/Console/TranslationsDeleteCommand.php index 60f54562..50498511 100644 --- a/src/Console/TranslationsDeleteCommand.php +++ b/src/Console/TranslationsDeleteCommand.php @@ -42,29 +42,31 @@ protected function execute(InputInterface $input, OutputInterface $output): int if ($translationCount < 2) { $io->error('You cannot delete the only one available translation!'); return 1; - } elseif ($translation !== null) { - $io->note('///////////////////////////////' . PHP_EOL . - '/////////// WARNING ///////////' . PHP_EOL . - '///////////////////////////////' . PHP_EOL . - 'This operation cannot be undone.' . PHP_EOL . - 'Deleting a translation, you will automatically delete every translated tags, node-sources, url-aliases and documents.'); - $confirmation = new ConfirmationQuestion( - 'Are you sure to delete ' . $translation->getName() . ' (' . $translation->getLocale() . ') translation?', - false - ); - if ( - $io->askQuestion( - $confirmation - ) - ) { - $this->managerRegistry->getManagerForClass(Translation::class)->remove($translation); - $this->managerRegistry->getManagerForClass(Translation::class)->flush(); - $io->success('Translation deleted.'); - } - } else { + } + + if ($translation === null) { $io->error('Translation for locale ' . $locale . ' does not exist.'); return 1; } + + $io->note('///////////////////////////////' . PHP_EOL . + '/////////// WARNING ///////////' . PHP_EOL . + '///////////////////////////////' . PHP_EOL . + 'This operation cannot be undone.' . PHP_EOL . + 'Deleting a translation, you will automatically delete every translated tags, node-sources, url-aliases and documents.'); + $confirmation = new ConfirmationQuestion( + 'Are you sure to delete ' . $translation->getName() . ' (' . $translation->getLocale() . ') translation?', + false + ); + if ( + $io->askQuestion( + $confirmation + ) + ) { + $this->managerRegistry->getManagerForClass(Translation::class)->remove($translation); + $this->managerRegistry->getManagerForClass(Translation::class)->flush(); + $io->success('Translation deleted.'); + } return 0; } } diff --git a/src/Console/TranslationsDisableCommand.php b/src/Console/TranslationsDisableCommand.php index 164b7422..4407fb5b 100644 --- a/src/Console/TranslationsDisableCommand.php +++ b/src/Console/TranslationsDisableCommand.php @@ -36,24 +36,24 @@ protected function execute(InputInterface $input, OutputInterface $output): int ->getRepository(Translation::class) ->findOneByLocale($locale); - if ($translation !== null) { - $confirmation = new ConfirmationQuestion( - 'Are you sure to disable ' . $translation->getName() . ' (' . $translation->getLocale() . ') translation?', - false - ); - if ( - $io->askQuestion( - $confirmation - ) - ) { - $translation->setAvailable(false); - $this->managerRegistry->getManagerForClass(Translation::class)->flush(); - $io->success('Translation disabled.'); - } - } else { + if ($translation === null) { $io->error('Translation for locale ' . $locale . ' does not exist.'); return 1; } + + $confirmation = new ConfirmationQuestion( + 'Are you sure to disable ' . $translation->getName() . ' (' . $translation->getLocale() . ') translation?', + false + ); + if ( + $io->askQuestion( + $confirmation + ) + ) { + $translation->setAvailable(false); + $this->managerRegistry->getManagerForClass(Translation::class)->flush(); + $io->success('Translation disabled.'); + } return 0; } } diff --git a/src/Console/TranslationsEnableCommand.php b/src/Console/TranslationsEnableCommand.php index f6656694..5c4121f4 100644 --- a/src/Console/TranslationsEnableCommand.php +++ b/src/Console/TranslationsEnableCommand.php @@ -36,24 +36,24 @@ protected function execute(InputInterface $input, OutputInterface $output): int ->getRepository(Translation::class) ->findOneByLocale($locale); - if ($translation !== null) { - $confirmation = new ConfirmationQuestion( - 'Are you sure to enable ' . $translation->getName() . ' (' . $translation->getLocale() . ') translation?', - false - ); - if ( - $io->askQuestion( - $confirmation - ) - ) { - $translation->setAvailable(true); - $this->managerRegistry->getManagerForClass(Translation::class)->flush(); - $io->success('Translation enabled.'); - } - } else { + if ($translation === null) { $io->error('Translation for locale ' . $locale . ' does not exist.'); return 1; } + + $confirmation = new ConfirmationQuestion( + 'Are you sure to enable ' . $translation->getName() . ' (' . $translation->getLocale() . ') translation?', + false + ); + if ( + $io->askQuestion( + $confirmation + ) + ) { + $translation->setAvailable(true); + $this->managerRegistry->getManagerForClass(Translation::class)->flush(); + $io->success('Translation enabled.'); + } return 0; } } diff --git a/src/Console/VersionsPurgeCommand.php b/src/Console/VersionsPurgeCommand.php index 8891e472..1c89935c 100644 --- a/src/Console/VersionsPurgeCommand.php +++ b/src/Console/VersionsPurgeCommand.php @@ -79,7 +79,6 @@ private function getRepository(): UserLogEntryRepository private function purgeByDate(InputInterface $input, OutputInterface $output): void { $io = new SymfonyStyle($input, $output); - $em = $this->managerRegistry->getManagerForClass(UserLogEntry::class); $dateTime = new \DateTime($input->getOption('before')); if ($dateTime >= new \DateTime()) { @@ -105,7 +104,6 @@ private function purgeByCount(InputInterface $input, OutputInterface $output): v { $io = new SymfonyStyle($input, $output); $count = (int) $input->getOption('count'); - $em = $this->managerRegistry->getManagerForClass(UserLogEntry::class); $question = new ConfirmationQuestion(sprintf( 'Do you want to purge all entities versions and to keep only the latest %s?',