From 58379678dfe8b6d0e3ca5a4c90e8a5c494b16cda Mon Sep 17 00:00:00 2001 From: doishub Date: Mon, 17 Jan 2022 16:42:48 +0100 Subject: [PATCH 01/48] Initial commit (bundle config) --- composer.json | 1 + src/DependencyInjection/Configuration.php | 31 +++++ .../ContaoComponentStyleManagerExtension.php | 24 ++++ src/Resources/contao/classes/StyleManager.php | 63 +++++++++- src/Resources/contao/classes/Sync.php | 114 ++++++++++++------ .../contao/widgets/ComponentStyleSelect.php | 107 +++++++++++----- 6 files changed, 272 insertions(+), 68 deletions(-) create mode 100644 src/DependencyInjection/Configuration.php create mode 100644 src/DependencyInjection/ContaoComponentStyleManagerExtension.php diff --git a/composer.json b/composer.json index 444d8c0..6c90bb8 100644 --- a/composer.json +++ b/composer.json @@ -18,6 +18,7 @@ } ], "require":{ + "ext-dom": "*", "contao/core-bundle":"^4.4" }, "require-dev": { diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php new file mode 100644 index 0000000..1ae0107 --- /dev/null +++ b/src/DependencyInjection/Configuration.php @@ -0,0 +1,31 @@ +getRootNode(); + } else { + // Backwards compatibility + $rootNode = $treeBuilder->root('contao_component_style_manager'); + } + + $rootNode + ->children() + ->booleanNode('use_bundle_config') + ->defaultTrue() + ->end() + ->end() + ; + + return $treeBuilder; + } +} diff --git a/src/DependencyInjection/ContaoComponentStyleManagerExtension.php b/src/DependencyInjection/ContaoComponentStyleManagerExtension.php new file mode 100644 index 0000000..f860c98 --- /dev/null +++ b/src/DependencyInjection/ContaoComponentStyleManagerExtension.php @@ -0,0 +1,24 @@ +processConfiguration(new Configuration(), $configs); + + $loader = new YamlFileLoader( + $container, + new FileLocator(__DIR__ . '/../Resources/config') + ); + + $container->setParameter('contao_component_style_manager.use_bundle_config', $config['use_bundle_config']); + } +} diff --git a/src/Resources/contao/classes/StyleManager.php b/src/Resources/contao/classes/StyleManager.php index 4ca5feb..725c990 100644 --- a/src/Resources/contao/classes/StyleManager.php +++ b/src/Resources/contao/classes/StyleManager.php @@ -8,8 +8,11 @@ namespace Oveleon\ContaoComponentStyleManager; use Contao\Backend; +use Contao\Controller; use Contao\CoreBundle\DataContainer\PaletteManipulator; use Contao\StringUtil; +use Contao\System; +use Contao\TemplateLoader; use Contao\Widget; class StyleManager @@ -376,6 +379,64 @@ public static function deserializeValues($arrValue){ return $arrValue; } + /** + * Load configuration files from third-party bundles and return them as array + */ + public static function loadBundleConfiguration(): ?array + { + if($arrFiles = self::getBundleConfigurationFiles()) + { + $sync = new Sync(); + return $sync->importStyleManagerFile($arrFiles, false); + } + + return null; + } + + /** + * Return all configuration files from third-party bundles + */ + public static function getBundleConfigurationFiles(): ?array + { + $arrFiles = Controller::getContainer()->get('contao.resource_finder')->findIn('templates')->files()->name('style-manager-*.xml'); + + if($arrFiles->hasResults()) + { + $projectDir = System::getContainer()->getParameter('kernel.project_dir'); + $arrBundleConfigs = null; + + foreach ($arrFiles as $file) + { + $strRelpath = $file->getRealPath(); + $arrBundleConfigs[basename($strRelpath)] = str_replace($projectDir, '', $strRelpath); + } + + return $arrBundleConfigs; + } + + return null; + } + + /** + * Check whether an element is visible in style manager widget + */ + public static function isVisibleGroup(StyleManagerModel $objGroup, string $strTable): bool + { + if( + 'tl_layout' === $strTable && !!$objGroup->extendLayout || + 'tl_page' === $strTable && !!$objGroup->extendPage || + 'tl_module' === $strTable && !!$objGroup->extendModule || + 'tl_article' === $strTable && !!$objGroup->extendArticle || + 'tl_form' === $strTable && !!$objGroup->extendForm || + 'tl_form_field' === $strTable && !!$objGroup->extendFormFields || + 'tl_content' === $strTable && !!$objGroup->extendContentElement || + 'tl_news' === $strTable && !!$objGroup->extendNews || + 'tl_calendar_events' === $strTable && !!$objGroup->extendEvents + ){ return true; } + + return false; + } + /** * Parse Template and set Variables * @@ -447,7 +508,7 @@ public function listFormFields($arrRow) * * @return bool */ - public function addVariableRegexp($strRegexp, $varValue, Widget $objWidget) + public function addVariableRegexp($strRegexp, $varValue, Widget $objWidget): bool { if ($strRegexp == 'variable') { diff --git a/src/Resources/contao/classes/Sync.php b/src/Resources/contao/classes/Sync.php index 2f5d7b7..f1d43e4 100644 --- a/src/Resources/contao/classes/Sync.php +++ b/src/Resources/contao/classes/Sync.php @@ -7,7 +7,20 @@ namespace Oveleon\ContaoComponentStyleManager; -class Sync extends \Backend +use ContainerFDoeHNy\get_ServiceLocator_ZcNHns_Contao_Fragment_Contao_ContentElement_MarkdownService; +use Contao\Backend; +use Contao\Config; +use Contao\DataContainer; +use Contao\Environment; +use Contao\File; +use Contao\FileUpload; +use Contao\Input; +use Contao\Message; +use Contao\Model\Collection; +use Contao\StringUtil; +use Contao\System; + +class Sync extends Backend { /** * @var string @@ -20,7 +33,7 @@ class Sync extends \Backend public function __construct() { parent::__construct(); - $this->strRootDir = \System::getContainer()->getParameter('kernel.project_dir'); + $this->strRootDir = System::getContainer()->getParameter('kernel.project_dir'); } /** @@ -32,20 +45,20 @@ public function __construct() */ public function importStyleManager() { - \Config::set('uploadTypes', \Config::get('uploadTypes') . ',xml'); + Config::set('uploadTypes', Config::get('uploadTypes') . ',xml'); - /** @var \FileUpload $objUploader */ - $objUploader = new \FileUpload(); + /** @var FileUpload $objUploader */ + $objUploader = new FileUpload(); - if (\Input::post('FORM_SUBMIT') == 'tl_style_manager_import') + if (Input::post('FORM_SUBMIT') == 'tl_style_manager_import') { - if (!\Input::post('confirm')) + if (!Input::post('confirm')) { $arrUploaded = $objUploader->uploadTo('system/tmp'); if (empty($arrUploaded)) { - \Message::addError($GLOBALS['TL_LANG']['ERR']['all_fields']); + Message::addError($GLOBALS['TL_LANG']['ERR']['all_fields']); $this->reload(); } @@ -56,16 +69,16 @@ public function importStyleManager() // Skip folders if (is_dir($this->strRootDir . '/' . $strFile)) { - \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['importFolder'], basename($strFile))); + Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['importFolder'], basename($strFile))); continue; } - $objFile = new \File($strFile); + $objFile = new File($strFile); // Skip anything but .xml files if ($objFile->extension != 'xml') { - \Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['filetype'], $objFile->extension)); + Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['filetype'], $objFile->extension)); continue; } @@ -76,7 +89,7 @@ public function importStyleManager() // Check whether there are any files if (empty($arrFiles)) { - \Message::addError($GLOBALS['TL_LANG']['ERR']['all_fields']); + Message::addError($GLOBALS['TL_LANG']['ERR']['all_fields']); $this->reload(); } @@ -84,15 +97,15 @@ public function importStyleManager() } // Return the form - return \Message::generate() . ' + return Message::generate() . '
-' . $GLOBALS['TL_LANG']['MSC']['backBT'] . ' +' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '
-
+
- +
@@ -116,15 +129,19 @@ public function importStyleManager() /** * Import StyleManager data from file * - * @param $arrFiles + * @param array $arrFiles + * @param bool $blnSave * * @throws \Exception */ - public function importStyleManagerFile(array $arrFiles) + public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ?array { + $arrStyleArchives = []; + $arrStyleGroups = []; + foreach ($arrFiles as $strFilePath) { - $objFile = new \File($strFilePath); + $objFile = new File($strFilePath); // Load the XML file if ($objFile->exists()) @@ -136,7 +153,7 @@ public function importStyleManagerFile(array $arrFiles) // Continue if there is no XML file if (!$xml instanceof \DOMDocument) { - \Message::addError(sprintf($GLOBALS['TL_LANG']['tl_theme']['missing_xml'], basename($strFilePath))); + Message::addError(sprintf($GLOBALS['TL_LANG']['tl_theme']['missing_xml'], basename($strFilePath))); continue; } @@ -148,7 +165,7 @@ public function importStyleManagerFile(array $arrFiles) } else { - return; + return null; } // Lock the tables @@ -164,7 +181,10 @@ public function importStyleManagerFile(array $arrFiles) $this->loadDataContainer($table); } - $this->Database->lockTables($arrLocks); + if($blnSave) + { + $this->Database->lockTables($arrLocks); + } // Get the current auto_increment values $intArchiveId = $this->Database->getNextId('tl_style_manager_archive'); @@ -252,9 +272,9 @@ public function importStyleManagerFile(array $arrFiles) case 'cssClasses': if($objChildren->{$strName}) { - $arrClasses = \StringUtil::deserialize($objChildren->{$strName}, true); + $arrClasses = StringUtil::deserialize($objChildren->{$strName}, true); $arrExists = $this->flattenKeyValueArray($arrClasses); - $arrValues = \StringUtil::deserialize($strValue, true); + $arrValues = StringUtil::deserialize($strValue, true); foreach($arrValues as $cssClass) { @@ -278,8 +298,8 @@ public function importStyleManagerFile(array $arrFiles) if(isset($dcaField['eval']['multiple']) && !!$dcaField['eval']['multiple'] && $dcaField['inputType'] === 'checkbox') { - $arrElements = \StringUtil::deserialize($objChildren->{$strName}, true); - $arrValues = \StringUtil::deserialize($strValue, true); + $arrElements = StringUtil::deserialize($objChildren->{$strName}, true); + $arrValues = StringUtil::deserialize($strValue, true); foreach($arrValues as $element) { @@ -299,29 +319,53 @@ public function importStyleManagerFile(array $arrFiles) } // Save children data - $objChildren->save(); + if($blnSave) + { + $objChildren->save(); + } + else + { + $arrStyleGroups[] = $objChildren->current(); + } } } } // Save archive data - $objArchive->save(); + if($blnSave) + { + $objArchive->save(); + } + else + { + $arrStyleArchives[] = $objArchive->current(); + } } // Unlock the tables - $this->Database->unlockTables(); + if($blnSave) + { + $this->Database->unlockTables(); + } } } + + if($blnSave) + { + return null; + } + + return [$arrStyleArchives, $arrStyleGroups]; } /** * Export StyleManager data * - * @param \DataContainer $dc + * @param DataContainer $dc * * @throws \Exception */ - public function exportStyleManager(\DataContainer $dc) + public function exportStyleManager(DataContainer $dc) { // Create a new XML document $xml = new \DOMDocument('1.0', 'UTF-8'); @@ -332,7 +376,7 @@ public function exportStyleManager(\DataContainer $dc) if (null === $objArchive) { - \Message::addError($GLOBALS['TL_LANG']['ERR']['noStyleManagerConfigFound']); + Message::addError($GLOBALS['TL_LANG']['ERR']['noStyleManagerConfigFound']); self::redirect(self::getReferer()); } @@ -350,7 +394,7 @@ public function exportStyleManager(\DataContainer $dc) $strTmp = md5(uniqid(mt_rand(), true)); // Create file and open the "save as …" dialogue - $objFile = new \File('system/tmp/' . $strTmp); + $objFile = new File('system/tmp/' . $strTmp); $objFile->write($xml->saveXML()); $objFile->close(); @@ -362,9 +406,9 @@ public function exportStyleManager(\DataContainer $dc) * * @param \DOMDocument $xml * @param \DOMNode $archives - * @param \Model\Collection $objArchive + * @param Collection $objArchive */ - protected function addArchiveData(\DOMDocument $xml, \DOMNode $archives, \Model\Collection $objArchive) + protected function addArchiveData(\DOMDocument $xml, \DOMNode $archives, Collection $objArchive) { $this->loadDataContainer('tl_style_manager_archive'); diff --git a/src/Resources/contao/widgets/ComponentStyleSelect.php b/src/Resources/contao/widgets/ComponentStyleSelect.php index 6881203..8688cde 100644 --- a/src/Resources/contao/widgets/ComponentStyleSelect.php +++ b/src/Resources/contao/widgets/ComponentStyleSelect.php @@ -47,10 +47,53 @@ class ComponentStyleSelect extends Widget */ public function generate() { - $objStyleArchives = StyleManagerArchiveModel::findAll(array('order'=>'sorting')); - $objStyleGroups = StyleManagerModel::findByTable($this->strTable, array('order'=>'pid,sorting')); + $arrObjStyleArchives = StyleManagerArchiveModel::findAll(array('order'=>'sorting')); + $arrObjStyleGroups = StyleManagerModel::findByTable($this->strTable, array('order'=>'pid,sorting')); - if($objStyleGroups === null || $objStyleArchives === null) + /* * * * * * + * + * ToDo: As far as the values are loaded from the configuration, they cannot be restored in the StyleManager. + * + * * * * * */ + + // Load and merge bundle configurations + if($this->getContainer()->getParameter('contao_component_style_manager.use_bundle_config')) + { + // Load bundle config + [$arrStyleArchives, $arrStyleGroups] = StyleManager::loadBundleConfiguration(); + + if($arrStyleArchives !== null && $arrStyleGroups !== null) + { + if(null !== $arrObjStyleArchives) + { + $arrObjStyleArchives = array_merge( + $arrObjStyleArchives->getModels(), + $arrStyleArchives + ); + }else $arrObjStyleArchives = $arrStyleArchives; + + // Make Collection mutable + $arrExistingGroupAliases = []; + + if(null !== $arrObjStyleGroups) + { + $arrExistingGroupAliases = $arrObjStyleGroups->fetchEach('alias'); + $arrObjStyleGroups = $arrObjStyleGroups->getModels(); + } + + // Append bundle config groups + foreach ($arrStyleGroups as $arrStyleGroup) + { + // Skip if the group is not allowed for the current table or the alias already exists in the backend configuration + if(StyleManager::isVisibleGroup($arrStyleGroup, $this->strTable) && !\in_array($arrStyleGroup->alias, $arrExistingGroupAliases)) + { + $arrObjStyleGroups[] = $arrStyleGroup; + } + } + } + } + + if($arrObjStyleGroups === null || $arrObjStyleArchives === null) { return $this->renderEmptyMessage(); } @@ -61,39 +104,39 @@ public function generate() $arrOrder = array(); // Prepare archives - while($objStyleArchives->next()) + foreach($arrObjStyleArchives as $objStyleArchive) { - $arrArchives[ $objStyleArchives->id ] = array( - 'title' => $objStyleArchives->title, - 'identifier' => $objStyleArchives->identifier, - 'desc' => $objStyleArchives->desc, - 'group' => $objStyleArchives->groupAlias, - 'model' => $objStyleArchives->current() + $arrArchives[ $objStyleArchive->id ] = array( + 'title' => $objStyleArchive->title, + 'identifier' => $objStyleArchive->identifier, + 'desc' => $objStyleArchive->desc, + 'group' => $objStyleArchive->groupAlias, + 'model' => $objStyleArchive ); - $arrOrder[] = $objStyleArchives->identifier; + $arrOrder[] = $objStyleArchive->identifier; } // Restore default values $this->varValue = StyleManager::deserializeValues($this->varValue); // Prepare group fields - while($objStyleGroups->next()) + foreach($arrObjStyleGroups as $objStyleGroup) { $arrOptions = array(); $strClass = 'tl_select'; $arrFieldOptions = array(); // set blank option - if(!!$objStyleGroups->blankOption) + if(!!$objStyleGroup->blankOption) { $arrFieldOptions[] = array('value'=>'', 'label'=>'-'); } // skip specific content elements - if(!!$objStyleGroups->extendContentElement && $this->strTable === 'tl_content') + if(!!$objStyleGroup->extendContentElement && $this->strTable === 'tl_content') { - $arrContentElements = StringUtil::deserialize($objStyleGroups->contentElements); + $arrContentElements = StringUtil::deserialize($objStyleGroup->contentElements); if($arrContentElements !== null && !in_array($this->activeRecord->type, $arrContentElements)) { @@ -102,9 +145,9 @@ public function generate() } // skip specific form fields - if(!!$objStyleGroups->extendFormFields && $this->strTable === 'tl_form_field') + if(!!$objStyleGroup->extendFormFields && $this->strTable === 'tl_form_field') { - $arrFormFields = StringUtil::deserialize($objStyleGroups->formFields); + $arrFormFields = StringUtil::deserialize($objStyleGroup->formFields); if($arrFormFields !== null && !in_array($this->activeRecord->type, $arrFormFields)) { @@ -113,9 +156,9 @@ public function generate() } // skip specific modules - if(!!$objStyleGroups->extendModule && $this->strTable === 'tl_module') + if(!!$objStyleGroup->extendModule && $this->strTable === 'tl_module') { - $arrModules = StringUtil::deserialize($objStyleGroups->modules); + $arrModules = StringUtil::deserialize($objStyleGroup->modules); if($arrModules !== null && !in_array($this->activeRecord->type, $arrModules)) { @@ -128,14 +171,14 @@ public function generate() { foreach ($GLOBALS['TL_HOOKS']['styleManagerSkipField'] as $callback) { - if(System::importStatic($callback[0])->{$callback[1]}($objStyleGroups, $this)) + if(System::importStatic($callback[0])->{$callback[1]}($objStyleGroup, $this)) { continue 2; } } } - $opts = StringUtil::deserialize($objStyleGroups->cssClasses); + $opts = StringUtil::deserialize($objStyleGroup->cssClasses); foreach ($opts as $opt) { $arrFieldOptions[] = array( @@ -145,8 +188,8 @@ public function generate() } // set options - $strFieldId = $this->strId . '_' . $objStyleGroups->id; - $strFieldName = $this->strName . '[' . $objStyleGroups->id . ']'; + $strFieldId = $this->strId . '_' . $objStyleGroup->id; + $strFieldName = $this->strName . '[' . $objStyleGroup->id . ']'; foreach ($arrFieldOptions as $strKey=>$arrOption) { @@ -156,7 +199,7 @@ public function generate() StringUtil::specialchars($arrOption['value']), // @deprecated: to be removed in Version 3.0. (interception of storage based on the alias. In future, only the ID must be set) - static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroups->id ] ?? '') ?: static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroups->alias ] ?? ''), + static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroup->id ] ?? '') ?: static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroup->alias ] ?? ''), $arrOption['label']); } @@ -170,7 +213,7 @@ public function generate() StringUtil::specialchars($arrOptgroup['value']), // @deprecated: to be removed in Version 3.0. (interception of storage based on the alias. In future, only the ID must be set) - static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroups->id ] ?? '') ?: static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroups->alias ] ?? ''), + static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroup->id ] ?? '') ?: static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroup->alias ] ?? ''), $arrOptgroup['label']); } @@ -180,27 +223,27 @@ public function generate() } // add chosen - if(!!$objStyleGroups->chosen) + if(!!$objStyleGroup->chosen) { $strClass .= ' tl_chosen'; } // create collection - $groupAlias = ($arrArchives[ $objStyleGroups->pid ]['group'] ?: 'group-' . $arrArchives[ $objStyleGroups->pid ]['identifier']) . '-' . $this->id; - $collectionAlias = $arrArchives[ $objStyleGroups->pid ]['identifier']; + $groupAlias = ($arrArchives[ $objStyleGroup->pid ]['group'] ?: 'group-' . $arrArchives[ $objStyleGroup->pid ]['identifier']) . '-' . $this->id; + $collectionAlias = $arrArchives[ $objStyleGroup->pid ]['identifier']; if(!in_array($collectionAlias, array_keys($arrCollection))) { $arrCollection[ $collectionAlias ] = array( - 'label' => $arrArchives[ $objStyleGroups->pid ]['title'], - 'desc' => $arrArchives[ $objStyleGroups->pid ]['desc'], + 'label' => $arrArchives[ $objStyleGroup->pid ]['title'], + 'desc' => $arrArchives[ $objStyleGroup->pid ]['desc'], 'group' => $groupAlias, 'fields' => array() ); } $arrCollection[ $collectionAlias ]['fields'][] = sprintf('%s%s%s', - ($objStyleGroups->cssClass === 'seperator' || $objStyleGroups->cssClass === 'separator' ? '
' : '') . 'cssClass ? ' class="' . $objStyleGroups->cssClass . '"' : '').'>

', + ($objStyleGroup->cssClass === 'seperator' || $objStyleGroup->cssClass === 'separator' ? '
' : '') . 'cssClass ? ' class="' . $objStyleGroup->cssClass . '"' : '').'>

', $strFieldName, $strFieldId, $strClass, @@ -208,7 +251,7 @@ public function generate() $this->getAttributes(), implode('', $arrOptions), $this->wizard, - '

'.$objStyleGroups->description.'

' + '

'.$objStyleGroup->description.'

' ); $isEmpty = false; From 02d5118cbd20c02d96b9b4a55eea3832e1e3034f Mon Sep 17 00:00:00 2001 From: doishub Date: Tue, 18 Jan 2022 11:26:21 +0100 Subject: [PATCH 02/48] Initial commit (bundle config) --- composer.json | 1 + src/Resources/contao/classes/Config.php | 140 ++++++++++++++++++ src/Resources/contao/classes/StyleManager.php | 80 +++------- src/Resources/contao/classes/Sync.php | 2 + .../models/StyleManagerArchiveModel.php | 34 +++++ .../contao/models/StyleManagerModel.php | 57 ++++++- .../contao/widgets/ComponentStyleSelect.php | 47 +----- 7 files changed, 256 insertions(+), 105 deletions(-) create mode 100644 src/Resources/contao/classes/Config.php diff --git a/composer.json b/composer.json index 6c90bb8..e051349 100644 --- a/composer.json +++ b/composer.json @@ -18,6 +18,7 @@ } ], "require":{ + "php":">=7.4", "ext-dom": "*", "contao/core-bundle":"^4.4" }, diff --git a/src/Resources/contao/classes/Config.php b/src/Resources/contao/classes/Config.php new file mode 100644 index 0000000..547953f --- /dev/null +++ b/src/Resources/contao/classes/Config.php @@ -0,0 +1,140 @@ + + */ +class Config +{ + /** + * Object instance (Singleton) + * @var Config + */ + protected static $objInstance; + + /** + * Group data + * @var array + */ + protected static $arrGroups = []; + + /** + * Archive data + * @var array + */ + protected static $arrArchive = []; + + /** + * Return all archives as array + */ + public static function getArchives(): ?array + { + return static::$arrArchive; + } + + /** + * Return all Groups as array + */ + public static function getGroups(?string $table=null): ?array + { + if(null === $table) + { + return static::$arrGroups; + } + + $arrObjStyleGroups = null; + + foreach (static::$arrGroups as $objStyleGroup) + { + // Skip if the group is not allowed for the current table + if(StyleManager::isVisibleGroup($objStyleGroup, $table)) + { + $arrObjStyleGroups[] = $objStyleGroup; + } + } + + return $arrObjStyleGroups; + } + + /** + * Load configuration files from third-party bundles and return them as array + */ + protected function loadBundleConfiguration(): ?array + { + if($arrFiles = $this->getBundleConfigurationFiles()) + { + $sync = new Sync(); + return $sync->importStyleManagerFile($arrFiles, false); + } + + return null; + } + + /** + * Return all configuration files from third-party bundles + */ + protected function getBundleConfigurationFiles(): ?array + { + $arrFiles = System::getContainer()->get('contao.resource_finder')->findIn('templates')->files()->name('style-manager-*.xml'); + + if($arrFiles->hasResults()) + { + $projectDir = System::getContainer()->getParameter('kernel.project_dir'); + $arrBundleConfigs = null; + + foreach ($arrFiles as $file) + { + $strRelpath = $file->getRealPath(); + $arrBundleConfigs[basename($strRelpath)] = str_replace($projectDir, '', $strRelpath); + } + + return $arrBundleConfigs; + } + + return null; + } + + /** + * Prevent direct instantiation (Singleton) + */ + protected function __construct() + { + [$arrStyleArchives, $arrStyleGroups] = static::loadBundleConfiguration(); + + self::$arrArchive = $arrStyleArchives; + self::$arrGroups = $arrStyleGroups; + } + + /** + * Prevent cloning of the object (Singleton) + */ + final public function __clone() + { + } + + /** + * Instantiate the config object + * + * @return Config The object instance + */ + public static function getInstance() + { + if (static::$objInstance === null) + { + static::$objInstance = new static(); + } + + return static::$objInstance; + } +} \ No newline at end of file diff --git a/src/Resources/contao/classes/StyleManager.php b/src/Resources/contao/classes/StyleManager.php index 725c990..0dd817c 100644 --- a/src/Resources/contao/classes/StyleManager.php +++ b/src/Resources/contao/classes/StyleManager.php @@ -173,14 +173,14 @@ public static function resetClasses($varValue, $dc, $strTable) $varValue = $cssID[1] ?? ''; } - $objStyles = StyleManagerModel::findByTable($strTable); + $objStyles = StyleManagerModel::findByTableAndConfiguration($strTable); $arrStyles = array(); if($objStyles !== null) { - while($objStyles->next()) + foreach($objStyles as $objStyle) { - $arrGroup = StringUtil::deserialize($objStyles->cssClasses, true); + $arrGroup = StringUtil::deserialize($objStyle->cssClasses, true); foreach ($arrGroup as $opts) { @@ -217,21 +217,21 @@ public static function cleanupClasses(&$arrValues, $strTable) { if(is_array($arrValues)) { - $objStyles = StyleManagerModel::findByTable($strTable); + $objStyles = StyleManagerModel::findByTableAndConfiguration($strTable); if($objStyles !== null) { $arrExistingKeys = array(); $arrExistingValues = array(); - while($objStyles->next()) + foreach($objStyles as $objStyle) { - $arrExistingKeys[] = $objStyles->id; + $arrExistingKeys[] = $objStyle->id; // @deprecated: to be removed in Version 3.0. (interception of storage based on the alias. In future, only the ID must be set) - $arrExistingKeys[] = $objStyles->alias; + $arrExistingKeys[] = $objStyle->alias; - $arrGroup = StringUtil::deserialize($objStyles->cssClasses, true); + $arrGroup = StringUtil::deserialize($objStyle->cssClasses, true); foreach ($arrGroup as $opts) { @@ -303,7 +303,7 @@ public static function isMultipleField($strField) * @return array|bool */ public static function serializeValues($varValue, $strTable){ - $objStyleGroups = StyleManagerModel::findByTable($strTable); + $objStyleGroups = StyleManagerModel::findByTableAndConfiguration($strTable); if($objStyleGroups === null) { @@ -311,12 +311,12 @@ public static function serializeValues($varValue, $strTable){ } $arrArchives = array(); - $objStyleArchives = StyleManagerArchiveModel::findAll(); + $objStyleArchives = StyleManagerArchiveModel::findAllWithConfiguration(); // Prepare archives identifier - while($objStyleArchives->next()) + foreach($objStyleArchives as $objStyleArchive) { - $arrArchives[ $objStyleArchives->id ] = $objStyleArchives->identifier; + $arrArchives[ $objStyleArchive->id ] = $objStyleArchive->identifier; } // Remove unused classes @@ -325,20 +325,20 @@ public static function serializeValues($varValue, $strTable){ }); // Rebuild array for template variables - while($objStyleGroups->next()) + foreach($objStyleGroups as $objStyleGroup) { - if(array_key_exists($objStyleGroups->id, $arrValue)) + if(array_key_exists($objStyleGroup->id, $arrValue)) { - if(!!$objStyleGroups->passToTemplate) + if(!!$objStyleGroup->passToTemplate) { - $identifier = $arrArchives[ $objStyleGroups->pid ]; + $identifier = $arrArchives[ $objStyleGroup->pid ]; - $arrValue['__vars__'][ $identifier ][ $objStyleGroups->alias ] = array( - 'id' => $objStyleGroups->id, - 'value' => $arrValue[ $objStyleGroups->id ] + $arrValue['__vars__'][ $identifier ][ $objStyleGroup->alias ] = array( + 'id' => $objStyleGroup->id, + 'value' => $arrValue[ $objStyleGroup->id ] ); - unset($arrValue[ $objStyleGroups->id ]); + unset($arrValue[ $objStyleGroup->id ]); } } } @@ -379,44 +379,6 @@ public static function deserializeValues($arrValue){ return $arrValue; } - /** - * Load configuration files from third-party bundles and return them as array - */ - public static function loadBundleConfiguration(): ?array - { - if($arrFiles = self::getBundleConfigurationFiles()) - { - $sync = new Sync(); - return $sync->importStyleManagerFile($arrFiles, false); - } - - return null; - } - - /** - * Return all configuration files from third-party bundles - */ - public static function getBundleConfigurationFiles(): ?array - { - $arrFiles = Controller::getContainer()->get('contao.resource_finder')->findIn('templates')->files()->name('style-manager-*.xml'); - - if($arrFiles->hasResults()) - { - $projectDir = System::getContainer()->getParameter('kernel.project_dir'); - $arrBundleConfigs = null; - - foreach ($arrFiles as $file) - { - $strRelpath = $file->getRealPath(); - $arrBundleConfigs[basename($strRelpath)] = str_replace($projectDir, '', $strRelpath); - } - - return $arrBundleConfigs; - } - - return null; - } - /** * Check whether an element is visible in style manager widget */ @@ -434,6 +396,8 @@ public static function isVisibleGroup(StyleManagerModel $objGroup, string $strTa 'tl_calendar_events' === $strTable && !!$objGroup->extendEvents ){ return true; } + // ToDo: Hook + return false; } diff --git a/src/Resources/contao/classes/Sync.php b/src/Resources/contao/classes/Sync.php index f1d43e4..64411af 100644 --- a/src/Resources/contao/classes/Sync.php +++ b/src/Resources/contao/classes/Sync.php @@ -188,6 +188,7 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? // Get the current auto_increment values $intArchiveId = $this->Database->getNextId('tl_style_manager_archive'); + $intGroupId = $this->Database->getNextId('tl_style_manager'); // Check if archive exists $archiveExists = function (string $identifier) : bool @@ -247,6 +248,7 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? if(!$childrenExists($alias, $objArchive->id)) { $objChildren = new StyleManagerModel(); + $objChildren->id = $intGroupId++; } else { diff --git a/src/Resources/contao/models/StyleManagerArchiveModel.php b/src/Resources/contao/models/StyleManagerArchiveModel.php index f9d2334..a6d14cc 100644 --- a/src/Resources/contao/models/StyleManagerArchiveModel.php +++ b/src/Resources/contao/models/StyleManagerArchiveModel.php @@ -7,6 +7,9 @@ namespace Oveleon\ContaoComponentStyleManager; +use Contao\Controller; +use Contao\System; + /** * Reads and writes fields from style manager categories * @@ -48,4 +51,35 @@ class StyleManagerArchiveModel extends \Model * @var string */ protected static $strTable = 'tl_style_manager_archive'; + + /** + * Find configuration archives and published archives + * + * @return \Model\Collection|StyleManagerArchiveModel[]|StyleManagerArchiveModel|null An array of models or null if there are no archive + */ + public static function findAllWithConfiguration(array $arrOptions=array()) + { + $objArchives = static::findAll($arrOptions); + + if(System::getContainer()->getParameter('contao_component_style_manager.use_bundle_config')) + { + $bundleConfig = Config::getInstance(); + $arrArchives = $bundleConfig::getArchives(); + + if(null !== $arrArchives) + { + if(null !== $objArchives) + { + return array_merge( + $objArchives->getModels(), + $arrArchives + ); + } + + return $arrArchives; + } + } + + return $objArchives; + } } diff --git a/src/Resources/contao/models/StyleManagerModel.php b/src/Resources/contao/models/StyleManagerModel.php index da88ed1..ccd98ce 100644 --- a/src/Resources/contao/models/StyleManagerModel.php +++ b/src/Resources/contao/models/StyleManagerModel.php @@ -7,6 +7,10 @@ namespace Oveleon\ContaoComponentStyleManager; +use Contao\Controller; +use Contao\Model; +use Contao\System; + /** * Reads and writes fields from style manager * @@ -87,7 +91,7 @@ * @author Daniele Sciannimanica */ -class StyleManagerModel extends \Model +class StyleManagerModel extends Model { /** @@ -132,7 +136,7 @@ public static function findByTable($strTable, array $arrOptions=array()) { foreach ($GLOBALS['TL_HOOKS']['styleManagerFindByTable'] as $callback) { - if (null !== ($result = \Contao\System::importStatic($callback[0])->{$callback[1]}($strTable, $arrOptions))) + if (null !== ($result = System::importStatic($callback[0])->{$callback[1]}($strTable, $arrOptions))) { return $result; } @@ -143,6 +147,55 @@ public static function findByTable($strTable, array $arrOptions=array()) } } + /** + * Find configuration and published css groups using their table + * + * @param $strTable + * @param array $arrOptions An optional options array + * + * @return \Model\Collection|StyleManagerModel[]|StyleManagerModel|null An array of models or null if there are no css groups + */ + public static function findByTableAndConfiguration($strTable, array $arrOptions=array()) + { + $objGroups = static::findByTable($strTable, $arrOptions); + + // Load and merge bundle configurations + if(System::getContainer()->getParameter('contao_component_style_manager.use_bundle_config')) + { + $arrObjStyleGroups = null; + + $bundleConfig = Config::getInstance(); + $arrGroups = $bundleConfig::getGroups($strTable); + + if(null !== $arrGroups) + { + $arrExistingGroupAliases = []; + + if(null !== $objGroups) + { + $arrExistingGroupAliases = $objGroups->fetchEach('alias'); + + // Make Collection mutable + $arrObjStyleGroups = $objGroups->getModels(); + } + + // Append bundle config groups + foreach ($arrGroups as $arrGroup) + { + // Skip if the alias already exists in the backend configuration + if(!\in_array($arrGroup->alias, $arrExistingGroupAliases)) + { + $arrObjStyleGroups[] = $arrGroup; + } + } + } + + return $arrObjStyleGroups; + } + + return $objGroups; + } + /** * Find one item by alias by their parent ID * diff --git a/src/Resources/contao/widgets/ComponentStyleSelect.php b/src/Resources/contao/widgets/ComponentStyleSelect.php index 8688cde..417370d 100644 --- a/src/Resources/contao/widgets/ComponentStyleSelect.php +++ b/src/Resources/contao/widgets/ComponentStyleSelect.php @@ -47,51 +47,8 @@ class ComponentStyleSelect extends Widget */ public function generate() { - $arrObjStyleArchives = StyleManagerArchiveModel::findAll(array('order'=>'sorting')); - $arrObjStyleGroups = StyleManagerModel::findByTable($this->strTable, array('order'=>'pid,sorting')); - - /* * * * * * - * - * ToDo: As far as the values are loaded from the configuration, they cannot be restored in the StyleManager. - * - * * * * * */ - - // Load and merge bundle configurations - if($this->getContainer()->getParameter('contao_component_style_manager.use_bundle_config')) - { - // Load bundle config - [$arrStyleArchives, $arrStyleGroups] = StyleManager::loadBundleConfiguration(); - - if($arrStyleArchives !== null && $arrStyleGroups !== null) - { - if(null !== $arrObjStyleArchives) - { - $arrObjStyleArchives = array_merge( - $arrObjStyleArchives->getModels(), - $arrStyleArchives - ); - }else $arrObjStyleArchives = $arrStyleArchives; - - // Make Collection mutable - $arrExistingGroupAliases = []; - - if(null !== $arrObjStyleGroups) - { - $arrExistingGroupAliases = $arrObjStyleGroups->fetchEach('alias'); - $arrObjStyleGroups = $arrObjStyleGroups->getModels(); - } - - // Append bundle config groups - foreach ($arrStyleGroups as $arrStyleGroup) - { - // Skip if the group is not allowed for the current table or the alias already exists in the backend configuration - if(StyleManager::isVisibleGroup($arrStyleGroup, $this->strTable) && !\in_array($arrStyleGroup->alias, $arrExistingGroupAliases)) - { - $arrObjStyleGroups[] = $arrStyleGroup; - } - } - } - } + $arrObjStyleArchives = StyleManagerArchiveModel::findAllWithConfiguration(array('order'=>'sorting')); + $arrObjStyleGroups = StyleManagerModel::findByTableAndConfiguration($this->strTable, array('order'=>'pid,sorting')); if($arrObjStyleGroups === null || $arrObjStyleArchives === null) { From 4dfe4853e6a74b97d0c39e6a7b633031613066b8 Mon Sep 17 00:00:00 2001 From: doishub Date: Wed, 19 Jan 2022 15:30:11 +0100 Subject: [PATCH 03/48] Revision of the storage of data in the StyleManager field. The fields are no longer stored by ID but by an identifier-alias combination. --- src/Resources/contao/classes/StyleManager.php | 43 +++++++++------- src/Resources/contao/classes/Sync.php | 51 +++++++++---------- .../models/StyleManagerArchiveModel.php | 7 ++- .../contao/models/StyleManagerModel.php | 8 +++ .../contao/widgets/ComponentStyleSelect.php | 12 +++-- 5 files changed, 73 insertions(+), 48 deletions(-) diff --git a/src/Resources/contao/classes/StyleManager.php b/src/Resources/contao/classes/StyleManager.php index 0dd817c..2aeffd2 100644 --- a/src/Resources/contao/classes/StyleManager.php +++ b/src/Resources/contao/classes/StyleManager.php @@ -223,13 +223,19 @@ public static function cleanupClasses(&$arrValues, $strTable) { $arrExistingKeys = array(); $arrExistingValues = array(); + $arrArchives = array(); - foreach($objStyles as $objStyle) + $objStyleArchives = StyleManagerArchiveModel::findAllWithConfiguration(); + + // Prepare archives identifier + foreach($objStyleArchives as $objStyleArchive) { - $arrExistingKeys[] = $objStyle->id; + $arrArchives[ $objStyleArchive->id ] = $objStyleArchive->identifier; + } - // @deprecated: to be removed in Version 3.0. (interception of storage based on the alias. In future, only the ID must be set) - $arrExistingKeys[] = $objStyle->alias; + foreach($objStyles as $objStyle) + { + $arrExistingKeys[] = self::generateAlias($arrArchives[ $objStyle->pid ], $objStyle->alias); $arrGroup = StringUtil::deserialize($objStyle->cssClasses, true); @@ -327,7 +333,9 @@ public static function serializeValues($varValue, $strTable){ // Rebuild array for template variables foreach($objStyleGroups as $objStyleGroup) { - if(array_key_exists($objStyleGroup->id, $arrValue)) + $strId = self::generateAlias($arrArchives[ $objStyleGroup->pid ], $objStyleGroup->alias); + + if(array_key_exists($strId, $arrValue)) { if(!!$objStyleGroup->passToTemplate) { @@ -335,10 +343,10 @@ public static function serializeValues($varValue, $strTable){ $arrValue['__vars__'][ $identifier ][ $objStyleGroup->alias ] = array( 'id' => $objStyleGroup->id, - 'value' => $arrValue[ $objStyleGroup->id ] + 'value' => $arrValue[ $strId ] ); - unset($arrValue[ $objStyleGroup->id ]); + unset($arrValue[ $strId ]); } } } @@ -357,19 +365,12 @@ public static function deserializeValues($arrValue){ if(isset($arrValue['__vars__'])) { - foreach ($arrValue['__vars__'] as $key => $values) + foreach ($arrValue['__vars__'] as $archiveAlias => $values) { foreach ($values as $alias => $arrItem) { - if(!is_array($arrItem)) - { - // @deprecated: to be removed in Version 3.0. (interception of storage based on the alias) - $arrValue[ $alias ] = $arrItem; - } - else - { - $arrValue[ $arrItem['id'] ] = html_entity_decode($arrItem['value']); - } + $strId = self::generateAlias($archiveAlias, $alias); + $arrValue[ $strId ] = html_entity_decode($arrItem['value']); } } @@ -379,6 +380,14 @@ public static function deserializeValues($arrValue){ return $arrValue; } + /** + * Generate a unique alias based on the archive identifier and the group alias + */ + public static function generateAlias($identifier, $alias): string + { + return $identifier . '_' . $alias; + } + /** * Check whether an element is visible in style manager widget */ diff --git a/src/Resources/contao/classes/Sync.php b/src/Resources/contao/classes/Sync.php index 64411af..b44f3f0 100644 --- a/src/Resources/contao/classes/Sync.php +++ b/src/Resources/contao/classes/Sync.php @@ -139,13 +139,19 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? $arrStyleArchives = []; $arrStyleGroups = []; + // Get the next id + $intArchiveId = $this->Database->getNextId('tl_style_manager_archive'); + $intGroupId = $this->Database->getNextId('tl_style_manager'); + foreach ($arrFiles as $strFilePath) { + // Open file $objFile = new File($strFilePath); - // Load the XML file + // Check if file exists if ($objFile->exists()) { + // Load xml file $xml = new \DOMDocument(); $xml->preserveWhiteSpace = false; $xml->loadXML($objFile->getContent()); @@ -157,39 +163,32 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? continue; } + // Get archives node $archives = $xml->getElementsByTagName('archives'); if($archives->count()){ // Skip archives node $archives = $archives->item(0)->childNodes; - } - else - { - return null; - } - - // Lock the tables - $arrLocks = array - ( - 'tl_style_manager_archive' => 'WRITE', - 'tl_style_manager' => 'WRITE' - ); - - // Load the DCAs of the locked tables - foreach (array_keys($arrLocks) as $table) - { - $this->loadDataContainer($table); - } + }else return null; if($blnSave) { + // Lock the tables + $arrLocks = array + ( + 'tl_style_manager_archive' => 'WRITE', + 'tl_style_manager' => 'WRITE' + ); + + // Load the DCAs of the locked tables + foreach (array_keys($arrLocks) as $table) + { + $this->loadDataContainer($table); + } + $this->Database->lockTables($arrLocks); } - // Get the current auto_increment values - $intArchiveId = $this->Database->getNextId('tl_style_manager_archive'); - $intGroupId = $this->Database->getNextId('tl_style_manager'); - // Check if archive exists $archiveExists = function (string $identifier) : bool { @@ -208,7 +207,7 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? $archive = $archives->item($i)->childNodes; $identifier = $archives->item($i)->getAttribute('identifier'); - if(!$archiveExists($identifier)) + if(!$blnSave || !$archiveExists($identifier)) { $objArchive = new StyleManagerArchiveModel(); $objArchive->id = ++$intArchiveId; @@ -245,10 +244,10 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? $alias = $children->item($c)->getAttribute('alias'); $fields = $children->item($c)->childNodes; - if(!$childrenExists($alias, $objArchive->id)) + if(!$blnSave || !$childrenExists($alias, $objArchive->id)) { $objChildren = new StyleManagerModel(); - $objChildren->id = $intGroupId++; + $objChildren->id = ++$intGroupId; } else { diff --git a/src/Resources/contao/models/StyleManagerArchiveModel.php b/src/Resources/contao/models/StyleManagerArchiveModel.php index a6d14cc..ea41d88 100644 --- a/src/Resources/contao/models/StyleManagerArchiveModel.php +++ b/src/Resources/contao/models/StyleManagerArchiveModel.php @@ -70,12 +70,17 @@ public static function findAllWithConfiguration(array $arrOptions=array()) { if(null !== $objArchives) { - return array_merge( + $arrArchives = array_merge( $objArchives->getModels(), $arrArchives ); } + // Sort by sorting + usort($arrArchives, function($a, $b) { + return $a->sorting <=> $b->sorting; + }); + return $arrArchives; } } diff --git a/src/Resources/contao/models/StyleManagerModel.php b/src/Resources/contao/models/StyleManagerModel.php index ccd98ce..012b9e5 100644 --- a/src/Resources/contao/models/StyleManagerModel.php +++ b/src/Resources/contao/models/StyleManagerModel.php @@ -190,6 +190,14 @@ public static function findByTableAndConfiguration($strTable, array $arrOptions= } } + if($arrObjStyleGroups) + { + // Sort by sorting + usort($arrObjStyleGroups, function($a, $b) { + return ($a->sorting <=> $b->sorting); + }); + } + return $arrObjStyleGroups; } diff --git a/src/Resources/contao/widgets/ComponentStyleSelect.php b/src/Resources/contao/widgets/ComponentStyleSelect.php index 417370d..a20a91b 100644 --- a/src/Resources/contao/widgets/ComponentStyleSelect.php +++ b/src/Resources/contao/widgets/ComponentStyleSelect.php @@ -145,8 +145,10 @@ public function generate() } // set options - $strFieldId = $this->strId . '_' . $objStyleGroup->id; - $strFieldName = $this->strName . '[' . $objStyleGroup->id . ']'; + + $strId = StyleManager::generateAlias($arrArchives[ $objStyleGroup->pid ]['identifier'], $objStyleGroup->alias); + $strFieldId = $this->strId . '_' . $strId; + $strFieldName = $this->strName . '[' . $strId . ']'; foreach ($arrFieldOptions as $strKey=>$arrOption) { @@ -156,7 +158,8 @@ public function generate() StringUtil::specialchars($arrOption['value']), // @deprecated: to be removed in Version 3.0. (interception of storage based on the alias. In future, only the ID must be set) - static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroup->id ] ?? '') ?: static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroup->alias ] ?? ''), + //static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroup->id ] ?? '') ?: static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroup->alias ] ?? ''), + static::optionSelected($arrOption['value'], $this->varValue[ $strId ] ?? ''), $arrOption['label']); } @@ -170,7 +173,8 @@ public function generate() StringUtil::specialchars($arrOptgroup['value']), // @deprecated: to be removed in Version 3.0. (interception of storage based on the alias. In future, only the ID must be set) - static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroup->id ] ?? '') ?: static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroup->alias ] ?? ''), + //static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroup->id ] ?? '') ?: static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroup->alias ] ?? ''), + static::optionSelected($arrOption['value'], $this->varValue[ $strId ] ?? ''), $arrOptgroup['label']); } From 2beb709f4c2e90352ed2d91962c7b4c8d5b9abbe Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 20 Jan 2022 10:43:37 +0100 Subject: [PATCH 04/48] Importer for bundle configurations added --- composer.json | 4 +- src/Resources/contao/classes/Config.php | 32 +++++----- src/Resources/contao/classes/StyleManager.php | 3 - src/Resources/contao/classes/Sync.php | 60 ++++++++++--------- .../contao/dca/tl_style_manager_archive.php | 23 ++++++- src/Resources/contao/languages/de/default.xlf | 4 ++ .../languages/de/tl_style_manager_archive.xlf | 16 ++++- src/Resources/contao/languages/en/default.xlf | 3 + .../languages/en/tl_style_manager_archive.xlf | 9 +++ src/Resources/contao/languages/fr/default.xlf | 8 ++- .../languages/fr/tl_style_manager_archive.xlf | 12 ++++ .../backend/be_style_manager_import.html5 | 47 +++++++++++++++ .../contao/widgets/ComponentStyleSelect.php | 10 ---- 13 files changed, 166 insertions(+), 65 deletions(-) create mode 100644 src/Resources/contao/templates/backend/be_style_manager_import.html5 diff --git a/composer.json b/composer.json index e051349..efe035c 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ "require":{ "php":">=7.4", "ext-dom": "*", - "contao/core-bundle":"^4.4" + "contao/core-bundle":"^4.10" }, "require-dev": { "contao/manager-plugin": "^2.0" @@ -46,7 +46,7 @@ }, "extra":{ "branch-alias": { - "dev-master": "2.5.x-dev" + "dev-master": "2.7.x-dev" }, "contao-manager-plugin": "Oveleon\\ContaoComponentStyleManager\\ContaoManager\\Plugin" } diff --git a/src/Resources/contao/classes/Config.php b/src/Resources/contao/classes/Config.php index 547953f..e30c12d 100644 --- a/src/Resources/contao/classes/Config.php +++ b/src/Resources/contao/classes/Config.php @@ -67,24 +67,10 @@ public static function getGroups(?string $table=null): ?array return $arrObjStyleGroups; } - /** - * Load configuration files from third-party bundles and return them as array - */ - protected function loadBundleConfiguration(): ?array - { - if($arrFiles = $this->getBundleConfigurationFiles()) - { - $sync = new Sync(); - return $sync->importStyleManagerFile($arrFiles, false); - } - - return null; - } - /** * Return all configuration files from third-party bundles */ - protected function getBundleConfigurationFiles(): ?array + public static function getBundleConfigurationFiles(): ?array { $arrFiles = System::getContainer()->get('contao.resource_finder')->findIn('templates')->files()->name('style-manager-*.xml'); @@ -105,6 +91,20 @@ protected function getBundleConfigurationFiles(): ?array return null; } + /** + * Load configuration files from third-party bundles and return them as array + */ + protected function loadBundleConfiguration(): ?array + { + if($arrFiles = $this->getBundleConfigurationFiles()) + { + $sync = new Sync(); + return $sync->importStyleManagerFile($arrFiles, false); + } + + return null; + } + /** * Prevent direct instantiation (Singleton) */ @@ -137,4 +137,4 @@ public static function getInstance() return static::$objInstance; } -} \ No newline at end of file +} diff --git a/src/Resources/contao/classes/StyleManager.php b/src/Resources/contao/classes/StyleManager.php index 2aeffd2..9ca30a7 100644 --- a/src/Resources/contao/classes/StyleManager.php +++ b/src/Resources/contao/classes/StyleManager.php @@ -8,11 +8,8 @@ namespace Oveleon\ContaoComponentStyleManager; use Contao\Backend; -use Contao\Controller; use Contao\CoreBundle\DataContainer\PaletteManipulator; use Contao\StringUtil; -use Contao\System; -use Contao\TemplateLoader; use Contao\Widget; class StyleManager diff --git a/src/Resources/contao/classes/Sync.php b/src/Resources/contao/classes/Sync.php index b44f3f0..1e74fcc 100644 --- a/src/Resources/contao/classes/Sync.php +++ b/src/Resources/contao/classes/Sync.php @@ -7,8 +7,8 @@ namespace Oveleon\ContaoComponentStyleManager; -use ContainerFDoeHNy\get_ServiceLocator_ZcNHns_Contao_Fragment_Contao_ContentElement_MarkdownService; use Contao\Backend; +use Contao\BackendTemplate; use Contao\Config; use Contao\DataContainer; use Contao\Environment; @@ -96,34 +96,35 @@ public function importStyleManager() $this->importStyleManagerFile($arrFiles); } - // Return the form - return Message::generate() . ' - - -
- - - - -
-
-

' . $GLOBALS['TL_LANG']['tl_style_manager_archive']['source'][0] . '

' . $objUploader->generateMarkup() . (isset($GLOBALS['TL_LANG']['tl_style_manager_archive']['source'][1]) ? ' -

' . $GLOBALS['TL_LANG']['tl_style_manager_archive']['source'][1] . '

' : '') . ' -
-
- -
- -
- -
- -
- -
-'; + if (Input::post('FORM_SUBMIT') == 'tl_style_manager_import_bundle') + { + if($bundleFiles = Input::post('bundleFiles')) + { + $this->importStyleManagerFile(array_map(fn($n) => html_entity_decode($n), $bundleFiles)); + } + } + + $template = new BackendTemplate('be_style_manager_import'); + + $template->backUrl = StringUtil::ampersand(str_replace('&key=import', '', Environment::get('request'))); + $template->backBT = $GLOBALS['TL_LANG']['MSC']['backBT']; + $template->backBTTitle = $GLOBALS['TL_LANG']['MSC']['backBTTitle']; + + $template->formId = 'tl_style_manager_import'; + $template->fileMaxSize = Config::get('maxFileSize'); + + $template->labelSource = $GLOBALS['TL_LANG']['tl_style_manager_archive']['source'][0]; + $template->descSource = $GLOBALS['TL_LANG']['tl_style_manager_archive']['source'][1]; + $template->fieldUpload = $objUploader->generateMarkup(); + + $template->labelImport = $GLOBALS['TL_LANG']['tl_style_manager_archive']['import'][0]; + $template->labelBundleConfig = $GLOBALS['TL_LANG']['tl_style_manager_archive']['headingBundleConfig']; + $template->emptyBundleFiles = $GLOBALS['TL_LANG']['tl_style_manager_archive']['emptyBundleConfig']; + $template->descBundleFiles = $GLOBALS['TL_LANG']['tl_style_manager_archive']['descBundleConfig']; + + $template->bundleFiles = \Oveleon\ContaoComponentStyleManager\Config::getBundleConfigurationFiles() ?? []; + + return $template->parse(); } /** @@ -347,6 +348,7 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? if($blnSave) { $this->Database->unlockTables(); + Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['MSC']['styleManagerConfigImported'], basename($strFilePath))); } } } diff --git a/src/Resources/contao/dca/tl_style_manager_archive.php b/src/Resources/contao/dca/tl_style_manager_archive.php index 7d94c00..9ea0946 100644 --- a/src/Resources/contao/dca/tl_style_manager_archive.php +++ b/src/Resources/contao/dca/tl_style_manager_archive.php @@ -52,7 +52,8 @@ 'label' => &$GLOBALS['TL_LANG']['tl_style_manager_archive']['import'], 'href' => 'key=import', 'class' => 'header_style_manager_import', - 'icon' => 'theme_import.svg' + 'icon' => 'theme_import.svg', + 'button_callback' => array('tl_style_manager_archive', 'importConfig') ), 'export' => array ( @@ -180,6 +181,8 @@ * @author Daniele Sciannimanica */ +use Contao\System; +use Oveleon\ContaoComponentStyleManager\Config; use Oveleon\ContaoComponentStyleManager\StyleManagerArchiveModel; class tl_style_manager_archive extends \Backend @@ -262,4 +265,22 @@ public function saveIdentifier($varValue, Contao\DataContainer $dc) return $varValue; } + + /** + * Return the import header button + */ + public function importConfig(string $href, string $label, string $title, string $class, string $attributes): string + { + if(System::getContainer()->getParameter('contao_component_style_manager.use_bundle_config')) + { + $bundleConfig = Config::getInstance(); + + if($arrFiles = $bundleConfig::getBundleConfigurationFiles()) + { + $label .= ' (' . count($arrFiles) . ')'; + } + } + + return '' . $label . ' '; + } } diff --git a/src/Resources/contao/languages/de/default.xlf b/src/Resources/contao/languages/de/default.xlf index 8d1b690..8ba3dd3 100644 --- a/src/Resources/contao/languages/de/default.xlf +++ b/src/Resources/contao/languages/de/default.xlf @@ -13,6 +13,10 @@ No style manager config found! Keine Konfiguration für den Style-Manager gefunden! + + The file %s was imported successfully. + Die Datei %s wurde erfolgreich importiert. + diff --git a/src/Resources/contao/languages/de/tl_style_manager_archive.xlf b/src/Resources/contao/languages/de/tl_style_manager_archive.xlf index 74860f2..982065a 100644 --- a/src/Resources/contao/languages/de/tl_style_manager_archive.xlf +++ b/src/Resources/contao/languages/de/tl_style_manager_archive.xlf @@ -10,6 +10,18 @@ Config Konfiguration + + Available configurations via external bundles + Vorhandene Konfigurationen über externe Bundles + + + No configurations available + Keine Konfigurationen vorhanden + + + Please note, as soon as the files displayed here are imported, they overwrite the configurations of the external bundles. So this function is only useful if you really want to overwrite or adjust the configurations. If they are deleted again, the configurations from the external bundles are automatically used again. + Bitte beachten Sie, sobald die hier angezeigten Dateien importiert werden, überschreiben sie die Konfigurationen der externen Bundles. Diese Funktion ist also nur sinnvoll, wenn Sie die Konfigurationen wirklich überschreiben oder anpassen wollen. Wenn diese wieder gelöscht werden, werden automatisch wieder die Konfigurationen aus den externen Bundles verwendet. + Add category Neue Kategorie @@ -35,8 +47,8 @@ Konfiguration exportieren - Source files - Quelldateien + Manual import + Manueller Import Here you can upload one .xml file to be imported. diff --git a/src/Resources/contao/languages/en/default.xlf b/src/Resources/contao/languages/en/default.xlf index c1b6ebb..2009333 100644 --- a/src/Resources/contao/languages/en/default.xlf +++ b/src/Resources/contao/languages/en/default.xlf @@ -10,6 +10,9 @@ No style manager config found! + + The file %s was imported successfully. + diff --git a/src/Resources/contao/languages/en/tl_style_manager_archive.xlf b/src/Resources/contao/languages/en/tl_style_manager_archive.xlf index aca2e1c..9175343 100644 --- a/src/Resources/contao/languages/en/tl_style_manager_archive.xlf +++ b/src/Resources/contao/languages/en/tl_style_manager_archive.xlf @@ -8,6 +8,15 @@ Config + + Available configurations via external bundles + + + No configurations available + + + Please note, as soon as the files displayed here are imported, they overwrite the configurations of the external bundles. So this function is only useful if you really want to overwrite or adjust the configurations. If they are deleted again, the configurations from the external bundles are automatically used again. + Add category diff --git a/src/Resources/contao/languages/fr/default.xlf b/src/Resources/contao/languages/fr/default.xlf index 9cc9339..7735ba6 100644 --- a/src/Resources/contao/languages/fr/default.xlf +++ b/src/Resources/contao/languages/fr/default.xlf @@ -7,11 +7,15 @@ The Alias "%s" already exists within this category! - L'Alias "%s" existe déjà dans cette catégorie ! + L'Alias "%s" existe déjà dans cette catégorie! No style manager config found! - Pas de configuration de style manager trouvée ! + Pas de configuration de style manager trouvée! + + + The file %s was imported successfully. + Le fichier %s a été importé avec succès. diff --git a/src/Resources/contao/languages/fr/tl_style_manager_archive.xlf b/src/Resources/contao/languages/fr/tl_style_manager_archive.xlf index a8a073d..12309f4 100644 --- a/src/Resources/contao/languages/fr/tl_style_manager_archive.xlf +++ b/src/Resources/contao/languages/fr/tl_style_manager_archive.xlf @@ -10,6 +10,18 @@ Config Configuration + + Available configurations via external bundles + Configurations disponibles via des faisceaux externes + + + No configurations available + Aucune configuration disponible + + + Please note, as soon as the files displayed here are imported, they overwrite the configurations of the external bundles. So this function is only useful if you really want to overwrite or adjust the configurations. If they are deleted again, the configurations from the external bundles are automatically used again. + Veuillez noter que dès que les fichiers affichés ici sont importés, ils écrasent les configurations des paquets externes. Cette fonction n'est donc utile que si vous souhaitez réellement écraser ou ajuster les configurations. Si vous les supprimez à nouveau, les configurations des paquets externes sont automatiquement réutilisées. + Add category Ajouter une catégorie diff --git a/src/Resources/contao/templates/backend/be_style_manager_import.html5 b/src/Resources/contao/templates/backend/be_style_manager_import.html5 new file mode 100644 index 0000000..f971516 --- /dev/null +++ b/src/Resources/contao/templates/backend/be_style_manager_import.html5 @@ -0,0 +1,47 @@ + + + + + +
+
+ + + + +
+
+

labelSource ?>

+
fieldUpload ?>
+

descSource ?>

+ +
+
+
+ +
+ + +
+
+

labelBundleConfig ?>

+ bundleFiles)): ?> + + bundleFiles as $fileName => $filePath): $strId = Contao\StringUtil::prepareSlug($fileName); ?> + + + + + +
+

