Selaa lähdekoodia

finalize websites refactoring and reintegrate ot_router into ot_core

Olivier Massot 4 vuotta sitten
vanhempi
commit
78d8ccdf9c

+ 0 - 1
README.md

@@ -26,7 +26,6 @@ du répertoire de l'application typo3
                 "Opentalent\\OtTemplating\\": "public/typo3conf/ext/ot_templating/Classes",
                 "Opentalent\\OtStats\\": "public/typo3conf/ext/ot_stats/Classes",
                 "Opentalent\\OtAdmin\\": "public/typo3conf/ext/ot_admin/Classes",
-                "Opentalent\\OtRouter\\": "public/typo3conf/ext/ot_router/Classes"
                 "Opentalent\\OtOptimizer\\": "public/typo3conf/ext/ot_optimizer/Classes"
     		}
     	}

+ 0 - 1
docker/conf/composer.json

@@ -64,7 +64,6 @@
 			"Opentalent\\OtTemplating\\": "public/typo3conf/ext/ot_templating/Classes",
 			"Opentalent\\OtAdmin\\": "public/typo3conf/ext/ot_admin/Classes",
 			"Opentalent\\OtStats\\": "public/typo3conf/ext/ot_stats/Classes",
-			"Opentalent\\OtRouter\\": "public/typo3conf/ext/ot_router/Classes",
 			"Opentalent\\OtOptimizer\\": "public/typo3conf/ext/ot_optimizer/Classes"
 		}
 	}

+ 1 - 1
ot_admin/Classes/Command/SetSiteDomainCommand.php

@@ -71,7 +71,7 @@ class SetSiteDomainCommand extends Command
         $io = new SymfonyStyle($input, $output);
 
         $siteController = GeneralUtility::makeInstance(ObjectManager::class)->get(SiteController::class);
-        $rootUid = $siteController->setSiteDomainAction($org_id, $domain, $redirect);
+        $rootUid = $siteController->setSiteCustomDomainAction($org_id, $domain, $redirect);
 
         $io->success(sprintf("The website with root uid " . $rootUid . " domain has been set to " . $domain));
     }

+ 153 - 254
ot_admin/Classes/Controller/SiteController.php

@@ -12,8 +12,9 @@ use Opentalent\OtCore\Controller\ActionController;
 use Opentalent\OtCore\Domain\Model\Organization;
 use Opentalent\OtCore\Domain\Repository\OrganizationRepository;
 use Opentalent\OtCore\Exception\ApiRequestException;
+use Opentalent\OtCore\Website\OtWebsiteRepository;
 use Opentalent\OtCore\Utility\FileUtility;
-use Opentalent\OtRouter\Routing\Indexer;
+use Opentalent\OtCore\Routing\Indexer;
 use PDO;
 use Symfony\Component\Yaml\Yaml;
 use TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException;
@@ -104,7 +105,7 @@ class SiteController extends ActionController
     /**
      * @var \TYPO3\CMS\Core\Database\ConnectionPool
      */
