getCategoryBeGroupTceFormsRestriction()) { return true; } if (self::getBackendUser()->isAdmin()) { // an admin may edit all news return true; } // If there are any categories with denied access, the user has no permission if (count(self::getAccessDeniedCategories($newsRecord))) { return false; } return true; } /** * Get an array with the uid and title of all categories the user doesn't have access to * * @param array $newsRecord * @return array */ public static function getAccessDeniedCategories(array $newsRecord): array { if (self::getBackendUser()->isAdmin()) { // an admin may edit all news so no categories without access return []; } // no category mounts set means access to all $backendUserCategories = self::getBackendUser()->getCategoryMountPoints(); if ($backendUserCategories === []) { return []; } $catService = GeneralUtility::makeInstance(CategoryService::class); $subCategories = $catService::getChildrenCategories(implode(',', $backendUserCategories)); if (!empty($subCategories)) { $backendUserCategories = explode(',', $subCategories); } $newsRecordCategories = self::getCategoriesForNewsRecord($newsRecord); // Remove categories the user has access to foreach ($newsRecordCategories as $key => $newsRecordCategory) { if (in_array($newsRecordCategory['uid'], $backendUserCategories)) { unset($newsRecordCategories[$key]); } } return $newsRecordCategories; } /** * Get all categories for a news record respecting l10n_mode * * @param array $newsRecord * @return array */ public static function getCategoriesForNewsRecord($newsRecord): array { // determine localization overlay mode to select categories either from parent or localized record if ($newsRecord['sys_language_uid'] > 0 && $newsRecord['l10n_parent'] > 0) { // localized version of a news record $categoryL10nMode = $GLOBALS['TCA']['tx_news_domain_model_news']['columns']['categories']['l10n_mode']; if ($categoryL10nMode === 'mergeIfNotBlank') { $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable('sys_category_record_mm'); $newsRecordCategoriesCount = $queryBuilder->count('*') ->from('sys_category_record_mm') ->where( $queryBuilder->expr()->eq('uid_foreign', $queryBuilder->createNamedParameter($newsRecord['uid'], \PDO::PARAM_INT)), $queryBuilder->expr()->eq('tablenames', $queryBuilder->createNamedParameter('tx_news_domain_model_news', \PDO::PARAM_STR)), $queryBuilder->expr()->eq('fieldname', $queryBuilder->createNamedParameter('categories', \PDO::PARAM_STR)) ) ->execute() ->fetchColumn(0); if ($newsRecordCategoriesCount > 0) { // take categories from localized version $newsRecordUid = $newsRecord['uid']; } else { // inherit categories from parent $newsRecordUid = $newsRecord['l10n_parent']; } } elseif ($categoryL10nMode === 'exclude') { // exclude: The localized version inherits the categories of the parent $newsRecordUid = $newsRecord['l10n_parent']; } else { // noCopy/prefixLangTitle: no inheritance $newsRecordUid = $newsRecord['uid']; } } else { $newsRecordUid = $newsRecord['uid']; } $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable('sys_category'); $queryBuilder->getRestrictions() ->removeByType(StartTimeRestriction::class) ->removeByType(HiddenRestriction::class) ->removeByType(EndTimeRestriction::class); $res = $queryBuilder ->select('sys_category_record_mm.uid_local', 'sys_category.title') ->from('sys_category') ->leftJoin( 'sys_category', 'sys_category_record_mm', 'sys_category_record_mm', $queryBuilder->expr()->eq('sys_category_record_mm.uid_local', $queryBuilder->quoteIdentifier('sys_category.uid')) ) ->where( $queryBuilder->expr()->eq('sys_category_record_mm.tablenames', $queryBuilder->createNamedParameter('tx_news_domain_model_news', \PDO::PARAM_STR)), $queryBuilder->expr()->eq('sys_category_record_mm.fieldname', $queryBuilder->createNamedParameter('categories', \PDO::PARAM_STR)), $queryBuilder->expr()->eq('sys_category_record_mm.uid_foreign', $queryBuilder->createNamedParameter($newsRecordUid, \PDO::PARAM_INT)) ) ->execute(); $categories = []; while ($row =$res->fetch()) { $categories[] = [ 'uid' => $row['uid_local'], 'title' => $row['title'] ]; } return $categories; } /** * Returns the current BE user. * * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication */ protected static function getBackendUser(): \TYPO3\CMS\Core\Authentication\BackendUserAuthentication { return $GLOBALS['BE_USER']; } }