| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539 |
- <?php
- namespace Opentalent\OtAdmin\Controller;
- use Opentalent\OtTemplating\Domain\Model\Organization;
- use Opentalent\OtTemplating\Domain\Repository\OrganizationRepository;
- use Opentalent\OtTemplating\Exception\ApiRequestException;
- use Psr\Log\LoggerAwareInterface;
- use Symfony\Component\Yaml\Yaml;
- use TYPO3\CMS\Core\Database\ConnectionPool;
- use TYPO3\CMS\Core\Utility\GeneralUtility;
- use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
- use TYPO3\CMS\Extbase\Object\ObjectManager;
- /**
- * The SiteController implements some admin-only operations
- * on Typo3 websites, like creation or update.
- */
- class SiteController extends ActionController
- {
- // Templates names
- const TEMPLATE_HOME = "OpenTalent.OtTemplating->home";
- const TEMPLATE_1COL = "OpenTalent.OtTemplating->1Col";
- const TEMPLATE_3COL = "OpenTalent.OtTemplating->home";
- const TEMPLATE_EVENTS = "OpenTalent.OtTemplating->events";
- const TEMPLATE_STRUCTURESEVENTS = "OpenTalent.OtTemplating->structuresEvents";
- const TEMPLATE_STRUCTURES = "OpenTalent.OtTemplating->structures";
- const TEMPLATE_CONTACT = "OpenTalent.OtTemplating->contact";
- const TEMPLATE_NEWS = "OpenTalent.OtTemplating->news";
- const TEMPLATE_MEMBERS = "OpenTalent.OtTemplating->members";
- const TEMPLATE_MEMBERSCA = "OpenTalent.OtTemplating->membersCa";
- const TEMPLATE_E404 = "OpenTalent.OtTemplating->e404";
- // Pages dokType values
- const DOK_PAGE = 1;
- const DOK_SHORTCUT = 4;
- const DOK_FOLDER = 116;
- // Contents CTypes
- const CTYPE_TEXT = 'text';
- const CTYPE_IMAGE = 'image';
- const CTYPE_TEXTPIC = 'textpic';
- const CTYPE_TEXTMEDIA = 'textmedia';
- const CTYPE_HTML = 'html';
- const CTYPE_HEADER = 'header';
- const CTYPE_UPLOADS = 'uploads';
- const CTYPE_LIST = 'list';
- const CTYPE_SITEMAP = 'menu_sitemap';
- // const DEFAULT_ROOT_PID = 134833;
- const DEFAULT_ROOT_PID = 11;
- // Default values
- const DEFAULT_THEME = 'Classic';
- const DEFAULT_COLOR = 'light-blue';
- /**
- * Doctrine connection pool
- * @var object|LoggerAwareInterface|\TYPO3\CMS\Core\SingletonInterface
- */
- private $cnnPool;
- /**
- * Index of the pages created
- * >> [slug => uid]
- * @var array
- */
- private $createdPagesIndex;
- public function __construct()
- {
- parent::__construct();
- $this->cnnPool = GeneralUtility::makeInstance(ConnectionPool::class);
- $this->createdPagesIndex = [];
- }
- /**
- * Creates a new website for the given organization, and
- * returns the root page uid of the newly created site
- *
- * @param int $organizationId
- * @return int Uid of the root page of the newly created website
- * @throws \RuntimeException
- */
- public function createSiteAction(int $organizationId) {
- // ** Get the organization object from the Opentalent API
- $manager = GeneralUtility::makeInstance(ObjectManager::class);
- $organizationRepository = GeneralUtility::makeInstance(
- OrganizationRepository::class,
- $manager
- );
- try {
- $organization = $organizationRepository->findById($organizationId);
- } catch (ApiRequestException $e) {
- throw new \RuntimeException('Unable to fetch the organization with id: ' . $organizationId);
- }
- // ** Test the existence of a website with this name and or organization id
- // Is there a site with this organization's name?
- $queryBuilder = $this->cnnPool->getQueryBuilderForTable('pages');
- $queryBuilder
- ->select('uid')
- ->from('pages')
- ->where($queryBuilder->expr()->eq('title', $queryBuilder->createNamedParameter($organization->getName())))
- ->andWhere('is_siteroot=1');
- $statement = $queryBuilder->execute();
- if ($statement->rowCount() > 0) {
- throw new \RuntimeException('A website with this name already exists: ' . $organization->getName());
- }
- // Is there a site with this organization's id?
- $queryBuilder = $this->cnnPool->getQueryBuilderForTable('pages');
- $statement = $queryBuilder
- ->select('uid')
- ->from('pages')
- ->where($queryBuilder->expr()->eq('tx_opentalent_structure_id', $queryBuilder->createNamedParameter($organization->getId())))
- ->andWhere('is_siteroot=1')
- ->execute();
- if ($statement->rowCount() > 0) {
- throw new \RuntimeException("A website with this organization's id already exists: " . $organization->getName());
- }
- // ** Create the new website
- // start transactions
- $tables = ['be_users', 'pages', 'sys_domain', 'sys_template', 'tt_content'];
- foreach ($tables as $table) {
- $this->cnnPool->getConnectionForTable($table)->beginTransaction();
- }
- $pages = [];
- try {
- // Create the site pages:
- // > Root page
- $rootUid = $this->insertRootPage($organization);
- // > 'Accueil' shortcut
- $this->insertPage(
- $organization,
- $rootUid,
- 'Accueil',
- '/accueil',
- '',
- [
- 'dokType' => self::DOK_SHORTCUT,
- 'shortcut' => $rootUid
- ]
- );
- // > 'Présentation' page
- $this->insertPage(
- $organization,
- $rootUid,
- 'Présentation',
- '/presentation'
- );
- // > 'Présentation > Qui sommes nous?' page (hidden by default)
- $this->insertPage(
- $organization,
- $this->createdPagesIndex['/presentation'],
- 'Qui sommes nous?',
- '/qui-sommes-nous',
- '',
- ['hidden' => 1]
- );
- // > 'Présentation > Les adhérents' page
- $this->insertPage(
- $organization,
- $this->createdPagesIndex['/presentation'],
- 'Les adhérents',
- '/les-adherents',
- self::TEMPLATE_MEMBERS
- );
- // > 'Présentation > Les membres du CA' page
- $this->insertPage(
- $organization,
- $this->createdPagesIndex['/presentation'],
- 'Les membres du CA',
- '/les-membres-du-ca',
- self::TEMPLATE_MEMBERSCA
- );
- // > 'Présentation > Historique' page (hidden by default)
- $this->insertPage(
- $organization,
- $this->createdPagesIndex['/presentation'],
- 'Historique',
- '/historique',
- '',
- ['hidden' => 1]
- );
- // > 'Actualités' page (hidden by default)
- $this->insertPage(
- $organization,
- $rootUid,
- 'Actualités',
- '/actualites',
- self::TEMPLATE_NEWS
- );
- // > 'Saison en cours' page
- $this->insertPage(
- $organization,
- $rootUid,
- 'Saison en cours',
- '/saison-en-cours'
- );
- // > 'Saison en cours > Les évènements' page
- $this->insertPage(
- $organization,
- $this->createdPagesIndex['/saison-en-cours'],
- 'Les évènements',
- '/les-evenements',
- self::TEMPLATE_EVENTS
- );
- // > 'Vie interne' page (restricted, hidden by default)
- $this->insertPage(
- $organization,
- $rootUid,
- 'Vie interne',
- '/vie-interne',
- '',
- [
- 'hidden' => 1,
- 'fe_group' => -2
- ]
- );
- // > 'Footer' page (not in the menu)
- $this->insertPage(
- $organization,
- $rootUid,
- 'Footer',
- '/footer',
- '',
- [
- 'dokType' => self::DOK_FOLDER,
- 'nav_hide' => 1
- ]
- );
- // > 'Footer > Contact' page
- $this->insertPage(
- $organization,
- $this->createdPagesIndex['/footer'],
- 'Contact',
- '/contact',
- self::TEMPLATE_CONTACT
- );
- // > 'Footer > Plan du site' page
- $this->insertPage(
- $organization,
- $this->createdPagesIndex['/footer'],
- 'Plan du site',
- '/plan-du-site'
- );
- // > 'Footer > Mentions légales' page
- $this->insertPage(
- $organization,
- $this->createdPagesIndex['/footer'],
- 'Mentions légales',
- '/mentions-legales'
- );
- // > 'Page introuvable' page (not in the menu, read-only)
- $this->insertPage(
- $organization,
- $rootUid,
- 'Page introuvable',
- '/page-introuvable',
- self::TEMPLATE_E404,
- [
- 'nav_hide' => 1,
- 'no_search' => 1
- ]
- );
- // Add content to these pages
- // >> root page content
- $this->insertContent(
- $rootUid,
- self::CTYPE_TEXTPIC,
- '<h1>Bienvenue sur le site de ' . $organization->getName() . '.</h1>',
- 0
- );
- // >> page 'qui sommes nous?'
- $this->insertContent(
- $this->createdPagesIndex['/qui-sommes-nous'],
- self::CTYPE_TEXT,
- 'Qui sommes nous ...',
- 0
- );
- // >> page 'historique'
- $this->insertContent(
- $this->createdPagesIndex['/historique'],
- self::CTYPE_TEXT,
- "Un peu d'histoire ...",
- 0
- );
- // >> page 'plan du site'
- $this->insertContent(
- $this->createdPagesIndex['/plan-du-site'],
- self::CTYPE_SITEMAP
- );
- // >> page 'mentions légales'
- $this->insertContent(
- $this->createdPagesIndex['/mentions-legales'],
- self::CTYPE_TEXT,
- '<p style="margin-bottom: 0cm"><b>Mentions Légales</b></p>',
- 0
- );
- // Build and update the domain
- $domain = $organization->getSubDomain() . '.opentalent.fr';
- $queryBuilder = $this->cnnPool->getQueryBuilderForTable('sys_domain');
- $queryBuilder->insert('sys_domain')
- ->values([
- 'pid' => $rootUid,
- 'domainName' => $domain
- ])
- ->execute();
- // Create the template
- $constants = "plugin.tx_ottemplating {" .
- " settings {" .
- " organization {" .
- " id = " . $organization->getId() .
- " name = " . $organization->getName() .
- " is_network = " . (1 ? $organization->getIsNetwork() : 0) .
- " email = " . $organization->getEmail() .
- " logoid = " . explode('/', $organization->getLogo(), -1)[0] .
- " twitter = " . $organization->getTwitter() .
- " facebook = " . $organization->getFacebook() .
- " }" .
- " network {" .
- " logo = " . $organization->getNetworkLogo() .
- " name = CMF" . $organization->getNetworkName() .
- " url = " . $organization->getNetworkUrl() .
- " }" .
- " }" .
- "}" .
- $queryBuilder = $this->cnnPool->getQueryBuilderForTable('sys_template');
- $queryBuilder->insert('sys_template')
- ->values([
- 'pid' => $rootUid,
- 'title' => $organization->getName(),
- 'sitetitle' => $organization->getName(),
- 'root' => 1,
- 'clear' => 3,
- 'include_static_file' => 'EXT:fluid_styled_content/Configuration/TypoScript/,EXT:fluid_styled_content/Configuration/TypoScript/Styling/,EXT:ot_widgets/Configuration/TypoScript,EXT:form/Configuration/TypoScript/,EXT:news/Configuration/TypoScript,EXT:ot_templating/Configuration/TypoScript',
- 'constants' => $constants
- ])
- ->execute();
- // Create the site config.yaml file
- $config = ['base'=> 'https://' . $domain,
- 'baseVariants'=>[],
- 'errorHandling'=>[
- ['errorCode'=>'404',
- 'errorHandler'=>'Page',
- 'errorContentSource'=>'t3://page?uid=' . $this->createdPagesIndex['/page-introuvable']],
- ['errorCode'=>'403',
- 'errorHandler'=>'Page',
- 'errorContentSource'=>'t3://page?uid=' . $this->createdPagesIndex['/page-introuvable']]
- ],
- 'flux_content_types'=>'',
- 'flux_page_templates'=>'',
- 'languages'=>[[
- 'title'=>'Fr',
- 'enabled'=>True,
- 'base'=>'/',
- 'typo3Language'=>'fr',
- 'locale'=>'fr_FR',
- 'iso-639-1'=>'fr',
- 'navigationTitle'=>'Fr',
- 'hreflang'=>'fr-FR',
- 'direction'=>'ltr',
- 'flag'=>'fr',
- 'languageId'=>'0',
- ]],
- 'rootPageId'=>$rootUid,
- 'routes'=>[]
- ];
- $yamlConfig = Yaml::dump($config, 4);
-
- // Create the contact form
- $contscatForm = "";
- // Create the BE user
- // Create the user_upload directory
- // throw new \Exception('not implemented');
- // Try to commit the result
- foreach ($tables as $table) {
- $commitSuccess = $this->cnnPool->getConnectionForTable($table)->commit();
- if (!$commitSuccess) {
- throw new \RuntimeException('Something went wrong while commiting the result');
- }
- }
- return $rootUid;
- } catch(\Exception $e) {
- // rollback
- foreach ($tables as $table) {
- $this->cnnPool->getConnectionForTable($table)->rollback();
- }
- throw $e;
- }
- }
- /**
- * Insert a new row in the 'pages' table of the Typo3 DB
- *
- * @param Organization $organization
- * @param int $pid
- * @param string $title
- * @param string $slug
- * @param string $template
- * @param array $moreValues
- * @return string
- */
- private function insertPage(Organization $organization,
- int $pid,
- string $title,
- string $slug,
- string $template = '',
- array $moreValues = []
- ) {
- $defaultValues = [
- 'pid' => $pid,
- 'perms_groupid' => 3,
- 'perms_user' => 27,
- 'cruser_id' => 1,
- 'dokType' => self::DOK_PAGE,
- 'title' => $title,
- 'slug' => $slug,
- 'backend_layout' => 'flux__grid',
- 'backend_layout_next_level' => 'flux__grid',
- 'tx_opentalent_structure_id' => $organization->getId()
- ];
- if ($template) {
- $defaultValues['tx_fed_page_controller_action'] = $template;
- $defaultValues['tx_fed_page_controller_action_sub'] = self::TEMPLATE_1COL;
- }
- $values = array_merge($defaultValues, $moreValues);
- $queryBuilder = $this->cnnPool->getQueryBuilderForTable('pages');
- $queryBuilder->insert('pages')
- ->values($values)
- ->execute();
- $uid = $queryBuilder->getConnection()->lastInsertId();
- $this->createdPagesIndex[$slug] = $uid;
- return $uid;
- }
- /**
- * Insert the root page of a new organization's website
- *
- * @param Organization $organization
- * @return string
- */
- private function insertRootPage(Organization $organization) {
- return $this->insertPage(
- $organization,
- self::DEFAULT_ROOT_PID,
- $organization->getName(),
- '/',
- self::TEMPLATE_HOME,
- [
- 'is_siteroot' => 1,
- 'TSconfig' => 'TCAdefaults.pages.tx_opentalent_structure_id =' . $organization->getId(),
- 'tx_opentalent_template' => self::DEFAULT_THEME,
- 'tx_opentalent_template_preferences' => '{"themeColor":"' . self::DEFAULT_COLOR . '","displayCarousel":"1"}'
- ]
- );
- }
- /**
- * Insert a new row in the 'tt_content' table of the Typo3 DB
- *
- * @param int $pid
- * @param string $cType
- * @param string $bodyText
- * @param int $colPos
- * @param array $moreValues
- */
- private function insertContent(int $pid,
- string $cType=self::CTYPE_TEXT,
- string $bodyText = '',
- int $colPos=0,
- array $moreValues = []) {
- $defaultValues = [
- 'pid' => $pid,
- 'cruser_id' => 1,
- 'CType' => $cType,
- 'colPos' => $colPos,
- 'bodyText' => $bodyText
- ];
- $values = array_merge($defaultValues, $moreValues);
- $queryBuilder = $this->cnnPool->getQueryBuilderForTable('tt_content');
- $queryBuilder->insert('tt_content')
- ->values($values)
- ->execute();
- }
- }
|