diff --git a/.gitignore b/.gitignore index 3b923d8..ea3128b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,7 @@ .DS_Store #IDE -.idea \ No newline at end of file +.idea + +#Build +vendor diff --git a/Classes/Hooks/PageLayoutViewDrawItemHook.php b/Classes/Backend/EventListener/PreviewEventListener.php similarity index 85% rename from Classes/Hooks/PageLayoutViewDrawItemHook.php rename to Classes/Backend/EventListener/PreviewEventListener.php index b04c230..589839f 100644 --- a/Classes/Hooks/PageLayoutViewDrawItemHook.php +++ b/Classes/Backend/EventListener/PreviewEventListener.php @@ -1,54 +1,26 @@ - * (c) 2016 Johann Derdak - * - * All rights reserved - * - * This script is part of the TYPO3 project. The TYPO3 project is - * free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ +declare(strict_types=1); + +namespace Denkwerk\DwContentElements\Backend\EventListener; use Denkwerk\DwContentElements\Service\IniProviderService; use Denkwerk\DwContentElements\Service\IniService; use Denkwerk\DwContentElements\Service\IrreService; use Denkwerk\DwContentElements\Service\UrlService; +use TYPO3\CMS\Backend\Form\Exception; use TYPO3\CMS\Backend\Form\Exception\AccessDeniedTableModifyException; use TYPO3\CMS\Backend\Form\FormDataCompiler; use TYPO3\CMS\Backend\Form\FormDataGroup\TcaDatabaseRecord; use TYPO3\CMS\Backend\Form\NodeFactory; use TYPO3\CMS\Backend\Utility\BackendUtility; -use TYPO3\CMS\Backend\View\PageLayoutView; -use TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface; +use TYPO3\CMS\Backend\View\Event\PageContentPreviewRenderingEvent; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Utility\LocalizationUtility; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; -/** - * Class PageLayoutViewDrawItemHook - * @package Denkwerk\DwContentElements\Hooks - */ -class PageLayoutViewDrawItemHook implements PageLayoutViewDrawItemHookInterface +class PreviewEventListener { - /** * @var IniService $iniService */ @@ -67,25 +39,11 @@ public function __construct() $this->iniService = GeneralUtility::makeInstance(IniService::class); $this->iniProviderService = GeneralUtility::makeInstance(IniProviderService::class); } - - /** - * Preprocessed the preview rendering of a content element. - * - * @param PageLayoutView $parentObject : Calling parent object - * @param boolean $drawItem : Whether to draw the item using the default functionalities - * @param string $headerContent : Header content - * @param string $itemContent : Item content - * @param array $row : Record row of tt_content - * @return void - * @throws \TYPO3\CMS\Backend\Form\Exception - */ - public function preProcess( - PageLayoutView &$parentObject, - &$drawItem, - &$headerContent, - &$itemContent, - array &$row - ) { + public function __invoke(PageContentPreviewRenderingEvent $event): void + { + if ($event->getTable() !== 'tt_content') { + return; + } /// Load all provider configurations as array $providers = $this->iniProviderService->loadProvider(); @@ -102,6 +60,8 @@ public function preProcess( } } + $row = $event->getRecord(); + // If it is an dwc content element if (isset($row['CType']) && !is_array($row['CType']) && @@ -136,7 +96,8 @@ public function preProcess( (isset($field['label']) && empty($field['label']) === false ? $field['label'] : - $parentObject->itemLabels[$field['name']] + //todo: make sure field exists + $event->getPageLayoutContext()->getItemLabels()[$field['name']] ) ); @@ -147,6 +108,8 @@ public function preProcess( } } $itemContent .= ''; + + $event->setPreviewContent($itemContent); } } @@ -158,7 +121,7 @@ public function preProcess( * @param string $itemLabels * @param string $fieldTable * @return string - * @throws \TYPO3\CMS\Backend\Form\Exception + * @throws Exception */ public function renderFieldPreview($fieldName, $row, $itemLabels = '', $fieldTable = 'tt_content') { @@ -304,8 +267,8 @@ public function renderFieldPreview($fieldName, $row, $itemLabels = '', $fieldTab case "selectCheckBox": $value = explode(',', $fieldValue); foreach ($items as $item) { - $filedContent .= $item[0] . ' ' . - (in_array($item[1], $value) ? '✔' : '✘') . + $filedContent .= $item['label'] . ' ' . + (in_array($item['value'], $value) ? '✔' : '✘') . '
'; } break; @@ -315,16 +278,17 @@ public function renderFieldPreview($fieldName, $row, $itemLabels = '', $fieldTab $value = explode(',', $fieldValue); $selectedContent = array(); foreach ($items as $item) { - if (in_array($item[1], $value)) { - $selectedContent[] = $item[0]; + if (in_array($item['value'], $value)) { + $selectedContent[] = $item['label']; } } $filedContent .= implode("
", $selectedContent); break; default: foreach ($items as $item) { - if ($item[1] == $fieldValue) { - $filedContent .= $item[0]; + if ($item['value'] == $fieldValue) { + + $filedContent .= $item['label']; } } } @@ -359,16 +323,12 @@ public function renderFieldPreview($fieldName, $row, $itemLabels = '', $fieldTab $filedContent .= ($filePreview != '' ? $filePreview : 'No File'); } else { if (isset($fieldConfig['foreign_table'])) { - /** @var ContentObjectRenderer $contentObj */ - $contentObj = GeneralUtility::makeInstance( - ContentObjectRenderer::class - ); - $contentObj->data = $row; + $count = 0; $filedContent .= '

