当前位置: 首页 > 知识库问答 >
问题:

TYPO3 Extbase:如何在没有原始sql查询的情况下获得禁用的相关对象?

阚元白
2023-03-14

ContactPerson与FrontendUser有关系,是关系的拥有方。现在我有以下问题:
我正在根据活动联系人激活/停用任务中的前端用户。当FrontendUser被禁用或删除时,contactPerson的结果-

    /** @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,
        )
    );

附言:$this-

问题是,在我的实际代码中,我无法使用findOneByUid(),因为我无法获取联系人的前端用户字段中的整数值(uid)。

如果不使用原始查询来获取联系人行,有没有办法解决这个问题?

因为我不想编写自己的QueryFactory,也不想在contactPerson中添加冗余字段,所以我现在用一条原始语句解决了这个问题。也许它可以帮助有同样问题的人:

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();
    }

}

共有2个答案

凤高澹
2023-03-14

我解决这个问题的方法是禁用TCA定义中的“enablecolumns”,然后自己在存储库中处理这个问题。这里是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();
}
郎泰平
2023-03-14

fe\u用户的启用字段有两个方面:

  • $querySettings-

看看wiki页面中的一些概述——上面写着6.2,但在7.6和8的大多数部分仍然有效。但是,这仅在直接调用存储库的情况下有效,而在作为另一个实体的一部分检索实体的情况下无效——在这种情况下,存储库不用于嵌套实体。

嵌套实体是隐式检索的-这发生在DataMapper::getPreparedQuery(DomainObjectInterface$parentObject,$propertyName)中。要调整子实体的查询设置,必须重载QueryFactoryInterface实现。

ext\u localconf中注册一个替代实现。php(用扩展的真实类名替换\Vendor\ExtensionName\Persistence\Generic\QueryFactory):

$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来覆盖/扩展该类:

$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\TYPO3\CMS\Extbase\Persistence\Generic\QueryFactory::class] = [
    'className' => \Vendor\ExtensionName\Persistence\Generic\QueryFactory::class,
];

然后在实现内部:

<?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;
    }
}

 类似资料:
  • 我正在创建一个进程,该进程通过JDBC连接到给定的SQL Server数据库,扫描每个表,并读取自上次运行该进程以来插入或更新的任何新数据。出于性能考虑,数据库所有者将不允许此进程对任何表进行联接。 所讨论的情景 表A是表B的父表 此过程从表A中读取数据 在读取表B的过程之前,将新的父记录插入表a,并将新的子记录插入表B 读取表B时,会出现子记录,这些子记录在上一次读取表a的结果集中没有相应的父记

  • 如果您说这是不可能的,那么我必须坚持HQL,我会在这里张贴的查询,我将需要您的帮助写下基于HQL的类(表)创建和基于HQL的查询字符串。 此外,如果您可以,请给我一个示例查询与夫妇或3个表联接,以及如何设置参数的SQL。

  • 有没有办法在Spring MVC中获取当前会话,但不是通过请求。通常,我们所做的是在操作/控制器类方法中获取请求。从这个请求中,我们逐个请求获得会话。getSession()。但是,有没有办法在没有此请求对象的情况下获取此会话? 我的动机是,在一个实用程序类中,我需要访问会话中设置的值,而这个实用程序类方法是从控制器类的50多个方法中访问的。如果我必须从请求中获得会话,那么我需要更改所有这50个位

  • 我知道我可以获得包名并从完整的类名中去掉相应数量的字符,但我猜已经有人这么做了?

  • 我试图在Java不使用外部库或HttpURLConnection类的情况下通过SSL Socket进行快速HTTP GET,并注意到结果因使用的HTTP服务器类型而异。 以下是主要的Java代码: 对于TrustedTrustManager代码: 不知何故,我可以访问几个lighttpd托管的网页,但这并没有扩展到谷歌和许多其他类型的服务器。 成功查询lighttpd自己主页的一个示例: 如果您知

  • 在模型查询API不够用的情况下,你可以使用原始的sql语句。django提供两种方法使用原始sql进行查询:一种是使用Manager.raw()方法,进行原始查询并返回模型实例;另一种是完全避开模型层,直接执行自定义的sql语句。 警告 编写原始的sql语句时,应该格外小心。每次使用的时候,都要确保转义了参数中的任何控制字符,以防受到sql注入攻击。更多信息请参阅防止sql注入。 进行原始查询 r