Browse Source

add the update config file command

Olivier Massot 4 năm trước cách đây
mục cha
commit
6a4b73d723

+ 106 - 0
ot_admin/Classes/Command/UpdateConfigFileCommand.php

@@ -0,0 +1,106 @@
+<?php
+
+namespace Opentalent\OtAdmin\Command;
+
+
+use Opentalent\OtAdmin\Controller\SiteController;
+use Opentalent\OtCore\Exception\NoSuchOrganizationException;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Object\ObjectManager;
+
+/**
+ * This CLI command create or update the organization config file, and update the identifier field in ot_websites table
+ * This is a light alternative to the update command, designed to be executed on a development env, just after
+ * the databases cloning.
+ *
+ * @package Opentalent\OtAdmin\Command
+ */
+class UpdateConfigFileCommand extends Command
+{
+    /**
+     * -- This method is expected by Typo3, do not rename ou remove --
+     *
+     * Allows to configure the command.
+     * Allows to add a description, a help text, and / or define arguments.
+     *
+     */
+    protected function configure()
+    {
+        $this
+            ->setName("ot:site:gen-config-file")
+            ->setDescription("Update an organization configuration file")
+            ->setHelp("This CLI command creates or updates the organization config file")
+            ->addOption(
+                'all',
+                null,
+                InputOption::VALUE_NONE,
+                "Update all of the organization websites"
+            )
+            ->addArgument(
+                'organization-id',
+                InputArgument::OPTIONAL,
+                "The organization's id in the opentalent DB"
+            );
+    }
+
+    /**
+     * -- This method is expected by Typo3, do not rename ou remove --
+     *
+     * @param InputInterface $input
+     * @param OutputInterface $output
+     * @throws \Exception
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $org_id = $input->getArgument('organization-id');
+        $all = $input->getOption('all');
+
+        if ($all && $org_id) {
+            throw new \InvalidArgumentException("You can not pass both an organization id and the --all option");
+        }
+        if (!$all && !$org_id) {
+            throw new \InvalidArgumentException("You shall either pass an organization id or use the --all option");
+        }
+
+        $io = new SymfonyStyle($input, $output);
+
+        $siteController = GeneralUtility::makeInstance(ObjectManager::class)->get(SiteController::class);
+
+        if ($all) {
+            $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
+            $queryBuilder = $connectionPool->getQueryBuilderForTable('ot_websites');
+            $sites = $queryBuilder
+                ->select('organization_id')
+                ->from('ot_websites')
+                ->where($queryBuilder->expr()->eq('deleted', 0))
+                ->andWhere($queryBuilder->expr()->gt('organization_id', 0))
+                ->execute()
+                ->fetchAll();
+
+            $io->progressStart(count($sites));
+
+            foreach ($sites as $site) {
+                $org_id = $site['organization_id'];
+                try {
+                    $siteController->updateConfigFileAction($org_id);
+                } catch (\Throwable $e) {
+                    $io->error('Organization Id: ' . $org_id . ' - ' . $e->getMessage());
+                }
+                $io->progressAdvance(1);
+            }
+            $io->progressFinish();
+
+            $io->success(sprintf("The websites config files have all been updated"));
+        } else {
+            $identifier = $siteController->updateConfigFileAction($org_id);
+            $io->success(sprintf("The config file with identifier " . $identifier . " has been updated"));
+        }
+    }
+}

+ 56 - 2
ot_admin/Classes/Controller/SiteController.php

@@ -1697,7 +1697,7 @@ class SiteController extends ActionController
     }
 
     /**
-     * CLI action for resetting the rights of admin and editors of the website
+     * Action for resetting the rights of admin and editors of the website
      * on all of the existing pages, including deleted ones
      *
      * @param int $organizationId
@@ -1726,6 +1726,54 @@ class SiteController extends ActionController
         }
     }
 
+    /**
+     * Create or update the organization config file, and update the identifier field in ot_websites table
+     *
+     * This is a light alternative to the updateAction(), designed to be executed on a development env, just after
+     * the databases cloning.
+     *
+     * @param int $organizationId
+     * @param bool $forceRecreate
+     * @return string
+     * @throws NoSuchRecordException
+     * @throws NoSuchWebsiteException
+     * @throws \Doctrine\DBAL\ConnectionException
+     * @throws \Doctrine\DBAL\DBALException
+     * @throws \Opentalent\OtCore\Exception\InvalidWebsiteConfigurationException
+     * @throws \Throwable
+     */
+    public function updateConfigFileAction(int $organizationId, bool $forceRecreate=false): string
+    {
+        $website = $this->otWebsiteRepository->getWebsiteByOrganizationId($organizationId);
+        $rootUid = $this->otWebsiteRepository->getWebsiteRootUid($website['uid']);
+
+        $this->connectionPool->getConnectionByName('Default')->beginTransaction();
+        try {
+            $recorded_identifier = $website['config_identifier'] ?? null;
+            $identifier = $this->writeConfigFile($rootUid, $forceRecreate, $recorded_identifier);
+
+            // ## Update the ot_website identifier
+            if ($recorded_identifier != $identifier) {
+                $queryBuilder = $this->connectionPool->getQueryBuilderForTable('ot_websites');
+                $queryBuilder->update('ot_websites')
+                    ->set('config_identifier', $identifier)
+                    ->where($queryBuilder->expr()->eq('uid', $website['uid']))
+                    ->execute();
+            }
+
+            $commitSuccess = $this->connectionPool->getConnectionByName('Default')->commit();
+            if (!$commitSuccess) {
+                throw new \RuntimeException('Something went wrong while commiting the result');
+            }
+            return $identifier;
+        }
+        catch (\Throwable $e) {
+            // rollback
+            $this->connectionPool->getConnectionByName('Default')->rollback();
+            throw $e;
+        }
+    }
+
     /**
      * Retrieve the Organization object from the repository and then,
      * from the Opentalent API
@@ -2060,7 +2108,13 @@ class SiteController extends ActionController
         $website = $this->otWebsiteRepository->getWebsiteByPageUid($rootUid);
         $domain = $this->otWebsiteRepository->resolveWebsiteDomain($website);
 
-        $existing = $this->otWebsiteRepository->findConfigFileAndContentFor($rootUid, $identifier);
+        try {
+            $existing = $this->otWebsiteRepository->findConfigFileAndContentFor($rootUid, $identifier);
+        } catch (\RuntimeException $e) {
+            // identifier might be obsolete
+            $existing = $this->otWebsiteRepository->findConfigFileAndContentFor($rootUid);
+        }
+
         $configFilename = $existing[0];
         $config = $existing[1];
 

+ 3 - 0
ot_admin/Configuration/Commands.php

@@ -22,6 +22,9 @@ return [
     'ot:site:update' => [
         'class' => Opentalent\OtAdmin\Command\UpdateSiteCommand::class
     ],
+    'ot:site:gen-config-file' => [
+        'class' => Opentalent\OtAdmin\Command\UpdateConfigFileCommand::class
+    ],
     'ot:site:clear-cache' => [
         'class' => Opentalent\OtAdmin\Command\ClearSiteCacheCommand::class
     ],

+ 6 - 2
ot_core/Classes/Website/OtWebsiteRepository.php

@@ -384,12 +384,16 @@ class OtWebsiteRepository
 
         if ($identifier !== null) {
             $filename = $configs_directory . $identifier . "/config.yaml";
-            $yamlConfig = Yaml::parseFile($filename);
+            try {
+                $yamlConfig = Yaml::parseFile($filename);
+            } catch (\Symfony\Component\Yaml\Exception\ParseException $e) {
+                throw new \RuntimeException("No configuration file found for identifier " . $identifier);
+            }
 
             if ($yamlConfig['rootPageId'] === $rootUid) {
                 return [$filename, $yamlConfig];
             } else {
-                throw new \RuntimeException("No configuration file found for identifier " . $identifier);
+                throw new \RuntimeException("The configuration file with identifier " . $identifier . " is attached to another root uid");
             }
         }