From 8203eae72b0298c593b0074638eeb9a35970b09e Mon Sep 17 00:00:00 2001 From: Kevin Ditscheid Date: Thu, 6 Dec 2018 17:10:48 +0100 Subject: [PATCH 01/11] [TASK] Prepare TYPO3 9LTS upgrade --- Configuration/TCA/Overrides/tt_content.php | 38 ++++++++++++++++++++++ composer.json | 2 +- ext_emconf.php | 4 +-- ext_tables.php | 10 ------ 4 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 Configuration/TCA/Overrides/tt_content.php diff --git a/Configuration/TCA/Overrides/tt_content.php b/Configuration/TCA/Overrides/tt_content.php new file mode 100644 index 0000000..9fad4d5 --- /dev/null +++ b/Configuration/TCA/Overrides/tt_content.php @@ -0,0 +1,38 @@ + '', 'constraints' => array( 'depends' => array( - 'php' => '5.5.0-7.1.99', - 'typo3' => '7.6.0-8.7.99', + 'php' => '5.5.0-7.3.99', + 'typo3' => '7.6.0-9.5.99', ), 'conflicts' => array( ), diff --git a/ext_tables.php b/ext_tables.php index 977238e..cc34e77 100644 --- a/ext_tables.php +++ b/ext_tables.php @@ -13,16 +13,6 @@ $GLOBALS['TCA']['tt_content']['types']['list']['subtypes_excludelist']['df_tabs_ $GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['df_tabs_plugin1'] = 'pi_flexform'; \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue('df_tabs_plugin1', 'FILE:EXT:df_tabs/Configuration/FlexForms/flexform.xml'); -// add plugin -\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPlugin( - array( - 'LLL:EXT:df_tabs/Resources/Private/Language/locallang.xlf:tt_content.list_type_plugin1', - 'df_tabs_plugin1', - 'EXT:df_tabs/Resources/Public/Images/contentElementWizard.png' - ), - 'list_type' -); - // add static typoscript template \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('df_tabs', 'Configuration/TypoScript/', 'df_tabs'); -- GitLab From bef5c63523bd4ddc67f9a8a0e45c3a94c06368d4 Mon Sep 17 00:00:00 2001 From: Kevin Ditscheid Date: Thu, 6 Dec 2018 19:12:29 +0100 Subject: [PATCH 02/11] [BUGFIX] Fix missing extension key for addPlugin --- Configuration/TCA/Overrides/tt_content.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Configuration/TCA/Overrides/tt_content.php b/Configuration/TCA/Overrides/tt_content.php index 9fad4d5..16f5c7d 100644 --- a/Configuration/TCA/Overrides/tt_content.php +++ b/Configuration/TCA/Overrides/tt_content.php @@ -32,7 +32,8 @@ call_user_func(function ($extKey) { $extKey . '_plugin1', 'EXT:' . $extKey . '/Resources/Public/Images/contentElementWizard.png' ), - 'list_type' + 'list_type', + $extKey ); }, 'df_tabs'); -- GitLab From adac60a91f037eac6e88f1cf3567ac2fc55a4dff Mon Sep 17 00:00:00 2001 From: Kevin Ditscheid Date: Fri, 4 Jan 2019 17:27:05 +0100 Subject: [PATCH 03/11] [TASK] Code cleanup for TYPO3 9LTS --- Classes/Controller/PluginController.php | 1 - Classes/Service/ConfigurationService.php | 3 +- Classes/Utility/ExtensionUtility.php | 66 +++++++++++++++++ Configuration/TCA/Overrides/sys_template.php | 35 +++++++++ Configuration/TCA/Overrides/tt_content.php | 37 +++++++--- .../{constants.txt => constants.typoscript} | 0 .../{setup.txt => setup.typoscript} | 0 .../Unit/Service/ConfigurationServiceTest.php | 2 +- ext_localconf.php | 50 +++++++++---- ext_tables.php | 74 +++++++++++-------- 10 files changed, 209 insertions(+), 59 deletions(-) create mode 100644 Classes/Utility/ExtensionUtility.php create mode 100644 Configuration/TCA/Overrides/sys_template.php rename Configuration/TypoScript/{constants.txt => constants.typoscript} (100%) rename Configuration/TypoScript/{setup.txt => setup.typoscript} (100%) diff --git a/Classes/Controller/PluginController.php b/Classes/Controller/PluginController.php index af52726..7f661b5 100644 --- a/Classes/Controller/PluginController.php +++ b/Classes/Controller/PluginController.php @@ -1,6 +1,5 @@ + */ +class ExtensionUtility { + /** + * Get the extension configuration + * + * @return array + */ + public static function getExtensionConfiguration(): array { + if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '9.0.0', '<')) { + return \unserialize( + $GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['df_tabs'], ['allowed_classes' => FALSE] + ); + } + + return $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['df_tabs']; + } + + /** + * Set the extension configuration + * + * @param array $configuration + */ + public static function setExtensionConfiguration(array $configuration) { + if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '9.0.0', '<')) { + $GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['df_tabs'] = \serialize($configuration); + } else { + $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['df_tabs'] = $configuration; + } + } +} diff --git a/Configuration/TCA/Overrides/sys_template.php b/Configuration/TCA/Overrides/sys_template.php new file mode 100644 index 0000000..f8e7a79 --- /dev/null +++ b/Configuration/TCA/Overrides/sys_template.php @@ -0,0 +1,35 @@ + 'foo', 'conf2' => 'bar'); - $GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['df_tabs'] = serialize($extensionConfiguration); + \SGalinski\DfTabs\Utility\ExtensionUtility::setExtensionConfiguration($extensionConfiguration); $this->context->conf = array('conf2' => 'foo'); diff --git a/ext_localconf.php b/ext_localconf.php index 393fe1d..bcc379b 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -1,21 +1,41 @@ = 8000000) { - require_once PATH_typo3conf . 'ext/df_tabs/Classes/Controller/PluginController.php'; -} +call_user_func( + function ($extKey) { + \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPItoST43( + $extKey, '', '_plugin1', 'list_type', 1 + ); -$GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include']['dftabs'] = 'EXT:df_tabs/Classes/Ajax/LoadAjax.php'; + $GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include'][$extKey] = 'EXT:df_tabs/Classes/Ajax/LoadAjax.php'; -// set global storage pid -$dfTabsExtConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['df_tabs']); -$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['df_tabs']['useJQuery'] = $dfTabsExtConf['useJQuery'] ? 1 : 0; + // set global storage pid + $dfTabsExtConf = \SGalinski\DfTabs\Utility\ExtensionUtility::getExtensionConfiguration(); + $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$extKey]['useJQuery'] = $dfTabsExtConf['useJQuery'] ? 1 : 0; + }, 'df_tabs' +); -?> diff --git a/ext_tables.php b/ext_tables.php index cc34e77..1606304 100644 --- a/ext_tables.php +++ b/ext_tables.php @@ -1,35 +1,51 @@ registerIcon( - 'extension-df_tabs-content-element', - \TYPO3\CMS\Core\Imaging\IconProvider\BitmapIconProvider::class, - ['source' => 'EXT:df_tabs/Resources/Public/Images/contentElementWizard.png'] + +call_user_func( + function ($extKey) { + // add plugin to the content element wizard list + if (TYPO3_MODE === 'BE') { + $GLOBALS['TBE_MODULES_EXT']['xMOD_db_new_content_el']['addElClasses'][\SGalinski\DfTabs\Wizards\ContentElementWizard::class] = + \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath( + $extKey + ) . 'Classes/Wizards/ContentElementWizard.php'; + } + + /** + * Register icons + */ + $iconRegistry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance( + \TYPO3\CMS\Core\Imaging\IconRegistry::class + ); + $iconRegistry->registerIcon( + 'extension-df_tabs-content-element', + \TYPO3\CMS\Core\Imaging\IconProvider\BitmapIconProvider::class, + ['source' => 'EXT:df_tabs/Resources/Public/Images/contentElementWizard.png'] + ); + }, 'df_tabs' ); -?> -- GitLab From 584e7a7f0367ed8c8764756569f570e1ad95fcb2 Mon Sep 17 00:00:00 2001 From: Kevin Ditscheid Date: Wed, 16 Jan 2019 12:37:06 +0100 Subject: [PATCH 04/11] [BUGFIX] Fixing df_tabs frontend plugin This commit removes the useJquery extension configuration and the dependency to deprecated DatabaseConnection class. It also modernizes the class name of the frontend plugin. --- Classes/Controller/PluginController.php | 4 +- .../DataProvider/AbstractBaseDataProvider.php | 2 +- .../AbstractDataBaseDataProvider.php | 45 +++++++++---- Classes/DataProvider/PagesDataProvider.php | 34 +++++----- Classes/Domain/Model/Tab.php | 2 +- Classes/Service/ConfigurationService.php | 47 ++++++------- Classes/View/TypoScriptView.php | 66 +++++++++---------- Configuration/TypoScript/constants.typoscript | 4 -- Configuration/TypoScript/setup.typoscript | 10 --- README.md | 5 -- composer.json | 5 +- ext_conf_template.txt | 2 - ext_emconf.php | 4 +- ext_localconf.php | 10 +-- 14 files changed, 125 insertions(+), 115 deletions(-) delete mode 100644 ext_conf_template.txt diff --git a/Classes/Controller/PluginController.php b/Classes/Controller/PluginController.php index 7f661b5..a64a4e7 100644 --- a/Classes/Controller/PluginController.php +++ b/Classes/Controller/PluginController.php @@ -1,5 +1,7 @@ exec_SELECTgetSingleRow('*', $this->table, 'uid = ' . (int) $uid); + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table); + $row = $queryBuilder->select('*') + ->from($this->table) + ->where( + $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)) + )->execute()->fetch(); /** @var TypoScriptFrontendController $typoscriptController */ $typoscriptController = $GLOBALS['TSFE']; @@ -64,13 +71,23 @@ abstract class AbstractDataBaseDataProvider extends AbstractBaseDataProvider { // * row is valid // * row language is different from currently needed language // * sys_language_contentOL is set - if (is_array($row) && $row['sys_language_uid'] != $typoscriptController->sys_language_content && - $typoscriptController->sys_language_contentOL + if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '9.0.0', '<')) { + $sysLanguageContent = $GLOBALS['TSFE']->sys_language_content; + $sysLanguageContentOl = $GLOBALS['TSFE']->sys_language_contentOL; + } else { + $context = GeneralUtility::makeInstance(Context::class); + $languageAspect = $context->getAspect('language'); + $sysLanguageContent = $languageAspect->getContentId(); + $sysLanguageContentOl = $languageAspect->getOverlayType(); + } + + if (\is_array($row) && $row['sys_language_uid'] !== $sysLanguageContent && + $sysLanguageContentOl ) { if ($this->table !== 'pages') { $row = $typoscriptController->sys_page->getRecordOverlay( - $this->table, $row, $typoscriptController->sys_language_content, - $typoscriptController->sys_language_contentOL + $this->table, $row, $sysLanguageContent, + $sysLanguageContentOl ); } else { $row = $typoscriptController->sys_page->getPageOverlay($row); @@ -97,16 +114,17 @@ abstract class AbstractDataBaseDataProvider extends AbstractBaseDataProvider { * * @param int $uid * @return string + * @throws \TYPO3\CMS\Frontend\ContentObject\Exception\ContentRenderingException */ public function getTabContent($uid) { $configuration = [ 'tables' => 'tt_content', - 'source' => implode(',', $this->getContentUids($uid)), + 'source' => \implode(',', $this->getContentUids($uid)), 'dontCheckPid' => 1 ]; - if (is_array($this->pluginConfiguration['records.'])) { - $configuration = array_merge($configuration, $this->pluginConfiguration['records.']); + if (\is_array($this->pluginConfiguration['records.'])) { + $configuration = \array_merge($configuration, $this->pluginConfiguration['records.']); } return $this->contentObject->render($this->contentObject->getContentObject('RECORDS'), $configuration); @@ -117,6 +135,7 @@ abstract class AbstractDataBaseDataProvider extends AbstractBaseDataProvider { * * @param int $uid * @return string + * @throws \TYPO3\CMS\Core\Context\Exception\AspectNotFoundException */ public function getTitle($uid) { if (!isset($this->cachedRecord[$uid])) { @@ -131,6 +150,7 @@ abstract class AbstractDataBaseDataProvider extends AbstractBaseDataProvider { * * @param int $uid * @return string + * @throws \TYPO3\CMS\Core\Context\Exception\AspectNotFoundException */ public function getLinkData($uid) { if (!isset($this->cachedRecord[$uid])) { @@ -145,6 +165,7 @@ abstract class AbstractDataBaseDataProvider extends AbstractBaseDataProvider { * * @param int $uid * @return string + * @throws \TYPO3\CMS\Core\Context\Exception\AspectNotFoundException */ public function getAjaxFallbackText($uid) { if (!isset($this->cachedRecord[$uid])) { diff --git a/Classes/DataProvider/PagesDataProvider.php b/Classes/DataProvider/PagesDataProvider.php index 0043cdf..6c7f148 100644 --- a/Classes/DataProvider/PagesDataProvider.php +++ b/Classes/DataProvider/PagesDataProvider.php @@ -25,7 +25,9 @@ namespace SGalinski\DfTabs\DataProvider; * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ -use TYPO3\CMS\Core\Database\DatabaseConnection; +use TYPO3\CMS\Core\Database\ConnectionPool; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Frontend\Page\PageRepository; /** * Data Provider for the pages table @@ -46,19 +48,21 @@ class PagesDataProvider extends AbstractDataBaseDataProvider { * @return array */ public function getContentUids($uid) { - $where = 'pid = ' . ((int) $uid) . $this->contentObject->enableFields('tt_content') . - ' ' . $this->pluginConfiguration['pages.']['additionalWhere'] . - ' AND sys_language_uid IN (0,-1)'; - - /** @var $db DatabaseConnection */ - $db = $GLOBALS['TYPO3_DB']; - $contentElements = $db->exec_SELECTgetRows( - 'uid', 'tt_content', $where, '', - $this->pluginConfiguration['pages.']['orderBy'], - $this->pluginConfiguration['pages.']['limit'], - 'uid' - ); - - return array_keys($contentElements); + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content'); + $pageRepository = GeneralUtility::makeInstance(PageRepository::class); + $queryBuilder->select('uid') + ->from('tt_content') + ->where( + 'pid = ' . ((int) $uid) . $pageRepository->enableFields('tt_content') . + ' ' . $this->pluginConfiguration['pages.']['additionalWhere'] . + ' AND sys_language_uid IN (0,-1)' + ) + ->setMaxResults($this->pluginConfiguration['pages.']['limit']); + $orderings = \explode(',', $this->pluginConfiguration['pages.']['orderBy']); + foreach ($orderings as $order) { + $queryBuilder->addOrderBy(\trim($order)); + } + $contentElements = $queryBuilder->execute()->fetchAll(); + return \array_column($contentElements, 'uid'); } } diff --git a/Classes/Domain/Model/Tab.php b/Classes/Domain/Model/Tab.php index 97f9864..8212692 100644 --- a/Classes/Domain/Model/Tab.php +++ b/Classes/Domain/Model/Tab.php @@ -85,7 +85,7 @@ class Tab { * @return void */ public function setRecord($record) { - $this->record = intval($record); + $this->record = (int)$record; } /** diff --git a/Classes/Service/ConfigurationService.php b/Classes/Service/ConfigurationService.php index 3073afb..5ab830d 100644 --- a/Classes/Service/ConfigurationService.php +++ b/Classes/Service/ConfigurationService.php @@ -25,6 +25,7 @@ namespace SGalinski\DfTabs\Service; * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +use SGalinski\DfTabs\Controller\PluginController; use SGalinski\DfTabs\Utility\ExtensionUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -33,17 +34,17 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; */ class ConfigurationService { /** - * @var \tx_dftabs_plugin1 + * @var PluginController */ - protected $controllerContext = NULL; + protected $controllerContext; /** * Injects the controller context * - * @param \tx_dftabs_plugin1 $context + * @param PluginController $context * @return void */ - public function injectControllerContext(\tx_dftabs_plugin1 $context) { + public function injectControllerContext(PluginController $context) { $this->controllerContext = $context; } @@ -59,22 +60,22 @@ class ConfigurationService { * @return array */ public function getConfiguration() { - $configuration = array_merge( + $configuration = \array_merge( $this->getExtensionConfiguration(), $this->getTypoScriptConfiguration(), $this->getFlexformConfiguration() ); if (isset($configuration['autoPlayInterval'])) { - $configuration['autoPlayInterval'] = intval($configuration['autoPlayInterval']); + $configuration['autoPlayInterval'] = (int)$configuration['autoPlayInterval']; } if (isset($configuration['pollingInterval'])) { - $configuration['pollingInterval'] = intval($configuration['pollingInterval']); + $configuration['pollingInterval'] = (int)$configuration['pollingInterval']; } if (isset($configuration['animationSpeed'])) { - $configuration['animationSpeed'] = intval($configuration['animationSpeed']); + $configuration['animationSpeed'] = (int)$configuration['animationSpeed']; } return $configuration; @@ -87,7 +88,7 @@ class ConfigurationService { */ protected function getExtensionConfiguration() { $configuration = ExtensionUtility::getExtensionConfiguration(); - if (!is_array($configuration)) { + if (!\is_array($configuration)) { return []; } @@ -102,7 +103,7 @@ class ConfigurationService { protected function getTypoScriptConfiguration() { $configuration = (array) $this->controllerContext->conf; foreach ($configuration as $key => &$option) { - if ($key{strlen($key) - 1} !== '.' && isset($configuration[$key . '.'])) { + if ($key{\strlen($key) - 1} !== '.' && isset($configuration[$key . '.'])) { $option = $this->controllerContext->cObj->stdWrap($option, $configuration[$key . '.']); } } @@ -129,54 +130,54 @@ class ConfigurationService { // } $configuration['ajax'] = FALSE; - $value = trim($this->controllerContext->pi_getFFvalue($data, 'enableAutoPlay')); + $value = \trim($this->controllerContext->pi_getFFvalue($data, 'enableAutoPlay')); if ($value !== '') { $configuration['enableAutoPlay'] = $value; } - $value = trim($this->controllerContext->pi_getFFvalue($data, 'enableMouseOver')); + $value = \trim($this->controllerContext->pi_getFFvalue($data, 'enableMouseOver')); if ($value !== '') { $configuration['enableMouseOver'] = $value; } - $value = trim($this->controllerContext->pi_getFFvalue($data, 'autoPlayInterval')); + $value = \trim($this->controllerContext->pi_getFFvalue($data, 'autoPlayInterval')); if ($value !== '') { - $configuration['autoPlayInterval'] = intval($value); + $configuration['autoPlayInterval'] = (int)$value; } - $value = trim($this->controllerContext->pi_getFFvalue($data, 'animationSpeed')); + $value = \trim($this->controllerContext->pi_getFFvalue($data, 'animationSpeed')); if ($value !== '') { - $configuration['animationSpeed'] = intval($value); + $configuration['animationSpeed'] = (int)$value; } - $value = trim($this->controllerContext->pi_getFFvalue($data, 'mode')); + $value = \trim($this->controllerContext->pi_getFFvalue($data, 'mode')); if ($value !== '') { $configuration['mode'] = $value; } - $value = trim($this->controllerContext->pi_getFFvalue($data, 'titles')); + $value = \trim($this->controllerContext->pi_getFFvalue($data, 'titles')); if ($value !== '') { - $configuration['titles'] = explode(chr(10), $value); + $configuration['titles'] = \explode(\chr(10), $value); } ### BEGIN Compatibility Code ### - $value = trim($this->controllerContext->pi_getFFvalue($data, 'pages')); + $value = \trim($this->controllerContext->pi_getFFvalue($data, 'pages')); if ($value !== '') { $configuration['data'] = $value; } - $value = trim($this->controllerContext->pi_getFFvalue($data, 'tt_content')); + $value = \trim($this->controllerContext->pi_getFFvalue($data, 'tt_content')); if ($value !== '') { $configuration['data'] = $value; } ### END Compatibility Code ### - $value = trim($this->controllerContext->pi_getFFvalue($data, 'data')); + $value = \trim($this->controllerContext->pi_getFFvalue($data, 'data')); if ($value !== '') { $configuration['data'] = $value; } - $value = trim($this->controllerContext->pi_getFFvalue($data, 'hashName')); + $value = \trim($this->controllerContext->pi_getFFvalue($data, 'hashName')); if ($value !== '') { $configuration['hashName'] = $value; } diff --git a/Classes/View/TypoScriptView.php b/Classes/View/TypoScriptView.php index d3e59d2..d6f1a07 100644 --- a/Classes/View/TypoScriptView.php +++ b/Classes/View/TypoScriptView.php @@ -26,8 +26,11 @@ namespace SGalinski\DfTabs\View; ***************************************************************/ use SGalinski\DfTabs\Domain\Model\Tab; +use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\Page\PageRenderer; use TYPO3\CMS\Core\SingletonInterface; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Core\Utility\VersionNumberUtility; use TYPO3\CMS\Extbase\Utility\LocalizationUtility; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; @@ -45,12 +48,12 @@ class TypoScriptView implements SingletonInterface { * * @var PageRenderer */ - protected $pageRenderer = NULL; + protected $pageRenderer; /** * @var ContentObjectRenderer */ - protected $contentObject = NULL; + protected $contentObject; /** * Internal plugin counter @@ -77,7 +80,7 @@ class TypoScriptView implements SingletonInterface { $this->pluginConfiguration[$tabId] = $configuration; $this->pluginConfiguration[$tabId]['counter'] = $this->counter; - if (in_array($this->pluginConfiguration[$tabId]['hashName'], $this->usedHashes)) { + if (\in_array($this->pluginConfiguration[$tabId]['hashName'], $this->usedHashes)) { $this->pluginConfiguration[$tabId]['hashName'] = 'tab' . $this->counter . '-'; } $this->usedHashes[] = $this->pluginConfiguration[$tabId]['hashName']; @@ -124,35 +127,31 @@ class TypoScriptView implements SingletonInterface { $animationCallback = ',animationCallback: ' . $config['animationCallback']; } - array_shift($records); + \array_shift($records); $menuId = $this->addPrefix('tabMenu-' . $config['counter'], $tabId); $contentId = $this->addPrefix('tabContents-' . $config['counter'], $tabId); - if ($config['useJQuery']) { - $inlineJavaScript = ' - document.documentElement.className = "' . $this->addPrefix('plugin1-hasJS', $tabId) . ' " - + document.documentElement.className; - $(document).ready(function() { - window.TabBar' . $config['counter'] . ' = new TabBar( - $("#' . $menuId . ' > ' . $config['menuNodeType'] . '"), - $("#' . $contentId . ' > ' . $config['contentNodeType'] . '"), { - '; + $inlineJavaScript = ' + document.documentElement.className = "' . $this->addPrefix('plugin1-hasJS', $tabId) . ' " + + document.documentElement.className; + $(document).ready(function() { + window.TabBar' . $config['counter'] . ' = new TabBar( + $("#' . $menuId . ' > ' . $config['menuNodeType'] . '"), + $("#' . $contentId . ' > ' . $config['contentNodeType'] . '"), { + '; + + if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '9.0.0', '<')) { + $sysLanguageUid = $GLOBALS['TSFE']->sys_language_uid; } else { - $inlineJavaScript = ' - document.documentElement.className = "' . $this->addPrefix('plugin1-hasJS', $tabId) . ' " - + document.documentElement.className; - window.addEvent("domready", function() { - this.TabBar' . $config['counter'] . ' = new TabBar( - $("#' . $menuId . ' > ' . $config['menuNodeType'] . '"), - $("#' . $contentId . ' > ' . $config['contentNodeType'] . '"), { - '; + $context = GeneralUtility::makeInstance(Context::class); + $sysLanguageUid = $context->getPropertyFromAspect('language', 'id'); } $inlineJavaScript .= ' autoPlayInterval: ' . $config['autoPlayInterval'] . ', enableAjax: ' . ($config['ajax'] ? 'true' : 'false') . ', - ajaxPageId: ' . intval($GLOBALS['TSFE']->id) . ', - ajaxLanguageId: ' . (int) $GLOBALS['TSFE']->sys_language_uid . ', - ajaxRecords: "' . implode(',', $records) . '", + ajaxPageId: ' . (int) $GLOBALS['TSFE']->id . ', + ajaxLanguageId: ' . $sysLanguageUid . ', + ajaxRecords: "' . \implode(',', $records) . '", ajaxPluginMode: "' . $mode . '", enableAutoPlay: ' . ($config['enableAutoPlay'] ? 'true' : 'false') . ', enableMouseOver: ' . ($config['enableMouseOver'] ? 'true' : 'false') . ', @@ -186,19 +185,20 @@ class TypoScriptView implements SingletonInterface { */ public function renderTabs($tabElements, $tabId) { $config = &$this->pluginConfiguration[$tabId]; - if (!count($tabElements)) { + if (!\count($tabElements)) { return LocalizationUtility::translate( 'df_tabs', 'LLL:EXT:df_tabs/Resources/Private/Language/locallang.xlf:noContentFound' ); } $tabContents = $tabMenuEntries = ''; - for ($index = 0; $index < count($tabElements); ++$index) { + $tabElementsCount = \count($tabElements); + for ($index = 0; $index < $tabElementsCount; ++$index) { $tabContents .= $this->getTabContent($tabElements[$index], $index, $tabId); $tabMenuEntries .= $this->getTabMenuEntry($tabElements[$index], $index, $tabId); } - $tabContents = str_replace( + $tabContents = \str_replace( ['###CLASSES###', '###ID###'], [ $this->addPrefix('tabContents', $tabId), @@ -207,7 +207,7 @@ class TypoScriptView implements SingletonInterface { $this->stdWrap($tabContents, 'tabContents', $tabId) ); - $tabMenuEntries = str_replace( + $tabMenuEntries = \str_replace( ['###CLASSES###', '###ID###'], [ $this->addPrefix('tabMenu', $tabId), @@ -236,7 +236,7 @@ class TypoScriptView implements SingletonInterface { $linkId = $this->pluginConfiguration[$tabId]['hashName'] . $index; $typolink = $target = ''; - if (strpos($menuEntry, '###LINK###') !== FALSE) { + if (\strpos($menuEntry, '###LINK###') !== FALSE) { $typolink = $this->contentObject->typoLink( '', [ 'parameter' => $tabElement->getLink(), @@ -255,7 +255,7 @@ class TypoScriptView implements SingletonInterface { $linkAnchor = '#' . $linkId; $hash = $linkAnchor; - if (strpos($menuEntry, '###LINK_ANCHOR###') !== FALSE && + if (\strpos($menuEntry, '###LINK_ANCHOR###') !== FALSE && $GLOBALS['TSFE']->config['baseURL'] !== '' ) { $linkAnchor = $this->contentObject->typoLink( @@ -267,7 +267,7 @@ class TypoScriptView implements SingletonInterface { ); } - $menuEntry = str_replace( + $menuEntry = \str_replace( ['###CLASSES###', '###ID###', '###LINK_ANCHOR###', '###LINK_ID###', '###LINK###', '###TARGET###', '###HASH###'], [$classes, $id, $linkAnchor, $linkId, $typolink, $target, $hash], $menuEntry @@ -290,13 +290,13 @@ class TypoScriptView implements SingletonInterface { $tabContent = $this->stdWrap($tabElement->getContent(), 'tabContent', $tabId); $classes = $this->addPrefix('tabContent', $tabId) . ($index === 0 ? ' ' . $this->addPrefix('tabContentSelected', $tabId) : ''); - $tabContent = str_replace( + $tabContent = \str_replace( ['###CLASSES###', '###ID###'], [$classes, $this->addPrefix('tabContent' . $index, $tabId)], $tabContent ); - $tab = str_replace( + $tab = \str_replace( '###CLASSES###', $this->addPrefix('tabTitle', $tabId), $this->stdWrap($tabElement->getTitle(), 'tabTitle', $tabId) diff --git a/Configuration/TypoScript/constants.typoscript b/Configuration/TypoScript/constants.typoscript index 4ef4a64..5e752c8 100644 --- a/Configuration/TypoScript/constants.typoscript +++ b/Configuration/TypoScript/constants.typoscript @@ -1,10 +1,6 @@ plugin.tx_dftabs_plugin1 { css = EXT:df_tabs/Resources/Public/StyleSheets/df_tabs.css js { - history = EXT:df_tabs/Resources/Public/Scripts/History/History.js - historyRouting = EXT:df_tabs/Resources/Public/Scripts/History/History.Routing.js - app = EXT:df_tabs/Resources/Public/Scripts/df_tabs.js - jqueryApp = EXT:df_tabs/Resources/Public/Scripts/jquery.tabs.js } diff --git a/Configuration/TypoScript/setup.typoscript b/Configuration/TypoScript/setup.typoscript index 1e7fdde..90e3a7d 100644 --- a/Configuration/TypoScript/setup.typoscript +++ b/Configuration/TypoScript/setup.typoscript @@ -3,17 +3,7 @@ page.includeCSS { } page.includeJS { - history = {$plugin.tx_dftabs_plugin1.js.history} - history.if.isFalse.data = global:TYPO3_CONF_VARS|EXTCONF|df_tabs|useJQuery - - historyRouting = {$plugin.tx_dftabs_plugin1.js.historyRouting} - historyRouting.if.isFalse.data = global:TYPO3_CONF_VARS|EXTCONF|df_tabs|useJQuery - - dftabs = {$plugin.tx_dftabs_plugin1.js.app} - dftabs.if.isFalse.data = global:TYPO3_CONF_VARS|EXTCONF|df_tabs|useJQuery - dftabs_jQuery = {$plugin.tx_dftabs_plugin1.js.jqueryApp} - dftabs_jQuery.if.isTrue.data = global:TYPO3_CONF_VARS|EXTCONF|df_tabs|useJQuery } plugin.tx_dftabs_plugin1 { diff --git a/README.md b/README.md index 029cd5f..f153a2d 100644 --- a/README.md +++ b/README.md @@ -174,11 +174,6 @@ There are various settings in the **setup.txt** TypoScript file, which allow you } } -#### Extension Settings - - basic.useJQuery = 1 -Set this setting ot "1" to use JQuerys instead of mootools (default). - #### Plugin Settings ##### Mode diff --git a/composer.json b/composer.json index 1ac5321..f7b07d8 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,10 @@ "issues": "https://gitlab.sgalinski.de/typo3/df_tabs/issues" }, "require": { - "typo3/cms-core": "7.6.0 - 9.5.99" + "typo3/cms-core": "^8.7.22 || ^9.5.3" + }, + "require-dev": { + "roave/security-advisories": "dev-master" }, "replace": { "df_tabs": "self.version" diff --git a/ext_conf_template.txt b/ext_conf_template.txt deleted file mode 100644 index 6bc8579..0000000 --- a/ext_conf_template.txt +++ /dev/null @@ -1,2 +0,0 @@ -# cat=basic; type=bool; label=Use JQuery:Set this setting ot "1" to use JQuerys instead of mootools -useJQuery = 0 \ No newline at end of file diff --git a/ext_emconf.php b/ext_emconf.php index 7e0c1e6..fb55c83 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -34,8 +34,8 @@ $EM_CONF[$_EXTKEY] = array( 'CGLcompliance_note' => '', 'constraints' => array( 'depends' => array( - 'php' => '5.5.0-7.3.99', - 'typo3' => '7.6.0-9.5.99', + 'php' => '7.0.0-7.3.99', + 'typo3' => '8.7.0-9.5.99', ), 'conflicts' => array( ), diff --git a/ext_localconf.php b/ext_localconf.php index bcc379b..6e76053 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -28,14 +28,14 @@ call_user_func( function ($extKey) { \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPItoST43( - $extKey, '', '_plugin1', 'list_type', 1 + $extKey, '', '_plugin1', 'list_type', TRUE + ); + // we correct the classname of the plugin controller + \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScriptSetup( + 'plugin.tx_dftabs_plugin1.userFunc=' . \SGalinski\DfTabs\Controller\PluginController::class . '->main' ); $GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include'][$extKey] = 'EXT:df_tabs/Classes/Ajax/LoadAjax.php'; - - // set global storage pid - $dfTabsExtConf = \SGalinski\DfTabs\Utility\ExtensionUtility::getExtensionConfiguration(); - $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$extKey]['useJQuery'] = $dfTabsExtConf['useJQuery'] ? 1 : 0; }, 'df_tabs' ); -- GitLab From 98825a313ca823eed71ed2bea675fb3c5362ef81 Mon Sep 17 00:00:00 2001 From: Kevin Ditscheid Date: Wed, 16 Jan 2019 14:52:01 +0100 Subject: [PATCH 05/11] [TASK] Remove the Ajax content loading --- Classes/Ajax/LoadAjax.php | 178 ------- Classes/Controller/PluginController.php | 30 -- .../AbstractDataBaseDataProvider.php | 15 - .../DataProvider/InterfaceDataProvider.php | 8 - .../DataProvider/TypoScriptDataProvider.php | 12 - Classes/Domain/Repository/TabRepository.php | 7 +- Classes/Service/ConfigurationService.php | 6 - Classes/Utility/ExtensionUtility.php | 2 +- Classes/View/TypoScriptView.php | 12 - Configuration/FlexForms/flexform.xml | 10 - Configuration/TCA/Overrides/tt_content.php | 1 - Configuration/TypoScript/constants.typoscript | 7 - Configuration/TypoScript/setup.typoscript | 17 +- README.md | 11 +- Resources/Private/Language/de.locallang.xlf | 6 +- Resources/Private/Language/locallang.xlf | 5 +- .../Public/Scripts/History/History.Routing.js | 145 ------ Resources/Public/Scripts/History/History.js | 114 ----- Resources/Public/Scripts/df_tabs.js | 465 ------------------ Resources/Public/Scripts/jquery.tabs.js | 44 +- .../AbstractBaseDataProviderTest.php | 2 +- .../AbstractDataBaseDataProviderTest.php | 17 - .../TypoScriptDataProviderTest.php | 22 - .../Domain/Repository/TabRepositoryTest.php | 25 - composer.json | 2 +- ext_emconf.php | 3 +- ext_localconf.php | 2 - 27 files changed, 11 insertions(+), 1157 deletions(-) delete mode 100644 Classes/Ajax/LoadAjax.php delete mode 100644 Resources/Public/Scripts/History/History.Routing.js delete mode 100644 Resources/Public/Scripts/History/History.js delete mode 100644 Resources/Public/Scripts/df_tabs.js diff --git a/Classes/Ajax/LoadAjax.php b/Classes/Ajax/LoadAjax.php deleted file mode 100644 index 4f163cf..0000000 --- a/Classes/Ajax/LoadAjax.php +++ /dev/null @@ -1,178 +0,0 @@ -initTSFE($parameters['id'], $parameters['languageId']); - - /** @var $controller \tx_dftabs_plugin1 */ - $controller = GeneralUtility::makeInstance('tx_dftabs_plugin1'); - $controller->cObj = $GLOBALS['TSFE']->cObj; - $controller->conf = $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_dftabs_plugin1.']; - $controller->conf['ajax'] = FALSE; - - $records = GeneralUtility::trimExplode(',', $parameters['records']); - $this->content = $controller->ajax($records, $parameters['mode']); - - if (t3lib_extMgm::isLoaded('content_replacer')) { - $extensionPath = t3lib_extMgm::extPath('content_replacer'); - require_once($extensionPath . 'Classes/Controller/class.tx_contentreplacer_controller_main.php'); - - /** @var $contentReplacer tx_contentreplacer_controller_Main */ - $contentReplacer = t3lib_div::makeInstance('tx_contentreplacer_controller_Main'); - $this->content = $contentReplacer->main($this->content); - } - } - - /** - * Converts relative paths in the HTML source to absolute paths for fileadmin/, typo3conf/ext/ and media/ folders. - * - * Note: Copied from the TypoScriptFrontendController and should be removed with a force to 6.2.6. - * - * @return void - * @see pagegen.php, INTincScript() - */ - public function setAbsRefPrefix() { - if (!$GLOBALS['TSFE']->absRefPrefix) { - return; - } - $search = array( - '"typo3temp/', - '"typo3conf/ext/', - '"' . TYPO3_mainDir . 'contrib/', - '"' . TYPO3_mainDir . 'ext/', - '"' . TYPO3_mainDir . 'sysext/', - '"' . $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], - '"' . $GLOBALS['TYPO3_CONF_VARS']['BE']['RTE_imageStorageDir'] - ); - $replace = array( - '"' . $GLOBALS['TSFE']->absRefPrefix . 'typo3temp/', - '"' . $GLOBALS['TSFE']->absRefPrefix . 'typo3conf/ext/', - '"' . $GLOBALS['TSFE']->absRefPrefix . TYPO3_mainDir . 'contrib/', - '"' . $GLOBALS['TSFE']->absRefPrefix . TYPO3_mainDir . 'ext/', - '"' . $GLOBALS['TSFE']->absRefPrefix . TYPO3_mainDir . 'sysext/', - '"' . $GLOBALS['TSFE']->absRefPrefix . $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], - '"' . $GLOBALS['TSFE']->absRefPrefix . $GLOBALS['TYPO3_CONF_VARS']['BE']['RTE_imageStorageDir'] - ); - $this->content = str_replace( - $search, - $replace, - $this->content - ); - } - - /** - * Prints the content - * - * @return void - */ - public function printContent() { - header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); - header('Cache-Control: no-store, no-cache, must-revalidate'); - header('Cache-Control: post-check=0, pre-check=0', FALSE); - header('Pragma: no-cache'); - - $this->setAbsRefPrefix(); - - echo $this->content; - } - - /** - * Initializes the TSFE object - * - * @param int $pageId - * @param int $languageId - * @return void - */ - protected function initTSFE($pageId, $languageId) { - if (is_object($GLOBALS['TSFE'])) { - return; - } - - $pageId = (int) $pageId; - $language = (int) $languageId; - t3lib_div::_GETset($language, 'L'); - t3lib_div::_GETset($pageId, 'pageId'); - - /** @var $typoScriptController tslib_fe */ - $GLOBALS['TSFE'] = $typoScriptController = t3lib_div::makeInstance( - 'tslib_fe', $GLOBALS['TYPO3_CONF_VARS'], $pageId, 0 - ); - -// if (!is_object($GLOBALS['TT'])) { -// $GLOBALS['TT'] = new NullTimeTracker(); -// } - $typoScriptController->initFEuser(); - $typoScriptController->initUserGroups(); - $typoScriptController->fetch_the_id(); - $typoScriptController->getPageAndRootline(); - $typoScriptController->initTemplate(); -// $typoScriptController->forceTemplateParsing = TRUE; -// $typoScriptController->getCompressedTCarray(); - $typoScriptController->no_cache = TRUE; - $typoScriptController->getConfigArray(); - $typoScriptController->settingLocale(); - $typoScriptController->settingLanguage(); -// $typoScriptController->no_cache = TRUE; -// $typoScriptController->tmpl->start($GLOBALS['TSFE']->rootLine); -// $typoScriptController->no_cache = FALSE; - $typoScriptController->newCObj(); - $typoScriptController->absRefPrefix = ($typoScriptController->config['config']['absRefPrefix'] ?: ''); - } -} - -/** @var $object LoadAjax */ -$object = GeneralUtility::makeInstance('Tx_DfTabs_Ajax_LoadAjax'); -$object->main(); -$object->printContent(); - -?> diff --git a/Classes/Controller/PluginController.php b/Classes/Controller/PluginController.php index a64a4e7..7884c4a 100644 --- a/Classes/Controller/PluginController.php +++ b/Classes/Controller/PluginController.php @@ -159,36 +159,6 @@ class PluginController extends AbstractPlugin { $this->prefixId = $this->pluginConfiguration['classPrefix'] . 'plugin1'; return $this->pi_wrapInBaseClass($content); } - - /** - * Controls the data flow for the usage within an AJAX call that should - * only return the contents of the given records - * - * @param array $records - * @param string $mode - * @return string - */ - public function ajax($records, $mode) { - $content = ''; - try { - $configurationManager = $this->getConfigurationManager(); - $this->pluginConfiguration = $configurationManager->getConfiguration(); - $this->pluginConfiguration['mode'] = $mode; - - $repository = $this->getTabRepository(); - $tabElements = $repository->buildTabElements(array(), $records); - - /** @var $element Tab */ - foreach ($tabElements as $element) { - $content .= '
' . $element->getContent() . '
'; - } - - } catch (\Exception $exception) { - $content = $exception->getMessage(); - } - - return $content; - } } ?> diff --git a/Classes/DataProvider/AbstractDataBaseDataProvider.php b/Classes/DataProvider/AbstractDataBaseDataProvider.php index 346e34b..801c0f0 100644 --- a/Classes/DataProvider/AbstractDataBaseDataProvider.php +++ b/Classes/DataProvider/AbstractDataBaseDataProvider.php @@ -159,19 +159,4 @@ abstract class AbstractDataBaseDataProvider extends AbstractBaseDataProvider { return $this->cachedRecord[$uid][$this->pluginConfiguration[$this->table . '.']['linkField']]; } - - /** - * Returns the ajax fallback text for this specific id - * - * @param int $uid - * @return string - * @throws \TYPO3\CMS\Core\Context\Exception\AspectNotFoundException - */ - public function getAjaxFallbackText($uid) { - if (!isset($this->cachedRecord[$uid])) { - $this->cachedRecord[$uid] = $this->getRecordData($uid); - } - - return $this->cachedRecord[$uid][$this->pluginConfiguration[$this->table . '.']['ajaxFallbackTextField']]; - } } diff --git a/Classes/DataProvider/InterfaceDataProvider.php b/Classes/DataProvider/InterfaceDataProvider.php index 97def05..ff1b2f4 100644 --- a/Classes/DataProvider/InterfaceDataProvider.php +++ b/Classes/DataProvider/InterfaceDataProvider.php @@ -53,14 +53,6 @@ interface InterfaceDataProvider { * @return string */ public function getLinkData($uid); - - /** - * Returns the ajax fallback text for this specific id - * - * @param int $uid - * @return string - */ - public function getAjaxFallbackText($uid); } ?> diff --git a/Classes/DataProvider/TypoScriptDataProvider.php b/Classes/DataProvider/TypoScriptDataProvider.php index 4307bc8..301f39b 100644 --- a/Classes/DataProvider/TypoScriptDataProvider.php +++ b/Classes/DataProvider/TypoScriptDataProvider.php @@ -62,16 +62,4 @@ class TypoScriptDataProvider extends AbstractBaseDataProvider { '', $this->pluginConfiguration['stdWrap.']['typoscriptLinks.']['tab' . $uid . '.'] ); } - - /** - * Returns the ajax fallback text for this typoscript element - * - * @param int $uid - * @return string - */ - public function getAjaxFallbackText($uid) { - return $this->contentObject->stdWrap( - '', $this->pluginConfiguration['stdWrap.']['typoscriptAjaxFallbackText.']['tab' . $uid . '.'] - ); - } } diff --git a/Classes/Domain/Repository/TabRepository.php b/Classes/Domain/Repository/TabRepository.php index 8b80b24..43cafd4 100644 --- a/Classes/Domain/Repository/TabRepository.php +++ b/Classes/Domain/Repository/TabRepository.php @@ -123,7 +123,6 @@ class TabRepository { public function buildTabElements($preferredTitles, $records) { $tabElements = []; $amountOfTabs = max(count($preferredTitles), count($records)); - $hasAJAX = ($this->pluginConfiguration['ajax'] == TRUE); for ($index = 0; $index < $amountOfTabs; ++$index) { $recordId = $records[$index]; $type = $this->pluginConfiguration['mode']; @@ -150,11 +149,7 @@ class TabRepository { /** @var $tabElement Tab */ $tabElement = GeneralUtility::makeInstance(Tab::class, htmlspecialchars($title), $recordId); $tabElement->setLink($dataProvider->getLinkData($recordId)); - if (!$hasAJAX || ($hasAJAX && !$index)) { - $tabElement->setContent($dataProvider->getTabContent($recordId)); - } else { - $tabElement->setContent($dataProvider->getAjaxFallbackText($recordId)); - } + $tabElement->setContent($dataProvider->getTabContent($recordId)); $tabElements[] = $tabElement; } diff --git a/Classes/Service/ConfigurationService.php b/Classes/Service/ConfigurationService.php index 5ab830d..4a58c1d 100644 --- a/Classes/Service/ConfigurationService.php +++ b/Classes/Service/ConfigurationService.php @@ -123,12 +123,6 @@ class ConfigurationService { protected function getFlexformConfiguration() { $data =& $this->controllerContext->cObj->data['pi_flexform']; $configuration = []; -// @todo Disables the ajax functionality -// $value = trim($this->controllerContext->pi_getFFvalue($data, 'ajax')); -// if ($value !== '') { -// $configuration['ajax'] = $value; -// } - $configuration['ajax'] = FALSE; $value = \trim($this->controllerContext->pi_getFFvalue($data, 'enableAutoPlay')); if ($value !== '') { diff --git a/Classes/Utility/ExtensionUtility.php b/Classes/Utility/ExtensionUtility.php index 03bf27b..a70971b 100644 --- a/Classes/Utility/ExtensionUtility.php +++ b/Classes/Utility/ExtensionUtility.php @@ -48,7 +48,7 @@ class ExtensionUtility { ); } - return $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['df_tabs']; + return $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['df_tabs'] ?? []; } /** diff --git a/Classes/View/TypoScriptView.php b/Classes/View/TypoScriptView.php index d6f1a07..39dae39 100644 --- a/Classes/View/TypoScriptView.php +++ b/Classes/View/TypoScriptView.php @@ -139,20 +139,8 @@ class TypoScriptView implements SingletonInterface { $("#' . $contentId . ' > ' . $config['contentNodeType'] . '"), { '; - if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '9.0.0', '<')) { - $sysLanguageUid = $GLOBALS['TSFE']->sys_language_uid; - } else { - $context = GeneralUtility::makeInstance(Context::class); - $sysLanguageUid = $context->getPropertyFromAspect('language', 'id'); - } - $inlineJavaScript .= ' autoPlayInterval: ' . $config['autoPlayInterval'] . ', - enableAjax: ' . ($config['ajax'] ? 'true' : 'false') . ', - ajaxPageId: ' . (int) $GLOBALS['TSFE']->id . ', - ajaxLanguageId: ' . $sysLanguageUid . ', - ajaxRecords: "' . \implode(',', $records) . '", - ajaxPluginMode: "' . $mode . '", enableAutoPlay: ' . ($config['enableAutoPlay'] ? 'true' : 'false') . ', enableMouseOver: ' . ($config['enableMouseOver'] ? 'true' : 'false') . ', classPrefix: "' . $config['classPrefix'] . '", diff --git a/Configuration/FlexForms/flexform.xml b/Configuration/FlexForms/flexform.xml index 41b8e97..b973804 100644 --- a/Configuration/FlexForms/flexform.xml +++ b/Configuration/FlexForms/flexform.xml @@ -56,16 +56,6 @@ - - - - - - - - - - diff --git a/Configuration/TCA/Overrides/tt_content.php b/Configuration/TCA/Overrides/tt_content.php index 7366962..4796a48 100644 --- a/Configuration/TCA/Overrides/tt_content.php +++ b/Configuration/TCA/Overrides/tt_content.php @@ -46,7 +46,6 @@ call_user_func( \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue( 'df_tabs_plugin1', 'FILE:EXT:' . $extKey . '/Configuration/FlexForms/flexform.xml' ); - }, 'df_tabs', 'tt_content' ); diff --git a/Configuration/TypoScript/constants.typoscript b/Configuration/TypoScript/constants.typoscript index 5e752c8..9bed253 100644 --- a/Configuration/TypoScript/constants.typoscript +++ b/Configuration/TypoScript/constants.typoscript @@ -17,7 +17,6 @@ plugin.tx_dftabs_plugin1 { contentNodeType = div animationCallback = changeHashOnTabChange = 0 - ajax = 0 removeFromTitle = # flexform options for the plugin usage with plain typoscript @@ -36,17 +35,11 @@ plugin.tx_dftabs_plugin1 { titleField = title linkField = uid - - # be careful that this text will be rendered in the AJAX version too (Cloaking) - ajaxFallbackTextField = subtitle } # tt_content mode related configuration settings tt_content { titleField = header linkField = header_link - - # be careful that this text will be rendered in the AJAX version too (Cloaking) - ajaxFallbackTextField = altText } } diff --git a/Configuration/TypoScript/setup.typoscript b/Configuration/TypoScript/setup.typoscript index 90e3a7d..c57a8a2 100644 --- a/Configuration/TypoScript/setup.typoscript +++ b/Configuration/TypoScript/setup.typoscript @@ -20,14 +20,13 @@ plugin.tx_dftabs_plugin1 { contentNodeType = {$plugin.tx_dftabs_plugin1.contentNodeType} animationCallback = {$plugin.tx_dftabs_plugin1.animationCallback} changeHashOnTabChange = {$plugin.tx_dftabs_plugin1.changeHashOnTabChange} - ajax = {$plugin.tx_dftabs_plugin1.ajax} removeFromTitle = {$plugin.tx_dftabs_plugin1.removeFromTitle} # flexform options for the usage of this plugin inside plain typoscript enableAutoPlay = {$plugin.tx_dftabs_plugin1.enableAutoPlay} autoPlayInterval = {$plugin.tx_dftabs_plugin1.autoPlayInterval} enableMouseOver = {$plugin.tx_dftabs_plugin1.enableMouseOver} - mode = {$plugin.tx_dftabs_plugin1.mode}ext_conf_template.txt + mode = {$plugin.tx_dftabs_plugin1.mode} titles = {$plugin.tx_dftabs_plugin1.titles} pages = {$plugin.tx_dftabs_plugin1.pages} tt_content = {$plugin.tx_dftabs_plugin1.tt_content} @@ -46,14 +45,12 @@ plugin.tx_dftabs_plugin1 { additionalWhere = {$plugin.tx_dftabs_plugin1.pages.additionalWhere} titleField = {$plugin.tx_dftabs_plugin1.pages.titleField} linkField = {$plugin.tx_dftabs_plugin1.pages.linkField} - ajaxFallbackTextField = {$plugin.tx_dftabs_plugin1.pages.ajaxFallbackTextField} } # tt_content mode related configuration settings tt_content { titleField = {$plugin.tx_dftabs_plugin1.tt_content.titleField} linkField = {$plugin.tx_dftabs_plugin1.tt_content.linkField} - ajaxFallbackTextField = {$plugin.tx_dftabs_plugin1.tt_content.ajaxFallbackTextField} } # output customization @@ -147,18 +144,6 @@ plugin.tx_dftabs_plugin1 { # typoscriptLinks.tab1.cObject.value = 12 _blank typoscriptLinks = - # Only in TypoScript Mode - # - # Fallback text for the ajax option - # Note: This text must be visibile in the fallback and AJAX version, - # because of cloaking issues! - # (tab will be incremented for each tab) - # - # Example: - # typoscriptAjaxFallbackText.tab1.cObject = TEXT - # typoscriptAjaxFallbackText.tab1.cObject.value = Fallback Text - typoscriptAjaxFallbackText = - # Extra configuration for the rendering of tt_content elements # for the modes pages, tt_content and combined records = diff --git a/README.md b/README.md index f153a2d..a365970 100644 --- a/README.md +++ b/README.md @@ -78,10 +78,7 @@ Furthermore you can define an auto-play mechanism with a custom interval to impl # Javascript callback function that is triggered for the tab switches. The default is no animation animationCallback = - - # Use ajax for post-loading of the contents to improve the initial loading performance - ajax = 0 - + # Remove a substring from all tab-title. Can be either a string, or a regex. This example will remove the string # 'Foo' if is found at the end of the title. removeFromTitle = Foo$ @@ -123,9 +120,6 @@ Furthermore you can define an auto-play mechanism with a custom interval to impl # Link field for links linkField = uid - - # Ajax fallback text field for non-javascript users with the ajax option; Note that this text must be visible in the Ajax and Fallback mode or you will get problems with cloaking - ajaxFallbackTextField = subtitle } # tt_content mode related configuration settings @@ -136,9 +130,6 @@ Furthermore you can define an auto-play mechanism with a custom interval to impl # Link field for links linkField = header_link - - # Ajax fallback text field for non-javascript users with the ajax option; Note that this text must be visible in the Ajax and Fallback mode or you will get problems with cloaking - ajaxFallbackTextField = altText } #### Output customization diff --git a/Resources/Private/Language/de.locallang.xlf b/Resources/Private/Language/de.locallang.xlf index 0a36b17..52e5ea1 100644 --- a/Resources/Private/Language/de.locallang.xlf +++ b/Resources/Private/Language/de.locallang.xlf @@ -9,10 +9,6 @@ stefan.galinski@gmail.com - - Enable AJAX - AJAX aktivieren - Autoplay Interval Auto-Play-Intervall @@ -71,4 +67,4 @@ - \ No newline at end of file + diff --git a/Resources/Private/Language/locallang.xlf b/Resources/Private/Language/locallang.xlf index a8f4f9c..f18a541 100644 --- a/Resources/Private/Language/locallang.xlf +++ b/Resources/Private/Language/locallang.xlf @@ -9,9 +9,6 @@ stefan.galinski@gmail.com - - Enable AJAX - Autoplay Interval @@ -56,4 +53,4 @@ - \ No newline at end of file + diff --git a/Resources/Public/Scripts/History/History.Routing.js b/Resources/Public/Scripts/History/History.Routing.js deleted file mode 100644 index 13a2471..0000000 --- a/Resources/Public/Scripts/History/History.Routing.js +++ /dev/null @@ -1,145 +0,0 @@ -/** - * History.Routing - * - * @version 2.0 - * - * @license MIT License - * @author Harald Kirschner - * @copyright 2008 Author - */ - -History.implement(new Options()); - -History.implement({ - - options: { - separator: ';' - }, - - routes: [], - - register: function(route) { - if (this.routes.push(route) === 1) { - this.addEvent('changed', this.match); - } - }, - - unregister: function(route) { - this.routes.remove(route); - }, - - match: function(state, previous, manual) { - if (!manual) { - //noinspection JSCheckFunctionSignatures - this.routes.each(Function.methodize('match', this.hashState)); - } - }, - - generate: function() { - //noinspection JSCheckFunctionSignatures - return this.routes.map(Function.methodize('generate')).clean().join(this.options.separator); - }, - - update: function() { - return this.setState(this.generate()); - } - -}); - -History.Route = new Class({ - - Implements: [Events, Options], - - /** - * pattern: Regular expression that matches the string updated from onGenerate - * defaults: Default values array, initially empty. - * flags: When regexp is a String, this is the second argument for new RegExp. - * skipDefaults: default true; generate is not called when current values are similar to the default values. - * generate: Should return the string for the state string, values are first argument - * onMatch: Will be called when the regexp matches, with the new values as argument. - */ - options: { - skipDefaults: true, - skipDefaultMatch: false, - defaults: [], - pattern: null, - flags: '', - generate: function(values) { - return values[0]; - }, - onMatch: function() { - } - }, - - initialize: function(options) { - this.setOptions(options); - this.pattern = this.options.pattern || '(.*)'; - if (typeOf(this.pattern) === 'string') { - this.pattern = new RegExp(this.pattern, this.options.flags); - } - this.values = this.defaults = this.options.defaults.slice(); - History.register(this); - return this; - }, - - setValues: function(values) { - if (this.values.toString() === values.toString()) { - return this; - } - this.values = values; - History.update(); - return this; - }, - - setValue: function(index, value) { - if (this.values[index] === value) { - return this; - } - this.values[index] = value; - History.update(); - return this; - }, - - build: function(values) { - var tmp = this.values; - this.values = values; - var state = History.generate(); - this.values = tmp; - return state; - }, - - destroy: function() { - History.unregister(this); - }, - - generate: function() { - if (this.options.skipDefaultMatch && (String(this.values) === String(this.defaults))) { - return null; - } - return this.options.generate.call(this, this.values); - }, - - match: function(state) { - var bits = state.match(this.pattern); - var defaults = this.defaults; - if (bits) { - bits.splice(0, 1); - for (var i = 0, j = bits.length; i < j; ++i) { - bits[i] = Array.pick([bits[i], defaults[i] || null]); - } - if (String(bits) !== String(defaults)) { - this.values = bits; - } - } else { - this.values = this.defaults; - } - this.fireEvent('onMatch', [this.values, this.defaults]); - } -}); - -Function.methodize = function(name) { - var args = Array.slice(arguments, 1); - return function(obj) { - return obj[name].apply(obj, args); - }; -}; diff --git a/Resources/Public/Scripts/History/History.js b/Resources/Public/Scripts/History/History.js deleted file mode 100644 index 1b4e9ca..0000000 --- a/Resources/Public/Scripts/History/History.js +++ /dev/null @@ -1,114 +0,0 @@ -/** - * History - * - * @version 1.0 - * - * @license MIT License - * @author Harald Kirschner - * @copyright 2008 Author - */ - -var History = Object.append(history, { - implement: function(obj) { - return Object.append(this, obj); - } -}); - -History.implement(new Events(function() { -})); - -History.implement({ - - hashState: '', - - start: function() { - if (this.started) { - return this; - } - this.hashState = this.getHash(); - if (Browser.ie && Browser.version < 8) { - var iframe = new Element('iframe', { - 'src': "javascript:''", - 'styles': { - 'position': 'absolute', - 'top': '-1000px' - } - }).inject(document.body).contentWindow; - var writeState = function(state) { - iframe.document.write("Moo!"); - iframe.document.close(); - }; - Object.append(this, { - '$listener': function(state) { - state = decodeURIComponent(state); - if (this.hashState !== state) { - this.setHash(state).changeState(state, false); - } - }.bind(this), - 'setState': function(state, force) { - if (this.hashState !== state || force) { - if (!force) { - this.setHash(state).changeState(state, true); - } - writeState(state); - } - return this; - }, - 'trace': function() { - var state = this.getHash(); - if (state !== this.hashState) { - writeState(state); - } - } - }); - var check = function() { - if (iframe.document && iframe.document.body) { - check = clearInterval(check); - if (!iframe.document.body.innerHTML) { - this.setState(this.hashState); - } - } - }; - check.periodical(50, this); - } - this.trace.periodical(150, this); - this.started = true; - return this; - }, - - changeState: function(state, manual) { - var stateOld = this.hashState; - this.hashState = state; - this.fireEvent('changed', [state, stateOld, manual]); - }, - - trace: function() { - var state = this.getHash(); - if (state !== this.hashState) { - this.changeState(state, false); - } - }, - - getHash: function() { - var href = location.href, pos = href.indexOf('#') + 1; - return (pos) ? href.substr(pos) : ''; - }, - - setHash: function(state) { - location.hash = '#' + state; - return this; - }, - - setState: function(state) { - if (this.hashState !== state) { - this.setHash(state).changeState(state, true); - } - return this; - }, - - getState: function() { - return this.hashState; - } - -}); diff --git a/Resources/Public/Scripts/df_tabs.js b/Resources/Public/Scripts/df_tabs.js deleted file mode 100644 index 6c1d472..0000000 --- a/Resources/Public/Scripts/df_tabs.js +++ /dev/null @@ -1,465 +0,0 @@ -/** - * A tab-bar widget with very basic functionality - * - * @author Stefan Galinski - */ -var TabBar = new Class({ - Implements: [Options, Events], - - /** - * Available options - * - * startIndex: starting tab index (beginning at 0) - * forceUsageOfLeft: always fall back to 'left' instead of using css transforms for slide - * enableAjax: ajax mode (post-loading of contents) - * ajaxPageId: TYPO3 page id (needed in AJAX case) - * ajaxRecords: Record ids (e.g. pages_12,tt_content4; needed in AJAX case) - * ajaxPluginMode: Plugin Mode (typoscript, pages, tt_content or combined) - * enableAutoPlay: usage of an auto play mechanism to switch between tabs - * autoPlayInterval: the time gap between the switch between two slides - * enableMouseOver: usage of mouse over in addition the normal click event for changing a tab - * classPrefix: prefix for all assigned classes - * hashName: prefix for the location hash listener - * pollingInterval: location hash polling interval - * animateCallback: animation callback function - * - * Events: - * onBeforeInitialize - * onAfterInitialize - * onTabChange - * - * @cfg {Object} - */ - options: { - startIndex: 0, - forceUsageOfLeft: false, - enableAjax: false, - ajaxPageId: 0, - ajaxLanguageId: 0, - ajaxRecords: '', - ajaxPluginMode: '', - enableAutoPlay: false, - autoPlayInterval: 7000, - enableMouseOver: false, - classPrefix: 'tx-dftabs-', - hashName: 'tab', - pollingInterval: 1000, - animationCallback: null, - - onBeforeInitialize: null, - onAfterInitialize: null, - onTabChange: null - }, - - /** - * Tab Entry Array with Fields of Type "Object" - * - * Structure: - * menuItem: related menu element - * contentItem: related content element - * - * @type {Array} - */ - elementMap: [], - - /** - * The Active Tab - * - * @type {int} - */ - previousTab: -1, - - /** - * The AutoPlay Instance - * - * @type {int} - */ - autoPlay: null, - - /** - * Timed Display Method - * - * @type {int} - */ - timedDisplayFunction: null, - - /** - * Initializes the tab widget - * - * @param {string} menuEntries - * @param {string} contentEntries - * @param {object} options - * @return {void} - */ - initialize: function(menuEntries, contentEntries, options) { - this.setOptions(options); - - for (var i = 0; i < menuEntries.length; ++i) { - this.elementMap[i] = {}; - this.elementMap[i].menuItem = menuEntries[i]; - this.elementMap[i].contentItem = contentEntries[i]; - } - - if (this.options.enableAjax) { - this.loadAjaxContents(); - } else { - this.finalizeInitialisation(); - } - }, - - /** - * Finalizes the initialisation for e.g. after the ajax loading of the contents - * - * @return {void} - */ - finalizeInitialisation: function() { - this.fireEvent('onBeforeInitialize', this); - - this.previousTab = this.options.startIndex; - this.parseContentLinks().addEvents().initAutoPlay().initHistory(); - - this.fireEvent('onAfterInitialize', this); - }, - - /** - * Loads the remaining ajax contents and calls the - * finalizeInitialisation() method afterwards. - * - * @return {void} - */ - loadAjaxContents: function() { - - (new Request({ - method: 'get', - url: 'index.php?eID=dftabs', - onComplete: function(response) { - var elements = new Element('div', { html: response }).getChildren(); - Object.each(elements, function(response, index) { - var element = $(this.options.classPrefix + 'tabContent' + (parseInt(index) + 1)); - if (element) { - element.set('html', ''); - element.grab(response); - } - }.bind(this)); - - this.finalizeInitialisation(); - }.bind(this) - })).send( - 'df_tabs[languageId]=' + this.options.ajaxLanguageId + - '&df_tabs[id]=' + this.options.ajaxPageId + - '&df_tabs[records]=' + this.options.ajaxRecords + - '&df_tabs[mode]=' + this.options.ajaxPluginMode - ); - }, - - /** - * Parses all links and adds a smooth scrolling to the tab if the link - * references to an internal tab on the very same page - * - * @return {TabBar} - */ - parseContentLinks: function() { - this.elementMap.each(function(element) { - var links = element.contentItem.getElements('a'); - links.each(function(link) { - var parts = link.href.split('#'); - if (parts[1] && parts[0] === location.href.split('#')[0]) { - var index = parts[1].substr(this.options.hashName.length); - link.addEvent('click', this.scrollToTab.pass(index, this)); - } - }.bind(this)); - }.bind(this)); - - return this; - }, - - /** - * Scrolls to the menu item of the given tab index - * - * @param {int} tabIndex - * @return {void} - */ - scrollToTab: function(tabIndex) { - (new Fx.Scroll(window, { - offset: { - x: 0, - y: this.elementMap[tabIndex].menuItem.getCoordinates().top - } - })).toTop(); - }, - - /** - * Adds the requested events to the tab menu elements - * - * @return {TabBar} - */ - addEvents: function() { - this.elementMap.each(function(element, index) { - if (this.options.enableMouseOver) { - element.menuItem.addEvent('mouseenter', this.timedDisplay.pass([index], this)); - element.contentItem.addEvent('mouseenter', this.clearTimedDisplay.bind(this)); - } else { - element.menuItem.addEvent('click', this.display.pass([index], this)); - } - - if (this.options.enableAutoPlay) { - if (this.options.enableMouseOver) { - element.menuItem.addEvents({ - 'mouseenter': this.stopAutoPlay.bind(this), - 'mouseleave': this.startAutoPlay.bind(this), - 'click': this.startAutoPlay.bind(this) - }); - } else { - element.menuItem.addEvent('click', this.stopAutoPlay.bind(this)); - } - } - }.bind(this)); - - return this; - }, - - /** - * Initializes the autoplay mechanism based on the visibility state - * - * Note: If the visibility state isn't available, the autplay functionality is - * started directly. - * - * @return {TabBar} - */ - initAutoPlay: function() { - var hidden = null, - visibilityChange = null; - if (typeof document.hidden !== 'undefined') { - hidden = 'hidden'; - visibilityChange = 'visibilitychange'; - } else if (typeof document.mozHidden !== 'undefined') { - hidden = 'mozHidden'; - visibilityChange = 'mozvisibilitychange'; - } else if (typeof document.msHidden !== 'undefined') { - hidden = 'msHidden'; - visibilityChange = 'msvisibilitychange'; - } else if (typeof document.webkitHidden !== 'undefined') { - hidden = 'webkitHidden'; - visibilityChange = 'webkitvisibilitychange'; - } - - if (visibilityChange) { - document.addEventListener(visibilityChange, this.toggleAutoplayBasedOnVisibility.bind(this, [ - hidden - ]), false); - this.toggleAutoplayBasedOnVisibility(hidden); - } else { - this.startAutoPlay(); - } - - return this; - }, - - /** - * Initializes the History manager that manages an History to rebuild the back button - * mechanism. - * - * @return {void} - */ - initHistory: function() { - // configure the History routing mechanism - (new History.Route({ - defaults: [], - flags: 'i', - pattern: '(?:^|' + History.options.separator + ')' + this.options.hashName + '(\\d+)', - - // called if a new History entry is created to generate the History key - generate: function(values) { - var index = parseInt(values[0], 10); - return this.options.hashName + (index ? index : ''); - }.bind(this), - - // called if match of the History key occurred while the hash of the url changed - onMatch: function(values) { - if (!values.length && window.location.hash !== '') { - return; - } - - var index = parseInt(values[0], 10); - if (isNaN(index) && this.previousTab !== this.options.startIndex) { - this.display(this.options.startIndex, false); - this.fireEvent('historyBackToStartPage', this); - - } else if (index >= 0 && index < this.elementMap.length) { - this.display(index, false); - this.fireEvent('menuEntryClicked', [this, index]); - } - }.bind(this) - })); - - // initial check if a matching hash was appended to the URL and apply the new state - History.trace(); - - // add listening mechanism to change the contents if the anchor was manually changed - // or the back button was pressed - History.start(); - - // fire the onHistoryInitialized event - this.fireEvent('historyInitialized', this); - }, - - /** - * Adds a small delay before displaying a tab (useful for mouseover) - * - * Note: The delay method is saved in the class property "timedDisplayFunction". - * - * @param {int} nextTabIndex - * @return {TabBar} - */ - timedDisplay: function(nextTabIndex) { - this.clearTimedDisplay(); - this.timedDisplayFunction = this.display.delay(250, this, [nextTabIndex]); - - return this; - }, - - /** - * Clears the timed display function - * - * @return {TabBar} - */ - clearTimedDisplay: function() { - clearTimeout(this.timedDisplayFunction); - - return this; - }, - - /** - * Displays the given tab index - * - * @param {int} nextTabIndex - * @param {Boolean} triggeredByAutoPlay - * @return {TabBar} - */ - display: function(nextTabIndex, triggeredByAutoPlay) { - if (triggeredByAutoPlay !== true) { - triggeredByAutoPlay = false; - } - - nextTabIndex = parseInt(nextTabIndex); - if (isNaN(nextTabIndex) || this.previousTab === nextTabIndex || - nextTabIndex < 0 || nextTabIndex >= this.elementMap.length - ) { - return this; - } - - if (this.options.animationCallback) { - this.options.animationCallback.pass([nextTabIndex, triggeredByAutoPlay], this)(); - } else { - this.animate(nextTabIndex); - } - - this.fireEvent('onTabChange', [this, this.previousTab, nextTabIndex]); - - return this; - }, - - /** - * Default "animation" of the transition between two tabs. In real it's just - * a toggling of the selected classes for the content and menu items. Define - * your own animation function to get a nice effect. - * - * @param {int} nextTabIndex - * @return {TabBar} - */ - animate: function(nextTabIndex) { - this.toggleContentItemSelectionClasses(nextTabIndex); - this.toggleMenuEntrySelectionClasses(nextTabIndex); - this.previousTab = nextTabIndex; - - return this; - }, - - /** - * Toggles the "tabContentSelected" class on the last and current content elements - * - * @param {int} nextTabIndex - * @return {TabBar} - */ - toggleContentItemSelectionClasses: function(nextTabIndex) { - var selectedClass = this.options.classPrefix + 'tabContentSelected'; - this.elementMap[this.previousTab].contentItem.removeClass(selectedClass); - this.elementMap[nextTabIndex].contentItem.addClass(selectedClass); - - return this; - }, - - /** - * Toggles the "tabMenuEntrySelected" class on the last and current menu entries - * - * @param {int} nextTabIndex - * @return {TabBar} - */ - toggleMenuEntrySelectionClasses: function(nextTabIndex) { - var selectedClass = this.options.classPrefix + 'tabMenuEntrySelected'; - this.elementMap[nextTabIndex].menuItem.addClass(selectedClass); - - if (Browser.ie && Browser.version < 10) { - this.elementMap[this.previousTab].menuItem.removeClass(selectedClass). - setStyle('visibility', 'hidden').setStyle('visibility', 'visible'); - } else { - this.elementMap[this.previousTab].menuItem.removeClass(selectedClass); - } - - return this; - }, - - /** - * Toggles the autplay setting based on the visibility state of the page - * - * @param {string} hidden field with the hidden state in the document object - * @return {TabBar} - */ - toggleAutoplayBasedOnVisibility: function(hidden) { - if (!document[hidden]) { - this.startAutoPlay(); - } else { - this.stopAutoPlay(); - } - - return this; - }, - - /** - * Implements the auto-play mechanism - * - * @return {void} - */ - autoPlayMechanism: function() { - if (this.previousTab < this.elementMap.length - 1) { - this.display(this.previousTab + 1, true); - } else { - this.display(0, true); - } - }, - - /** - * Starts the auto-play mechanism - * - * @return {TabBar} - */ - startAutoPlay: function() { - if (this.options.enableAutoPlay && !this.autoPlay) { - this.autoPlay = this.autoPlayMechanism.periodical(this.options.autoPlayInterval, this); - } - - return this; - }, - - /** - * Stops the auto-play mechanism - * - * @return {TabBar} - */ - stopAutoPlay: function() { - clearInterval(this.autoPlay); - this.autoPlay = null; - - return this; - } -}); diff --git a/Resources/Public/Scripts/jquery.tabs.js b/Resources/Public/Scripts/jquery.tabs.js index 511d895..d60d60e 100644 --- a/Resources/Public/Scripts/jquery.tabs.js +++ b/Resources/Public/Scripts/jquery.tabs.js @@ -11,10 +11,6 @@ var TabBar = function(menuEntries, contentEntries, options) { * Available options * * startIndex: starting tab index (beginning at 0) - * enableAjax: ajax mode (post-loading of contents) - * ajaxPageId: TYPO3 page id (needed in AJAX case) - * ajaxRecords: Record ids (e.g. pages_12,tt_content4; needed in AJAX case) - * ajaxPluginMode: Plugin Mode (typoscript, pages, tt_content or combined) * enableAutoPlay: usage of an auto play mechanism to switch between tabs * autoPlayInterval: the time gap between the switch between two slides * enableMouseOver: usage of mouse over in addition the normal click event for changing a tab @@ -32,11 +28,6 @@ var TabBar = function(menuEntries, contentEntries, options) { */ this.options = { startIndex: 0, - enableAjax: false, - ajaxPageId: 0, - ajaxLanguageId: 0, - ajaxRecords: '', - ajaxPluginMode: '', enableAutoPlay: false, autoPlayInterval: 7000, enableMouseOver: false, @@ -90,11 +81,7 @@ var TabBar = function(menuEntries, contentEntries, options) { this.elementMap[i].contentItem = $(contentEntries[i]); } - if (this.options.enableAjax) { - this.loadAjaxContents(); - } else { - this.finalizeInitialisation(); - } + this.finalizeInitialisation(); }; /** @@ -104,7 +91,7 @@ var TabBar = function(menuEntries, contentEntries, options) { */ TabBar.prototype = { /** - * Finalizes the initialisation for e.g. after the ajax loading of the contents + * Finalizes the initialisation * * @return {void} */ @@ -117,33 +104,6 @@ TabBar.prototype = { this.trigger('afterInitialize', this); }, - /** - * Loads the remaining ajax contents and calls the - * finalizeInitialisation() method afterwards. - * - * @return {void} - */ - loadAjaxContents: function() { - $.ajax({ - type: 'get', - url: 'index.php?eID=dftabs', - data: 'df_tabs[languageId]=' + this.options.ajaxLanguageId + - '&df_tabs[id]=' + this.options.ajaxPageId + - '&df_tabs[records]=' + this.options.ajaxRecords + - '&df_tabs[mode]=' + this.options.ajaxPluginMode, - success: function(response) { - $.each($(response), function(index, element) { - var containerElement = $('#' + this.options.classPrefix + 'tabContent' + (parseInt(index, 10) + 1)); - if (containerElement.length) { - containerElement.empty().append($(element)); - } - }.bind(this)); - - this.finalizeInitialisation(); - }.bind(this) - }); - }, - /** * Parses all links and adds a smooth scrolling to the tab if the link * references to an internal tab on the very same page diff --git a/Tests/Unit/DataProvider/AbstractBaseDataProviderTest.php b/Tests/Unit/DataProvider/AbstractBaseDataProviderTest.php index ad5facc..660a3f5 100644 --- a/Tests/Unit/DataProvider/AbstractBaseDataProviderTest.php +++ b/Tests/Unit/DataProvider/AbstractBaseDataProviderTest.php @@ -42,7 +42,7 @@ class Tx_DfTabs_DataProvider_AbstractBaseDataProviderTest extends Tx_DfTabs_Base public function setUp() { $this->fixture = $this->getAccessibleMock( 'Tx_DfTabs_DataProvider_AbstractBaseDataProvider', - array('getLinkData', 'getTabContent', 'getTitle', 'getAjaxFallbackText') + array('getLinkData', 'getTabContent', 'getTitle') ); } diff --git a/Tests/Unit/DataProvider/AbstractDataBaseDataProviderTest.php b/Tests/Unit/DataProvider/AbstractDataBaseDataProviderTest.php index ec7f121..68298f7 100644 --- a/Tests/Unit/DataProvider/AbstractDataBaseDataProviderTest.php +++ b/Tests/Unit/DataProvider/AbstractDataBaseDataProviderTest.php @@ -148,23 +148,6 @@ class Tx_DfTabs_DataProvider_AbstractDataBaseDataProviderTest extends Tx_DfTabs_ $this->assertSame('Foo', $this->fixture->getLinkData(1)); } - /** - * @test - * @return void - */ - public function getAjaxFallbackTextFetchesTheTextFromTheDatabase() { - /** @noinspection PhpUndefinedMethodInspection */ - $this->fixture->_set('table', 'tt_content'); - - $pluginConfiguration = array('tt_content.' => array('ajaxFallbackTextField' => 'altText')); - $this->fixture->injectPluginConfiguration($pluginConfiguration); - - /** @noinspection PhpUndefinedMethodInspection */ - $this->database->expects($this->once())->method('exec_SELECTgetSingleRow') - ->with('*', 'tt_content', 'uid = 1')->will($this->returnValue(array('altText' => 'Foo'))); - $this->assertSame('Foo', $this->fixture->getAjaxFallbackText(1)); - } - /** * @test * @return void diff --git a/Tests/Unit/DataProvider/TypoScriptDataProviderTest.php b/Tests/Unit/DataProvider/TypoScriptDataProviderTest.php index 690ac8e..4944d96 100644 --- a/Tests/Unit/DataProvider/TypoScriptDataProviderTest.php +++ b/Tests/Unit/DataProvider/TypoScriptDataProviderTest.php @@ -105,28 +105,6 @@ class Tx_DfTabs_DataProvider_TypoScriptDataProviderTest extends Tx_DfTabs_BaseTe $this->assertSame('Foo', $this->fixture->getLinkData(1)); } - /** - * @test - * @return void - */ - public function getAjaxFallbackTextReturnsTheResultsOfDedicatedStandardWraps() { - $pluginConfiguration = array( - 'stdWrap.' => array( - 'typoscriptAjaxFallbackText.' => array( - 'tab1.' => array( - 'foo' => 'bar', - ), - ), - ), - ); - $this->fixture->injectPluginConfiguration($pluginConfiguration); - - /** @noinspection PhpUndefinedMethodInspection */ - $this->contentObject->expects($this->once())->method('stdWrap') - ->with('', array('foo' => 'bar'))->will($this->returnValue('Foo')); - - $this->assertSame('Foo', $this->fixture->getAjaxFallbackText(1)); - } } ?> diff --git a/Tests/Unit/Domain/Repository/TabRepositoryTest.php b/Tests/Unit/Domain/Repository/TabRepositoryTest.php index ab57be3..632c637 100644 --- a/Tests/Unit/Domain/Repository/TabRepositoryTest.php +++ b/Tests/Unit/Domain/Repository/TabRepositoryTest.php @@ -142,31 +142,6 @@ class Tx_DfTabs_Domain_Repository_TabRepositoryTest extends Tx_DfTabs_BaseTestCa $this->assertEquals(array($tab1, $tab2), $collection); } - /** - * @test - * @return void - */ - public function buildTabElementsReturnsATabElementCollectionWithAjaxInMind() { - $this->fixture->injectPluginConfiguration(array('ajax' => '1',)); - - $dataProvider = $this->getMock('Tx_DfTabs_DataProvider_AbstractBaseDataProvider'); - /** @noinspection PhpUndefinedMethodInspection */ - $this->fixture->expects($this->exactly(2))->method('getDataProvider')->will($this->returnValue($dataProvider)); - $dataProvider->expects($this->once())->method('getAjaxFallbackText')->will($this->returnValue('Fallback')); - $dataProvider->expects($this->once())->method('getTabContent')->will($this->returnValue('Foo')); - $dataProvider->expects($this->exactly(2))->method('getLinkData')->will($this->returnValue('')); - $dataProvider->expects($this->exactly(2))->method('getTitle')->will($this->returnValue('Bar')); - - $tab1 = new Tx_DfTabs_Domain_Model_Tab('Bar', 2); - $tab1->setContent('Foo'); - - $tab2 = new Tx_DfTabs_Domain_Model_Tab('Bar', 2); - $tab2->setContent('Fallback'); - - $collection = $this->fixture->buildTabElements(array(), array('pages_2', 'tt_content_2')); - $this->assertEquals(array($tab1, $tab2), $collection); - } - /** * @test * @return void diff --git a/composer.json b/composer.json index f7b07d8..560fcf8 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "sgalinski/df-tabs", "type": "typo3-cms-extension", - "description": "Tabbed Content and Pages - Create tab based content elements and pages easily and flexible with configurable mouseover handling, animations, ajax and autoplay features! It requires mootools or jquery.", + "description": "Tabbed Content and Pages - Create tab based content elements and pages easily and flexible with configurable mouseover handling, animations and autoplay features! It requires jquery.", "homepage": "https://www.sgalinski.de", "license": ["GPL-2.0-or-later"], "version": "5.3.0", diff --git a/ext_emconf.php b/ext_emconf.php index fb55c83..f4d2735 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -12,7 +12,7 @@ $EM_CONF[$_EXTKEY] = array( 'title' => 'Tabbed Content and Pages', - 'description' => 'Create tab based content elements and pages easily and flexible with configurable mouseover handling, animations, ajax and autoplay features! It requires mootools or jquery.', + 'description' => 'Create tab based content elements and pages easily and flexible with configurable mouseover handling, animations and autoplay features! It requires jquery.', 'category' => 'fe', 'shy' => 0, 'version' => '5.3.0', @@ -42,7 +42,6 @@ $EM_CONF[$_EXTKEY] = array( 'suggests' => array( ), ), - '_md5_values_when_last_written' => 'a:48:{s:16:"ext_autoload.php";s:4:"24ba";s:21:"ext_conf_template.txt";s:4:"9cfc";s:12:"ext_icon.gif";s:4:"0d1d";s:12:"ext_icon.png";s:4:"6b58";s:17:"ext_localconf.php";s:4:"a4a3";s:14:"ext_tables.php";s:4:"3ae9";s:25:"Classes/Ajax/LoadAjax.php";s:4:"b6d4";s:39:"Classes/Controller/PluginController.php";s:4:"6eb7";s:49:"Classes/DataProvider/AbstractBaseDataProvider.php";s:4:"359c";s:53:"Classes/DataProvider/AbstractDataBaseDataProvider.php";s:4:"954b";s:44:"Classes/DataProvider/ContentDataProvider.php";s:4:"5eaa";s:44:"Classes/DataProvider/FactoryDataProvider.php";s:4:"7cfe";s:46:"Classes/DataProvider/InterfaceDataProvider.php";s:4:"3241";s:42:"Classes/DataProvider/PagesDataProvider.php";s:4:"dbd4";s:47:"Classes/DataProvider/TypoScriptDataProvider.php";s:4:"34e1";s:28:"Classes/Domain/Model/Tab.php";s:4:"a2b1";s:43:"Classes/Domain/Repository/TabRepository.php";s:4:"0005";s:38:"Classes/Exception/GenericException.php";s:4:"b11c";s:40:"Classes/Service/ConfigurationService.php";s:4:"ba60";s:31:"Classes/View/TypoScriptView.php";s:4:"8343";s:40:"Classes/Wizards/ContentElementWizard.php";s:4:"5f2b";s:36:"Configuration/FlexForms/flexform.xml";s:4:"b2c5";s:38:"Configuration/TypoScript/constants.txt";s:4:"241b";s:34:"Configuration/TypoScript/setup.txt";s:4:"e769";s:43:"Resources/Private/Language/de.locallang.xlf";s:4:"0217";s:40:"Resources/Private/Language/locallang.xlf";s:4:"a2b6";s:47:"Resources/Public/Images/backgroundTabActive.png";s:4:"4ec0";s:58:"Resources/Public/Images/backgroundTabActiveAlternative.png";s:4:"31f4";s:49:"Resources/Public/Images/backgroundTabInactive.png";s:4:"0a02";s:48:"Resources/Public/Images/contentElementWizard.png";s:4:"7051";s:35:"Resources/Public/Scripts/df_tabs.js";s:4:"1425";s:39:"Resources/Public/Scripts/jquery.tabs.js";s:4:"c08e";s:40:"Resources/Public/Scripts/tabAnimation.js";s:4:"b30d";s:43:"Resources/Public/Scripts/History/History.js";s:4:"7e00";s:51:"Resources/Public/Scripts/History/History.Routing.js";s:4:"8c7e";s:40:"Resources/Public/StyleSheets/df_tabs.css";s:4:"124d";s:52:"Resources/Public/StyleSheets/df_tabs_alternative.css";s:4:"e5ca";s:27:"Tests/Unit/BaseTestCase.php";s:4:"e936";s:56:"Tests/Unit/DataProvider/AbstractBaseDataProviderTest.php";s:4:"ee34";s:60:"Tests/Unit/DataProvider/AbstractDataBaseDataProviderTest.php";s:4:"eb79";s:51:"Tests/Unit/DataProvider/FactoryDataProviderTest.php";s:4:"9aa2";s:49:"Tests/Unit/DataProvider/PagesDataProviderTest.php";s:4:"b8bc";s:54:"Tests/Unit/DataProvider/TypoScriptDataProviderTest.php";s:4:"1f4a";s:35:"Tests/Unit/Domain/Model/TabTest.php";s:4:"405f";s:50:"Tests/Unit/Domain/Repository/TabRepositoryTest.php";s:4:"0f18";s:47:"Tests/Unit/Service/ConfigurationServiceTest.php";s:4:"7ae3";s:38:"Tests/Unit/View/TypoScriptViewTest.php";s:4:"f4c6";s:14:"doc/manual.sxw";s:4:"565f";}', 'suggests' => array( ), ); diff --git a/ext_localconf.php b/ext_localconf.php index 6e76053..933dbcc 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -34,8 +34,6 @@ call_user_func( \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScriptSetup( 'plugin.tx_dftabs_plugin1.userFunc=' . \SGalinski\DfTabs\Controller\PluginController::class . '->main' ); - - $GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include'][$extKey] = 'EXT:df_tabs/Classes/Ajax/LoadAjax.php'; }, 'df_tabs' ); -- GitLab From 6caba20c247604ee06c475197f705038b624997c Mon Sep 17 00:00:00 2001 From: Kevin Ditscheid Date: Mon, 28 Jan 2019 14:35:36 +0100 Subject: [PATCH 06/11] [BUGFIX] Make getExtensionConfiguration return empty array on failure --- Classes/Utility/ExtensionUtility.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Classes/Utility/ExtensionUtility.php b/Classes/Utility/ExtensionUtility.php index a70971b..f02aff6 100644 --- a/Classes/Utility/ExtensionUtility.php +++ b/Classes/Utility/ExtensionUtility.php @@ -43,9 +43,10 @@ class ExtensionUtility { */ public static function getExtensionConfiguration(): array { if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '9.0.0', '<')) { - return \unserialize( + $extConf = \unserialize( $GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['df_tabs'], ['allowed_classes' => FALSE] ); + return $extConf ?? []; } return $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['df_tabs'] ?? []; -- GitLab From da9d6fa1761def587c18c514a4dfe85093ad0576 Mon Sep 17 00:00:00 2001 From: Kevin Ditscheid Date: Mon, 28 Jan 2019 14:44:11 +0100 Subject: [PATCH 07/11] [BUGFIX] Update the extConf check to check for array after unserializing --- Classes/Utility/ExtensionUtility.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/Utility/ExtensionUtility.php b/Classes/Utility/ExtensionUtility.php index f02aff6..1182658 100644 --- a/Classes/Utility/ExtensionUtility.php +++ b/Classes/Utility/ExtensionUtility.php @@ -46,7 +46,7 @@ class ExtensionUtility { $extConf = \unserialize( $GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['df_tabs'], ['allowed_classes' => FALSE] ); - return $extConf ?? []; + return is_array($extConf) ? $extConf : []; } return $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['df_tabs'] ?? []; -- GitLab From b8763fcf0488d775cb63fdbc677db8062949d55a Mon Sep 17 00:00:00 2001 From: Kevin Ditscheid Date: Tue, 29 Jan 2019 13:14:59 +0100 Subject: [PATCH 08/11] [BUGFIX] Fix some parts where missing config could cause a mess --- Classes/Controller/PluginController.php | 3 +-- Classes/DataProvider/PagesDataProvider.php | 16 +++++++++++----- Classes/Domain/Repository/TabRepository.php | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Classes/Controller/PluginController.php b/Classes/Controller/PluginController.php index 7884c4a..c0bc939 100644 --- a/Classes/Controller/PluginController.php +++ b/Classes/Controller/PluginController.php @@ -26,7 +26,6 @@ namespace SGalinski\DfTabs\Controller; ***************************************************************/ use SGalinski\DfTabs\DataProvider\AbstractBaseDataProvider; -use SGalinski\DfTabs\Domain\Model\Tab; use SGalinski\DfTabs\Domain\Repository\TabRepository; use SGalinski\DfTabs\Service\ConfigurationService; use SGalinski\DfTabs\View\TypoScriptView; @@ -148,7 +147,7 @@ class PluginController extends AbstractPlugin { $renderer = $this->getRenderer($tabId); $records = $repository->getRecords(); - $tabElements = $repository->buildTabElements($this->pluginConfiguration['titles'], $records); + $tabElements = $repository->buildTabElements($this->pluginConfiguration['titles'] ?? [], $records); $content .= $renderer->renderTabs($tabElements, $tabId); $renderer->addInlineJavaScriptCode($records, $this->pluginConfiguration['mode'], $tabId); diff --git a/Classes/DataProvider/PagesDataProvider.php b/Classes/DataProvider/PagesDataProvider.php index 6c7f148..7db123e 100644 --- a/Classes/DataProvider/PagesDataProvider.php +++ b/Classes/DataProvider/PagesDataProvider.php @@ -56,12 +56,18 @@ class PagesDataProvider extends AbstractDataBaseDataProvider { 'pid = ' . ((int) $uid) . $pageRepository->enableFields('tt_content') . ' ' . $this->pluginConfiguration['pages.']['additionalWhere'] . ' AND sys_language_uid IN (0,-1)' - ) - ->setMaxResults($this->pluginConfiguration['pages.']['limit']); - $orderings = \explode(',', $this->pluginConfiguration['pages.']['orderBy']); - foreach ($orderings as $order) { - $queryBuilder->addOrderBy(\trim($order)); + ); + if ($this->pluginConfiguration['pages.']['limit']) { + $queryBuilder->setMaxResults($this->pluginConfiguration['pages.']['limit']); } + + if ($this->pluginConfiguration['pages.']['orderBy']) { + $orderings = \explode(',', $this->pluginConfiguration['pages.']['orderBy']); + foreach ($orderings as $order) { + $queryBuilder->addOrderBy(\trim($order)); + } + } + $contentElements = $queryBuilder->execute()->fetchAll(); return \array_column($contentElements, 'uid'); } diff --git a/Classes/Domain/Repository/TabRepository.php b/Classes/Domain/Repository/TabRepository.php index 43cafd4..31ca361 100644 --- a/Classes/Domain/Repository/TabRepository.php +++ b/Classes/Domain/Repository/TabRepository.php @@ -120,7 +120,7 @@ class TabRepository { * @param array $records * @return array */ - public function buildTabElements($preferredTitles, $records) { + public function buildTabElements(array $preferredTitles, array $records) { $tabElements = []; $amountOfTabs = max(count($preferredTitles), count($records)); for ($index = 0; $index < $amountOfTabs; ++$index) { -- GitLab From d34e93ae2f61fdac203d1843484bad82ccb2a969 Mon Sep 17 00:00:00 2001 From: Kevin Ditscheid Date: Thu, 31 Jan 2019 17:00:36 +0100 Subject: [PATCH 09/11] [TASK] Remove enableFields call, because the QueryBuilder already provides them in the restrictions --- Classes/DataProvider/PagesDataProvider.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Classes/DataProvider/PagesDataProvider.php b/Classes/DataProvider/PagesDataProvider.php index 7db123e..7f86066 100644 --- a/Classes/DataProvider/PagesDataProvider.php +++ b/Classes/DataProvider/PagesDataProvider.php @@ -49,11 +49,10 @@ class PagesDataProvider extends AbstractDataBaseDataProvider { */ public function getContentUids($uid) { $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content'); - $pageRepository = GeneralUtility::makeInstance(PageRepository::class); $queryBuilder->select('uid') ->from('tt_content') ->where( - 'pid = ' . ((int) $uid) . $pageRepository->enableFields('tt_content') . + 'pid = ' . ((int) $uid) . ' ' . $this->pluginConfiguration['pages.']['additionalWhere'] . ' AND sys_language_uid IN (0,-1)' ); -- GitLab From b482b375347b1b2c78caf65278740b594535786a Mon Sep 17 00:00:00 2001 From: Kevin Ditscheid Date: Wed, 6 Feb 2019 14:19:38 +0100 Subject: [PATCH 10/11] [TASK] Integrate the df_tabs plugin via Page TsConfig --- .../Page/NewContentElementWizard.tsconfig | 16 ++++++ ext_localconf.php | 16 ++++++ ext_tables.php | 51 ------------------- 3 files changed, 32 insertions(+), 51 deletions(-) create mode 100644 Configuration/TsConfig/Page/NewContentElementWizard.tsconfig delete mode 100644 ext_tables.php diff --git a/Configuration/TsConfig/Page/NewContentElementWizard.tsconfig b/Configuration/TsConfig/Page/NewContentElementWizard.tsconfig new file mode 100644 index 0000000..baef409 --- /dev/null +++ b/Configuration/TsConfig/Page/NewContentElementWizard.tsconfig @@ -0,0 +1,16 @@ +mod { + wizards.newContentElement.wizardItems.plugins { + elements { + twitter { + iconIdentifier = extension-df_tabs-content-element + title = LLL:EXT:df_tabs/Resources/Private/Language/locallang.xlf:plugin1_title + description = LLL:EXT:df_tabs/Resources/Private/Language/locallang.xlf:plugin1_plus_wiz_description + tt_content_defValues { + CType = list + list_type = df_tabs_plugin1 + } + } + } + show = * + } +} diff --git a/ext_localconf.php b/ext_localconf.php index 933dbcc..994ce7b 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -34,6 +34,22 @@ call_user_func( \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScriptSetup( 'plugin.tx_dftabs_plugin1.userFunc=' . \SGalinski\DfTabs\Controller\PluginController::class . '->main' ); + + \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig( + '' + ); + + /** + * Register icons + */ + $iconRegistry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance( + \TYPO3\CMS\Core\Imaging\IconRegistry::class + ); + $iconRegistry->registerIcon( + 'extension-' . $extKey . '-content-element', + \TYPO3\CMS\Core\Imaging\IconProvider\BitmapIconProvider::class, + ['source' => 'EXT:' . $extKey . '/Resources/Public/Images/contentElementWizard.png'] + ); }, 'df_tabs' ); diff --git a/ext_tables.php b/ext_tables.php deleted file mode 100644 index 1606304..0000000 --- a/ext_tables.php +++ /dev/null @@ -1,51 +0,0 @@ -registerIcon( - 'extension-df_tabs-content-element', - \TYPO3\CMS\Core\Imaging\IconProvider\BitmapIconProvider::class, - ['source' => 'EXT:df_tabs/Resources/Public/Images/contentElementWizard.png'] - ); - }, 'df_tabs' -); - -- GitLab From 250fb7906f513f8c4a84fcd646cd07c0e109d1b2 Mon Sep 17 00:00:00 2001 From: axelbraunschweiger Date: Thu, 7 Feb 2019 12:33:17 -0500 Subject: [PATCH 11/11] [BUGFIX] Change language label in backend module --- Resources/Private/Language/locallang.xlf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Resources/Private/Language/locallang.xlf b/Resources/Private/Language/locallang.xlf index fbe0b19..8bf3eb2 100644 --- a/Resources/Private/Language/locallang.xlf +++ b/Resources/Private/Language/locallang.xlf @@ -51,6 +51,9 @@ Pages/Content Elements In Tabs + + [ContentTabs] Pages/Content Elements In Tabs + -- GitLab