问题描述
我有以下型号:
ContactPerson 与 FrontendUser 有关系,并且是关系的拥有方.现在我有以下问题:
我正在根据处于活动状态的 ContactPersons 在任务中激活/停用 FrontendUsers.当 FrontendUser 被禁用或删除时,contactPerson->getFrontendUser() 的结果为 null,即使两个存储库都忽略了EnableFields:
ContactPerson has a relation to FrontendUser and is the owning side of the relation. Now I have following problem:
I am activating/deactivating the FrontendUsers in a task, based on the ContactPersons which are active. When the FrontendUser is disabled or deleted the result of contactPerson->getFrontendUser() is null, even if both repositories ignoreEnableFields:
/** @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);
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump(
array(
'$debugContactPerson' => $debugContactPerson,
'$debugFrontendUser' => $debugFrontendUser,
)
);
结果:
Ps:$this->frontendUserRepository->findByUid(7);
也不起作用,因为它没有使用查询,但是 persistenceManager->getObjectByIdentifier(...
这当然会忽略查询设置.
P.s.: $this->frontendUserRepository->findByUid(7);
also doesn't work because it isn't using the query, but persistenceManager->getObjectByIdentifier(...
which is of course ignoring the query-settings.
问题是,在我的实际代码中,我无法使用 findOneByUid(),因为我无法在 contact_person 的 frontend_user 字段中获取 integer-Value(uid).
The problem is, in my real code I can't use findOneByUid(), because I can't get the integer-Value(uid) in the frontend_user field of the contact_person.
有什么方法可以在不使用原始查询来获取 contact_person-row 的情况下解决这个问题?
Any way to solve this without using a raw query to get the contact_person-row?
因为我不想编写自己的 QueryFactory 并且我不想向我的 contactPerson 添加冗余字段,所以我现在用原始语句解决了它.也许它可以帮助有同样问题的人:
Because I didn't want to write an own QueryFactory and I didn't want to add a redundant field to my contactPerson I solved it now with a raw statement. Maybe it can help someone with the same problem:
class FrontendUserRepository extends \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository
{
/**
* @param \Vendor\ExtKey\Domain\Model\ContactPerson $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();
}
}
推荐答案
直接调用仓库
fe_users
表的enable字段有两个方面:
Invoking repository directly
There are two aspects for the enable fields of table fe_users
:
$querySettings->setIgnoreEnableFields(true);
$querySettings->setEnableFieldsToBeIgnored(['disable']);
看看一些wiki 页面 - 它说 6.2,但它在 7.6 和 8 的大多数部分仍然有效.但是,这仅适用于直接调用存储库的情况,而不适用于作为另一个实体的一部分检索实体的情况 - 在这种情况下,存储库不用于嵌套实体.
Have a look to some overview in the wiki page - it says 6.2, but it's still valid in most parts for 7.6 and 8 as well. However, this only works if the repository is invoked directly, but not if an entity is retrieved as part of another entity - in this case the repository is not used for nested entities.
隐式检索嵌套实体 - 这发生在 DataMapper::getPreparedQuery(DomainObjectInterface $parentObject, $propertyName)
中.要调整子实体的查询设置,必须重载 QueryFactoryInterface
实现.
Nested entities are retrieved implicitly - this happens in DataMapper::getPreparedQuery(DomainObjectInterface $parentObject, $propertyName)
. To adjust query settings for child entities, the QueryFactoryInterface
implementation has to be overloaded.
在 ext_localconf.php
中注册一个替代实现(用你的扩展的真实类名替换 \Vendor\ExtensionName\Persistence\Generic\QueryFactory
):
Register an alternative implementation in ext_localconf.php
(replace \Vendor\ExtensionName\Persistence\Generic\QueryFactory
with the real class name of your extension):
$extbaseObjectContainer = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
\TYPO3\CMS\Extbase\Object\Container\Container::class
);
$extbaseObjectContainer->registerImplementation(
\TYPO3\CMS\Extbase\Persistence\Generic\QueryFactoryInterface::class,
\Vendor\ExtensionName\Persistence\Generic\QueryFactory::class
);
在新的 Typo3 版本 (v8+) 中,registerImplementation 方法不再适用于 QueryFactory.相反,XCLASS 必须用于覆盖/扩展类:
With new Typo3 versions (v8+), the registerImplementation method no longer works for QueryFactory. Instead, a XCLASS must be used to overwrite/extend the class:
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\TYPO3\CMS\Extbase\Persistence\Generic\QueryFactory::class] = [
'className' => \Vendor\ExtensionName\Persistence\Generic\QueryFactory::class,
];
然后在实现里面:
Then inside the implementation:
<?php
namespace \Vendor\ExtensionName\Persistence\Generic;
use TYPO3\CMS\Extbase\Domain\Model\FrontendUser;
class QueryFactory extends \TYPO3\CMS\Extbase\Persistence\Generic\QueryFactory {
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;
}
}
这篇关于TYPO3 Extbase:如何在没有原始 sql 查询的情况下禁用相关对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!