#typo3 #extbase
#typo3 #extbase
Вопрос:
Сценарий:
ContactPerson имеет отношение к интерфейсному пользователю и является стороной-владельцем отношения. Теперь у меня следующая проблема:
я активирую / деактивирую интерфейсных пользователей в задаче на основе активных контактных лиц. Когда интерфейсный пользователь отключен или удален, результат ContactPerson-> getFrontendUser() равен нулю, даже если оба репозитория игнорируют поля:
/** @var Typo3QuerySettings $querySettings */
$querySettings = $this->objectManager->get(Typo3QuerySettings::class);
$querySettings->setIgnoreEnableFields(true);
$querySettings->setRespectStoragePage(false);
$this->frontendUserRepository->setDefaultQuerySettings($querySettings);
$debugContactPerson = $this->contactPersonRepository->findOneByContactPersonIdAndIncludeDeletedAndHidden('634');
$debugFrontendUser = $this->frontendUserRepository->findOneByUid(7);
TYPO3CMSExtbaseUtilityDebuggerUtility::var_dump(
array(
'$debugContactPerson' => $debugContactPerson,
'$debugFrontendUser' => $debugFrontendUser,
)
);
P.s.: $this->frontendUserRepository->findByUid(7);
также не работает, потому что он не использует запрос, но persistenceManager->getObjectByIdentifier(...
, конечно, игнорирует настройки запроса.
Проблема в том, что в моем реальном коде я не могу использовать findOneByUid(), потому что я не могу получить целочисленное значение (uid) в поле frontend_user поля contact_person .
Есть ли способ решить эту проблему без использования необработанного запроса для получения строки contact_person?
Мое (да, необработанный запрос) решение:
Поскольку я не хотел писать собственный QueryFactory и не хотел добавлять избыточное поле к моему контактеру, я решил это сейчас с помощью необработанного оператора. Может быть, это может помочь кому-то с той же проблемой:
class FrontendUserRepository extends TYPO3CMSExtbaseDomainRepositoryFrontendUserRepository
{
/**
* @param VendorExtKeyDomainModelContactPerson $contactPerson
* @return Object
*/
public function findByContactPersonByRawQuery(ContactPerson $contactPerson){
$query = $this->createQuery();
$query->statement(
"SELECT fe_users.* FROM fe_users" .
" LEFT JOIN tx_extkey_domain_model_contactperson contact_person ON contact_person.frontend_user = fe_users.uid" .
" WHERE contact_person.uid = " . $contactPerson->getUid()
);
return $query->execute()->getFirst();
}
}
Комментарии:
1. Я опубликовал отчет об ошибке для TYPO3: forge.typo3.org/issues/84955
Ответ №1:
Прямой вызов репозитория
Для полей включения таблицы есть два аспекта fe_users
:
$querySettings->setIgnoreEnableFields(true);
$querySettings->setEnableFieldsToBeIgnored(['disable']);
Посмотрите на некоторый обзор на странице wiki — там написано 6.2, но он по-прежнему действителен в большинстве частей для 7.6 и 8. Однако это работает только в том случае, если репозиторий вызывается напрямую, но не в том случае, если объект извлекается как часть другого объекта — в этом случае репозиторий не используется для вложенных объектов.
Измените настройки запроса для вложенных объектов
Вложенные объекты извлекаются неявно — это происходит в DataMapper::getPreparedQuery(DomainObjectInterface $parentObject, $propertyName)
. Чтобы настроить параметры запроса для дочерних объектов, QueryFactoryInterface
реализация должна быть перегружена.
Зарегистрируйте альтернативную реализацию в ext_localconf.php
(замените VendorExtensionNamePersistenceGenericQueryFactory
на реальное имя класса вашего расширения):
$extbaseObjectContainer = TYPO3CMSCoreUtilityGeneralUtility::makeInstance(
TYPO3CMSExtbaseObjectContainerContainer::class
);
$extbaseObjectContainer->registerImplementation(
TYPO3CMSExtbasePersistenceGenericQueryFactoryInterface::class,
VendorExtensionNamePersistenceGenericQueryFactory::class
);
С новыми версиями Typo3 (v8 ) метод registerImplementation больше не работает для QueryFactory. Вместо этого для перезаписи / расширения класса необходимо использовать XCLASS:
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][TYPO3CMSExtbasePersistenceGenericQueryFactory::class] = [
'className' => VendorExtensionNamePersistenceGenericQueryFactory::class,
];
Затем внутри реализации:
<?php
namespace VendorExtensionNamePersistenceGeneric;
use TYPO3CMSExtbaseDomainModelFrontendUser;
class QueryFactory extends TYPO3CMSExtbasePersistenceGenericQueryFactory {
public function create($className) {
$query = parent::create($className);
if (is_a($className, FrontendUser::class, true)) {
// @todo Find a way to configure that more generic
$querySettings = $query->getQuerySettings();
$querySettings->setIgnoreEnableFields(true);
// ... whatever you need to adjust in addition ...
}
return $query;
}
}
Комментарии:
1. $querySettings-> setIgnoreEnableFields(true);
2. // если больше ничего не указано, все разрешаемые поля игнорируются $querySettings-> setIgnoreEnableFields(true); // определите отдельные поля, которые будут игнорироваться $querySettings-> setEnableFieldsToBeIgnored([‘disable’]); Первый должен отключить все разрешаемые поля. Но это влияет только на запросы репозитория, а не на отношение какой-либо другой модели.
3. Точно, это работает только в том случае, если репозиторий вызывается напрямую, но не в том случае, если объект извлекается как часть другого объекта — в этом случае репозиторий не используется для вложенных объектов. Я обновлю приведенный выше ответ, чтобы привести пример того, как это сделать по отдельности.
4. @OliverHader Есть опыт работы с 8.7.x? Я не могу получить fe_users, которые отключены. Работал с 7.6.x
Ответ №2:
Мое решение этой проблемы состояло в том, чтобы отключить «enablecolumns» в определениях TCA и разобраться с этим в репозитории самостоятельно. Вот пример метода findAll:
public function findAll($ignoreEnableFields = false) {
$query = $this->createQuery();
if (!$ignoreEnableFields) {
$currTime = time();
$query->matching(
$query->logicalAnd(
$query->equals("hidden", 0),
$query->logicalOr(
$query->equals("starttime", 0),
$query->lessThanOrEqual("starttime", $currTime)
),
$query->logicalOr(
$query->equals("endtime", 0),
$query->greaterThanOrEqual("endtime", $currTime)
)
)
);
}
return $query->execute();
}
Комментарии:
1. Отключение раздела
$TCA['fe_users']['ctrl']['enablecolumns']
оказывает глобальное влияние на все обработчики интерфейсных пользователей, а не только на приложения Extbase. Таким образом, это, вероятно, также изменит поведение входа в систему — отключенные или просроченные учетные записи пользователей все еще могут использоваться для входа в соответствующее приложение.