[FEATURE] Integrate possibility to extend workspace module 44/22444/7
authorOliver Hader <oliver@typo3.org>
Sat, 20 Jul 2013 11:08:18 +0000 (13:08 +0200)
committerOliver Hader <oliver.hader@typo3.org>
Mon, 14 Oct 2013 23:46:41 +0000 (01:46 +0200)
The workspace module only can be extended by overriding PHP and
JavaScript components. This feature aims to integrate a possibility
to extend the definition and behaviour of displayed columns in the
workspace module.

Change-Id: I8ba18c8e35bfc09a5a34becaa66b6543ad73ee01
Resolves: #50219
Releases: 6.2
Reviewed-on: https://review.typo3.org/22444
Reviewed-by: Oliver Hader
Tested-by: Oliver Hader
typo3/sysext/workspaces/Classes/ColumnDataProviderInterface.php [new file with mode: 0644]
typo3/sysext/workspaces/Classes/Controller/AbstractController.php
typo3/sysext/workspaces/Classes/Controller/ReviewController.php
typo3/sysext/workspaces/Classes/Service/AdditionalColumnService.php [new file with mode: 0644]
typo3/sysext/workspaces/Classes/Service/AdditionalResourceService.php [new file with mode: 0644]
typo3/sysext/workspaces/Classes/Service/GridDataService.php
typo3/sysext/workspaces/Resources/Public/JavaScript/Store/mainstore.js
typo3/sysext/workspaces/Resources/Public/JavaScript/grid.js
typo3/sysext/workspaces/Resources/Public/JavaScript/helpers.js

diff --git a/typo3/sysext/workspaces/Classes/ColumnDataProviderInterface.php b/typo3/sysext/workspaces/Classes/ColumnDataProviderInterface.php
new file mode 100644 (file)
index 0000000..2d1f9a4
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+namespace TYPO3\CMS\Workspaces;
+
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2012-2013 Oliver Hader <oliver.hader@typo3.org>
+ * 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.
+ * A copy is found in the textfile GPL.txt and important notices to the license
+ * from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ * 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!
+ ***************************************************************/
+/**
+ * Interface for (additional) columns.
+ *
+ * @author Oliver Hader <oliver.hader@typo3.org>
+ */
+interface ColumnDataProviderInterface {
+
+       /**
+        * @return array
+        */
+       public function getDefinition();
+
+       /**
+        * @param Domain\Model\CombinedRecord $combinedRecord
+        * @return string|integer|array
+        */
+       public function getData(\TYPO3\CMS\Workspaces\Domain\Model\CombinedRecord $combinedRecord);
+
+}
+?>
\ No newline at end of file
index 8b3a82b..3135ba0 100644 (file)
@@ -83,6 +83,25 @@ class AbstractController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControl
                        'depth_infi' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_infi')
                ));
                $this->pageRenderer->addInlineLanguageLabelFile('EXT:workspaces/Resources/Private/Language/locallang.xlf');
+               $this->assignExtensionSettings();
+       }
+
+       /**
+        * Assigns additional Workspace settings to TYPO3.settings.Workspaces.extension
+        *
+        * @return void
+        */
+       protected function assignExtensionSettings() {
+               $extension = array(
+                       'AdditionalColumn' => array(
+                               'Definition' => array(),
+                               'Handler' => array(),
+                       ),
+               );
+
+               $extension['AdditionalColumn']['Definition'] = $this->getAdditionalColumnService()->getDefinition();
+               $extension['AdditionalColumn']['Handler'] = $this->getAdditionalColumnService()->getHandler();
+               $this->pageRenderer->addInlineSetting('Workspaces', 'extension', $extension);
        }
 
        /**
@@ -117,4 +136,18 @@ class AbstractController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControl
                return $language;
        }
 
+       /**
+        * @return \TYPO3\CMS\Workspaces\Service\AdditionalColumnService
+        */
+       protected function getAdditionalColumnService() {
+               return $this->objectManager->get('TYPO3\\CMS\\Workspaces\\Service\\AdditionalColumnService');
+       }
+
+       /**
+        * @return \TYPO3\CMS\Workspaces\Service\AdditionalResourceService
+        */
+       protected function getAdditionalResourceService() {
+               return $this->objectManager->get('TYPO3\\CMS\\Workspaces\\Service\\AdditionalResourceService');
+       }
+
 }