descBundleFiles?>

+ + +

emptyBundleFiles?>

+ +
+
+
+
diff --git a/src/Resources/contao/widgets/ComponentStyleSelect.php b/src/Resources/contao/widgets/ComponentStyleSelect.php index a20a91b..d06dfbd 100644 --- a/src/Resources/contao/widgets/ComponentStyleSelect.php +++ b/src/Resources/contao/widgets/ComponentStyleSelect.php @@ -144,8 +144,6 @@ public function generate() ); } - // set options - $strId = StyleManager::generateAlias($arrArchives[ $objStyleGroup->pid ]['identifier'], $objStyleGroup->alias); $strFieldId = $this->strId . '_' . $strId; $strFieldName = $this->strName . '[' . $strId . ']'; @@ -156,11 +154,7 @@ public function generate() { $arrOptions[] = sprintf('', StringUtil::specialchars($arrOption['value']), - - // @deprecated: to be removed in Version 3.0. (interception of storage based on the alias. In future, only the ID must be set) - //static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroup->id ] ?? '') ?: static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroup->alias ] ?? ''), static::optionSelected($arrOption['value'], $this->varValue[ $strId ] ?? ''), - $arrOption['label']); } else @@ -171,11 +165,7 @@ public function generate() { $arrOptgroups[] = sprintf('', StringUtil::specialchars($arrOptgroup['value']), - - // @deprecated: to be removed in Version 3.0. (interception of storage based on the alias. In future, only the ID must be set) - //static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroup->id ] ?? '') ?: static::optionSelected($arrOption['value'], $this->varValue[ $objStyleGroup->alias ] ?? ''), static::optionSelected($arrOption['value'], $this->varValue[ $strId ] ?? ''), - $arrOptgroup['label']); } From 327d56ebe16c5f880355ba557b0d6bccb274841a Mon Sep 17 00:00:00 2001 From: doishub Date: Mon, 24 Jan 2022 10:30:32 +0100 Subject: [PATCH 05/48] Object conversion migration / command added --- src/Command/ObjectConversionCommand.php | 87 +++++++++++++++++ .../ContaoComponentStyleManagerExtension.php | 4 +- .../Version30/ObjectConversionMigration.php | 94 +++++++++++++++++++ src/Resources/config/commands.yml | 9 ++ src/Resources/config/migrations.yml | 7 ++ src/Resources/contao/classes/Sync.php | 94 ++++++++++++++++++- .../contao/dca/tl_style_manager_archive.php | 2 +- .../models/StyleManagerArchiveModel.php | 4 +- 8 files changed, 296 insertions(+), 5 deletions(-) create mode 100644 src/Command/ObjectConversionCommand.php create mode 100644 src/Migration/Version30/ObjectConversionMigration.php create mode 100644 src/Resources/config/commands.yml create mode 100644 src/Resources/config/migrations.yml diff --git a/src/Command/ObjectConversionCommand.php b/src/Command/ObjectConversionCommand.php new file mode 100644 index 0000000..b4e423d --- /dev/null +++ b/src/Command/ObjectConversionCommand.php @@ -0,0 +1,87 @@ +framework = $contaoFramework; + $this->framework->initialize(); + + $this->sync = new Sync(); + + parent::__construct(); + } + + protected function configure(): void + { + $this + ->setDescription('Converts the StyleManager object to the new schema based on the given table.') + ->addArgument('table', InputArgument::REQUIRED, 'The name of the Table') + ->addOption('force', 'f', InputOption::VALUE_NONE, 'Check tables even if they have already been converted.'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + + $strTable = $input->getArgument('table'); + $blnForce = $input->getOption('force'); + + if(null === $strTable) + { + throw new InvalidArgumentException('Please enter an existing table'); + } + + if($this->sync->shouldRunObjectConversion($strTable) || $blnForce) + { + $io->writeln(sprintf('Start converting table %s', $strTable)); + + $this->sync->performObjectConversion($strTable); + + $io->success(sprintf('Table %s were successfully converted.', $strTable)); + } + else + { + $io->note(sprintf('The table %s seems to be already converted. Use the --force option to convert this table anyway.', $strTable)); + } + + return Command::SUCCESS; + } +} diff --git a/src/DependencyInjection/ContaoComponentStyleManagerExtension.php b/src/DependencyInjection/ContaoComponentStyleManagerExtension.php index f860c98..a1fc784 100644 --- a/src/DependencyInjection/ContaoComponentStyleManagerExtension.php +++ b/src/DependencyInjection/ContaoComponentStyleManagerExtension.php @@ -2,7 +2,6 @@ namespace Oveleon\ContaoComponentStyleManager\DependencyInjection; -use Contao\Controller; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\Extension; @@ -19,6 +18,9 @@ public function load(array $configs, ContainerBuilder $container) new FileLocator(__DIR__ . '/../Resources/config') ); + $loader->load('migrations.yml'); + $loader->load('commands.yml'); + $container->setParameter('contao_component_style_manager.use_bundle_config', $config['use_bundle_config']); } } diff --git a/src/Migration/Version30/ObjectConversionMigration.php b/src/Migration/Version30/ObjectConversionMigration.php new file mode 100644 index 0000000..97aa1a8 --- /dev/null +++ b/src/Migration/Version30/ObjectConversionMigration.php @@ -0,0 +1,94 @@ +connection = $connection; + + $this->framework = $framework; + $this->framework->initialize(); + + $this->sync = new Sync(); + } + + public function shouldRun(): bool + { + $schemaManager = $this->connection->getSchemaManager(); + + // If the database table itself does not exist we should do nothing + if (!$schemaManager->tablesExist(['tl_style_manager'])) + { + return false; + } + + return $this->sync->shouldRunObjectConversion('tl_article') + || $this->sync->shouldRunObjectConversion('tl_content') + || $this->sync->shouldRunObjectConversion('tl_calendar_events') + || $this->sync->shouldRunObjectConversion('tl_form') + || $this->sync->shouldRunObjectConversion('tl_form_field') + || $this->sync->shouldRunObjectConversion('tl_layout') + || $this->sync->shouldRunObjectConversion('tl_module') + || $this->sync->shouldRunObjectConversion('tl_news') + || $this->sync->shouldRunObjectConversion('tl_page') + ; + } + + public function run(): MigrationResult + { + if($this->sync->shouldRunObjectConversion('tl_article')) + $this->sync->performObjectConversion('tl_article'); + + if($this->sync->shouldRunObjectConversion('tl_content')) + $this->sync->performObjectConversion('tl_content'); + + if($this->sync->shouldRunObjectConversion('tl_calendar_events')) + $this->sync->performObjectConversion('tl_calendar_events'); + + if($this->sync->shouldRunObjectConversion('tl_form')) + $this->sync->performObjectConversion('tl_form'); + + if($this->sync->shouldRunObjectConversion('tl_form_field')) + $this->sync->performObjectConversion('tl_form_field'); + + if($this->sync->shouldRunObjectConversion('tl_layout')) + $this->sync->performObjectConversion('tl_layout'); + + if($this->sync->shouldRunObjectConversion('tl_module')) + $this->sync->performObjectConversion('tl_module'); + + if($this->sync->shouldRunObjectConversion('tl_news')) + $this->sync->performObjectConversion('tl_news'); + + if($this->sync->shouldRunObjectConversion('tl_page')) + $this->sync->performObjectConversion('tl_page'); + + return new MigrationResult( + true, + 'StyleManager configurations were successfully converted. Please note, if custom tables have been added to the StyleManager, they must be migrated using the `contao:stylemanager:object-conversion table` command.' + ); + } +} diff --git a/src/Resources/config/commands.yml b/src/Resources/config/commands.yml new file mode 100644 index 0000000..ebe359c --- /dev/null +++ b/src/Resources/config/commands.yml @@ -0,0 +1,9 @@ +services: + _defaults: + autoconfigure: true + public: false + + contao.stylemanager.object_conversion: + class: Oveleon\ContaoComponentStyleManager\Command\ObjectConversionCommand + arguments: + - '@contao.framework' diff --git a/src/Resources/config/migrations.yml b/src/Resources/config/migrations.yml new file mode 100644 index 0000000..6534169 --- /dev/null +++ b/src/Resources/config/migrations.yml @@ -0,0 +1,7 @@ +services: + Oveleon\ContaoComponentStyleManager\Migration\Version30\ObjectConversionMigration: + arguments: + - '@database_connection' + - '@contao.framework' + tags: + - { name: contao.migration, priority: 0 } diff --git a/src/Resources/contao/classes/Sync.php b/src/Resources/contao/classes/Sync.php index 1e74fcc..f94b9e8 100644 --- a/src/Resources/contao/classes/Sync.php +++ b/src/Resources/contao/classes/Sync.php @@ -37,7 +37,99 @@ public function __construct() } /** - * Import + * Check if the object conversion should be performed + */ + public function shouldRunObjectConversion($table = null): bool + { + $arrTables = $this->Database->listTables(); + + if(null === $table || !in_array($table, $arrTables)) + { + return false; + } + + $objConfig = $this->Database->query("SELECT styleManager FROM " . $table . " WHERE styleManager IS NOT NULL LIMIT 0,1"); + + if($objConfig && $arrConfig = StringUtil::deserialize($objConfig->styleManager)) + { + return is_numeric(array_key_first($arrConfig)); + } + + return false; + } + + /** + * Perform the object conversion + */ + public function performObjectConversion($table = null): void + { + $arrTables = $this->Database->listTables(); + + if(null === $table || !in_array($table, $arrTables)) + { + return; + } + + if($objRows = $this->Database->query("SELECT id, styleManager FROM " . $table . " WHERE styleManager IS NOT NULL")) + { + $objArchives = StyleManagerArchiveModel::findAll(); + $arrArchives = []; + + foreach ($objArchives as $objArchive) + { + $arrArchives[ $objArchive->id ] = $objArchive->identifier; + } + + $arrConfigs = $objRows->fetchEach('styleManager'); + $arrIds = []; + + foreach ($arrConfigs as $sttConfig) + { + if($arrConfig = StringUtil::deserialize($sttConfig)) + { + $arrIds = array_merge($arrIds, array_keys($arrConfig)); + } + } + + $objGroups = StyleManagerModel::findMultipleByIds($arrIds); + $arrGroups = []; + + if(null !== $objGroups) + { + foreach ($objGroups as $objGroup) + { + $arrGroups[ $objGroup->id ] = $objGroup; + } + + foreach ($objRows->fetchAllAssoc() as $arrRow) + { + $config = StringUtil::deserialize($arrRow['styleManager']); + + // Skip is config already converted + if(!is_numeric(array_key_first($config))) + { + continue; + } + + $arrAliasPairKeys = array_map(function($intGroupKey) use ($arrArchives, $arrGroups) { + return StyleManager::generateAlias($arrArchives[ $arrGroups[$intGroupKey]->pid ], $arrGroups[$intGroupKey]->alias); + }, array_keys($config)); + + $newConfig = array_combine($arrAliasPairKeys, $config); + + $this->Database + ->prepare("UPDATE " . $table . " SET styleManager=? WHERE id=?") + ->execute( + serialize($newConfig), + $arrRow['id'] + ); + } + } + } + } + + /** + * Display import form in back end * * @return string * diff --git a/src/Resources/contao/dca/tl_style_manager_archive.php b/src/Resources/contao/dca/tl_style_manager_archive.php index 9ea0946..a0bc23f 100644 --- a/src/Resources/contao/dca/tl_style_manager_archive.php +++ b/src/Resources/contao/dca/tl_style_manager_archive.php @@ -277,7 +277,7 @@ public function importConfig(string $href, string $label, string $title, string if($arrFiles = $bundleConfig::getBundleConfigurationFiles()) { - $label .= ' (' . count($arrFiles) . ')'; + $label .= ' (' . count($arrFiles) . ')'; } } diff --git a/src/Resources/contao/models/StyleManagerArchiveModel.php b/src/Resources/contao/models/StyleManagerArchiveModel.php index ea41d88..adc5c9c 100644 --- a/src/Resources/contao/models/StyleManagerArchiveModel.php +++ b/src/Resources/contao/models/StyleManagerArchiveModel.php @@ -7,7 +7,7 @@ namespace Oveleon\ContaoComponentStyleManager; -use Contao\Controller; +use Contao\Model; use Contao\System; /** @@ -43,7 +43,7 @@ * @author Daniele Sciannimanica */ -class StyleManagerArchiveModel extends \Model +class StyleManagerArchiveModel extends Model { /** From c0a7ed13968b4a28e3997a9a4b8c51ebec665e05 Mon Sep 17 00:00:00 2001 From: doishub Date: Mon, 24 Jan 2022 10:48:28 +0100 Subject: [PATCH 06/48] Update docs --- README.md | 2 ++ docs/BUNDLE_CONFIG.md | 9 +++++++++ docs/IMPORT_EXPORT.md | 3 +++ 3 files changed, 14 insertions(+) create mode 100644 docs/BUNDLE_CONFIG.md diff --git a/README.md b/README.md index 6a06fff..3845c18 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ This plugin is designed to simplify theme customizations without the need of man - Passing variables to the template - Formatting output using predefined methods or your own - Import / Export + - Automatic import of configurations from third-party bundles - Available for - Layouts - Pages @@ -53,3 +54,4 @@ composer require oveleon/contao-component-style-manager - [Use template variables](docs/TEMPLATE_VARIABLES.md) - [Extend and support other extensions](docs/SUPPORT.md) - [Import / Export](docs/IMPORT_EXPORT.md) +- [Bundle-Configurations](docs/BUNDLE_CONFIG.md) diff --git a/docs/BUNDLE_CONFIG.md b/docs/BUNDLE_CONFIG.md new file mode 100644 index 0000000..8bead41 --- /dev/null +++ b/docs/BUNDLE_CONFIG.md @@ -0,0 +1,9 @@ +## Bundle-Configurations +Instead of the import function, from version 3, configurations can be automatically provided by other bundles. For the deployment, a configuration file, which can be exported via the StyleManager, must be stored under `contao/templates` of the bundle. If the automatic import of these configuration files is not prevented (allowed by default), archives and CSS groups are automatically added to the defined areas. + +To prevent dynamic configurations from being read in, the following lines must be added to the config.yml file: +```yaml +contao_component_style_manager: + use_bundle_config: false +``` + diff --git a/docs/IMPORT_EXPORT.md b/docs/IMPORT_EXPORT.md index 7aa8fe3..05ecca9 100644 --- a/docs/IMPORT_EXPORT.md +++ b/docs/IMPORT_EXPORT.md @@ -4,3 +4,6 @@ To fill projects with a default setting, the Import and Export functions are ava When importing, the categories as well as the CSS groups are only added additively. This allows CSS classes to be added to the actual project without being deleted after an import. > Please note that the import completes the records by the identifier (categories) and the alias (CSS groups). So if the aliases are changed in the current project, they are not overwritten / added, but a new group is created after the import. + +### Prepare dynamic configurations +See also: [Bundle-Configurations](BUNDLE_CONFIG.md) From 486e0df11b1b09addd99aba99869550c0928f6ba Mon Sep 17 00:00:00 2001 From: doishub Date: Mon, 24 Jan 2022 10:56:17 +0100 Subject: [PATCH 07/48] Added migration documentation to the readme --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 3845c18..4280bd9 100644 --- a/README.md +++ b/README.md @@ -55,3 +55,16 @@ composer require oveleon/contao-component-style-manager - [Extend and support other extensions](docs/SUPPORT.md) - [Import / Export](docs/IMPORT_EXPORT.md) - [Bundle-Configurations](docs/BUNDLE_CONFIG.md) + +## Migration + +#### Migrate from version 2 to 3 +Bundle configurations were added with version 3. This makes it necessary to migrate the StyleManager dataset. If only standard Contao tables were used and the StyleManager was not added to other / own database tables, calling the install tool is sufficient. + +If the StyleManager was used for other / own database tables, these tables must be migrated manually using the following command: + +```shell +$ php contao-console contao:stylemanager:object-conversion tl_mytable +``` + + From 3b81eb83612f9b71715515642cff11f613637724 Mon Sep 17 00:00:00 2001 From: doishub Date: Mon, 24 Jan 2022 11:10:36 +0100 Subject: [PATCH 08/48] Added hooks `styleManagerIsVisibleGroup` and `styleManagerGroupFieldOptions` --- docs/BUNDLE_CONFIG.md | 2 +- src/Resources/contao/classes/StyleManager.php | 10 +++++++++- .../contao/widgets/ComponentStyleSelect.php | 12 ++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/docs/BUNDLE_CONFIG.md b/docs/BUNDLE_CONFIG.md index 8bead41..a80ded7 100644 --- a/docs/BUNDLE_CONFIG.md +++ b/docs/BUNDLE_CONFIG.md @@ -1,5 +1,5 @@ ## Bundle-Configurations -Instead of the import function, from version 3, configurations can be automatically provided by other bundles. For the deployment, a configuration file, which can be exported via the StyleManager, must be stored under `contao/templates` of the bundle. If the automatic import of these configuration files is not prevented (allowed by default), archives and CSS groups are automatically added to the defined areas. +Instead of the import function, from version 3, configurations can be automatically provided by other bundles. For the deployment, a configuration file, which can be exported via the StyleManager, must be stored under `contao/templates` of the bundle. The file needs to start with `style-manager-`. If the automatic import of these configuration files is not prevented (allowed by default), archives and CSS groups are automatically added to the defined areas. To prevent dynamic configurations from being read in, the following lines must be added to the config.yml file: ```yaml diff --git a/src/Resources/contao/classes/StyleManager.php b/src/Resources/contao/classes/StyleManager.php index 9ca30a7..715499a 100644 --- a/src/Resources/contao/classes/StyleManager.php +++ b/src/Resources/contao/classes/StyleManager.php @@ -10,6 +10,7 @@ use Contao\Backend; use Contao\CoreBundle\DataContainer\PaletteManipulator; use Contao\StringUtil; +use Contao\System; use Contao\Widget; class StyleManager @@ -402,7 +403,14 @@ public static function isVisibleGroup(StyleManagerModel $objGroup, string $strTa 'tl_calendar_events' === $strTable && !!$objGroup->extendEvents ){ return true; } - // ToDo: Hook + // Check is visible group for custom configurations + if (isset($GLOBALS['TL_HOOKS']['styleManagerIsVisibleGroup']) && \is_array($GLOBALS['TL_HOOKS']['styleManagerGroupFieldOptions'])) + { + foreach ($GLOBALS['TL_HOOKS']['styleManagerIsVisibleGroup'] as $callback) + { + return System::importStatic($callback[0])->{$callback[1]}($objGroup, $strTable); + } + } return false; } diff --git a/src/Resources/contao/widgets/ComponentStyleSelect.php b/src/Resources/contao/widgets/ComponentStyleSelect.php index d06dfbd..7314258 100644 --- a/src/Resources/contao/widgets/ComponentStyleSelect.php +++ b/src/Resources/contao/widgets/ComponentStyleSelect.php @@ -144,6 +144,18 @@ public function generate() ); } + // dynamically change or expand group options + if (isset($GLOBALS['TL_HOOKS']['styleManagerGroupFieldOptions']) && \is_array($GLOBALS['TL_HOOKS']['styleManagerGroupFieldOptions'])) + { + foreach ($GLOBALS['TL_HOOKS']['styleManagerGroupFieldOptions'] as $callback) + { + if($optionCallback = System::importStatic($callback[0])->{$callback[1]}($arrFieldOptions, $objStyleGroup, $this)) + { + $arrFieldOptions = $optionCallback; + } + } + } + $strId = StyleManager::generateAlias($arrArchives[ $objStyleGroup->pid ]['identifier'], $objStyleGroup->alias); $strFieldId = $this->strId . '_' . $strId; $strFieldName = $this->strName . '[' . $strId . ']'; From e6939e5ee1ab0fa6489259e9204f7d6a98835122 Mon Sep 17 00:00:00 2001 From: doishub Date: Mon, 24 Jan 2022 13:40:51 +0100 Subject: [PATCH 09/48] Fixed error when no bundle configuration was submitted --- src/Resources/contao/classes/Config.php | 38 +++++++++++++++++++------ 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/Resources/contao/classes/Config.php b/src/Resources/contao/classes/Config.php index e30c12d..bea5479 100644 --- a/src/Resources/contao/classes/Config.php +++ b/src/Resources/contao/classes/Config.php @@ -55,12 +55,15 @@ public static function getGroups(?string $table=null): ?array $arrObjStyleGroups = null; - foreach (static::$arrGroups as $objStyleGroup) + if(static::$arrGroups) { - // Skip if the group is not allowed for the current table - if(StyleManager::isVisibleGroup($objStyleGroup, $table)) + foreach (static::$arrGroups as $objStyleGroup) { - $arrObjStyleGroups[] = $objStyleGroup; + // Skip if the group is not allowed for the current table + if(StyleManager::isVisibleGroup($objStyleGroup, $table)) + { + $arrObjStyleGroups[] = $objStyleGroup; + } } } @@ -72,19 +75,38 @@ public static function getGroups(?string $table=null): ?array */ public static function getBundleConfigurationFiles(): ?array { + $projectDir = System::getContainer()->getParameter('kernel.project_dir'); $arrFiles = System::getContainer()->get('contao.resource_finder')->findIn('templates')->files()->name('style-manager-*.xml'); + $arrBundleConfigs = null; - if($arrFiles->hasResults()) + if($projectTemplates = glob($projectDir . '/templates/style-manager-*.xml')) { - $projectDir = System::getContainer()->getParameter('kernel.project_dir'); - $arrBundleConfigs = null; + foreach ($projectTemplates as $template) + { + $arrBundleConfigs[basename($template) . ' (/templates)'] = str_replace($projectDir, '', $template); + } + } + if($arrFiles->hasResults()) + { foreach ($arrFiles as $file) { $strRelpath = $file->getRealPath(); - $arrBundleConfigs[basename($strRelpath)] = str_replace($projectDir, '', $strRelpath); + + try{ + $filePath = str_replace('\\', "/",$strRelpath); + $bundleName = str_replace("/vendor/", "", substr($filePath, strpos($filePath, '/vendor/'))); + $bundleName = substr($bundleName, 0, strpos($bundleName, '/src')); + }catch (\Exception $e){ + $bundleName = 'vendor'; + } + + $arrBundleConfigs[basename($strRelpath) . ' (' . $bundleName . ')'] = str_replace($projectDir, '', $strRelpath); } + } + if($arrBundleConfigs) + { return $arrBundleConfigs; } From 8a63281d66c3679e9e0d08ed75a07e76f8aa43f3 Mon Sep 17 00:00:00 2001 From: doishub Date: Mon, 24 Jan 2022 16:43:41 +0100 Subject: [PATCH 10/48] Update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4280bd9..7774cbc 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ This plugin is designed to simplify theme customizations without the need of man - Passing variables to the template - Formatting output using predefined methods or your own - Import / Export - - Automatic import of configurations from third-party bundles + - Automatic import of configurations from third-party bundles [![new](https://img.shields.io/badge/-new-brightgreen?style=flat-square)](#contao-component-style-manager) - Available for - Layouts - Pages From 4ac8094c81b1ff42383fdc65d9b9cc21e18d6e3e Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 3 Feb 2022 10:25:53 +0100 Subject: [PATCH 11/48] Update contao version requirement --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index efe035c..16bfc1b 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ "require":{ "php":">=7.4", "ext-dom": "*", - "contao/core-bundle":"^4.10" + "contao/core-bundle":">=4.9.22" }, "require-dev": { "contao/manager-plugin": "^2.0" From 2f9457a0230655f0919c02e4ffad4b062a275419 Mon Sep 17 00:00:00 2001 From: Sebastian Zoglowek Date: Mon, 14 Feb 2022 10:08:45 +0100 Subject: [PATCH 12/48] [Update] Change utf8_bin collation to binary --- src/Resources/contao/dca/tl_style_manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Resources/contao/dca/tl_style_manager.php b/src/Resources/contao/dca/tl_style_manager.php index 530fb22..d7fbc65 100644 --- a/src/Resources/contao/dca/tl_style_manager.php +++ b/src/Resources/contao/dca/tl_style_manager.php @@ -124,7 +124,7 @@ 'inputType' => 'text', 'search' => true, 'eval' => array('rgxp'=>'alias', 'maxlength'=>128, 'tl_class'=>'w50'), - 'sql' => "varchar(255) COLLATE utf8_bin NOT NULL default ''", + 'sql' => "varchar(255) BINARY NOT NULL default ''", 'save_callback' => array ( array('tl_style_manager', 'generateAlias') From b12758b545cf0123a21e655d2f47b6dd1e18851f Mon Sep 17 00:00:00 2001 From: doishub Date: Wed, 30 Mar 2022 10:15:45 +0200 Subject: [PATCH 13/48] Fixed a bug in the findByTableAndConfiguration method; If no configuration files were found, `null` was always returned, even if definitions existed in the backend --- src/Resources/contao/models/StyleManagerModel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Resources/contao/models/StyleManagerModel.php b/src/Resources/contao/models/StyleManagerModel.php index 012b9e5..56d50ba 100644 --- a/src/Resources/contao/models/StyleManagerModel.php +++ b/src/Resources/contao/models/StyleManagerModel.php @@ -196,9 +196,9 @@ public static function findByTableAndConfiguration($strTable, array $arrOptions= usort($arrObjStyleGroups, function($a, $b) { return ($a->sorting <=> $b->sorting); }); - } - return $arrObjStyleGroups; + return $arrObjStyleGroups; + } } return $objGroups; From 070102351bbb1522d87a2df98937b448b7bf965e Mon Sep 17 00:00:00 2001 From: doishub Date: Wed, 30 Mar 2022 10:25:21 +0200 Subject: [PATCH 14/48] Show the separator line only if fields are already output before it --- src/Resources/public/stylemanager.css | 20 +++++++++++++------- src/Resources/public/stylemanager.css.map | 2 +- src/Resources/public/stylemanager.scss | 21 +++++++++++++-------- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/Resources/public/stylemanager.css b/src/Resources/public/stylemanager.css index 95acdcf..1331087 100644 --- a/src/Resources/public/stylemanager.css +++ b/src/Resources/public/stylemanager.css @@ -48,11 +48,22 @@ background: #fdfdfd; padding: 5px 5px 15px 5px; } +.widget.stylemanager .tab-content > hr { + display: none; + float: left; + clear: both; + width: calc(100% - 30px); + margin: 22px 15px 6px; + background: #e6e6e8; +} .widget.stylemanager .tab-content > div { margin-left: 15px; margin-right: 15px; min-height: 80px; } +.widget.stylemanager .tab-content > div + hr { + display: block; +} .widget.stylemanager .tab-content > div.seperator, .widget.stylemanager .tab-content > div.separator { clear: both; } @@ -69,13 +80,6 @@ line-height: 1.3; border-bottom: 1px solid #e6e6e8; } -.widget.stylemanager .tab-content > hr { - float: left; - clear: both; - width: calc(100% - 30px); - margin: 22px 15px 6px; - background: #e6e6e8; -} .widget.stylemanager .tab-content:after { display: block; content: ""; @@ -161,3 +165,5 @@ width: calc(100% - 30px); } } + +/*# sourceMappingURL=stylemanager.css.map */ diff --git a/src/Resources/public/stylemanager.css.map b/src/Resources/public/stylemanager.css.map index 37e846b..c9cfb14 100644 --- a/src/Resources/public/stylemanager.css.map +++ b/src/Resources/public/stylemanager.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["stylemanager.scss"],"names":[],"mappings":"AAMM;EACE;;;AAQN;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAEA;EACE;;AAIJ;EACE;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACD;EACA;;AAIH;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EA0BE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAOJ;EACE;;;AAIJ;EAOQ;IACE;IACA;;EAEA;IACE;;;AASZ;EAOQ;IACE;IACA;;EAEA;IACE","file":"stylemanager.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["stylemanager.scss"],"names":[],"mappings":"AAMM;EACE;;;AAQN;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAEA;EACE;;AAIJ;EACE;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAEA;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACE;EACD;EACA;;AAIH;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EA0BE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAOJ;EACE;;;AAIJ;EAOQ;IACE;IACA;;EAEA;IACE;;;AASZ;EAOQ;IACE;IACA;;EAEA;IACE","file":"stylemanager.css"} \ No newline at end of file diff --git a/src/Resources/public/stylemanager.scss b/src/Resources/public/stylemanager.scss index ff94f9e..681bbc0 100644 --- a/src/Resources/public/stylemanager.scss +++ b/src/Resources/public/stylemanager.scss @@ -67,11 +67,24 @@ background: #fdfdfd; padding: 5px 5px 15px 5px; + > hr{ + display: none; + float: left; + clear: both; + width: calc(100% - 30px); + margin: 22px 15px 6px; + background: #e6e6e8; + } + > div{ margin-left: 15px; margin-right: 15px; min-height: 80px; + + hr { + display: block; + } + &.seperator, &.separator{ clear: both; @@ -92,14 +105,6 @@ } } - > hr{ - float: left; - clear: both; - width: calc(100% - 30px); - margin: 22px 15px 6px; - background: #e6e6e8; - } - &:after{ display: block; content: ''; From 08feb6d0c20b6893b9e2cbadd49cc27a462ab30e Mon Sep 17 00:00:00 2001 From: doishub Date: Fri, 1 Apr 2022 09:45:45 +0200 Subject: [PATCH 15/48] Fixes an error when there are no archives and the migration is executed --- src/Resources/contao/classes/Sync.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Resources/contao/classes/Sync.php b/src/Resources/contao/classes/Sync.php index f94b9e8..694124f 100644 --- a/src/Resources/contao/classes/Sync.php +++ b/src/Resources/contao/classes/Sync.php @@ -75,6 +75,11 @@ public function performObjectConversion($table = null): void $objArchives = StyleManagerArchiveModel::findAll(); $arrArchives = []; + if(null === $objArchives) + { + return; + } + foreach ($objArchives as $objArchive) { $arrArchives[ $objArchive->id ] = $objArchive->identifier; From 32a71550e278fbccfa82d08e6bfdf41aad9ea2d3 Mon Sep 17 00:00:00 2001 From: doishub Date: Fri, 1 Apr 2022 11:39:07 +0200 Subject: [PATCH 16/48] Make export method more flexible --- src/Resources/contao/classes/Sync.php | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/Resources/contao/classes/Sync.php b/src/Resources/contao/classes/Sync.php index 694124f..97f7abb 100644 --- a/src/Resources/contao/classes/Sync.php +++ b/src/Resources/contao/classes/Sync.php @@ -461,20 +461,21 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? /** * Export StyleManager data * - * @param DataContainer $dc - * * @throws \Exception */ - public function exportStyleManager(DataContainer $dc) + public function exportStyleManager(?DataContainer $dc, $objArchives = null, bool $blnSendToBrowser = true) { // Create a new XML document $xml = new \DOMDocument('1.0', 'UTF-8'); $xml->formatOutput = true; // Archives - $objArchive = StyleManagerArchiveModel::findAll(['order' => 'groupAlias,sorting']); + if(null === $objArchives) + { + $objArchives = StyleManagerArchiveModel::findAll(['order' => 'groupAlias,sorting']); + } - if (null === $objArchive) + if (null === $objArchives) { Message::addError($GLOBALS['TL_LANG']['ERR']['noStyleManagerConfigFound']); self::redirect(self::getReferer()); @@ -485,9 +486,9 @@ public function exportStyleManager(DataContainer $dc) $archives = $xml->appendChild($archives); // Add the archives - while($objArchive->next()) + while($objArchives->next()) { - $this->addArchiveData($xml, $archives, $objArchive); + $this->addArchiveData($xml, $archives, $objArchives); } // Generate temp name @@ -498,6 +499,11 @@ public function exportStyleManager(DataContainer $dc) $objFile->write($xml->saveXML()); $objFile->close(); + if(!$blnSendToBrowser) + { + return $objFile; + } + $objFile->sendToBrowser('style-manager-export.xml'); } From 5bfeafaa21e9ffb3e032917013aa3b152db6ae42 Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 14 Apr 2022 10:05:08 +0200 Subject: [PATCH 17/48] Disable the possibility to import bundle configurations if they are not enabled --- src/Resources/contao/classes/Sync.php | 2 ++ .../languages/de/tl_style_manager_archive.xlf | 8 +++-- .../languages/en/tl_style_manager_archive.xlf | 5 +++- .../languages/fr/tl_style_manager_archive.xlf | 8 +++-- .../backend/be_style_manager_import.html5 | 30 +++++++++++-------- 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/Resources/contao/classes/Sync.php b/src/Resources/contao/classes/Sync.php index 97f7abb..ff3eda8 100644 --- a/src/Resources/contao/classes/Sync.php +++ b/src/Resources/contao/classes/Sync.php @@ -214,10 +214,12 @@ public function importStyleManager() $template->descSource = $GLOBALS['TL_LANG']['tl_style_manager_archive']['source'][1]; $template->fieldUpload = $objUploader->generateMarkup(); + $template->useBundleConfig = System::getContainer()->getParameter('contao_component_style_manager.use_bundle_config'); $template->labelImport = $GLOBALS['TL_LANG']['tl_style_manager_archive']['import'][0]; $template->labelBundleConfig = $GLOBALS['TL_LANG']['tl_style_manager_archive']['headingBundleConfig']; $template->emptyBundleFiles = $GLOBALS['TL_LANG']['tl_style_manager_archive']['emptyBundleConfig']; $template->descBundleFiles = $GLOBALS['TL_LANG']['tl_style_manager_archive']['descBundleConfig']; + $template->activeDescBundleFiles = $GLOBALS['TL_LANG']['tl_style_manager_archive']['activateBundleConfig']; $template->bundleFiles = \Oveleon\ContaoComponentStyleManager\Config::getBundleConfigurationFiles() ?? []; diff --git a/src/Resources/contao/languages/de/tl_style_manager_archive.xlf b/src/Resources/contao/languages/de/tl_style_manager_archive.xlf index 982065a..eb606a2 100644 --- a/src/Resources/contao/languages/de/tl_style_manager_archive.xlf +++ b/src/Resources/contao/languages/de/tl_style_manager_archive.xlf @@ -19,8 +19,12 @@ Keine Konfigurationen vorhanden
- Please note, as soon as the files displayed here are imported, they overwrite the configurations of the external bundles. So this function is only useful if you really want to overwrite or adjust the configurations. If they are deleted again, the configurations from the external bundles are automatically used again. - Bitte beachten Sie, sobald die hier angezeigten Dateien importiert werden, überschreiben sie die Konfigurationen der externen Bundles. Diese Funktion ist also nur sinnvoll, wenn Sie die Konfigurationen wirklich überschreiben oder anpassen wollen. Wenn diese wieder gelöscht werden, werden automatisch wieder die Konfigurationen aus den externen Bundles verwendet. + Please note that the configurations displayed here are automatically available in all areas and do not have to be imported. With the import of these files, the bundle configurations are provided for the backend and overwrite from this moment on all properties that come from the bundle. If these are deleted again, the original from the bundle is used. + Bitte beachten Sie, dass die hier angezeigten Konfigurationen automatisch in allen Bereichen zur Verfügung stehen und nicht zwingend importiert werden müssen. Mit dem Import dieser Dateien werden die Bundle-Konfigurationen für das Backend bereitgestellt und überschreiben ab diesen Moment alle Eigenschaften, welche aus dem Bundle kommen. Sollten diese wieder gelöscht werden, wird das Original aus dem Bundle herangezogen. + + + The bundle configuration has been disabled for this project. To have configurations of other bundles imported, you have to activate them first. + Die Bundle-Konfiguration wurde für diese Projekt ausgeschaltet. Um Konfigurationen anderer Bundles importieren zu lassen, müssen Sie diese vorerst aktivieren. Add category diff --git a/src/Resources/contao/languages/en/tl_style_manager_archive.xlf b/src/Resources/contao/languages/en/tl_style_manager_archive.xlf index 9175343..78f8482 100644 --- a/src/Resources/contao/languages/en/tl_style_manager_archive.xlf +++ b/src/Resources/contao/languages/en/tl_style_manager_archive.xlf @@ -15,7 +15,10 @@ No configurations available - Please note, as soon as the files displayed here are imported, they overwrite the configurations of the external bundles. So this function is only useful if you really want to overwrite or adjust the configurations. If they are deleted again, the configurations from the external bundles are automatically used again. + Please note that the configurations displayed here are automatically available in all areas and do not have to be imported. With the import of these files, the bundle configurations are provided for the backend and overwrite from this moment on all properties that come from the bundle. If these are deleted again, the original from the bundle is used. + + + The bundle configuration has been disabled for this project. To have configurations of other bundles imported, you have to activate them first. Add category diff --git a/src/Resources/contao/languages/fr/tl_style_manager_archive.xlf b/src/Resources/contao/languages/fr/tl_style_manager_archive.xlf index 12309f4..60abd21 100644 --- a/src/Resources/contao/languages/fr/tl_style_manager_archive.xlf +++ b/src/Resources/contao/languages/fr/tl_style_manager_archive.xlf @@ -19,8 +19,12 @@ Aucune configuration disponible - Please note, as soon as the files displayed here are imported, they overwrite the configurations of the external bundles. So this function is only useful if you really want to overwrite or adjust the configurations. If they are deleted again, the configurations from the external bundles are automatically used again. - Veuillez noter que dès que les fichiers affichés ici sont importés, ils écrasent les configurations des paquets externes. Cette fonction n'est donc utile que si vous souhaitez réellement écraser ou ajuster les configurations. Si vous les supprimez à nouveau, les configurations des paquets externes sont automatiquement réutilisées. + Please note that the configurations displayed here are automatically available in all areas and do not have to be imported. With the import of these files, the bundle configurations are provided for the backend and overwrite from this moment on all properties that come from the bundle. If these are deleted again, the original from the bundle is used. + Veuillez noter que les configurations affichées ici sont automatiquement disponibles dans tous les domaines et ne doivent pas obligatoirement être importées. Avec l'importation de ces fichiers, les configurations du bundle sont mises à disposition pour le backend et remplacent dès ce moment toutes les propriétés provenant du bundle. Si celles-ci devaient être supprimées, l'original du bundle serait utilisé. + + + The bundle configuration has been disabled for this project. To have configurations of other bundles imported, you have to activate them first. + La configuration des bundles a été désactivée pour ce projet. Pour pouvoir importer les configurations d'autres bundles, vous devez d'abord les activer. Add category diff --git a/src/Resources/contao/templates/backend/be_style_manager_import.html5 b/src/Resources/contao/templates/backend/be_style_manager_import.html5 index f971516..430318b 100644 --- a/src/Resources/contao/templates/backend/be_style_manager_import.html5 +++ b/src/Resources/contao/templates/backend/be_style_manager_import.html5 @@ -27,19 +27,25 @@

