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