diff --git a/Classes/Utility/TemplateDirectivesService.php b/Classes/Utility/TemplateDirectivesService.php
index 45d78a1..b899d2c 100644
--- a/Classes/Utility/TemplateDirectivesService.php
+++ b/Classes/Utility/TemplateDirectivesService.php
@@ -30,9 +30,9 @@ class TemplateDirectivesService
* ignoreUids=777,888 : list of uids to ignore
*
* @param string $lineFromConstant The constant line
- * @return void
+ * @return true
*/
- public function lookForDirectives(string $lineFromConstant): void
+ public function lookForDirectives(string $lineFromConstant): bool
{
// Remove all spaces and line feed from input line
$inputLine = trim(str_replace(' ', '', $lineFromConstant));
@@ -47,7 +47,9 @@ public function lookForDirectives(string $lineFromConstant): void
$this->directives[$matchDirective[$i]] = $matchDirective[$i + 1];
}
}
+ return true;
}
+ return false;
}
/**
diff --git a/Classes/Utility/TemplateService.php b/Classes/Utility/TemplateService.php
index 0d90cf9..e45b6af 100644
--- a/Classes/Utility/TemplateService.php
+++ b/Classes/Utility/TemplateService.php
@@ -14,16 +14,26 @@
namespace Oktopuce\SiteGenerator\Utility;
use Doctrine\DBAL\Exception;
+use Oktopuce\SiteGenerator\Dto\BaseDto;
+use Oktopuce\SiteGenerator\Wizard\Event\UpdateTyposcriptContentEvent;
+use Psr\EventDispatcher\EventDispatcherInterface;
+use Psr\Log\LogLevel;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
+use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\Utility\GeneralUtility;
// Cf. app/vendor/typo3/cms-tstemplate/Classes/Controller/ConstantEditorController.php
class TemplateService
{
- public function __construct(private readonly ConnectionPool $connectionPool)
+ public function __construct(
+ private readonly EventDispatcherInterface $eventDispatcher,
+ private readonly ConnectionPool $connectionPool,
+ private readonly TemplateDirectivesService $templateDirectivesService,
+ private readonly DataHandler $dataHandler
+ )
{
}
@@ -79,8 +89,8 @@ public function calculateConstantPositions(
$operatorPosition = strcspn($line, ' {=<');
$key = substr($line, 0, $operatorPosition);
$line = ltrim(substr($line, $operatorPosition));
- if ($line[0] === '=') {
- $constantPositions[$prefix . $key] = $lineCounter - 1;
+ if ($line[0] === '=' || $line[0] === ':') {
+ $constantPositions[$prefix . $key . "_" . $lineCounter] = $lineCounter - 1;
} elseif ($line[0] === '{') {
$braceLevel++;
$this->calculateConstantPositions($rawTemplateConstantsArray, $constantPositions, $prefix . $key . '.', $braceLevel, $lineCounter);
@@ -114,4 +124,154 @@ public function updateValueInConf(string $rawConstant, string $var): string
}
return implode('=', $parts);
}
+
+ /**
+ * @param string $table Name database table
+ * @param array $record Record data to update
+ * @param string $contentField Name of field which contains the content to update
+ * @param BaseDto $siteData
+ * @return bool true if content was update, false if no data was updated
+ */
+ public function updateContent(string $table, array $record, string $contentField, BaseDto $siteData): bool
+ {
+ $rawTemplateConstantsArray = explode(LF, $record[$contentField] ?? '');
+ $constantPositions = $this->calculateConstantPositions($rawTemplateConstantsArray);
+
+ $updatedTemplateConstantsArray = [];
+ $directivesPositions = [];
+
+ // For all constants, check if we need to update it
+ foreach ($constantPositions as $key => $rawP) {
+ // Looking for directives in comments
+ if($this->templateDirectivesService->lookForDirectives(($rawP > 0 ? $rawTemplateConstantsArray[$rawP - 1] : ''))) {
+ $directivesPositions[] = $rawP - 1;
+ };
+
+ $value = GeneralUtility::trimExplode('=', $rawTemplateConstantsArray[$rawP]);
+
+ $uidsToExclude = GeneralUtility::trimExplode(',',
+ $this->templateDirectivesService->getIgnoreUids(), true);
+ $filteredMapping = $mapping = $siteData->getMappingArrayMerge(
+ $this->templateDirectivesService->getTable('pages')
+ );
+
+ // Manage uids to exclude
+ if (!empty($uidsToExclude)) {
+ $filteredMapping = array_filter($mapping, static function ($key) use ($uidsToExclude) {
+ return !in_array((string)$key, $uidsToExclude, true);
+ }, ARRAY_FILTER_USE_KEY);
+ }
+
+ $action = $this->templateDirectivesService->getAction('mapInList');
+ $updatedValue = '';
+
+ switch ($action) {
+ case 'mapInList' :
+ $updatedValue = $this->mapInList($value[1], $filteredMapping);
+ break;
+ case 'mapInString' :
+ $updatedValue = $this->mapInString($value[1], $filteredMapping);
+ break;
+ case 'exclude' :
+ // Exclude all line
+ break;
+ default :
+ // Call custom action if there is one
+ $parameters = $this->templateDirectivesService->getParameters();
+ $event = $this->eventDispatcher->dispatch(new UpdateTyposcriptContentEvent($action, $parameters,
+ $value[1], $filteredMapping, $this->templateDirectivesService));
+ $updatedValue = $event->getUpdatedValue();
+ break;
+ }
+
+ if (!empty($updatedValue)) {
+ $updatedTemplateConstantsArray[$rawP] = $updatedValue;
+ }
+ }
+
+ if ($updatedTemplateConstantsArray) {
+ foreach ($updatedTemplateConstantsArray as $rowP => $updatedTemplateConstant) {
+ $rawTemplateConstantsArray[$rowP] = $this->updateValueInConf($rawTemplateConstantsArray[$rowP], $updatedTemplateConstant);
+ }
+ if($GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['site_generator']['removeDirectivesFromOutput'] ?? true) {
+ // Remove directives from output
+ $rawTemplateConstantsArray = array_diff_key($rawTemplateConstantsArray, array_flip($directivesPositions));
+ }
+
+ // Set the data to be saved
+ $recordData = [];
+ $recordUid = $record['_ORIG_uid'] ?? $record['uid'];
+ $recordData[$table][$recordUid][$contentField] = implode(LF, $rawTemplateConstantsArray);
+ // Create new tce-object
+ $this->dataHandler->start($recordData, []);
+ $this->dataHandler->process_datamap();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Update constant in list
+ *
+ * @param string $value
+ * @param array $filteredMapping
+ * @return string Empty string or value updated
+ */
+ protected function mapInList(
+ string $value,
+ array $filteredMapping
+ ): string {
+ $functionName = '';
+ // Check if the value in constant is a list of int - 78,125,98 - or just an int
+ if (preg_match('/^\\s*([[:alpha:]]+)\\s*\\((.*)\\).*/', $value, $match)) {
+ $functionName = $match[1];
+ $value = $match[2];
+ }
+ if (preg_match('/^\d+(?:,\d+)*$/', $value)) {
+ $updateConstant = false;
+
+ $listOfInt = GeneralUtility::trimExplode(',', $value, true);
+
+ // Set new uid for constants
+ array_walk($listOfInt,
+ static function (&$constantValue) use ($filteredMapping, &$updateConstant) {
+ if (isset($filteredMapping[(int)$constantValue])) {
+ $constantValue = $filteredMapping[(int)$constantValue];
+ $updateConstant = true;
+ }
+ });
+ if ($updateConstant) {
+ $newList = implode(',', $listOfInt);
+ if($functionName) {
+ $newList = "$functionName($newList)";
+ }
+ return $newList;
+ }
+ }
+ return ('');
+ }
+
+ /**
+ * Update constants in string
+ *
+ * @param string $value
+ * @param array $filteredMapping
+ * @return string Empty string or value updated
+ */
+ protected function mapInString(
+ string $value,
+ array $filteredMapping
+ ): string {
+ $updateConstant = false;
+ $count = 0;
+
+ foreach ($filteredMapping as $modelUid => $siteUid) {
+ $value = str_replace((string)$modelUid, (string)$siteUid, $value, $count);
+ $updateConstant = ($updateConstant || $count > 0);
+ }
+ if ($updateConstant) {
+ return ($value);
+ }
+ return ('');
+ }
}
diff --git a/Classes/Wizard/Event/AbstractUpdateTyposcriptContentEvent.php b/Classes/Wizard/Event/AbstractUpdateTyposcriptContentEvent.php
new file mode 100644
index 0000000..b5b68d3
--- /dev/null
+++ b/Classes/Wizard/Event/AbstractUpdateTyposcriptContentEvent.php
@@ -0,0 +1,130 @@
+action = $action;
+ $this->parameters = $parameters;
+ $this->value = $value;
+ $this->filteredMapping = $filteredMapping;
+ $this->templateDirectivesService = $templateDirectivesService;
+ }
+
+ /**
+ * @return string
+ */
+ public function getAction(): string
+ {
+ return $this->action;
+ }
+
+ /**
+ * @return string
+ */
+ public function getParameters(): string
+ {
+ return $this->parameters;
+ }
+
+ /**
+ * @return string
+ */
+ public function getValue(): string
+ {
+ return $this->value;
+ }
+
+ /**
+ * @return array
+ */
+ public function getFilteredMapping(): array
+ {
+ return $this->filteredMapping;
+ }
+
+ /**
+ * @return TemplateDirectivesService
+ */
+ public function getTemplateDirectivesService(): TemplateDirectivesService
+ {
+ return $this->templateDirectivesService;
+ }
+
+ /**
+ * Get the updated value
+ *
+ * @return string Empty if no update required otherwise the value to update
+ */
+ public function getUpdatedValue(): string
+ {
+ return $this->updatedValue;
+ }
+
+ /**
+ * Set the updated value
+ *
+ * @param string $updatedValue The value to update
+ * @return void
+ */
+ public function setUpdatedValue(string $updatedValue): void
+ {
+ $this->updatedValue = $updatedValue;
+ }
+}
diff --git a/Classes/Wizard/Event/UpdateTemplateHPEvent.php b/Classes/Wizard/Event/UpdateTemplateHPEvent.php
index 625fe96..552f66d 100644
--- a/Classes/Wizard/Event/UpdateTemplateHPEvent.php
+++ b/Classes/Wizard/Event/UpdateTemplateHPEvent.php
@@ -13,118 +13,8 @@
namespace Oktopuce\SiteGenerator\Wizard\Event;
-use Oktopuce\SiteGenerator\Utility\TemplateDirectivesService;
-
/**
* This event is fired when state StateUpdateTemplateHP is executed and action is a custom action
* i.e. : different from : mapInList, mapInString or exclude
*/
-final class UpdateTemplateHPEvent
-{
- /**
- * @var string
- */
- private string $updatedValue = '';
-
- /**
- * @var string
- */
- private string $action;
-
- /**
- * @var string
- */
- private string $parameters;
-
- /**
- * @var array
- */
- private array $filteredMapping;
-
- /**
- * @var string
- */
- private string $value;
-
- /**
- * @var TemplateDirectivesService
- */
- private TemplateDirectivesService $templateDirectivesService;
-
- /**
- * @param string $action The action
- * @param string $parameters The parameter
- * @param string $value Current value
- * @param array $filteredMapping Mapping filtered - i.e. ignoredUids already removed
- * @param TemplateDirectivesService $templateDirectivesService
- */
- public function __construct(string $action, string $parameters, string $value, array $filteredMapping, TemplateDirectivesService $templateDirectivesService)
- {
- $this->action = $action;
- $this->parameters = $parameters;
- $this->value = $value;
- $this->filteredMapping = $filteredMapping;
- $this->templateDirectivesService = $templateDirectivesService;
- }
-
- /**
- * @return string
- */
- public function getAction(): string
- {
- return $this->action;
- }
-
- /**
- * @return string
- */
- public function getParameters(): string
- {
- return $this->parameters;
- }
-
- /**
- * @return string
- */
- public function getValue(): string
- {
- return $this->value;
- }
-
- /**
- * @return array
- */
- public function getFilteredMapping(): array
- {
- return $this->filteredMapping;
- }
-
- /**
- * @return TemplateDirectivesService
- */
- public function getTemplateDirectivesService(): TemplateDirectivesService
- {
- return $this->templateDirectivesService;
- }
-
- /**
- * Get the updated value
- *
- * @return string Empty if no update required otherwise the value to update
- */
- public function getUpdatedValue(): string
- {
- return $this->updatedValue;
- }
-
- /**
- * Set the updated value
- *
- * @param string $updatedValue The value to update
- * @return void
- */
- public function setUpdatedValue(string $updatedValue): void
- {
- $this->updatedValue = $updatedValue;
- }
-}
+final class UpdateTemplateHPEvent extends AbstractUpdateTyposcriptContentEvent {}
diff --git a/Classes/Wizard/Event/UpdateTyposcriptContentEvent.php b/Classes/Wizard/Event/UpdateTyposcriptContentEvent.php
new file mode 100644
index 0000000..dc31287
--- /dev/null
+++ b/Classes/Wizard/Event/UpdateTyposcriptContentEvent.php
@@ -0,0 +1,20 @@
+getMappingArrayMerge('pages') as $pageId) {
@@ -58,6 +63,12 @@ protected function updatePageTS(BaseDto $siteData): void
// Get record data
$origRow = BackendUtility::getRecord('pages', $pageId);
+ if($this->templateService->updateContent('pages', $origRow, 'TSconfig', $siteData)) {
+ $pagesUpdatedOnIdentifiers[] = $pageId;
+ // Get record data
+ $origRow = BackendUtility::getRecord('pages', $pageId);
+ }
+
if ($origRow['TSconfig']) {
$newsTSConfig = '';
$line = strtok($origRow['TSconfig'], PHP_EOL);
@@ -100,5 +111,11 @@ protected function updatePageTS(BaseDto $siteData): void
// @extensionScannerIgnoreLine
$siteData->addMessage($this->translate('generate.success.updatePageTS', [implode(',', $pagesUpdated)]));
}
+
+ if (!empty($pagesUpdatedOnIdentifiers)) {
+ $this->log(LogLevel::NOTICE, 'Update page TSConfig : updating identifiers done for pages : ' . implode(',', $pagesUpdatedOnIdentifiers));
+ // @extensionScannerIgnoreLine
+ $siteData->addMessage($this->translate('generate.success.updatePageTSonIdentifiers', [implode(',', $pagesUpdatedOnIdentifiers)]));
+ }
}
}
diff --git a/Classes/Wizard/StateUpdateTemplateHP.php b/Classes/Wizard/StateUpdateTemplateHP.php
index f9ba216..11a5c02 100644
--- a/Classes/Wizard/StateUpdateTemplateHP.php
+++ b/Classes/Wizard/StateUpdateTemplateHP.php
@@ -13,14 +13,9 @@
namespace Oktopuce\SiteGenerator\Wizard;
-use Oktopuce\SiteGenerator\Utility\TemplateDirectivesService;
-use Psr\EventDispatcher\EventDispatcherInterface;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
use Psr\Log\LogLevel;
-use TYPO3\CMS\Core\DataHandling\DataHandler;
use Oktopuce\SiteGenerator\Dto\BaseDto;
use Oktopuce\SiteGenerator\Utility\TemplateService;
-use Oktopuce\SiteGenerator\Wizard\Event\UpdateTemplateHPEvent;
/**
* StateUpdateTemplate
@@ -28,17 +23,12 @@
class StateUpdateTemplateHP extends StateBase implements SiteGeneratorStateInterface
{
/**
- * @param TemplateDirectivesService $templateDirectivesService
- * @param EventDispatcherInterface $eventDispatcher
* @param TemplateService $templateService
- * @param DataHandler $dataHandler
*/
public function __construct(
- readonly protected TemplateDirectivesService $templateDirectivesService,
- readonly protected EventDispatcherInterface $eventDispatcher,
- readonly protected TemplateService $templateService,
- readonly protected DataHandler $dataHandler
- ) {
+ readonly protected TemplateService $templateService
+ )
+ {
parent::__construct();
}
@@ -64,133 +54,12 @@ protected function updateTemplate(BaseDto $siteData): void
{
// Cf. app/vendor/typo3/cms-tstemplate/Classes/Controller/ConstantEditorController.php
$allTemplatesOnPage = $this->templateService->getAllTemplateRecordsOnPage($siteData->getHpPid());
-
foreach ($allTemplatesOnPage as $template) {
- $rawTemplateConstantsArray = explode(LF, $template['constants']);
- $constantPositions = $this->templateService->calculateConstantPositions($rawTemplateConstantsArray);
-
- $updatedTemplateConstantsArray = [];
-
- // For all constants, check if we need to update it
- foreach ($constantPositions as $key => $rawP) {
- // Looking for directives in comments
- $this->templateDirectivesService->lookForDirectives(($rawP > 0 ? $rawTemplateConstantsArray[$rawP - 1] : ''));
- $table = $this->templateDirectivesService->getTable('pages');
-
- $value = GeneralUtility::trimExplode('=', $rawTemplateConstantsArray[$rawP]);
-
- $uidsToExclude = GeneralUtility::trimExplode(',',
- $this->templateDirectivesService->getIgnoreUids(), true);
- $filteredMapping = $mapping = $siteData->getMappingArrayMerge($table);
-
- // Manage uids to exclude
- if (!empty($uidsToExclude)) {
- $filteredMapping = array_filter($mapping, static function ($key) use ($uidsToExclude) {
- return !in_array((string)$key, $uidsToExclude, true);
- }, ARRAY_FILTER_USE_KEY);
- }
-
- $action = $this->templateDirectivesService->getAction('mapInList');
- $updatedValue = '';
-
- switch ($action) {
- case 'mapInList' :
- $updatedValue = $this->mapInList($value[1], $filteredMapping);
- break;
- case 'mapInString' :
- $updatedValue = $this->mapInString($value[1], $filteredMapping);
- break;
- case 'exclude' :
- // Exclude all line
- break;
- default :
- // Call custom action if there is one
- $parameters = $this->templateDirectivesService->getParameters();
- $event = $this->eventDispatcher->dispatch(new UpdateTemplateHPEvent($action, $parameters,
- $value[1], $filteredMapping, $this->templateDirectivesService));
- $updatedValue = $event->getUpdatedValue();
- break;
- }
-
- if (!empty($updatedValue)) {
- $updatedTemplateConstantsArray[$rawP] = $updatedValue;
- }
- }
-
- if ($updatedTemplateConstantsArray) {
- foreach ($updatedTemplateConstantsArray as $rowP => $updatedTemplateConstant) {
- $rawTemplateConstantsArray[$rowP] = $this->templateService->updateValueInConf($rawTemplateConstantsArray[$rowP], $updatedTemplateConstant);
- }
-
- // Set the data to be saved
- $recordData = [];
- $templateUid = $template['_ORIG_uid'] ?? $template['uid'];
- $recordData['sys_template'][$templateUid]['constants'] = implode(LF, $rawTemplateConstantsArray);
- // Create new tce-object
- $this->dataHandler->start($recordData, []);
- $this->dataHandler->process_datamap();
-
+ if($this->templateService->updateContent('sys_template', $template, 'constants', $siteData)) {
// @extensionScannerIgnoreLine
$siteData->addMessage($this->translate('generate.success.templateHpUpdated'));
$this->log(LogLevel::NOTICE, 'Update home page template with new uids done');
- }
- }
- }
-
- /**
- * Update constant in list
- *
- * @param string $value
- * @param array $filteredMapping
- * @return string Empty string or value updated
- */
- protected function mapInList(
- string $value,
- array $filteredMapping
- ): string {
- // Check if the value in constant is a list of int - 78,125,98 - or just an int
- if (preg_match('/^\d+(?:,\d+)*$/', $value)) {
- $updateConstant = false;
-
- $listOfInt = GeneralUtility::trimExplode(',', $value, true);
-
- // Set new uid for constants
- array_walk($listOfInt,
- static function (&$constantValue) use ($filteredMapping, &$updateConstant) {
- if (isset($filteredMapping[(int)$constantValue])) {
- $constantValue = $filteredMapping[(int)$constantValue];
- $updateConstant = true;
- }
- });
-
- if ($updateConstant) {
- return implode(',', $listOfInt);
- }
- }
- return ('');
- }
-
- /**
- * Update constants in string
- *
- * @param string $value
- * @param array $filteredMapping
- * @return string Empty string or value updated
- */
- protected function mapInString(
- string $value,
- array $filteredMapping
- ): string {
- $updateConstant = false;
- $count = 0;
-
- foreach ($filteredMapping as $modelUid => $siteUid) {
- $value = str_replace((string)$modelUid, (string)$siteUid, $value, $count);
- $updateConstant = ($updateConstant || $count > 0);
- }
- if ($updateConstant) {
- return ($value);
+ };
}
- return ('');
}
-}
+}
\ No newline at end of file
diff --git a/Documentation/Administrators/UpdateTemplate/Index.rst b/Documentation/Administrators/UpdateTemplate/Index.rst
index 4f1b13f..f4ec74b 100644
--- a/Documentation/Administrators/UpdateTemplate/Index.rst
+++ b/Documentation/Administrators/UpdateTemplate/Index.rst
@@ -35,7 +35,7 @@ Sample
# Map all values in the string and exclude some of them
# ext=SiteGenerator; table=tt_content; action=mapInString; ignoreUids=29,30
- multipleCeWithIgnore = addInList(28,29,30)
+ multipleCeWithIgnore := addInList(28,29,30)
# For custom action you must used the event UpdateTemplateHPEvent
# ext=SiteGenerator; action=customAction; parameters=custom parameters
diff --git a/Resources/Private/Language/locallang.xlf b/Resources/Private/Language/locallang.xlf
index 59e0ef0..dd644d3 100644
--- a/Resources/Private/Language/locallang.xlf
+++ b/Resources/Private/Language/locallang.xlf
@@ -80,6 +80,9 @@
- Update page TSConfig (TCEMAIN.clearCacheCmd) done for pages : %s
+
+ - Update page TSConfig on identifiers done for pages : %s
+
- The site configuration for domain '%s' has been created
diff --git a/ext_conf_template.txt b/ext_conf_template.txt
index b8cdb1a..ade3d15 100644
--- a/ext_conf_template.txt
+++ b/ext_conf_template.txt
@@ -8,6 +8,7 @@
# customsubcategory=140=Folder
# customsubcategory=150=BE Group access lists
# customsubcategory=160=Site configuration
+# customsubcategory=170=TypoScript code update
# cat=Basic/100/10_ModelPid; type=string; label=Models PID: Models page uid used to generate the new site (comma separated for multiple models)
modelsPid =
@@ -21,6 +22,10 @@ commonMountPointUid =
# cat=Basic/120/10_OneForm; type=boolean; label=Only one form page for data: Check this if you want only one form page to gather data
onlyOneFormPage = false
+# cat=Basic/170/10_RemoveDirectivesFromOutput; type=boolean; label=Remove update directives from output: Check this if you don't want update directives in the output
+removeDirectivesFromOutput = true
+
+
# cat=Label/130/10_PageTitle; type=string; label=Home page title: The title used for the home page (can be overridden in form)
homePageTitle = Home