TYPO3 API  SVNRelease
class.t3lib_contextmenu_abstractdataprovider.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003  *  Copyright notice
00004  *
00005  *  (c) 2010-2011 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
00006  *  All rights reserved
00007  *
00008  *  This script is part of the TYPO3 project. The TYPO3 project is
00009  *  free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  The GNU General Public License can be found at
00015  *  http://www.gnu.org/copyleft/gpl.html.
00016  *  A copy is found in the textfile GPL.txt and important notices to the license
00017  *  from the author is found in LICENSE.txt distributed with these scripts.
00018  *
00019  *
00020  *  This script is distributed in the hope that it will be useful,
00021  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  *  GNU General Public License for more details.
00024  *
00025  *  This copyright notice MUST APPEAR in all copies of the script!
00026  ***************************************************************/
00027 
00028 /**
00029  * Abstract Context Menu Data Provider
00030  *
00031  * @author Stefan Galinski <stefan.galinski@gmail.com>
00032  * @package TYPO3
00033  * @subpackage t3lib
00034  */
00035 abstract class t3lib_contextmenu_AbstractDataProvider {
00036     /**
00037      * List of actions that are generally disabled
00038      *
00039      * @var array
00040      */
00041     protected $disableItems = array();
00042 
00043     /**
00044      * Context Menu Type (e.g. table.pages, table.tt_content)
00045      *
00046      * @var string
00047      */
00048     protected $contextMenuType = '';
00049 
00050     /**
00051      * Returns the context menu type
00052      *
00053      * @return string
00054      */
00055     public function getContextMenuType() {
00056         return $this->contextMenuType;
00057     }
00058 
00059     /**
00060      * Sets the context menu type
00061      *
00062      * @param string $contextMenuType
00063      * @return void
00064      */
00065     public function setContextMenuType($contextMenuType) {
00066         $this->contextMenuType = $contextMenuType;
00067     }
00068 
00069     /**
00070      * Returns the actions of the node
00071      *
00072      * @param t3lib_tree_Node $node
00073      * @return t3lib_contextmenu_ActionCollection
00074      */
00075     abstract public function getActionsForNode(t3lib_tree_Node $node);
00076 
00077     /**
00078      * Returns the configuration of the specified context menu type
00079      *
00080      * @return array
00081      */
00082     protected function getConfiguration() {
00083         $contextMenuActions = $GLOBALS['BE_USER']->getTSConfig(
00084             'options.contextMenu.' . $this->contextMenuType . '.items'
00085         );
00086 
00087         return $contextMenuActions['properties'];
00088     }
00089 
00090     /**
00091      * Evaluates a given display condition and returns true if the condition matches
00092      *
00093      * Examples:
00094      * getContextInfo|inCutMode:1 || isInCopyMode:1
00095      * isLeafNode:1
00096      * isLeafNode:1 && isInCutMode:1
00097      *
00098      * @param t3lib_tree_Node $node
00099      * @param string $displayCondition
00100      * @return boolean
00101      */
00102     protected function evaluateDisplayCondition(t3lib_tree_Node $node, $displayCondition) {
00103         if ($displayCondition === '') {
00104             return TRUE;
00105         }
00106 
00107             // parse condition string
00108         $conditions = array();
00109         preg_match_all('/(.+?)(>=|<=|!=|=|>|<)(.+?)(\|\||&&|$)/is', $displayCondition, $conditions);
00110 
00111         $lastResult = FALSE;
00112         $chainType = '';
00113         $amountOfConditions = count($conditions[0]);
00114         for ($i = 0; $i < $amountOfConditions; ++$i) {
00115                 // check method for existence
00116             $method = trim($conditions[1][$i]);
00117             list($method, $index) = explode('|', $method);
00118             if (!method_exists($node, $method)) {
00119                 continue;
00120             }
00121 
00122                 // fetch compare value
00123             $returnValue = call_user_func(array($node, $method));
00124             if (is_array($returnValue)) {
00125                 $returnValue = $returnValue[$index];
00126             }
00127 
00128                 // compare fetched and expected values
00129             $operator = trim($conditions[2][$i]);
00130             $expected = trim($conditions[3][$i]);
00131             if ($operator === '=') {
00132                 $returnValue = ($returnValue == $expected);
00133             } elseif ($operator === '>') {
00134                 $returnValue = ($returnValue > $expected);
00135             } elseif ($operator === '<') {
00136                 $returnValue = ($returnValue < $expected);
00137             } elseif ($operator === '>=') {
00138                 $returnValue = ($returnValue >= $expected);
00139             } elseif ($operator === '<=') {
00140                 $returnValue = ($returnValue <= $expected);
00141             } elseif ($operator === '!=') {
00142                 $returnValue = ($returnValue != $expected);
00143             } else {
00144                 $returnValue = FALSE;
00145                 $lastResult = FALSE;
00146             }
00147 
00148                 // chain last result and the current if requested
00149             if ($chainType === '||') {
00150                 $lastResult = ($lastResult || $returnValue);
00151             } elseif ($chainType === '&&') {
00152                 $lastResult = ($lastResult && $returnValue);
00153             } else {
00154                 $lastResult = $returnValue;
00155             }
00156 
00157                 // save chain type for the next condition
00158             $chainType = trim($conditions[4][$i]);
00159         }
00160 
00161         return $lastResult;
00162     }
00163 
00164     /**
00165      * Returns the next context menu level
00166      *
00167      * @param array $actions
00168      * @param t3lib_tree_Node $node
00169      * @param int $level
00170      * @return t3lib_contextmenu_ActionCollection
00171      */
00172     protected function getNextContextMenuLevel(array $actions, t3lib_tree_Node $node, $level = 0) {
00173         /** @var $actionCollection t3lib_contextmenu_ActionCollection */
00174         $actionCollection = t3lib_div::makeInstance('t3lib_contextmenu_ActionCollection');
00175 
00176         if ($level > 5) {
00177             return $actionCollection;
00178         }
00179 
00180         $type = '';
00181         foreach ($actions as $index => $actionConfiguration) {
00182             if (substr($index, -1) !== '.') {
00183                 $type = $actionConfiguration;
00184                 if ($type !== 'DIVIDER') {
00185                     continue;
00186                 }
00187             }
00188 
00189             if (!in_array($type, array('DIVIDER', 'SUBMENU', 'ITEM'))) {
00190                 continue;
00191             }
00192 
00193             /** @var $action t3lib_contextmenu_Action */
00194             $action = t3lib_div::makeInstance('t3lib_contextmenu_Action');
00195             $action->setId($index);
00196 
00197             if ($type === 'DIVIDER') {
00198                 $action->setType('divider');
00199             } else {
00200                 if (in_array($actionConfiguration['name'], $this->disableItems)
00201                     || (isset($actionConfiguration['displayCondition'])
00202                         && trim($actionConfiguration['displayCondition']) !== ''
00203                         && !$this->evaluateDisplayCondition($node, $actionConfiguration['displayCondition'])
00204                     )
00205                 ) {
00206                     unset($action);
00207                     continue;
00208                 }
00209 
00210                 $label = $GLOBALS['LANG']->sL($actionConfiguration['label'], TRUE);
00211                 if ($type === 'SUBMENU') {
00212                     $action->setType('submenu');
00213                     $action->setChildActions(
00214                         $this->getNextContextMenuLevel($actionConfiguration, $node, $level + 1)
00215                     );
00216                 } else {
00217                     $action->setType('action');
00218                     $action->setCallbackAction($actionConfiguration['callbackAction']);
00219 
00220                     if (is_array($actionConfiguration['customAttributes.'])) {
00221                         $action->setCustomAttributes($actionConfiguration['customAttributes.']);
00222                     }
00223                 }
00224 
00225                 $action->setLabel($label);
00226                 if (isset($actionConfiguration['icon']) && trim($actionConfiguration['icon']) !== '') {
00227                     $action->setIcon($actionConfiguration['icon']);
00228                 } elseif (isset($actionConfiguration['spriteIcon'])) {
00229                     $action->setClass(
00230                         t3lib_iconWorks::getSpriteIconClasses($actionConfiguration['spriteIcon'])
00231                     );
00232                 }
00233             }
00234 
00235             $actionCollection->offsetSet($level . intval($index), $action);
00236             $actionCollection->ksort();
00237         }
00238 
00239         return $actionCollection;
00240     }
00241 }
00242 
00243 ?>