labelBundleConfig ?>

- bundleFiles)): ?> - - bundleFiles as $fileName => $filePath): $strId = Contao\StringUtil::prepareSlug($fileName); ?> - - - - - -
-

descBundleFiles?>

- + useBundleConfig): ?> + bundleFiles)): ?> +

descBundleFiles?>

+ + + bundleFiles as $fileName => $filePath): $strId = Contao\StringUtil::prepareSlug($fileName); ?> + + + + + +
+ + + +

emptyBundleFiles?>

+ -

emptyBundleFiles?>

+

activeDescBundleFiles?>

From 17a91313506feb9c3d958921369f805a3cb63074 Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 14 Apr 2022 11:44:51 +0200 Subject: [PATCH 18/48] - Fixed merging of same groups and categories from different bundle configurations during import - Removed unnecessary importing of bundle configurations in the category overview --- src/Resources/contao/classes/Sync.php | 40 +++++++++++++++---- .../contao/dca/tl_style_manager_archive.php | 4 +- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/Resources/contao/classes/Sync.php b/src/Resources/contao/classes/Sync.php index ff3eda8..61fe46d 100644 --- a/src/Resources/contao/classes/Sync.php +++ b/src/Resources/contao/classes/Sync.php @@ -290,14 +290,24 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? } // Check if archive exists - $archiveExists = function (string $identifier) : bool + $archiveExists = function (string $identifier) use ($blnSave, $arrStyleArchives) : bool { + if(!$blnSave) + { + return array_key_exists($identifier, $arrStyleArchives); + } + return $this->Database->prepare("SELECT identifier FROM tl_style_manager_archive WHERE identifier=?")->execute($identifier)->numRows > 0; }; // Check if children exists - $childrenExists = function (string $alias, string $pid) : bool + $childrenExists = function (string $alias, string $pid) use($blnSave, $arrStyleGroups) : bool { + if(!$blnSave) + { + return array_key_exists($alias, $arrStyleGroups); + } + return $this->Database->prepare("SELECT alias FROM tl_style_manager WHERE alias=? AND pid=?")->execute($alias, $pid)->numRows > 0; }; @@ -309,8 +319,15 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? if(!$blnSave || !$archiveExists($identifier)) { - $objArchive = new StyleManagerArchiveModel(); - $objArchive->id = ++$intArchiveId; + if(!$blnSave && $archiveExists($identifier)) + { + $objArchive = $arrStyleArchives[$identifier]; + } + else + { + $objArchive = new StyleManagerArchiveModel(); + $objArchive->id = ++$intArchiveId; + } } else { @@ -346,8 +363,15 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? if(!$blnSave || !$childrenExists($alias, $objArchive->id)) { - $objChildren = new StyleManagerModel(); - $objChildren->id = ++$intGroupId; + if(!$blnSave && $childrenExists($alias, $objArchive->id)) + { + $objChildren = $arrStyleGroups[$alias]; + } + else + { + $objChildren = new StyleManagerModel(); + $objChildren->id = ++$intGroupId; + } } else { @@ -426,7 +450,7 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? } else { - $arrStyleGroups[] = $objChildren->current(); + $arrStyleGroups[ $objChildren->alias ] = $objChildren->current(); } } } @@ -439,7 +463,7 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? } else { - $arrStyleArchives[] = $objArchive->current(); + $arrStyleArchives[ $objArchive->identifier ] = $objArchive->current(); } } diff --git a/src/Resources/contao/dca/tl_style_manager_archive.php b/src/Resources/contao/dca/tl_style_manager_archive.php index a0bc23f..7375221 100644 --- a/src/Resources/contao/dca/tl_style_manager_archive.php +++ b/src/Resources/contao/dca/tl_style_manager_archive.php @@ -273,9 +273,7 @@ public function importConfig(string $href, string $label, string $title, string { if(System::getContainer()->getParameter('contao_component_style_manager.use_bundle_config')) { - $bundleConfig = Config::getInstance(); - - if($arrFiles = $bundleConfig::getBundleConfigurationFiles()) + if($arrFiles = Config::getBundleConfigurationFiles()) { $label .= ' (' . count($arrFiles) . ')'; } From 5e157faf2b34ba58450f858abcb31dafc73ce496 Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 14 Apr 2022 12:25:47 +0200 Subject: [PATCH 19/48] Display of the active bundle configurations in the overview --- .../contao/dca/tl_style_manager_archive.php | 27 +++++++++++++++++ .../languages/de/tl_style_manager_archive.xlf | 10 +++++-- .../languages/en/tl_style_manager_archive.xlf | 5 +++- .../languages/fr/tl_style_manager_archive.xlf | 8 +++-- src/Resources/public/stylemanager.css | 24 +++++++++++++++ src/Resources/public/stylemanager.css.map | 2 +- src/Resources/public/stylemanager.scss | 29 +++++++++++++++++++ 7 files changed, 98 insertions(+), 7 deletions(-) diff --git a/src/Resources/contao/dca/tl_style_manager_archive.php b/src/Resources/contao/dca/tl_style_manager_archive.php index 7375221..19fa8ef 100644 --- a/src/Resources/contao/dca/tl_style_manager_archive.php +++ b/src/Resources/contao/dca/tl_style_manager_archive.php @@ -68,6 +68,13 @@ 'href' => 'act=select', 'class' => 'header_edit_all', 'attributes' => 'onclick="Backend.getScrollOffset()" accesskey="e"' + ), + 'config' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_style_manager_archive']['headingActiveBundles'], + 'href' => 'key=import', + 'class' => 'header_style_manager_config', + 'button_callback' => array('tl_style_manager_archive', 'activeConfig') ) ), 'operations' => array @@ -281,4 +288,24 @@ public function importConfig(string $href, string $label, string $title, string return '' . $label . ' '; } + + /** + * Return the configurations label + */ + public function activeConfig(string $href, string $label, string $title, string $class, string $attributes): string + { + if(System::getContainer()->getParameter('contao_component_style_manager.use_bundle_config')) + { + $count = 0; + + if($arrFiles = Config::getBundleConfigurationFiles()) + { + $count = count($arrFiles); + } + + return ''. $label .': ' . $count . ''; + } + + return ''; + } } diff --git a/src/Resources/contao/languages/de/tl_style_manager_archive.xlf b/src/Resources/contao/languages/de/tl_style_manager_archive.xlf index eb606a2..1b56386 100644 --- a/src/Resources/contao/languages/de/tl_style_manager_archive.xlf +++ b/src/Resources/contao/languages/de/tl_style_manager_archive.xlf @@ -11,8 +11,12 @@ Konfiguration
- Available configurations via external bundles - Vorhandene Konfigurationen über externe Bundles + Bundle configurations + Bundle-Konfigurationen + + + Active configurations + Aktive Konfigurationen No configurations available @@ -24,7 +28,7 @@ The bundle configuration has been disabled for this project. To have configurations of other bundles imported, you have to activate them first. - Die Bundle-Konfiguration wurde für diese Projekt ausgeschaltet. Um Konfigurationen anderer Bundles importieren zu lassen, müssen Sie diese vorerst aktivieren. + Die Bundle-Konfiguration wurde für dieses Projekt ausgeschaltet. Um Konfigurationen anderer Bundles importieren zu lassen, müssen Sie diese vorerst aktivieren. Add category diff --git a/src/Resources/contao/languages/en/tl_style_manager_archive.xlf b/src/Resources/contao/languages/en/tl_style_manager_archive.xlf index 78f8482..6e54bec 100644 --- a/src/Resources/contao/languages/en/tl_style_manager_archive.xlf +++ b/src/Resources/contao/languages/en/tl_style_manager_archive.xlf @@ -9,7 +9,10 @@ Config - Available configurations via external bundles + Bundle configurations + + + Active configurations No configurations available diff --git a/src/Resources/contao/languages/fr/tl_style_manager_archive.xlf b/src/Resources/contao/languages/fr/tl_style_manager_archive.xlf index 60abd21..13ec43b 100644 --- a/src/Resources/contao/languages/fr/tl_style_manager_archive.xlf +++ b/src/Resources/contao/languages/fr/tl_style_manager_archive.xlf @@ -11,8 +11,12 @@ Configuration - Available configurations via external bundles - Configurations disponibles via des faisceaux externes + Bundle configurations + Configuration des paquets + + + Active configurations + Configurations actives No configurations available diff --git a/src/Resources/public/stylemanager.css b/src/Resources/public/stylemanager.css index 1331087..fa46559 100644 --- a/src/Resources/public/stylemanager.css +++ b/src/Resources/public/stylemanager.css @@ -147,6 +147,10 @@ display: none !important; } +#tl_buttons .header_style_manager_config { + display: none; +} + @media (min-width: 600px) { .widget.stylemanager .tab-content > div { width: calc(50% - 30px); @@ -156,6 +160,26 @@ width: calc(100% - 30px); } } +@media (min-width: 770px) { + #tl_buttons { + position: relative; + } + #tl_buttons .header_style_manager_config { + position: absolute; + top: 8px; + left: 18px; + display: inline-block; + padding: 4px 9px; + background: #74B739; + color: #fff; + border-radius: 10px; + font-size: 0.9em; + line-height: 1; + } + #tl_buttons .header_style_manager_import sup { + display: none; + } +} @media (min-width: 1200px) { .widget.stylemanager .tab-content > div { width: calc(33.333% - 30px); diff --git a/src/Resources/public/stylemanager.css.map b/src/Resources/public/stylemanager.css.map index c9cfb14..ad2389e 100644 --- a/src/Resources/public/stylemanager.css.map +++ b/src/Resources/public/stylemanager.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["stylemanager.scss"],"names":[],"mappings":"AAMM;EACE;;;AAQN;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAEA;EACE;;AAIJ;EACE;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAEA;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACE;EACD;EACA;;AAIH;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EA0BE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAOJ;EACE;;;AAIJ;EAOQ;IACE;IACA;;EAEA;IACE;;;AASZ;EAOQ;IACE;IACA;;EAEA;IACE","file":"stylemanager.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["stylemanager.scss"],"names":[],"mappings":"AAMM;EACE;;;AAQN;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAEA;EACE;;AAIJ;EACE;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAEA;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACE;EACD;EACA;;AAIH;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EA0BE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAOJ;EACE;;;AAMF;EACE;;;AAIJ;EAOQ;IACE;IACA;;EAEA;IACE;;;AAQZ;EACE;IACE;;EAEA;IACE;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EAGF;IACE;;;AAKN;EAOQ;IACE;IACA;;EAEA;IACE","file":"stylemanager.css"} \ No newline at end of file diff --git a/src/Resources/public/stylemanager.scss b/src/Resources/public/stylemanager.scss index 681bbc0..77ddc9a 100644 --- a/src/Resources/public/stylemanager.scss +++ b/src/Resources/public/stylemanager.scss @@ -185,6 +185,13 @@ } } +#tl_buttons{ + + .header_style_manager_config{ + display: none; + } +} + @media (min-width: 600px) { .widget { @@ -205,6 +212,28 @@ } } +@media (min-width: 770px) { + #tl_buttons{ + position: relative; + + .header_style_manager_config{ + position: absolute; + top: 8px; + left: 18px; + display: inline-block; + padding: 4px 9px; + background: #74B739; + color: #fff; + border-radius: 10px; + font-size: .9em; + line-height: 1; + } + + .header_style_manager_import sup{ + display: none; + } + } +} @media (min-width: 1200px) { .widget { From ef4d7f0e61eea34e877a428d56de106178bc5f22 Mon Sep 17 00:00:00 2001 From: doishub Date: Wed, 11 May 2022 16:57:42 +0200 Subject: [PATCH 20/48] Bugfix: When importing multiple bundle configurations the same aliases were overwritten --- src/Resources/contao/classes/Sync.php | 33 ++++++++++++++------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/Resources/contao/classes/Sync.php b/src/Resources/contao/classes/Sync.php index 61fe46d..6487705 100644 --- a/src/Resources/contao/classes/Sync.php +++ b/src/Resources/contao/classes/Sync.php @@ -271,21 +271,21 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? $archives = $archives->item(0)->childNodes; }else return null; - if($blnSave) + // Lock the tables + $arrLocks = array + ( + 'tl_style_manager_archive' => 'WRITE', + 'tl_style_manager' => 'WRITE' + ); + + // Load the DCAs of the locked tables + foreach (array_keys($arrLocks) as $table) { - // Lock the tables - $arrLocks = array - ( - 'tl_style_manager_archive' => 'WRITE', - 'tl_style_manager' => 'WRITE' - ); - - // Load the DCAs of the locked tables - foreach (array_keys($arrLocks) as $table) - { - $this->loadDataContainer($table); - } + $this->loadDataContainer($table); + } + if($blnSave) + { $this->Database->lockTables($arrLocks); } @@ -305,7 +305,7 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? { if(!$blnSave) { - return array_key_exists($alias, $arrStyleGroups); + return array_key_exists($pid . '_' . $alias, $arrStyleGroups); } return $this->Database->prepare("SELECT alias FROM tl_style_manager WHERE alias=? AND pid=?")->execute($alias, $pid)->numRows > 0; @@ -365,7 +365,7 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? { if(!$blnSave && $childrenExists($alias, $objArchive->id)) { - $objChildren = $arrStyleGroups[$alias]; + $objChildren = $arrStyleGroups[$objArchive->id . '_' . $alias]; } else { @@ -450,7 +450,8 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? } else { - $arrStyleGroups[ $objChildren->alias ] = $objChildren->current(); + $strKey = $objChildren->pid . '_' . $objChildren->alias; + $arrStyleGroups[ $strKey ] = $objChildren->current(); } } } From 2373784b56575a0e7e064c149a50dd5a0645a82e Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 12 May 2022 12:05:10 +0200 Subject: [PATCH 21/48] Added strict mode to be able to replace or overwrite bundle configurations via the backend. --- composer.json | 1 + src/DependencyInjection/Configuration.php | 3 + .../ContaoComponentStyleManagerExtension.php | 1 + src/Resources/contao/classes/Config.php | 4 +- src/Resources/contao/classes/Styles.php | 8 +- src/Resources/contao/classes/Sync.php | 122 +++++++++++++++++- .../contao/models/StyleManagerModel.php | 45 +++++-- 7 files changed, 163 insertions(+), 21 deletions(-) diff --git a/composer.json b/composer.json index 16bfc1b..5e3f924 100644 --- a/composer.json +++ b/composer.json @@ -19,6 +19,7 @@ ], "require":{ "php":">=7.4", + "ext-json": "*", "ext-dom": "*", "contao/core-bundle":">=4.9.22" }, diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 1ae0107..aeb2196 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -23,6 +23,9 @@ public function getConfigTreeBuilder() ->booleanNode('use_bundle_config') ->defaultTrue() ->end() + ->booleanNode('strict') + ->defaultFalse() + ->end() ->end() ; diff --git a/src/DependencyInjection/ContaoComponentStyleManagerExtension.php b/src/DependencyInjection/ContaoComponentStyleManagerExtension.php index a1fc784..78318de 100644 --- a/src/DependencyInjection/ContaoComponentStyleManagerExtension.php +++ b/src/DependencyInjection/ContaoComponentStyleManagerExtension.php @@ -22,5 +22,6 @@ public function load(array $configs, ContainerBuilder $container) $loader->load('commands.yml'); $container->setParameter('contao_component_style_manager.use_bundle_config', $config['use_bundle_config']); + $container->setParameter('contao_component_style_manager.strict', $config['strict']); } } diff --git a/src/Resources/contao/classes/Config.php b/src/Resources/contao/classes/Config.php index bea5479..bb21982 100644 --- a/src/Resources/contao/classes/Config.php +++ b/src/Resources/contao/classes/Config.php @@ -57,12 +57,12 @@ public static function getGroups(?string $table=null): ?array if(static::$arrGroups) { - foreach (static::$arrGroups as $objStyleGroup) + foreach (static::$arrGroups as $combinedAlias => $objStyleGroup) { // Skip if the group is not allowed for the current table if(StyleManager::isVisibleGroup($objStyleGroup, $table)) { - $arrObjStyleGroups[] = $objStyleGroup; + $arrObjStyleGroups[ $combinedAlias ] = $objStyleGroup; } } } diff --git a/src/Resources/contao/classes/Styles.php b/src/Resources/contao/classes/Styles.php index d46504c..4613ff1 100644 --- a/src/Resources/contao/classes/Styles.php +++ b/src/Resources/contao/classes/Styles.php @@ -65,7 +65,7 @@ public function get($identifier, $arrGroups=null) foreach ($arrGroups as $groupAlias) { - if($value = $this->getGroupValue($this->styles[ $identifier ][ $groupAlias ])) + if($value = $this->getGroupValue($this->styles[ $identifier ][ $groupAlias ] ?? null)) { $collection[] = $value; } @@ -103,7 +103,7 @@ public function prepare($identifier, $arrGroups=null) */ public function format($format, $method='') { - if(!$format || $this->styles === null || !is_array($this->styles[ $this->currIdentifier ])) + if(!$format || $this->styles === null || !is_array(($this->styles[ $this->currIdentifier ] ?? null))) { return ''; } @@ -129,7 +129,7 @@ public function format($format, $method='') { foreach ($this->currGroups as $alias) { - if(($value = $this->getGroupValue($this->styles[ $this->currIdentifier ][ $alias ])) !== '') + if(($value = $this->getGroupValue($this->styles[ $this->currIdentifier ][ $alias ] ?? null)) !== '') { $arrValues[ $alias ] = $this->parseValueType($value); } @@ -190,7 +190,7 @@ private function getCategoryValues($arrVariables) */ private function getGroupValue($arrVariable) { - return $arrVariable['value']; + return $arrVariable['value'] ?? null; } /** diff --git a/src/Resources/contao/classes/Sync.php b/src/Resources/contao/classes/Sync.php index 6487705..d281f0c 100644 --- a/src/Resources/contao/classes/Sync.php +++ b/src/Resources/contao/classes/Sync.php @@ -10,6 +10,7 @@ use Contao\Backend; use Contao\BackendTemplate; use Contao\Config; +use Contao\Controller; use Contao\DataContainer; use Contao\Environment; use Contao\File; @@ -305,7 +306,7 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? { if(!$blnSave) { - return array_key_exists($pid . '_' . $alias, $arrStyleGroups); + return array_key_exists($alias, $arrStyleGroups); } return $this->Database->prepare("SELECT alias FROM tl_style_manager WHERE alias=? AND pid=?")->execute($alias, $pid)->numRows > 0; @@ -361,11 +362,13 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? $alias = $children->item($c)->getAttribute('alias'); $fields = $children->item($c)->childNodes; - if(!$blnSave || !$childrenExists($alias, $objArchive->id)) + $strChildAlias = self::combineAliases($objArchive->identifier, $alias); + + if(!$blnSave || !$childrenExists($strChildAlias, $objArchive->id)) { - if(!$blnSave && $childrenExists($alias, $objArchive->id)) + if(!$blnSave && $childrenExists($strChildAlias, $objArchive->id)) { - $objChildren = $arrStyleGroups[$objArchive->id . '_' . $alias]; + $objChildren = $arrStyleGroups[$strChildAlias]; } else { @@ -398,7 +401,7 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? if($objChildren->{$strName}) { $arrClasses = StringUtil::deserialize($objChildren->{$strName}, true); - $arrExists = $this->flattenKeyValueArray($arrClasses); + $arrExists = self::flattenKeyValueArray($arrClasses); $arrValues = StringUtil::deserialize($strValue, true); foreach($arrValues as $cssClass) @@ -450,7 +453,7 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? } else { - $strKey = $objChildren->pid . '_' . $objChildren->alias; + $strKey = self::combineAliases($objArchive->identifier, $objChildren->alias); $arrStyleGroups[ $strKey ] = $objChildren->current(); } } @@ -485,6 +488,106 @@ public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ? return [$arrStyleArchives, $arrStyleGroups]; } + /** + * Merge group objects + */ + public static function mergeGroupObjects(?StyleManagerModel $objOriginal, ?StyleManagerModel $objMerge, ?array $skipFields = null, bool $skipEmpty = true, $forceOverwrite = true): ?StyleManagerModel + { + if(null === $objOriginal || null === $objMerge) + { + return $objOriginal; + } + + Controller::loadDataContainer('tl_style_manager'); + + foreach ($objMerge->row() as $field => $value) + { + if( + ($skipEmpty && (!$value || strtolower($value) === 'null')) || + (null !== $skipFields && in_array($field, $skipFields)) + ) + { + continue; + } + + switch($field) + { + // Merge and manipulation of existing classes + case 'cssClasses': + if($objOriginal->{$field}) + { + $arrClasses = StringUtil::deserialize($objOriginal->{$field}, true); + $arrExists = self::flattenKeyValueArray($arrClasses); + $arrValues = StringUtil::deserialize($value, true); + + foreach($arrValues as $cssClass) + { + if(array_key_exists($cssClass['key'], $arrExists)) + { + if(!$forceOverwrite) + { + continue; + } + + // Overwrite existing value + $key = array_search($field, array_column($arrClasses, 'key')); + + $arrClasses[ $key ] = [ + 'key' => $cssClass['key'], + 'value' => $cssClass['value'] + ]; + + continue; + } + + $arrClasses[] = [ + 'key' => $cssClass['key'], + 'value' => $cssClass['value'] + ]; + } + + $value = serialize($arrClasses); + } + + break; + // Check for multiple fields like contentElement + default: + $fieldOptions = $GLOBALS['TL_DCA']['tl_style_manager']['fields'][$field]; + + if(isset($fieldOptions['eval']['multiple']) && !!$fieldOptions['eval']['multiple'] && $fieldOptions['inputType'] === 'checkbox') + { + $arrElements = StringUtil::deserialize($objOriginal->{$field}, true); + $arrValues = StringUtil::deserialize($value, true); + + foreach($arrValues as $element) + { + if(in_array($element, $arrElements)) + { + if(!$forceOverwrite) + { + continue; + } + + $key = array_search($element, $arrElements); + $arrElements[ $key ] = $element; + + continue; + } + + $arrElements[] = $element; + } + + $value = serialize($arrElements); + } + } + + // Overwrite field values + $objOriginal->{$field} = $value; + } + + return $objOriginal; + } + /** * Export StyleManager data * @@ -622,7 +725,7 @@ protected function addRowData(\DOMDocument $xml, \DOMNode $row, array $arrData) * * @return array */ - public function flattenKeyValueArray($arr) + public static function flattenKeyValueArray($arr) { if(empty($arr)) { @@ -637,4 +740,9 @@ public function flattenKeyValueArray($arr) return $arrTmp; } + + public static function combineAliases(...$aliases): string + { + return implode('_', $aliases); + } } diff --git a/src/Resources/contao/models/StyleManagerModel.php b/src/Resources/contao/models/StyleManagerModel.php index 56d50ba..a7fdaeb 100644 --- a/src/Resources/contao/models/StyleManagerModel.php +++ b/src/Resources/contao/models/StyleManagerModel.php @@ -157,10 +157,11 @@ public static function findByTable($strTable, array $arrOptions=array()) */ public static function findByTableAndConfiguration($strTable, array $arrOptions=array()) { + $objContainer = System::getContainer(); $objGroups = static::findByTable($strTable, $arrOptions); // Load and merge bundle configurations - if(System::getContainer()->getParameter('contao_component_style_manager.use_bundle_config')) + if($objContainer->getParameter('contao_component_style_manager.use_bundle_config')) { $arrObjStyleGroups = null; @@ -169,23 +170,51 @@ public static function findByTableAndConfiguration($strTable, array $arrOptions= if(null !== $arrGroups) { - $arrExistingGroupAliases = []; + $arrArchiveIdentifier = []; + + if(null !== ($objArchives = StyleManagerArchiveModel::findAll())) + { + $arrArchiveIdentifier = array_combine( + $objArchives->fetchEach('id'), + $objArchives->fetchEach('identifier') + ); + } if(null !== $objGroups) { - $arrExistingGroupAliases = $objGroups->fetchEach('alias'); + foreach ($objGroups as $objGroup) + { + $alias = Sync::combineAliases( + $arrArchiveIdentifier[$objGroup->pid], + $objGroup->alias + ); - // Make Collection mutable - $arrObjStyleGroups = $objGroups->getModels(); + $arrObjStyleGroups[ $alias ] = $objGroup->current(); + } } // Append bundle config groups - foreach ($arrGroups as $arrGroup) + foreach ($arrGroups as $combinedAlias => $objGroup) { + $blnStrict = $objContainer->getParameter('contao_component_style_manager.strict'); + // Skip if the alias already exists in the backend configuration - if(!\in_array($arrGroup->alias, $arrExistingGroupAliases)) + if($blnStrict && $arrObjStyleGroups && !\array_key_exists($combinedAlias, $arrObjStyleGroups)) { - $arrObjStyleGroups[] = $arrGroup; + $arrObjStyleGroups[ $combinedAlias ] = $objGroup; + } + elseif(!$blnStrict) + { + // Merge if the alias already exists in the backend configuration + if($arrObjStyleGroups && \array_key_exists($combinedAlias, $arrObjStyleGroups)) + { + // Overwrite with merged object + $arrObjStyleGroups[ $combinedAlias ] = Sync::mergeGroupObjects($objGroup, $arrObjStyleGroups[ $combinedAlias ], ['id', 'pid', 'alias']); + } + else + { + $arrObjStyleGroups[ $combinedAlias ] = $objGroup; + } } } } From f8aefdd7d1b2825cc8e54326e712153daac5a5f1 Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 12 May 2022 14:14:29 +0200 Subject: [PATCH 22/48] Bugfix: Provided all StyleManager classes were subsequently removed, the field was not saved and the classes were retained. --- src/Resources/contao/dca/tl_article.php | 1 + src/Resources/contao/dca/tl_calendar_events.php | 1 + src/Resources/contao/dca/tl_content.php | 1 + src/Resources/contao/dca/tl_form.php | 1 + src/Resources/contao/dca/tl_form_field.php | 1 + src/Resources/contao/dca/tl_layout.php | 1 + src/Resources/contao/dca/tl_module.php | 1 + src/Resources/contao/dca/tl_news.php | 1 + src/Resources/contao/dca/tl_page.php | 1 + 9 files changed, 9 insertions(+) diff --git a/src/Resources/contao/dca/tl_article.php b/src/Resources/contao/dca/tl_article.php index 6edaf84..a6afcce 100644 --- a/src/Resources/contao/dca/tl_article.php +++ b/src/Resources/contao/dca/tl_article.php @@ -16,6 +16,7 @@ ); $GLOBALS['TL_DCA']['tl_article']['fields']['cssID']['sql'] = "text NULL"; +$GLOBALS['TL_DCA']['tl_article']['fields']['cssID']['eval']['alwaysSave'] = true; $GLOBALS['TL_DCA']['tl_article']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); $GLOBALS['TL_DCA']['tl_article']['fields']['cssID']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); diff --git a/src/Resources/contao/dca/tl_calendar_events.php b/src/Resources/contao/dca/tl_calendar_events.php index 76a3033..20dee9b 100644 --- a/src/Resources/contao/dca/tl_calendar_events.php +++ b/src/Resources/contao/dca/tl_calendar_events.php @@ -20,6 +20,7 @@ ); $GLOBALS['TL_DCA']['tl_calendar_events']['fields']['cssClass']['sql'] = "text NULL"; + $GLOBALS['TL_DCA']['tl_calendar_events']['fields']['cssClass']['eval']['alwaysSave'] = true; $GLOBALS['TL_DCA']['tl_calendar_events']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); $GLOBALS['TL_DCA']['tl_calendar_events']['fields']['cssClass']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); diff --git a/src/Resources/contao/dca/tl_content.php b/src/Resources/contao/dca/tl_content.php index 82d3a45..b268617 100644 --- a/src/Resources/contao/dca/tl_content.php +++ b/src/Resources/contao/dca/tl_content.php @@ -16,6 +16,7 @@ ); $GLOBALS['TL_DCA']['tl_content']['fields']['cssID']['sql'] = "text NULL"; +$GLOBALS['TL_DCA']['tl_content']['fields']['cssID']['eval']['alwaysSave'] = true; $GLOBALS['TL_DCA']['tl_content']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); $GLOBALS['TL_DCA']['tl_content']['fields']['cssID']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); diff --git a/src/Resources/contao/dca/tl_form.php b/src/Resources/contao/dca/tl_form.php index d5ca2de..bb03e08 100644 --- a/src/Resources/contao/dca/tl_form.php +++ b/src/Resources/contao/dca/tl_form.php @@ -16,6 +16,7 @@ ); $GLOBALS['TL_DCA']['tl_form']['fields']['attributes']['sql'] = "text NULL"; +$GLOBALS['TL_DCA']['tl_form']['fields']['attributes']['eval']['alwaysSave'] = true; $GLOBALS['TL_DCA']['tl_form']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); $GLOBALS['TL_DCA']['tl_form']['fields']['attributes']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); diff --git a/src/Resources/contao/dca/tl_form_field.php b/src/Resources/contao/dca/tl_form_field.php index 470da09..b2fd7ad 100644 --- a/src/Resources/contao/dca/tl_form_field.php +++ b/src/Resources/contao/dca/tl_form_field.php @@ -16,6 +16,7 @@ ); $GLOBALS['TL_DCA']['tl_form_field']['fields']['class']['sql'] = "text NULL"; +$GLOBALS['TL_DCA']['tl_form_field']['fields']['class']['eval']['alwaysSave'] = true; $GLOBALS['TL_DCA']['tl_form_field']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); $GLOBALS['TL_DCA']['tl_form_field']['list']['sorting']['child_record_callback'] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'listFormFields'); diff --git a/src/Resources/contao/dca/tl_layout.php b/src/Resources/contao/dca/tl_layout.php index d07c600..8aff072 100644 --- a/src/Resources/contao/dca/tl_layout.php +++ b/src/Resources/contao/dca/tl_layout.php @@ -16,6 +16,7 @@ ); $GLOBALS['TL_DCA']['tl_layout']['fields']['cssClass']['sql'] = "text NULL"; +$GLOBALS['TL_DCA']['tl_layout']['fields']['cssClass']['eval']['alwaysSave'] = true; $GLOBALS['TL_DCA']['tl_layout']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); $GLOBALS['TL_DCA']['tl_layout']['fields']['cssClass']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); diff --git a/src/Resources/contao/dca/tl_module.php b/src/Resources/contao/dca/tl_module.php index 78444c5..a0e9d74 100644 --- a/src/Resources/contao/dca/tl_module.php +++ b/src/Resources/contao/dca/tl_module.php @@ -16,6 +16,7 @@ ); $GLOBALS['TL_DCA']['tl_module']['fields']['cssID']['sql'] = "text NULL"; +$GLOBALS['TL_DCA']['tl_module']['fields']['cssID']['eval']['alwaysSave'] = true; $GLOBALS['TL_DCA']['tl_module']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); $GLOBALS['TL_DCA']['tl_module']['fields']['cssID']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); diff --git a/src/Resources/contao/dca/tl_news.php b/src/Resources/contao/dca/tl_news.php index 8b77d5a..a9dfe55 100644 --- a/src/Resources/contao/dca/tl_news.php +++ b/src/Resources/contao/dca/tl_news.php @@ -20,6 +20,7 @@ ); $GLOBALS['TL_DCA']['tl_news']['fields']['cssClass']['sql'] = "text NULL"; + $GLOBALS['TL_DCA']['tl_news']['fields']['cssClass']['eval']['alwaysSave'] = true; $GLOBALS['TL_DCA']['tl_news']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); $GLOBALS['TL_DCA']['tl_news']['fields']['cssClass']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); diff --git a/src/Resources/contao/dca/tl_page.php b/src/Resources/contao/dca/tl_page.php index c291f31..ec917e5 100644 --- a/src/Resources/contao/dca/tl_page.php +++ b/src/Resources/contao/dca/tl_page.php @@ -16,6 +16,7 @@ ); $GLOBALS['TL_DCA']['tl_page']['fields']['cssClass']['sql'] = "text NULL"; +$GLOBALS['TL_DCA']['tl_page']['fields']['cssClass']['eval']['alwaysSave'] = true; $GLOBALS['TL_DCA']['tl_page']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); $GLOBALS['TL_DCA']['tl_page']['fields']['cssClass']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); From 15b2f06d62076b28f2e7bebd4e28084a4e9113af Mon Sep 17 00:00:00 2001 From: Sebastian Zoglowek Date: Thu, 19 May 2022 10:54:18 +0200 Subject: [PATCH 23/48] [Update] Add findBy method to models --- src/Resources/contao/models/StyleManagerArchiveModel.php | 1 + src/Resources/contao/models/StyleManagerModel.php | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Resources/contao/models/StyleManagerArchiveModel.php b/src/Resources/contao/models/StyleManagerArchiveModel.php index adc5c9c..19827c7 100644 --- a/src/Resources/contao/models/StyleManagerArchiveModel.php +++ b/src/Resources/contao/models/StyleManagerArchiveModel.php @@ -32,6 +32,7 @@ * @method static \Model\Collection|StyleManagerArchiveModel[]|StyleManagerArchiveModel|null findByTitle($val, array $opt=array()) * @method static \Model\Collection|StyleManagerArchiveModel[]|StyleManagerArchiveModel|null findByIdentifier($val, array $opt=array()) * @method static \Model\Collection|StyleManagerArchiveModel[]|StyleManagerArchiveModel|null findByGroupAlias($val, array $opt=array()) + * @method static \Model\Collection|StyleManagerArchiveModel[]|StyleManagerArchiveModel|null findBy($col, $val, array $opt=array()) * @method static \Model\Collection|StyleManagerArchiveModel[]|StyleManagerArchiveModel|null findAll(array $opt=array()) * * @method static integer countById($id, array $opt=array()) diff --git a/src/Resources/contao/models/StyleManagerModel.php b/src/Resources/contao/models/StyleManagerModel.php index a7fdaeb..7546b99 100644 --- a/src/Resources/contao/models/StyleManagerModel.php +++ b/src/Resources/contao/models/StyleManagerModel.php @@ -69,6 +69,7 @@ * @method static \Model\Collection|StyleManagerModel[]|StyleManagerModel|null findByContentElements($val, array $opt=array()) * @method static \Model\Collection|StyleManagerModel[]|StyleManagerModel|null findByExtendNews($val, array $opt=array()) * @method static \Model\Collection|StyleManagerModel[]|StyleManagerModel|null findByExtendEvents($val, array $opt=array()) + * @method static \Model\Collection|StyleManagerModel[]|StyleManagerModel|null findBy($col, $val, array $opt=array()) * @method static \Model\Collection|StyleManagerModel[]|StyleManagerModel|null findAll(array $opt=array()) * * @method static integer countById($id, array $opt=array()) From 35b008afc1b27ef75e1d103795598bec0fe3fb3f Mon Sep 17 00:00:00 2001 From: Sebastian Zoglowek Date: Thu, 19 May 2022 11:07:01 +0200 Subject: [PATCH 24/48] [Update] Fix styleManagerIsVisibleGroup-Hook and update docs --- docs/SUPPORT.md | 33 ++++++++++++++++++- src/Resources/contao/classes/StyleManager.php | 2 +- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/docs/SUPPORT.md b/docs/SUPPORT.md index a0f8b32..b9579d4 100644 --- a/docs/SUPPORT.md +++ b/docs/SUPPORT.md @@ -81,7 +81,38 @@ public function onFindByTable($strTable, $arrOptions) } ``` -### 4. **Skip fields** that should not be displayed in the Backend Select-Widget +### 4. Provide the StyleManager your new groups + +To load the new CSS groups within your elements, it is necessary to provide the StyleManager the new groups. In order to make this possible the **styleManagerIsVisibleGroup**-Hook is prepared. + + +```php +// HOOK +$GLOBALS['TL_HOOKS']['styleManagerIsVisibleGroup'][] = array('\\Namespace\\Class', 'isVisibleGroup'); +``` + +```php +use Oveleon\ContaoComponentStyleManager\StyleManagerModel; + +/** + * Check whether an element is visible in style manager widget + * + * @param $objGroup + * @param $strTable + * + * @return bool + */ +public function isVisibleGroup($objGroup, $strTable) +{ + if( + 'tl_mydca1' === $strTable && !!$objGroup->extendMyDca1 + ){ return true; } + + return false; +} +``` + +### 5. **Skip fields** that should not be displayed in the Backend Select-Widget 📌 _This step is only necessary for tables with different types like tl_content, tl_module or tl_form_fields_ diff --git a/src/Resources/contao/classes/StyleManager.php b/src/Resources/contao/classes/StyleManager.php index 715499a..7bac734 100644 --- a/src/Resources/contao/classes/StyleManager.php +++ b/src/Resources/contao/classes/StyleManager.php @@ -404,7 +404,7 @@ public static function isVisibleGroup(StyleManagerModel $objGroup, string $strTa ){ return true; } // Check is visible group for custom configurations - if (isset($GLOBALS['TL_HOOKS']['styleManagerIsVisibleGroup']) && \is_array($GLOBALS['TL_HOOKS']['styleManagerGroupFieldOptions'])) + if (isset($GLOBALS['TL_HOOKS']['styleManagerIsVisibleGroup']) && \is_array($GLOBALS['TL_HOOKS']['styleManagerIsVisibleGroup'])) { foreach ($GLOBALS['TL_HOOKS']['styleManagerIsVisibleGroup'] as $callback) { From b513f950c8cc0063713061a22b633ecc84a74c4c Mon Sep 17 00:00:00 2001 From: doishub Date: Fri, 7 Oct 2022 15:01:49 +0200 Subject: [PATCH 25/48] Rebase bundle-config --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 7774cbc..ccd9b3a 100644 --- a/README.md +++ b/README.md @@ -66,5 +66,3 @@ If the StyleManager was used for other / own database tables, these tables must ```shell $ php contao-console contao:stylemanager:object-conversion tl_mytable ``` - - From 2635dcdc89fd1ea1dc6f3ff72f5822c68262e011 Mon Sep 17 00:00:00 2001 From: doishub Date: Mon, 10 Oct 2022 11:50:23 +0200 Subject: [PATCH 26/48] Restructure bundle --- composer.json | 4 +- docs/SUPPORT.md | 13 - .../ContaoComponentStyleManagerExtension.php | 5 +- src/EventListener/AddCustomRegexpListener.php | 35 + .../StyleManagerArchiveListener.php | 110 +++ .../DataContainer/StyleManagerListener.php | 162 ++++ .../ExecutePostActionsListener.php} | 25 +- src/EventListener/LoadFormFieldListener.php | 33 + src/EventListener/ParseTemplateListener.php | 45 ++ .../KernelRequestSubscriber.php | 32 + .../StyleManagerArchiveModel.php | 3 +- .../models => Model}/StyleManagerModel.php | 6 +- .../config/{commands.yml => commands.yaml} | 0 .../{migrations.yml => migrations.yaml} | 0 src/Resources/config/services.yaml | 9 + src/Resources/contao/classes/Support.php | 40 - src/Resources/contao/config/config.php | 52 +- src/Resources/contao/dca/tl_article.php | 8 +- .../contao/dca/tl_calendar_events.php | 8 +- src/Resources/contao/dca/tl_content.php | 8 +- src/Resources/contao/dca/tl_form.php | 8 +- src/Resources/contao/dca/tl_form_field.php | 10 +- src/Resources/contao/dca/tl_layout.php | 8 +- src/Resources/contao/dca/tl_module.php | 8 +- src/Resources/contao/dca/tl_news.php | 8 +- src/Resources/contao/dca/tl_page.php | 8 +- src/Resources/contao/dca/tl_style_manager.php | 706 +++++------------- .../contao/dca/tl_style_manager_archive.php | 311 ++------ .../classes => StyleManager}/Config.php | 2 +- .../classes => StyleManager}/StyleManager.php | 92 +-- .../classes => StyleManager}/Styles.php | 6 +- .../contao/classes => StyleManager}/Sync.php | 7 +- .../ComponentStyleSelect.php | 5 +- 33 files changed, 808 insertions(+), 969 deletions(-) create mode 100644 src/EventListener/AddCustomRegexpListener.php create mode 100644 src/EventListener/DataContainer/StyleManagerArchiveListener.php create mode 100644 src/EventListener/DataContainer/StyleManagerListener.php rename src/{Resources/contao/classes/Ajax.php => EventListener/ExecutePostActionsListener.php} (54%) create mode 100644 src/EventListener/LoadFormFieldListener.php create mode 100644 src/EventListener/ParseTemplateListener.php create mode 100644 src/EventSubscriber/KernelRequestSubscriber.php rename src/{Resources/contao/models => Model}/StyleManagerArchiveModel.php (96%) rename src/{Resources/contao/models => Model}/StyleManagerModel.php (98%) rename src/Resources/config/{commands.yml => commands.yaml} (100%) rename src/Resources/config/{migrations.yml => migrations.yaml} (100%) create mode 100644 src/Resources/config/services.yaml delete mode 100644 src/Resources/contao/classes/Support.php rename src/{Resources/contao/classes => StyleManager}/Config.php (98%) rename src/{Resources/contao/classes => StyleManager}/StyleManager.php (83%) rename src/{Resources/contao/classes => StyleManager}/Styles.php (96%) rename src/{Resources/contao/classes => StyleManager}/Sync.php (98%) rename src/{Resources/contao/widgets => Widget}/ComponentStyleSelect.php (98%) diff --git a/composer.json b/composer.json index 5e3f924..2c625a7 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "php":">=7.4", "ext-json": "*", "ext-dom": "*", - "contao/core-bundle":">=4.9.22" + "contao/core-bundle":">=4.13" }, "require-dev": { "contao/manager-plugin": "^2.0" @@ -47,7 +47,7 @@ }, "extra":{ "branch-alias": { - "dev-master": "2.7.x-dev" + "dev-master": "3.0.x-dev" }, "contao-manager-plugin": "Oveleon\\ContaoComponentStyleManager\\ContaoManager\\Plugin" } diff --git a/docs/SUPPORT.md b/docs/SUPPORT.md index b9579d4..03c5f57 100644 --- a/docs/SUPPORT.md +++ b/docs/SUPPORT.md @@ -149,16 +149,3 @@ public function onSkipField($objStyleGroups, $objWidget) return false; } ``` - - -# Support Rocksolid Custom Elements -see: [Rocksolid Custom Elements](https://github.com/madeyourday/contao-rocksolid-custom-elements) - -Use the callback function `onloadCallback` in your custom element configuration and reference the following function: -``` - 'onloadCallback' => array( - array('Oveleon\ContaoComponentStyleManager\Support', 'extendRockSolidCustomElementsPalettes') - ) -``` - -ℹ **From version `2.4` this callback is no longer needed** diff --git a/src/DependencyInjection/ContaoComponentStyleManagerExtension.php b/src/DependencyInjection/ContaoComponentStyleManagerExtension.php index 78318de..29d2c13 100644 --- a/src/DependencyInjection/ContaoComponentStyleManagerExtension.php +++ b/src/DependencyInjection/ContaoComponentStyleManagerExtension.php @@ -18,8 +18,9 @@ public function load(array $configs, ContainerBuilder $container) new FileLocator(__DIR__ . '/../Resources/config') ); - $loader->load('migrations.yml'); - $loader->load('commands.yml'); + $loader->load('migrations.yaml'); + $loader->load('commands.yaml'); + $loader->load('services.yaml'); $container->setParameter('contao_component_style_manager.use_bundle_config', $config['use_bundle_config']); $container->setParameter('contao_component_style_manager.strict', $config['strict']); diff --git a/src/EventListener/AddCustomRegexpListener.php b/src/EventListener/AddCustomRegexpListener.php new file mode 100644 index 0000000..7c1b7a6 --- /dev/null +++ b/src/EventListener/AddCustomRegexpListener.php @@ -0,0 +1,35 @@ +addError('Field ' . $objWidget->label . ' must begin with a letter and may not contain any spaces or special characters (e.g. myVariable).'); + } + + return true; + } + + return false; + } +} diff --git a/src/EventListener/DataContainer/StyleManagerArchiveListener.php b/src/EventListener/DataContainer/StyleManagerArchiveListener.php new file mode 100644 index 0000000..a9942a1 --- /dev/null +++ b/src/EventListener/DataContainer/StyleManagerArchiveListener.php @@ -0,0 +1,110 @@ +id); + + if(null !== $objArchive && $objArchive->identifier) + { + $GLOBALS['TL_DCA']['tl_style_manager_archive']['fields']['identifier']['eval']['mandatory'] = false; + $GLOBALS['TL_DCA']['tl_style_manager_archive']['fields']['identifier']['eval']['disabled'] = true; + } + } + + /** + * @Callback(table="tl_style_manager_archive", target="list.label.label") + */ + public function addIdentifierInfo($row, $label) + { + if($row['identifier']) + { + $label .= sprintf('[%s]', $row['identifier']); + } + + return $label; + } + + /** + * @Callback(table="tl_style_manager_archive", target="list.global_operations.import.button") + */ + public function importConfigButton(string $href, string $label, string $title, string $class, string $attributes): string + { + if(System::getContainer()->getParameter('contao_component_style_manager.use_bundle_config')) + { + if($arrFiles = Config::getBundleConfigurationFiles()) + { + $label .= sprintf(' (%s)', count($arrFiles)); + } + } + + return vsprintf('%s ', [ + Backend::addToUrl($href), + $class, + StringUtil::specialchars($title), + $attributes, + $label + ]); + } + + /** + * @Callback(table="tl_style_manager_archive", target="list.global_operations.config.button") + */ + public function bundleConfigButton(string $href, string $label, string $title, string $class, string $attributes): string + { + if(System::getContainer()->getParameter('contao_component_style_manager.use_bundle_config')) + { + $count = 0; + + if($arrFiles = Config::getBundleConfigurationFiles()) + { + $count = count($arrFiles); + } + + return vsprintf('%s: %s', [ + Backend::addToUrl($href), + $class, + $attributes, + $label, + $count + ]); + } + + return ''; + } + + /** + * @Callback(table="tl_style_manager_archive", target=""fields.identifier.save") + */ + public function generateIdentifier($varValue, DataContainer $dc): string + { + $aliasExists = function (string $alias) use ($dc): bool + { + $objDatabase = Database::getInstance(); + + return $objDatabase->prepare("SELECT id FROM tl_style_manager_archive WHERE identifier=? AND id!=?")->execute($alias, $dc->id)->numRows > 0; + }; + + if ($aliasExists($varValue)) + { + throw new \Exception(sprintf($GLOBALS['TL_LANG']['ERR']['identifierExists'], $varValue)); + } + + return $varValue; + } +} diff --git a/src/EventListener/DataContainer/StyleManagerListener.php b/src/EventListener/DataContainer/StyleManagerListener.php new file mode 100644 index 0000000..37bd668 --- /dev/null +++ b/src/EventListener/DataContainer/StyleManagerListener.php @@ -0,0 +1,162 @@ +getParameter('kernel.bundles'); + + if (!isset($bundles['ContaoCalendarBundle'])) + { + unset($GLOBALS['TL_DCA']['tl_style_manager']['fields']['extendEvents']); + } + + if (!isset($bundles['ContaoNewsBundle'])) + { + unset($GLOBALS['TL_DCA']['tl_style_manager']['fields']['extendNews']); + } + } + + /** + * @Callback(table="tl_style_manager", target="list.sorting.child_record") + */ + public function listGroupRecords(array $row): string + { + $arrExtends = null; + $label = $row['title']; + + if($row['passToTemplate']) + { + $parent = StyleManagerArchiveModel::findById($row['pid']); + + $label = vsprintf('$ %s', [ + $parent->identifier, + $row['alias'], + $label + ]); + } + else + { + $label = sprintf('C %s', $label); + } + + foreach ($row as $field => $value) + { + if(strpos($field, 'extend') === 0 && !!$value) + { + $arrExtends[] = &$GLOBALS['TL_LANG']['tl_style_manager'][ $field ][0]; + } + } + + if($arrExtends !== null) + { + $label .= sprintf('[%s]', implode(", ", $arrExtends)); + } + + return $label; + } + + /** + * @Callback(table="tl_style_manager", target="fields.alias.save") + */ + public function generateAlias($varValue, DataContainer $dc): string + { + $aliasExists = function (string $alias) use ($dc): bool + { + $objDatabase = Database::getInstance(); + + return $objDatabase->prepare("SELECT id FROM tl_style_manager WHERE alias=? AND id!=? AND pid=?")->execute($alias, $dc->id, $dc->activeRecord->pid)->numRows > 0; + }; + + // Generate an alias if there is none + if ($varValue == '') + { + $varValue = System::getContainer()->get('contao.slug')->generate($dc->activeRecord->title, $dc->id, $aliasExists); + } + elseif ($aliasExists($varValue)) + { + throw new \Exception(sprintf($GLOBALS['TL_LANG']['ERR']['groupAliasExists'], $varValue)); + } + + return $varValue; + } + + /** + * @Callback(table="tl_style_manager", target="fields.cssClasses.load") + */ + public function translateKeyValue($varValue) + { + Controller::loadLanguageFile('tl_style_manager'); + + $GLOBALS['TL_LANG']['MSC']['ow_key'] = $GLOBALS['TL_LANG']['tl_style_manager']['ow_key']; + $GLOBALS['TL_LANG']['MSC']['ow_value'] = $GLOBALS['TL_LANG']['tl_style_manager']['ow_value']; + + return $varValue; + } + + /** + * @Callback(table="tl_style_manager", target="fields.formFields.options") + */ + public function getFormFields(): array + { + Controller::loadLanguageFile('tl_form_field'); + + $arrFields = $GLOBALS['TL_FFL']; + + // Add the translation + foreach (array_keys($arrFields) as $key) + { + $arrFields[$key] = $GLOBALS['TL_LANG']['FFL'][$key][0]; + } + + return $arrFields; + } + + /** + * @Callback(table="tl_style_manager", target="fields.contentElements.options") + */ + public function getContentElements(): array + { + $groups = []; + + foreach ($GLOBALS['TL_CTE'] as $k=>$v) + { + foreach (array_keys($v) as $kk) + { + $groups[$k][] = $kk; + } + } + + return $groups; + } + + /** + * @Callback(table="tl_style_manager", target="fields.modules.options") + */ + public function getModules(): array + { + $groups = []; + + foreach ($GLOBALS['FE_MOD'] as $k=>$v) + { + foreach (array_keys($v) as $kk) + { + $groups[$k][] = $kk; + } + } + + return $groups; + } +} diff --git a/src/Resources/contao/classes/Ajax.php b/src/EventListener/ExecutePostActionsListener.php similarity index 54% rename from src/Resources/contao/classes/Ajax.php rename to src/EventListener/ExecutePostActionsListener.php index 1a2ab6b..e7a4a4e 100644 --- a/src/Resources/contao/classes/Ajax.php +++ b/src/EventListener/ExecutePostActionsListener.php @@ -5,23 +5,24 @@ * (c) https://www.oveleon.de/ */ -namespace Oveleon\ContaoComponentStyleManager; +namespace Oveleon\ContaoComponentStyleManager\EventListener; use Contao\CoreBundle\Exception\NoContentResponseException; +use Contao\CoreBundle\ServiceAnnotation\Hook; +use Contao\DataContainer; +use Contao\Input; +use Contao\System; use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface; -class Ajax extends \Backend +/** + * @Hook("executePostActions") + */ +class ExecutePostActionsListener { /** - * Ajax actions that do require a data container object - * - * @param $strAction - * @param \DataContainer $dc - * - * @throws \Exception - * @throws NoContentResponseException + * Saves the status of selected tabs */ - public function executePostActions($strAction, \DataContainer $dc) + public function __invoke($strAction, DataContainer $dc) { if($strAction !== 'selectStyleManagerSection') { @@ -29,10 +30,10 @@ public function executePostActions($strAction, \DataContainer $dc) } /** @var AttributeBagInterface $objSessionBag */ - $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend'); + $objSessionBag = System::getContainer()->get('session')->getBag('contao_backend'); $fs = $objSessionBag->get('stylemanager_section_states'); - $fs[\Input::post('groupAlias')] = \Input::post('identifier'); + $fs[Input::post('groupAlias')] = Input::post('identifier'); $objSessionBag->set('stylemanager_section_states', $fs); throw new NoContentResponseException(); diff --git a/src/EventListener/LoadFormFieldListener.php b/src/EventListener/LoadFormFieldListener.php new file mode 100644 index 0000000..c61f191 --- /dev/null +++ b/src/EventListener/LoadFormFieldListener.php @@ -0,0 +1,33 @@ +styleManager instanceof Styles)) + { + $arrStyles = StringUtil::deserialize($objWidget->styleManager); + $objWidget->styleManager = new Styles(isset($arrStyles['__vars__']) ? $arrStyles['__vars__'] : null); + } + + return $objWidget; + } +} diff --git a/src/EventListener/ParseTemplateListener.php b/src/EventListener/ParseTemplateListener.php new file mode 100644 index 0000000..8ce9709 --- /dev/null +++ b/src/EventListener/ParseTemplateListener.php @@ -0,0 +1,45 @@ +getName(), 'fe_page') === 0) + { + global $objPage; + + $arrStyles = array_filter(array_merge_recursive( + StringUtil::deserialize($objPage->styleManager, true), + StringUtil::deserialize($template->layout->styleManager, true) + )); + + $template->styleManager = serialize($arrStyles); + } + + // Build Styles object and assign it to the template + if(!($template->styleManager instanceof Styles)) + { + $arrStyles = StringUtil::deserialize($template->styleManager); + $template->styleManager = new Styles(isset($arrStyles['__vars__']) ? $arrStyles['__vars__'] : null); + } + } +} diff --git a/src/EventSubscriber/KernelRequestSubscriber.php b/src/EventSubscriber/KernelRequestSubscriber.php new file mode 100644 index 0000000..d3718b8 --- /dev/null +++ b/src/EventSubscriber/KernelRequestSubscriber.php @@ -0,0 +1,32 @@ +scopeMatcher = $scopeMatcher; + } + + public static function getSubscribedEvents() + { + return [KernelEvents::REQUEST => 'onKernelRequest']; + } + + public function onKernelRequest(RequestEvent $e): void + { + $request = $e->getRequest(); + + if ($this->scopeMatcher->isBackendRequest($request)) { + $GLOBALS['TL_CSS'][] = 'bundles/contaocomponentstylemanager/stylemanager.css|static'; + } + } +} diff --git a/src/Resources/contao/models/StyleManagerArchiveModel.php b/src/Model/StyleManagerArchiveModel.php similarity index 96% rename from src/Resources/contao/models/StyleManagerArchiveModel.php rename to src/Model/StyleManagerArchiveModel.php index 19827c7..934eb85 100644 --- a/src/Resources/contao/models/StyleManagerArchiveModel.php +++ b/src/Model/StyleManagerArchiveModel.php @@ -5,10 +5,11 @@ * (c) https://www.oveleon.de/ */ -namespace Oveleon\ContaoComponentStyleManager; +namespace Oveleon\ContaoComponentStyleManager\Model; use Contao\Model; use Contao\System; +use Oveleon\ContaoComponentStyleManager\StyleManager\Config; /** * Reads and writes fields from style manager categories diff --git a/src/Resources/contao/models/StyleManagerModel.php b/src/Model/StyleManagerModel.php similarity index 98% rename from src/Resources/contao/models/StyleManagerModel.php rename to src/Model/StyleManagerModel.php index 7546b99..3b89e92 100644 --- a/src/Resources/contao/models/StyleManagerModel.php +++ b/src/Model/StyleManagerModel.php @@ -5,11 +5,12 @@ * (c) https://www.oveleon.de/ */ -namespace Oveleon\ContaoComponentStyleManager; +namespace Oveleon\ContaoComponentStyleManager\Model; -use Contao\Controller; use Contao\Model; use Contao\System; +use Oveleon\ContaoComponentStyleManager\StyleManager\Config; +use Oveleon\ContaoComponentStyleManager\StyleManager\Sync; /** * Reads and writes fields from style manager @@ -94,7 +95,6 @@ class StyleManagerModel extends Model { - /** * Table name * @var string diff --git a/src/Resources/config/commands.yml b/src/Resources/config/commands.yaml similarity index 100% rename from src/Resources/config/commands.yml rename to src/Resources/config/commands.yaml diff --git a/src/Resources/config/migrations.yml b/src/Resources/config/migrations.yaml similarity index 100% rename from src/Resources/config/migrations.yml rename to src/Resources/config/migrations.yaml diff --git a/src/Resources/config/services.yaml b/src/Resources/config/services.yaml new file mode 100644 index 0000000..927eaf8 --- /dev/null +++ b/src/Resources/config/services.yaml @@ -0,0 +1,9 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: true + + Oveleon\ContaoComponentStyleManager\: + resource: '../../' + exclude: '../../{Model,DependencyInjection,Resources}' diff --git a/src/Resources/contao/classes/Support.php b/src/Resources/contao/classes/Support.php deleted file mode 100644 index d240fde..0000000 --- a/src/Resources/contao/classes/Support.php +++ /dev/null @@ -1,40 +0,0 @@ -getParameter('kernel.packages'); - $version = floatval($packages['oveleon/contao-component-style-manager']); - - if($version >= 2.4 || $version == 0){ - return; - } - - foreach ($GLOBALS['TL_DCA'][$dc->table]['palettes'] as $key => &$palette) - { - if (!is_array($palette) && strpos($key, 'rsce_') === 0) - { - preg_match_all('/(.*)({expert_legend.*)/', $palette, $matches); - - $palette = $matches[1][0] . '{style_manager_legend},styleManager;' . $matches[2][0]; - } - } - } -} diff --git a/src/Resources/contao/config/config.php b/src/Resources/contao/config/config.php index 6cdd8f1..28b3d53 100644 --- a/src/Resources/contao/config/config.php +++ b/src/Resources/contao/config/config.php @@ -1,42 +1,24 @@ array - ( - 'style_manager' => array - ( - 'tables' => array('tl_style_manager_archive', 'tl_style_manager'), - 'export' => array('\\Oveleon\\ContaoComponentStyleManager\\Sync', 'exportStyleManager'), - 'import' => array('\\Oveleon\\ContaoComponentStyleManager\\Sync', 'importStyleManager'), - ) - ) -)); +ArrayUtil::arrayInsert($GLOBALS['BE_MOD'], count($GLOBALS['BE_MOD']['design']), [ + 'design' => [ + 'style_manager' => [ + 'tables' => ['tl_style_manager_archive', 'tl_style_manager'], + 'export' => [Sync::class, 'exportStyleManager'], + 'import' => [Sync::class, 'importStyleManager'] + ] + ] +]); // Back end form fields -array_insert($GLOBALS['BE_FFL'], 1, array -( - 'stylemanager' => '\\Oveleon\\ContaoComponentStyleManager\\ComponentStyleSelect' -)); +$GLOBALS['BE_FFL']['stylemanager'] = ComponentStyleSelect::class; // Models -$GLOBALS['TL_MODELS']['tl_style_manager'] = '\\Oveleon\\ContaoComponentStyleManager\\StyleManagerModel'; -$GLOBALS['TL_MODELS']['tl_style_manager_archive'] = '\\Oveleon\\ContaoComponentStyleManager\\StyleManagerArchiveModel'; - -// Hooks -$GLOBALS['TL_HOOKS']['parseTemplate'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onParseTemplate'); -$GLOBALS['TL_HOOKS']['loadFormField'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoadFormField'); -$GLOBALS['TL_HOOKS']['addCustomRegexp'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addVariableRegexp'); -$GLOBALS['TL_HOOKS']['executePostActions'][] = array('\\Oveleon\\ContaoComponentStyleManager\\Ajax', 'executePostActions'); - -// Style sheet -if (TL_MODE == 'BE') -{ - $GLOBALS['TL_CSS'][] = 'bundles/contaocomponentstylemanager/stylemanager.css|static'; -} +$GLOBALS['TL_MODELS']['tl_style_manager'] = StyleManagerModel::class; +$GLOBALS['TL_MODELS']['tl_style_manager_archive'] = StyleManagerArchiveModel::class; diff --git a/src/Resources/contao/dca/tl_article.php b/src/Resources/contao/dca/tl_article.php index a6afcce..45ed806 100644 --- a/src/Resources/contao/dca/tl_article.php +++ b/src/Resources/contao/dca/tl_article.php @@ -5,6 +5,8 @@ * (c) https://www.oveleon.de/ */ +use Oveleon\ContaoComponentStyleManager\StyleManager\StyleManager; + // Extend fields $GLOBALS['TL_DCA']['tl_article']['fields']['styleManager'] = array ( @@ -18,6 +20,6 @@ $GLOBALS['TL_DCA']['tl_article']['fields']['cssID']['sql'] = "text NULL"; $GLOBALS['TL_DCA']['tl_article']['fields']['cssID']['eval']['alwaysSave'] = true; -$GLOBALS['TL_DCA']['tl_article']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); -$GLOBALS['TL_DCA']['tl_article']['fields']['cssID']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); -$GLOBALS['TL_DCA']['tl_article']['fields']['cssID']['save_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onSave'); +$GLOBALS['TL_DCA']['tl_article']['config']['onload_callback'][] = [StyleManager::class, 'addPalette']; +$GLOBALS['TL_DCA']['tl_article']['fields']['cssID']['load_callback'][] = [StyleManager::class, 'onLoad']; +$GLOBALS['TL_DCA']['tl_article']['fields']['cssID']['save_callback'][] = [StyleManager::class, 'onSave']; diff --git a/src/Resources/contao/dca/tl_calendar_events.php b/src/Resources/contao/dca/tl_calendar_events.php index 20dee9b..b138003 100644 --- a/src/Resources/contao/dca/tl_calendar_events.php +++ b/src/Resources/contao/dca/tl_calendar_events.php @@ -5,6 +5,8 @@ * (c) https://www.oveleon.de/ */ +use Oveleon\ContaoComponentStyleManager\StyleManager\StyleManager; + $bundles = Contao\System::getContainer()->getParameter('kernel.bundles'); if (isset($bundles['ContaoCalendarBundle'])) @@ -22,7 +24,7 @@ $GLOBALS['TL_DCA']['tl_calendar_events']['fields']['cssClass']['sql'] = "text NULL"; $GLOBALS['TL_DCA']['tl_calendar_events']['fields']['cssClass']['eval']['alwaysSave'] = true; - $GLOBALS['TL_DCA']['tl_calendar_events']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); - $GLOBALS['TL_DCA']['tl_calendar_events']['fields']['cssClass']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); - $GLOBALS['TL_DCA']['tl_calendar_events']['fields']['cssClass']['save_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onSave'); + $GLOBALS['TL_DCA']['tl_calendar_events']['config']['onload_callback'][] = [StyleManager::class, 'addPalette']; + $GLOBALS['TL_DCA']['tl_calendar_events']['fields']['cssClass']['load_callback'][] = [StyleManager::class, 'onLoad']; + $GLOBALS['TL_DCA']['tl_calendar_events']['fields']['cssClass']['save_callback'][] = [StyleManager::class, 'onSave']; } diff --git a/src/Resources/contao/dca/tl_content.php b/src/Resources/contao/dca/tl_content.php index b268617..3dc76fc 100644 --- a/src/Resources/contao/dca/tl_content.php +++ b/src/Resources/contao/dca/tl_content.php @@ -5,6 +5,8 @@ * (c) https://www.oveleon.de/ */ +use Oveleon\ContaoComponentStyleManager\StyleManager\StyleManager; + // Extend fields $GLOBALS['TL_DCA']['tl_content']['fields']['styleManager'] = array ( @@ -18,6 +20,6 @@ $GLOBALS['TL_DCA']['tl_content']['fields']['cssID']['sql'] = "text NULL"; $GLOBALS['TL_DCA']['tl_content']['fields']['cssID']['eval']['alwaysSave'] = true; -$GLOBALS['TL_DCA']['tl_content']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); -$GLOBALS['TL_DCA']['tl_content']['fields']['cssID']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); -$GLOBALS['TL_DCA']['tl_content']['fields']['cssID']['save_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onSave'); +$GLOBALS['TL_DCA']['tl_content']['config']['onload_callback'][] = [StyleManager::class, 'addPalette']; +$GLOBALS['TL_DCA']['tl_content']['fields']['cssID']['load_callback'][] = [StyleManager::class, 'onLoad']; +$GLOBALS['TL_DCA']['tl_content']['fields']['cssID']['save_callback'][] = [StyleManager::class, 'onSave']; diff --git a/src/Resources/contao/dca/tl_form.php b/src/Resources/contao/dca/tl_form.php index bb03e08..850b309 100644 --- a/src/Resources/contao/dca/tl_form.php +++ b/src/Resources/contao/dca/tl_form.php @@ -5,6 +5,8 @@ * (c) https://www.oveleon.de/ */ +use Oveleon\ContaoComponentStyleManager\StyleManager\StyleManager; + // Extend fields $GLOBALS['TL_DCA']['tl_form']['fields']['styleManager'] = array ( @@ -18,6 +20,6 @@ $GLOBALS['TL_DCA']['tl_form']['fields']['attributes']['sql'] = "text NULL"; $GLOBALS['TL_DCA']['tl_form']['fields']['attributes']['eval']['alwaysSave'] = true; -$GLOBALS['TL_DCA']['tl_form']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); -$GLOBALS['TL_DCA']['tl_form']['fields']['attributes']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); -$GLOBALS['TL_DCA']['tl_form']['fields']['attributes']['save_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onSave'); +$GLOBALS['TL_DCA']['tl_form']['config']['onload_callback'][] = [StyleManager::class, 'addPalette']; +$GLOBALS['TL_DCA']['tl_form']['fields']['attributes']['load_callback'][] = [StyleManager::class, 'onLoad']; +$GLOBALS['TL_DCA']['tl_form']['fields']['attributes']['save_callback'][] = [StyleManager::class, 'onSave']; diff --git a/src/Resources/contao/dca/tl_form_field.php b/src/Resources/contao/dca/tl_form_field.php index b2fd7ad..2f6e1b0 100644 --- a/src/Resources/contao/dca/tl_form_field.php +++ b/src/Resources/contao/dca/tl_form_field.php @@ -5,6 +5,8 @@ * (c) https://www.oveleon.de/ */ +use Oveleon\ContaoComponentStyleManager\StyleManager\StyleManager; + // Extend fields $GLOBALS['TL_DCA']['tl_form_field']['fields']['styleManager'] = array ( @@ -18,7 +20,7 @@ $GLOBALS['TL_DCA']['tl_form_field']['fields']['class']['sql'] = "text NULL"; $GLOBALS['TL_DCA']['tl_form_field']['fields']['class']['eval']['alwaysSave'] = true; -$GLOBALS['TL_DCA']['tl_form_field']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); -$GLOBALS['TL_DCA']['tl_form_field']['list']['sorting']['child_record_callback'] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'listFormFields'); -$GLOBALS['TL_DCA']['tl_form_field']['fields']['class']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); -$GLOBALS['TL_DCA']['tl_form_field']['fields']['class']['save_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onSave'); +$GLOBALS['TL_DCA']['tl_form_field']['config']['onload_callback'][] = [StyleManager::class, 'addPalette']; +$GLOBALS['TL_DCA']['tl_form_field']['list']['sorting']['child_record_callback'] = [StyleManager::class, 'listFormFields']; +$GLOBALS['TL_DCA']['tl_form_field']['fields']['class']['load_callback'][] = [StyleManager::class, 'onLoad']; +$GLOBALS['TL_DCA']['tl_form_field']['fields']['class']['save_callback'][] = [StyleManager::class, 'onSave']; diff --git a/src/Resources/contao/dca/tl_layout.php b/src/Resources/contao/dca/tl_layout.php index 8aff072..65c78e8 100644 --- a/src/Resources/contao/dca/tl_layout.php +++ b/src/Resources/contao/dca/tl_layout.php @@ -5,6 +5,8 @@ * (c) https://www.oveleon.de/ */ +use Oveleon\ContaoComponentStyleManager\StyleManager\StyleManager; + // Extend fields $GLOBALS['TL_DCA']['tl_layout']['fields']['styleManager'] = array ( @@ -18,6 +20,6 @@ $GLOBALS['TL_DCA']['tl_layout']['fields']['cssClass']['sql'] = "text NULL"; $GLOBALS['TL_DCA']['tl_layout']['fields']['cssClass']['eval']['alwaysSave'] = true; -$GLOBALS['TL_DCA']['tl_layout']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); -$GLOBALS['TL_DCA']['tl_layout']['fields']['cssClass']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); -$GLOBALS['TL_DCA']['tl_layout']['fields']['cssClass']['save_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onSave'); +$GLOBALS['TL_DCA']['tl_layout']['config']['onload_callback'][] = [StyleManager::class, 'addPalette']; +$GLOBALS['TL_DCA']['tl_layout']['fields']['cssClass']['load_callback'][] = [StyleManager::class, 'onLoad']; +$GLOBALS['TL_DCA']['tl_layout']['fields']['cssClass']['save_callback'][] = [StyleManager::class, 'onSave']; diff --git a/src/Resources/contao/dca/tl_module.php b/src/Resources/contao/dca/tl_module.php index a0e9d74..8e5b7c5 100644 --- a/src/Resources/contao/dca/tl_module.php +++ b/src/Resources/contao/dca/tl_module.php @@ -5,6 +5,8 @@ * (c) https://www.oveleon.de/ */ +use Oveleon\ContaoComponentStyleManager\StyleManager\StyleManager; + // Extend fields $GLOBALS['TL_DCA']['tl_module']['fields']['styleManager'] = array ( @@ -18,6 +20,6 @@ $GLOBALS['TL_DCA']['tl_module']['fields']['cssID']['sql'] = "text NULL"; $GLOBALS['TL_DCA']['tl_module']['fields']['cssID']['eval']['alwaysSave'] = true; -$GLOBALS['TL_DCA']['tl_module']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); -$GLOBALS['TL_DCA']['tl_module']['fields']['cssID']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); -$GLOBALS['TL_DCA']['tl_module']['fields']['cssID']['save_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onSave'); +$GLOBALS['TL_DCA']['tl_module']['config']['onload_callback'][] = [StyleManager::class, 'addPalette']; +$GLOBALS['TL_DCA']['tl_module']['fields']['cssID']['load_callback'][] = [StyleManager::class, 'onLoad']; +$GLOBALS['TL_DCA']['tl_module']['fields']['cssID']['save_callback'][] = [StyleManager::class, 'onSave']; diff --git a/src/Resources/contao/dca/tl_news.php b/src/Resources/contao/dca/tl_news.php index a9dfe55..8744014 100644 --- a/src/Resources/contao/dca/tl_news.php +++ b/src/Resources/contao/dca/tl_news.php @@ -5,6 +5,8 @@ * (c) https://www.oveleon.de/ */ +use Oveleon\ContaoComponentStyleManager\StyleManager\StyleManager; + $bundles = Contao\System::getContainer()->getParameter('kernel.bundles'); if (isset($bundles['ContaoNewsBundle'])) @@ -22,7 +24,7 @@ $GLOBALS['TL_DCA']['tl_news']['fields']['cssClass']['sql'] = "text NULL"; $GLOBALS['TL_DCA']['tl_news']['fields']['cssClass']['eval']['alwaysSave'] = true; - $GLOBALS['TL_DCA']['tl_news']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); - $GLOBALS['TL_DCA']['tl_news']['fields']['cssClass']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); - $GLOBALS['TL_DCA']['tl_news']['fields']['cssClass']['save_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onSave'); + $GLOBALS['TL_DCA']['tl_news']['config']['onload_callback'][] = [StyleManager::class, 'addPalette']; + $GLOBALS['TL_DCA']['tl_news']['fields']['cssClass']['load_callback'][] = [StyleManager::class, 'onLoad']; + $GLOBALS['TL_DCA']['tl_news']['fields']['cssClass']['save_callback'][] = [StyleManager::class, 'onSave']; } diff --git a/src/Resources/contao/dca/tl_page.php b/src/Resources/contao/dca/tl_page.php index ec917e5..a83048d 100644 --- a/src/Resources/contao/dca/tl_page.php +++ b/src/Resources/contao/dca/tl_page.php @@ -5,6 +5,8 @@ * (c) https://www.oveleon.de/ */ +use Oveleon\ContaoComponentStyleManager\StyleManager\StyleManager; + // Extend fields $GLOBALS['TL_DCA']['tl_page']['fields']['styleManager'] = array ( @@ -18,6 +20,6 @@ $GLOBALS['TL_DCA']['tl_page']['fields']['cssClass']['sql'] = "text NULL"; $GLOBALS['TL_DCA']['tl_page']['fields']['cssClass']['eval']['alwaysSave'] = true; -$GLOBALS['TL_DCA']['tl_page']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); -$GLOBALS['TL_DCA']['tl_page']['fields']['cssClass']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); -$GLOBALS['TL_DCA']['tl_page']['fields']['cssClass']['save_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onSave'); +$GLOBALS['TL_DCA']['tl_page']['config']['onload_callback'][] = [StyleManager::class,'addPalette']; +$GLOBALS['TL_DCA']['tl_page']['fields']['cssClass']['load_callback'][] = [StyleManager::class,'onLoad']; +$GLOBALS['TL_DCA']['tl_page']['fields']['cssClass']['save_callback'][] = [StyleManager::class,'onSave']; diff --git a/src/Resources/contao/dca/tl_style_manager.php b/src/Resources/contao/dca/tl_style_manager.php index d16ece1..8c9219a 100644 --- a/src/Resources/contao/dca/tl_style_manager.php +++ b/src/Resources/contao/dca/tl_style_manager.php @@ -5,512 +5,220 @@ * (c) https://www.oveleon.de/ */ -$GLOBALS['TL_DCA']['tl_style_manager'] = array -( +$GLOBALS['TL_DCA']['tl_style_manager'] = [ + // Config - 'config' => array - ( - 'dataContainer' => 'Table', - 'ptable' => 'tl_style_manager_archive', - 'switchToEdit' => true, - 'enableVersioning' => true, - 'markAsCopy' => 'title', - 'onload_callback' => array - ( - array('tl_style_manager', 'checkPermission') - ), - 'sql' => array - ( - 'keys' => array - ( - 'id' => 'primary', + 'config' => [ + 'dataContainer' => 'Table', + 'ptable' => 'tl_style_manager_archive', + 'switchToEdit' => true, + 'enableVersioning' => true, + 'markAsCopy' => 'title', + 'sql' => [ + 'keys' => [ + 'id' => 'primary', 'pid,sorting' => 'index' - ) - ) - ), + ] + ] + ], // List - 'list' => array - ( - 'sorting' => array - ( - 'mode' => 4, - 'fields' => array('sorting'), - 'headerFields' => array('title', 'identifier'), - 'panelLayout' => 'filter;sort,search,limit', - 'disableGrouping' => true, - 'child_record_callback' => array('tl_style_manager', 'listGroupRecords'), - 'child_record_class' => 'no_padding' - ), - 'global_operations' => array - ( - 'all' => array - ( - 'label' => &$GLOBALS['TL_LANG']['MSC']['all'], - 'href' => 'act=select', - 'class' => 'header_edit_all', - 'attributes' => 'onclick="Backend.getScrollOffset()" accesskey="e"' - ) - ), - 'operations' => array - ( - 'editheader' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['editheader'], - 'href' => 'act=edit', - 'icon' => 'edit.svg' - ), - 'copy' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['copy'], - 'href' => 'act=paste&mode=copy', - 'icon' => 'copy.svg' - ), - 'delete' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['delete'], - 'href' => 'act=delete', - 'icon' => 'delete.svg', - 'attributes' => 'onclick="if(!confirm(\'' . ($GLOBALS['TL_LANG']['MSC']['deleteConfirm'] ?? null) . '\'))return false;Backend.getScrollOffset()"' - ), - 'show' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['show'], - 'href' => 'act=show', - 'icon' => 'show.svg' - ) - ) - ), + 'list' => [ + 'sorting' => [ + 'mode' => 4, + 'fields' => ['sorting'], + 'headerFields' => ['title', 'identifier'], + 'panelLayout' => 'filter;sort,search,limit', + 'disableGrouping' => true, + 'child_record_class' => 'no_padding' + ], + 'global_operations' => [ + 'all' => [ + 'href' => 'act=select', + 'class' => 'header_edit_all', + 'attributes' => 'onclick="Backend.getScrollOffset()" accesskey="e"' + ] + ], + 'operations' => [ + 'editheader' => [ + 'href' => 'act=edit', + 'icon' => 'edit.svg' + ], + 'copy' => [ + 'href' => 'act=paste&mode=copy', + 'icon' => 'copy.svg' + ], + 'delete' => [ + 'href' => 'act=delete', + 'icon' => 'delete.svg', + 'attributes' => 'onclick="if(!confirm(\'' . ($GLOBALS['TL_LANG']['MSC']['deleteConfirm'] ?? null) . '\'))return false;Backend.getScrollOffset()"' + ], + 'show' => [ + 'href' => 'act=show', + 'icon' => 'show.svg' + ] + ] + ], // Palettes - 'palettes' => array - ( - '__selector__' => array('extendContentElement','extendFormFields','extendModule'), - 'default' => '{title_legend},title,alias,description;{config_legend},cssClasses;{publish_legend},extendLayout,extendPage,extendArticle,extendModule,extendNews,extendEvents,extendForm,extendFormFields,extendContentElement;{expert_legend:hide},chosen,blankOption,cssClass,passToTemplate;' - ), + 'palettes' => [ + '__selector__' => ['extendContentElement','extendFormFields','extendModule'], + 'default' => '{title_legend},title,alias,description;{config_legend},cssClasses;{publish_legend},extendLayout,extendPage,extendArticle,extendModule,extendNews,extendEvents,extendForm,extendFormFields,extendContentElement;{expert_legend:hide},chosen,blankOption,cssClass,passToTemplate;' + ], // Sub-Palettes - 'subpalettes' => array - ( - 'extendContentElement' => 'contentElements', - 'extendFormFields' => 'formFields', - 'extendModule' => 'modules' - ), + 'subpalettes' => [ + 'extendContentElement' => 'contentElements', + 'extendFormFields' => 'formFields', + 'extendModule' => 'modules' + ], // Fields - 'fields' => array - ( - 'id' => array - ( - 'sql' => "int(10) unsigned NOT NULL auto_increment" - ), - 'pid' => array - ( - 'foreignKey' => 'tl_style_manager_archive.title', - 'sql' => "int(10) unsigned NOT NULL default 0", - 'relation' => array('type'=>'belongsTo', 'load'=>'lazy') - ), - 'sorting' => array - ( - 'sql' => "int(10) unsigned NOT NULL default 0" - ), - 'tstamp' => array - ( - 'sql' => "int(10) unsigned NOT NULL default '0'" - ), - 'alias' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['alias'], - 'inputType' => 'text', - 'search' => true, - 'eval' => array('rgxp'=>'alias', 'maxlength'=>128, 'tl_class'=>'w50'), - 'sql' => "varchar(255) BINARY NOT NULL default ''", - 'save_callback' => array - ( - array('tl_style_manager', 'generateAlias') - ), - ), - 'title' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['title'], - 'exclude' => true, - 'search' => true, - 'inputType' => 'text', - 'eval' => array('mandatory'=>true, 'maxlength'=>255, 'tl_class'=>'w50'), - 'sql' => "varchar(255) NOT NULL default ''" - ), - 'description' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['description'], - 'inputType' => 'text', - 'eval' => array('maxlength'=>255, 'tl_class'=>'w50'), - 'sql' => "varchar(255) NOT NULL default ''" - ), - 'cssClasses' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['cssClasses'], - 'exclude' => true, - 'inputType' => 'keyValueWizard', - 'eval' => array('allowHtml'=>true, 'tl_class'=>'clr long'), - 'load_callback' => array( - array('tl_style_manager', 'prepareData'), - array('tl_style_manager', 'translateKeyValue') - ), - 'sql' => "blob NULL" - ), - 'cssClass' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['cssClass'], - 'exclude' => true, - 'inputType' => 'text', - 'reference' => &$GLOBALS['TL_LANG']['tl_style_manager'], - 'eval' => array('helpwizard'=>true, 'maxlength'=>64, 'tl_class'=>'w50'), - 'explanation' => 'styleManagerFieldClass', - 'sql' => "varchar(64) NOT NULL default ''" - ), - 'chosen' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['chosen'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array('tl_class'=>'w50'), - 'sql' => "char(1) NOT NULL default '1'" - ), - 'blankOption' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['blankOption'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array('tl_class'=>'w50'), - 'sql' => "char(1) NOT NULL default '1'" - ), - 'passToTemplate' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['passToTemplate'], - 'exclude' => true, - 'filter' => true, - 'inputType' => 'checkbox', - 'eval' => array('tl_class'=>'w50 m12'), - 'sql' => "char(1) NOT NULL default ''" - ), - 'extendLayout' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['extendLayout'], - 'exclude' => true, - 'filter' => true, - 'inputType' => 'checkbox', - 'eval' => array('tl_class'=>'w50 clr'), - 'sql' => "char(1) NOT NULL default ''" - ), - 'extendPage' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['extendPage'], - 'exclude' => true, - 'filter' => true, - 'inputType' => 'checkbox', - 'eval' => array('tl_class'=>'w50 clr'), - 'sql' => "char(1) NOT NULL default ''" - ), - 'extendArticle' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['extendArticle'], - 'exclude' => true, - 'filter' => true, - 'inputType' => 'checkbox', - 'eval' => array('tl_class'=>'w50 clr'), - 'sql' => "char(1) NOT NULL default ''" - ), - 'extendForm' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['extendForm'], - 'exclude' => true, - 'filter' => true, - 'inputType' => 'checkbox', - 'eval' => array('tl_class'=>'w50 clr'), - 'sql' => "char(1) NOT NULL default ''" - ), - 'extendFormFields' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['extendFormFields'], - 'exclude' => true, - 'filter' => true, - 'inputType' => 'checkbox', - 'eval' => array('tl_class'=>'w50 clr', 'submitOnChange'=>true), - 'sql' => "char(1) NOT NULL default ''" - ), - 'formFields' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['formFields'], - 'inputType' => 'checkbox', - 'options_callback' => array('tl_style_manager', 'getFormFields'), - 'eval' => array('multiple'=>true, 'mandatory'=>true, 'tl_class'=>'w50 clr'), - 'sql' => "blob NULL" - ), - 'extendContentElement' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['extendContentElement'], - 'exclude' => true, - 'filter' => true, - 'inputType' => 'checkbox', - 'eval' => array('tl_class'=>'w50 clr', 'submitOnChange'=>true), - 'sql' => "char(1) NOT NULL default ''" - ), - 'contentElements' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['contentElements'], - 'inputType' => 'checkbox', - 'options_callback' => array('tl_style_manager', 'getContentElements'), - 'reference' => &$GLOBALS['TL_LANG']['CTE'], - 'eval' => array('multiple'=>true, 'mandatory'=>true, 'tl_class'=>'w50 clr'), - 'sql' => "blob NULL" - ), - 'extendModule' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['extendModule'], - 'exclude' => true, - 'filter' => true, - 'inputType' => 'checkbox', - 'eval' => array('tl_class'=>'w50 clr', 'submitOnChange'=>true), - 'sql' => "char(1) NOT NULL default ''" - ), - 'modules' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['modules'], - 'inputType' => 'checkbox', - 'options_callback' => array('tl_style_manager', 'getModules'), - 'reference' => &$GLOBALS['TL_LANG']['FMD'], - 'eval' => array('multiple'=>true, 'mandatory'=>true, 'tl_class'=>'w50 clr'), - 'sql' => "blob NULL" - ), - 'extendNews' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['extendNews'], - 'exclude' => true, - 'filter' => true, - 'inputType' => 'checkbox', - 'eval' => array('tl_class'=>'w50 clr'), - 'sql' => "char(1) NOT NULL default ''" - ), - 'extendEvents' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['extendEvents'], - 'exclude' => true, - 'filter' => true, - 'inputType' => 'checkbox', - 'eval' => array('tl_class'=>'w50 clr'), - 'sql' => "char(1) NOT NULL default ''" - ) - ) -); - - -/** - * Provide miscellaneous methods that are used by the data configuration array. - * - * @author Daniele Sciannimanica - */ - -class tl_style_manager extends Contao\Backend -{ - /** - * Import the back end user object - */ - public function __construct() - { - parent::__construct(); - $this->import('BackendUser', 'User'); - } - - /** - * Check permissions to edit table tl_style_manager - * - * @throws Contao\CoreBundle\Exception\AccessDeniedException - */ - public function checkPermission() - { - $bundles = Contao\System::getContainer()->getParameter('kernel.bundles'); - - if (!isset($bundles['ContaoCalendarBundle'])) - { - unset($GLOBALS['TL_DCA']['tl_style_manager']['fields']['extendEvents']); - } - - if (!isset($bundles['ContaoNewsBundle'])) - { - unset($GLOBALS['TL_DCA']['tl_style_manager']['fields']['extendNews']); - } - - return; - } - - /** - * List a group record - * - * @param array $row - * - * @return string - */ - public function listGroupRecords($row) - { - $arrExtends = null; - $label = $row['title']; - - if($row['passToTemplate']) - { - $label = '$ ' . $label; - } - else - { - $label = 'C ' . $label; - } - - foreach ($row as $field => $value) - { - if(strpos($field, 'extend') === 0 && !!$value) - { - $arrExtends[] = &$GLOBALS['TL_LANG']['tl_style_manager'][ $field ][0]; - } - } - - if($arrExtends !== null) - { - $label .= '[' . implode(", ", $arrExtends) . ']'; - } - - return $label; - } - - /** - * Auto-generate an style group alias if it has not been set yet - * - * @param mixed $varValue - * @param \DataContainer $dc - * - * @return string - * - * @throws Exception - */ - public function generateAlias($varValue, \DataContainer $dc) - { - $aliasExists = function (string $alias) use ($dc): bool - { - return $this->Database->prepare("SELECT id FROM tl_style_manager WHERE alias=? AND id!=? AND pid=?")->execute($alias, $dc->id, $dc->activeRecord->pid)->numRows > 0; - }; - - // Generate an alias if there is none - if ($varValue == '') - { - $varValue = Contao\System::getContainer()->get('contao.slug')->generate($dc->activeRecord->title, $dc->id, $aliasExists); - } - elseif ($aliasExists($varValue)) - { - throw new Exception(sprintf($GLOBALS['TL_LANG']['ERR']['groupAliasExists'], $varValue)); - } - - return $varValue; - } - - /** - * Prepare data from older versions - * - * @param mixed $varValue - * @param \DataContainer $dc - * - * @return string - */ - public function translateKeyValue($varValue, \DataContainer $dc) - { - $GLOBALS['TL_LANG']['MSC']['ow_key'] = $GLOBALS['TL_LANG']['tl_style_manager']['ow_key']; - $GLOBALS['TL_LANG']['MSC']['ow_value'] = $GLOBALS['TL_LANG']['tl_style_manager']['ow_value']; - - return $varValue; - } - - /** - * Prepare data from older versions - * - * @param mixed $varValue - * @param \DataContainer $dc - * - * @return string - */ - public function prepareData($varValue, \DataContainer $dc) - { - $arrValue = \StringUtil::deserialize($varValue); - - if($arrValue !== null) - { - if(!isset($arrValue[0]['key'])) - { - foreach ($arrValue as &$item) { - $item = array( - 'key' => $item, - 'value' => '' - ); - } - } - } - - return serialize($arrValue); - } - - /** - * Return all content elements as array - * - * @return array - */ - public function getContentElements() - { - $groups = array(); - - foreach ($GLOBALS['TL_CTE'] as $k=>$v) - { - foreach (array_keys($v) as $kk) - { - $groups[$k][] = $kk; - } - } - - return $groups; - } - - /** - * Return all form fields as array - * - * @return array - */ - public function getFormFields() - { - \System::loadLanguageFile('tl_form_field'); - - $arrFields = $GLOBALS['TL_FFL']; - - // Add the translation - foreach (array_keys($arrFields) as $key) - { - $arrFields[$key] = $GLOBALS['TL_LANG']['FFL'][$key][0]; - } - - return $arrFields; - } - - /** - * Get all modules and return them as array - * - * @return array - */ - public function getModules() - { - $groups = array(); - - foreach ($GLOBALS['FE_MOD'] as $k=>$v) - { - foreach (array_keys($v) as $kk) - { - $groups[$k][] = $kk; - } - } - - return $groups; - } -} + 'fields' => [ + 'id' => [ + 'sql' => "int(10) unsigned NOT NULL auto_increment" + ], + 'pid' => [ + 'foreignKey' => 'tl_style_manager_archive.title', + 'sql' => "int(10) unsigned NOT NULL default 0", + 'relation' => ['type'=>'belongsTo', 'load'=>'lazy'] + ], + 'sorting' => [ + 'sql' => "int(10) unsigned NOT NULL default 0" + ], + 'tstamp' => [ + 'sql' => "int(10) unsigned NOT NULL default '0'" + ], + 'alias' => [ + 'inputType' => 'text', + 'search' => true, + 'eval' => ['rgxp'=>'alias', 'maxlength'=>128, 'tl_class'=>'w50'], + 'sql' => "varchar(255) BINARY NOT NULL default ''" + ], + 'title' => [ + 'exclude' => true, + 'search' => true, + 'inputType' => 'text', + 'eval' => ['mandatory'=>true, 'maxlength'=>255, 'tl_class'=>'w50'], + 'sql' => "varchar(255) NOT NULL default ''" + ], + 'description' => [ + 'inputType' => 'text', + 'eval' => ['maxlength'=>255, 'tl_class'=>'w50'], + 'sql' => "varchar(255) NOT NULL default ''" + ], + 'cssClasses' => [ + 'exclude' => true, + 'inputType' => 'keyValueWizard', + 'eval' => ['allowHtml'=>true, 'tl_class'=>'clr long'], + 'sql' => "blob NULL" + ], + 'cssClass' => [ + 'exclude' => true, + 'inputType' => 'text', + 'reference' => &$GLOBALS['TL_LANG']['tl_style_manager'], + 'eval' => ['helpwizard'=>true, 'maxlength'=>64, 'tl_class'=>'w50'], + 'explanation' => 'styleManagerFieldClass', + 'sql' => "varchar(64) NOT NULL default ''" + ], + 'chosen' => [ + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => ['tl_class'=>'w50'], + 'sql' => "char(1) NOT NULL default '1'" + ], + 'blankOption' => [ + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => ['tl_class'=>'w50'], + 'sql' => "char(1) NOT NULL default '1'" + ], + 'passToTemplate' => [ + 'exclude' => true, + 'filter' => true, + 'inputType' => 'checkbox', + 'eval' => ['tl_class'=>'w50 m12'], + 'sql' => "char(1) NOT NULL default ''" + ], + 'extendLayout' => [ + 'exclude' => true, + 'filter' => true, + 'inputType' => 'checkbox', + 'eval' => ['tl_class'=>'w50 clr'], + 'sql' => "char(1) NOT NULL default ''" + ], + 'extendPage' => [ + 'exclude' => true, + 'filter' => true, + 'inputType' => 'checkbox', + 'eval' => ['tl_class'=>'w50 clr'], + 'sql' => "char(1) NOT NULL default ''" + ], + 'extendArticle' => [ + 'exclude' => true, + 'filter' => true, + 'inputType' => 'checkbox', + 'eval' => ['tl_class'=>'w50 clr'], + 'sql' => "char(1) NOT NULL default ''" + ], + 'extendForm' => [ + 'exclude' => true, + 'filter' => true, + 'inputType' => 'checkbox', + 'eval' => ['tl_class'=>'w50 clr'], + 'sql' => "char(1) NOT NULL default ''" + ], + 'extendFormFields' => [ + 'exclude' => true, + 'filter' => true, + 'inputType' => 'checkbox', + 'eval' => ['tl_class'=>'w50 clr', 'submitOnChange'=>true], + 'sql' => "char(1) NOT NULL default ''" + ], + 'formFields' => [ + 'inputType' => 'checkbox', + 'eval' => ['multiple'=>true, 'mandatory'=>true, 'tl_class'=>'w50 clr'], + 'sql' => "blob NULL" + ], + 'extendContentElement' => [ + 'exclude' => true, + 'filter' => true, + 'inputType' => 'checkbox', + 'eval' => ['tl_class'=>'w50 clr', 'submitOnChange'=>true], + 'sql' => "char(1) NOT NULL default ''" + ], + 'contentElements' => [ + 'inputType' => 'checkbox', + 'reference' => &$GLOBALS['TL_LANG']['CTE'], + 'eval' => ['multiple'=>true, 'mandatory'=>true, 'tl_class'=>'w50 clr'], + 'sql' => "blob NULL" + ], + 'extendModule' => [ + 'exclude' => true, + 'filter' => true, + 'inputType' => 'checkbox', + 'eval' => ['tl_class'=>'w50 clr', 'submitOnChange'=>true], + 'sql' => "char(1) NOT NULL default ''" + ], + 'modules' => [ + 'inputType' => 'checkbox', + 'reference' => &$GLOBALS['TL_LANG']['FMD'], + 'eval' => ['multiple'=>true, 'mandatory'=>true, 'tl_class'=>'w50 clr'], + 'sql' => "blob NULL" + ], + 'extendNews' => [ + 'exclude' => true, + 'filter' => true, + 'inputType' => 'checkbox', + 'eval' => ['tl_class'=>'w50 clr'], + 'sql' => "char(1) NOT NULL default ''" + ], + 'extendEvents' => [ + 'exclude' => true, + 'filter' => true, + 'inputType' => 'checkbox', + 'eval' => ['tl_class'=>'w50 clr'], + 'sql' => "char(1) NOT NULL default ''" + ] + ] +]; diff --git a/src/Resources/contao/dca/tl_style_manager_archive.php b/src/Resources/contao/dca/tl_style_manager_archive.php index 76872c2..71e9ee5 100644 --- a/src/Resources/contao/dca/tl_style_manager_archive.php +++ b/src/Resources/contao/dca/tl_style_manager_archive.php @@ -5,305 +5,124 @@ * (c) https://www.oveleon.de/ */ -$GLOBALS['TL_DCA']['tl_style_manager_archive'] = array -( - +$GLOBALS['TL_DCA']['tl_style_manager_archive'] = [ // Config - 'config' => array - ( + 'config' => [ 'dataContainer' => 'Table', - 'ctable' => array('tl_style_manager'), + 'ctable' => ['tl_style_manager'], 'switchToEdit' => true, 'enableVersioning' => true, 'markAsCopy' => 'title', - 'onload_callback' => array - ( - array('tl_style_manager_archive', 'checkPermission'), - array('tl_style_manager_archive', 'checkIdentifier') - ), - 'sql' => array - ( - 'keys' => array - ( + 'sql' => [ + 'keys' => [ 'id' => 'primary' - ) - ) - ), + ] + ] + ], // List - 'list' => array - ( - 'sorting' => array - ( + 'list' => [ + 'sorting' => [ 'mode' => 1, - 'fields' => array('groupAlias', 'sorting'), + 'fields' => ['groupAlias', 'sorting'], 'panelLayout' => 'filter;search,limit' - ), - 'label' => array - ( - 'fields' => array('title'), - 'format' => '%s', - 'label_callback' => array('tl_style_manager_archive', 'addIdentifierInfo') - ), - 'global_operations' => array - ( - 'import' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager_archive']['import'], + ], + 'label' => [ + 'fields' => ['title'], + 'format' => '%s' + ], + 'global_operations' => [ + 'import' => [ 'href' => 'key=import', 'class' => 'header_style_manager_import', - 'icon' => 'theme_import.svg', - 'button_callback' => array('tl_style_manager_archive', 'importConfig') - ), - 'export' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager_archive']['export'], + 'icon' => 'theme_import.svg' + ], + 'export' => [ 'href' => 'key=export', 'class' => 'header_style_manager_export', 'icon' => 'theme_export.svg' - ), - 'all' => array - ( - 'label' => &$GLOBALS['TL_LANG']['MSC']['all'], + ], + 'all' => [ 'href' => 'act=select', 'class' => 'header_edit_all', 'attributes' => 'onclick="Backend.getScrollOffset()" accesskey="e"' - ), - 'config' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager_archive']['headingActiveBundles'], + ], + 'config' => [ 'href' => 'key=import', - 'class' => 'header_style_manager_config', - 'button_callback' => array('tl_style_manager_archive', 'activeConfig') - ) - ), - 'operations' => array - ( - 'edit' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager_archive']['edit'], + 'class' => 'header_style_manager_config' + ] + ], + 'operations' => [ + 'edit' => [ 'href' => 'table=tl_style_manager', 'icon' => 'edit.svg' - ), - 'editheader' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager_archive']['editheader'], + ], + 'editheader' => [ 'href' => 'act=edit', 'icon' => 'header.svg', - ), - 'copy' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager_archive']['copy'], + ], + 'copy' => [ 'href' => 'act=copy', 'icon' => 'copy.svg' - ), - 'delete' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager_archive']['delete'], + ], + 'delete' => [ 'href' => 'act=delete', 'icon' => 'delete.svg', 'attributes' => 'onclick="if(!confirm(\'' . ($GLOBALS['TL_LANG']['MSC']['deleteConfirm'] ?? null) . '\'))return false;Backend.getScrollOffset()"' - ), - 'show' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager_archive']['show'], + ], + 'show' => [ 'href' => 'act=show', 'icon' => 'show.svg' - ) - ) - ), + ] + ] + ], // Palettes - 'palettes' => array - ( + 'palettes' => [ 'default' => '{title_legend},title,identifier;{config_legend},groupAlias,sorting;desc' - ), + ], // Fields - 'fields' => array - ( - 'id' => array - ( + 'fields' => [ + 'id' => [ 'sql' => "int(10) unsigned NOT NULL auto_increment" - ), - 'tstamp' => array - ( + ], + 'tstamp' => [ 'sql' => "int(10) unsigned NOT NULL default '0'" - ), - 'title' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager_archive']['title'], + ], + 'title' => [ 'search' => true, 'inputType' => 'text', - 'eval' => array('mandatory'=>true, 'maxlength'=>255, 'tl_class'=>'w50'), + 'eval' => ['mandatory'=>true, 'maxlength'=>255, 'tl_class'=>'w50'], 'sql' => "varchar(255) NOT NULL default ''" - ), - 'desc' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager_archive']['desc'], + ], + 'desc' => [ 'exclude' => true, 'search' => true, 'inputType' => 'textarea', - 'eval' => array('style'=>'height:60px', 'decodeEntities'=>true, 'tl_class'=>'clr'), + 'eval' => ['style'=>'height:60px', 'decodeEntities'=>true, 'tl_class'=>'clr'], 'sql' => "text NULL" - ), - 'identifier' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager_archive']['identifier'], + ], + 'identifier' => [ 'exclude' => true, 'search' => true, 'inputType' => 'text', - 'eval' => array('mandatory'=>true, 'rgxp'=>'variable', 'nospace'=>true, 'maxlength'=>255, 'tl_class'=>'w50', 'doNotCopy'=>true), + 'eval' => ['mandatory'=>true, 'rgxp'=>'variable', 'nospace'=>true, 'maxlength'=>255, 'tl_class'=>'w50', 'doNotCopy'=>true], 'sql' => "varchar(255) NOT NULL default ''", - 'save_callback' => array - ( - array('tl_style_manager_archive', 'saveIdentifier') - ), - ), - 'groupAlias' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager_archive']['groupAlias'], + ], + 'groupAlias' => [ 'exclude' => true, 'search' => true, 'inputType' => 'text', - 'eval' => array('rgxp'=>'variable', 'nospace'=>true, 'maxlength'=>255, 'tl_class'=>'w50'), + 'eval' => ['rgxp'=>'variable', 'nospace'=>true, 'maxlength'=>255, 'tl_class'=>'w50'], 'sql' => "varchar(255) NOT NULL default ''" - ), - 'sorting' => array - ( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager_archive']['sorting'], + ], + 'sorting' => [ 'exclude' => true, 'sorting' => true, 'inputType' => 'text', - 'eval' => array('rgxp'=>'natural', 'nospace'=>true, 'maxlength'=>255, 'tl_class'=>'w50'), + 'eval' => ['rgxp'=>'natural', 'nospace'=>true, 'maxlength'=>255, 'tl_class'=>'w50'], 'sql' => "int(10) NOT NULL default '0'" - ) - ) -); - - -/** - * Provide miscellaneous methods that are used by the data configuration array. - * - * @author Daniele Sciannimanica - */ - -use Contao\System; -use Oveleon\ContaoComponentStyleManager\Config; -use Oveleon\ContaoComponentStyleManager\StyleManagerArchiveModel; - -class tl_style_manager_archive extends \Backend -{ - /** - * Import the back end user object - */ - public function __construct() - { - parent::__construct(); - $this->import('BackendUser', 'User'); - } - - /** - * Check permissions to edit table tl_style_manager_archive - * - * @throws Contao\CoreBundle\Exception\AccessDeniedException - */ - public function checkPermission() - { - return; - } - - /** - * Add identifier information - * - * @param array $row - * @param string $label - * - * @return string - */ - public function addIdentifierInfo($row, $label) - { - if($row['identifier']) - { - $label .= '[' . $row['identifier'] . ']'; - } - - return $label; - } - - /** - * Check identifier - * - * @param $dc - */ - public function checkIdentifier($dc){ - $objArchive = StyleManagerArchiveModel::findById($dc->id); - - if(null !== $objArchive && $objArchive->identifier) - { - $GLOBALS['TL_DCA']['tl_style_manager_archive']['fields']['identifier']['eval']['mandatory'] = false; - $GLOBALS['TL_DCA']['tl_style_manager_archive']['fields']['identifier']['eval']['disabled'] = true; - } - } - - /** - * Check if identifier already exists - * - * @param mixed $varValue - * @param Contao\DataContainer $dc - * - * @return string - * - * @throws Exception - */ - public function saveIdentifier($varValue, Contao\DataContainer $dc) - { - $aliasExists = function (string $alias) use ($dc): bool - { - return $this->Database->prepare("SELECT id FROM tl_style_manager_archive WHERE identifier=? AND id!=?")->execute($alias, $dc->id)->numRows > 0; - }; - - if ($aliasExists($varValue)) - { - throw new Exception(sprintf($GLOBALS['TL_LANG']['ERR']['identifierExists'], $varValue)); - } - - return $varValue; - } - - /** - * Return the import header button - */ - public function importConfig(string $href, string $label, string $title, string $class, string $attributes): string - { - if(System::getContainer()->getParameter('contao_component_style_manager.use_bundle_config')) - { - if($arrFiles = Config::getBundleConfigurationFiles()) - { - $label .= ' (' . count($arrFiles) . ')'; - } - } - - return '' . $label . ' '; - } - - /** - * Return the configurations label - */ - public function activeConfig(string $href, string $label, string $title, string $class, string $attributes): string - { - if(System::getContainer()->getParameter('contao_component_style_manager.use_bundle_config')) - { - $count = 0; - - if($arrFiles = Config::getBundleConfigurationFiles()) - { - $count = count($arrFiles); - } - - return ''. $label .': ' . $count . ''; - } - - return ''; - } -} + ] + ] +]; diff --git a/src/Resources/contao/classes/Config.php b/src/StyleManager/Config.php similarity index 98% rename from src/Resources/contao/classes/Config.php rename to src/StyleManager/Config.php index bb21982..85b888e 100644 --- a/src/Resources/contao/classes/Config.php +++ b/src/StyleManager/Config.php @@ -6,7 +6,7 @@ * (c) https://www.oveleon.de/ */ -namespace Oveleon\ContaoComponentStyleManager; +namespace Oveleon\ContaoComponentStyleManager\StyleManager; use Contao\System; diff --git a/src/Resources/contao/classes/StyleManager.php b/src/StyleManager/StyleManager.php similarity index 83% rename from src/Resources/contao/classes/StyleManager.php rename to src/StyleManager/StyleManager.php index 7bac734..ac10923 100644 --- a/src/Resources/contao/classes/StyleManager.php +++ b/src/StyleManager/StyleManager.php @@ -5,29 +5,26 @@ * (c) https://www.oveleon.de/ */ -namespace Oveleon\ContaoComponentStyleManager; +namespace Oveleon\ContaoComponentStyleManager\StyleManager; use Contao\Backend; use Contao\CoreBundle\DataContainer\PaletteManipulator; use Contao\StringUtil; use Contao\System; -use Contao\Widget; +use Oveleon\ContaoComponentStyleManager\Model\StyleManagerArchiveModel; +use Oveleon\ContaoComponentStyleManager\Model\StyleManagerModel; class StyleManager { /** - * Valid CSS-Class fields - * - * field => size - * - * @var array + * Valid CSS-Class fields [field => size] */ - public static $validCssClassFields = array( + public static array $validCssClassFields = [ 'cssID' => 2, 'cssClass' => 1, 'class' => 1, 'attributes' => 2 - ); + ]; /** * Load callback for the CSS-Classes DCA-Field @@ -306,7 +303,8 @@ public static function isMultipleField($strField) * * @return array|bool */ - public static function serializeValues($varValue, $strTable){ + public static function serializeValues($varValue, $strTable) + { $objStyleGroups = StyleManagerModel::findByTableAndConfiguration($strTable); if($objStyleGroups === null) @@ -359,8 +357,8 @@ public static function serializeValues($varValue, $strTable){ * * @return mixed */ - public static function deserializeValues($arrValue){ - + public static function deserializeValues($arrValue) + { if(isset($arrValue['__vars__'])) { foreach ($arrValue['__vars__'] as $archiveAlias => $values) @@ -415,52 +413,6 @@ public static function isVisibleGroup(StyleManagerModel $objGroup, string $strTa return false; } - /** - * Parse Template and set Variables - * - * @param $template - */ - public function onParseTemplate($template) - { - // Check page and template variables to pass them to the template - if(strpos($template->getName(), 'fe_page') === 0) - { - global $objPage; - - $arrStyles = array_filter(array_merge_recursive( - StringUtil::deserialize($objPage->styleManager, true), - StringUtil::deserialize($template->layout->styleManager, true) - )); - - $template->styleManager = serialize($arrStyles); - } - - // Build Styles object and assign it to the template - if(!($template->styleManager instanceof Styles)) - { - $arrStyles = StringUtil::deserialize($template->styleManager); - $template->styleManager = new Styles(isset($arrStyles['__vars__']) ? $arrStyles['__vars__'] : null); - } - } - - /** - * Parse Template and set Variables - * - * @param $objWidget - * - * @return \Widget - */ - public function onLoadFormField($objWidget) - { - if(!($objWidget->styleManager instanceof Styles)) - { - $arrStyles = StringUtil::deserialize($objWidget->styleManager); - $objWidget->styleManager = new Styles(isset($arrStyles['__vars__']) ? $arrStyles['__vars__'] : null); - } - - return $objWidget; - } - /** * Add the type of input field * @@ -476,28 +428,4 @@ public function listFormFields($arrRow) $formField = new \tl_form_field(); return $formField->listFormFields($arrRow); } - - /** - * Add a new regexp "variable" - * - * @param $strRegexp - * @param $varValue - * @param Widget $objWidget - * - * @return bool - */ - public function addVariableRegexp($strRegexp, $varValue, Widget $objWidget): bool - { - if ($strRegexp == 'variable') - { - if (!preg_match('/^[a-zA-Z](?:_?[a-zA-Z0-9]+)$/', $varValue)) - { - $objWidget->addError('Field ' . $objWidget->label . ' must begin with a letter and may not contain any spaces or special characters (e.g. myVariable).'); - } - - return true; - } - - return false; - } } diff --git a/src/Resources/contao/classes/Styles.php b/src/StyleManager/Styles.php similarity index 96% rename from src/Resources/contao/classes/Styles.php rename to src/StyleManager/Styles.php index 4613ff1..a120f1f 100644 --- a/src/Resources/contao/classes/Styles.php +++ b/src/StyleManager/Styles.php @@ -5,7 +5,9 @@ * (c) https://www.oveleon.de/ */ -namespace Oveleon\ContaoComponentStyleManager; +namespace Oveleon\ContaoComponentStyleManager\StyleManager; + +use Contao\System; class Styles { @@ -149,7 +151,7 @@ public function format($format, $method='') { foreach ($GLOBALS['TL_HOOKS']['styleManagerFormatMethod'] as $callback) { - return \System::importStatic($callback[0])->{$callback[1]}($format, $method, $this); + return System::importStatic($callback[0])->{$callback[1]}($format, $method, $this); } } diff --git a/src/Resources/contao/classes/Sync.php b/src/StyleManager/Sync.php similarity index 98% rename from src/Resources/contao/classes/Sync.php rename to src/StyleManager/Sync.php index d281f0c..fb692e0 100644 --- a/src/Resources/contao/classes/Sync.php +++ b/src/StyleManager/Sync.php @@ -5,7 +5,7 @@ * (c) https://www.oveleon.de/ */ -namespace Oveleon\ContaoComponentStyleManager; +namespace Oveleon\ContaoComponentStyleManager\StyleManager; use Contao\Backend; use Contao\BackendTemplate; @@ -20,6 +20,9 @@ use Contao\Model\Collection; use Contao\StringUtil; use Contao\System; +use Oveleon\ContaoComponentStyleManager\Model\StyleManagerArchiveModel; +use Oveleon\ContaoComponentStyleManager\Model\StyleManagerModel; +use Oveleon\ContaoComponentStyleManager\StyleManager\Config as BundleConfig; class Sync extends Backend { @@ -222,7 +225,7 @@ public function importStyleManager() $template->descBundleFiles = $GLOBALS['TL_LANG']['tl_style_manager_archive']['descBundleConfig']; $template->activeDescBundleFiles = $GLOBALS['TL_LANG']['tl_style_manager_archive']['activateBundleConfig']; - $template->bundleFiles = \Oveleon\ContaoComponentStyleManager\Config::getBundleConfigurationFiles() ?? []; + $template->bundleFiles = BundleConfig::getBundleConfigurationFiles() ?? []; return $template->parse(); } diff --git a/src/Resources/contao/widgets/ComponentStyleSelect.php b/src/Widget/ComponentStyleSelect.php similarity index 98% rename from src/Resources/contao/widgets/ComponentStyleSelect.php rename to src/Widget/ComponentStyleSelect.php index 7314258..015c5f4 100644 --- a/src/Resources/contao/widgets/ComponentStyleSelect.php +++ b/src/Widget/ComponentStyleSelect.php @@ -5,7 +5,7 @@ * (c) https://www.oveleon.de/ */ -namespace Oveleon\ContaoComponentStyleManager; +namespace Oveleon\ContaoComponentStyleManager\Widget; use Contao\BackendUser; use Contao\Database; @@ -13,6 +13,9 @@ use Contao\StringUtil; use Contao\System; use Contao\Widget; +use Oveleon\ContaoComponentStyleManager\Model\StyleManagerArchiveModel; +use Oveleon\ContaoComponentStyleManager\Model\StyleManagerModel; +use Oveleon\ContaoComponentStyleManager\StyleManager\StyleManager; /** * Provide methods to handle select menus for style manager. From 84f83d4698330b2a28ca52520fc549c9807014df Mon Sep 17 00:00:00 2001 From: doishub Date: Tue, 11 Oct 2022 12:26:38 +0200 Subject: [PATCH 27/48] Partial import added --- src/ContaoManager/Plugin.php | 16 +- .../BackendModule/ImportController.php | 510 ++++++++++++++++++ .../StyleManagerArchiveListener.php | 6 +- src/Resources/config/routes.yaml | 3 + src/Resources/contao/config/config.php | 3 +- .../contao/dca/tl_style_manager_archive.php | 6 +- .../languages/de/tl_style_manager_archive.xlf | 76 ++- .../languages/de/tl_style_manager_import.xlf | 44 ++ .../languages/en/tl_style_manager_archive.xlf | 53 +- .../languages/en/tl_style_manager_import.xlf | 35 ++ .../languages/fr/tl_style_manager_archive.xlf | 74 ++- .../languages/fr/tl_style_manager_import.xlf | 44 ++ .../backend/be_style_manager_import.html5 | 53 -- src/Resources/views/import.html.twig | 126 +++++ src/StyleManager/Config.php | 4 +- src/StyleManager/Sync.php | 407 +------------- 16 files changed, 923 insertions(+), 537 deletions(-) create mode 100644 src/Controller/BackendModule/ImportController.php create mode 100644 src/Resources/config/routes.yaml create mode 100644 src/Resources/contao/languages/de/tl_style_manager_import.xlf create mode 100644 src/Resources/contao/languages/en/tl_style_manager_import.xlf create mode 100644 src/Resources/contao/languages/fr/tl_style_manager_import.xlf delete mode 100644 src/Resources/contao/templates/backend/be_style_manager_import.html5 create mode 100644 src/Resources/views/import.html.twig diff --git a/src/ContaoManager/Plugin.php b/src/ContaoManager/Plugin.php index 02fc0fe..737fd0f 100644 --- a/src/ContaoManager/Plugin.php +++ b/src/ContaoManager/Plugin.php @@ -12,13 +12,16 @@ use Contao\CoreBundle\ContaoCoreBundle; use Contao\CalendarBundle\ContaoCalendarBundle; +use Contao\ManagerPlugin\Routing\RoutingPluginInterface; use Contao\NewsBundle\ContaoNewsBundle; use Contao\ManagerPlugin\Bundle\BundlePluginInterface; use Contao\ManagerPlugin\Bundle\Config\BundleConfig; use Contao\ManagerPlugin\Bundle\Parser\ParserInterface; use Oveleon\ContaoComponentStyleManager\ContaoComponentStyleManager; +use Symfony\Component\Config\Loader\LoaderResolverInterface; +use Symfony\Component\HttpKernel\KernelInterface; -class Plugin implements BundlePluginInterface +class Plugin implements BundlePluginInterface, RoutingPluginInterface { /** * {@inheritdoc} @@ -31,4 +34,15 @@ public function getBundles(ParserInterface $parser): array ->setReplace(['componentStyleManager']), ]; } + + /** + * {@inheritdoc} + */ + public function getRouteCollection(LoaderResolverInterface $resolver, KernelInterface $kernel) + { + return $resolver + ->resolve(__DIR__.'/../Resources/config/routes.yaml') + ->load(__DIR__.'/../Resources/config/routes.yaml') + ; + } } diff --git a/src/Controller/BackendModule/ImportController.php b/src/Controller/BackendModule/ImportController.php new file mode 100644 index 0000000..1979211 --- /dev/null +++ b/src/Controller/BackendModule/ImportController.php @@ -0,0 +1,510 @@ +twig = $twig; + $this->requestStack = $requestStack; + $this->translator = $translator; + } + + public function __invoke(): Response + { + Controller::loadLanguageFile('defaults'); + Controller::loadLanguageFile('tl_style_manager_import'); + + // Add xml extension as valid upload type + Config::set('uploadTypes', Config::get('uploadTypes') . ',xml'); + + /** @var FileUpload $objUploader */ + $objUploader = new FileUpload(); + + // Get current request + $request = $this->requestStack->getCurrentRequest(); + + $partial = !!$request->get('import_partial'); + $configs = null; + + switch ($request->get('FORM_SUBMIT')) + { + case 'style_manager_import': + $configs = $this->importByFileUploader($objUploader, $partial); + break; + + case 'style_manager_import_partial': + $this->importPartial($request->get('files'), $request->get('archives'), $request->get('groups')); + break; + + case 'style_manager_import_bundle': + if(!$files = $request->get('bundleFiles')) + { + Message::addError($this->translator->trans('ERR.all_fields', [], 'contao_default')); + + // Reload page + throw new RedirectResponseException($request->getUri(), 303); + } + + $configs = $this->importBundleConfigFiles($files, $partial); + } + + if($configs !== null) + { + $configs = $this->createImportTree(...$configs); + } + + return new Response($this->twig->render('@ContaoComponentStyleManager/import.html.twig', [ + 'headline' => $partial ? $this->translator->trans('tl_style_manager_import.importPartial', [], 'contao_default') : 'Import', + 'messages' => Message::generate(), + 'useBundleConfig' => System::getContainer()->getParameter('contao_component_style_manager.use_bundle_config'), + 'bundleFiles' => BundleConfig::getBundleConfigurationFiles() ?? [], + 'partial' => $partial, + 'configs' => $configs, + 'form' => [ + 'id' => 'style_manager_import', + 'rt' => System::getContainer()->get('contao.csrf.token_manager')->getDefaultTokenValue(), + 'maxFileSize' => Config::get('maxFileSize'), + 'uploadWidget' => $objUploader->generateMarkup() + ], + 'action' => [ + 'back' => str_replace('/' . self::ROUTE, '', TL_SCRIPT) . '?do=style_manager', + ], + 'label' => [ + 'back' => $this->translator->trans('MSC.backBT', [], 'contao_default'), + 'backTitle' => $this->translator->trans('MSC.backBTTitle', [], 'contao_default'), + 'files' => $this->translator->trans('tl_style_manager_import.files', [], 'contao_default'), + 'import' => $this->translator->trans('tl_style_manager_import.import', [], 'contao_default'), + 'importPartial' => $this->translator->trans('tl_style_manager_import.importPartial', [], 'contao_default'), + 'importPartialDesc' => $this->translator->trans('tl_style_manager_import.importPartialDesc', [], 'contao_default'), + 'importManual' => $this->translator->trans('tl_style_manager_import.importManual', [], 'contao_default'), + 'widgetDescription' => $this->translator->trans('tl_style_manager_import.uploadFile', [], 'contao_default'), + 'bundleUpload' => $this->translator->trans('tl_style_manager_import.bundleConfig', [], 'contao_default'), + 'bundleConfigEmpty' => $this->translator->trans('tl_style_manager_import.bundleConfigEmpty', [], 'contao_default'), + 'bundleConfigInactive' => $this->translator->trans('tl_style_manager_import.bundleConfigInactive', [], 'contao_default'), + ] + ])); + } + + /** + * Create a tree from archives and groups + */ + public function createImportTree($archives, $groups, $files) + { + $collection = [ + 'files' => $files, + 'collection' => [] + ]; + + $_groups = $groups; + + // Check if archive exists + $getGroups = function (int $pid) use (&$_groups): array + { + $collection = []; + + foreach ($_groups ?? [] as $alias => &$group) + { + if($pid === $group->pid) + { + $collection[ $alias ] = $group; + + array_splice($_groups, array_search($alias, $_groups), 1); + } + } + + return $collection; + }; + + foreach ($archives ?? [] as $key => $archive) + { + $collection['collection'][ $key ] = [ + 'archive' => $archive, + 'children' => $getGroups((int) $archive->id) + ]; + } + + return $collection; + } + + /** + * Partial import + */ + private function importPartial(array $files, array $archives, array $groups): ?array + { + return $this->importFiles($files, true, $archives, $groups); + } + + /** + * Import based on bundle configurations + */ + public function importBundleConfigFiles(array $files, bool $partial = false): ?array + { + return $this->importFiles(array_map(fn($n) => html_entity_decode($n), $files), !$partial); + } + + /** + * Import using a FileUploader + */ + public function importByFileUploader(FileUpload $objUploader, bool $partial = false): ?array + { + Controller::loadLanguageFile('default'); + + // Get current request + $request = $this->requestStack->getCurrentRequest(); + + // Upload files + $uploaded = $objUploader->uploadTo('system/tmp'); + + // Get root dir + $rootDir = System::getContainer()->getParameter('kernel.project_dir'); + + if (empty($uploaded)) + { + Message::addError($this->translator->trans('ERR.all_fields', [], 'contao_default')); + + // Reload page + throw new RedirectResponseException($request->getUri(), 303); + } + + $arrFiles = []; + + foreach ($uploaded as $file) + { + // Skip folders + if (is_dir($rootDir . '/' . $file)) + { + Message::addError(sprintf($this->translator->trans('ERR.importFolder', [], 'contao_default'), basename($file))); + continue; + } + + $objFile = new File($file); + + // Skip anything but .xml files + if ($objFile->extension != 'xml') + { + Message::addError(sprintf($this->translator->trans('ERR.filetype', [], 'contao_default'), $objFile->extension)); + continue; + } + + $arrFiles[] = $file; + } + + // Check whether there are any files + if (empty($arrFiles)) + { + Message::addError($this->translator->trans('ERR.all_fields', [], 'contao_default')); + + // Reload page + throw new RedirectResponseException($request->getUri(), 303); + } + + $data = $this->importFiles($arrFiles, !$partial); + + if($partial) + { + return $data; + } + + // Reload page + throw new RedirectResponseException($request->getUri(), 303); + } + + /** + * Import config files + */ + public static function importFiles(array $files, bool $blnSave = true, ?array $allowedArchives = null, ?array $allowedGroups = null): ?array + { + $arrStyleArchives = []; + $arrStyleGroups = []; + + $database = Database::getInstance(); + $translator = Controller::getContainer()->get('translator'); + + // Get the next id + $intArchiveId = $database->getNextId('tl_style_manager_archive'); + $intGroupId = $database->getNextId('tl_style_manager'); + + foreach ($files as $filePath) + { + $objFile = new File($filePath); + + // Check if file exists + if ($objFile->exists()) + { + // Load xml file + $xml = new DOMDocument(); + $xml->preserveWhiteSpace = false; + + // Continue if there is no readable XML file + if (!$xml->loadXML($objFile->getContent())) + { + Message::addError($translator->trans('tl_theme.missing_xml', [basename($filePath)], 'contao_default')); + continue; + } + + // Get archives node + $archives = $xml->getElementsByTagName('archives'); + + if($archives->count()){ + // Skip archives node + $archives = $archives->item(0)->childNodes; + }else return null; + + // Lock the tables + $arrLocks = array + ( + 'tl_style_manager_archive' => 'WRITE', + 'tl_style_manager' => 'WRITE' + ); + + // Load the DCAs of the locked tables + foreach (array_keys($arrLocks) as $table) + { + Controller::loadDataContainer($table); + } + + if($blnSave) + { + $database->lockTables($arrLocks); + } + + // Check if archive exists + $archiveExists = function (string $identifier) use ($database, $blnSave, $arrStyleArchives) : bool + { + if(!$blnSave) + { + return array_key_exists($identifier, $arrStyleArchives); + } + + return $database->prepare("SELECT identifier FROM tl_style_manager_archive WHERE identifier=?")->execute($identifier)->numRows > 0; + }; + + // Check if children exists + $childrenExists = function (string $alias, string $pid) use($database, $blnSave, $arrStyleGroups) : bool + { + if(!$blnSave) + { + return array_key_exists($alias, $arrStyleGroups); + } + + return $database->prepare("SELECT alias FROM tl_style_manager WHERE alias=? AND pid=?")->execute($alias, $pid)->numRows > 0; + }; + + // Loop through the archives + for ($i=0; $i<$archives->length; $i++) + { + $archive = $archives->item($i)->childNodes; + $identifier = $archives->item($i)->getAttribute('identifier'); + + if(null !== $allowedArchives && !in_array($identifier, $allowedArchives)) + { + continue; + } + + if(!$blnSave || !$archiveExists($identifier)) + { + if(!$blnSave && $archiveExists($identifier)) + { + $objArchive = $arrStyleArchives[$identifier]; + } + else + { + $objArchive = new StyleManagerArchiveModel(); + $objArchive->id = ++$intArchiveId; + } + } + else + { + $objArchive = StyleManagerArchiveModel::findByIdentifier($identifier); + } + + // Loop through the archives fields + for ($a=0; $a<$archive->length; $a++) + { + $strField = $archive->item($a)->nodeName; + + if($strField === 'field') + { + $strName = $archive->item($a)->getAttribute('title'); + $strValue = $archive->item($a)->nodeValue; + + if($strName === 'id' || strtolower($strValue) === 'null') + { + continue; + } + + $objArchive->{$strName} = $strValue; + } + elseif($strField === 'children') + { + $children = $archive->item($a)->childNodes; + + // Loop through the archives fields + for ($c=0; $c<$children->length; $c++) + { + $alias = $children->item($c)->getAttribute('alias'); + $fields = $children->item($c)->childNodes; + + $strChildAlias = Sync::combineAliases($objArchive->identifier, $alias); + + if(null !== $allowedGroups && !in_array($strChildAlias, $allowedGroups)) + { + continue; + } + + if(!$blnSave || !$childrenExists($strChildAlias, $objArchive->id)) + { + if(!$blnSave && $childrenExists($strChildAlias, $objArchive->id)) + { + $objChildren = $arrStyleGroups[$strChildAlias]; + } + else + { + $objChildren = new StyleManagerModel(); + $objChildren->id = ++$intGroupId; + } + } + else + { + $objChildren = StyleManagerModel::findByAliasAndPid($alias, $objArchive->id); + } + + // Loop through the children fields + for ($f=0; $f<$fields->length; $f++) + { + $strName = $fields->item($f)->getAttribute('title'); + $strValue = $fields->item($f)->nodeValue; + + if($strName === 'id' || !$strValue || strtolower($strValue) === 'null') + { + continue; + } + + switch($strName) + { + case 'pid': + $strValue = $objArchive->id; + break; + case 'cssClasses': + if($objChildren->{$strName}) + { + $arrClasses = StringUtil::deserialize($objChildren->{$strName}, true); + $arrExists = Sync::flattenKeyValueArray($arrClasses); + $arrValues = StringUtil::deserialize($strValue, true); + + foreach($arrValues as $cssClass) + { + if(array_key_exists($cssClass['key'], $arrExists)) + { + continue; + } + + $arrClasses[] = array( + 'key' => $cssClass['key'], + 'value' => $cssClass['value'] + ); + } + + $strValue = serialize($arrClasses); + } + + break; + default: + $dcaField = $GLOBALS['TL_DCA']['tl_style_manager']['fields'][$strName]; + + if(isset($dcaField['eval']['multiple']) && !!$dcaField['eval']['multiple'] && $dcaField['inputType'] === 'checkbox') + { + $arrElements = StringUtil::deserialize($objChildren->{$strName}, true); + $arrValues = StringUtil::deserialize($strValue, true); + + foreach($arrValues as $element) + { + if(in_array($element, $arrElements)) + { + continue; + } + + $arrElements[] = $element; + } + + $strValue = serialize($arrElements); + } + } + + $objChildren->{$strName} = $strValue; + } + + // Save children data + if($blnSave) + { + $objChildren->save(); + } + else + { + $strKey = Sync::combineAliases($objArchive->identifier, $objChildren->alias); + $arrStyleGroups[ $strKey ] = $objChildren->current(); + } + } + } + } + + // Save archive data + if($blnSave) + { + $objArchive->save(); + } + else + { + $arrStyleArchives[ $objArchive->identifier ] = $objArchive->current(); + } + } + + // Unlock the tables + if($blnSave) + { + $database->unlockTables(); + Message::addConfirmation($translator->trans('MSC.styleManagerConfigImported', [basename($filePath)], 'contao_default')); + } + } + } + + if($blnSave) + { + return null; + } + + return [$arrStyleArchives, $arrStyleGroups, $files]; + } +} diff --git a/src/EventListener/DataContainer/StyleManagerArchiveListener.php b/src/EventListener/DataContainer/StyleManagerArchiveListener.php index a9942a1..3654776 100644 --- a/src/EventListener/DataContainer/StyleManagerArchiveListener.php +++ b/src/EventListener/DataContainer/StyleManagerArchiveListener.php @@ -2,12 +2,12 @@ namespace Oveleon\ContaoComponentStyleManager\EventListener\DataContainer; -use Contao\Backend; use Contao\CoreBundle\ServiceAnnotation\Callback; use Contao\Database; use Contao\DataContainer; use Contao\StringUtil; use Contao\System; +use Oveleon\ContaoComponentStyleManager\Controller\BackendModule\ImportController; use Oveleon\ContaoComponentStyleManager\Model\StyleManagerArchiveModel; use Oveleon\ContaoComponentStyleManager\StyleManager\Config; @@ -54,7 +54,7 @@ public function importConfigButton(string $href, string $label, string $title, s } return vsprintf('%s ', [ - Backend::addToUrl($href), + TL_SCRIPT. '/' . ImportController::ROUTE, $class, StringUtil::specialchars($title), $attributes, @@ -77,7 +77,7 @@ public function bundleConfigButton(string $href, string $label, string $title, s } return vsprintf('%s: %s', [ - Backend::addToUrl($href), + TL_SCRIPT. '/' . ImportController::ROUTE, $class, $attributes, $label, diff --git a/src/Resources/config/routes.yaml b/src/Resources/config/routes.yaml new file mode 100644 index 0000000..1fcbadf --- /dev/null +++ b/src/Resources/config/routes.yaml @@ -0,0 +1,3 @@ +bigger: + resource: '@ContaoComponentStyleManager/Controller' + type: annotation diff --git a/src/Resources/contao/config/config.php b/src/Resources/contao/config/config.php index 28b3d53..19853fd 100644 --- a/src/Resources/contao/config/config.php +++ b/src/Resources/contao/config/config.php @@ -10,8 +10,7 @@ 'design' => [ 'style_manager' => [ 'tables' => ['tl_style_manager_archive', 'tl_style_manager'], - 'export' => [Sync::class, 'exportStyleManager'], - 'import' => [Sync::class, 'importStyleManager'] + 'export' => [Sync::class, 'export'] ] ] ]); diff --git a/src/Resources/contao/dca/tl_style_manager_archive.php b/src/Resources/contao/dca/tl_style_manager_archive.php index 71e9ee5..92d2e40 100644 --- a/src/Resources/contao/dca/tl_style_manager_archive.php +++ b/src/Resources/contao/dca/tl_style_manager_archive.php @@ -33,7 +33,6 @@ ], 'global_operations' => [ 'import' => [ - 'href' => 'key=import', 'class' => 'header_style_manager_import', 'icon' => 'theme_import.svg' ], @@ -48,7 +47,6 @@ 'attributes' => 'onclick="Backend.getScrollOffset()" accesskey="e"' ], 'config' => [ - 'href' => 'key=import', 'class' => 'header_style_manager_config' ] ], @@ -123,6 +121,10 @@ 'inputType' => 'text', 'eval' => ['rgxp'=>'natural', 'nospace'=>true, 'maxlength'=>255, 'tl_class'=>'w50'], 'sql' => "int(10) NOT NULL default '0'" + ], + 'bundleConfig' => [ + 'reference' => &$GLOBALS['TL_LANG']['tl_style_manager_archive']['bundleConfig'], + 'eval' => array('helpwizard'=>true), ] ] ]; diff --git a/src/Resources/contao/languages/de/tl_style_manager_archive.xlf b/src/Resources/contao/languages/de/tl_style_manager_archive.xlf index 1b56386..f165be4 100644 --- a/src/Resources/contao/languages/de/tl_style_manager_archive.xlf +++ b/src/Resources/contao/languages/de/tl_style_manager_archive.xlf @@ -10,26 +10,7 @@ Config Konfiguration - - Bundle configurations - Bundle-Konfigurationen - - - Active configurations - Aktive Konfigurationen - - - No configurations available - Keine Konfigurationen vorhanden - - - Please note that the configurations displayed here are automatically available in all areas and do not have to be imported. With the import of these files, the bundle configurations are provided for the backend and overwrite from this moment on all properties that come from the bundle. If these are deleted again, the original from the bundle is used. - Bitte beachten Sie, dass die hier angezeigten Konfigurationen automatisch in allen Bereichen zur Verfügung stehen und nicht zwingend importiert werden müssen. Mit dem Import dieser Dateien werden die Bundle-Konfigurationen für das Backend bereitgestellt und überschreiben ab diesen Moment alle Eigenschaften, welche aus dem Bundle kommen. Sollten diese wieder gelöscht werden, wird das Original aus dem Bundle herangezogen. - - - The bundle configuration has been disabled for this project. To have configurations of other bundles imported, you have to activate them first. - Die Bundle-Konfiguration wurde für dieses Projekt ausgeschaltet. Um Konfigurationen anderer Bundles importieren zu lassen, müssen Sie diese vorerst aktivieren. - + Add category Neue Kategorie @@ -46,6 +27,14 @@ Import a config Konfiguration importieren + + Configurations + Konfigurationen + + + Import a config + Konfiguration importieren + Export Exportieren @@ -54,14 +43,6 @@ Export a config Konfiguration exportieren - - Manual import - Manueller Import - - - Here you can upload one .xml file to be imported. - Hier können Sie eine .xml-Datei für den Import hochladen. - Edit category Kategorie bearbeiten @@ -124,7 +105,7 @@ The identifier is used to receive the group classes if they is passed to the template. (e.g. $this->styleManager->get('myCategoryIdentifier') - Die Kennung dient zum entgegennehmen der Gruppenklassen, sofern diese an das Template übergeben werden. (Bspw. $this->styleManager->get('meineKategorieKennung') + Die Kennung dient zum Entgegennehmen der Gruppenklassen, sofern diese an das Template übergeben werden. (Bspw. $this->styleManager->get('meineKategorieKennung') Group-Identifier @@ -142,6 +123,43 @@ Enter a freely definable number here to define the sort index. This is used to determine the order of the categories in the backend. Geben Sie hier eine frei definierbare Zahl ein, um den Sortierindex zu definieren. Dieser dient dazu, die Reihenfolge der Kategorien im Backend zu bestimmen. + + + About the bundle configuration + Über die Bundle-Konfiguration + + + Bundle configurations are used to automatically consume and use StyleManager properties from other bundles. + Bundle-Konfigurationen dienen dazu, automatisiert StyleManager-Eigentschaften aus anderen Bundles zu konsumieren und verwenden zu können. + + + Overwrite configuration + Konfiguration überschreiben + + + If you import the configurations into the system using the Import button, properties with the same identifiers (category) and aliases (CSS group) will be added / overwritten. If you delete these properties later, the original configuration will be used again. + Sofern Sie die Bundle-Konfigurationen über den Import-Button in das System importieren, werden Eigenschaften mit denselben Kennungen (Kategorie) und Aliasse (CSS-Gruppe) ergänzt / überschrieben. Beim nachträglichen Löschen dieser Eigenschaften wird die Original-Konfiguration wieder verwendet. + + + Switch on / off + Ein- / Ausschalten + + + Automatic reading of bundle configurations can be switched off via config.yaml: + <br/><br/> +<pre> +contao_component_style_manager: + use_bundle_config: false +</pre> + + Das automatische Einlesen von Bundle-Konfigurationen kann über die config.yaml ausgeschaltet werden: + <br/><br/> +<pre> + contao_component_style_manager: + use_bundle_config: false +</pre> + + diff --git a/src/Resources/contao/languages/de/tl_style_manager_import.xlf b/src/Resources/contao/languages/de/tl_style_manager_import.xlf new file mode 100644 index 0000000..f5fbe74 --- /dev/null +++ b/src/Resources/contao/languages/de/tl_style_manager_import.xlf @@ -0,0 +1,44 @@ + + + + + + Bundle configurations + Bundle-Konfigurationen + + + No configurations available + Keine Konfigurationen vorhanden + + + The bundle configuration has been disabled for this project. To have configurations of other bundles imported, you have to activate them first. + Die Bundle-Konfiguration wurde für dieses Projekt ausgeschaltet. Um Konfigurationen anderer Bundles importieren zu lassen, müssen Sie diese vorerst aktivieren. + + + + Files + Dateien + + + Import + Importieren + + + Import parts + Teilimport + + + Allows you to select the records to import before importing. + Ermöglicht die Auswahl der zu importierenden Datensätze vor dem Import. + + + Manual import + Manueller Import + + + Here you can upload one .xml file to be imported. + Hier können Sie eine .xml-Datei für den Import hochladen. + + + + diff --git a/src/Resources/contao/languages/en/tl_style_manager_archive.xlf b/src/Resources/contao/languages/en/tl_style_manager_archive.xlf index 6e54bec..65dfc62 100644 --- a/src/Resources/contao/languages/en/tl_style_manager_archive.xlf +++ b/src/Resources/contao/languages/en/tl_style_manager_archive.xlf @@ -8,21 +8,7 @@ Config - - Bundle configurations - - - Active configurations - - - No configurations available - - - Please note that the configurations displayed here are automatically available in all areas and do not have to be imported. With the import of these files, the bundle configurations are provided for the backend and overwrite from this moment on all properties that come from the bundle. If these are deleted again, the original from the bundle is used. - - - The bundle configuration has been disabled for this project. To have configurations of other bundles imported, you have to activate them first. - + Add category @@ -35,18 +21,18 @@ Import a config + + Configurations + + + Import a config + Export Export a config - - Source files - - - Here you can upload one .xml file to be imported. - Edit category @@ -107,6 +93,31 @@ Enter a freely definable number here to define the sort index. This is used to determine the order of the categories in the backend. + + + About the bundle configuration + + + Bundle configurations are used to automatically consume and use StyleManager properties from other bundles. + + + Overwrite configuration + + + If you import the configurations into the system using the Import button, properties with the same identifiers (category) and aliases (CSS group) will be added / overwritten. If you delete these properties later, the original configuration will be used again. + + + Switch on / off + + + Automatic reading of bundle configurations can be switched off via config.yaml: + <br/><br/> + <pre> + contao_component_style_manager: + use_bundle_config: false + </pre> + + diff --git a/src/Resources/contao/languages/en/tl_style_manager_import.xlf b/src/Resources/contao/languages/en/tl_style_manager_import.xlf new file mode 100644 index 0000000..fcfd458 --- /dev/null +++ b/src/Resources/contao/languages/en/tl_style_manager_import.xlf @@ -0,0 +1,35 @@ + + + + + + Bundle configurations + + + No configurations available + + + The bundle configuration has been disabled for this project. To have configurations of other bundles imported, you have to activate them first. + + + + Files + + + Import + + + Import parts + + + Allows you to select the records to import before importing. + + + Manual import + + + Here you can upload one .xml file to be imported. + + + + diff --git a/src/Resources/contao/languages/fr/tl_style_manager_archive.xlf b/src/Resources/contao/languages/fr/tl_style_manager_archive.xlf index 13ec43b..cdef33f 100644 --- a/src/Resources/contao/languages/fr/tl_style_manager_archive.xlf +++ b/src/Resources/contao/languages/fr/tl_style_manager_archive.xlf @@ -10,26 +10,7 @@ Config Configuration - - Bundle configurations - Configuration des paquets - - - Active configurations - Configurations actives - - - No configurations available - Aucune configuration disponible - - - Please note that the configurations displayed here are automatically available in all areas and do not have to be imported. With the import of these files, the bundle configurations are provided for the backend and overwrite from this moment on all properties that come from the bundle. If these are deleted again, the original from the bundle is used. - Veuillez noter que les configurations affichées ici sont automatiquement disponibles dans tous les domaines et ne doivent pas obligatoirement être importées. Avec l'importation de ces fichiers, les configurations du bundle sont mises à disposition pour le backend et remplacent dès ce moment toutes les propriétés provenant du bundle. Si celles-ci devaient être supprimées, l'original du bundle serait utilisé. - - - The bundle configuration has been disabled for this project. To have configurations of other bundles imported, you have to activate them first. - La configuration des bundles a été désactivée pour ce projet. Pour pouvoir importer les configurations d'autres bundles, vous devez d'abord les activer. - + Add category Ajouter une catégorie @@ -46,6 +27,14 @@ Import a config Importer une configuration + + Configurations + Configurations + + + Import a config + Importer la configuration + Export Exporter @@ -54,14 +43,6 @@ Export a config Exporter une configuration - - Source files - Fichiers source - - - Here you can upload one .xml file to be imported. - Vous pouvez uploader un fichier .xml à importer. - Edit category Éditer la catégorie @@ -142,6 +123,43 @@ Enter a freely definable number here to define the sort index. This is used to determine the order of the categories in the backend. Indiquez un nombre libre pour définir l'ordre de tri. Il est utilisé pour déterminer l'ordre des catégories dans le back-office. + + + About the bundle configuration + À propos de la configuration du bundle + + + Bundle configurations are used to automatically consume and use StyleManager properties from other bundles. + Les configurations de bundle servent à consommer et à pouvoir utiliser de manière automatisée les propriétés StyleManager d'autres bundles. + + + Overwrite configuration + Remplacer la configuration + + + If you import the configurations into the system using the Import button, properties with the same identifiers (category) and aliases (CSS group) will be added / overwritten. If you delete these properties later, the original configuration will be used again. + Dans la mesure où vous importez les configurations de bundle dans le système via le bouton d'importation, les propriétés sont complétées / écrasées par les mêmes identifiants (catégorie) et alias (groupe CSS). En cas de suppression ultérieure de ces propriétés, la configuration d'origine sera à nouveau utilisée. + + + Switch on / off + Mise en marche / arrêt + + + Automatic reading of bundle configurations can be switched off via config.yaml: + <br/><br/> +<pre> +contao_component_style_manager: + use_bundle_config: false +</pre> + + La lecture automatique des configurations de bundle peut être désactivée via le fichier config.yaml: + <br/><br/> +<pre> +contao_component_style_manager: + use_bundle_config: false +</pre> + + diff --git a/src/Resources/contao/languages/fr/tl_style_manager_import.xlf b/src/Resources/contao/languages/fr/tl_style_manager_import.xlf new file mode 100644 index 0000000..a59700e --- /dev/null +++ b/src/Resources/contao/languages/fr/tl_style_manager_import.xlf @@ -0,0 +1,44 @@ + + + + + + Bundle configurations + Configurations de bundle + + + No configurations available + Aucune configuration disponible + + + The bundle configuration has been disabled for this project. To have configurations of other bundles imported, you have to activate them first. + La configuration des bundles a été désactivée pour ce projet. Pour pouvoir importer les configurations d'autres bundles, vous devez d'abord les activer. + + + + Files + Fichiers + + + Import + Importer + + + Import parts + Importation de pièces + + + Allows you to select the records to import before importing. + Permet de sélectionner les enregistrements à importer avant l'importation. + + + Manual import + Importation manuelle + + + Here you can upload one .xml file to be imported. + Ici, vous pouvez télécharger un fichier .xml pour l'importation. + + + + diff --git a/src/Resources/contao/templates/backend/be_style_manager_import.html5 b/src/Resources/contao/templates/backend/be_style_manager_import.html5 deleted file mode 100644 index 430318b..0000000 --- a/src/Resources/contao/templates/backend/be_style_manager_import.html5 +++ /dev/null @@ -1,53 +0,0 @@ - - - - - -
-
- - - - -
-
-

