‪TYPO3CMS  ‪main
ModuleProvider.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
23 
29 {
30  public function ‪__construct(protected readonly ‪ModuleRegistry $moduleRegistry) {}
31 
36  public function ‪isModuleRegistered(string ‪$identifier): bool
37  {
38  return $this->moduleRegistry->hasModule(‪$identifier);
39  }
40 
44  public function ‪getModule(
45  string ‪$identifier,
46  ?‪BackendUserAuthentication $user = null,
47  bool $respectWorkspaceRestrictions = true
48  ): ?‪ModuleInterface {
49  if (($user === null && $this->moduleRegistry->hasModule(‪$identifier))
50  || $this->accessGranted(‪$identifier, $user, $respectWorkspaceRestrictions)
51  ) {
52  $module = $this->moduleRegistry->getModule(‪$identifier);
53  if ($module->hasSubModules()) {
54  foreach ($module->getSubModules() as $subModuleIdentifier => $subModule) {
55  if ($user !== null && !$this->‪accessGranted($subModuleIdentifier, $user, $respectWorkspaceRestrictions)) {
56  $module->‪removeSubModule($subModuleIdentifier);
57  }
58  }
59  }
60  return $module;
61  }
62 
63  return null;
64  }
65 
72  public function ‪getModules(
73  ?‪BackendUserAuthentication $user = null,
74  bool $respectWorkspaceRestrictions = true,
75  bool $grouped = true
76  ): array {
77  if (!$grouped) {
78  return array_filter(
79  $this->moduleRegistry->getModules(),
80  fn(‪ModuleInterface $module): bool => $user === null || $this->‪accessGranted($module->‪getIdentifier(), $user, $respectWorkspaceRestrictions)
81  );
82  }
83 
84  $availableModules = array_filter($this->moduleRegistry->getModules(), static fn(‪ModuleInterface $module): bool => !$module->‪hasParentModule());
85 
86  foreach ($availableModules as ‪$identifier => $module) {
87  if ($user !== null && !$this->‪accessGranted(‪$identifier, $user, $respectWorkspaceRestrictions)) {
88  unset($availableModules[‪$identifier]);
89  continue;
90  }
91  foreach ($module->‪getSubModules() as $subModuleIdentifier => $subModule) {
92  if ($user !== null && !$this->‪accessGranted($subModuleIdentifier, $user, $respectWorkspaceRestrictions)) {
93  $module->‪removeSubModule($subModuleIdentifier);
94  }
95  }
96  }
97 
98  return $availableModules;
99  }
100 
106  public function ‪getModuleForMenu(
107  string ‪$identifier,
109  bool $respectWorkspaceRestrictions = true
110  ): ?‪MenuModule {
111  $module = $this->‪getModule($identifier, $user, $respectWorkspaceRestrictions);
112  if ($module === null) {
113  return null;
114  }
115  // Before preparing the module for the menu, check if it is defined ad hidden in TSconfig
116  $hideModules = ‪GeneralUtility::trimExplode(',', $user->‪getTSConfig()['options.']['hideModules'] ?? '', true);
117  if (in_array(‪$identifier, $hideModules, true)) {
118  return null;
119  }
120  $menuItem = new ‪MenuModule(clone $module);
121  if ($menuItem->isStandalone()) {
122  return $menuItem;
123  }
124  foreach ($module->getSubModules() as $subModuleIdentifier => $subModule) {
125  if (in_array($subModuleIdentifier, $hideModules, true)) {
126  continue;
127  }
128  $subMenuItem = new ‪MenuModule(clone $subModule);
129  $menuItem->addSubModule($subMenuItem);
130  }
131  if (!$menuItem->hasSubModules()) {
132  // In case the main module does not have any submodules, unset it again
133  return null;
134  }
135  return $menuItem;
136  }
137 
145  public function ‪getModulesForModuleMenu(
147  bool $respectWorkspaceRestrictions = true
148  ): array {
149  $moduleMenuItems = [];
150  $moduleMenuState = json_decode($user->uc['modulemenu'] ?? '{}', true);
151 
152  // Before preparing the modules for the menu, check if we need to hide some of them (defined in TSconfig)
153  $hideModules = ‪GeneralUtility::trimExplode(',', $user->‪getTSConfig()['options.']['hideModules'] ?? '', true);
154  foreach ($this->‪getModules($user, $respectWorkspaceRestrictions) as ‪$identifier => $module) {
155  if (in_array(‪$identifier, $hideModules, true)
156  || !($module->getAppearance()['renderInModuleMenu'] ?? true)
157  ) {
158  continue;
159  }
160  // Only use main modules for this first level
161  if ($module->hasParentModule()) {
162  continue;
163  }
164  $menuItem = new ‪MenuModule(clone $module, isset($moduleMenuState[‪$identifier]));
165  $moduleMenuItems[‪$identifier] = $menuItem;
166  if ($menuItem->isStandalone()) {
167  continue;
168  }
169  foreach ($module->getSubModules() as $subModuleIdentifier => $subModule) {
170  if (in_array($subModuleIdentifier, $hideModules, true)
171  || !($subModule->getAppearance()['renderInModuleMenu'] ?? true)
172  ) {
173  continue;
174  }
175  $subMenuItem = new ‪MenuModule(clone $subModule);
176  $menuItem->addSubModule($subMenuItem);
177  }
178  if (!$menuItem->hasSubModules()) {
179  // In case the main module does not have any submodules, unset it again
180  unset($moduleMenuItems[‪$identifier]);
181  }
182  }
183  return $moduleMenuItems;
184  }
185 
189  public function ‪accessGranted(
190  string ‪$identifier,
192  bool $respectWorkspaceRestrictions = true
193  ): bool {
194  if (!$this->moduleRegistry->hasModule(‪$identifier)) {
195  return false;
196  }
197 
198  $module = $this->moduleRegistry->getModule(‪$identifier);
199 
200  if ($respectWorkspaceRestrictions && ‪ExtensionManagementUtility::isLoaded('workspaces')) {
201  $workspaceAccess = $module->getWorkspaceAccess();
202  if ($workspaceAccess === '' && $module->hasParentModule()) {
203  // In case workspace access is not set explicitly use the information
204  // from the parent module as this access restriction is inherited.
205  $workspaceAccess = $module->getParentModule()->getWorkspaceAccess();
206  }
207  if ($workspaceAccess !== '' && $workspaceAccess !== '*') {
208  if (($workspaceAccess === 'live' && $user->workspace !== 0)
209  || ($workspaceAccess === 'offline' && $user->workspace === 0)
210  ) {
211  return false;
212  }
213  } elseif ($user->workspace === -99) {
214  return false;
215  }
216  }
217 
218  $moduleAccess = $module->getAccess();
219  if ($moduleAccess === '') {
220  // Early return since this module does not have any access permissions set
221  return true;
222  }
223 
224  // Check if this module is only allowed by system maintainers (= admins who are in the list of system maintainers)
226  return $user->‪isSystemMaintainer();
227  }
228 
229  // Check if this module is only allowed by admins
230  if ($moduleAccess === 'admin') {
231  return $user->‪isAdmin();
232  }
233 
234  // This checks if a user is permitted to access the module, being
235  // either admin or having necessary module access permissions set.
236  if ($user->‪isAdmin() || $user->‪check('modules', ‪$identifier)) {
237  return true;
238  }
239 
240  return false;
241  }
242 
250  {
251  $modules = array_filter($this->moduleRegistry->getModules(), ‪function (‪ModuleInterface $module) use ($user): bool {
252  return $this->‪accessGranted($module->‪getIdentifier(), $user)
253  && ($module->‪isStandalone() || $module->‪hasParentModule());
254  });
255 
256  return reset($modules) ?: null;
257  }
258 
265  public function ‪getUserModules(): array
266  {
267  return array_filter($this->moduleRegistry->getModules(), static fn(‪ModuleInterface $module): bool => $module->‪getAccess() === 'user');
268  }
269 }
‪TYPO3\CMS\Backend\Module\ModuleInterface\getSubModules
‪ModuleInterface[] getSubModules()
‪TYPO3\CMS\Backend\Module\ModuleInterface\removeSubModule
‪removeSubModule(string $identifier)
‪TYPO3\CMS\Backend\Module\ModuleProvider\getFirstAccessibleModule
‪getFirstAccessibleModule(BackendUserAuthentication $user)
Definition: ModuleProvider.php:249
‪TYPO3\CMS\Backend\Module\ModuleProvider\accessGranted
‪accessGranted(string $identifier, BackendUserAuthentication $user, bool $respectWorkspaceRestrictions=true)
Definition: ModuleProvider.php:189
‪TYPO3\CMS\Backend\Module\ModuleRegistry
Definition: ModuleRegistry.php:28
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getTSConfig
‪array getTSConfig()
Definition: BackendUserAuthentication.php:857
‪TYPO3\CMS\Backend\Module\ModuleInterface\isStandalone
‪isStandalone()
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\isAdmin
‪bool isAdmin()
Definition: BackendUserAuthentication.php:241
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\check
‪bool check($type, $value)
Definition: BackendUserAuthentication.php:514
‪TYPO3\CMS\Backend\Module\ModuleProvider\isModuleRegistered
‪isModuleRegistered(string $identifier)
Definition: ModuleProvider.php:36
‪TYPO3\CMS\Backend\Module\ModuleProvider
Definition: ModuleProvider.php:29
‪TYPO3\CMS\Backend\Module\ModuleProvider\getModulesForModuleMenu
‪MenuModule[] getModulesForModuleMenu(BackendUserAuthentication $user, bool $respectWorkspaceRestrictions=true)
Definition: ModuleProvider.php:145
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\isSystemMaintainer
‪isSystemMaintainer(bool $pure=false)
Definition: BackendUserAuthentication.php:358
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\isLoaded
‪static isLoaded(string $key)
Definition: ExtensionManagementUtility.php:55
‪TYPO3\CMS\Backend\Module\ModuleInterface\getAccess
‪getAccess()
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility
Definition: ExtensionManagementUtility.php:32
‪TYPO3\CMS\Backend\Module\ModuleInterface\getIdentifier
‪getIdentifier()
‪TYPO3\CMS\Backend\function
‪static return function(ContainerConfigurator $container, ContainerBuilder $containerBuilder)
Definition: Services.php:19
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\ROLE_SYSTEMMAINTAINER
‪const ROLE_SYSTEMMAINTAINER
Definition: BackendUserAuthentication.php:63
‪TYPO3\CMS\Backend\Module\ModuleProvider\getModules
‪ModuleInterface[] getModules(?BackendUserAuthentication $user=null, bool $respectWorkspaceRestrictions=true, bool $grouped=true)
Definition: ModuleProvider.php:72
‪TYPO3\CMS\Backend\Module\MenuModule
Definition: MenuModule.php:26
‪TYPO3\CMS\Backend\Module\ModuleProvider\getModuleForMenu
‪getModuleForMenu(string $identifier, BackendUserAuthentication $user, bool $respectWorkspaceRestrictions=true)
Definition: ModuleProvider.php:106
‪TYPO3\CMS\Backend\Module\ModuleInterface
Definition: ModuleInterface.php:24
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Backend\Module\ModuleInterface\hasParentModule
‪hasParentModule()
‪TYPO3\CMS\Backend\Module\ModuleProvider\__construct
‪__construct(protected readonly ModuleRegistry $moduleRegistry)
Definition: ModuleProvider.php:30
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Backend\Module
Definition: BaseModule.php:18
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode(string $delim, string $string, bool $removeEmptyValues=false, int $limit=0)
Definition: GeneralUtility.php:822
‪TYPO3\CMS\Backend\Module\ModuleProvider\getUserModules
‪ModuleInterface[] getUserModules()
Definition: ModuleProvider.php:265
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37
‪TYPO3\CMS\Backend\Module\ModuleProvider\getModule
‪getModule(string $identifier, ?BackendUserAuthentication $user=null, bool $respectWorkspaceRestrictions=true)
Definition: ModuleProvider.php:44