-    private $connectionPool;
+    private \TYPO3\CMS\Core\Database\ConnectionPool $connectionPool;
 
     public function injectConnectionPool(\TYPO3\CMS\Core\Database\ConnectionPool $connectionPool)
     {
@@ -114,13 +115,22 @@ class SiteController extends ActionController
     /**
      * @var \TYPO3\CMS\Core\Cache\CacheManager
      */
-    private $cacheManager;
+    private \TYPO3\CMS\Core\Cache\CacheManager $cacheManager;
 
     public function injectCacheManager(\TYPO3\CMS\Core\Cache\CacheManager $cacheManager)
     {
         $this->cacheManager = $cacheManager;
     }
 
+    /**
+     * @var OtWebsiteRepository
+     */
+    protected OtWebsiteRepository $otWebsiteRepository;
+
+    public function injectOtWebsiteRepository(OtWebsiteRepository $otWebsiteRepository) {
+        $this->otWebsiteRepository = $otWebsiteRepository;
+    }
+
     /**
      * Index of the pages created during the process
      * >> [slug => uid]
@@ -157,19 +167,20 @@ class SiteController extends ActionController
      */
     public function getSiteInfosAction(int $organizationId): SiteInfos
     {
-        $rootUid = $this->findRootUidFor($organizationId);
-        $config = $this->findConfigFor($rootUid);
+        $website = $this->otWebsiteRepository->getWebsiteByOrganizationId($organizationId);
+        $rootUid = $this->otWebsiteRepository->getWebsiteRootUid($website['uid']);
+
         $organizationExtraData = $this->fetchOrganizationExtraData($organizationId);
 
         $rootPage = $this->otPageRepository->getPage($rootUid);
 
         $site = new SiteInfos(
             $rootUid,
-            $rootPage['title'],
-            $config['base'],
-            $rootPage['tx_opentalent_template'],
-            $rootPage['tx_opentalent_template_preferences'],
-            $rootPage['tx_opentalent_matomo_id'],
+            $website['organization_name'],
+            $this->otWebsiteRepository->getWebsiteDomain($website['uid']),
+            $website['template'],
+            $website['template_preferences'],
+            $website['matomo_id'],
             self::IS_PRODUCT_PREMIUM[$organizationExtraData['admin']['product']] ?? false,
             (bool)$rootPage['deleted'],
             ($rootPage['hidden'] || $rootPage['fe_group'] < 0),
@@ -236,9 +247,8 @@ class SiteController extends ActionController
         $queryBuilder->getRestrictions()->removeAll();
         $statement = $queryBuilder
             ->select('uid')
-            ->from('pages')
-            ->where($queryBuilder->expr()->eq('tx_opentalent_structure_id', $queryBuilder->createNamedParameter($organization->getId())))
-            ->andWhere('is_siteroot=1')
+            ->from('ot_websites')
+            ->where($queryBuilder->expr()->eq('organization_id', $queryBuilder->createNamedParameter($organization->getId())))
             ->execute();
         if ($statement->rowCount() > 0) {
             throw new \RuntimeException("A website with this organization's id already exists: " . $organization->getName() . "\n(if you can't see it, it might have been soft-deleted)");
@@ -251,13 +261,19 @@ class SiteController extends ActionController
 
         // keep tracks of the created folders and files to be able to remove them during a rollback
         try {
+            // Create the website:
+            $websiteUid = $this->insertOtWebsite($organization);
+
             // Create the site pages:
             // > Root page
-            $rootUid = $this->insertRootPage($organization);
+            $rootUid = $this->insertRootPage(
+                $websiteUid,
+                $organization->getName()
+            );
 
             // > 'Accueil' shortcut
             $this->insertPage(
-                $organization,
+                $websiteUid,
                 $rootUid,
                 'Accueil',
                 '/accueil',
@@ -270,7 +286,7 @@ class SiteController extends ActionController
 
             // > 'Présentation' page
             $this->insertPage(
-                $organization,
+                $websiteUid,
                 $rootUid,
                 'Présentation',
                 '/presentation'
@@ -278,7 +294,7 @@ class SiteController extends ActionController
 
             // > 'Présentation > Qui sommes nous?' page (hidden by default)
             $this->insertPage(
-                $organization,
+                $websiteUid,
                 $this->createdPagesIndex['/presentation'],
                 'Qui sommes nous?',
                 '/qui-sommes-nous',
@@ -288,7 +304,7 @@ class SiteController extends ActionController
 
             // > 'Présentation > Les adhérents' page
             $this->insertPage(
-                $organization,
+                $websiteUid,
                 $this->createdPagesIndex['/presentation'],
                 'Les adhérents',
                 '/les-adherents',
@@ -297,7 +313,7 @@ class SiteController extends ActionController
 
             // > 'Présentation > Les membres du CA' page
             $this->insertPage(
-                $organization,
+                $websiteUid,
                 $this->createdPagesIndex['/presentation'],
                 'Les membres du CA',
                 '/les-membres-du-ca',
@@ -307,7 +323,7 @@ class SiteController extends ActionController
             if ($isNetwork) {
                 // > 'Présentation > Les sociétés adhérentes' page
                 $this->insertPage(
-                    $organization,
+                    $websiteUid,
                     $this->createdPagesIndex['/presentation'],
                     'Les sociétés adhérentes',
                     '/societes-adherentes',
@@ -317,7 +333,7 @@ class SiteController extends ActionController
 
             // > 'Présentation > Historique' page (hidden by default)
             $this->insertPage(
-                $organization,
+                $websiteUid,
                 $this->createdPagesIndex['/presentation'],
                 'Historique',
                 '/historique',
@@ -329,7 +345,7 @@ class SiteController extends ActionController
 
             // > 'Actualités' page (hidden by default)
             $this->insertPage(
-                $organization,
+                $websiteUid,
                 $rootUid,
                 'Actualités',
                 '/actualites',
@@ -339,7 +355,7 @@ class SiteController extends ActionController
 
             // > 'Saison en cours' page
             $this->insertPage(
-                $organization,
+                $websiteUid,
                 $rootUid,
                 'Saison en cours',
                 '/saison-en-cours'
@@ -347,7 +363,7 @@ class SiteController extends ActionController
 
             // > 'Saison en cours > Les évènements' page
             $this->insertPage(
-                $organization,
+                $websiteUid,
                 $this->createdPagesIndex['/saison-en-cours'],
                 'Les évènements',
                 '/les-evenements',
@@ -357,7 +373,7 @@ class SiteController extends ActionController
             if ($isNetwork) {
                 // > 'Présentation > Les sociétés adhérentes' page
                 $this->insertPage(
-                    $organization,
+                    $websiteUid,
                     $this->createdPagesIndex['/presentation'],
                     'Évènements des structures',
                     '/evenements-des-structures',
@@ -367,7 +383,7 @@ class SiteController extends ActionController
 
             // > 'Vie interne' page (restricted, hidden by default)
             $this->insertPage(
-                $organization,
+                $websiteUid,
                 $rootUid,
                 'Vie interne',
                 '/vie-interne',
@@ -380,7 +396,7 @@ class SiteController extends ActionController
 
             // > 'Footer' page (not in the menu)
             $this->insertPage(
-                $organization,
+                $websiteUid,
                 $rootUid,
                 'Footer',
                 '/footer',
@@ -393,7 +409,7 @@ class SiteController extends ActionController
 
             // > 'Footer > Contact' page
             $this->insertPage(
-                $organization,
+                $websiteUid,
                 $this->createdPagesIndex['/footer'],
                 'Contact',
                 '/contact',
@@ -402,7 +418,7 @@ class SiteController extends ActionController
 
             // > 'Footer > Plan du site' page
             $this->insertPage(
-                $organization,
+                $websiteUid,
                 $this->createdPagesIndex['/footer'],
                 'Plan du site',
                 '/plan-du-site'
@@ -410,7 +426,7 @@ class SiteController extends ActionController
 
             // > 'Footer > Mentions légales' page
             $this->insertPage(
-                $organization,
+                $websiteUid,
                 $this->createdPagesIndex['/footer'],
                 'Mentions légales',
                 '/mentions-legales',
@@ -419,7 +435,7 @@ class SiteController extends ActionController
 
             // > 'Présentation > Contact' shortcut
             $this->insertPage(
-                $organization,
+                $websiteUid,
                 $this->createdPagesIndex['/presentation'],
                 'Contact',
                 '/ecrivez-nous',
@@ -432,7 +448,7 @@ class SiteController extends ActionController
 
             // > 'Page introuvable' page (not in the menu, read-only)
             $this->insertPage(
-                $organization,
+                $websiteUid,
                 $rootUid,
                 'Page introuvable',
                 '/page-introuvable',
@@ -475,23 +491,6 @@ class SiteController extends ActionController
                 self::CTYPE_SITEMAP
             );
 
-            // Build and update the domain
-            if ($mode == self::MODE_PROD) {
-                $domain = $this->getOrganizationDomain($organizationId);
-            } elseif ($mode == self::MODE_DEV) {
-                $domain = $organization->getSubDomain() . '/';
-            } else {
-                throw new RuntimeException('Unknown value for $mode: ' . $mode);
-            }
-
-            $queryBuilder = $this->connectionPool->getQueryBuilderForTable('sys_domain');
-            $queryBuilder->insert('sys_domain')
-                ->values([
-                    'pid' => $rootUid,
-                    'domainName' => $domain
-                ])
-                ->execute();
-
             // update sys_template
             $constants = $this->getTemplateConstants($organizationId, $organizationExtraData);
 
@@ -518,7 +517,12 @@ class SiteController extends ActionController
                 ->execute();
 
             // Create the site config.yaml file
-            $this->writeConfigFile($organizationId, $rootUid, $domain, true);
+            $this->writeConfigFile(
+                $organizationId,
+                $rootUid,
+                $organization->getSubDomain() . '.opentalent.fr',
+                true
+            );
 
             // Create the user_upload and form_definitions directories and update the sys_filemounts table
             $uploadRelPath = "/user_upload/" . $organizationId;
@@ -638,10 +642,10 @@ class SiteController extends ActionController
      */
     public function updateSiteAction(int $organizationId, bool $deep=false): int
     {
-        $rootUid = $this->findRootUidFor($organizationId);
+        $website = $this->otWebsiteRepository->getWebsiteByOrganizationId($organizationId);
+        $rootUid = $this->otWebsiteRepository->getWebsiteRootUid($website['uid']);
 
         $organization = $this->fetchOrganization($organizationId);
-        $organizationDomain = $this->getOrganizationDomain($organizationId);
 
         // This extra-data can not be retrieved from the API for now, but
         // this shall be set up as soon as possible, to avoid requesting
@@ -653,19 +657,28 @@ class SiteController extends ActionController
 
         // keep tracks of the created folders and files to be able to remove them during a rollback
         try {
-            // ## Update the pages table (structure id, structure domain)
-            $sitePages = $this->otPageRepository->getAllSitePages($rootUid);
+
+            // ## Update the ot_website table
+            $queryBuilder = $this->connectionPool->getQueryBuilderForTable('ot_websites');
+            $queryBuilder->update('ot_websites')
+                ->set('subdomain', $organization->getSubDomain())
+                ->set('organization_name', $organization->getName())
+                ->where($queryBuilder->expr()->eq('uid', $website['uid']))
+                ->execute();
+            
+            // ## Update the root page's subpages
+            $sitePages = $this->otPageRepository->getAllSubpagesForPage($rootUid);
             foreach ($sitePages as $page) {
                 $queryBuilder = $this->connectionPool->getQueryBuilderForTable('pages');
                 $queryBuilder->update('pages')
-                    ->set('tx_opentalent_structure_id', $organizationId)
-                    ->set('tx_opentalent_structure_domain', $organizationDomain)
+                    ->set('ot_website_uid', $website['uid'])
                     ->where($queryBuilder->expr()->eq('uid', $page['uid']))
                     ->execute();
             }
 
             // ## Update the config.yaml file
             if ($deep) {
+                $organizationDomain = $this->otWebsiteRepository->getWebsiteDomain($rootUid);
                 $this->writeConfigFile($organizationId, $rootUid, $organizationDomain, true);
             }
 
@@ -682,7 +695,7 @@ class SiteController extends ActionController
             $queryBuilder = $this->connectionPool->getQueryBuilderForTable('pages');
             $queryBuilder
                 ->update('pages')
-                ->set('TSconfig', $this->getRootPageTsConfig($organization))
+                ->set('TSconfig', 'TCAdefaults.pages.ot_website_uid=' . $website['uid'])
                 ->where($queryBuilder->expr()->eq('uid', $rootUid))
                 ->execute();
 
@@ -691,9 +704,9 @@ class SiteController extends ActionController
                 $this->resetBeUserPermsAction($organizationId, true);
             }
 
-            // ## Reset the routing index
-            $routingIndexer = GeneralUtility::makeInstance(ObjectManager::class)->get(Indexer::class);
-            $routingIndexer->indexRoutesForWebsite($rootUid);
+//            // ## Reset the routing index
+//            $routingIndexer = GeneralUtility::makeInstance(ObjectManager::class)->get(Indexer::class);
+//            $routingIndexer->indexRoutesForWebsite($rootUid);
 
             // Try to commit the result
             $commitSuccess = $this->connectionPool->getConnectionByName('Default')->commit();
@@ -737,14 +750,17 @@ class SiteController extends ActionController
      * @throws \Doctrine\DBAL\DBALException
      * @throws \Throwable
      */
-    public function deleteSiteAction(int $organizationId, bool $hard=false, ?int $redirectTo=null, bool $force = false) {
-        $rootUid = $this->findRootUidFor($organizationId);
+    public function deleteSiteAction(int $organizationId, bool $hard=false, ?int $redirectTo=null, bool $force = false): int
+    {
+        $website = $this->otWebsiteRepository->getWebsiteByOrganizationId($organizationId);
+        $websiteUid = $website['uid'];
+        $rootUid = $this->otWebsiteRepository->getWebsiteRootUid($website['uid']);
 
         $queryBuilder = $this->connectionPool->getQueryBuilderForTable('pages');
         $isDeleted = $queryBuilder
             ->select('deleted')
-            ->from('pages')
-            ->where($queryBuilder->expr()->eq('uid', $rootUid))
+            ->from('ot_websites')
+            ->where($queryBuilder->expr()->eq('uid', $website['uid']))
             ->execute()
             ->fetchColumn(0) == 1;
 
@@ -762,8 +778,10 @@ class SiteController extends ActionController
             if ($redirectTo == $organizationId) {
                 throw new \InvalidArgumentException('redirectTo value has to be different from the organizationId');
             }
-            $originUrl = $this->getSiteInfosAction($organizationId)->getBaseUrl();
-            $targetUrl = $this->getSiteInfosAction($redirectTo)->getBaseUrl();
+            $originUrl = $this->otWebsiteRepository->getWebsiteDomain($websiteUid);
+
+            $targetOrganizationWebsite = $this->otWebsiteRepository->getWebsiteByOrganizationId($redirectTo);
+            $targetUrl = $this->otWebsiteRepository->getWebsiteDomain($targetOrganizationWebsite['uid']);
         }
 
         // start transactions
@@ -773,6 +791,7 @@ class SiteController extends ActionController
         $renamed = [];
 
         try {
+
             $pages = $this->otPageRepository->getAllSubpagesForPage($rootUid);
             foreach($pages as $page) {
                 $this->delete('tt_content', 'pid', $page['uid'], $hard);
@@ -780,12 +799,9 @@ class SiteController extends ActionController
             }
             $this->delete('tt_content', 'pid', $rootUid, $hard);
             $this->delete('pages', 'uid', $rootUid, $hard);
-            $this->delete('sys_template', 'pid', $rootUid, $hard);
 
-            if ($hard) {
-                // there is no 'deleted' field in sys_domain
-                $this->delete('sys_domain', 'pid', $rootUid, $hard);
-            }
+            $this->delete('sys_template', 'pid', $rootUid, $hard);
+            $this->delete('ot_websites', 'uid', $websiteUid, $hard);
 
             try {
                 $adminBeUserUid = $this->findAdminBeUserUid($rootUid);
@@ -974,8 +990,11 @@ class SiteController extends ActionController
      * @throws \Doctrine\DBAL\ConnectionException
      * @throws \Doctrine\DBAL\DBALException
      */
-    public function undeleteSiteAction(int $organizationId) {
-        $rootUid = $this->findRootUidFor($organizationId);
+    public function undeleteSiteAction(int $organizationId): int
+    {
+        $website = $this->otWebsiteRepository->getWebsiteByOrganizationId($organizationId, false);
+        $websiteUid = $website['uid'];
+        $rootUid = $this->otWebsiteRepository->getWebsiteRootUid($website['uid'], false);
 
         // start transactions
         $this->connectionPool->getConnectionByName('Default')->beginTransaction();
@@ -984,8 +1003,14 @@ class SiteController extends ActionController
         $renamed = [];
 
         try {
-            $pages = $this->otPageRepository->getAllSubpagesForPage($rootUid);
+            $queryBuilder = $this->connectionPool->getQueryBuilderForTable('tt_content');
+            $queryBuilder
+                ->update('ot_websites')
+                ->set('deleted', 0)
+                ->where($queryBuilder->expr()->eq('uid', $websiteUid))
+                ->execute();
 
+            $pages = $this->otPageRepository->getAllSubpagesForPage($rootUid);
             foreach($pages as $page) {
                 $queryBuilder = $this->connectionPool->getQueryBuilderForTable('tt_content');
                 $queryBuilder
@@ -1030,7 +1055,6 @@ class SiteController extends ActionController
                 ->where($queryBuilder->expr()->eq('path', "'/user_upload/" . $organizationId . "/'"))
                 ->execute();
 
-
             try {
                 $editorsGroupUid = $this->findEditorsBeGroupUid($rootUid, false);
                 if ($editorsGroupUid !== null) {
@@ -1128,7 +1152,7 @@ class SiteController extends ActionController
      */
     public function clearSiteCacheAction(int $organizationId, $clearAll=false): int
     {
-        $rootUid = $this->findRootUidFor($organizationId);
+        $rootUid = $this->otWebsiteRepository->findRootUidForOrganization($organizationId);
 
         OtCacheManager::clearSiteCache($rootUid, $clearAll);
 
@@ -1141,14 +1165,17 @@ class SiteController extends ActionController
      * @param int $organizationId
      * @param int $rootUid
      * @return array
+     * @throws NoSuchWebsiteException
      */
-    private function scanSite(int $organizationId, int $rootUid) {
+    private function scanSite(int $organizationId, int $rootUid): array
+    {
+        $website = $this->otWebsiteRepository->getWebsiteByOrganizationId($organizationId);
+        $rootUid = $this->otWebsiteRepository->getWebsiteRootUid($website['uid']);
 
         $warnings = [];
 
-        // fetch pages and root page
-        $pages = $this->otPageRepository->getAllSitePages($rootUid);
-
+        // fetch and index pages and root page
+        $pages = $this->otPageRepository->getPageWithSubpages($rootUid);
         $rootPage = null;
         $pageIndex = [];
         foreach ($pages as $page) {
@@ -1161,11 +1188,14 @@ class SiteController extends ActionController
         $extraData = $this->fetchOrganizationExtraData($organizationId);
 
         // load site's settings (uncomment if needed)
-        // $config = $this->findConfigFor($rootUid);
+        // $config = $this->otWebsiteRepository->findConfigFor($rootUid);
 
         // Check site's title
+        if (trim($website['organization_name']) != trim($organization->getName())) {
+            $warnings[] = "Website's organization name is different from what is registered in the Opentalent DB";
+        }
         if (trim($rootPage['title']) != trim($organization->getName())) {
-            $warnings[] = "Site's title does not match the organization name";
+            $warnings[] = "Root page's title does not match the organization name";
         }
 
         // Who is the expected owner among the be_users? there should be only one.
@@ -1265,6 +1295,7 @@ class SiteController extends ActionController
      * @param bool $fullScan If true, a 'warnings' entry will be added to the result, and a full scan of
      *                       the website pages will be performed.
      * @return SiteStatus
+     * @throws NoSuchWebsiteException
      */
     public function getSiteStatusAction(int $organizationId, bool $fullScan = false): SiteStatus
     {
@@ -1306,16 +1337,25 @@ class SiteController extends ActionController
      * @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
      * @throws NoSuchWebsiteException
      */
-    public function setSiteDomainAction(int $organizationId, string $newDomain, bool $redirect = true): int
+    public function setSiteCustomDomainAction(int $organizationId, string $newDomain, bool $redirect = true): int
     {
         if (!preg_match(self::RX_DOMAIN,$newDomain) &&
             !preg_match("/[a-z0-9A-Z-]+\//", $newDomain)) {
             throw new \InvalidArgumentException("The given domain does not seems to be a valid domain: " . $newDomain);
         }
 
-        $infos = $this->getSiteInfosAction($organizationId);
-        $originUrl = $infos->getBaseUrl();
-        $rootUid = $infos->getRootUid();
+        $website = $this->otWebsiteRepository->getWebsiteByOrganizationId($organizationId);
+        $websiteUid = $website['uid'];
+        $rootUid = $this->otWebsiteRepository->getWebsiteRootUid($websiteUid);
+
+        // ## Update the ot_website table
+        $queryBuilder = $this->connectionPool->getQueryBuilderForTable('ot_websites');
+        $queryBuilder->update('ot_websites')
+            ->set('custom_domain', $newDomain)
+            ->where($queryBuilder->expr()->eq('uid', $websiteUid))
+            ->execute();
+
+        $originUrl = $this->otWebsiteRepository->getWebsiteDomain($websiteUid);
 
         if (preg_replace('/https?:\/\//', '', $originUrl) == preg_replace('/https?:\/\//', '', $newDomain) ) {
             throw new \RuntimeException('The new domain should be different of the current one');
@@ -1508,7 +1548,7 @@ class SiteController extends ActionController
                                                         "and force the admin or group uid at the same time.");
         }
 
-        $rootUid = $this->findRootUidFor($organizationId);
+        $rootUid = $this->otWebsiteRepository->findRootUidForOrganization($organizationId);
 
         $organizationExtraData = $this->fetchOrganizationExtraData($organizationId);
         $isPremium = self::IS_PRODUCT_PREMIUM[$organizationExtraData['admin']['product']];
@@ -1589,7 +1629,7 @@ class SiteController extends ActionController
             ->execute();
 
         // fetch pages and root page
-        $pages = $this->otPageRepository->getAllSitePages($rootUid);
+        $pages = $this->otPageRepository->getPageWithSubpages($rootUid);
 
         // To understand how the rights levels are computed:
         // @see https://ressources.opentalent.fr/display/EX/Droits+des+BE+Users
@@ -1693,7 +1733,7 @@ class SiteController extends ActionController
      */
     public function updateRoutingIndexAction(int $organizationId)
     {
-        $rootUid = $this->findRootUidFor($organizationId);
+        $rootUid = $this->otWebsiteRepository->findRootUidForOrganization($organizationId);
 
         $routingIndexer = GeneralUtility::makeInstance(ObjectManager::class)->get(Indexer::class);
         $routingIndexer->indexRoutesForWebsite($rootUid);
@@ -1717,89 +1757,29 @@ class SiteController extends ActionController
     }
 
     /**
-     * Retrieves the current full domain of the given organization.
-     *
-     * @param int $organizationId
-     * @return string
-     */
-    private function getOrganizationDomain(int $organizationId): string
-    {
-        $queryBuilder = $this->connectionPool->getQueryBuilderForTable('pages');
-        $queryBuilder->getRestrictions()->removeAll();
-        $customDomain = $queryBuilder
-            ->select('domain')
-            ->from('tx_opentalent_custom_domains')
-            ->where($queryBuilder->expr()->eq('organization_id', $organizationId))
-            ->execute()
-            ->fetchColumn(0);
-
-        if ($customDomain) {
-            return $customDomain;
-        }
-
-        $organization = $this->fetchOrganization($organizationId);
-
-        return $organization->getSubDomain() . '.opentalent.fr';
-    }
-
-    /**
-     * Try to find the root page uid of the organization's website and return it.
-     * Throw a Opentalent\OtAdmin\NoSuchWebsiteException exception if the website does not exist.
+     * Insert a new row in the 'pages' table of the Typo3 DB
+     * and return its uid
      *
-     * @param $organizationId
+     * @param Organization $organization
      * @return int
-     * @throws NoSuchWebsiteException
      */
-    private function findRootUidFor($organizationId): int
+    private function insertOtWebsite(Organization $organization): int
     {
-        $queryBuilder = $this->connectionPool->getQueryBuilderForTable('pages');
-        $queryBuilder->getRestrictions()->removeAll();
-        $rows = $queryBuilder
-            ->select('uid')
-            ->from('pages')
-            ->where('is_siteroot=1')
-            ->andWhere($queryBuilder->expr()->eq('tx_opentalent_structure_id', $organizationId))
-            ->execute()
-            ->fetchAll();
-
-        if (count($rows) > 1) {
-            throw new \RuntimeException("More than one website match this organization id");
-        }
-
-        $rootUid = (int)$rows[0]['uid'];
-        if ($rootUid > 0) {
-            return $rootUid;
-        }
-        throw new NoSuchWebsiteException("No website found for organization " . $organizationId);
-    }
+        $values = [
+            'organization_id' => $organization->getId(),
+            'subdomain' => $organization->getSubDomain(),
+            'locale' => 'fr_FR',
+            'organization_name' => $organization->getName()
+        ];
 
-    /**
-     * Try to find the id of the organization owning this website.
-     *
-     * @param $rootUid
-     * @return int
-     * @throws NoSuchWebsiteException
-     */
-    private function findOrganizationIdUidFor($rootUid): int
-    {
-        $queryBuilder = $this->connectionPool->getQueryBuilderForTable('pages');
-        $queryBuilder->getRestrictions()->removeAll();
-        $organizationId = $queryBuilder
-            ->select('tx_opentalent_structure_id')
-            ->from('pages')
-            ->where('is_siteroot=1')
-            ->andWhere($queryBuilder->expr()->eq('uid', $rootUid))
-            ->execute()
-            ->fetchColumn(0);
+        $queryBuilder = $this->connectionPool->getQueryBuilderForTable('ot_websites');
+        $queryBuilder->insert('ot_websites')
+            ->values($values)
+            ->execute();
 
-        if ($organizationId > 0) {
-            return $organizationId;
-        }
-        throw new NoSuchWebsiteException("No organization found for website " . $rootUid);
+        return (int)$queryBuilder->getConnection()->lastInsertId();
     }
 
-
-
     /**
      * Determine which folder-type Typo3 page should contain the new website
      * CREATES IT if needed, and return its uid
@@ -1860,7 +1840,7 @@ class SiteController extends ActionController
      * @param array $moreValues
      * @return int
      */
-    private function insertPage(Organization $organization,
+    private function insertPage(int $website_uid,
                                 int $pid,
                                 string $title,
                                 string $slug,
@@ -1878,8 +1858,7 @@ class SiteController extends ActionController
             'slug' => $slug,
             'backend_layout' => 'flux__grid',
             'backend_layout_next_level' => 'flux__grid',
-            'tx_opentalent_structure_id' => $organization->getId(),
-            'tx_opentalent_structure_domain' => $this->getOrganizationDomain($organization->getId()),
+            'ot_website_uid' => $website_uid,
         ];
 
         if ($template) {
@@ -1907,17 +1886,17 @@ class SiteController extends ActionController
      * @param Organization $organization
      * @return int
      */
-    private function insertRootPage(Organization $organization): int
+    private function insertRootPage(int $website_uid, string $title): int
     {
         return $this->insertPage(
-            $organization,
+            $website_uid,
             $this->getParentFolderUid(),
-            $organization->getName(),
+            $title,
             '/',
             self::TEMPLATE_HOME,
             [
                 'is_siteroot' => 1,
-                'TSconfig' => $this->getRootPageTsConfig($organization),
+                'TSconfig' => 'TCAdefaults.pages.ot_website_uid=' . $website_uid,
                 'tx_opentalent_template' => self::DEFAULT_THEME,
                 'tx_opentalent_template_preferences' => '{"themeColor":"' . self::DEFAULT_COLOR . '","displayCarousel":"1"}'
             ]
@@ -2047,17 +2026,6 @@ class SiteController extends ActionController
             "}";
     }
 
-    /**
-     * Return the TSConfig for the root page of the given organization
-     *
-     * @param Organization $organization
-     * @return string
-     */
-    private function getRootPageTsConfig(Organization $organization): string {
-        return "TCAdefaults.pages.tx_opentalent_structure_id=" . $organization->getId() . "\r\n" .
-               "TCAdefaults.pages.tx_opentalent_structure_domain=" . $this->getOrganizationDomain($organization->getId());
-    }
-
     /**
      * Create the given directory, give its property to the www-data group and
      * record it as a newly created dir (for an eventual rollback)
@@ -2089,75 +2057,6 @@ class SiteController extends ActionController
         }
     }
 
-    /**
-     * Try to find the config file of the website in the less resource-consuming way
-     * and parse it.
-     *
-     * @param int $rootUid
-     * @return array   Path of the configuration file and parsed configuration of the website
-     */
-    protected function findConfigFileAndContentFor(int $rootUid): array
-    {
-        $configs_directory = $_ENV['TYPO3_PATH_APP'] . "/config/sites/";
-        $candidates = array_filter(
-                scandir($configs_directory),
-                function ($x) { return $x != '.' && $x != '..'; }
-            );
-
-        // try to filter by directory name
-        foreach ($candidates as $subdir) {
-            if (preg_match('/\.*_' . $rootUid . '$/', $subdir)) {
-                $filename = $configs_directory . $subdir . '/config.yaml';
-                try {
-                    $yamlConfig = Yaml::parseFile($filename);
-
-                    if ($yamlConfig['rootPageId'] === $rootUid) {
-                        return [$filename, $yamlConfig];
-                    }
-                } catch (\Symfony\Component\Yaml\Exception\ParseException $e) {
-                    continue;
-                }
-            }
-        }
-
-        // it wasn't found the easy way, let's look to each file... :(
-        foreach ($candidates as $subdir) {
-            $filename = $configs_directory . $subdir . '/config.yaml';
-            try {
-                $yamlConfig = Yaml::parseFile($filename);
-                if ($yamlConfig['rootPageId'] === $rootUid) {
-                    return [$filename, $yamlConfig];
-                }
-            } catch (\Symfony\Component\Yaml\Exception\ParseException $e) {
-                continue;
-            }
-        }
-
-        return [null, []];
-    }
-
-    /**
-     * Similar to findConfigFileAndContentFor(), but only returns the parsed configuration
-     * @param int $rootUid
-     * @return array   Configuration of the website
-     */
-    protected function findConfigFor(int $rootUid): array
-    {
-        $pathAndConfig = $this->findConfigFileAndContentFor($rootUid);
-        return $pathAndConfig[1];
-    }
-
-    /**
-     * Similar to findConfigFileAndContentFor(), but only returns the config file path
-     * @param int $rootUid
-     * @return string   Path of the config file of the given website
-     */
-    protected function findConfigFilePathFor(int $rootUid): string
-    {
-        $pathAndConfig = $this->findConfigFileAndContentFor($rootUid);
-        return $pathAndConfig[0];
-    }
-
     /**
      * Create or update the .../sites/.../config.yaml file of the given site
      *
@@ -2168,7 +2067,7 @@ class SiteController extends ActionController
      */
     private function writeConfigFile(int $organizationId, int $rootUid, string $domain, bool $forceRecreate = false): void
     {
-        $existing = $this->findConfigFileAndContentFor($rootUid);
+        $existing = $this->otWebsiteRepository->findConfigFileAndContentFor($rootUid);
         $configFilename = $existing[0];
         $config = $existing[1];
 
@@ -2450,9 +2349,9 @@ class SiteController extends ActionController
 
         // [For retrocompatibility] Try to find if there is a be_user still in the v8.7 data format
         if ($adminUid == null) {
-            $organizationId = $this->findOrganizationIdUidFor($rootUid);
+            $website = $this->otWebsiteRepository->getWebsiteByPageUid($rootUid);
 
-            $extraData = $this->fetchOrganizationExtraData($organizationId);
+            $extraData = $this->fetchOrganizationExtraData($website['organization_id']);
             $expectedUsername = $extraData['admin']['username'];
 
             $queryBuilder = $this->connectionPool->getQueryBuilderForTable('be_users');

+ 2 - 2
ot_admin/Classes/Http/ApiController.php

@@ -273,7 +273,7 @@ class ApiController implements LoggerAwareInterface
      * @return JsonResponse
      * @throws \Exception
      */
-    public function setSiteDomainAction(ServerRequest $request): JsonResponse
+    public function setSiteCustomDomainAction(ServerRequest $request): JsonResponse
     {
         $this->assertIpAllowed();
 
@@ -287,7 +287,7 @@ class ApiController implements LoggerAwareInterface
         $redirect = (isset($queryParams['redirect']) && $queryParams['redirect']);
 
         $controller = GeneralUtility::makeInstance(ObjectManager::class)->get(SiteController::class);
-        $rootUid = $controller->setSiteDomainAction($organizationId, $domain, $redirect);
+        $rootUid = $controller->setSiteCustomDomainAction($organizationId, $domain, $redirect);
 
         return new JsonResponse(
             [

+ 1 - 1
ot_admin/Configuration/Backend/Routes.php

@@ -34,7 +34,7 @@ return [
     ],
     'site_setdomain' => [
         'path' => '/otadmin/site/set-domain',
-        'target' => ApiController::class . '::setSiteDomainAction',
+        'target' => ApiController::class . '::setSiteCustomDomainAction',
         'access' => 'public'
     ],
     'site_resetperms' => [

+ 0 - 4
ot_admin/Readme.md

@@ -9,10 +9,6 @@ This extension provides commands available by the API, CLI, or a dedicated admin
 | Vendor | Opentalent |
 | Nom | OtAdmin |
 
-**IMPORTANT**:
-
-* Cette extension dépend de l'extension OtRouter
-
 ## CLI
 
 Pour exécuter une commande depuis la console 

+ 15 - 0
ot_core/Classes/Exception/InvalidWebsiteConfigurationException.php

@@ -0,0 +1,15 @@
+<?php
+
+
+namespace Opentalent\OtCore\Exception;
+
+
+use Exception;
+
+/**
+ * Class NoSuchWebsite
+ * Raise this exception when website has no domain defined in db
+ *
+ * @package Opentalent\OtCore\Exception
+ */
+class InvalidWebsiteConfigurationException extends Exception {}

+ 3 - 3
ot_core/Classes/Website/OtPageRepository.php

@@ -125,13 +125,13 @@ class OtPageRepository
     /**
      * Returns all the pages of the given page's website, starting from the root page
      *
-     * @param int $rootUid
+     * @param int $pageUid
      * @param bool $withRestrictions Set to true to add the standard restrictions (deleted, forbidden...etc.)
      * @return array
      */
-    public function getAllSitePages(int $rootUid, bool $withRestrictions=false): array
+    public function getPageWithSubpages(int $pageUid, bool $withRestrictions=false): array
     {
-        return array_merge([$this->getPage($rootUid)], $this->getAllSubpagesForPage($rootUid));
+        return array_merge([$this->getPage($pageUid)], $this->getAllSubpagesForPage($pageUid));
     }
 
     /**

+ 166 - 9
ot_core/Classes/Website/OtWebsiteRepository.php

@@ -2,8 +2,15 @@
 
 namespace Opentalent\OtCore\Website;
 
-use TYPO3\CMS\Extbase\Persistence\Generic\Qom\Join;
+use Opentalent\OtCore\Exception\InvalidWebsiteConfigurationException;
+use Opentalent\OtCore\Exception\NoSuchWebsiteException;
+use Symfony\Component\Yaml\Yaml;
 
+/**
+ * Repository for the ot_websites table
+ *
+ * @package Opentalent\OtCore\Website
+ */
 class OtWebsiteRepository
 {
     /**
@@ -16,50 +23,84 @@ class OtWebsiteRepository
         $this->connectionPool = $connectionPool;
     }
 
+    /**
+     * Get an OtWebsite by uid
+     *
+     * @throws NoSuchWebsiteException
+     */
     public function getWebsiteByUid(int $uid, bool $withRestrictions = true): array
     {
         $queryBuilder = $this->connectionPool->getQueryBuilderForTable('ot_websites');
         if (!$withRestrictions) {
             $queryBuilder->getRestrictions()->removeAll();
         }
-        return $queryBuilder
+        $website = $queryBuilder
             ->select('*')
             ->from('ot_websites')
             ->where($queryBuilder->expr()->eq('uid', $uid))
             ->execute()
             ->fetch();
+        if (!isset($website['uid'])) {
+            throw new NoSuchWebsiteException('No website found for organization ' . $organizationId);
+        }
+        return $website;
     }
 
+    /**
+     * Get the OtWebsite of the given organization
+     *
+     * @throws NoSuchWebsiteException
+     */
     public function getWebsiteByOrganizationId(int $organizationId, bool $withRestrictions = true): array
     {
         $queryBuilder = $this->connectionPool->getQueryBuilderForTable('ot_websites');
         if (!$withRestrictions) {
             $queryBuilder->getRestrictions()->removeAll();
         }
-        return $queryBuilder
+        $website = $queryBuilder
             ->select('*')
             ->from('ot_websites')
             ->where($queryBuilder->expr()->eq('organization_id', $organizationId))
             ->execute()
             ->fetch();
+        if (!isset($website['uid'])) {
+            throw new NoSuchWebsiteException('No website found for organization ' . $organizationId);
+        }
+        return $website;
     }
 
+    /**
+     * Get the OtWebsite of the given page
+     *
+     * @throws NoSuchWebsiteException
+     */
     public function getWebsiteByPageUid(int $pageUid, bool $withRestrictions = true): array
     {
-        $queryBuilder = $this->connectionPool->getQueryBuilderForTable('pages');
+        $queryBuilder = $this->connectionPool->getQueryBuilderForTable('ot_websites');
         if (!$withRestrictions) {
             $queryBuilder->getRestrictions()->removeAll();
         }
-        return $queryBuilder
+        $website = $queryBuilder
             ->select('w.*')
             ->from('ot_websites', 'w')
             ->innerJoin('w', 'pages', 'p', $queryBuilder->expr()->eq('p.ot_website_uid', 'w.uid'))
             ->where($queryBuilder->expr()->eq('p.uid', $pageUid))
             ->execute()
             ->fetch();
+        if (!isset($website['uid'])) {
+            throw new NoSuchWebsiteException('No website found for page ' . $pageUid);
+        }
+        return $website;
     }
 
-    public function getWebsiteRootUid(int $websiteUid, bool $withRestrictions = true): array {
+    /**
+     * Get the root page uid of the given OtWebsite
+     *
+     * @param int $websiteUid
+     * @param bool $withRestrictions
+     * @return int
+     */
+    public function getWebsiteRootUid(int $websiteUid, bool $withRestrictions = true): int {
         $queryBuilder = $this->connectionPool->getQueryBuilderForTable('ot_websites');
         if (!$withRestrictions) {
             $queryBuilder->getRestrictions()->removeAll();
@@ -73,11 +114,42 @@ class OtWebsiteRepository
             ->fetchColumn(0);
     }
 
+    /**
+     * Try to find the root page uid of the organization's website and return it.
+     * Throw a Opentalent\OtAdmin\NoSuchWebsiteException exception if the website does not exist.
+     *
+     * @param int $organizationId
+     * @param bool $withRestrictions
+     * @return int
+     * @throws NoSuchWebsiteException
+     */
+    public function findRootUidForOrganization(int $organizationId, bool $withRestrictions = true): int
+    {
+        $queryBuilder = $this->connectionPool->getQueryBuilderForTable('pages');
+        if (!$withRestrictions) {
+            $queryBuilder->getRestrictions()->removeAll();
+        }
+        $rootUid = $queryBuilder
+            ->select('p.uid')
+            ->from('pages', 'p')
+            ->innerJoin('p', 'ot_websites', 'w', $queryBuilder->expr()->eq('p.ot_website_uid', 'w.uid'))
+            ->where($queryBuilder->expr()->eq('w.organization_id', $organizationId))
+            ->andWhere($queryBuilder->expr()->eq('p.is_siteroot', 1))
+            ->execute()
+            ->fetchColumn(0);
+        if (!$rootUid) {
+            throw new NoSuchWebsiteException("No website found for organization " . $organizationId);
+        }
+        return $rootUid;
+    }
+
     /**
      * Retrieves the current full domain of the given website.
      *
      * @param int $websiteUid
      * @return string
+     * @throws InvalidWebsiteConfigurationException
+     * @throws NoSuchWebsiteException
      */
     public function getWebsiteDomain(int $websiteUid): string
     {
@@ -85,21 +157,106 @@ class OtWebsiteRepository
 
         if ($website['custom_domain']) {
             return $website['custom_domain'];
+        } else if ($website['subdomain']) {
+            return $website['subdomain'] . '.opentalent.fr';
         }
-
-        return $website['subdomain'] . '.opentalent.fr';
+        throw new InvalidWebsiteConfigurationException("No domain defined for website " . $website['uid']);
     }
 
+    /**
+     * Get the website current base uri
+     *
+     * @param int $websiteUid
+     * @return string
+     * @throws InvalidWebsiteConfigurationException
+     * @throws NoSuchWebsiteException
+     */
     public function getWebsiteBaseUri(int $websiteUid): string
     {
         return 'https://' . $this->getWebsiteDomain($websiteUid);
     }
 
-    public function getWebsiteConfiguration(int $rootUid, string $domain): array {
+    /**
+     * Generate an array as it would be loaded from the site.yaml configuration
+     * file of the given website
+     *
+     * @param int $rootUid
+     * @param string $domain
+     * @return array
+     */
+    public function generateWebsiteConfiguration(int $rootUid, string $domain): array {
         return [
+
         ];
     }
 
+    /**
+     * Try to find the config file of the website in the less resource-consuming way
+     * and parse it.
+     *
+     * @param int $rootUid
+     * @return array   Path of the configuration file and parsed configuration of the website
+     */
+    public function findConfigFileAndContentFor(int $rootUid): array
+    {
+        $configs_directory = $_ENV['TYPO3_PATH_APP'] . "/config/sites/";
+        $candidates = array_filter(
+            scandir($configs_directory),
+            function ($x) { return $x != '.' && $x != '..'; }
+        );
+
+        // try to filter by directory name
+        foreach ($candidates as $subdir) {
+            if (preg_match('/\.*_' . $rootUid . '$/', $subdir)) {
+                $filename = $configs_directory . $subdir . '/config.yaml';
+                try {
+                    $yamlConfig = Yaml::parseFile($filename);
+
+                    if ($yamlConfig['rootPageId'] === $rootUid) {
+                        return [$filename, $yamlConfig];
+                    }
+                } catch (\Symfony\Component\Yaml\Exception\ParseException $e) {
+                    continue;
+                }
+            }
+        }
+
+        // it wasn't found the easy way, let's look to each file... :(
+        foreach ($candidates as $subdir) {
+            $filename = $configs_directory . $subdir . '/config.yaml';
+            try {
+                $yamlConfig = Yaml::parseFile($filename);
+                if ($yamlConfig['rootPageId'] === $rootUid) {
+                    return [$filename, $yamlConfig];
+                }
+            } catch (\Symfony\Component\Yaml\Exception\ParseException $e) {
+                continue;
+            }
+        }
+
+        return [null, []];
+    }
 
+    /**
+     * Similar to findConfigFileAndContentFor(), but only returns the parsed configuration
+     *
+     * @param int $rootUid
+     * @return array   Configuration of the website
+     */
+    public function findConfigFor(int $rootUid): array
+    {
+        $pathAndConfig = $this->findConfigFileAndContentFor($rootUid);
+        return $pathAndConfig[1];
+    }
 
+    /**
+     * Similar to findConfigFileAndContentFor(), but only returns the config file path
+     * @param int $rootUid
+     * @return string   Path of the config file of the given website
+     */
+    public function findConfigFilePathFor(int $rootUid): string
+    {
+        $pathAndConfig = $this->findConfigFileAndContentFor($rootUid);
+        return $pathAndConfig[0];
+    }
 }

+ 59 - 0
ot_optimizer/Classes/XClass/Routing/FeRouter.php

@@ -0,0 +1,59 @@
+<?php
+namespace Opentalent\OtCore\Middleware;
+
+use Opentalent\OtCore\Routing\Resolver;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Object\ObjectManager;
+use TYPO3\CMS\Frontend\Controller\ErrorController;
+use TYPO3\CMS\Frontend\Page\PageAccessFailureReasons;
+
+/**
+ * Hooks into the frontend request and use the index table to resolve a page uid
+ *
+ * @internal
+ */
+class FeRouter implements MiddlewareInterface
+{
+    /**
+     *
+     * @param ServerRequestInterface $request
+     * @param RequestHandlerInterface $handler
+     * @return ResponseInterface
+     */
+    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
+    {
+//        if (TYPO3_MODE === 'FE') {
+//            $uri = $request->getUri();
+//            $resolver = GeneralUtility::makeInstance(ObjectManager::class)->get(Resolver::class);
+//            if ($_SERVER['TYPO3_CONTEXT'] == 'Development') {
+//                $pageUid = $resolver->resolveDevRoute(
+//                    $uri->getPath()
+//                );
+//            } else {
+//                $pageUid = $resolver->resolveRoute(
+//                    $uri->getHost(),
+//                    $uri->getPath(),
+//                );
+//            }
+//
+//            if ($pageUid) {
+//                $params = $request->getQueryParams();
+//                $params['id'] = $pageUid;
+//                $request = $request->withQueryParams($params);
+//            } else {
+//                return GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
+//                    $request,
+//                    'The requested page does not exist',
+//                    ['code' => PageAccessFailureReasons::PAGE_NOT_FOUND]
+//                );
+//            }
+//        }
+
+        // just pass the plate to the next middleware...
+        return $handler->handle($request);
+    }
+}

+ 0 - 0
ot_optimizer/Classes/Routing/OtPageRouter.php → ot_optimizer/Classes/XClass/Routing/OtPageRouter.php


+ 0 - 39
ot_router/Classes/Middleware/Router.php

@@ -1,39 +0,0 @@
-<?php
-namespace Opentalent\OtRouter\Middleware;
-
-use Opentalent\OtRouter\Routing\Resolver;
-use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\ServerRequestInterface;
-use Psr\Http\Server\MiddlewareInterface;
-use Psr\Http\Server\RequestHandlerInterface;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Extbase\Object\ObjectManager;
-
-/**
- * Hooks into the frontend request and use the index table to resolve a page uid
- *
- * @internal
- */
-class Router implements MiddlewareInterface
-{
-    /**
-     *
-     * @param ServerRequestInterface $request
-     * @param RequestHandlerInterface $handler
-     * @return ResponseInterface
-     */
-    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
-    {
-        $uri = $request->getUri();
-
-        $resolver = GeneralUtility::makeInstance(ObjectManager::class)->get(Resolver::class);
-
-        $pageUid = $resolver->getPageUid(
-            $uri->getHost(),
-            $uri->getPath(),
-        );
-
-        // just pass the plate to the next middleware...
-        return $handler->handle($request);
-    }
-}

+ 0 - 106
ot_router/Classes/Routing/Indexer.php

@@ -1,106 +0,0 @@
-<?php
-
-namespace Opentalent\OtRouter\Routing;
-
-use Opentalent\OtCore\Page\OtPageRepository;
-use Opentalent\OtRouter\Utility\RouteNormalizer;
-use TYPO3\CMS\Core\Database\ConnectionPool;
-
-/**
- * Provides methods to index the Typo3 pages and populate the routing db table
- *
- * @package Opentalent\OtRouter\Routing
- */
-class Indexer
-{
-    const INDEX_TABLENAME = 'tx_opentalent_router';
-
-    /**
-     * @var ConnectionPool
-     */
-    private ConnectionPool $connectionPool;
-
-    public function injectConnectionPool(ConnectionPool $connectionPool)
-    {
-        $this->connectionPool = $connectionPool;
-    }
-
-    /**
-     * @var OtPageRepository
-     */
-    protected OtPageRepository $otPageRepository;
-
-    public function injectOtPageRepository(OtPageRepository $otPageRepository) {
-        $this->otPageRepository = $otPageRepository;
-    }
-
-    /**
-     * Clear then repopulate the whole index
-     */
-    public function indexAllRoutes() {
-        $queryBuilder = $this->connectionPool->getQueryBuilderForTable('pages');
-        $rootPages = $queryBuilder
-            ->select('uid')
-            ->from('pages')
-            ->where($queryBuilder->expr()->eq('is_siteroot', 1))
-            ->execute()
-            ->fetchAll();
-
-        foreach ($rootPages as $rootPage) {
-            $this->indexRoutesForWebsite($rootPage);
-        }
-    }
-
-    /**
-     * Clear and recreate the index entry for the target website
-     *
-     * @param int $rootUid
-     */
-    public function indexRoutesForWebsite(int $rootUid) {
-        foreach ($this->otPageRepository->getAllSitePages($rootUid) as $page) {
-            $this->registerIndexEntry(
-                $page['uid'],
-                $page['tx_opentalent_structure_domain'],
-                $page['slug'],
-                $rootUid
-            );
-        }
-    }
-
-    public function indexRouteForPage(int $pageUid) {
-        $page = $this->otPageRepository->getPage($pageUid);
-        $rootPage = $this->otPageRepository->getRootPageFor($pageUid);
-
-        $this->registerIndexEntry(
-            $page['uid'],
-            $page['tx_opentalent_structure_domain'],
-            $page['slug'],
-            $rootPage['uid']
-        );
-    }
-
-    private function registerIndexEntry(int $pageUid,
-                                      string $domain,
-                                      string $slug,
-                                      ?int $rootUid = null) {
-        $queryBuilder = $this->connectionPool->getQueryBuilderForTable(self::INDEX_TABLENAME);
-        $queryBuilder
-            ->delete(self::INDEX_TABLENAME)
-            ->where($queryBuilder->expr()->eq('page_uid', $pageUid))
-            ->execute();
-
-        $entry = [
-            'domain' => RouteNormalizer::normalizeDomain($domain),
-            'root_uid' => $rootUid,
-            'slug' => RouteNormalizer::normalizeSlug($slug),
-            'page_uid' => $pageUid,
-            'last_update' => date('Y-m-d H:i:s')
-        ];
-
-        $queryBuilder = $this->connectionPool->getQueryBuilderForTable(self::INDEX_TABLENAME);
-        $queryBuilder
-            ->insert(self::INDEX_TABLENAME)
-            ->values($entry)
-            ->execute();
-    }
-}

+ 0 - 18
ot_router/Configuration/RequestMiddlewares.php

@@ -1,18 +0,0 @@
-<?php
-
-/**
- * Register middlewares, which will be triggered at each request
- */
-return [
-    'frontend' => [
-        'logout-rewriter' => [
-            'target' => Opentalent\OtRouter\Middleware\Router::class,
-            'before' => [
-                'typo3/cms-adminpanel/data-persister'
-            ],
-            'after' => [
-                'typo3/cms-adminpanel/renderer'
-            ],
-        ],
-    ],
-];

+ 0 - 14
ot_router/Readme.md

@@ -1,14 +0,0 @@
-# OtRouter
-
-Bypass the builtin Typo3 routing with dedicated router adapted to a large amount of websites
-
-|||
-|---|---|
-| Extension key | ot_router |
-| Vendor | Opentalent |
-| Nom | OtRouter |
-
-Cette extension implémente un système de routing basé sur un index des pages sous forme de table additionnelle dans la
-base de données.
-
-Pour plus d'informations: <https://ressources.opentalent.fr/pages/viewpage.action?pageId=11481740>

BIN
ot_router/Resources/Public/Icons/Extension.png


+ 0 - 28
ot_router/composer.json

@@ -1,28 +0,0 @@
-{
-    "name": "opentalent/ot-router",
-    "type": "typo3-cms-extension",
-    "description": "Bypass the builtin Typo3 routing with dedicated router adapted to a large amount of websites",
-    "authors": [
-        {
-            "name": "Olivier Massot",
-            "role": "Developer"
-        }
-    ],
-    "require": {
-        "typo3/cms-core": "^9.5"
-    },
-    "autoload": {
-        "psr-4": {
-            "Opentalent\\OtRouter\\": "Classes"
-        }
-    },
-    "autoload-dev": {
-        "psr-4": {
-            "Opentalent\\OtRouter\\Tests\\": "Tests"
-        }
-    },
-    "replace": {
-        "ot_router": "self.version",
-        "typo3-ter/ot-router": "self.version"
-    }
-}

+ 0 - 29
ot_router/ext_emconf.php

@@ -1,29 +0,0 @@
-<?php
-
-/***************************************************************
- * Extension Manager/Repository config file for ext: "ot_optimizer"
- *
- * Manual updates:
- * Only the data in the array - anything else is removed by next write.
- * "version" and "dependencies" must not be touched!
- ***************************************************************/
-
-$EM_CONF[$_EXTKEY] = [
-    'title' => 'Router',
-    'description' => 'Bypass the builtin Typo3 routing with dedicated router adapted to a large amount of websites',
-    'category' => 'services',
-    'author' => 'Olivier Massot',
-    'author_email' => 'olivier.massot@2iopenservice.fr',
-    'state' => 'alpha',
-    'uploadfolder' => 0,
-    'createDirs' => '',
-    'clearCacheOnLoad' => 0,
-    'version' => '0.1.0',
-    'constraints' => [
-        'depends' => [
-            'typo3' => '8.7.0-10.4.99',
-        ],
-        'conflicts' => [],
-        'suggests' => [],
-    ],
-];

+ 0 - 15
ot_router/ext_tables.sql

@@ -1,15 +0,0 @@
-# ext_tables.sql contient les directives permettant d ajouter des tables et champs à la DB
-
-#
-# Table structure for table 'tx_opentalent_router'
-#
-CREATE TABLE tx_opentalent_router (
-    uid INT UNSIGNED NOT NULL AUTO_INCREMENT,
-    domain VARCHAR(2048) NOT NULL,
-    root_uid INT UNSIGNED NOT NULL,
-    slug VARCHAR(2048) NOT NULL,
-    page_uid INT UNSIGNED NOT NULL,
-    last_update DATETIME NOT NULL,
-    PRIMARY KEY (uid)
-);
-