[TASK] Remove global option BACK_PATH
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Module / BaseScriptClass.php
1 <?php
2 namespace TYPO3\CMS\Backend\Module;
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 use TYPO3\CMS\Backend\Utility\BackendUtility;
18 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
19 use TYPO3\CMS\Core\Database\DatabaseConnection;
20 use TYPO3\CMS\Core\Messaging\FlashMessage;
21 use TYPO3\CMS\Core\Page\PageRenderer;
22 use TYPO3\CMS\Core\Utility\GeneralUtility;
23 use TYPO3\CMS\Lang\LanguageService;
24
25 /**
26 * Parent class for 'ScriptClasses' in backend modules.
27 *
28 * EXAMPLE PROTOTYPE
29 *
30 * As for examples there are lots of them if you search for classes which extends \TYPO3\CMS\Backend\Module\BaseScriptClass
31 * However you can see a prototype example of how a module might use this class in an index.php file typically hosting a backend module.
32 *
33 * NOTICE: This example only outlines the basic structure of how this class is used.
34 * You should consult the documentation and other real-world examples for some actual things to do when building modules.
35 *
36 * TYPICAL SETUP OF A BACKEND MODULE:
37 *
38 * PrototypeController EXTENDS THE CLASS \TYPO3\CMS\Backend\Module\BaseScriptClass with a main() and printContent() function:
39 *
40 * namespace Vendor\Prototype\Controller;
41 *
42 * class PrototypeController extends \TYPO3\CMS\Backend\Module\BaseScriptClass {
43 * public function __construct() {
44 * $this->getLanguageService()->includeLLFile('EXT:prototype/Resources/Private/Language/locallang.xlf');
45 * $this->getBackendUser()->modAccess($GLOBALS['MCONF'], TRUE);
46 * }
47 * }
48 *
49 * MAIN FUNCTION - HERE YOU CREATE THE MODULE CONTENT IN $this->content
50 * public function main() {
51 * TYPICALLY THE INTERNAL VAR, $this->doc is instantiated like this:
52 * $this->doc = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Template\DocumentTemplate::class);
53 * ... AND OF COURSE A LOT OF OTHER THINGS GOES ON - LIKE PUTTING CONTENT INTO $this->content
54 * $this->content='';
55 * }
56 * PRINT CONTENT - DONE AS THE LAST THING
57 * public function printContent() {
58 * echo $this->content;
59 * }
60 *
61 * MAKE INSTANCE OF THE SCRIPT CLASS AND CALL init()
62 * $GLOBALS['SOBE'] = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\Vendor\Prototype\Controller\PrototypeController::class);
63 * $GLOBALS['SOBE']->init();
64 *
65 *
66 * THEN WE WILL CHECK IF THERE IS A 'SUBMODULE' REGISTERED TO BE INITIALIZED AS WELL:
67 * $GLOBALS['SOBE']->checkExtObj();
68 *
69 * THEN WE CALL THE main() METHOD AND THIS SHOULD SPARK THE CREATION OF THE MODULE OUTPUT.
70 * $GLOBALS['SOBE']->main();
71 * FINALLY THE printContent() FUNCTION WILL OUTPUT THE ACCUMULATED CONTENT
72 * $GLOBALS['SOBE']->printContent();
73 */
74 class BaseScriptClass
75 {
76 /**
77 * Loaded with the global array $MCONF which holds some module configuration from the conf.php file of backend modules.
78 *
79 * @see init()
80 * @var array
81 */
82 public $MCONF = array();
83
84 /**
85 * The integer value of the GET/POST var, 'id'. Used for submodules to the 'Web' module (page id)
86 *
87 * @see init()
88 * @var int
89 */
90 public $id;
91
92 /**
93 * The value of GET/POST var, 'CMD'
94 *
95 * @see init()
96 * @var mixed
97 */
98 public $CMD;
99
100 /**
101 * A WHERE clause for selection records from the pages table based on read-permissions of the current backend user.
102 *
103 * @see init()
104 * @var string
105 */
106 public $perms_clause;
107
108 /**
109 * The module menu items array. Each key represents a key for which values can range between the items in the array of that key.
110 *
111 * @see init()
112 * @var array
113 */
114 public $MOD_MENU = array(
115 'function' => array()
116 );
117
118 /**
119 * Current settings for the keys of the MOD_MENU array
120 *
121 * @see $MOD_MENU
122 * @var array
123 */
124 public $MOD_SETTINGS = array();
125
126 /**
127 * Module TSconfig based on PAGE TSconfig / USER TSconfig
128 *
129 * @see menuConfig()
130 * @var array
131 */
132 public $modTSconfig;
133
134 /**
135 * If type is 'ses' then the data is stored as session-lasting data. This means that it'll be wiped out the next time the user logs in.
136 * Can be set from extension classes of this class before the init() function is called.
137 *
138 * @see menuConfig(), \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleData()
139 * @var string
140 */
141 public $modMenu_type = '';
142
143 /**
144 * dontValidateList can be used to list variables that should not be checked if their value is found in the MOD_MENU array. Used for dynamically generated menus.
145 * Can be set from extension classes of this class before the init() function is called.
146 *
147 * @see menuConfig(), \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleData()
148 * @var string
149 */
150 public $modMenu_dontValidateList = '';
151
152 /**
153 * List of default values from $MOD_MENU to set in the output array (only if the values from MOD_MENU are not arrays)
154 * Can be set from extension classes of this class before the init() function is called.
155 *
156 * @see menuConfig(), \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleData()
157 * @var string
158 */
159 public $modMenu_setDefaultList = '';
160
161 /**
162 * Contains module configuration parts from TBE_MODULES_EXT if found
163 *
164 * @see handleExternalFunctionValue()
165 * @var array
166 */
167 public $extClassConf;
168
169 /**
170 * Generally used for accumulating the output content of backend modules
171 *
172 * @var string
173 */
174 public $content = '';
175
176 /**
177 * @var \TYPO3\CMS\Backend\Template\DocumentTemplate
178 */
179 public $doc;
180
181 /**
182 * May contain an instance of a 'Function menu module' which connects to this backend module.
183 *
184 * @see checkExtObj()
185 * @var AbstractFunctionModule
186 */
187 public $extObj;
188
189 /**
190 * @var PageRenderer
191 */
192 protected $pageRenderer = null;
193
194 /**
195 * Initializes the backend module by setting internal variables, initializing the menu.
196 *
197 * @return void
198 * @see menuConfig()
199 */
200 public function init()
201 {
202 // Name might be set from outside
203 if (!$this->MCONF['name']) {
204 $this->MCONF = $GLOBALS['MCONF'];
205 }
206 $this->id = (int)GeneralUtility::_GP('id');
207 $this->CMD = GeneralUtility::_GP('CMD');
208 $this->perms_clause = $this->getBackendUser()->getPagePermsClause(1);
209 $this->menuConfig();
210 $this->handleExternalFunctionValue();
211 }
212
213 /**
214 * Initializes the internal MOD_MENU array setting and unsetting items based on various conditions. It also merges in external menu items from the global array TBE_MODULES_EXT (see mergeExternalItems())
215 * Then MOD_SETTINGS array is cleaned up (see \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleData()) so it contains only valid values. It's also updated with any SET[] values submitted.
216 * Also loads the modTSconfig internal variable.
217 *
218 * @return void
219 * @see init(), $MOD_MENU, $MOD_SETTINGS, \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleData(), mergeExternalItems()
220 */
221 public function menuConfig()
222 {
223 // Page/be_user TSconfig settings and blinding of menu-items
224 $this->modTSconfig = BackendUtility::getModTSconfig($this->id, 'mod.' . $this->MCONF['name']);
225 $this->MOD_MENU['function'] = $this->mergeExternalItems($this->MCONF['name'], 'function', $this->MOD_MENU['function']);
226 $this->MOD_MENU['function'] = BackendUtility::unsetMenuItems($this->modTSconfig['properties'], $this->MOD_MENU['function'], 'menu.function');
227 $this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, GeneralUtility::_GP('SET'), $this->MCONF['name'], $this->modMenu_type, $this->modMenu_dontValidateList, $this->modMenu_setDefaultList);
228 }
229
230 /**
231 * Merges menu items from global array $TBE_MODULES_EXT
232 *
233 * @param string $modName Module name for which to find value
234 * @param string $menuKey Menu key, eg. 'function' for the function menu.
235 * @param array $menuArr The part of a MOD_MENU array to work on.
236 * @return array Modified array part.
237 * @access private
238 * @see \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::insertModuleFunction(), menuConfig()
239 */
240 public function mergeExternalItems($modName, $menuKey, $menuArr)
241 {
242 $mergeArray = $GLOBALS['TBE_MODULES_EXT'][$modName]['MOD_MENU'][$menuKey];
243 if (is_array($mergeArray)) {
244 foreach ($mergeArray as $k => $v) {
245 if (((string)$v['ws'] === '' || $this->getBackendUser()->workspace === 0 && GeneralUtility::inList($v['ws'], 'online')) || $this->getBackendUser()->workspace === -1 && GeneralUtility::inList($v['ws'], 'offline') || $this->getBackendUser()->workspace > 0 && GeneralUtility::inList($v['ws'], 'custom')) {
246 $menuArr[$k] = $this->getLanguageService()->sL($v['title']);
247 }
248 }
249 }
250 return $menuArr;
251 }
252
253 /**
254 * Loads $this->extClassConf with the configuration for the CURRENT function of the menu.
255 *
256 * @param string $MM_key The key to MOD_MENU for which to fetch configuration. 'function' is default since it is first and foremost used to get information per "extension object" (I think that is what its called)
257 * @param string $MS_value The value-key to fetch from the config array. If NULL (default) MOD_SETTINGS[$MM_key] will be used. This is useful if you want to force another function than the one defined in MOD_SETTINGS[function]. Call this in init() function of your Script Class: handleExternalFunctionValue('function', $forcedSubModKey)
258 * @return void
259 * @see getExternalItemConfig(), init()
260 */
261 public function handleExternalFunctionValue($MM_key = 'function', $MS_value = null)
262 {
263 if ($MS_value === null) {
264 $MS_value = $this->MOD_SETTINGS[$MM_key];
265 }
266 $this->extClassConf = $this->getExternalItemConfig($this->MCONF['name'], $MM_key, $MS_value);
267 }
268
269 /**
270 * Returns configuration values from the global variable $TBE_MODULES_EXT for the module given.
271 * For example if the module is named "web_info" and the "function" key ($menuKey) of MOD_SETTINGS is "stat" ($value) then you will have the values of $TBE_MODULES_EXT['webinfo']['MOD_MENU']['function']['stat'] returned.
272 *
273 * @param string $modName Module name
274 * @param string $menuKey Menu key, eg. "function" for the function menu. See $this->MOD_MENU
275 * @param string $value Optionally the value-key to fetch from the array that would otherwise have been returned if this value was not set. Look source...
276 * @return mixed The value from the TBE_MODULES_EXT array.
277 * @see handleExternalFunctionValue()
278 */
279 public function getExternalItemConfig($modName, $menuKey, $value = '')
280 {
281 if (isset($GLOBALS['TBE_MODULES_EXT'][$modName])) {
282 return (string)$value !== '' ? $GLOBALS['TBE_MODULES_EXT'][$modName]['MOD_MENU'][$menuKey][$value] : $GLOBALS['TBE_MODULES_EXT'][$modName]['MOD_MENU'][$menuKey];
283 }
284 return null;
285 }
286
287 /**
288 * Creates an instance of the class found in $this->extClassConf['name'] in $this->extObj if any (this should hold three keys, "name", "path" and "title" if a "Function menu module" tries to connect...)
289 * This value in extClassConf might be set by an extension (in an ext_tables/ext_localconf file) which thus "connects" to a module.
290 * The array $this->extClassConf is set in handleExternalFunctionValue() based on the value of MOD_SETTINGS[function]
291 * If an instance is created it is initiated with $this passed as value and $this->extClassConf as second argument. Further the $this->MOD_SETTING is cleaned up again after calling the init function.
292 *
293 * @return void
294 * @see handleExternalFunctionValue(), \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::insertModuleFunction(), $extObj
295 */
296 public function checkExtObj()
297 {
298 if (is_array($this->extClassConf) && $this->extClassConf['name']) {
299 $this->extObj = GeneralUtility::makeInstance($this->extClassConf['name']);
300 $this->extObj->init($this, $this->extClassConf);
301 // Re-write:
302 $this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, GeneralUtility::_GP('SET'), $this->MCONF['name'], $this->modMenu_type, $this->modMenu_dontValidateList, $this->modMenu_setDefaultList);
303 }
304 }
305
306 /**
307 * Calls the checkExtObj function in sub module if present.
308 *
309 * @return void
310 */
311 public function checkSubExtObj()
312 {
313 if (is_object($this->extObj)) {
314 $this->extObj->checkExtObj();
315 }
316 }
317
318 /**
319 * Calls the 'header' function inside the "Function menu module" if present.
320 * A header function might be needed to add JavaScript or other stuff in the head. This can't be done in the main function because the head is already written.
321 * example call in the header function:
322 * $this->pObj->doc->JScode = $this->pObj->doc->wrapScriptTags(' ...
323 *
324 * @return void
325 */
326 public function extObjHeader()
327 {
328 if (is_callable(array($this->extObj, 'head'))) {
329 $this->extObj->head();
330 }
331 }
332
333 /**
334 * Calls the 'main' function inside the "Function menu module" if present
335 *
336 * @return void
337 */
338 public function extObjContent()
339 {
340 if ($this->extObj === null) {
341 $flashMessage = GeneralUtility::makeInstance(
342 FlashMessage::class,
343 $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang.xlf:no_modules_registered'),
344 $this->getLanguageService()->getLL('title'),
345 FlashMessage::ERROR
346 );
347 $this->content .= $flashMessage->render();
348 } else {
349 $this->extObj->pObj = $this;
350 if (is_callable(array($this->extObj, 'main'))) {
351 $this->content .= $this->extObj->main();
352 }
353 }
354 }
355
356 /**
357 * Returns the Language Service
358 * @return LanguageService
359 */
360 protected function getLanguageService()
361 {
362 return $GLOBALS['LANG'];
363 }
364
365 /**
366 * Returns the Backend User
367 * @return BackendUserAuthentication
368 */
369 protected function getBackendUser()
370 {
371 return $GLOBALS['BE_USER'];
372 }
373
374 /**
375 * @return DatabaseConnection
376 */
377 protected function getDatabaseConnection()
378 {
379 return $GLOBALS['TYPO3_DB'];
380 }
381
382 /**
383 * @return PageRenderer
384 */
385 protected function getPageRenderer()
386 {
387 if ($this->pageRenderer === null) {
388 $this->pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
389 }
390
391 return $this->pageRenderer;
392 }
393 }