TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,293 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Beuser\Service;
|
||||
|
||||
use TYPO3\CMS\Backend\Module\ModuleProvider;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\DataHandling\PageDoktypeRegistry;
|
||||
use TYPO3\CMS\Core\Imaging\Icon;
|
||||
use TYPO3\CMS\Core\Imaging\IconFactory;
|
||||
use TYPO3\CMS\Core\Imaging\IconSize;
|
||||
use TYPO3\CMS\Core\Schema\Field\StaticSelectFieldType;
|
||||
use TYPO3\CMS\Core\Schema\SchemaLabelResolver;
|
||||
use TYPO3\CMS\Core\Schema\TcaSchemaFactory;
|
||||
use TYPO3\CMS\Core\Site\SiteFinder;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Transform information of user and groups into better format
|
||||
* @internal
|
||||
*/
|
||||
final readonly class UserInformationService
|
||||
{
|
||||
public function __construct(
|
||||
private IconFactory $iconFactory,
|
||||
private ModuleProvider $moduleProvider,
|
||||
private TcaSchemaFactory $tcaSchemaFactory,
|
||||
private PageDoktypeRegistry $pageDoktypeRegistry,
|
||||
private SchemaLabelResolver $schemaLabelResolver,
|
||||
private SiteFinder $siteFinder,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Get all relevant information for a backend usergroup
|
||||
*/
|
||||
public function getGroupInformation(int $groupId): array
|
||||
{
|
||||
$usergroupRecord = BackendUtility::getRecord('be_groups', $groupId);
|
||||
if (!$usergroupRecord) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$user = GeneralUtility::makeInstance(BackendUserAuthentication::class);
|
||||
$user->enablecolumns = [
|
||||
'deleted' => true,
|
||||
];
|
||||
|
||||
// Setup dummy user to allow fetching all group data
|
||||
// @see \TYPO3\CMS\Core\Authentication\BackendUserAuthentication::fetchGroups
|
||||
$user->user = [
|
||||
'uid' => PHP_INT_MAX,
|
||||
'options' => 3,
|
||||
// The below admin flag is required to prevent workspace access checks,
|
||||
// triggered by workspaceInit() in fetchGroupData(). Those would fail
|
||||
// due to insufficient permissions of the dummy user and therefore might
|
||||
// result in generating superfluous log entries.
|
||||
'admin' => 1,
|
||||
'workspace_id' => 0,
|
||||
'realName' => 'fakeUser',
|
||||
'email' => 'fake.user@typo3.org',
|
||||
'TSconfig' => '',
|
||||
'category_perms' => '',
|
||||
$user->usergroup_column => $groupId,
|
||||
];
|
||||
$user->fetchGroupData();
|
||||
|
||||
$data = $this->convert($user);
|
||||
$data['group'] = $usergroupRecord;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all relevant information of the user
|
||||
*/
|
||||
public function getUserInformation(int $userId): array
|
||||
{
|
||||
$user = GeneralUtility::makeInstance(BackendUserAuthentication::class);
|
||||
$user->enablecolumns = [
|
||||
'deleted' => true,
|
||||
];
|
||||
$user->setBeUserByUid($userId);
|
||||
if (!$user->user) {
|
||||
return [];
|
||||
}
|
||||
$user->fetchGroupData();
|
||||
|
||||
return $this->convert($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert hard readable user & group information into structured
|
||||
* data which can be rendered later
|
||||
*/
|
||||
private function convert(BackendUserAuthentication $user): array
|
||||
{
|
||||
// usergroups
|
||||
$data = [
|
||||
'user' => $user->user ?? [],
|
||||
'groups' => [
|
||||
'inherit' => $user->userGroupsUID,
|
||||
'direct' => GeneralUtility::trimExplode(',', (string)($user->user['usergroup'] ?? ''), true),
|
||||
],
|
||||
'modules' => [],
|
||||
];
|
||||
$data['groups']['diff'] = array_diff($data['groups']['inherit'], $data['groups']['direct']);
|
||||
foreach ($data['groups'] as $type => $groups) {
|
||||
foreach ($groups as $id) {
|
||||
$record = BackendUtility::getRecord('be_groups', (int)$id);
|
||||
if (isset($record['uid'])) {
|
||||
$recordId = $record['uid'];
|
||||
$data['groups']['all'][$recordId]['row'] = $record;
|
||||
$data['groups']['all'][$recordId][$type] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// languages
|
||||
$siteLanguages = $this->getAllSiteLanguages();
|
||||
$userLanguages = GeneralUtility::trimExplode(',', $user->groupData['allowed_languages'] ?? '', true);
|
||||
asort($userLanguages);
|
||||
foreach ($userLanguages as $languageId) {
|
||||
$languageId = (int)$languageId;
|
||||
$record = $siteLanguages[$languageId] ?? null;
|
||||
if ($record) {
|
||||
$data['languages'][$languageId] = $record;
|
||||
}
|
||||
}
|
||||
|
||||
// table permissions
|
||||
$data['tables']['tables_select'] = [];
|
||||
$data['tables']['tables_modify'] = [];
|
||||
foreach (['tables_select', 'tables_modify'] as $tableField) {
|
||||
$temp = GeneralUtility::trimExplode(',', $user->groupData[$tableField] ?? '', true);
|
||||
foreach ($temp as $tableName) {
|
||||
if ($this->tcaSchemaFactory->has($tableName)) {
|
||||
$data['tables'][$tableField][$tableName] = $this->tcaSchemaFactory->get($tableName)->getTitle() ?: $tableName;
|
||||
}
|
||||
}
|
||||
}
|
||||
$data['tables']['all'] = array_replace($data['tables']['tables_select'], $data['tables']['tables_modify']);
|
||||
|
||||
// Page Tree Entry Points / dbMounts
|
||||
$dbMounts = GeneralUtility::trimExplode(',', $user->groupData['webmounts'] ?? '', true);
|
||||
asort($dbMounts);
|
||||
foreach ($dbMounts as $mount) {
|
||||
$record = BackendUtility::getRecord('pages', (int)$mount);
|
||||
if ($record) {
|
||||
$data['dbMounts'][] = $record;
|
||||
}
|
||||
}
|
||||
|
||||
// File mounts
|
||||
$fileMounts = GeneralUtility::trimExplode(',', $user->groupData['filemounts'] ?? '', true);
|
||||
asort($fileMounts);
|
||||
foreach ($fileMounts as $mount) {
|
||||
$record = BackendUtility::getRecord('sys_filemounts', (int)$mount);
|
||||
if ($record) {
|
||||
$data['fileMounts'][] = $record;
|
||||
}
|
||||
}
|
||||
|
||||
// Modules
|
||||
$modules = GeneralUtility::trimExplode(',', $user->groupData['modules'] ?? '', true);
|
||||
foreach ($modules as $moduleIdentifier) {
|
||||
if ($this->moduleProvider->isModuleRegistered($moduleIdentifier)) {
|
||||
$data['modules'][] = $this->moduleProvider->getModule($moduleIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
// Categories
|
||||
$categories = $user->getCategoryMountPoints();
|
||||
foreach ($categories as $category) {
|
||||
$record = BackendUtility::getRecord('sys_category', $category);
|
||||
if ($record) {
|
||||
$data['categories'][$category] = $record;
|
||||
}
|
||||
}
|
||||
|
||||
// workspaces
|
||||
if (ExtensionManagementUtility::isLoaded('workspaces')) {
|
||||
$data['workspaces'] = [
|
||||
'loaded' => true,
|
||||
'record' => $user->workspaceRec,
|
||||
];
|
||||
}
|
||||
|
||||
// file & folder permissions
|
||||
$filePermissions = $user->groupData['file_permissions'] ?? '';
|
||||
if ($filePermissions) {
|
||||
$items = GeneralUtility::trimExplode(',', $filePermissions, true);
|
||||
/** @var StaticSelectFieldType $fieldType */
|
||||
$fieldType = $this->tcaSchemaFactory->get('be_groups')->getField('file_permissions');
|
||||
foreach ($fieldType->getConfiguration()['items'] ?? [] as $availableItem) {
|
||||
if (in_array($availableItem['value'], $items, true)) {
|
||||
$data['fileFolderPermissions'][] = $availableItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tsconfig
|
||||
$data['tsconfig'] = $user->getTSConfig();
|
||||
|
||||
// non_exclude_fields
|
||||
$fieldListTmp = GeneralUtility::trimExplode(',', $user->groupData['non_exclude_fields'] ?? '', true);
|
||||
$fieldList = [];
|
||||
foreach ($fieldListTmp as $item) {
|
||||
$itemParts = explode(':', $item);
|
||||
$itemTable = $itemParts[0];
|
||||
$itemField = $itemParts[1] ?? '';
|
||||
if (!empty($itemField) && $this->tcaSchemaFactory->has($itemTable)) {
|
||||
$schema = $this->tcaSchemaFactory->get($itemTable);
|
||||
$fieldList[$itemTable]['label'] = $schema->getTitle();
|
||||
if ($schema->hasField($itemField)) {
|
||||
$fieldList[$itemTable]['fields'][$itemField] = $schema->getField($itemField)->getLabel();
|
||||
}
|
||||
}
|
||||
}
|
||||
$data['non_exclude_fields'] = $fieldList;
|
||||
|
||||
// page types
|
||||
foreach ($this->pageDoktypeRegistry->getAllDoktypes() as $specialItem) {
|
||||
if (!GeneralUtility::inList($user->groupData['pagetypes_select'] ?? '', $specialItem->getValue())) {
|
||||
continue;
|
||||
}
|
||||
$label = $specialItem->getLabel();
|
||||
$icon = $specialItem->getIcon() ?? 'apps-pagetree-page-default';
|
||||
$data['pageTypes'][] = ['label' => $label, 'value' => $specialItem->getValue(), 'icon' => $icon];
|
||||
}
|
||||
|
||||
// page content types
|
||||
$pageContentTypes = GeneralUtility::trimExplode(',', $user->groupData['explicit_allowdeny'] ?? '', true);
|
||||
foreach ($pageContentTypes as $item) {
|
||||
$split = explode(':', $item);
|
||||
if (count($split) !== 3) {
|
||||
continue;
|
||||
}
|
||||
[$table, $recordType, $recordTypeValue] = $split;
|
||||
$label = $this->schemaLabelResolver->getLabelForFieldValue(...$split);
|
||||
$data['pageContentTypes'][] = [
|
||||
// If label is empty => the record type value does not exist so we use "empty-empty" as icon instead of falling back to the default record type icon
|
||||
'icon' => $label ? $this->iconFactory->getIconForRecord($table, [$recordType => $recordTypeValue], IconSize::SMALL)->getIdentifier() : 'install-check-extables',
|
||||
'label' => $label,
|
||||
'shortType' => $recordTypeValue,
|
||||
'longType' => $item,
|
||||
];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function getAllSiteLanguages(): array
|
||||
{
|
||||
$siteLanguages = [];
|
||||
foreach ($this->siteFinder->getAllSites() as $site) {
|
||||
foreach ($site->getAllLanguages() as $languageId => $language) {
|
||||
if (isset($siteLanguages[$languageId])) {
|
||||
// Language already provided by another site, check if values differ
|
||||
if (!str_contains($siteLanguages[$languageId]['title'], $language->getTitle())) {
|
||||
// Language already provided by another site, but with a different title
|
||||
$siteLanguages[$languageId]['title'] .= ', ' . $language->getTitle();
|
||||
}
|
||||
if ($siteLanguages[$languageId]['flagIconIdentifier'] !== $language->getFlagIdentifier()) {
|
||||
// Language already provided by another site, but with a different flag icon identifier
|
||||
$siteLanguages[$languageId]['flagIconIdentifier'] = 'flags-multiple';
|
||||
}
|
||||
} else {
|
||||
$siteLanguages[$languageId] = [
|
||||
'title' => $language->getTitle(),
|
||||
'flagIconIdentifier' => $language->getFlagIdentifier(),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $siteLanguages;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user