From ee5a174fede6454c457310a152cc84e8d4f2c692 Mon Sep 17 00:00:00 2001 From: Claus Due Date: Fri, 23 Nov 2012 01:35:28 +0100 Subject: [PATCH] [TASK] Initial stable version Fully compatible with FED templates. --- Classes/Backend/PageLayoutSelector.php | 114 ++++++ Classes/Controller/PageController.php | 129 +++++++ .../Provider/PageConfigurationProvider.php | 358 ++++++++++++++++++ Classes/Service/ConfigurationService.php | 50 +++ Classes/Service/PageService.php | 223 +++++++++++ Configuration/TypoScript/setup.txt | 8 + Resources/Private/Language/locallang_db.xml | 14 + Resources/Private/Templates/Page/Render.html | 0 ext_emconf.php | 50 +++ ext_icon.gif | Bin 0 -> 177 bytes ext_localconf.php | 17 + ext_tables.php | 42 ++ ext_tables.sql | 8 + 13 files changed, 1013 insertions(+) create mode 100644 Classes/Backend/PageLayoutSelector.php create mode 100644 Classes/Controller/PageController.php create mode 100644 Classes/Provider/PageConfigurationProvider.php create mode 100644 Classes/Service/ConfigurationService.php create mode 100644 Classes/Service/PageService.php create mode 100644 Configuration/TypoScript/setup.txt create mode 100644 Resources/Private/Language/locallang_db.xml create mode 100644 Resources/Private/Templates/Page/Render.html create mode 100644 ext_emconf.php create mode 100644 ext_icon.gif create mode 100644 ext_localconf.php create mode 100644 ext_tables.php create mode 100644 ext_tables.sql diff --git a/Classes/Backend/PageLayoutSelector.php b/Classes/Backend/PageLayoutSelector.php new file mode 100644 index 00000000..03ab1991 --- /dev/null +++ b/Classes/Backend/PageLayoutSelector.php @@ -0,0 +1,114 @@ +, Wildside A/S + * 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 2 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! + ***************************************************************/ + +/** + * Class that renders a Page template selection field. + * + * @package Fluidpages + * @subpackage Backend + */ +class Tx_Fluidpages_Backend_PageLayoutSelector { + + /** + * @var Tx_Extbase_Configuration_BackendConfigurationManager + */ + protected $configurationManager; + + /** + * @var Tx_Fluidpages_Service_ConfigurationService + */ + protected $configurationService; + + /** + * @var array + */ + protected $recognizedFormats = array('html', 'xml', 'txt', 'json', 'js', 'css'); + + /** + * @var Tx_Fluidpages_Service_PageService + */ + protected $pageService; + + /** + * CONSTRUCTOR + */ + public function __construct() { + $objectManager = t3lib_div::makeInstance('Tx_Extbase_Object_ObjectManager'); + $this->configurationManager = $objectManager->get('Tx_Extbase_Configuration_BackendConfigurationManager'); + $this->configurationService = $objectManager->get('Tx_Fluidpages_Service_ConfigurationService'); + $this->pageService = $objectManager->get('Tx_Fluidpages_Service_PageService'); + } + + /** + * Renders a Fluid Page Layout file selector + * + * @param array $parameters + * @param mixed $pObj + * @return string + */ + public function renderField(&$parameters, &$pObj) { + $name = $parameters['itemFormElName']; + $value = $parameters['itemFormElValue']; + $availableTemplates = $this->pageService->getAvailablePageTemplateFiles(); + if (strpos($name, 'tx_fed_controller_action_sub') === FALSE) { + $onChange = 'onchange="if (confirm(TBE_EDITOR.labels.onChangeAlert) && TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };"'; + } + if ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['fed']['setup']['enableFallbackFluidPageTemplate'] && empty($value) === TRUE) { + $fallbackTemplatePathAndFilename = $this->pageService->getFallbackPageTemplatePathAndFilename(); + if (strpos($fallbackTemplatePathAndFilename, '->')) { + list ($extensionName, $templateFileBase) = explode('->', $fallbackTemplatePathAndFilename); + $fallbackTemplateIdentifier = trim($fallbackTemplatePathAndFilename, '.html'); + unset($templateFileBase); + } else { + $extensionName = NULL; + $fallbackTemplateIdentifier = $fallbackTemplatePathAndFilename; + } + $value = $fallbackTemplateIdentifier; + $emptyLabel = $this->configurationManager->getPageTemplateLabel($extensionName, $fallbackTemplateIdentifier); + } + $selector = '' . LF; + return $selector; + } + +} diff --git a/Classes/Controller/PageController.php b/Classes/Controller/PageController.php new file mode 100644 index 00000000..73a83474 --- /dev/null +++ b/Classes/Controller/PageController.php @@ -0,0 +1,129 @@ +, Wildside A/S + * + * 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 2 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! + ***************************************************************/ + +/** + * Page Controller + * + * @package Fluidpages + * @subpackage Controller + * @route off + */ +class Tx_Fluidpages_Controller_PageController extends Tx_Extbase_MVC_Controller_ActionController { + + /** + * @var string + */ + protected $defaultViewObjectName = 'Tx_Flux_MVC_View_ExposedTemplateView'; + + /** + * @var Tx_Fluidpages_Service_PageService + */ + protected $pageService; + + /** + * @var Tx_Fluidpages_Service_ConfigurationService + */ + protected $configurationService; + + /** + * @var Tx_Flux_Service_FlexForm + */ + protected $flexFormService; + + /** + * @param Tx_Fluidpages_Service_PageService $pageService + */ + public function injectPageService(Tx_Fluidpages_Service_PageService $pageService) { + $this->pageService = $pageService; + } + + /** + * @param Tx_Fluidpages_Service_ConfigurationService $configurationService + * @return void + */ + public function injectConfigurationService(Tx_Fluidpages_Service_ConfigurationService $configurationService) { + $this->configurationService = $configurationService; + } + + /** + * @param Tx_Flux_Service_FlexForm $flexFormService + * @return void + */ + public function injectFlexFormService(Tx_Flux_Service_FlexForm $flexformService) { + $this->flexFormService = $flexformService; + } + + /** + * @param Tx_Flux_MVC_View_ExposedTemplateView $view + * + * @return void + */ + public function initializeView(Tx_Flux_MVC_View_ExposedTemplateView $view) { + $configuration = $this->pageService->getPageTemplateConfiguration($GLOBALS['TSFE']->id); + list ($extensionName, $action) = explode('->', $configuration['tx_fed_page_controller_action']); + $paths = $this->configurationService->getPageConfiguration($extensionName); + $flexFormSource = $this->pageService->getPageFlexFormSource($GLOBALS['TSFE']->id); + $flexformData = $this->flexFormService->convertFlexFormContentToArray($flexFormSource); + $view->setLayoutRootPath($paths['layoutRootPath']); + $view->setPartialRootPath($paths['partialRootPath']); + $templatePathAndFilename = $paths['templateRootPath'] . 'Page/' . $action . '.html'; + if (file_exists($templatePathAndFilename) === FALSE && $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['fed']['setup']['enableFallbackFluidPageTemplate']) { + $templatePathAndFilename = $this->settings['templates']['fallbackFluidPageTemplate']; + } + $templatePathAndFilename = Tx_Flux_Utility_Path::translatePath($templatePathAndFilename); + if (file_exists($templatePathAndFilename) === TRUE) { + $view->setTemplatePathAndFilename($templatePathAndFilename); + $view->assignMultiple($flexformData); + $view->assign('page', $GLOBALS['TSFE']->page); + $view->assign('user', $GLOBALS['TSFE']->fe_user->user); + $view->assign('cookies', $_COOKIE); + $view->assign('session', $_SESSION); + } else { + $message = 'Template file "' . $templatePathAndFilename . '" does not exist.'; + if (pathinfo($templatePathAndFilename, PATHINFO_BASENAME) === '') { + $message .= ' Additionally, the specified template file basename was empty.'; + if ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['fed']['setup']['enableFallbackFluidPageTemplate']) { + $message .= ' The fallback page template feature is enabled but the fallback template was not found.'; + } else { + $message .= ' A fallback page template was not defined - which means that you probably just need to'; + $message .= ' select a page template for this page or make sure your page inherits its template '; + $message .= ' from the parent page template.'; + } + } + $this->flashMessageContainer->add($message, 'Template file not found'); + } + $this->view = $view; + } + + /** + * @return string + * @route off + */ + public function renderAction() { + $this->view->setControllerContext($this->controllerContext); + return $this->view->render(); + } + +} diff --git a/Classes/Provider/PageConfigurationProvider.php b/Classes/Provider/PageConfigurationProvider.php new file mode 100644 index 00000000..d8afbb99 --- /dev/null +++ b/Classes/Provider/PageConfigurationProvider.php @@ -0,0 +1,358 @@ +, Wildside A/S + * + * 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! + *****************************************************************/ + +/** + * Page Configuration Provider + * + * @author Claus Due , Wildside A/S + * @package Fluidpages + * @subpackage Provider + */ +class Tx_Fluidpages_Provider_PageConfigurationProvider extends Tx_Flux_Provider_AbstractConfigurationProvider implements Tx_Flux_Provider_ConfigurationProviderInterface { + + /** + * @var string + */ + protected $tableName = 'pages'; + + /** + * @var string + */ + protected $fieldName = 'tx_fed_page_flexform'; + + /** + * @var string + */ + protected $extensionKey = 'fed'; + + /** + * @var string + */ + protected $configurationSectionName = 'Configuration'; + + /** + * @var t3lib_flexFormTools + */ + protected $flexformTool; + + /** + * @var Tx_Fluidpages_Service_PageService + */ + protected $pageService; + + /** + * @var Tx_Extbase_Configuration_ConfigurationManagerInterface + */ + protected $configurationManager; + + /** + * @var Tx_Fluidpages_Service_ConfigurationService + */ + protected $configurationService; + + /** + * @var integer + */ + protected $priority = 100; + + /** + * CONSTRUCTOR + */ + public function __construct() { + $this->flexformTool = t3lib_div::makeInstance('t3lib_flexFormTools'); + } + + /** + * @param Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager + * @return void + */ + public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager) { + $this->configurationManager = $configurationManager; + } + + /** + * @param Tx_Fluidpages_Service_PageService $pageService + * @return void + */ + public function injectPageService(Tx_Fluidpages_Service_PageService $pageService) { + $this->pageService = $pageService; + } + + /** + * @param Tx_Fluidpages_Service_ConfigurationService $configurationService + * @return void + */ + public function injectConfigurationService(Tx_Fluidpages_Service_ConfigurationService $configurationService) { + $this->configurationService = $configurationService; + } + + /** + * @param array $row + * @return string + */ + public function getTemplatePathAndFilename(array $row) { + $configuration = $this->pageService->getPageTemplateConfiguration($row['uid']); + $templatePathAndFilename = NULL; + if ($configuration['tx_fed_page_controller_action']) { + $action = $configuration['tx_fed_page_controller_action']; + list ($extensionName, $action) = explode('->', $action); + $paths = $this->configurationService->getPageConfiguration($extensionName); + $templatePathAndFilename = $paths['templateRootPath'] . '/Page/' . $action . '.html'; + } elseif ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['fed']['setup']['enableFallbackFluidPageTemplate']) { + $templatePathAndFilename = $this->pageService->getFallbackPageTemplatePathAndFilename(); + } + return $templatePathAndFilename; + } + + /** + * @param array $row + * @return array + */ + public function getTemplateVariables(array $row) { + $configuration = $this->pageService->getPageTemplateConfiguration($row['uid']); + #/** @var Tx_Flux_Service_FlexForm $flexFormUtility */ + #$flexFormUtility = $this->objectManager->get('Tx_Flux_Service_FlexForm'); + #$flexFormUtility->setContentObjectData($row['tx_fed_page_flexform']); + $this->flexFormService->setContentObjectData($row['tx_fed_page_flexform']); + $flexform = $this->flexFormService->getAll(); + if ($configuration['tx_fed_page_controller_action']) { + $action = $configuration['tx_fed_page_controller_action']; + list ($extensionName, $action) = explode('->', $action); + $paths = Tx_Flux_Utility_Path::translatePath((array) $this->configurationService->getPageConfiguration($extensionName)); + $templatePathAndFilename = $paths['templateRootPath'] . '/Page/' . $action . '.html'; + } elseif ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['fed']['setup']['enableFallbackFluidPageTemplate']) { + $templatePathAndFilename = $this->pageService->getFallbackPageTemplatePathAndFilename(); + } else { + return array(); + } + + /** @var Tx_Flux_MVC_View_ExposedStandaloneView $view */ + $view = $this->objectManager->get('Tx_Flux_MVC_View_ExposedStandaloneView'); + $view->setTemplatePathAndFilename($templatePathAndFilename); + $view->assignMultiple($flexform); + $stored = $view->getStoredVariable('Tx_Flux_ViewHelpers_FlexformViewHelper', 'storage', 'Configuration'); + $stored['sheets'] = array(); + foreach ($stored['fields'] as $field) { + $groupKey = $field['sheets']['name']; + $groupLabel = $field['sheets']['label']; + if (is_array($stored['sheets'][$groupKey]) === FALSE) { + $stored['sheets'][$groupKey] = array( + 'name' => $groupKey, + 'label' => $groupLabel, + 'fields' => array() + ); + } + array_push($stored['sheets'][$groupKey]['fields'], $field); + } + return $stored; + } + + /** + * Pre-process page's FlexForm configuration. Builds an XML array temporarily which + * will contain all configuration of the parent page. If no values are changed, this + * temporary XML is removed after database operation. + * + * @param array $row the record data, by reference. Changing fields' values changes the record's values just before saving + * @param integer $id The ID of the current record (which is sometimes now included in $row + * @param t3lib_TCEmain $reference A reference to the t3lib_TCEmain object that is currently saving the record + * @return void + */ + public function preProcessRecord(array &$row, $id, t3lib_TCEmain $reference) { + if ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['fed']['setup']['enableFluidPageTemplateVariableInheritance'] < 1) { + return; + } + if (strpos($id, 'NEW') === FALSE) { + $newElement = FALSE; + $existingPageRecord = array_pop($GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'pages', "uid = '" . $id . "'")); + $existingConfigurationString = $existingPageRecord['tx_fed_page_flexform']; + } else { + $existingConfigurationString = NULL; + $newElement = TRUE; + } + $pageSelect = new t3lib_pageSelect(); + $pages = $pageSelect->getRootLine($newElement ? $row['pid'] : $id); + $inheritedConfiguration = NULL; + $inheritedConfigurationString = NULL; + foreach ($pages as $page) { + if (empty($page['tx_fed_page_flexform']) === FALSE) { + $inheritedConfigurationString = $page['tx_fed_page_flexform']; + $inheritedConfiguration = t3lib_div::xml2array($inheritedConfigurationString); + if ($existingConfigurationString === NULL) { + $existingConfigurationString = $inheritedConfigurationString; + } + break; + } + } + if ($inheritedConfiguration === NULL) { + // no configuration exists in rootline - no need to proceed + return; + } elseif ($newElement) { + $row['tx_fed_page_flexform'] = $inheritedConfiguration; + } + $selectedTemplate = $row['tx_fed_page_controller_action']; + if (empty($selectedTemplate) === TRUE) { + foreach ($pages as $page) { + if (empty($page['tx_fed_page_controller_action_sub']) === FALSE) { + $selectedTemplate = $page['tx_fed_page_controller_action_sub']; + break; + } + } + } + if (empty($row['tx_fed_page_flexform']) === TRUE) { + // this page has no configuration, read the configuration from parent + $row['tx_fed_page_flexform'] = $inheritedConfigurationString; + } + if ($inheritedConfigurationString === $row['tx_fed_page_flexform']) { + // quick decision on raw string comparison which would indicate an old page that has previously stored an inherited configuration + $configurationsMatch = TRUE; + } else { + $currentConfiguration = is_array($row['tx_fed_page_flexform']) === TRUE ? $row['tx_fed_page_flexform'] : (array) t3lib_div::xml2array($row['tx_fed_page_flexform']); + $configurationsMatch = $this->assertMultidimensionalArraysAreIdentical($currentConfiguration, $inheritedConfiguration); + } + if ($configurationsMatch === TRUE) { + // inherited configuration is the same as the + $row['tx_fed_page_flexform'] = $inheritedConfiguration; + } + $existingConfiguration = (array) t3lib_div::xml2array($existingConfigurationString); + $newConfiguration = is_array($row['tx_fed_page_flexform']) === TRUE ? $row['tx_fed_page_flexform'] : (array) t3lib_div::xml2array($row['tx_fed_page_flexform']); + $newConfigurationString = t3lib_div::array2xml($newConfiguration, '', 0, 'T3FlexForms'); + $configurationsMatch = $this->assertMultidimensionalArraysAreIdentical($newConfiguration, $inheritedConfiguration); + if ($configurationsMatch === TRUE) { + // ensure that this page has exactly the same FlexForm XML as its parent if the fields match. + // this will synchronize this page with its parent, so that whenever the parent is updated + // this page will also be updated. + $existingConfigurationString = $inheritedConfigurationString; + $overrideValues = array('tx_fed_page_flexform' => $inheritedConfigurationString); + } else { + $overrideValues = array('tx_fed_page_flexform' => $newConfigurationString); + } + $treeChildrenWhichRequireUpdate = $this->getAllSubPageIdsWhichInheritConfiguration($id, $selectedTemplate, $existingConfigurationString, $existingConfiguration); + if (count($treeChildrenWhichRequireUpdate) > 0) { + $GLOBALS['TYPO3_DB']->exec_UPDATEquery('pages', "uid IN (" . implode(',', $treeChildrenWhichRequireUpdate) . ")", $overrideValues); + } + unset($reference); + } + + /** + * Post-process database operations on the "pages" table, triggering configuration comparison + * with the new parent (if parent has changed, naturally). + * + * @param string $status TYPO3 operation identifier, i.e. "new" etc. + * @param integer $id The ID of the current record (which is sometimes now included in $row + * @param array $row The record's data, by reference. Changing fields' values changes the record's values just before saving after operation + * @param t3lib_TCEmain $reference A reference to the t3lib_TCEmain object that is currently performing the database operation + * @return void + */ + public function postProcessDatabaseOperation($status, $id, &$row, t3lib_TCEmain $reference) { + if ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['fed']['setup']['enableFluidPageTemplateVariableInheritance'] < 1) { + return; + } + $pageSelect = new t3lib_pageSelect(); + $pages = $pageSelect->getRootLine($id); + $inheritedConfiguration = NULL; + $inheritedConfigurationString = NULL; + foreach ($pages as $page) { + if (empty($page['tx_fed_page_flexform']) === FALSE) { + $inheritedConfigurationString = $page['tx_fed_page_flexform']; + $inheritedConfiguration = t3lib_div::xml2array($inheritedConfigurationString); + break; + } + } + if ($inheritedConfiguration === NULL) { + // no manipulation necessary, there is no inherited configuration + return; + } + if (empty($row['tx_fed_page_flexform']) === TRUE) { + // no manipulation necessary, record does not have a flexform + return; + } + unset($status, $reference); + } + + /** + * Returns an array of every child subpage of the current page, which + * has requested to inherit configuration and has not changed any variables + * which are currently set in the configuration. The result can then be used for + * a bulk update. + * + * @param integer $pid + * @param string $selectedTemplate + * @param string $configurationString + * @param array $configuration + * @return array + */ + protected function getAllSubPageIdsWhichInheritConfiguration($pid, $selectedTemplate, $configurationString, $configuration) { + $subpages = array(); + $clause = "pid = '" . $pid . "' AND (tx_fed_page_controller_action = '' OR tx_fed_page_controller_action = '" . $selectedTemplate . "')"; + $subpagesWithSameOrNoController = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( + 'uid,tx_fed_page_flexform,tx_fed_page_controller_action_sub', + 'pages', + $clause + ); + foreach ($subpagesWithSameOrNoController as $page) { + if ($page['tx_fed_page_flexform'] === $configurationString || empty($page['tx_fed_page_flexform']) === TRUE) { + array_push($subpages, $page['uid']); + continue; + } + $pageConfiguration = (array) t3lib_div::xml2array($page['tx_fed_page_flexform']); + if ($this->assertMultidimensionalArraysAreIdentical($pageConfiguration, $configuration) === TRUE) { + array_push($subpages, $page['uid']); + continue; + } + if (empty($page['tx_fed_page_controller_action_sub']) === FALSE && $page['tx_fed_page_controller_action_sub'] != $selectedTemplate) { + // changed templates, do not propagate to children + continue; + } + $children = $this->getAllSubPageIdsWhichInheritConfiguration($page['uid'], $selectedTemplate, $configurationString, $configuration); + if (count($children) > 0) { + array_merge($subpages, $children); + } + } + return $subpages; + } + + /** + * @param array $a First multidimensional array + * @param array $b Second multidimensional array + * @return boolean + */ + protected function assertMultidimensionalArraysAreIdentical(array $a, array $b) { + foreach ($a as $index => $value) { + if (isset($b[$index]) === FALSE) { + return FALSE; + } elseif (is_array($value)) { + if ($this->assertMultidimensionalArraysAreIdentical($value, $b[$index]) === FALSE) { + return FALSE; + } + } else { + if ($value != $b[$index]) { + return FALSE; + } + } + } + return (boolean) (count(array_diff(array_keys($a), array_keys($b)) > 0)); + } + +} diff --git a/Classes/Service/ConfigurationService.php b/Classes/Service/ConfigurationService.php new file mode 100644 index 00000000..4d391163 --- /dev/null +++ b/Classes/Service/ConfigurationService.php @@ -0,0 +1,50 @@ +, Wildside A/S + * + * 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 2 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! + ***************************************************************/ + +/** + * Configuration Service + * + * Provides methods to read various configuration related + * to Fluid Content Elements. + * + * @author Claus Due, Wildside A/S + * @package Fluidpages + * @subpackage Service + */ +class Tx_Fluidpages_Service_ConfigurationService extends Tx_Flux_Service_Configuration implements t3lib_Singleton { + + + /** + * Get definitions of paths for Page Templates defined in TypoScript + * + * @param string $extensionName + * @return array + * @api + */ + public function getPageConfiguration($extensionName = NULL) { + return $this->getTypoScriptSubConfiguration($extensionName, 'page'); + } + +} diff --git a/Classes/Service/PageService.php b/Classes/Service/PageService.php new file mode 100644 index 00000000..479206cd --- /dev/null +++ b/Classes/Service/PageService.php @@ -0,0 +1,223 @@ +, Wildside A/S + * + * 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 2 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! + ***************************************************************/ + +/** + * Page Service + * + * Service for interacting with Pages - gets content elements and page configuration + * options. + * + * @package Fluidpages + * @subpackage Service + */ +class Tx_Fluidpages_Service_PageService implements t3lib_Singleton { + + /** + * @var Tx_Extbase_Object_ObjectManager + */ + protected $objectManager; + + /** + * @var Tx_Extbase_Configuration_ConfigurationManagerInterface + */ + protected $configurationManager; + + /** + * @var Tx_Fluidpages_Service_ConfigurationService + */ + protected $configurationService; + + /** + * @param Tx_Extbase_Object_ObjectManager $objectManager + * @return void + */ + public function injectObjectManager(Tx_Extbase_Object_ObjectManager $objectManager) { + $this->objectManager = $objectManager; + } + + /** + * @param Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager + * @return void + */ + public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager) { + $this->configurationManager = $configurationManager; + } + + /** + * @param Tx_Fluidpages_Service_ConfigurationService $configurationService + * @return void + */ + public function injectConfigurationService(Tx_Fluidpages_Service_ConfigurationService $configurationService) { + $this->configurationService = $configurationService; + } + + /** + * Gets an array of the column definition in a BackendLayout object + * + * @return array + * @api + */ + public function getColumnConfiguration() { + $config = $page->getBackendLayout()->getConfig(); + $parser = $this->objectManager->get('t3lib_tsparser'); + $parser->parse($config); + $array = $parser->setup; + $columns = array(); + foreach ($array['rows'] as $row) { + foreach ($row['columns'] as $column) { + $columns[$column['colPos']] = $column['name']; + } + } + return $columns; + } + + /** + * Process RootLine to find first usable, configured Fluid Page Template. + * WARNING: do NOT use the output of this feature to overwrite $row - the + * record returned may or may not be the same recod as defined in $id. + * + * @param integer $pageUid + * @return array + * @api + */ + public function getPageTemplateConfiguration($pageUid) { + if ($pageUid < 1) { + return NULL; + } + $pageSelect = new t3lib_pageSelect(); + $rootLine = $pageSelect->getRootLine($pageUid); + $rootLine = array_values($rootLine); + foreach ($rootLine as $index => $row) { + if ($index == 0 && strpos($row['tx_fed_page_controller_action'], '->')) { + return $row; + } elseif ($index > 0 && strpos($row['tx_fed_page_controller_action_sub'], '->')) { + $row['tx_fed_page_controller_action'] = $row['tx_fed_page_controller_action_sub']; + return $row; + } + } + return NULL; + } + + /** + * Gets the fallback Fluid Page Template defined in TypoScript + * + * @param boolean $translatePath If FALSE, does not translate the TypoScript path + * @return string + */ + public function getFallbackPageTemplatePathAndFilename($translatePath = TRUE) { + $fallbackTemplatePathAndFilename = $this->settings['defaults']['templates']['fallbackFluidPageTemplate']; + if ($translatePath === TRUE) { + $fallbackTemplatePathAndFilename = t3lib_div::getFileAbsFileName($fallbackTemplatePathAndFilename); + } + if (file_exists($fallbackTemplatePathAndFilename) || ($translatePath === FALSE)) { + return $fallbackTemplatePathAndFilename; + } else { + return t3lib_extMgm::extPath('fluidpages', 'Resources/Private/Templates/Page/Render.html'); + } + } + + /** + * Get a usable page configuration flexform from rootline + * + * @param integer $pageUid + * @return string + * @api + */ + public function getPageFlexFormSource($pageUid) { + if ($pageUid < 1) { + return NULL; + } + $pageSelect = new t3lib_pageSelect(); + $rootLine = $pageSelect->getRootLine($pageUid); + foreach ($rootLine as $row) { + if (!empty($row['tx_fed_page_flexform'])) { + return $row['tx_fed_page_flexform']; + } + } + return NULL; + } + + /** + * Gets a human-readable label from a Fluid Page template file + * + * @param string $extensionName + * @param string $templateFile + * @return string + * @api + */ + public function getPageTemplateLabel($extensionName, $templateFile) { + if ($extensionName === NULL) { + $extensionName = 'fed'; + } + $config = $this->configurationService->getPageConfiguration($extensionName); + if (file_exists($templateFile) === TRUE) { + $templatePathAndFilename = $templateFile; + } else { + $templatePathAndFilename = $config['templateRootPath'] . 'Page/' . $templateFile . '.html'; + } + $exposedView = $this->objectManager->get('Tx_Flux_MVC_View_ExposedStandaloneView'); + $exposedView->setTemplatePathAndFilename($templatePathAndFilename); + $exposedView->setLayoutRootPath($config['layoutRootPath']); + $exposedView->setPartialRootPath($config['partialRootPath']); + $page = $exposedView->getStoredVariable('Tx_Flux_ViewHelpers_FlexformViewHelper', 'storage', 'Configuration'); + return $page['label'] ? $page['label'] : $templateFile . '.html'; + } + + /** + * Gets a list of usable Page Templates from defined page template TypoScript + * + * @param string $format + * @return array + * @api + */ + public function getAvailablePageTemplateFiles($format = 'html') { + $typoScript = $this->configurationService->getPageConfiguration(); + $output = array(); + if (is_array($typoScript) === FALSE) { + return $output; + } + foreach ($typoScript as $extensionName=>$group) { + if (isset($group['enable']) === TRUE && $group['enable'] < 1) { + continue; + } + $path = $group['templateRootPath'] . 'Page' . '/'; + $files = scandir($path); + $output[$extensionName] = array(); + foreach ($files as $k=>$file) { + $pathinfo = pathinfo($path . $file); + $extension = $pathinfo['extension']; + if (substr($file, 0, 1) === '.') { + unset($files[$k]); + } else if (strtolower($extension) != strtolower($format)) { + unset($files[$k]); + } else { + $output[$extensionName][] = $pathinfo['filename']; + } + } + } + return $output; + } + +} diff --git a/Configuration/TypoScript/setup.txt b/Configuration/TypoScript/setup.txt new file mode 100644 index 00000000..caaf97e5 --- /dev/null +++ b/Configuration/TypoScript/setup.txt @@ -0,0 +1,8 @@ +[GLOBAL] +page = PAGE +page.typeNum = 0 +page.5 = USER +page.5.userFunc = tx_extbase_core_bootstrap->run +page.5.extensionName = Fluidpages +page.5.pluginName = Page +page.10 > diff --git a/Resources/Private/Language/locallang_db.xml b/Resources/Private/Language/locallang_db.xml new file mode 100644 index 00000000..8561a4ea --- /dev/null +++ b/Resources/Private/Language/locallang_db.xml @@ -0,0 +1,14 @@ + + + + database + Language labels for database tables/fields belonging to extension 'fluidpages' + + + + + + + + + \ No newline at end of file diff --git a/Resources/Private/Templates/Page/Render.html b/Resources/Private/Templates/Page/Render.html new file mode 100644 index 00000000..e69de29b diff --git a/ext_emconf.php b/ext_emconf.php new file mode 100644 index 00000000..33a0cf94 --- /dev/null +++ b/ext_emconf.php @@ -0,0 +1,50 @@ + 'Fluid Page Templates', + 'description' => 'Fluid Page Template engine - integrates compact and highly dynamic page templates with all the benefits of Fluid.', + 'category' => 'misc', + 'author' => 'Claus Due', + 'author_email' => 'claus@wildside.dk', + 'author_company' => 'Wildside A/S', + 'shy' => '', + 'dependencies' => 'cms,flux', + 'conflicts' => '', + 'priority' => '', + 'module' => '', + 'state' => 'stable', + 'internal' => '', + 'uploadfolder' => 0, + 'createDirs' => '', + 'modify_tables' => '', + 'clearCacheOnLoad' => 1, + 'lockType' => '', + 'version' => '0.9.0', + 'constraints' => array( + 'depends' => array( + 'typo3' => '4.5-0.0.0', + 'cms' => '', + 'flux' => '', + ), + 'conflicts' => array( + ), + 'suggests' => array( + 'fluidwidget' => '', + ), + ), + 'suggests' => array( + ), + '_md5_values_when_last_written' => 'a:33:{s:9:"README.md";s:4:"f971";s:12:"ext_icon.gif";s:4:"68b4";s:17:"ext_localconf.php";s:4:"a6bf";s:14:"ext_tables.php";s:4:"8085";s:34:"Configuration/Common/constants.txt";s:4:"d41d";s:30:"Configuration/Common/setup.txt";s:4:"acb7";s:44:"Configuration/TwitterBootstrap/constants.txt";s:4:"d41d";s:40:"Configuration/TwitterBootstrap/setup.txt";s:4:"f012";s:60:"Resources/Private/Elements/Common/Display/AddressAndMap.html";s:4:"91c0";s:55:"Resources/Private/Elements/Common/Display/FileList.html";s:4:"c000";s:61:"Resources/Private/Elements/Common/Flux/AjaxContentLoader.html";s:4:"c5a0";s:53:"Resources/Private/Elements/Common/Layout/Columns.html";s:4:"1b6c";s:63:"Resources/Private/Elements/Common/Layout/ContentRandomizer.html";s:4:"2aac";s:61:"Resources/Private/Elements/Common/Layout/JQueryAccordion.html";s:4:"a98f";s:56:"Resources/Private/Elements/Common/Layout/JQueryTabs.html";s:4:"5415";s:60:"Resources/Private/Elements/Common/Navigation/BreadCrumb.html";s:4:"8e08";s:58:"Resources/Private/Elements/Common/Navigation/Redirect.html";s:4:"b96c";s:54:"Resources/Private/Elements/Common/Resource/Script.html";s:4:"50af";s:63:"Resources/Private/Elements/Common/Resource/SocialBookmarks.html";s:4:"bc79";s:53:"Resources/Private/Elements/Common/Resource/Style.html";s:4:"f309";s:58:"Resources/Private/Elements/TwitterBootstrap/Accordion.html";s:4:"f8a1";s:54:"Resources/Private/Elements/TwitterBootstrap/Alert.html";s:4:"c3d1";s:60:"Resources/Private/Elements/TwitterBootstrap/ButtonGroup.html";s:4:"2b0a";s:59:"Resources/Private/Elements/TwitterBootstrap/ButtonLink.html";s:4:"c89f";s:57:"Resources/Private/Elements/TwitterBootstrap/FluidRow.html";s:4:"8c42";s:57:"Resources/Private/Elements/TwitterBootstrap/HeroUnit.html";s:4:"49ac";s:63:"Resources/Private/Elements/TwitterBootstrap/NavigationList.html";s:4:"fb32";s:59:"Resources/Private/Elements/TwitterBootstrap/PageHeader.html";s:4:"db43";s:53:"Resources/Private/Elements/TwitterBootstrap/Tabs.html";s:4:"d492";s:59:"Resources/Private/Elements/TwitterBootstrap/Thumbnails.html";s:4:"2c21";s:53:"Resources/Private/Elements/TwitterBootstrap/Well.html";s:4:"18a8";s:34:"Resources/Private/Layouts/FCE.html";s:4:"5a0f";s:39:"Resources/Public/Icons/icon-twitter.png";s:4:"9450";}', +); + +?> \ No newline at end of file diff --git a/ext_icon.gif b/ext_icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..085b6fd0985cb2966f6d75d5a4ca88a4920fc259 GIT binary patch literal 177 zcmZ?wbhEHb6k-ry*v!E2?Afzx*RGv9b!y|rjWcGV=Kufy8NfjCCkrDx122OPhzBx*fhBIkNzc_&6L~79IJKB6oDTBfUTnl3I%TP% zruO6j&OHi~0_O`)(!0QMrDO7RzKVdm8ccVc7&91xn7sYeH>c^cynIx>QELg8(^i>j bpH5B6)!f*|ey*EEsLxX3RZXLiAcHjk_Papu literal 0 HcmV?d00001 diff --git a/ext_localconf.php b/ext_localconf.php new file mode 100644 index 00000000..68820d0b --- /dev/null +++ b/ext_localconf.php @@ -0,0 +1,17 @@ + 'render', + ), + array( + ), + Tx_Extbase_Utility_Extension::PLUGIN_TYPE_PLUGIN +); + +$GLOBALS['TYPO3_CONF_VARS']['FE']['addRootLineFields'] .= ($GLOBALS['TYPO3_CONF_VARS']['FE']['addRootLineFields'] == '' ? '' : ',') . 'tx_fed_page_controller_action,tx_fed_page_controller_action_sub,tx_fed_page_flexform,'; diff --git a/ext_tables.php b/ext_tables.php new file mode 100644 index 00000000..5484e1fb --- /dev/null +++ b/ext_tables.php @@ -0,0 +1,42 @@ + array ( + 'exclude' => 1, + 'label' => 'LLL:EXT:fluidpages/Resources/Private/Language/locallang_db.xml:pages.tx_fed_page_controller_action', + 'config' => array ( + 'type' => 'user', + 'userFunc' => 'Tx_Fluidpages_Backend_PageLayoutSelector->renderField' + ) + ), + 'tx_fed_page_controller_action_sub' => array ( + 'exclude' => 1, + 'label' => 'LLL:EXT:fluidpages/Resources/Private/Language/locallang_db.xml:pages.tx_fed_page_controller_action_sub', + 'config' => array ( + 'type' => 'user', + 'userFunc' => 'Tx_Fluidpages_Backend_PageLayoutSelector->renderField' + ) + ), + 'tx_fed_page_flexform' => Array ( + 'exclude' => 1, + 'label' => 'LLL:EXT:fluidpages/Resources/Private/Language/locallang_db.xml:pages.tx_fed_page_flexform', + 'config' => array ( + 'type' => 'flex', + ) + ), +), 1); +t3lib_extMgm::addToAllTCAtypes( + 'pages', + 'tx_fed_page_controller_action,tx_fed_page_controller_action_sub,tx_fed_page_flexform', + '0,1,4', + 'before:layout' +); \ No newline at end of file diff --git a/ext_tables.sql b/ext_tables.sql new file mode 100644 index 00000000..101cf681 --- /dev/null +++ b/ext_tables.sql @@ -0,0 +1,8 @@ +# +# Table structure for table 'pages' +# +CREATE TABLE pages ( + tx_fed_page_flexform text NOT NULL, + tx_fed_page_controller_action varchar(255) DEFAULT '' NOT NULL, + tx_fed_page_controller_action_sub varchar(255) DEFAULT '' NOT NULL, +); \ No newline at end of file