[TASK] Deprecate AbstractFunctionModule->incLocalLang()
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Module / AbstractFunctionModule.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\Template\DocumentTemplate;
18 use TYPO3\CMS\Backend\Utility\BackendUtility;
19 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
20 use TYPO3\CMS\Core\Database\DatabaseConnection;
21 use TYPO3\CMS\Core\Page\PageRenderer;
22 use TYPO3\CMS\Core\Utility\ArrayUtility;
23 use TYPO3\CMS\Core\Utility\GeneralUtility;
24 use TYPO3\CMS\Lang\LanguageService;
25
26 /**
27 * Parent class for 'Extension Objects' in backend modules.
28 *
29 * Used for 'submodules' to other modules. Also called 'Function menu modules'
30 * in \TYPO3\CMS\Core\Utility\ExtensionManagementUtility. And now its even called
31 * 'Extension Objects'. Or 'Module functions'. Wish we had just one name. Or a
32 * name at all...(?) Thank God its not so advanced when it works...
33 *
34 * In other words this class is used for backend modules which is not true
35 * backend modules appearing in the menu but rather adds themselves as a new
36 * entry in the function menu which typically exists for a backend
37 * module (like Web>Functions, Web>Info or Tools etc...)
38 * The magic that binds this together is stored in the global variable
39 * $TBE_MODULES_EXT where extensions wanting to connect a module based on
40 * this class to an existing backend module store configuration which consists
41 * of the classname, script-path and a label (title/name).
42 *
43 * For more information about this, please see the large example comment for the
44 * class \TYPO3\CMS\Backend\Module\BaseScriptClass. This will show the principle of a
45 * 'level-1' connection. The more advanced example - having two layers as it is done
46 * by the 'func_wizards' extension with the 'web_info' module - can be seen in the
47 * comment above.
48 *
49 * EXAMPLE: One level.
50 * This can be seen in the extension 'frontend' where the info module have a
51 * function added. In 'ext_tables.php' this is done by this function call:
52 *
53 * \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::insertModuleFunction(
54 * 'web_info',
55 * \TYPO3\CMS\Frontend\Controller\PageInformationController::class,
56 * NULL,
57 * 'LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:mod_tx_cms_webinfo_page'
58 * );
59 *
60 * EXAMPLE: Two levels.
61 * This is the advanced example. You can see it with the extension 'func_wizards'
62 * which is the first layer but then providing another layer for extensions to connect by.
63 * The key used in TBE_MODULES_EXT is normally 'function' (for the 'function menu')
64 * but the 'func_wizards' extension uses an alternative key for its configuration: 'wiz'.
65 * In the 'ext_tables.php' file of an extension ('wizard_crpages') which uses the
66 * framework provided by 'func_wizards' this looks like this:
67 *
68 * \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::insertModuleFunction(
69 * 'web_func',
70 * \TYPO3\CMS\WizardCrpages\Controller\CreatePagesWizardModuleFunctionController::class
71 * NULL,
72 * 'LLL:EXT:wizard_crpages/locallang.xlf:wiz_crMany',
73 * 'wiz'
74 * );
75 *
76 * But for this two-level thing to work it also requires that the parent
77 * module (the real backend module) supports it.
78 * This is the case for the modules web_func and web_info since they have two
79 * times inclusion sections in their index.php scripts. For example (from web_func):
80 *
81 * Make instance:
82 * $GLOBALS['SOBE'] = GeneralUtility::makeInstance(\TYPO3\CMS\Func\Controller\PageFunctionsController::class);
83 * $GLOBALS['SOBE']->init();
84 *
85 * Anyways, the final interesting thing is to see what the framework
86 * "func_wizard" actually does:
87 *
88 * class WebFunctionWizardsBaseController extends \TYPO3\CMS\Backend\Module\AbstractFunctionModule {
89 * var $localLangFile = "locallang.xlf";
90 * var $function_key = "wiz";
91 * function init(&$pObj, $conf) {
92 * OK, handles ordinary init. This includes setting up the
93 * menu array with ->modMenu
94 * parent::init($pObj,$conf);
95 * $this->handleExternalFunctionValue();
96 * }
97 * }
98 *
99 * Notice that the handleExternalFunctionValue of this class
100 * is called and that the ->function_key internal var is set!
101 *
102 * The two level-2 sub-module "wizard_crpages" and "wizard_sortpages"
103 * are totally normal "submodules".
104 * @see \TYPO3\CMS\Backend\Module\BaseScriptClass
105 * @see \TYPO3\CMS\FuncWizards\Controller\WebFunctionWizardsBaseController
106 * @see \TYPO3\CMS\WizardSortpages\View\SortPagesWizardModuleFunction
107 */
108 abstract class AbstractFunctionModule
109 {
110 /**
111 * Contains a reference to the parent (calling) object (which is probably an instance of
112 * an extension class to \TYPO3\CMS\Backend\Module\BaseScriptClass
113 *
114 * @var BaseScriptClass
115 * @see init()
116 */
117 public $pObj;
118
119 /**
120 * @var BaseScriptClass
121 */
122 public $extObj = null;
123
124 /**
125 * Set to the directory name of this class file.
126 *
127 * @see init()
128 * @var string
129 * @deprecated since TYPO3 v8, will be removed in TYPO3 v9
130 */
131 public $thisPath = '';
132
133 /**
134 * Can be hardcoded to the name of a locallang.xlf file (from the same directory as the class file) to use/load
135 * and is included / added to $GLOBALS['LOCAL_LANG']
136 *
137 * @see init()
138 * @var string
139 */
140 public $localLangFile = '';
141
142 /**
143 * Contains module configuration parts from TBE_MODULES_EXT if found
144 *
145 * @see handleExternalFunctionValue()
146 * @var array
147 */
148 public $extClassConf;
149
150 /**
151 * If this value is set it points to a key in the TBE_MODULES_EXT array (not on the top level..) where another classname/filepath/title can be defined for sub-subfunctions.
152 * This is a little hard to explain, so see it in action; it used in the extension 'func_wizards' in order to provide yet a layer of interfacing with the backend module.
153 * The extension 'func_wizards' has this description: 'Adds the 'Wizards' item to the function menu in Web>Func. This is just a framework for wizard extensions.' - so as you can see it is designed to allow further connectivity - 'level 2'
154 *
155 * @see handleExternalFunctionValue(), \TYPO3\CMS\FuncWizards\Controller\WebFunctionWizardsBaseController
156 * @var string
157 */
158 public $function_key = '';
159
160 /**
161 * @var PageRenderer
162 */
163 protected $pageRenderer = null;
164
165 /**
166 * Initialize the object
167 *
168 * @param BaseScriptClass $pObj A reference to the parent (calling) object
169 * @param array $conf The configuration set for this module - from global array TBE_MODULES_EXT
170 * @throws \RuntimeException
171 * @see \TYPO3\CMS\Backend\Module\BaseScriptClass::checkExtObj()
172 */
173 public function init(&$pObj, $conf)
174 {
175 $this->pObj = $pObj;
176 // Path of this script:
177 $reflector = new \ReflectionObject($this);
178 $this->thisPath = dirname($reflector->getFileName());
179 if (!@is_dir($this->thisPath)) {
180 throw new \RuntimeException('TYPO3 Fatal Error: Could not find path for class ' . get_class($this), 1381164687);
181 }
182 // Local lang:
183 if (!empty($this->localLangFile)) {
184 $this->getLanguageService()->includeLLFile($this->localLangFile);
185 }
186 // Setting MOD_MENU items as we need them for logging:
187 $this->pObj->MOD_MENU = array_merge($this->pObj->MOD_MENU, $this->modMenu());
188 }
189
190 /**
191 * If $this->function_key is set (which means there are two levels of object connectivity) then
192 * $this->extClassConf is loaded with the TBE_MODULES_EXT configuration for that sub-sub-module
193 *
194 * @see $function_key, \TYPO3\CMS\FuncWizards\Controller\WebFunctionWizardsBaseController::init()
195 */
196 public function handleExternalFunctionValue()
197 {
198 // Must clean first to make sure the correct key is set...
199 $this->pObj->MOD_SETTINGS = BackendUtility::getModuleData($this->pObj->MOD_MENU, GeneralUtility::_GP('SET'), $this->pObj->MCONF['name']);
200 if ($this->function_key) {
201 $this->extClassConf = $this->pObj->getExternalItemConfig($this->pObj->MCONF['name'], $this->function_key, $this->pObj->MOD_SETTINGS[$this->function_key]);
202 }
203 }
204
205 /**
206 * Including any locallang file configured and merging its content over
207 * the current global LOCAL_LANG array (which is EXPECTED to exist!!!)
208 * @deprecated since TYPO3 v8, will be removed in TYPO3 v9
209 */
210 public function incLocalLang()
211 {
212 GeneralUtility::logDeprecatedFunction();
213 if (
214 $this->localLangFile
215 && (
216 @is_file(($this->thisPath . '/' . $this->localLangFile))
217 || @is_file(($this->thisPath . '/' . substr($this->localLangFile, 0, -4) . '.xml'))
218 )
219 ) {
220 $LOCAL_LANG = $this->getLanguageService()->includeLLFile($this->thisPath . '/' . $this->localLangFile, false);
221 if (is_array($LOCAL_LANG)) {
222 $GLOBALS['LOCAL_LANG'] = (array)$GLOBALS['LOCAL_LANG'];
223 ArrayUtility::mergeRecursiveWithOverrule($GLOBALS['LOCAL_LANG'], $LOCAL_LANG);
224 }
225 }
226 }
227
228 /**
229 * Same as \TYPO3\CMS\Backend\Module\BaseScriptClass::checkExtObj()
230 *
231 * @see \TYPO3\CMS\Backend\Module\BaseScriptClass::checkExtObj()
232 */
233 public function checkExtObj()
234 {
235 if (is_array($this->extClassConf) && $this->extClassConf['name']) {
236 $this->extObj = GeneralUtility::makeInstance($this->extClassConf['name']);
237 $this->extObj->init($this->pObj, $this->extClassConf);
238 // Re-write:
239 $this->pObj->MOD_SETTINGS = BackendUtility::getModuleData($this->pObj->MOD_MENU, GeneralUtility::_GP('SET'), $this->pObj->MCONF['name']);
240 }
241 }
242
243 /**
244 * Calls the main function inside ANOTHER sub-submodule which might exist.
245 */
246 public function extObjContent()
247 {
248 if (is_object($this->extObj)) {
249 return $this->extObj->main();
250 }
251 }
252
253 /**
254 * Dummy function - but is used to set up additional menu items for this submodule.
255 *
256 * @return array A MOD_MENU array which will be merged together with the one from the parent object
257 * @see init(), \TYPO3\CMS\Frontend\Controller\PageInformationController::modMenu()
258 */
259 public function modMenu()
260 {
261 return [];
262 }
263
264 /**
265 * @return LanguageService
266 */
267 protected function getLanguageService()
268 {
269 return $GLOBALS['LANG'];
270 }
271
272 /**
273 * @return BackendUserAuthentication
274 */
275 protected function getBackendUserAuthentication()
276 {
277 return $GLOBALS['BE_USER'];
278 }
279
280 /**
281 * @return DocumentTemplate
282 */
283 protected function getDocumentTemplate()
284 {
285 return $GLOBALS['TBE_TEMPLATE'];
286 }
287
288 /**
289 * @return string
290 * @deprecated since TYPO3 v8, will be removed in TYPO3 v9
291 */
292 protected function getBackPath()
293 {
294 GeneralUtility::logDeprecatedFunction();
295 return '';
296 }
297
298 /**
299 * @return DatabaseConnection
300 * @deprecated since TYPO3 v8, will be removed in TYPO3 v9, use the Doctrine DBAL layer via the ConnectionPool class
301 */
302 protected function getDatabaseConnection()
303 {
304 GeneralUtility::logDeprecatedFunction();
305 return $GLOBALS['TYPO3_DB'];
306 }
307
308 /**
309 * @return PageRenderer
310 */
311 protected function getPageRenderer()
312 {
313 if ($this->pageRenderer === null) {
314 $this->pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
315 }
316
317 return $this->pageRenderer;
318 }
319 }