index f0c9cf9..50fff3b 100644 (file)
@@ -152,30 +152,41 @@ class ReviewController extends \TYPO3\CMS\Workspaces\Controller\AbstractControll
                $this->pageRenderer->addJsFile($this->backPath . 'js/extjs/ux/Ext.app.SearchField.js');
                $this->pageRenderer->addJsFile($this->backPath . 'js/extjs/ux/Ext.ux.FitToParent.js');
                $resourcePath = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('workspaces') . 'Resources/Public/JavaScript/';
+
+               // @todo Integrate additional stylesheet resources
                $this->pageRenderer->addCssFile($resourcePath . 'gridfilters/css/GridFilters.css');
                $this->pageRenderer->addCssFile($resourcePath . 'gridfilters/css/RangeMenu.css');
-               $jsFiles = array(
-                       'gridfilters/menu/RangeMenu.js',
-                       'gridfilters/menu/ListMenu.js',
-                       'gridfilters/GridFilters.js',
-                       'gridfilters/filter/Filter.js',
-                       'gridfilters/filter/StringFilter.js',
-                       'gridfilters/filter/DateFilter.js',
-                       'gridfilters/filter/ListFilter.js',
-                       'gridfilters/filter/NumericFilter.js',
-                       'gridfilters/filter/BooleanFilter.js',
-                       'gridfilters/filter/BooleanFilter.js',
-                       'Store/mainstore.js',
-                       'configuration.js',
-                       'helpers.js',
-                       'actions.js',
-                       'component.js',
-                       'toolbar.js',
-                       'grid.js',
-                       'workspaces.js'
+
+               $filters = array(
+                       $resourcePath. 'gridfilters/menu/RangeMenu.js',
+                       $resourcePath. 'gridfilters/menu/ListMenu.js',
+                       $resourcePath .'gridfilters/GridFilters.js',
+                       $resourcePath . 'gridfilters/filter/Filter.js',
+                       $resourcePath . 'gridfilters/filter/StringFilter.js',
+                       $resourcePath . 'gridfilters/filter/DateFilter.js',
+                       $resourcePath . 'gridfilters/filter/ListFilter.js',
+                       $resourcePath . 'gridfilters/filter/NumericFilter.js',
+                       $resourcePath . 'gridfilters/filter/BooleanFilter.js',
+                       $resourcePath . 'gridfilters/filter/BooleanFilter.js',
                );
-               foreach ($jsFiles as $jsFile) {
-                       $this->pageRenderer->addJsFile($resourcePath . $jsFile);
+
+               $custom = $this->getAdditionalResourceService()->getJavaScriptResources();
+
+               $resources = array(
+                       $resourcePath . 'Store/mainstore.js',
+                       $resourcePath . 'configuration.js',
+                       $resourcePath . 'helpers.js',
+                       $resourcePath . 'actions.js',
+                       $resourcePath . 'component.js',
+                       $resourcePath . 'toolbar.js',
+                       $resourcePath . 'grid.js',
+                       $resourcePath . 'workspaces.js'
+               );
+
+               $javaScriptFiles = array_merge($filters, $custom, $resources);
+
+               foreach ($javaScriptFiles as $javaScriptFile) {
+                       $this->pageRenderer->addJsFile($javaScriptFile);
                }
        }
 
diff --git a/typo3/sysext/workspaces/Classes/Service/AdditionalColumnService.php b/typo3/sysext/workspaces/Classes/Service/AdditionalColumnService.php
new file mode 100644 (file)
index 0000000..f6a5a42
--- /dev/null
@@ -0,0 +1,128 @@
+<?php
+namespace TYPO3\CMS\Workspaces\Service;
+
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2013 Oliver Hader <oliver.hader@typo3.org>
+ * 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.
+ * A copy is found in the textfile GPL.txt and important notices to the license
+ * from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ * 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!
+ ***************************************************************/
+/**
+ * Service for additional columns in GridPanel
+ *
+ * @author Oliver Hader <oliver.hader@typo3.org>
+ */
+class AdditionalColumnService implements \TYPO3\CMS\Core\SingletonInterface {
+
+       /**
+        * @var array|\TYPO3\CMS\Workspaces\ColumnDataProviderInterface[]
+        */
+       protected $columns = array();
+
+       /**
+        * @return \TYPO3\CMS\Workspaces\Service\AdditionalColumnService
+        */
+       static public function getInstance() {
+               return self::getObjectManager()->get('TYPO3\\CMS\\Workspaces\\Service\\AdditionalColumnService');
+       }
+
+       /**
+        * @return \TYPO3\CMS\Extbase\Object\ObjectManager
+        */
+       static public function getObjectManager() {
+               return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
+       }
+
+       /**
+        * Registers data provider for a particular column name.
+        *
+        * @param string $columnName
+        * @param string|object $dataProviderClassOrObject
+        * @return void
+        * @throws \RuntimeException
+        */
+       public function register($columnName, $dataProviderClassOrObject) {
+               if (is_object($dataProviderClassOrObject)) {
+                       $dataProvider = $dataProviderClassOrObject;
+               } else {
+                       $dataProvider = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($dataProviderClassOrObject);
+               }
+
+               if (!$dataProvider instanceof \TYPO3\CMS\Workspaces\ColumnDataProviderInterface) {
+                       throw new \RuntimeException('Data provider needs to implement ColumnDataProviderInterface', 1374309323);
+               }
+
+               $this->columns[$columnName] = $dataProvider;
+       }
+
+       /**
+        * Gets definition for JavaScript settings.
+        *
+        * @return array Column settings
+        */
+       public function getDefinition() {
+               $columnSettings = array();
+               foreach ($this->columns as $columnName => $dataProvider) {
+                       $definition = $dataProvider->getDefinition();
+
+                       if (!is_array($definition)) {
+                               $definition = array();
+                       }
+
+                       $definition['name'] = $columnName;
+                       $columnSettings[] = $definition;
+               }
+               return $columnSettings;
+       }
+
+       /**
+        * Gets JavaScript handler object, e.g.
+        * TYPO3.Workspaces.Configuration.AdditionalColumn.extension.MyCustomField
+        *
+        * @return array Column settings
+        */
+       public function getHandler() {
+               $columnSettings = array();
+               foreach (array_keys($this->columns) as $columnName) {
+                       $columnSettings[] = 'TYPO3.Workspaces.extension.AdditionalColumn.' . $columnName;
+               }
+               return $columnSettings;
+       }
+
+       /**
+        * Gets data for grid data.
+        *
+        * @param \TYPO3\CMS\Workspaces\Domain\Model\CombinedRecord $combinedRecord
+        * @return array Record data
+        */
+       public function getData(\TYPO3\CMS\Workspaces\Domain\Model\CombinedRecord $combinedRecord) {
+               $recordData = array();
+               foreach ($this->columns as $columnName => $dataProvider) {
+                       $data = $dataProvider->getData($combinedRecord);
+
+                       if ($data !== NULL) {
+                               $recordData[$columnName] = $data;
+                       }
+               }
+               return $recordData;
+       }
+}
diff --git a/typo3/sysext/workspaces/Classes/Service/AdditionalResourceService.php b/typo3/sysext/workspaces/Classes/Service/AdditionalResourceService.php
new file mode 100644 (file)
index 0000000..98078e9
--- /dev/null
@@ -0,0 +1,104 @@
+<?php
+namespace TYPO3\CMS\Workspaces\Service;
+
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2013 Oliver Hader <oliver.hader@typo3.org>
+ * 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.
+ * A copy is found in the textfile GPL.txt and important notices to the license
+ * from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ * 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!
+ ***************************************************************/
+/**
+ * Service for additional columns in GridPanel
+ *
+ * @author Oliver Hader <oliver.hader@typo3.org>
+ */
+class AdditionalResourceService implements \TYPO3\CMS\Core\SingletonInterface {
+
+       /**
+        * @var array
+        */
+       protected $javaScriptResources = array();
+
+       /**
+        * @var array
+        */
+       protected $stylesheetResources = array();
+
+       /**
+        * @return \TYPO3\CMS\Workspaces\Service\AdditionalResourceService
+        */
+       static public function getInstance() {
+               return self::getObjectManager()->get('TYPO3\\CMS\\Workspaces\\Service\\AdditionalResourceService');
+       }
+
+       /**
+        * @return \TYPO3\CMS\Extbase\Object\ObjectManager
+        */
+       static public function getObjectManager() {
+               return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
+       }
+
+       /**
+        * @param string $name
+        * @param string $resourcePath
+        * @return void
+        */
+       public function addJavaScriptResource($name, $resourcePath) {
+               $this->javaScriptResources[$name] = $this->resolvePath($resourcePath);
+       }
+
+       /**
+        * @param string $name
+        * @param string $resourcePath
+        * @return void
+        */
+       public function addStylesheetResource($name, $resourcePath) {
+               $this->stylesheetResources[$name] = $this->resolvePath($resourcePath);
+       }
+
+       /**
+        * @return array
+        */
+       public function getJavaScriptResources() {
+               return $this->javaScriptResources;
+       }
+
+       /**
+        * @return array
+        */
+       public function getStyleSheetResources() {
+               return $this->stylesheetResources;
+       }
+
+       /**
+        * @param string $resourcePath
+        * @return NULL|string
+        */
+       protected function resolvePath($resourcePath) {
+               $absoluteFilePath = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($resourcePath);
+               $absolutePath = dirname($absoluteFilePath);
+               $fileName = basename($absoluteFilePath);
+
+               return \TYPO3\CMS\Core\Utility\PathUtility::getRelativePathTo($absolutePath) . $fileName;
+       }
+
+}
index c297d33..356d6c5 100644 (file)
@@ -191,6 +191,12 @@ class GridDataService {
                                        $versionArray['allowedAction_edit'] = $isRecordTypeAllowedToModify && !$isDeletedPage;
                                        $versionArray['allowedAction_editVersionedPage'] = $isRecordTypeAllowedToModify && !$isDeletedPage;
                                        $versionArray['state_Workspace'] = $recordState;
+
+                                       $versionArray = array_merge(
+                                               $versionArray,
+                                               $this->getAdditionalColumnService()->getData($combinedRecord)
+                                       );
+
                                        if ($filterTxt == '' || $this->isFilterTextInVisibleColumns($filterTxt, $versionArray)) {
                                                $this->dataArray[] = $versionArray;
                                        }
@@ -555,6 +561,13 @@ class GridDataService {
        }
 
        /**
+        * @return \TYPO3\CMS\Workspaces\Service\AdditionalColumnService
+        */
+       protected function getAdditionalColumnService() {
+               return $this->getObjectManager()->get('TYPO3\\CMS\\Workspaces\\Service\\AdditionalColumnService');
+       }
+
+       /**
         * @return \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
         */
        protected function getSignalSlotDispatcher() {
index fa421ec..6de8130 100644 (file)
@@ -31,8 +31,7 @@ TYPO3.Workspaces.Configuration.StoreFieldArray = [
        {name : 'allowedAction_edit'},
        {name : 'allowedAction_editVersionedPage'},
        {name : 'allowedAction_view'}
-
-];
+].concat(TYPO3.settings.Workspaces.extension.AdditionalColumn.Definition);
 
 TYPO3.Workspaces.MainStore = new Ext.data.GroupingStore({
        storeId : 'workspacesMainStore',
index 4933880..5888e71 100644 (file)
@@ -106,7 +106,7 @@ TYPO3.Workspaces.WorkspaceGrid = new Ext.grid.GridPanel({
                                        TYPO3.Workspaces.Configuration.WsTitleWithIcon,
                                        TYPO3.Workspaces.Configuration.TitleWithIcon,
                                        TYPO3.Workspaces.Configuration.ChangeDate
-                               ],
+                               ].concat(TYPO3.Workspaces.Helpers.getAdditionalColumnHandler()),
                                listeners: {
 
                                        columnmoved: function(colModel) {
@@ -135,7 +135,7 @@ TYPO3.Workspaces.WorkspaceGrid = new Ext.grid.GridPanel({
                                        TYPO3.Workspaces.Configuration.ChangeDate,
                                        TYPO3.Workspaces.Configuration.Stage,
                                        TYPO3.Workspaces.Configuration.RowButtons
-                               ],
+                               ].concat(TYPO3.Workspaces.Helpers.getAdditionalColumnHandler()),
                                listeners: {
 
                                        columnmoved: function(colModel) {
index 4c0b6a3..31b0b34 100644 (file)
@@ -178,5 +178,13 @@ TYPO3.Workspaces.Helpers = {
                                }
                        ]
                });
+       },
+
+       getAdditionalColumnHandler: function() {
+               var handlers = [];
+               Ext.each(TYPO3.settings.Workspaces.extension.AdditionalColumn.Handler, function(objectName) {
+                       handlers.push(eval(objectName));
+               });
+               return handlers;
        }
 };
\ No newline at end of file