labelSource ?>

-
fieldUpload ?>
-

descSource ?>

- -
-
-
- -
- - -
-
-

labelBundleConfig ?>

- useBundleConfig): ?> - bundleFiles)): ?> -

descBundleFiles?>

- - - bundleFiles as $fileName => $filePath): $strId = Contao\StringUtil::prepareSlug($fileName); ?> - - - - - -
- - - -

emptyBundleFiles?>

- - -

activeDescBundleFiles?>

- -
-
-
-
diff --git a/src/Resources/views/import.html.twig b/src/Resources/views/import.html.twig new file mode 100644 index 0000000..eb4e146 --- /dev/null +++ b/src/Resources/views/import.html.twig @@ -0,0 +1,126 @@ +{% extends "@ContaoCore/Backend/be_page.html.twig" %} + +{% block headline %} + {{ headline }} +{% endblock %} + +{% block error %}{% endblock %} + +{% block main %} + {% if messages %} + {{ messages|raw }} + {% endif %} + + + +
+ {% if partial %} +
+ + + +
+
+
+

{{ label.files }}

+ {% for fileName in configs.files %} +
+ + 📄 {{ fileName }} +
+ {% endfor %} +
+

Wählen Sie hier die Datensätze aus, welche importiert werden sollen.

+
+ {% for archiveAlias, archive in configs.collection %} +
+ + +
+ {% for groupAlias, child in archive.children %} +
+ + +
+ {% endfor %} +
+
+ {% endfor %} +
+ +
+ +
+
+
+
+ {% else %} +
+ + + + +
+
+