'; foreach (IrreService::getRelations( - $contentObj, + $row, $fieldConfig['foreign_table'] ) as $item) { $irreItemLabel = $item[$GLOBALS['TCA'][$fieldConfig['foreign_table']]['ctrl']['label']]; @@ -397,7 +357,7 @@ public function renderFieldPreview($fieldName, $row, $itemLabels = '', $fieldTab $filedContent .= ''; } - return $filedContent; + return $filedContent ; } /** @@ -496,8 +456,9 @@ protected function explodeSingleFieldShowItemConfiguration($field) return array( 'fieldName' => $fieldArray[0], - 'fieldLabel' => isset($fieldArray[1]) ?? null, - 'paletteName' => isset($fieldArray[2]) ?? null, + 'fieldLabel' => (isset($fieldArray[1]) && trim($fieldArray[1]) !== '' ? $fieldArray[1] : null), + 'paletteName' => (isset($fieldArray[2]) && trim($fieldArray[2]) !== '' ? $fieldArray[2] : null) ); } -} + +} \ No newline at end of file diff --git a/Classes/Controller/BackendController.php b/Classes/Controller/BackendController.php index c7d641e..12c899e 100644 --- a/Classes/Controller/BackendController.php +++ b/Classes/Controller/BackendController.php @@ -26,12 +26,17 @@ * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +use Psr\Http\Message\ResponseInterface; +use TYPO3\CMS\Backend\Template\ModuleTemplateFactory; +use TYPO3\CMS\Extbase\Http\ForwardResponse; +use TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException; use Denkwerk\DwContentElements\Service\FileService; use Denkwerk\DwContentElements\Service\IniProviderService; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; use TYPO3\CMS\Core\Core\Environment; +use TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface; /** * Class BackendController @@ -39,16 +44,25 @@ */ class BackendController extends ActionController { - + /** + * @param ModuleTemplateFactory $moduleTemplateFactory + */ + public function __construct( + protected readonly ModuleTemplateFactory $moduleTemplateFactory + ) { + } + /** * First load action, will display information about the creation of a content element * or send the user to the right step of create the source extension * - * @return void * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException */ - public function indexAction() + public function indexAction(): ResponseInterface { + $moduleTemplate = $this->moduleTemplateFactory->create($this->request); + $moduleTemplate->setTitle('Dw Content Elements: Overview'); + /** @var IniProviderService $iniProviderService */ $iniProviderService = GeneralUtility::makeInstance(IniProviderService::class); @@ -61,61 +75,78 @@ public function indexAction() ) { // Check if source extension exists if (!is_dir(Environment::getPublicPath() . '/typo3conf/ext/dw_content_elements_source')) { - $this->forward('createSourceExt'); + return $this->redirect( + 'createSourceExt', + 'Backend', + 'dw_content_elements' + ); } else { - $this->forward('loadSourceExt'); + return $this->redirect( + 'loadSourceExt', + 'Backend', + 'dw_content_elements' + ); } } + return $moduleTemplate->renderResponse('Index'); } /** * Action for the create of the source extension * - * @return void + * * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException */ - public function createSourceExtAction() + public function createSourceExtAction(): ResponseInterface { + $moduleTemplate = $this->moduleTemplateFactory->create($this->request); + $moduleTemplate->setTitle('Dw Content Elements: Create source extension'); + if ($this->request->hasArgument('createSourceExt')) { /** * @var FileService $fileService */ - $fileService = $this->objectManager->get( - FileService::class - ); + $fileService = GeneralUtility::makeInstance(FileService::class); $fileService->setSourceExtensionDirectory( Environment::getPublicPath() . '/typo3conf/ext/dw_content_elements_source/' ); $success = $fileService->createSourceExt(); if ($success) { - $this->forward( + return $this->redirect( 'loadSourceExt', 'Backend', - null, - array( + 'dw_content_elements', + [ 'hasCreatedSourceExt' => true, - ) + ] ); } else { - $this->view->assign('createFail', true); + $moduleTemplate->assign('createFail', true); } } + + return $moduleTemplate->renderResponse('CreateSourceExt'); } /** * Action for the info to install the source extension at the extension manager * * @return void - * @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException + * @throws NoSuchArgumentException */ - public function loadSourceExtAction() + public function loadSourceExtAction(): ResponseInterface { + $moduleTemplate = $this->moduleTemplateFactory->create($this->request); + $moduleTemplate->setTitle('Dw Content Elements: Load source extension'); + $hasCreatedSourceExt = false; if ($this->request->hasArgument('hasCreatedSourceExt')) { $hasCreatedSourceExt = $this->request->getArgument('hasCreatedSourceExt'); } - $this->view->assign('hasCreatedSourceExt', $hasCreatedSourceExt); + + $moduleTemplate->assign('hasCreatedSourceExt', $hasCreatedSourceExt); + return $moduleTemplate->renderResponse('LoadSourceExt'); } } diff --git a/Classes/Controller/BaseController.php b/Classes/Controller/BaseController.php index e89ad61..e19122e 100755 --- a/Classes/Controller/BaseController.php +++ b/Classes/Controller/BaseController.php @@ -25,127 +25,21 @@ * * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ - use Denkwerk\DwContentElements\Service\IrreService; -use Denkwerk\DwContentElements\Utility\Paths; -use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; -use TYPO3\CMS\Extbase\Mvc\View\ViewInterface; -use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; -use TYPO3\CMS\Extbase\Annotation as Extbase; -use TYPO3Fluid\Fluid\View\Exception\InvalidTemplateResourceException; -use TYPO3Fluid\Fluid\View\TemplatePaths; /** * Class BaseController * @package Denkwerk\DwContentElements\Controller */ -class BaseController extends ActionController +abstract class BaseController implements SingletonInterface { - /** - * ReflectionClass - * - * @var \ReflectionClass - */ - protected $classReflection; - - /** - * ContentObject - * - * @var ContentObjectRenderer - */ - protected $contentObj; - - /** - * Data object - * - * @var mixed - */ - protected $data; - - /** - * IrreService - * - * @var \Denkwerk\DwContentElements\Service\IrreService - * @Extbase\Inject - */ - protected $irreService; - /** * @param IrreService $irreService */ - public function __construct(IrreService $irreService) - { - $this->irreService = $irreService; - } - - /** - * Initializeview - * - * @param ViewInterface $view The initializeview - * @return void - * @throws \ReflectionException - */ - protected function initializeView(ViewInterface $view) - { - $this->classReflection = new \ReflectionClass($this); - // @extensionScannerIgnoreLine - $this->contentObj = $this->configurationManager->getContentObject(); - $this->data = $this->contentObj->data; - $view->assign('data', $this->contentObj->data); - } - - /** - * This action will render the content element - * - * @return void - * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException - */ - public function renderAction() - { - // Try to load the action template path - try { - /** @var TemplatePaths $templatePathsContext */ - $templatePathsContext = $this->view->getTemplatePaths(); - - $actionFilePath = Paths::resolveFileInPaths( - $templatePathsContext->getTemplateRootPaths(), - substr($this->classReflection->getShortName(), 0, -10) . '/' . - ucfirst($this->contentObj->data['CType']), - $templatePathsContext->getFormat() - ); - } catch (InvalidTemplateResourceException $error) { - // Fallback try to load action template path from the templates folder of the extension - $actionFilePath = GeneralUtility::getFileAbsFileName( - 'typo3conf/ext/' . $this->request->getControllerExtensionKey() . - '/Resources/Private/Templates/' . substr($this->classReflection->getShortName(), 0, -10) . '/' . - ucfirst($this->contentObj->data['CType']) . '.' . $this->request->getFormat() - ); - - if (!is_file($actionFilePath)) { - throw new InvalidTemplateResourceException( - $error->getMessage() . ' Also not found in fallback location "$actionFilePath"', - 1225709595 - ); - } - } - - // Set the action template path - $this->view->setTemplatePathAndFilename($actionFilePath); - - if ($this->classReflection->hasMethod($this->contentObj->data['CType'] . 'Action')) { - $this->forward($this->contentObj->data['CType']); - } - } - - /** - * This action will render the content element without cache - * - * @return void - * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException - */ - public function nonCacheableRenderAction() - { - $this->renderAction(); + public function __construct( + protected readonly IrreService $irreService + ) { } } diff --git a/Classes/DataProcessing/ContentElementActionProcessor.php b/Classes/DataProcessing/ContentElementActionProcessor.php new file mode 100644 index 0000000..bea742b --- /dev/null +++ b/Classes/DataProcessing/ContentElementActionProcessor.php @@ -0,0 +1,88 @@ + + * + * All rights reserved + * + * This script is part of the TYPO3 project. The TYPO3 project is + * free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * The GNU General Public License can be found at + * http://www.gnu.org/copyleft/gpl.html. + * + * This script is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * This copyright notice MUST APPEAR in all copies of the script! + ***************************************************************/ +use T3docs\Examples\Domain\Repository\CategoryRepository; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; +use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface; + +/** + * Class ContentElementActionProcessor + * @package Denkwerk\DwContentElements\DataProcessing + */ +class ContentElementActionProcessor implements DataProcessorInterface +{ + /** + * This DataProcessor checks at the call whether in the setting "controllerActionClass" is set and + * whether this class has a function which is named the same as the current fluid "templateName". + * If there is a function with the same name, this is executed and the return value is passed to the view. + * + * @param ContentObjectRenderer $cObj The data of the content element or page + * @param array $contentObjectConfiguration The configuration of Content Object + * @param array $processorConfiguration The configuration of this processor + * @param array $processedData Key/value store of processed data (e.g. to be passed to a Fluid View) + * @return array the processed data as key/value store + */ + public function process( + ContentObjectRenderer $cObj, + array $contentObjectConfiguration, + array $processorConfiguration, + array $processedData + ) { + // Check possible typescript if condition + if (isset($processorConfiguration['if.']) && + !$cObj->checkIf($processorConfiguration['if.']) + ) { + return $processedData; + } + + // Execute function if class and methode exist + if (isset($processorConfiguration['controllerActionClass']) && + isset($contentObjectConfiguration['templateName']) && + isset($processedData['data']) && + class_exists(trim($processorConfiguration['controllerActionClass'])) === true && + method_exists( + trim($processorConfiguration['controllerActionClass']), + lcfirst($contentObjectConfiguration['templateName']) + ) === true + ) { + $controllerActionClass = GeneralUtility::makeInstance( + trim($processorConfiguration['controllerActionClass']) + ); + // $elementsController->e1102ThreeColumnTile($contentObj); + $contentElementVariable = $controllerActionClass->{lcfirst($contentObjectConfiguration['templateName'])}($processedData['data']); + + // Add result to view + if (is_array($contentElementVariable)) { + $processedData = $processedData + $contentElementVariable; + } + } + + return $processedData; + } +} diff --git a/Classes/Service/IniProviderService.php b/Classes/Service/IniProviderService.php index c6f0296..1e9e67b 100755 --- a/Classes/Service/IniProviderService.php +++ b/Classes/Service/IniProviderService.php @@ -26,7 +26,6 @@ * This copyright notice MUST APPEAR in all copies of the script! * **************************************************************/ -use Denkwerk\DwContentElementsSource\Controller\ElementsController; use TYPO3\CMS\Core\Configuration\ExtensionConfiguration; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -48,7 +47,7 @@ public function loadProvider() $providers = []; // Get global extension configurations - $configurations = isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dw_content_elements']) ?? null; + $configurations = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dw_content_elements'] ?? null; // Load custom provider extensions, if is set if (isset($configurations['providers']) && @@ -65,10 +64,6 @@ public function loadProvider() // Use as fallback the provider extension "dw_content_elements_source", if is load $providers['dw_content_elements_source'] = $this->mergeConfigurations( array( - 'pluginName' => 'ContentRenderer', - 'controllerActions' => array(ElementsController::class => 'render'), - 'nonCacheableControllerActions' => array(ElementsController::class => 'nonCacheableRender'), - 'namespace' => 'Denkwerk.DwContentElementsSource', 'elementsPath' => '/Configuration/Elements' ) ); diff --git a/Classes/Service/IniService.php b/Classes/Service/IniService.php index fd29227..262b738 100755 --- a/Classes/Service/IniService.php +++ b/Classes/Service/IniService.php @@ -39,7 +39,7 @@ class IniService { /** - * @var \Denkwerk\DwContentElements\Utility\TypoScriptParser $tsParser + * @var TypoScriptParser $tsParser */ private $tsParser; @@ -64,14 +64,16 @@ public function loadConfig($configFile) $result = false; $configFileAbsPath = Paths::concat( array( - realpath(Environment::getPublicPath()), + realpath(Environment::getProjectPath()), realpath($configFile), ) ); if (is_file($configFileAbsPath) === true) { $result = $this->tsParser->parseTypoScriptFile($configFileAbsPath); - $result['configFileAbsPath'] = $configFileAbsPath; + if (is_array($result)) { + $result['configFileAbsPath'] = $configFileAbsPath; + } } return $result; diff --git a/Classes/Service/InjectorService.php b/Classes/Service/InjectorService.php index 548b9f0..90ba09f 100644 --- a/Classes/Service/InjectorService.php +++ b/Classes/Service/InjectorService.php @@ -29,9 +29,11 @@ use Denkwerk\DwContentElements\Service\IniProviderService; use Denkwerk\DwContentElements\Service\IniService; use TYPO3\CMS\Core\Imaging\IconProvider\BitmapIconProvider; +use TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider; use TYPO3\CMS\Core\Imaging\IconRegistry; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Core\Utility\PathUtility; use TYPO3\CMS\Extbase\Utility\ExtensionUtility; /** @@ -143,7 +145,7 @@ public function injectTca() * * @return void */ - public function injectPluginConfiguration() + public function injectTypoScripConfiguration() { // Load all provider configurations as array $providers = $this->iniProviderService->loadProvider(); @@ -159,11 +161,11 @@ public function injectPluginConfiguration() $providerConfig ); - // Add plugin config of the content elements - $this->addPluginConfigForElements( + // Add rendering typoscript config of the content elements + $this->addRenderingConfigForElements( $contentElements, $providerNameCamelCase, - $providerConfig + $providerConfig['controllerActionClass'] ?? '' ); // Add content elements to the content elements wizard @@ -181,32 +183,21 @@ public function injectPluginConfiguration() } /** - * Add plugin config of the content elements + * Add rendering typoscript config of the content elements * * @param $contentElements - * @param $providerNameCamelCase - * @param $providerConfig + * @param string $providerNameCamelCase + * @param string $controllerActionClass * @return void */ - public function addPluginConfigForElements($contentElements, $providerNameCamelCase, $providerConfig) - { + public function addRenderingConfigForElements( + $contentElements, + string $providerNameCamelCase, + string $controllerActionClass = '' + ) { $typoScript = '[GLOBAL] '; - // Add extension plugin - ExtensionUtility::configurePlugin( - // unique plugin name - $providerConfig['namespace'], - $providerConfig['pluginName'], - // accessible controller-action-combinations - $providerConfig['controllerActions'], - // non-cachable controller-action-combinations (they must already be enabled) - (isset($providerConfig['nonCacheableControllerActions']) ? - $providerConfig['nonCacheableControllerActions'] : - array() - ) - ); - - // Add all content elements to wizards + // Add rendering to all content elements if (is_array($contentElements) && empty($contentElements) === false ) { @@ -214,32 +205,23 @@ public function addPluginConfigForElements($contentElements, $providerNameCamelC if (isset($elementConfig['title']) && isset($elementConfig['fields']) ) { - //Set rendering typoScript + // Set content element rendering typoScript $typoScript .= "\n - tt_content." . lcfirst($key) . - " < tt_content.list.20." . - strtolower($providerNameCamelCase) . "_" . strtolower($providerConfig['pluginName']) . " \n"; + tt_content {\n + " . lcfirst($key) . " =< lib.contentElement\n + " . lcfirst($key) . " {\n + templateName = " . ucfirst($key) . "\n" . + ( + trim($controllerActionClass) !== '' ? + "dataProcessing.10 = Denkwerk\DwContentElements\DataProcessing\ContentElementActionProcessor\n + dataProcessing.10 {\n + controllerActionClass = " . $controllerActionClass . "\n + }" : + "" + ) . " - $controllerActions = $providerConfig['controllerActions']; - - // Replace controller and actions with nonCacheable version - // if content element config "noCache" is true - if (isset($elementConfig['noCache']) && - (boolean)$elementConfig['noCache'] === true && - isset($providerConfig['nonCacheableControllerActions']) - ) { - $controllerActions = $providerConfig['nonCacheableControllerActions']; - } - - foreach ($controllerActions as $controller => $actions) { - $actionArray = explode(',', $actions); - foreach ($actionArray as $index => $action) { - $typoScript .= "tt_content." . - lcfirst($key) . ".switchableControllerActions." . - $controller . "." . ($index + 1) . " = " . - $action . " \n"; - } - } + }\n + }"; } } } @@ -283,19 +265,10 @@ public function addElementsToWizard(array $contentElements, $providerNameCamelCa $iconIdentifier = 'content-textpic'; // Registration the content element icon, if set - if ($elementConfig['icon']) { - /** @var IconRegistry $iconRegistry */ - $iconRegistry = GeneralUtility::makeInstance( - IconRegistry::class - ); + if (isset($elementConfig['icon']) && + $elementConfig['icon'] !== '' + ) { $iconIdentifier = 'dwc-' . lcfirst($key); - $iconRegistry->registerIcon( - $iconIdentifier, - BitmapIconProvider::class, - array( - 'source' => (string)$elementConfig['icon'], - ) - ); } // Add the icon to the content element config @@ -307,7 +280,8 @@ public function addElementsToWizard(array $contentElements, $providerNameCamelCa $providerNameCamelCase . '.elements.' . lcfirst($key) . ' { ' . $icon . ' title = ' . (string)$elementConfig['title'] . ' - description = ' . (string)$elementConfig['description'] . ' + description = ' . (isset($elementConfig['description']) ? + (string)$elementConfig['description'] : '') . ' tt_content_defValues.CType = ' . lcfirst($key) . ' }' ); @@ -332,4 +306,72 @@ function ($c) { $providerName ); } + + /** + * Creates the array with all content element icons for the icon registration in icon.php + * + * @return array + */ + public function generateIconConfig(): array + { + $icons = [ + 'dw-content-element-module-icon' => [ + 'provider' => SvgIconProvider::class, + 'source' => 'EXT:dw_content_elements/Resources/Public/Icons/Backend-Module-Icon.svg', + ], + ]; + + // Load all provider configurations as array + $providers = $this->iniProviderService->loadProvider(); + + if (count($providers) > 0) { + foreach ($providers as $provider => $providerConfig) { + + // Add content elements to the content elements wizard + if (isset($providerConfig['addElementsToWizard']) && + (bool)$providerConfig['addElementsToWizard'] === true + ) { + + // Generate camelcase version of the provider + $providerNameCamelCase = $this->getCamelCaseProviderName($provider); + + // Load all content elements configurations + $contentElements = $this->iniService->loadAllContentElementsConfig( + $provider, + $providerConfig + ); + + foreach ($contentElements as $key => $elementConfig) { + // Registration the content element icon, if set + if (isset($elementConfig['icon']) && + $elementConfig['icon'] !== '' + ) { + $iconProvider = BitmapIconProvider::class; + $filePath = $elementConfig['icon']; + + // If file not exists we need to set a default + $realFilePath = GeneralUtility::getFileAbsFileName($elementConfig['icon']); + if ($realFilePath === '' || + file_exists($realFilePath) === false + ) { + $filePath = 'EXT:dw_content_elements/Resources/Public/Icons/content-element-fallback.svg'; + } + + // Change icon provider to SVG on SVG icons + if (PathUtility::pathinfo($filePath, PATHINFO_EXTENSION) === 'svg') { + $iconProvider = SvgIconProvider::class; + } + + $icons['dwc-' . lcfirst($key)] = [ + 'provider' => $iconProvider, + 'source' => $filePath + ]; + } + } + } + } + } + + return $icons; + } } diff --git a/Classes/Service/IrreService.php b/Classes/Service/IrreService.php index 35c4b51..8c7c975 100755 --- a/Classes/Service/IrreService.php +++ b/Classes/Service/IrreService.php @@ -25,7 +25,7 @@ * * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ - +use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; use Denkwerk\DwContentElements\Utility\Logger; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\Query\QueryBuilder; @@ -34,6 +34,7 @@ use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction; use TYPO3\CMS\Core\Database\Query\Restriction\StartTimeRestriction; use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Extbase\Persistence\Repository; /** * Class IrreService @@ -45,12 +46,12 @@ class IrreService * Set data for Inline Relational Record Editing entry * If set the repositoryName the function will call the magic function "findByForeignUid" * - * @param \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $contentObj + * @param array $elementData data row of content element * @param string $tableName Name of the table * @param string $repositoryName Name of the repository if any repository exist. (Optional) * @return array */ - public static function getRelations($contentObj, $tableName, $repositoryName = '') + public static function getRelations($elementData, $tableName, $repositoryName = '') { $result = array(); @@ -65,15 +66,15 @@ public static function getRelations($contentObj, $tableName, $repositoryName = ' array_key_exists("foreign_uid", $fieldsInDatabase) ) { // If "$repositoryName" is not set. Get the table data by single select - if ($contentObj->data[$tableName] > 0 && + if ($elementData[$tableName] > 0 && empty($repositoryName) ) { - $foreignUid = $contentObj->data['uid']; - if (isset($contentObj->data['_LOCALIZED_UID'])) { - $foreignUid = $contentObj->data['_LOCALIZED_UID']; + $foreignUid = $elementData['uid']; + if (isset($elementData['_LOCALIZED_UID'])) { + $foreignUid = $elementData['_LOCALIZED_UID']; } - /** @var \TYPO3\CMS\Core\Database\Query\QueryBuilder $queryBuilder */ + /** @var QueryBuilder $queryBuilder */ $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable($tableName); @@ -86,31 +87,25 @@ public static function getRelations($contentObj, $tableName, $repositoryName = ' $rows = $queryBuilder ->select('*') ->from($tableName) - ->where('foreign_uid = ' . $foreignUid) - ->orderBy('sorting') - ->execute(); + ->where('foreign_uid = ' . $foreignUid)->orderBy('sorting')->executeQuery(); - foreach ($rows as $row) { + while ($row = $rows->fetchAssociative()) { // Get "tt_content" content elements of the relations if it exist a row "content_elements" - array_push($result, self::getContentElements($contentObj, $row, $tableName)); + array_push($result, self::getContentElements($row)); } } // Get the IRRE data by the repository magic function "findByForeignUid" - if ($contentObj->data[$tableName] > 0 && + if ($elementData[$tableName] > 0 && empty($repositoryName) === false ) { - $foreignUid = $contentObj->data['uid']; - if (isset($contentObj->data['_LOCALIZED_UID'])) { - $foreignUid = $contentObj->data['_LOCALIZED_UID']; + $foreignUid = $elementData['uid']; + if (isset($elementData['_LOCALIZED_UID'])) { + $foreignUid = $elementData['_LOCALIZED_UID']; } - /*** @var $extbaseObjectManager \TYPO3\CMS\Extbase\Object\ObjectManager */ - $extbaseObjectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance( - 'TYPO3\\CMS\\Extbase\\Object\\ObjectManager' - ); - /*** @var $repository \TYPO3\CMS\Extbase\Persistence\Repository */ - $repository = $extbaseObjectManager->get($repositoryName); + /** @var Repository $repository */ + $repository = GeneralUtility::makeInstance(Repository::class); // Get the table data by the given repository $rows = $repository->findByForeignUid($foreignUid); @@ -124,8 +119,8 @@ public static function getRelations($contentObj, $tableName, $repositoryName = ' Logger::simpleErrorLog( 'DWC: IRRE Service: Column "foreign_uid" not found on table "' . $tableName . '"', $tableName, - $contentObj->data['uid'], - $contentObj->data['pid'] + $elementData['uid'], + $elementData['pid'] ); } @@ -137,12 +132,12 @@ public static function getRelations($contentObj, $tableName, $repositoryName = ' * @deprecated since 1.2 will be removed in 2.0 * Please use the "getRelations($repositoryName)" function * - * @param \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $contentObj + * @param array $elementData data row of content element * @param array $data * @param string $parentTable * @return array */ - public static function getContentElements($contentObj, $data, $parentTable) + public static function getContentElements($data) { if (is_array($data) ) { @@ -162,9 +157,7 @@ public static function getContentElements($contentObj, $data, $parentTable) $elementRows = $queryBuilder ->select('uid') ->from('tt_content') - ->where('foreign_uid = ' . $data['uid']) - ->orderBy('sorting') - ->execute(); + ->where('foreign_uid = ' . $data['uid'])->orderBy('sorting')->executeQuery(); $contentElements = array(); foreach ($elementRows as $elementRow) { diff --git a/Classes/UserFunc/Tca.php b/Classes/UserFunc/Tca.php index 12ca64e..a788ed9 100644 --- a/Classes/UserFunc/Tca.php +++ b/Classes/UserFunc/Tca.php @@ -65,7 +65,11 @@ public function __construct() public function setTtContentTitle(&$params) { // Set the title by using the header field like the TYPO3 default settings - $params['title'] = $params['row']['header']; + if (is_array($params) && + isset($params['row']['header']) + ) { + $params['title'] = $params['row']['header']; + } // Load all provider configurations as array $providers = $this->iniProviderService->loadProvider(); @@ -110,9 +114,7 @@ public function setTtContentTitle(&$params) $result = $queryBuilder ->select(...$previewListFields) ->from('tt_content') - ->where('uid=' . $params['row']['uid']) - ->setMaxResults(1) - ->execute(); + ->where('uid=' . $params['row']['uid'])->setMaxResults(1)->executeQuery(); $row = $result->fetch(); if (empty($row) === false) { diff --git a/Classes/Utility/Paths.php b/Classes/Utility/Paths.php index db728a2..affaf5d 100755 --- a/Classes/Utility/Paths.php +++ b/Classes/Utility/Paths.php @@ -132,22 +132,25 @@ public static function concat() */ public static function getAllDirFiles($dir, &$results = array()) { - $files = scandir($dir); - - foreach ($files as $key => $value) { - $path = realpath($dir . DIRECTORY_SEPARATOR . $value); - - if (is_file($path)) { - //Set the filename without extension as key - $results[str_replace( - '.' . pathinfo($path, PATHINFO_EXTENSION), - '', - $value - )] = $path; - } elseif (is_dir($path) && - !in_array($value, array(".", "..")) - ) { - self::getAllDirFiles($path, $results); + $results = []; + if (is_dir(realpath($dir))) { + $files = scandir($dir); + + foreach ($files as $key => $value) { + $path = realpath($dir . DIRECTORY_SEPARATOR . $value); + + if (is_file($path)) { + //Set the filename without extension as key + $results[str_replace( + '.' . pathinfo($path, PATHINFO_EXTENSION), + '', + $value + )] = $path; + } elseif (is_dir($path) && + !in_array($value, array(".", "..")) + ) { + self::getAllDirFiles($path, $results); + } } } diff --git a/Classes/Utility/TypoScriptParser.php b/Classes/Utility/TypoScriptParser.php index 38d65bc..1097b72 100644 --- a/Classes/Utility/TypoScriptParser.php +++ b/Classes/Utility/TypoScriptParser.php @@ -71,7 +71,10 @@ public function parseTypoScriptFile($filePath) $result = false; if (is_file($filePath) && - pathinfo($filePath, PATHINFO_EXTENSION) === 'ts' + ( + pathinfo($filePath, PATHINFO_EXTENSION) === 'ts' || + pathinfo($filePath, PATHINFO_EXTENSION) === 'typoscript' + ) ) { $fileContent = file_get_contents($filePath); diff --git a/Classes/Xclass/CaseContentObject.php b/Classes/Xclass/CaseContentObject.php deleted file mode 100644 index be61d6d..0000000 --- a/Classes/Xclass/CaseContentObject.php +++ /dev/null @@ -1,141 +0,0 @@ -iniService = GeneralUtility::makeInstance(IniService::class); - $this->iniProviderService = GeneralUtility::makeInstance(IniProviderService::class); - } - - /** - * Rendering the cObject, CASE - * - * @param array $conf Array of TypoScript properties - * @return string Output - */ - public function render($conf = array()) - { - - if (!empty($conf['if.']) && !$this->cObj->checkIf($conf['if.'])) { - return ''; - } - - $setCurrent = $this->cObj->stdWrapValue('setCurrent', $conf ?? []); - if ($setCurrent) { - $this->cObj->data[$this->cObj->currentValKey] = $setCurrent; - } - $key = $this->cObj->stdWrapValue('key', $conf, null); - - /** - * ============================================HOTFIX BEGIN=================================================== - * - * Only a hotfix for the bug: Missing rendering configuration for the content elements - * Die Rendering Definition sollte unter $GLOBALS['TSFE']->tmpl->setup['tt_content.'] stehen. - * Es kann unter nicht geklärten bedingungen vorkommen das diese Konfiguration nicht im - * Cache ist oder geladen wird - * - * @ToDo: Remove Hotfix or refactor - */ - if (array_key_exists($key, $conf) === false && - empty($key) === false - ) { - // Load all provider configurations as array - $providers = $this->iniProviderService->loadProvider(); - - // Load all content elements config files - if (count($providers) > 0) { - foreach ($providers as $provider => $providerConfig) { - $providerElementsConfigFiles = $this->iniService->loadAllContentElementsConfigFiles( - $provider, - $providerConfig - ); - - //If it is a content element of the extension dw_content_elements - if (isset($providerElementsConfigFiles[ucfirst($key)])) { - $namespaceParts = explode('.', $providerConfig['namespace'], 2); - $controllerActions = array(); - - foreach ($providerConfig['controllerActions'] as $controller => $actions) { - $actionsArray = explode(',', $actions); - $controllerActions[$controller . '.'] = array(); - foreach ($actionsArray as $index => $action) { - $controllerActions[$controller . '.'][$index + 1] = $action; - } - } - - //Set missing configuration - $conf[$key] = 'USER'; - $conf[$key . '.'] = array( - 'userFunc' => 'TYPO3\CMS\Extbase\Core\Bootstrap->run', - 'extensionName' => $namespaceParts[1], - 'pluginName' => $providerConfig['pluginName'], - 'vendorName' => $namespaceParts[0], - 'switchableControllerActions.' => $controllerActions, - ); - - //Set the missing rendering configuration in the global template service variable - $GLOBALS['TSFE']->tmpl->setup['tt_content.'] = $conf; - } - } - } - } - //=============================================HOTFIX ENDE==================================================== - - $key = isset($conf[$key]) && (string)$conf[$key] !== '' ? $key : 'default'; - // If no "default" property is available, then an empty string is returned - if ($key === 'default' && !isset($conf['default'])) { - $theValue = ''; - } else { - $theValue = $this->cObj->cObjGetSingle($conf[$key], $conf[$key . '.'] ?? [], $key); - } - if (isset($conf['stdWrap.'])) { - $theValue = $this->cObj->stdWrap($theValue, $conf['stdWrap.']); - } - - return $theValue; - } -} diff --git a/Configuration/Backend/Modules.php b/Configuration/Backend/Modules.php new file mode 100644 index 0000000..8390511 --- /dev/null +++ b/Configuration/Backend/Modules.php @@ -0,0 +1,19 @@ + [ + 'parent' => 'system', + 'access' => 'user', + 'workspaces' => 'live', + 'path' => '/module/dwcontentelements', + 'labels' => 'LLL:EXT:dw_content_elements/Resources/Private/Language/locallang_mod.xlf', + 'iconIdentifier' => 'dw-content-element-module-icon', + 'extensionName' => 'DwContentElements', + 'controllerActions' => [ + \Denkwerk\DwContentElements\Controller\BackendController::class => [ + 'index', 'createSourceExt', 'loadSourceExt', + ], + ], + ], +]; diff --git a/Configuration/Icons.php b/Configuration/Icons.php new file mode 100644 index 0000000..1251c28 --- /dev/null +++ b/Configuration/Icons.php @@ -0,0 +1,9 @@ +generateIconConfig(); diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index e849851..cfbd7ec 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -3,10 +3,18 @@ services: autowire: true autoconfigure: true public: false - + Denkwerk\DwContentElements\: - resource: '../Classes/*' - exclude: '../Classes/Domain/Model/*' + resource: '../Classes/*' + + Denkwerk\DwContentElements\Backend\EventListener\PreviewEventListener: + tags: + - name: event.listener + identifier: 'dw-content-elements/preview-rendering' + + Denkwerk\DwContentElements\Controller\BaseController: + arguments: + $irreService: '@Denkwerk\DwContentElements\Service\IrreService' Denkwerk\DwContentElements\Service\FileService: public: true @@ -31,3 +39,5 @@ services: Denkwerk\DwContentElements\Service\UrlService: public: true shared: true + + diff --git a/Configuration/TCA/Overrides/pages.php b/Configuration/TCA/Overrides/pages.php index c7cc7d2..97e3968 100644 --- a/Configuration/TCA/Overrides/pages.php +++ b/Configuration/TCA/Overrides/pages.php @@ -1,6 +1,6 @@ 'MyContentElements', 'pluginCategory' => 'My own content elements', - 'controllerActions' => ['Elements' => 'render'], - 'nonCacheableControllerActions' => ['Elements' => 'nonCacheableRender'], - 'namespace' => 'Denkwerk.MyContentElements', + 'controllerActionClass' => null, 'elementsPath' => '/Configuration/Elements', - 'addElementsToWizard' => TRUE, + 'addElementsToWizard' => true, 'elementWizardTabTitle' => 'My content elements' ]; @@ -26,11 +23,9 @@ $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dw_content_elements']['providers']['my_c There are some mandatory options: -- `pluginName`: The name of the plugin - `pluginCategory`: The plugins category (optgroup) -- `controllerActions`: The controller actions -- `nonCacheableControllerActions`: The noncachable controller actions, will use if the content element has "noCache=1" -- `namespace`: The plugins namespace, vendor and plugin namespace separated by dots +- `controllerActionClass`: The class that will be loaded by the TODO data processor to execute the function with the name of the content item to be rendered +- `elementsPath`: The path to the content elements configuration - `addElementsToWizard`: If true, add a tab with the elements of this provider into the new elements wizard - `elementWizardTabTitle`: The label of the new elements wizard tab diff --git a/Resources/Private/Language/locallang.xlf b/Resources/Private/Language/locallang.xlf index fef12b0..799bb29 100644 --- a/Resources/Private/Language/locallang.xlf +++ b/Resources/Private/Language/locallang.xlf @@ -21,18 +21,17 @@ -

  • Die Config-Datei wird unter /typo3conf/ext/dw_content_elements_source/Configuration/Elements/E1000MyContentElement.ts angelegt.
  • +
  • Die Config-Datei wird unter /packages/dw_content_elements_source/Configuration/Elements/E1000MyContentElement.ts angelegt.
  • Hier werden alle Konfigurationen gesetzt: Titel Beschreibung, Preview icon, Datenbankfelder und overwriteShowItem.
  • Beispiel für eine Config-Datei:
    title = E1000 My Content Element
    description = Content Element with header, subheader
    - icon = ../../typo3conf/ext/dw_content_elements_source/Resources/Public/Thumbnails/E1000MyContentElement_icon.png
    + icon = EXT:dw_content_elements_source/Resources/Public/Thumbnails/E1000MyContentElement_icon.png
    fields = header, subheader
    overWriteShowitem = 0
    previewFields = header, subheader
    previewListFields = header, subheader
    - noCache = 0
  • @@ -46,7 +45,7 @@ -
  • Das FLUID-Template erhält den gleichen Namen wie die Conig-Datei und wird unter /typo3conf/ext/dw_content_elements_source/Resources/Private/Templates/Elements/E1000MyContentElement.html abgelegt
  • +
  • Das FLUID-Template erhält den gleichen Namen wie die Conig-Datei und wird unter /packages/dw_content_elements_source/Resources/Private/Templates/Elements/E1000MyContentElement.html abgelegt
  • Das FLUID-Template enthält das Markup zur Frontend-Ausgabe. Die Daten der eingestellen Felder können über die Variabel 'data' ausgelesen (bspw. {data.header}.
  • Beispiel für ein FLUID-Template:
    %0s @@ -65,11 +64,10 @@ @@ -83,12 +81,28 @@ -
  • TypoScript settings und globale Constanten werden in der setup.txt verwaltet (/typo3conf/ext/dw_content_elements_source/Configuration/TypoScript/setup.txt eintragen).
  • +
  • TypoScript settings und globale Constanten werden in der setup.txt verwaltet (/packages/dw_content_elements_source/Configuration/TypoScript/setup.txt eintragen).
  • Im FLUID-Template können diese mit der Variable "settings" abgefragt werden.
  • ]]> + + Extension Settings + + + + +
  • pluginCategory: The plugins category (optgroup) for the CType Select.
  • +
  • controllerActionClass: The class that will be loaded by the TODO data processor to execute the function with the name of the content item to be rendered
  • +
  • elementsPath: The path to the content elements configuration
  • +
  • addElementsToWizard: If true, add a tab with the elements of this provider into the new elements wizard
  • +
  • elementWizardTabTitle: The label of the new elements wizard tab
  • + + ]]> + +
    diff --git a/Resources/Private/Language/locallang_db.xlf b/Resources/Private/Language/locallang_db.xlf index 464802d..135c7f1 100755 --- a/Resources/Private/Language/locallang_db.xlf +++ b/Resources/Private/Language/locallang_db.xlf @@ -9,17 +9,6 @@ Additional fields - - - Dw Content Elements - - - Dw Content Elements - - - Dashboard for Dw Content Elements - - diff --git a/Resources/Private/Language/locallang_mod.xlf b/Resources/Private/Language/locallang_mod.xlf new file mode 100644 index 0000000..cf6c559 --- /dev/null +++ b/Resources/Private/Language/locallang_mod.xlf @@ -0,0 +1,20 @@ + + + +
    + + + + Dw Content Elements + + + Dw Content Elements + + + Dashboard for Dw Content Elements + + + + + + diff --git a/Resources/Private/Layouts/BackendDefault.html b/Resources/Private/Layouts/BackendDefault.html deleted file mode 100644 index 35d2a2c..0000000 --- a/Resources/Private/Layouts/BackendDefault.html +++ /dev/null @@ -1,32 +0,0 @@ - -
    -
    -
    -
    - - -
    - -
    - - -
    -
    - - -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    diff --git a/Resources/Private/SourceExt/Classes/Controller/ElementsController.php b/Resources/Private/SourceExt/Classes/Controller/ElementsController.php index 6bc8788..a0441ab 100644 --- a/Resources/Private/SourceExt/Classes/Controller/ElementsController.php +++ b/Resources/Private/SourceExt/Classes/Controller/ElementsController.php @@ -24,7 +24,7 @@ * * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ - +use Psr\Http\Message\ResponseInterface; use Denkwerk\DwContentElements\Controller\BaseController; /** @@ -33,18 +33,16 @@ */ class ElementsController extends BaseController { - /** - * e1000ListAction + * e1000List */ - public function e1000ListAction() + public function e1000List(array $elementData): array { - $this->view->assign( - 'irreRelations', - $this->irreService->getRelations( - $this->contentObj, + return [ + 'irreRelations' => $this->irreService->getRelations( + $elementData, 'tx_dwcontentelementssource_domain_model_listitem' ) - ); + ]; } } diff --git a/Resources/Private/SourceExt/Configuration/Elements/E1000List.ts b/Resources/Private/SourceExt/Configuration/Elements/E1000List.ts index ed5420e..48c426f 100644 --- a/Resources/Private/SourceExt/Configuration/Elements/E1000List.ts +++ b/Resources/Private/SourceExt/Configuration/Elements/E1000List.ts @@ -4,5 +4,4 @@ icon = EXT:dw_content_elements_source/Resources/Public/Thumbnails/E1000List.png fields = --palette--;Headline;headerText, tx_dwcontentelementssource_domain_model_listitem overWriteShowitem = 0 previewFields = tx_dwc_headline, subheader -previewListFields = tx_dwc_headline, subheader -noCache=0 \ No newline at end of file +previewListFields = tx_dwc_headline, subheader \ No newline at end of file diff --git a/Resources/Private/SourceExt/Configuration/Services.yaml b/Resources/Private/SourceExt/Configuration/Services.yaml new file mode 100644 index 0000000..3cc5b55 --- /dev/null +++ b/Resources/Private/SourceExt/Configuration/Services.yaml @@ -0,0 +1,8 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: false + + Denkwerk\DwContentElementsSource\: + resource: '../Classes/*' diff --git a/Resources/Private/SourceExt/Configuration/TCA/Overrides/sys_template.php b/Resources/Private/SourceExt/Configuration/TCA/Overrides/sys_template.php new file mode 100644 index 0000000..2613495 --- /dev/null +++ b/Resources/Private/SourceExt/Configuration/TCA/Overrides/sys_template.php @@ -0,0 +1,13 @@ + 'headline', 'tstamp' => 'tstamp', 'crdate' => 'crdate', - 'cruser_id' => 'cruser_id', - 'dividers2tabs' => true, 'hideTable' => true, 'sortby' => 'sorting', - 'versioningWS' => 2, - 'versioning_followPages' => true, + 'versioningWS' => true, 'origUid' => 't3_origuid', 'languageField' => 'sys_language_uid', 'transOrigPointerField' => 'l10n_parent', @@ -58,15 +55,15 @@ 'starttime' => 'starttime', 'endtime' => 'endtime', ), + 'security' => [ + 'ignorePageTypeRestriction' => true, + ], 'searchFields' => 'headline, text', 'iconfile' => 'EXT:dw_content_elements_source/Resources/Public/Icons/IRRE.gif' ), - 'interface' => array( - 'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, headline, text', - ), 'types' => array( '1' => array('showitem' => 'sys_language_uid, l10n_parent, l10n_diffsource, headline, text, - --div--;LLL:EXT:cms/locallang_ttc.xlf:tabs.access,starttime, endtime'), + --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.access,starttime, endtime'), ), 'palettes' => array( '1' => array('showitem' => ''), @@ -74,27 +71,15 @@ 'columns' => array( 'sys_language_uid' => array( 'exclude' => 1, - 'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.language', - 'config' => [ - 'type' => 'select', - 'renderType' => 'selectSingle', - 'special' => 'languages', - 'items' => [ - [ - 'LLL:EXT:lang/Resources/Private/Language/locallang_general.xlf:LGL.allLanguages', - -1, - 'flags-multiple' - ], - ], - 'default' => 0, - ] + 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language', + 'config' => ['type' => 'language'] ), 'l10n_parent' => array( 'displayCond' => 'FIELD:sys_language_uid:>:0', - 'exclude' => 1, - 'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.l18n_parent', + 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent', 'config' => array( 'type' => 'select', + 'renderType' => 'selectSingle', 'items' => array( array('', 0), ), @@ -110,7 +95,7 @@ ), ), 't3ver_label' => array( - 'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.versionLabel', + 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.versionLabel', 'config' => array( 'type' => 'input', 'size' => 30, @@ -119,41 +104,41 @@ ), 'hidden' => array( 'exclude' => 1, - 'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.hidden', + 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.hidden', 'config' => array( 'type' => 'check', ), ), 'starttime' => array( 'exclude' => 1, - 'l10n_mode' => 'mergeIfNotBlank', - 'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.starttime', + 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.starttime', 'config' => array( 'type' => 'input', 'size' => 13, - 'max' => 20, 'eval' => 'datetime', 'checkbox' => 0, 'default' => 0, 'range' => array( 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')) ), + 'renderType' => 'inputDateTime', + ['behaviour' => ['allowLanguageSynchronization' => true]], ), ), 'endtime' => array( 'exclude' => 1, - 'l10n_mode' => 'mergeIfNotBlank', - 'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.endtime', + 'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.endtime', 'config' => array( 'type' => 'input', 'size' => 13, - 'max' => 20, 'eval' => 'datetime', 'checkbox' => 0, 'default' => 0, 'range' => array( 'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y')) ), + 'renderType' => 'inputDateTime', + ['behaviour' => ['allowLanguageSynchronization' => true]], ), ), 'headline' => array( @@ -162,7 +147,8 @@ 'config' => array( 'type' => 'input', 'size' => 30, - 'eval' => 'trim,required' + 'eval' => 'trim', + 'required' => true ), ), 'text' => array( @@ -172,9 +158,10 @@ 'type' => 'text', 'cols' => '40', 'rows' => '15', - 'eval' => 'trim' - ), - 'defaultExtras' => 'richtext:rte_transform[flag=rte_enabled|mode=ts_css]' + 'eval' => 'trim', + 'enableRichtext' => true, + 'richtextConfiguration' => 'default' + ) ), ), ]; diff --git a/Resources/Private/SourceExt/Configuration/TypoScript/constants.txt b/Resources/Private/SourceExt/Configuration/TypoScript/constants.typoscript similarity index 100% rename from Resources/Private/SourceExt/Configuration/TypoScript/constants.txt rename to Resources/Private/SourceExt/Configuration/TypoScript/constants.typoscript diff --git a/Resources/Private/SourceExt/Configuration/TypoScript/setup.txt b/Resources/Private/SourceExt/Configuration/TypoScript/setup.txt deleted file mode 100644 index 72e9ca4..0000000 --- a/Resources/Private/SourceExt/Configuration/TypoScript/setup.txt +++ /dev/null @@ -1,3 +0,0 @@ -plugin.tx_dwcontentelementssource.settings { - -} \ No newline at end of file diff --git a/Resources/Private/SourceExt/Configuration/TypoScript/setup.typoscript b/Resources/Private/SourceExt/Configuration/TypoScript/setup.typoscript new file mode 100644 index 0000000..39820ad --- /dev/null +++ b/Resources/Private/SourceExt/Configuration/TypoScript/setup.typoscript @@ -0,0 +1,19 @@ +# ================================ BEGIN: Configuration for content item template paths ================================ +lib.contentElement { + templateRootPaths { + 300 = EXT:dw_content_elements_source/Resources/Private/Templates/ + } + partialRootPaths { + 300 = EXT:dw_content_elements_source/Resources/Private/Partials/ + } + layoutRootPaths { + 300 = EXT:dw_content_elements_source/Resources/Private/Layouts/ + } + settings { + + } +} +# ================================= END: Configuration for content item template paths ================================= + +plugin.tx_dwcontentelementssource.settings < lib.contentElement.settings +module.tx_dwcontentelementssource.settings < lib.contentElement.settings \ No newline at end of file diff --git a/Resources/Private/SourceExt/Resources/Private/Layouts/Default.html b/Resources/Private/SourceExt/Resources/Private/Layouts/Default.html index 24f730c..2d3c7af 100644 --- a/Resources/Private/SourceExt/Resources/Private/Layouts/Default.html +++ b/Resources/Private/SourceExt/Resources/Private/Layouts/Default.html @@ -1 +1 @@ - + diff --git a/Resources/Private/SourceExt/Resources/Private/Partials/Elements/E1000List/Sections.html b/Resources/Private/SourceExt/Resources/Private/Partials/E1000List/Sections.html similarity index 100% rename from Resources/Private/SourceExt/Resources/Private/Partials/Elements/E1000List/Sections.html rename to Resources/Private/SourceExt/Resources/Private/Partials/E1000List/Sections.html diff --git a/Resources/Private/SourceExt/Resources/Private/Templates/Elements/E1000List.html b/Resources/Private/SourceExt/Resources/Private/Templates/E1000List.html similarity index 98% rename from Resources/Private/SourceExt/Resources/Private/Templates/Elements/E1000List.html rename to Resources/Private/SourceExt/Resources/Private/Templates/E1000List.html index 1711dc0..9c7722e 100644 --- a/Resources/Private/SourceExt/Resources/Private/Templates/Elements/E1000List.html +++ b/Resources/Private/SourceExt/Resources/Private/Templates/E1000List.html @@ -8,7 +8,7 @@ - +
    diff --git a/Resources/Private/SourceExt/Resources/Private/Templates/Elements/Render.html b/Resources/Private/SourceExt/Resources/Private/Templates/Elements/Render.html deleted file mode 100644 index a6d155d..0000000 --- a/Resources/Private/SourceExt/Resources/Private/Templates/Elements/Render.html +++ /dev/null @@ -1 +0,0 @@ -Fallback view for render action. This view should never be rendered. \ No newline at end of file diff --git a/Resources/Private/SourceExt/composer.json b/Resources/Private/SourceExt/composer.json index 057f3bf..38a0b1d 100644 --- a/Resources/Private/SourceExt/composer.json +++ b/Resources/Private/SourceExt/composer.json @@ -1,10 +1,11 @@ { - "name": "dw-typo3/dw-content-elements_source", + "name": "dw-typo3/dw-content-elements-source", "type": "typo3-cms-extension", - "version": "1.0.15", + "version": "1.1.0", "description": "Custom content elements source extension", "require": { - "typo3/cms-core": ">=8.7,<10.4.99", + "typo3/cms-core": ">=12.4.0,<12.4.99", + "typo3/cms-fluid-styled-content": ">=12.4.0,<12.4.99", "dw-typo3/dw-content-elements": "*" }, "autoload": { @@ -12,6 +13,11 @@ "Denkwerk\\DwContentElementsSource\\": "Classes" } }, + "extra": { + "typo3/cms": { + "extension-key": "dw_content_elements_source" + } + }, "authors": [ { "name": "Sascha Zander", diff --git a/Resources/Private/SourceExt/ext_emconf.php b/Resources/Private/SourceExt/ext_emconf.php index a684aa1..23aa725 100644 --- a/Resources/Private/SourceExt/ext_emconf.php +++ b/Resources/Private/SourceExt/ext_emconf.php @@ -12,27 +12,16 @@ 'title' => 'Content Elements Source', 'description' => 'This extension included your created content elements.', 'category' => 'misc', - 'shy' => 0, - 'version' => '1.0.15', - 'dependencies' => 'cms,extbase', - 'conflicts' => '', - 'loadOrder' => '', - 'module' => '', + 'version' => '1.1.0', 'state' => 'stable', - 'uploadfolder' => 0, - 'createDirs' => '', - 'modify_tables' => '', - 'clearcacheonload' => 1, - 'lockType' => '', + 'clearCacheOnLoad' => true, 'author' => 'Sascha Zander', 'author_email' => 'sascha.zander@denkwerk.com', 'author_company' => '', - 'CGLcompliance' => '', - 'CGLcompliance_note' => '', - 'priority' => 'bottom', 'constraints' => array( 'depends' => array( - 'typo3' => '8.7.0-10.4.99', + 'typo3' => '12.4.0-12.4.99', + 'fluid_styled_content' => '12.4.0-12.4.99', 'cms' => '', 'extbase' => '', 'dw_content_elements' => '', @@ -41,5 +30,4 @@ 'suggests' => array(), ), '_md5_values_when_last_written' => 'a:0:{}', - 'suggests' => array(), ); diff --git a/Resources/Private/SourceExt/ext_tables.php b/Resources/Private/SourceExt/ext_tables.php deleted file mode 100644 index 134c0de..0000000 --- a/Resources/Private/SourceExt/ext_tables.php +++ /dev/null @@ -1,23 +0,0 @@ - - + -

    +

    -

    +

    -

    -

    +

    +

    - +
    diff --git a/Resources/Private/Templates/Backend/Index.html b/Resources/Private/Templates/Backend/Index.html index c4f9329..7ee128b 100644 --- a/Resources/Private/Templates/Backend/Index.html +++ b/Resources/Private/Templates/Backend/Index.html @@ -1,38 +1,33 @@ - + -

    +

    -

    +

    -

    +

    -

    - +

    + -

    +

    -

    - +

    + -

    - +

    + - -

    ToDos

    -
      -
    • Layout anpassen (Weiche für TYPO3 V6.2 und V7.4).
    • -
    • Texte überarbeiten und mindestens noch ins Englische übersetzen.
    • -
    • Dokumentation mit allen einstellungs möglichkeiten erstellen.
    • -
    -
    +

    +
    diff --git a/Resources/Private/Templates/Backend/LoadSourceExt.html b/Resources/Private/Templates/Backend/LoadSourceExt.html index c9294e4..2b275f2 100644 --- a/Resources/Private/Templates/Backend/LoadSourceExt.html +++ b/Resources/Private/Templates/Backend/LoadSourceExt.html @@ -1,25 +1,25 @@ - + -

    +

    -

    +

    -

    -

    +

    +

      -
    • -
    • -
    • -
    • +
    • +
    • +
    • +
    -

    - +

    +
    \ No newline at end of file diff --git a/Resources/Public/Backend/Images/Documentation/example_element_template.png b/Resources/Public/Backend/Images/Documentation/example_element_template.png index d164ed7..fb03aad 100644 Binary files a/Resources/Public/Backend/Images/Documentation/example_element_template.png and b/Resources/Public/Backend/Images/Documentation/example_element_template.png differ diff --git a/Resources/Public/Icons/Backend-Module-Icon.svg b/Resources/Public/Icons/Backend-Module-Icon.svg new file mode 100644 index 0000000..b69bedd --- /dev/null +++ b/Resources/Public/Icons/Backend-Module-Icon.svg @@ -0,0 +1,47 @@ + + + + +Created by potrace 1.11, written by Peter Selinger 2001-2013 + + + + + + + diff --git a/Resources/Public/Icons/Extension.svg b/Resources/Public/Icons/Extension.svg new file mode 100644 index 0000000..5876c30 --- /dev/null +++ b/Resources/Public/Icons/Extension.svg @@ -0,0 +1,46 @@ + + + + +Created by potrace 1.11, written by Peter Selinger 2001-2013 + + + + + + diff --git a/Resources/Public/Icons/content-element-fallback.svg b/Resources/Public/Icons/content-element-fallback.svg new file mode 100644 index 0000000..2bed5cf --- /dev/null +++ b/Resources/Public/Icons/content-element-fallback.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/composer.json b/composer.json index 169a10b..a685980 100644 --- a/composer.json +++ b/composer.json @@ -1,11 +1,12 @@ { "name": "dw-typo3/dw-content-elements", "type": "typo3-cms-extension", - "version": "2.2.1", + "version": "12.0.0", "description": "Custom content elements builder", "homepage": "https://github.com/Digi92/dw_content_elements", "require": { - "typo3/minimal": "^11.5" + "typo3/cms-core": "^12.4", + "typo3/cms-fluid-styled-content": "^12.4" }, "autoload": { "psr-4": { diff --git a/ext_conf_template.txt b/ext_conf_template.txt index 93c0801..4f29f94 100644 --- a/ext_conf_template.txt +++ b/ext_conf_template.txt @@ -5,4 +5,7 @@ addElementsToWizard = 1 elementWizardTabTitle = Content Elements # cat=general/paths; type=input; label=Add the plugins category (optgroup) title -pluginCategory = LLL:EXT:dw_content_elements/Resources/Private/Language/locallang_db.xlf:mlang_tabs_tab \ No newline at end of file +pluginCategory = LLL:EXT:dw_content_elements/Resources/Private/Language/locallang_db.xlf:mlang_tabs_tab + +# cat=general/paths; type=input; label=The class that will be loaded by the TODO data processor to execute the function with the name of the content item to be rendered +controllerActionClass = \ No newline at end of file diff --git a/ext_emconf.php b/ext_emconf.php index b91400b..e67c22a 100755 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -12,32 +12,20 @@ 'title' => 'Content Elements', 'description' => 'Custom content elements', 'category' => 'misc', - 'shy' => 0, - 'version' => '2.2.1', - 'dependencies' => 'cms,extbase', - 'conflicts' => '', - 'loadOrder' => '', - 'module' => '', + 'version' => '12.0.0', 'state' => 'stable', - 'uploadfolder' => 0, - 'createDirs' => '', - 'modify_tables' => '', - 'clearcacheonload' => 1, - 'lockType' => '', + 'clearCacheOnLoad' => true, 'author' => 'Sascha Zander', 'author_email' => 'sascha.zander@denkwerk.com', 'author_company' => '', - 'CGLcompliance' => '', - 'CGLcompliance_note' => '', - 'priority' => 'top', 'constraints' => array( 'depends' => array( - 'typo3' => '10.4.1-11.5.99', + 'typo3' => '12.4.1-12.4.99', + 'fluid_styled_content' => '12.4.1-12.4.99', 'extbase' => '', ), 'conflicts' => array(), 'suggests' => array(), ), '_md5_values_when_last_written' => 'a:0:{}', - 'suggests' => array(), ); diff --git a/ext_icon.png b/ext_icon.png deleted file mode 100644 index 542ae50..0000000 Binary files a/ext_icon.png and /dev/null differ diff --git a/ext_localconf.php b/ext_localconf.php index 28d5f4c..c8cf047 100755 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -1,23 +1,14 @@ tmpl->setup['tt_content.'] stehen. - * Es kann unter nicht geklärten bedingungen vorkommen das diese Konfiguration nicht im Cache ist oder geladen wird - * - * @ToDo: Remove Hotfix or refactor - */ -$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['TYPO3\\CMS\\Frontend\\ContentObject\\CaseContentObject'] = array( - 'className' => 'Denkwerk\\DwContentElements\\Xclass\\CaseContentObject', -); - +### - ### // Override preview in the page view -$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem']['dw_content_elements'] = - 'Denkwerk\\DwContentElements\\Hooks\\PageLayoutViewDrawItemHook'; +//$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem']['dw_content_elements'] = +// \Denkwerk\DwContentElements\Hooks\PageLayoutViewDrawItemHook::class; +### - ### // Override preview in the list view if (isset($GLOBALS['TCA']['tt_content']) && !isset($GLOBALS['TCA']['tt_content']['ctrl']['label_userFunc'])) { @@ -25,6 +16,6 @@ 'Denkwerk\\DwContentElements\\UserFunc\\Tca->setTtContentTitle'; } -// Register content element plugins +// Register content element $injectorService = new \Denkwerk\DwContentElements\Service\InjectorService(); -$injectorService->injectPluginConfiguration(); +$injectorService->injectTypoScripConfiguration(); diff --git a/ext_tables.php b/ext_tables.php deleted file mode 100755 index fcb2a0d..0000000 --- a/ext_tables.php +++ /dev/null @@ -1,20 +0,0 @@ - action combinations - \Denkwerk\DwContentElements\Controller\BackendController::class => 'index, createSourceExt, loadSourceExt', - ), - array( // Additional configuration - 'access' => 'user,group', - 'icon' => 'EXT:dw_content_elements/ext_icon.png', - 'labels' => 'LLL:EXT:dw_content_elements/Resources/Private/Language/locallang_db.xlf', - ) -);