e7d80798065d9ee3f01ff214502d2f45f8310d25
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / ContextMenu / AbstractContextMenuDataProvider.php
1 <?php
2 namespace TYPO3\CMS\Backend\ContextMenu;
3
4 /**
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 /**
18 * Abstract Context Menu Data Provider
19 *
20 * @author Stefan Galinski <stefan.galinski@gmail.com>
21 */
22 abstract class AbstractContextMenuDataProvider {
23
24 /**
25 * List of actions that are generally disabled
26 *
27 * @var array
28 */
29 protected $disableItems = array();
30
31 /**
32 * Context Menu Type (e.g. table.pages, table.tt_content)
33 *
34 * @var string
35 */
36 protected $contextMenuType = '';
37
38 /**
39 * Returns the context menu type
40 *
41 * @return string
42 */
43 public function getContextMenuType() {
44 return $this->contextMenuType;
45 }
46
47 /**
48 * Sets the context menu type
49 *
50 * @param string $contextMenuType
51 * @return void
52 */
53 public function setContextMenuType($contextMenuType) {
54 $this->contextMenuType = $contextMenuType;
55 }
56
57 /**
58 * Returns the actions of the node
59 *
60 * @param \TYPO3\CMS\Backend\Tree\TreeNode $node
61 * @return \TYPO3\CMS\Backend\ContextMenu\ContextMenuActionCollection
62 */
63 abstract public function getActionsForNode(\TYPO3\CMS\Backend\Tree\TreeNode $node);
64
65 /**
66 * Returns the configuration of the specified context menu type
67 *
68 * @return array
69 */
70 protected function getConfiguration() {
71 $contextMenuActions = $GLOBALS['BE_USER']->getTSConfig('options.contextMenu.' . $this->contextMenuType . '.items');
72 return $contextMenuActions['properties'];
73 }
74
75 /**
76 * Evaluates a given display condition and returns TRUE if the condition matches
77 *
78 * Examples:
79 * getContextInfo|inCutMode:1 || isInCopyMode:1
80 * isLeafNode:1
81 * isLeafNode:1 && isInCutMode:1
82 *
83 * @param \TYPO3\CMS\Backend\Tree\TreeNode $node
84 * @param string $displayCondition
85 * @return boolean
86 */
87 protected function evaluateDisplayCondition(\TYPO3\CMS\Backend\Tree\TreeNode $node, $displayCondition) {
88 if ($displayCondition === '') {
89 return TRUE;
90 }
91 // Parse condition string
92 $conditions = array();
93 preg_match_all('/(.+?)(>=|<=|!=|=|>|<)(.+?)(\\|\\||&&|$)/is', $displayCondition, $conditions);
94 $lastResult = FALSE;
95 $chainType = '';
96 $amountOfConditions = count($conditions[0]);
97 for ($i = 0; $i < $amountOfConditions; ++$i) {
98 // Check method for existence
99 $method = trim($conditions[1][$i]);
100 list($method, $index) = explode('|', $method);
101 if (!method_exists($node, $method)) {
102 continue;
103 }
104 // Fetch compare value
105 $returnValue = call_user_func(array($node, $method));
106 if (is_array($returnValue)) {
107 $returnValue = $returnValue[$index];
108 }
109 // Compare fetched and expected values
110 $operator = trim($conditions[2][$i]);
111 $expected = trim($conditions[3][$i]);
112 if ($operator === '=') {
113 $returnValue = $returnValue == $expected;
114 } elseif ($operator === '>') {
115 $returnValue = $returnValue > $expected;
116 } elseif ($operator === '<') {
117 $returnValue = $returnValue < $expected;
118 } elseif ($operator === '>=') {
119 $returnValue = $returnValue >= $expected;
120 } elseif ($operator === '<=') {
121 $returnValue = $returnValue <= $expected;
122 } elseif ($operator === '!=') {
123 $returnValue = $returnValue != $expected;
124 } else {
125 $returnValue = FALSE;
126 $lastResult = FALSE;
127 }
128 // Chain last result and the current if requested
129 if ($chainType === '||') {
130 $lastResult = $lastResult || $returnValue;
131 } elseif ($chainType === '&&') {
132 $lastResult = $lastResult && $returnValue;
133 } else {
134 $lastResult = $returnValue;
135 }
136 // Save chain type for the next condition
137 $chainType = trim($conditions[4][$i]);
138 }
139 return $lastResult;
140 }
141
142 /**
143 * Returns the next context menu level
144 *
145 * @param array $actions
146 * @param \TYPO3\CMS\Backend\Tree\TreeNode $node
147 * @param integer $level
148 * @return \TYPO3\CMS\Backend\ContextMenu\ContextMenuActionCollection
149 */
150 protected function getNextContextMenuLevel(array $actions, \TYPO3\CMS\Backend\Tree\TreeNode $node, $level = 0) {
151 /** @var $actionCollection \TYPO3\CMS\Backend\ContextMenu\ContextMenuActionCollection */
152 $actionCollection = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\ContextMenu\\ContextMenuActionCollection');
153 if ($level > 5) {
154 return $actionCollection;
155 }
156 $type = '';
157 foreach ($actions as $index => $actionConfiguration) {
158 if (substr($index, -1) !== '.') {
159 $type = $actionConfiguration;
160 if ($type !== 'DIVIDER') {
161 continue;
162 }
163 }
164 if (!in_array($type, array('DIVIDER', 'SUBMENU', 'ITEM'))) {
165 continue;
166 }
167 /** @var $action \TYPO3\CMS\Backend\ContextMenu\ContextMenuAction */
168 $action = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\ContextMenu\\ContextMenuAction');
169 $action->setId($index);
170 if ($type === 'DIVIDER') {
171 $action->setType('divider');
172 } else {
173 if (in_array($actionConfiguration['name'], $this->disableItems) || isset($actionConfiguration['displayCondition']) && trim($actionConfiguration['displayCondition']) !== '' && !$this->evaluateDisplayCondition($node, $actionConfiguration['displayCondition'])) {
174 unset($action);
175 continue;
176 }
177 $label = $GLOBALS['LANG']->sL($actionConfiguration['label'], TRUE);
178 if ($type === 'SUBMENU') {
179 $action->setType('submenu');
180 $action->setChildActions($this->getNextContextMenuLevel($actionConfiguration, $node, $level + 1));
181 } else {
182 $action->setType('action');
183 $action->setCallbackAction($actionConfiguration['callbackAction']);
184 if (is_array($actionConfiguration['customAttributes.'])) {
185 $action->setCustomAttributes($actionConfiguration['customAttributes.']);
186 }
187 }
188 $action->setLabel($label);
189 if (isset($actionConfiguration['icon']) && trim($actionConfiguration['icon']) !== '') {
190 $action->setIcon($actionConfiguration['icon']);
191 } elseif (isset($actionConfiguration['spriteIcon'])) {
192 $action->setClass(\TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconClasses($actionConfiguration['spriteIcon']));
193 }
194 }
195 $actionCollection->offsetSet($level . (int)$index, $action);
196 $actionCollection->ksort();
197 }
198 return $actionCollection;
199 }
200
201 }