{{ label.importManual }}

+
{{ form.uploadWidget|raw }}
+

{{ label.widgetDescription }}

+
+ + + + + + +

{{ label.importPartialDesc }}

+
+
+
+
+
+
+ + +
+
+

+ {{ label.bundleUpload }} + + + +

+ {% if useBundleConfig %} + {% if bundleFiles|length > 0 %} + + {% for fileName, filePath in bundleFiles %} + + + + + {% endfor %} +
+ +
+ + + + + + +

{{ label.importPartialDesc }}

+
+
+ {% else %} +

{{ label.bundleConfigEmpty }}

+ {% endif %} + {% else %} +

{{ label.bundleConfigInactive }}

+ {% endif %} +
+
+
+ {% endif %} +
+{% endblock %} diff --git a/src/StyleManager/Config.php b/src/StyleManager/Config.php index 85b888e..384f842 100644 --- a/src/StyleManager/Config.php +++ b/src/StyleManager/Config.php @@ -9,6 +9,7 @@ namespace Oveleon\ContaoComponentStyleManager\StyleManager; use Contao\System; +use Oveleon\ContaoComponentStyleManager\Controller\BackendModule\ImportController; /** * A static class to store config data @@ -120,8 +121,7 @@ protected function loadBundleConfiguration(): ?array { if($arrFiles = $this->getBundleConfigurationFiles()) { - $sync = new Sync(); - return $sync->importStyleManagerFile($arrFiles, false); + return ImportController::importFiles($arrFiles, false); } return null; diff --git a/src/StyleManager/Sync.php b/src/StyleManager/Sync.php index fb692e0..bc0a30f 100644 --- a/src/StyleManager/Sync.php +++ b/src/StyleManager/Sync.php @@ -8,36 +8,23 @@ namespace Oveleon\ContaoComponentStyleManager\StyleManager; use Contao\Backend; -use Contao\BackendTemplate; -use Contao\Config; use Contao\Controller; use Contao\DataContainer; -use Contao\Environment; use Contao\File; -use Contao\FileUpload; -use Contao\Input; use Contao\Message; use Contao\Model\Collection; use Contao\StringUtil; -use Contao\System; +use DOMDocument; +use DOMElement; +use DOMNode; use Oveleon\ContaoComponentStyleManager\Model\StyleManagerArchiveModel; use Oveleon\ContaoComponentStyleManager\Model\StyleManagerModel; -use Oveleon\ContaoComponentStyleManager\StyleManager\Config as BundleConfig; class Sync extends Backend { - /** - * @var string - */ - protected $strRootDir; - - /** - * Set the root directory - */ public function __construct() { parent::__construct(); - $this->strRootDir = System::getContainer()->getParameter('kernel.project_dir'); } /** @@ -137,360 +124,6 @@ public function performObjectConversion($table = null): void } } - /** - * Display import form in back end - * - * @return string - * - * @throws \Exception - */ - public function importStyleManager() - { - Config::set('uploadTypes', Config::get('uploadTypes') . ',xml'); - - /** @var FileUpload $objUploader */ - $objUploader = new FileUpload(); - - if (Input::post('FORM_SUBMIT') == 'tl_style_manager_import') - { - if (!Input::post('confirm')) - { - $arrUploaded = $objUploader->uploadTo('system/tmp'); - - if (empty($arrUploaded)) - { - Message::addError($GLOBALS['TL_LANG']['ERR']['all_fields']); - $this->reload(); - } - - $arrFiles = array(); - - foreach ($arrUploaded as $strFile) - { - // Skip folders - if (is_dir($this->strRootDir . '/' . $strFile)) - { - Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['importFolder'], basename($strFile))); - continue; - } - - $objFile = new File($strFile); - - // Skip anything but .xml files - if ($objFile->extension != 'xml') - { - Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['filetype'], $objFile->extension)); - continue; - } - - $arrFiles[] = $strFile; - } - } - - // Check whether there are any files - if (empty($arrFiles)) - { - Message::addError($GLOBALS['TL_LANG']['ERR']['all_fields']); - $this->reload(); - } - - $this->importStyleManagerFile($arrFiles); - } - - if (Input::post('FORM_SUBMIT') == 'tl_style_manager_import_bundle') - { - if($bundleFiles = Input::post('bundleFiles')) - { - $this->importStyleManagerFile(array_map(fn($n) => html_entity_decode($n), $bundleFiles)); - } - } - - $template = new BackendTemplate('be_style_manager_import'); - - $template->backUrl = StringUtil::ampersand(str_replace('&key=import', '', Environment::get('request'))); - $template->backBT = $GLOBALS['TL_LANG']['MSC']['backBT']; - $template->backBTTitle = $GLOBALS['TL_LANG']['MSC']['backBTTitle']; - - $template->formId = 'tl_style_manager_import'; - $template->fileMaxSize = Config::get('maxFileSize'); - - $template->labelSource = $GLOBALS['TL_LANG']['tl_style_manager_archive']['source'][0]; - $template->descSource = $GLOBALS['TL_LANG']['tl_style_manager_archive']['source'][1]; - $template->fieldUpload = $objUploader->generateMarkup(); - - $template->useBundleConfig = System::getContainer()->getParameter('contao_component_style_manager.use_bundle_config'); - $template->labelImport = $GLOBALS['TL_LANG']['tl_style_manager_archive']['import'][0]; - $template->labelBundleConfig = $GLOBALS['TL_LANG']['tl_style_manager_archive']['headingBundleConfig']; - $template->emptyBundleFiles = $GLOBALS['TL_LANG']['tl_style_manager_archive']['emptyBundleConfig']; - $template->descBundleFiles = $GLOBALS['TL_LANG']['tl_style_manager_archive']['descBundleConfig']; - $template->activeDescBundleFiles = $GLOBALS['TL_LANG']['tl_style_manager_archive']['activateBundleConfig']; - - $template->bundleFiles = BundleConfig::getBundleConfigurationFiles() ?? []; - - return $template->parse(); - } - - /** - * Import StyleManager data from file - * - * @param array $arrFiles - * @param bool $blnSave - * - * @throws \Exception - */ - public function importStyleManagerFile(array $arrFiles, bool $blnSave = true): ?array - { - $arrStyleArchives = []; - $arrStyleGroups = []; - - // Get the next id - $intArchiveId = $this->Database->getNextId('tl_style_manager_archive'); - $intGroupId = $this->Database->getNextId('tl_style_manager'); - - foreach ($arrFiles as $strFilePath) - { - // Open file - $objFile = new File($strFilePath); - - // Check if file exists - if ($objFile->exists()) - { - // Load xml file - $xml = new \DOMDocument(); - $xml->preserveWhiteSpace = false; - $xml->loadXML($objFile->getContent()); - - // Continue if there is no XML file - if (!$xml instanceof \DOMDocument) - { - Message::addError(sprintf($GLOBALS['TL_LANG']['tl_theme']['missing_xml'], basename($strFilePath))); - continue; - } - - // Get archives node - $archives = $xml->getElementsByTagName('archives'); - - if($archives->count()){ - // Skip archives node - $archives = $archives->item(0)->childNodes; - }else return null; - - // Lock the tables - $arrLocks = array - ( - 'tl_style_manager_archive' => 'WRITE', - 'tl_style_manager' => 'WRITE' - ); - - // Load the DCAs of the locked tables - foreach (array_keys($arrLocks) as $table) - { - $this->loadDataContainer($table); - } - - if($blnSave) - { - $this->Database->lockTables($arrLocks); - } - - // Check if archive exists - $archiveExists = function (string $identifier) use ($blnSave, $arrStyleArchives) : bool - { - if(!$blnSave) - { - return array_key_exists($identifier, $arrStyleArchives); - } - - return $this->Database->prepare("SELECT identifier FROM tl_style_manager_archive WHERE identifier=?")->execute($identifier)->numRows > 0; - }; - - // Check if children exists - $childrenExists = function (string $alias, string $pid) use($blnSave, $arrStyleGroups) : bool - { - if(!$blnSave) - { - return array_key_exists($alias, $arrStyleGroups); - } - - return $this->Database->prepare("SELECT alias FROM tl_style_manager WHERE alias=? AND pid=?")->execute($alias, $pid)->numRows > 0; - }; - - // Loop through the archives - for ($i=0; $i<$archives->length; $i++) - { - $archive = $archives->item($i)->childNodes; - $identifier = $archives->item($i)->getAttribute('identifier'); - - if(!$blnSave || !$archiveExists($identifier)) - { - if(!$blnSave && $archiveExists($identifier)) - { - $objArchive = $arrStyleArchives[$identifier]; - } - else - { - $objArchive = new StyleManagerArchiveModel(); - $objArchive->id = ++$intArchiveId; - } - } - else - { - $objArchive = StyleManagerArchiveModel::findByIdentifier($identifier); - } - - // Loop through the archives fields - for ($a=0; $a<$archive->length; $a++) - { - $strField = $archive->item($a)->nodeName; - - if($strField === 'field') - { - $strName = $archive->item($a)->getAttribute('title'); - $strValue = $archive->item($a)->nodeValue; - - if($strName === 'id' || strtolower($strValue) === 'null') - { - continue; - } - - $objArchive->{$strName} = $strValue; - } - elseif($strField === 'children') - { - $children = $archive->item($a)->childNodes; - - // Loop through the archives fields - for ($c=0; $c<$children->length; $c++) - { - $alias = $children->item($c)->getAttribute('alias'); - $fields = $children->item($c)->childNodes; - - $strChildAlias = self::combineAliases($objArchive->identifier, $alias); - - if(!$blnSave || !$childrenExists($strChildAlias, $objArchive->id)) - { - if(!$blnSave && $childrenExists($strChildAlias, $objArchive->id)) - { - $objChildren = $arrStyleGroups[$strChildAlias]; - } - else - { - $objChildren = new StyleManagerModel(); - $objChildren->id = ++$intGroupId; - } - } - else - { - $objChildren = StyleManagerModel::findByAliasAndPid($alias, $objArchive->id); - } - - // Loop through the children fields - for ($f=0; $f<$fields->length; $f++) - { - $strName = $fields->item($f)->getAttribute('title'); - $strValue = $fields->item($f)->nodeValue; - - if($strName === 'id' || !$strValue || strtolower($strValue) === 'null') - { - continue; - } - - switch($strName) - { - case 'pid': - $strValue = $objArchive->id; - break; - case 'cssClasses': - if($objChildren->{$strName}) - { - $arrClasses = StringUtil::deserialize($objChildren->{$strName}, true); - $arrExists = self::flattenKeyValueArray($arrClasses); - $arrValues = StringUtil::deserialize($strValue, true); - - foreach($arrValues as $cssClass) - { - if(array_key_exists($cssClass['key'], $arrExists)) - { - continue; - } - - $arrClasses[] = array( - 'key' => $cssClass['key'], - 'value' => $cssClass['value'] - ); - } - - $strValue = serialize($arrClasses); - } - - break; - default: - $dcaField = $GLOBALS['TL_DCA']['tl_style_manager']['fields'][$strName]; - - if(isset($dcaField['eval']['multiple']) && !!$dcaField['eval']['multiple'] && $dcaField['inputType'] === 'checkbox') - { - $arrElements = StringUtil::deserialize($objChildren->{$strName}, true); - $arrValues = StringUtil::deserialize($strValue, true); - - foreach($arrValues as $element) - { - if(in_array($element, $arrElements)) - { - continue; - } - - $arrElements[] = $element; - } - - $strValue = serialize($arrElements); - } - } - - $objChildren->{$strName} = $strValue; - } - - // Save children data - if($blnSave) - { - $objChildren->save(); - } - else - { - $strKey = self::combineAliases($objArchive->identifier, $objChildren->alias); - $arrStyleGroups[ $strKey ] = $objChildren->current(); - } - } - } - } - - // Save archive data - if($blnSave) - { - $objArchive->save(); - } - else - { - $arrStyleArchives[ $objArchive->identifier ] = $objArchive->current(); - } - } - - // Unlock the tables - if($blnSave) - { - $this->Database->unlockTables(); - Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['MSC']['styleManagerConfigImported'], basename($strFilePath))); - } - } - } - - if($blnSave) - { - return null; - } - - return [$arrStyleArchives, $arrStyleGroups]; - } - /** * Merge group objects */ @@ -592,14 +225,12 @@ public static function mergeGroupObjects(?StyleManagerModel $objOriginal, ?Style } /** - * Export StyleManager data - * - * @throws \Exception + * Export StyleManager records */ - public function exportStyleManager(?DataContainer $dc, $objArchives = null, bool $blnSendToBrowser = true) + public function export(?DataContainer $dc, $objArchives = null, bool $blnSendToBrowser = true) { // Create a new XML document - $xml = new \DOMDocument('1.0', 'UTF-8'); + $xml = new DOMDocument('1.0', 'UTF-8'); $xml->formatOutput = true; // Archives @@ -642,12 +273,8 @@ public function exportStyleManager(?DataContainer $dc, $objArchives = null, bool /** * Add an archive data row to the XML document - * - * @param \DOMDocument $xml - * @param \DOMNode $archives - * @param Collection $objArchive */ - protected function addArchiveData(\DOMDocument $xml, \DOMNode $archives, Collection $objArchive) + protected function addArchiveData(DOMDocument $xml, DOMNode $archives, Collection $objArchive): void { $this->loadDataContainer('tl_style_manager_archive'); @@ -665,12 +292,8 @@ protected function addArchiveData(\DOMDocument $xml, \DOMNode $archives, Collect /** * Add a children data row to the XML document - * - * @param \DOMDocument $xml - * @param \DOMNode|\DOMElement $archive - * @param int $pid */ - protected function addChildrenData(\DOMDocument $xml, \DOMElement $archive, int $pid) + protected function addChildrenData(DOMDocument $xml, DOMElement $archive, int $pid): void { // Add children node $children = $xml->createElement('children'); @@ -698,14 +321,10 @@ protected function addChildrenData(\DOMDocument $xml, \DOMElement $archive, int /** * Add field data to the XML document - * - * @param \DOMDocument $xml - * @param \DOMNode $row - * @param array $arrData */ - protected function addRowData(\DOMDocument $xml, \DOMNode $row, array $arrData) + protected function addRowData(DOMDocument $xml, DOMNode $row, array $arrData): void { - foreach ($arrData as $k=>$v) + foreach ($arrData as $k => $v) { $field = $xml->createElement('field'); $field->setAttribute('title', $k); @@ -723,12 +342,8 @@ protected function addRowData(\DOMDocument $xml, \DOMNode $row, array $arrData) /** * Flatten Key Value Array - * - * @param $arr - * - * @return array */ - public static function flattenKeyValueArray($arr) + public static function flattenKeyValueArray($arr): array { if(empty($arr)) { From 21298daff8c53825cd0556be34aeee05376ee5bb Mon Sep 17 00:00:00 2001 From: doishub Date: Tue, 11 Oct 2022 13:04:21 +0200 Subject: [PATCH 28/48] Update docs --- README.md | 15 +++------------ docs/MIGRATE.md | 10 ++++++++++ 2 files changed, 13 insertions(+), 12 deletions(-) create mode 100644 docs/MIGRATE.md diff --git a/README.md b/README.md index ccd9b3a..6d89782 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,8 @@ This plugin is designed to simplify theme customizations without the need of man - Passing variables to the template - Formatting output using predefined methods or your own - Import / Export - - Automatic import of configurations from third-party bundles [![new](https://img.shields.io/badge/-new-brightgreen?style=flat-square)](#contao-component-style-manager) + - Automatic import of configurations from third-party bundles (Bundle configurations) [![new](https://img.shields.io/badge/-new-brightgreen?style=flat-square)](#contao-component-style-manager) + - Partial import [![new](https://img.shields.io/badge/-new-brightgreen?style=flat-square)](#contao-component-style-manager) - Available for - Layouts - Pages @@ -55,14 +56,4 @@ composer require oveleon/contao-component-style-manager - [Extend and support other extensions](docs/SUPPORT.md) - [Import / Export](docs/IMPORT_EXPORT.md) - [Bundle-Configurations](docs/BUNDLE_CONFIG.md) - -## Migration - -#### Migrate from version 2 to 3 -Bundle configurations were added with version 3. This makes it necessary to migrate the StyleManager dataset. If only standard Contao tables were used and the StyleManager was not added to other / own database tables, calling the install tool is sufficient. - -If the StyleManager was used for other / own database tables, these tables must be migrated manually using the following command: - -```shell -$ php contao-console contao:stylemanager:object-conversion tl_mytable -``` +- [Migration](docs/MIGRATE.md) diff --git a/docs/MIGRATE.md b/docs/MIGRATE.md new file mode 100644 index 0000000..6aacbb9 --- /dev/null +++ b/docs/MIGRATE.md @@ -0,0 +1,10 @@ +## Migration + +#### Migrate from version 2 to 3 +Bundle configurations were added with version 3. This makes it necessary to migrate the StyleManager dataset. If only standard Contao tables were used and the StyleManager was not added to other / own database tables, calling the install tool is sufficient. + +If the StyleManager was used for other / own database tables, these tables must be migrated manually using the following command: + +```shell +$ php contao-console contao:stylemanager:object-conversion tl_mytable +``` From 06edc2463a66828ed92c6ff23212eb94090908b9 Mon Sep 17 00:00:00 2001 From: doishub Date: Wed, 12 Oct 2022 15:16:31 +0200 Subject: [PATCH 29/48] Fix migration --- src/Command/ObjectConversionCommand.php | 2 +- src/EventListener/LoadFormFieldListener.php | 3 ++- src/EventListener/ParseTemplateListener.php | 3 ++- .../Version30/ObjectConversionMigration.php | 4 ++-- src/StyleManager/StyleManager.php | 16 ++++++++------- src/StyleManager/Sync.php | 20 ++++++++++++++++--- 6 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/Command/ObjectConversionCommand.php b/src/Command/ObjectConversionCommand.php index b4e423d..f8c2745 100644 --- a/src/Command/ObjectConversionCommand.php +++ b/src/Command/ObjectConversionCommand.php @@ -11,7 +11,7 @@ namespace Oveleon\ContaoComponentStyleManager\Command; use Contao\CoreBundle\Framework\ContaoFramework; -use Oveleon\ContaoComponentStyleManager\Sync; +use Oveleon\ContaoComponentStyleManager\StyleManager\Sync; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Input\InputArgument; diff --git a/src/EventListener/LoadFormFieldListener.php b/src/EventListener/LoadFormFieldListener.php index c61f191..63006ab 100644 --- a/src/EventListener/LoadFormFieldListener.php +++ b/src/EventListener/LoadFormFieldListener.php @@ -10,6 +10,7 @@ use Contao\CoreBundle\ServiceAnnotation\Hook; use Contao\StringUtil; use Contao\Widget; +use Oveleon\ContaoComponentStyleManager\StyleManager\StyleManager; use Oveleon\ContaoComponentStyleManager\StyleManager\Styles; /** @@ -25,7 +26,7 @@ public function __invoke(Widget $objWidget) if(!($objWidget->styleManager instanceof Styles)) { $arrStyles = StringUtil::deserialize($objWidget->styleManager); - $objWidget->styleManager = new Styles(isset($arrStyles['__vars__']) ? $arrStyles['__vars__'] : null); + $objWidget->styleManager = new Styles($arrStyles[StyleManager::VARS_KEY] ?? null); } return $objWidget; diff --git a/src/EventListener/ParseTemplateListener.php b/src/EventListener/ParseTemplateListener.php index 8ce9709..a6f95cd 100644 --- a/src/EventListener/ParseTemplateListener.php +++ b/src/EventListener/ParseTemplateListener.php @@ -10,6 +10,7 @@ use Contao\CoreBundle\ServiceAnnotation\Hook; use Contao\StringUtil; use Contao\Template; +use Oveleon\ContaoComponentStyleManager\StyleManager\StyleManager; use Oveleon\ContaoComponentStyleManager\StyleManager\Styles; /** @@ -39,7 +40,7 @@ public function __invoke(Template $template) if(!($template->styleManager instanceof Styles)) { $arrStyles = StringUtil::deserialize($template->styleManager); - $template->styleManager = new Styles(isset($arrStyles['__vars__']) ? $arrStyles['__vars__'] : null); + $template->styleManager = new Styles($arrStyles[StyleManager::VARS_KEY] ?? null); } } } diff --git a/src/Migration/Version30/ObjectConversionMigration.php b/src/Migration/Version30/ObjectConversionMigration.php index 97aa1a8..337fdbf 100644 --- a/src/Migration/Version30/ObjectConversionMigration.php +++ b/src/Migration/Version30/ObjectConversionMigration.php @@ -6,7 +6,7 @@ use Contao\CoreBundle\Migration\AbstractMigration; use Contao\CoreBundle\Migration\MigrationResult; use Doctrine\DBAL\Connection; -use Oveleon\ContaoComponentStyleManager\Sync; +use Oveleon\ContaoComponentStyleManager\StyleManager\Sync; class ObjectConversionMigration extends AbstractMigration { @@ -37,7 +37,7 @@ public function __construct(Connection $connection, ContaoFramework $framework) public function shouldRun(): bool { - $schemaManager = $this->connection->getSchemaManager(); + $schemaManager = $this->connection->createSchemaManager(); // If the database table itself does not exist we should do nothing if (!$schemaManager->tablesExist(['tl_style_manager'])) diff --git a/src/StyleManager/StyleManager.php b/src/StyleManager/StyleManager.php index ac10923..e7a04ab 100644 --- a/src/StyleManager/StyleManager.php +++ b/src/StyleManager/StyleManager.php @@ -16,6 +16,8 @@ class StyleManager { + const VARS_KEY = '__vars__'; + /** * Valid CSS-Class fields [field => size] */ @@ -134,9 +136,9 @@ public static function updateClasses($varValue, $dc) $varValues = StringUtil::deserialize($dc->activeRecord->styleManager, true); // remove vars node - if(isset($varValues['__vars__'])) + if(isset($varValues[StyleManager::VARS_KEY])) { - unset($varValues['__vars__']); + unset($varValues[StyleManager::VARS_KEY]); } // append classes @@ -337,7 +339,7 @@ public static function serializeValues($varValue, $strTable) { $identifier = $arrArchives[ $objStyleGroup->pid ]; - $arrValue['__vars__'][ $identifier ][ $objStyleGroup->alias ] = array( + $arrValue[ StyleManager::VARS_KEY ][ $identifier ][ $objStyleGroup->alias ] = array( 'id' => $objStyleGroup->id, 'value' => $arrValue[ $strId ] ); @@ -359,9 +361,9 @@ public static function serializeValues($varValue, $strTable) */ public static function deserializeValues($arrValue) { - if(isset($arrValue['__vars__'])) + if(isset($arrValue[ StyleManager::VARS_KEY ])) { - foreach ($arrValue['__vars__'] as $archiveAlias => $values) + foreach ($arrValue[ StyleManager::VARS_KEY ] as $archiveAlias => $values) { foreach ($values as $alias => $arrItem) { @@ -370,7 +372,7 @@ public static function deserializeValues($arrValue) } } - unset($arrValue['__vars__']); + unset($arrValue[ StyleManager::VARS_KEY ]); } return $arrValue; @@ -423,7 +425,7 @@ public static function isVisibleGroup(StyleManagerModel $objGroup, string $strTa public function listFormFields($arrRow) { $arrStyles = StringUtil::deserialize($arrRow['styleManager']); - $arrRow['styleManager'] = new Styles(isset($arrStyles['__vars__']) ? $arrStyles['__vars__'] : null); + $arrRow['styleManager'] = new Styles($arrStyles[StyleManager::VARS_KEY] ?? null); $formField = new \tl_form_field(); return $formField->listFormFields($arrRow); diff --git a/src/StyleManager/Sync.php b/src/StyleManager/Sync.php index bc0a30f..8bc5a5f 100644 --- a/src/StyleManager/Sync.php +++ b/src/StyleManager/Sync.php @@ -43,7 +43,14 @@ public function shouldRunObjectConversion($table = null): bool if($objConfig && $arrConfig = StringUtil::deserialize($objConfig->styleManager)) { - return is_numeric(array_key_first($arrConfig)); + $key = array_key_first($arrConfig); + + if($key === StyleManager::VARS_KEY && count($arrConfig) > 1) + { + $key = array_keys($arrConfig)[1]; + } + + return is_numeric($key); } return false; @@ -101,14 +108,21 @@ public function performObjectConversion($table = null): void { $config = StringUtil::deserialize($arrRow['styleManager']); + $key = array_key_first($config); + + if($key === StyleManager::VARS_KEY && count($config) > 1) + { + $key = array_keys($config)[1]; + } + // Skip is config already converted - if(!is_numeric(array_key_first($config))) + if(!is_numeric($key)) { continue; } $arrAliasPairKeys = array_map(function($intGroupKey) use ($arrArchives, $arrGroups) { - return StyleManager::generateAlias($arrArchives[ $arrGroups[$intGroupKey]->pid ], $arrGroups[$intGroupKey]->alias); + return $intGroupKey === StyleManager::VARS_KEY ? StyleManager::VARS_KEY : StyleManager::generateAlias($arrArchives[ $arrGroups[$intGroupKey]->pid ], $arrGroups[$intGroupKey]->alias); }, array_keys($config)); $newConfig = array_combine($arrAliasPairKeys, $config); From 05c12f54650ee29880387ac69306d9588f9702b5 Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 13 Oct 2022 08:24:07 +0200 Subject: [PATCH 30/48] Code clean up --- src/Command/ObjectConversionCommand.php | 11 +--- .../BackendModule/ImportController.php | 2 +- src/StyleManager/Config.php | 9 ++-- src/StyleManager/Styles.php | 50 ++++--------------- 4 files changed, 15 insertions(+), 57 deletions(-) diff --git a/src/Command/ObjectConversionCommand.php b/src/Command/ObjectConversionCommand.php index f8c2745..105b8a6 100644 --- a/src/Command/ObjectConversionCommand.php +++ b/src/Command/ObjectConversionCommand.php @@ -29,15 +29,8 @@ class ObjectConversionCommand extends Command { protected static $defaultName = 'contao:stylemanager:object-conversion'; - /** - * @var ContaoFramework - */ - protected $framework; - - /** - * @var Sync - */ - private $sync; + protected ContaoFramework $framework; + private Sync $sync; public function __construct(ContaoFramework $contaoFramework) { diff --git a/src/Controller/BackendModule/ImportController.php b/src/Controller/BackendModule/ImportController.php index 1979211..1e3fbf3 100644 --- a/src/Controller/BackendModule/ImportController.php +++ b/src/Controller/BackendModule/ImportController.php @@ -120,7 +120,7 @@ public function __invoke(): Response /** * Create a tree from archives and groups */ - public function createImportTree($archives, $groups, $files) + public function createImportTree($archives, $groups, $files): array { $collection = [ 'files' => $files, diff --git a/src/StyleManager/Config.php b/src/StyleManager/Config.php index 384f842..1c361e7 100644 --- a/src/StyleManager/Config.php +++ b/src/StyleManager/Config.php @@ -20,21 +20,18 @@ class Config { /** * Object instance (Singleton) - * @var Config */ - protected static $objInstance; + protected static Config $objInstance; /** * Group data - * @var array */ - protected static $arrGroups = []; + protected static array $arrGroups = []; /** * Archive data - * @var array */ - protected static $arrArchive = []; + protected static array $arrArchive = []; /** * Return all archives as array diff --git a/src/StyleManager/Styles.php b/src/StyleManager/Styles.php index a120f1f..0421eca 100644 --- a/src/StyleManager/Styles.php +++ b/src/StyleManager/Styles.php @@ -13,41 +13,31 @@ class Styles { /** * Style Collection - * @var array|null */ - private $styles = null; + private ?array $styles; /** * Current identifier - * @var string */ - private $currIdentifier = ''; + private string $currIdentifier = ''; /** * Current groups - * @var array|null */ - private $currGroups = null; + private ?array $currGroups = null; /** * Initialize the object - * - * @param array $arrStyles */ - public function __construct($arrStyles=null) + public function __construct(?array $arrStyles = null) { $this->styles = $arrStyles; } /** * Return the css class collection of an identifier - * - * @param $identifier - * @param null $arrGroups - * - * @return string */ - public function get($identifier, $arrGroups=null) + public function get($identifier, $arrGroups=null): string { if($this->styles === null || !is_array(($this->styles[ $identifier ] ?? null))) { @@ -81,13 +71,8 @@ public function get($identifier, $arrGroups=null) /** * Prepare css classes - * - * @param $identifier - * @param null $arrGroups - * - * @return Styles */ - public function prepare($identifier, $arrGroups=null) + public function prepare($identifier, $arrGroups=null): Styles { $this->currIdentifier = $identifier; $this->currGroups = $arrGroups; @@ -97,13 +82,8 @@ public function prepare($identifier, $arrGroups=null) /** * Return formatted css classes - * - * @param $format - * @param string $method - * - * @return string */ - public function format($format, $method='') + public function format(string $format, string $method=''): string { if(!$format || $this->styles === null || !is_array(($this->styles[ $this->currIdentifier ] ?? null))) { @@ -166,14 +146,10 @@ public function format($format, $method='') /** * Return all values of a category - * - * @param $arrVariables - * - * @return array */ - private function getCategoryValues($arrVariables) + private function getCategoryValues($arrVariables): array { - $arrValues = array(); + $arrValues = []; foreach ($arrVariables as $alias => $arrVariable) { @@ -185,10 +161,6 @@ private function getCategoryValues($arrVariables) /** * Return the value of a group - * - * @param $arrVariable - * - * @return mixed */ private function getGroupValue($arrVariable) { @@ -197,10 +169,6 @@ private function getGroupValue($arrVariable) /** * Return the value as correct type - * - * @param $strValue - * - * @return mixed */ private function parseValueType($strValue) { From 975a7ddb1354d9dfd5bf5a0ae24793eac1308aa9 Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 13 Oct 2022 08:30:05 +0200 Subject: [PATCH 31/48] Fix Config accessed before initialization --- src/StyleManager/Config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StyleManager/Config.php b/src/StyleManager/Config.php index 1c361e7..c98951c 100644 --- a/src/StyleManager/Config.php +++ b/src/StyleManager/Config.php @@ -21,7 +21,7 @@ class Config /** * Object instance (Singleton) */ - protected static Config $objInstance; + protected static ?Config $objInstance = null; /** * Group data From 086c640c26c2baea45d71f19a5c73f743518c485 Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 13 Oct 2022 09:07:50 +0200 Subject: [PATCH 32/48] Update docs --- docs/CONFIGURATION.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index 3b484c0..e93f22c 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -1,9 +1,11 @@ # Manage Categories: -### Fields: -- `Title`: The title of the category, which is displayed above the defined style groups in the backend -- `Idenfifier`: A unique value for retrieving the classes in the template -- `Group-Idenfifier`: In this field you can specify an alias that combines categories with the same alias and displays them as tabs in the backend. -- `Sort-Index`: This field is used to determine the order of the categories in the backend + +| Field | Description | +|--------------------|------------------------------------------------------------------------------------------------------------------------------| +| `Title` | The title of the category. | +| `Idenfifier` | A unique value. This value must be used to retrieve the template variables. | +| `Group-Idenfifier` | In this field you can specify an alias that combines categories with the same alias and displays them as tabs in the widget. | +| `Sort-Index` | This field is used to determine the order of the categories in the widget. | #### Example backend view of combined categories using `Group-Idenfifier`: ![Manage Categories: Image 3](https://www.oveleon.de/share/github-assets/contao-component-style-manager/2.0/combined-groups.png) @@ -12,11 +14,13 @@ # Manage CSS-Groups: ### Fields: -- `Alias`: Define an alias with which the group can be accessed. This is only required for passing on to the template. -- `Add search field`: Use of chosen for a search field within the select box -- `Use as template variable`: This field declares whether this group is set in the class attribute of the corresponding element or passed to the template. -- `CSS class`: To further customize the display of the backend fields, you can enter a selection of predefined CSS classes. (long, clr, separator) -> All other fields should be self-explanatory +| Field | Description | +|----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `Alias` | A unique value. This value must be used to retrieve the template variables. | +| `Add search field` | Activates the search within the widget for this CSS group. This setting is recommended only for a larger set of options. | +| `Use as template variable` | This field defines the type of usage. When this field is checked, the variable is passed to the template instead of being used as a CSS class. [More about template variables](TEMPLATE_VARIABLES). | +| `CSS class` | To further customize the display of the backend fields, you can specify a selection of predefined CSS classes. (long, clr, separator) | +| `...` | All other fields should be self-explanatory | #### Example css group: ![Manage Groups: Image 1](https://www.oveleon.de/share/github-assets/contao-component-style-manager/2.0/groups-edit.png) From a298b78df57070b5dd7b15fc8590331092d132a5 Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 13 Oct 2022 09:08:15 +0200 Subject: [PATCH 33/48] Update docs --- docs/CONFIGURATION.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index e93f22c..cc307dd 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -7,7 +7,7 @@ | `Group-Idenfifier` | In this field you can specify an alias that combines categories with the same alias and displays them as tabs in the widget. | | `Sort-Index` | This field is used to determine the order of the categories in the widget. | -#### Example backend view of combined categories using `Group-Idenfifier`: +### Example backend view of combined categories using `Group-Idenfifier`: ![Manage Categories: Image 3](https://www.oveleon.de/share/github-assets/contao-component-style-manager/2.0/combined-groups.png)
@@ -22,5 +22,5 @@ | `CSS class` | To further customize the display of the backend fields, you can specify a selection of predefined CSS classes. (long, clr, separator) | | `...` | All other fields should be self-explanatory | -#### Example css group: +### Example css group: ![Manage Groups: Image 1](https://www.oveleon.de/share/github-assets/contao-component-style-manager/2.0/groups-edit.png) From fdb16b30b5c2eb3e092192b0598f638816c2a173 Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 13 Oct 2022 09:09:55 +0200 Subject: [PATCH 34/48] Update docs --- docs/CONFIGURATION.md | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index cc307dd..0067640 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -1,3 +1,13 @@ +## Documentation +- __[Configuration](CONFIGURATION.md)__ +- [Use template variables](TEMPLATE_VARIABLES.md) +- [Extend and support other extensions](SUPPORT.md) +- [Import / Export](IMPORT_EXPORT.md) +- [Bundle-Configurations](BUNDLE_CONFIG.md) +- [Migration](docs/MIGRATE.md) + +--- + # Manage Categories: | Field | Description | @@ -13,14 +23,14 @@
# Manage CSS-Groups: -### Fields: -| Field | Description | -|----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `Alias` | A unique value. This value must be used to retrieve the template variables. | -| `Add search field` | Activates the search within the widget for this CSS group. This setting is recommended only for a larger set of options. | -| `Use as template variable` | This field defines the type of usage. When this field is checked, the variable is passed to the template instead of being used as a CSS class. [More about template variables](TEMPLATE_VARIABLES). | -| `CSS class` | To further customize the display of the backend fields, you can specify a selection of predefined CSS classes. (long, clr, separator) | -| `...` | All other fields should be self-explanatory | + +| Field | Description | +|----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `Alias` | A unique value. This value must be used to retrieve the template variables. | +| `Add search field` | Activates the search within the widget for this CSS group. This setting is recommended only for a larger set of options. | +| `Use as template variable` | This field defines the type of usage. When this field is checked, the variable is passed to the template instead of being used as a CSS class. [More about template variables](TEMPLATE_VARIABLES.md). | +| `CSS class` | To further customize the display of the backend fields, you can specify a selection of predefined CSS classes. (long, clr, separator) | +| `...` | All other fields should be self-explanatory | ### Example css group: ![Manage Groups: Image 1](https://www.oveleon.de/share/github-assets/contao-component-style-manager/2.0/groups-edit.png) From 89aa77d41859d74556edfba54bf1c4ea68d6bd1a Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 13 Oct 2022 09:28:31 +0200 Subject: [PATCH 35/48] Update docs --- docs/CONFIGURATION.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index 0067640..e39dd96 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -8,7 +8,11 @@ --- -# Manage Categories: +After the installation, a new navigation item "StyleManager" is displayed in the backend to create and edit the dataset of categories and CSS groups. + +# Categories: + +Categories can be considered as archives and form a logical separation of CSS groups. A special feature for the display in the backend, is the merging of these categories via the field `Group-Identifier`. This field can be filled freely to display categories with the same group identifier bundled as tab navigation in the widget. | Field | Description | |--------------------|------------------------------------------------------------------------------------------------------------------------------| @@ -22,7 +26,11 @@
-# Manage CSS-Groups: +# CSS-Groups: + +If a category has been created, any CSS groups can be created within it. A CSS group represents the actual selection of selectable options that are made available to the editor for the various areas (articles, content elements, ...). + +A special feature is that CSS groups can also be used as template variables via the `Use as template variable` field. In this case, the selected options are not automatically made available as a CSS class, but must be accepted manually in the template. Learn more about template variables. | Field | Description | |----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| From 5a56b8578b0952c1adbf3325d740972adb1dba4a Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 13 Oct 2022 10:28:57 +0200 Subject: [PATCH 36/48] Update docs --- docs/BUNDLE_CONFIG.md | 15 ++++++- docs/CONFIGURATION.md | 2 +- docs/IMPORT_EXPORT.md | 12 +++++- docs/MIGRATE.md | 15 ++++++- docs/SUPPORT.md | 10 +++++ docs/TEMPLATE_VARIABLES.md | 87 +++++++++++++++++++++++--------------- 6 files changed, 102 insertions(+), 39 deletions(-) diff --git a/docs/BUNDLE_CONFIG.md b/docs/BUNDLE_CONFIG.md index a80ded7..034c08a 100644 --- a/docs/BUNDLE_CONFIG.md +++ b/docs/BUNDLE_CONFIG.md @@ -1,8 +1,19 @@ -## Bundle-Configurations +## Documentation +- [Configuration](CONFIGURATION.md) +- [Use template variables](TEMPLATE_VARIABLES.md) +- [Extend and support other extensions](SUPPORT.md) +- [Import / Export](IMPORT_EXPORT.md) +- __[Bundle-Configurations](BUNDLE_CONFIG.md)__ +- [Migration](docs/MIGRATE.md) + +--- + +# Bundle-Configurations Instead of the import function, from version 3, configurations can be automatically provided by other bundles. For the deployment, a configuration file, which can be exported via the StyleManager, must be stored under `contao/templates` of the bundle. The file needs to start with `style-manager-`. If the automatic import of these configuration files is not prevented (allowed by default), archives and CSS groups are automatically added to the defined areas. -To prevent dynamic configurations from being read in, the following lines must be added to the config.yml file: +To prevent dynamic configurations from being read in, you can make the following configuration: ```yaml +# config.yaml contao_component_style_manager: use_bundle_config: false ``` diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index e39dd96..0d53c99 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -30,7 +30,7 @@ Categories can be considered as archives and form a logical separation of CSS gr If a category has been created, any CSS groups can be created within it. A CSS group represents the actual selection of selectable options that are made available to the editor for the various areas (articles, content elements, ...). -A special feature is that CSS groups can also be used as template variables via the `Use as template variable` field. In this case, the selected options are not automatically made available as a CSS class, but must be accepted manually in the template. Learn more about template variables. +A special feature is that CSS groups can also be used as template variables via the `Use as template variable` field. In this case, the selected options are not automatically made available as a CSS class, but must be accepted manually in the template. [Learn more about template variables](TEMPLATE_VARIABLES.md). | Field | Description | |----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| diff --git a/docs/IMPORT_EXPORT.md b/docs/IMPORT_EXPORT.md index 05ecca9..503358e 100644 --- a/docs/IMPORT_EXPORT.md +++ b/docs/IMPORT_EXPORT.md @@ -1,4 +1,14 @@ -## Import / Export +## Documentation +- [Configuration](CONFIGURATION.md) +- [Use template variables](TEMPLATE_VARIABLES.md) +- [Extend and support other extensions](SUPPORT.md) +- __[Import / Export](IMPORT_EXPORT.md)__ +- [Bundle-Configurations](BUNDLE_CONFIG.md) +- [Migration](docs/MIGRATE.md) + +--- + +# Import / Export To fill projects with a default setting, the Import and Export functions are available. When importing, the categories as well as the CSS groups are only added additively. This allows CSS classes to be added to the actual project without being deleted after an import. diff --git a/docs/MIGRATE.md b/docs/MIGRATE.md index 6aacbb9..71ec6ac 100644 --- a/docs/MIGRATE.md +++ b/docs/MIGRATE.md @@ -1,10 +1,21 @@ -## Migration +## Documentation +- [Configuration](CONFIGURATION.md) +- [Use template variables](TEMPLATE_VARIABLES.md) +- [Extend and support other extensions](SUPPORT.md) +- [Import / Export](IMPORT_EXPORT.md) +- [Bundle-Configurations](BUNDLE_CONFIG.md) +- __[Migration](docs/MIGRATE.md)__ + +--- + +# Migration #### Migrate from version 2 to 3 -Bundle configurations were added with version 3. This makes it necessary to migrate the StyleManager dataset. If only standard Contao tables were used and the StyleManager was not added to other / own database tables, calling the install tool is sufficient. +Bundle configurations were added with version 3. This makes it necessary to migrate the StyleManager dataset. If only standard Contao tables were used and the StyleManager was not added to other / own database tables, calling the install tool is sufficient. Starting with Contao 5, the migration has to be confirmed manually by the Contao Manager. If the StyleManager was used for other / own database tables, these tables must be migrated manually using the following command: ```shell +# vendor/bin/ $ php contao-console contao:stylemanager:object-conversion tl_mytable ``` diff --git a/docs/SUPPORT.md b/docs/SUPPORT.md index 03c5f57..7bc7d97 100644 --- a/docs/SUPPORT.md +++ b/docs/SUPPORT.md @@ -1,3 +1,13 @@ +## Documentation +- [Configuration](CONFIGURATION.md) +- [Use template variables](TEMPLATE_VARIABLES.md) +- __[Extend and support other extensions](SUPPORT.md)__ +- [Import / Export](IMPORT_EXPORT.md) +- [Bundle-Configurations](BUNDLE_CONFIG.md) +- [Migration](docs/MIGRATE.md) + +--- + # Support your own or vendor DCA's If you have your own DCA that you want to make available for the StyleManager, you can do this in **three to four steps**. As in Contao itself, the DCA must contain a field where the CSS classes can be stored. The following fields are already included: diff --git a/docs/TEMPLATE_VARIABLES.md b/docs/TEMPLATE_VARIABLES.md index b9564ea..65fd5e4 100644 --- a/docs/TEMPLATE_VARIABLES.md +++ b/docs/TEMPLATE_VARIABLES.md @@ -1,29 +1,31 @@ +## Documentation +- [Configuration](CONFIGURATION.md) +- __[Use template variables](TEMPLATE_VARIABLES.md)__ +- [Extend and support other extensions](SUPPORT.md) +- [Import / Export](IMPORT_EXPORT.md) +- [Bundle-Configurations](BUNDLE_CONFIG.md) +- [Migration](docs/MIGRATE.md) + +--- + # Passing css group variables to a template: -If the checkbox "Use as template variable" is set, these are not automatically passed to the class of the corresponding element but are available in the template. +If the checkbox `Use as template variable` is set, these are not automatically passed to the CSS class of the corresponding element but are available in the template. To access the variables, we can access the corresponding class collection via the `styleManager` object. ![Passing Variables: Image 1](https://www.oveleon.de/share/github-assets/contao-component-style-manager/2.0/template-vars-list.png) -### There are two ways to receive the values: -- **`get`**: Return selected CSS classes of a category or a specific group - - Parameter: - - `identifier: string`: Category identifier - - `groups: null|array` (optional): Group aliases -- **`prepare`** + **`format`**: Different from the get method, you can specify your own output format and a predefined or custom method to validate the output - - `prepare`-Parameter: - - `identifier: string`: Category identifier - - `groups: null|array` (optional): Group aliases - - `format`-Parameter: - - `format: string`: The format parameter must contain a format string valid for `sprintf` (PHP: [sprintf](https://www.php.net/manual/de/function.sprintf.php))). - - `method: string` (optional): Name of Method - -#### `format`-Methods -- `json`: Returns a JSON object using the alias and value (e.g. `{"alias1":"my-class-1","alias2":"my-class-2"}`) - -To set up a custom method for validating the values, the hook `styleManagerFormatMethod` can be registered. - -### Examples: -#### Using `get`-Method +## API: +### `get` +Return selected CSS classes of a category or a specific group + +__Method arguments:__ + +| Argument | Type | Description | +|-------------------|----------------|---------------------| +| identifier | `string` | Category identifier | +| groups (Optional) | `null׀array` | Group aliases | + +__Example:__ ```php // Return of all selected CSS classes of a category $this->styleManager->get('myCategoryIdentifier'); @@ -32,26 +34,45 @@ $this->styleManager->get('myCategoryIdentifier'); $this->styleManager->get('myCategoryIdentifier', ['alias1', 'alias2']); ``` -#### Using `prepare` + `format`-Method +### `prepare` + `format` +Different from the `get` method, you can specify your own output format and a predefined or custom method to validate the output. + +__Arguments of the `prepare` method:__ + +| Argument | Type | Description | +|-------------------|----------------|---------------------| +| identifier | `string` | Category identifier | +| groups (Optional) | `null׀array` | Group aliases | + +__Arguments of the `format` method:__ + +| Argument | Type | Description | +|-------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------| +| format | `string` | The format parameter must contain a format string valid for `sprintf` (PHP: [sprintf](https://www.php.net/manual/de/function.sprintf.php))) | +| method (Optional) | `string` | A method name to manipulate the output | + +__Example:__ ```php -// Return of all selected CSS classes of a category with class attribute +// Return of all selected CSS classes of a category within a class attribute $this->styleManager->prepare('myCategoryIdentifier')->format('class="%s"'); -// Often additional classes are appended to an existing class attribute. In this case, unnecessary if-else statements can be avoided. +// Additional classes are often appended to an existing class attribute. In this case, unnecessary if-else statements can be avoided by appending a space character if a value exists. $this->styleManager->prepare('myCategoryIdentifier')->format(' %s'); -// Return of all selected CSS classes in specific groups of a category as json with data attribute +// Return of all selected CSS classes in specific group of a category as json within a data attribute $this->styleManager->prepare('myCategoryIdentifier', ['alias1'])->format("data-slider='%s'", 'json'); ``` -#### Example of use -``` -
...
- or -
styleManager->prepare('myCategoryIdentifier')->format("class="%s")?>>...
+## Format methods +### `json` +Returns a JSON object using the alias and value (e.g. `{"alias1":"my-class-1","alias2":"my-class-2"}`) -
...
+### Create your own methods +To add your own methods you can use the `styleManagerFormatMethod` hook: -
">...
+```php +function customFormatMethod(string $format, string $method, Styles $context): string +{ + // Custom stuff +} ``` - From 5101c41b620329f7f99c9fb7ac238a52c2122c68 Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 13 Oct 2022 10:30:34 +0200 Subject: [PATCH 37/48] Update docs --- docs/TEMPLATE_VARIABLES.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/TEMPLATE_VARIABLES.md b/docs/TEMPLATE_VARIABLES.md index 65fd5e4..192ae9f 100644 --- a/docs/TEMPLATE_VARIABLES.md +++ b/docs/TEMPLATE_VARIABLES.md @@ -15,7 +15,7 @@ To access the variables, we can access the corresponding class collection via th ![Passing Variables: Image 1](https://www.oveleon.de/share/github-assets/contao-component-style-manager/2.0/template-vars-list.png) ## API: -### `get` +### 🔹 `get` Return selected CSS classes of a category or a specific group __Method arguments:__ @@ -34,7 +34,7 @@ $this->styleManager->get('myCategoryIdentifier'); $this->styleManager->get('myCategoryIdentifier', ['alias1', 'alias2']); ``` -### `prepare` + `format` +### 🔹 `prepare` + `format` Different from the `get` method, you can specify your own output format and a predefined or custom method to validate the output. __Arguments of the `prepare` method:__ @@ -64,7 +64,7 @@ $this->styleManager->prepare('myCategoryIdentifier', ['alias1'])->format("data-s ``` ## Format methods -### `json` +### 🔸 `json` Returns a JSON object using the alias and value (e.g. `{"alias1":"my-class-1","alias2":"my-class-2"}`) ### Create your own methods From 2987801bcb838900b118b2414a8a583a82cf0575 Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 13 Oct 2022 11:52:39 +0200 Subject: [PATCH 38/48] Update docs --- README.md | 2 +- docs/BUNDLE_CONFIG.md | 2 +- docs/CONFIGURATION.md | 2 +- docs/IMPORT_EXPORT.md | 2 +- docs/MIGRATE.md | 2 +- docs/SUPPORT.md | 166 +++++++++++++----------------- docs/TEMPLATE_VARIABLES.md | 2 +- src/StyleManager/StyleManager.php | 2 +- 8 files changed, 81 insertions(+), 99 deletions(-) diff --git a/README.md b/README.md index 6d89782..82c6fab 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ composer require oveleon/contao-component-style-manager ## Documentation - [Configuration](docs/CONFIGURATION.md) - [Use template variables](docs/TEMPLATE_VARIABLES.md) -- [Extend and support other extensions](docs/SUPPORT.md) +- [Support own extensions](docs/SUPPORT.md) - [Import / Export](docs/IMPORT_EXPORT.md) - [Bundle-Configurations](docs/BUNDLE_CONFIG.md) - [Migration](docs/MIGRATE.md) diff --git a/docs/BUNDLE_CONFIG.md b/docs/BUNDLE_CONFIG.md index 034c08a..3690262 100644 --- a/docs/BUNDLE_CONFIG.md +++ b/docs/BUNDLE_CONFIG.md @@ -1,7 +1,7 @@ ## Documentation - [Configuration](CONFIGURATION.md) - [Use template variables](TEMPLATE_VARIABLES.md) -- [Extend and support other extensions](SUPPORT.md) +- [Support own extensions](SUPPORT.md) - [Import / Export](IMPORT_EXPORT.md) - __[Bundle-Configurations](BUNDLE_CONFIG.md)__ - [Migration](docs/MIGRATE.md) diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index 0d53c99..6ab2065 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -1,7 +1,7 @@ ## Documentation - __[Configuration](CONFIGURATION.md)__ - [Use template variables](TEMPLATE_VARIABLES.md) -- [Extend and support other extensions](SUPPORT.md) +- [Support own extensions](SUPPORT.md) - [Import / Export](IMPORT_EXPORT.md) - [Bundle-Configurations](BUNDLE_CONFIG.md) - [Migration](docs/MIGRATE.md) diff --git a/docs/IMPORT_EXPORT.md b/docs/IMPORT_EXPORT.md index 503358e..0127983 100644 --- a/docs/IMPORT_EXPORT.md +++ b/docs/IMPORT_EXPORT.md @@ -1,7 +1,7 @@ ## Documentation - [Configuration](CONFIGURATION.md) - [Use template variables](TEMPLATE_VARIABLES.md) -- [Extend and support other extensions](SUPPORT.md) +- [Support own extensions](SUPPORT.md) - __[Import / Export](IMPORT_EXPORT.md)__ - [Bundle-Configurations](BUNDLE_CONFIG.md) - [Migration](docs/MIGRATE.md) diff --git a/docs/MIGRATE.md b/docs/MIGRATE.md index 71ec6ac..d46e755 100644 --- a/docs/MIGRATE.md +++ b/docs/MIGRATE.md @@ -1,7 +1,7 @@ ## Documentation - [Configuration](CONFIGURATION.md) - [Use template variables](TEMPLATE_VARIABLES.md) -- [Extend and support other extensions](SUPPORT.md) +- [Support own extensions](SUPPORT.md) - [Import / Export](IMPORT_EXPORT.md) - [Bundle-Configurations](BUNDLE_CONFIG.md) - __[Migration](docs/MIGRATE.md)__ diff --git a/docs/SUPPORT.md b/docs/SUPPORT.md index 7bc7d97..8c80631 100644 --- a/docs/SUPPORT.md +++ b/docs/SUPPORT.md @@ -1,156 +1,138 @@ ## Documentation - [Configuration](CONFIGURATION.md) - [Use template variables](TEMPLATE_VARIABLES.md) -- __[Extend and support other extensions](SUPPORT.md)__ +- __[Support own extensions](SUPPORT.md)__ - [Import / Export](IMPORT_EXPORT.md) - [Bundle-Configurations](BUNDLE_CONFIG.md) - [Migration](docs/MIGRATE.md) --- -# Support your own or vendor DCA's -If you have your own DCA that you want to make available for the StyleManager, you can do this in **three to four steps**. -As in Contao itself, the DCA must contain a field where the CSS classes can be stored. The following fields are already included: +# Support own extensions +To use the StyleManager in your own DCA's as well, four to five steps are required. -- `cssID` (multiple field) -- `cssClass` (single field) -- `class` (single field) -- `attributes` (multiple field) +__First things first__\ +As in Contao itself, the DCA must contain a field where the CSS classes can be stored. One of the following fields should exist: + +| Field | Size | +|--------------|----------------| +| `cssID` | multiple field | +| `cssClass` | single field | +| `class` | single field | +| `attributes` | multiple field | > Please note that the field size must be observed! -### 1. Extending the **CSS group fields** in `tl_style_manager` DCA - +## Step 1: Expand your DCA +Adding the StyleManager widget in your own DCA. As an example we use the DCA name `tl_mydca` and the Field `attribute` (storage for CSS-Classes). + ```php -// Extend the default palette -Contao\CoreBundle\DataContainer\PaletteManipulator::create() - ->addField(array('extendMyDca'), 'publish_legend', Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_APPEND) - ->applyToPalette('default', 'tl_style_manager'); +use Oveleon\ContaoComponentStyleManager\StyleManager\StyleManager; -// Extend fields -$GLOBALS['TL_DCA']['tl_style_manager']['fields']['extendMyDca'] = array -( - 'label' => &$GLOBALS['TL_LANG']['tl_style_manager']['extendMyDca'], - 'exclude' => true, - 'filter' => true, - 'inputType' => 'checkbox', - 'eval' => array('tl_class'=>'clr'), - 'sql' => "char(1) NOT NULL default ''" -); +// Extend the StyleManager field +$GLOBALS['TL_DCA']['tl_mydca']['fields']['styleManager'] = [ + 'inputType' => 'stylemanager', + 'eval' => ['tl_class'=>'clr stylemanager'], + 'sql' => "blob NULL" +]; + +// Extend the palette (StyleManager provides a helper callback to automatically include all palettes in the DCA, Contao's palette manipulator can also be used) +$GLOBALS['TL_DCA']['tl_mydca']['config']['onload_callback'][] = [StyleManager::class, 'addPalette']; + +// Adding callback methods for the CSS-class field (cssID, cssClass, class or attributes) +$GLOBALS['TL_DCA']['tl_mydca']['fields']['attributes']['load_callback'][] = [StyleManager::class, 'onLoad']; +$GLOBALS['TL_DCA']['tl_mydca']['fields']['attributes']['save_callback'][] = [StyleManager::class, 'onSave']; ``` -### 2. Adding the styleManager **legend and field** to your DCA - +## Step 2: Expand the StyleManager DCA +To be able to select the new DCA within the StyleManager configuration (CSS Groups), we need to make it known in the next step. To use the same naming scheme as in StyleManager, we name our new field "extendMyDca". + ```php +use Contao\CoreBundle\DataContainer\PaletteManipulator; + // Extend fields -$GLOBALS['TL_DCA']['tl_mydca']['fields']['styleManager'] = array -( - 'label' => &$GLOBALS['TL_LANG']['tl_mydca']['styleManager'], - 'exclude' => true, - 'inputType' => 'stylemanager', - 'eval' => array('tl_class'=>'clr stylemanager'), - 'sql' => "blob NULL" -); - -// Extend the palette (Since version 2.4 this callback method can be used, before that the field "styleManager" must be added via the palette manipulator.) -$GLOBALS['TL_DCA']['tl_mydca']['config']['onload_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'addPalette'); - -// Adding callback methods for the CSS-Class field (cssID, cssClass, class or attributes) -$GLOBALS['TL_DCA']['tl_mydca']['fields']['attributes']['load_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onLoad'); -$GLOBALS['TL_DCA']['tl_mydca']['fields']['attributes']['save_callback'][] = array('\\Oveleon\\ContaoComponentStyleManager\\StyleManager', 'onSave'); -``` +$GLOBALS['TL_DCA']['tl_style_manager']['fields']['extendMyDca'] = [ + 'inputType' => 'checkbox', + 'eval' => ['tl_class'=>'clr'], + 'sql' => "char(1) NOT NULL default ''" +]; -### 3. Provide the StyleManager the new DCA +// Extend the default palette +PaletteManipulator::create() + ->addField(['extendMyDca'], 'publish_legend', PaletteManipulator::POSITION_APPEND) + ->applyToPalette('default', 'tl_style_manager'); +``` -To get the selected CSS groups for the new DCA and to provide them in the backend, it is necessary to provide the StyleManager with the new DCA. In order to make this possible the **styleManagerFindByTable**-Hook is prepared. +## Step 3: Make your DCA known to the StyleManager widget -```php -// HOOK -$GLOBALS['TL_HOOKS']['styleManagerFindByTable'][] = array('\\Namespace\\Class', 'onFindByTable'); -``` +To get the selected CSS groups for the new DCA and to provide them in the StyleManager widget, it is necessary to provide the StyleManager with the new DCA. In order to make this possible the `styleManagerFindByTable` hook is prepared. ```php -use Oveleon\ContaoComponentStyleManager\StyleManagerModel; +use Contao\CoreBundle\ServiceAnnotation\Hook; +use Oveleon\ContaoComponentStyleManager\Model\StyleManagerModel; /** * Find css groups using their table - * - * @param string $strTable - * @param array $arrOptions - * - * @return \Model\Collection|StyleManagerModel[]|StyleManagerModel|null A collection of models or null if there are no css groups + * + * @Hook("styleManagerFindByTable") */ -public function onFindByTable($strTable, $arrOptions) +public function onFindByTable(string $table, array $options = []) { - if($strTable === 'tl_mydca') + if('tl_mydca' === $table) { - return StyleManagerModel::findBy(array('extendMyDca=1'), null, $arrOptions); + return StyleManagerModel::findBy(['extendMyDca=1'], null, $options); } return null; } ``` -### 4. Provide the StyleManager your new groups - -To load the new CSS groups within your elements, it is necessary to provide the StyleManager the new groups. In order to make this possible the **styleManagerIsVisibleGroup**-Hook is prepared. - +## Step 4: Provide the StyleManager your new groups -```php -// HOOK -$GLOBALS['TL_HOOKS']['styleManagerIsVisibleGroup'][] = array('\\Namespace\\Class', 'isVisibleGroup'); -``` +To check if the CSS groups is allowed for the current component, we need to include a check function via the hook `styleManagerIsVisibleGroup`. ```php +use Contao\CoreBundle\ServiceAnnotation\Hook; use Oveleon\ContaoComponentStyleManager\StyleManagerModel; /** - * Check whether an element is visible in style manager widget - * - * @param $objGroup - * @param $strTable - * - * @return bool + * Check whether an element is visible for my dca in style manager widget + * + * @Hook("styleManagerIsVisibleGroup") */ -public function isVisibleGroup($objGroup, $strTable) +public function isVisibleGroup(StyleManagerModel $group, string $table): bool { - if( - 'tl_mydca1' === $strTable && !!$objGroup->extendMyDca1 - ){ return true; } + if('tl_mydca' === $table && !!$group->extendMyDca) + { + return true; + } - return false; + return false; } ``` -### 5. **Skip fields** that should not be displayed in the Backend Select-Widget +## Step 5: **Skip fields** that should not be displayed 📌 _This step is only necessary for tables with different types like tl_content, tl_module or tl_form_fields_ If the DCA provides several types, which can be selected individually under the CSS groups, a further check has to take place to display them only for certain types. ```php -// HOOK -$GLOBALS['TL_HOOKS']['styleManagerSkipField'][] = array('\\Namespace\\Class', 'onSkipField'); -``` +use Contao\StringUtil; +use Contao\CoreBundle\ServiceAnnotation\Hook; -```php /** - * StyleManager Support - * - * If the field is not selected in the CSS group, it is skipped - * - * @param $objStyleGroups - * @param $objWidget + * Skip non-valid fields * - * @return bool Skip field + * @Hook("styleManagerSkipField") */ -public function onSkipField($objStyleGroups, $objWidget) +public function onSkipField(StyleManagerModel $styleGroups, Widget $widget) { - if(!!$objStyleGroups->extendMyDca && $objWidget->strTable === 'tl_mydca') + if(!!$styleGroups->extendMyDca && 'tl_mydca' === $widget->strTable) { - $arrDcaTypes = \StringUtil::deserialize($objStyleGroups->dcaTypes); + $arrDcaTypes = StringUtil::deserialize($styleGroups->dcaTypes); - if($arrDcaTypes !== null && !in_array($objWidget->activeRecord->type, $arrDcaTypes)) + if($arrDcaTypes !== null && !in_array($widget->activeRecord->type, $arrDcaTypes)) { return true; } diff --git a/docs/TEMPLATE_VARIABLES.md b/docs/TEMPLATE_VARIABLES.md index 192ae9f..56cddc4 100644 --- a/docs/TEMPLATE_VARIABLES.md +++ b/docs/TEMPLATE_VARIABLES.md @@ -1,7 +1,7 @@ ## Documentation - [Configuration](CONFIGURATION.md) - __[Use template variables](TEMPLATE_VARIABLES.md)__ -- [Extend and support other extensions](SUPPORT.md) +- [Support own extensions](SUPPORT.md) - [Import / Export](IMPORT_EXPORT.md) - [Bundle-Configurations](BUNDLE_CONFIG.md) - [Migration](docs/MIGRATE.md) diff --git a/src/StyleManager/StyleManager.php b/src/StyleManager/StyleManager.php index e7a04ab..1525312 100644 --- a/src/StyleManager/StyleManager.php +++ b/src/StyleManager/StyleManager.php @@ -63,7 +63,7 @@ public function addPalette($dc) { $palette = PaletteManipulator::create() ->addLegend('style_manager_legend', 'expert_legend', PaletteManipulator::POSITION_BEFORE) - ->addField(array('styleManager'), 'style_manager_legend', PaletteManipulator::POSITION_APPEND); + ->addField(['styleManager'], 'style_manager_legend', PaletteManipulator::POSITION_APPEND); foreach ($GLOBALS['TL_DCA'][ $dc->table ]['palettes'] as $key=>$value){ if($key === '__selector__') From 22fbd3df00d8e39de37404f4be489cb0a2a89454 Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 13 Oct 2022 11:53:35 +0200 Subject: [PATCH 39/48] Update docs --- docs/SUPPORT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/SUPPORT.md b/docs/SUPPORT.md index 8c80631..cb4b781 100644 --- a/docs/SUPPORT.md +++ b/docs/SUPPORT.md @@ -11,7 +11,7 @@ # Support own extensions To use the StyleManager in your own DCA's as well, four to five steps are required. -__First things first__\ +### First things first As in Contao itself, the DCA must contain a field where the CSS classes can be stored. One of the following fields should exist: | Field | Size | From 13c775693b949f53c85d074e9f8863b4978146d4 Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 13 Oct 2022 11:55:18 +0200 Subject: [PATCH 40/48] Update docs --- docs/SUPPORT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/SUPPORT.md b/docs/SUPPORT.md index cb4b781..dbe00f7 100644 --- a/docs/SUPPORT.md +++ b/docs/SUPPORT.md @@ -45,7 +45,7 @@ $GLOBALS['TL_DCA']['tl_mydca']['fields']['attributes']['save_callback'][] = [Sty ``` ## Step 2: Expand the StyleManager DCA -To be able to select the new DCA within the StyleManager configuration (CSS Groups), we need to make it known in the next step. To use the same naming scheme as in StyleManager, we name our new field "extendMyDca". +To be able to select the new DCA within the StyleManager configuration (CSS Groups), we need to make it known in the next step. To use the same naming scheme as in StyleManager, we name our new field "extend`table-name`" (`extendMyDca`). ```php use Contao\CoreBundle\DataContainer\PaletteManipulator; From 4772574656639c5917d7dc90594230dd8934b568 Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 13 Oct 2022 12:03:59 +0200 Subject: [PATCH 41/48] Update docs --- docs/SUPPORT.md | 77 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/docs/SUPPORT.md b/docs/SUPPORT.md index dbe00f7..5932235 100644 --- a/docs/SUPPORT.md +++ b/docs/SUPPORT.md @@ -118,6 +118,7 @@ public function isVisibleGroup(StyleManagerModel $group, string $table): bool If the DCA provides several types, which can be selected individually under the CSS groups, a further check has to take place to display them only for certain types. ```php +use Contao\Widget; use Contao\StringUtil; use Contao\CoreBundle\ServiceAnnotation\Hook; @@ -141,3 +142,79 @@ public function onSkipField(StyleManagerModel $styleGroups, Widget $widget) return false; } ``` + +# Boilerplate + +```php +{self::SM_FIELD_NAME}) + { + return true; + } + + return false; + } + + /** + * Skip non-valid fields (Step 5) + * + * @Hook("styleManagerSkipField") + */ + public function onSkipField(StyleManagerModel $styleGroups, Widget $widget) + { + if(!!$styleGroups->{self::SM_FIELD_NAME} && self::DCA_NAME === $widget->strTable) + { + $arrDcaTypes = StringUtil::deserialize($styleGroups->dcaTypes); + + if($arrDcaTypes !== null && !in_array($widget->activeRecord->type, $arrDcaTypes)) + { + return true; + } + } + + return false; + } +} +``` From 0634dde2ebe0f45e9fe76e1bf294afeb06b858d2 Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 13 Oct 2022 12:04:45 +0200 Subject: [PATCH 42/48] Update docs --- docs/SUPPORT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/SUPPORT.md b/docs/SUPPORT.md index 5932235..04db15c 100644 --- a/docs/SUPPORT.md +++ b/docs/SUPPORT.md @@ -11,7 +11,7 @@ # Support own extensions To use the StyleManager in your own DCA's as well, four to five steps are required. -### First things first +## First things first As in Contao itself, the DCA must contain a field where the CSS classes can be stored. One of the following fields should exist: | Field | Size | From 8c859ec565de1bd3a66590027fd5bfde20c8006d Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 13 Oct 2022 12:18:18 +0200 Subject: [PATCH 43/48] Update docs --- UPGRADE.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 UPGRADE.md diff --git a/UPGRADE.md b/UPGRADE.md new file mode 100644 index 0000000..d0cfaca --- /dev/null +++ b/UPGRADE.md @@ -0,0 +1,12 @@ +# Version 2.* to 3.0 +## Storage adjustment +### Migration +If you update from version 2 to version 3, you have to perform a migration, otherwise the records will break and cannot be reassigned in the backend. + +[Learn more about migration](docs/MIGRATE.md) + +## Restructure of the Bundle +### Namespaces +Due to the restructuring of the bundle, the namespaces have to be adjusted, if the StyleManager was used for vendor DCAs. + +[Learn more about StyleManager Support](docs/SUPPORT.md) From a7ca3efa8c272893f6e73874159bea03771970b7 Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 13 Oct 2022 12:22:36 +0200 Subject: [PATCH 44/48] Update docs --- UPGRADE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UPGRADE.md b/UPGRADE.md index d0cfaca..4d44678 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,7 +1,7 @@ # Version 2.* to 3.0 ## Storage adjustment ### Migration -If you update from version 2 to version 3, you have to perform a migration, otherwise the records will break and cannot be reassigned in the backend. +If you update from version 2 to version 3, you have to perform a migration, otherwise the records will break and cannot be reassigned in the backend. If the StyleManager widget is already called before running a migration, selected properties are inserted into the DCA's CSS class field to avoid errors. [Learn more about migration](docs/MIGRATE.md) From b247362d5ffe387b4d908fbfe50a5050fc996a80 Mon Sep 17 00:00:00 2001 From: doishub Date: Thu, 13 Oct 2022 12:24:32 +0200 Subject: [PATCH 45/48] Update docs --- UPGRADE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UPGRADE.md b/UPGRADE.md index 4d44678..b770bff 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,7 +1,7 @@ # Version 2.* to 3.0 ## Storage adjustment ### Migration -If you update from version 2 to version 3, you have to perform a migration, otherwise the records will break and cannot be reassigned in the backend. If the StyleManager widget is already called before running a migration, selected properties are inserted into the DCA's CSS class field to avoid errors. +If you update from version 2 to version 3, you have to perform a migration, otherwise the records will break and cannot be reassigned in the StyleManager widget. If the StyleManager widget is already called before running a migration, selected properties are inserted into the DCA's CSS class field to avoid errors. [Learn more about migration](docs/MIGRATE.md) From 92d62a2afa39cbcfb346598834097a296d60d779 Mon Sep 17 00:00:00 2001 From: Sebastian Zoglowek Date: Thu, 20 Oct 2022 14:33:55 +0200 Subject: [PATCH 46/48] [Bugfix] Fixed a bug with bundle configurations not loading when outside of src folder --- src/StyleManager/Config.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/StyleManager/Config.php b/src/StyleManager/Config.php index c98951c..2b16d9b 100644 --- a/src/StyleManager/Config.php +++ b/src/StyleManager/Config.php @@ -94,7 +94,11 @@ public static function getBundleConfigurationFiles(): ?array try{ $filePath = str_replace('\\', "/",$strRelpath); $bundleName = str_replace("/vendor/", "", substr($filePath, strpos($filePath, '/vendor/'))); - $bundleName = substr($bundleName, 0, strpos($bundleName, '/src')); + + if (str_contains($bundleName, '/src')) + { + $bundleName = substr($bundleName, 0, strpos($bundleName, '/src')); + } }catch (\Exception $e){ $bundleName = 'vendor'; } From acd03d676686ac359d1e394af43c67d0189c8b7f Mon Sep 17 00:00:00 2001 From: doishub Date: Fri, 21 Oct 2022 09:10:47 +0200 Subject: [PATCH 47/48] Stop running migration when no archives exist --- src/StyleManager/Sync.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/StyleManager/Sync.php b/src/StyleManager/Sync.php index 8bc5a5f..ff34d09 100644 --- a/src/StyleManager/Sync.php +++ b/src/StyleManager/Sync.php @@ -40,8 +40,9 @@ public function shouldRunObjectConversion($table = null): bool } $objConfig = $this->Database->query("SELECT styleManager FROM " . $table . " WHERE styleManager IS NOT NULL LIMIT 0,1"); + $archives = StyleManagerArchiveModel::countAll(); - if($objConfig && $arrConfig = StringUtil::deserialize($objConfig->styleManager)) + if($objConfig && $archives > 0 && $arrConfig = StringUtil::deserialize($objConfig->styleManager)) { $key = array_key_first($arrConfig); From 9ba4d406ace8f2f17e4662f5fd704ba7c2bbfb45 Mon Sep 17 00:00:00 2001 From: doishub Date: Mon, 24 Oct 2022 13:18:50 +0200 Subject: [PATCH 48/48] Routes name renamed --- src/Resources/config/routes.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Resources/config/routes.yaml b/src/Resources/config/routes.yaml index 1fcbadf..d94b7f1 100644 --- a/src/Resources/config/routes.yaml +++ b/src/Resources/config/routes.yaml @@ -1,3 +1,3 @@ -bigger: +stylemanager: resource: '@ContaoComponentStyleManager/Controller' type: annotation