查询不同语言的实体

Query an entity in a different Language

我正在尝试使用系统默认语言以外的一种语言查询实体,我的存储库方法如下所示,

public function findOneByMaterialnumber( $materialnumber, $sysLanguageUid ){
    $query = $this->createQuery();
    $query->matching($query->like('materialnumber',$materialnumber));

    $query->getQuerySettings()->setIgnoreEnableFields(true);
    $query->getQuerySettings()->setRespectStoragePage(false);

    $query->getQuerySettings()->setLanguageUid($sysLanguageUid);
    //$query->getQuerySettings()->setRespectSysLanguage(false);
    //$query->getQuerySettings()->setLanguageMode('strict');
    //$query->getQuerySettings()->setLanguageOverlayMode(false);

$parser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser');  
$queryParts = $parser->parseQuery($query); 
//\TYPO3\CMS\Core\Utility\DebugUtility::debug($queryParts, 'Query');
print_r($queryParts);
exit;

    return $query->execute()->getFirst();
}


但是这个结果的查询仍然以非严格的方式包含 sys_language_uid 。调试后的查询对象如下所示。

[keywords] => Array
    (
    )

[tables] => Array
    (
        [tx_productfinder_domain_model_product] => tx_productfinder_domain_model_product
    )

[unions] => Array
    (
    )

[fields] => Array
    (
        [tx_productfinder_domain_model_product] => tx_productfinder_domain_model_product.*
    )

[where] => Array
    (
        [0] => tx_productfinder_domain_model_product.materialnumber LIKE :
    )

[additionalWhereClause] => Array
    (
        [0] => (tx_productfinder_domain_model_product.sys_language_uid IN (0,-1))
    )

[orderings] => Array
    (
        [0] => tx_productfinder_domain_model_product.ordercode ASC
        [1] => tx_productfinder_domain_model_product.title ASC
        [2] => tx_productfinder_domain_model_product.materialnumber ASC
    )

[limit] => 
[offset] => 
[tableAliasMap] => Array
    (
        [tx_productfinder_domain_model_product] => tx_productfinder_domain_model_product
    )


无论我查询的 sys_language_uid 是什么,都会发生这种情况。我究竟做错了什么?

如您所见,我尝试了各种 QuerySettings、setRespectSysLanguage、setLanguageMode 和 setLanguageOverlayMode 的组合。据我了解,我必须严格查询并且没有语言覆盖。但是 none 的那些,或者它们的组合,都按预期工作。

edit. 我在这里发布的答案原来也不起作用。我最终做的是编写自定义语句,将其执行到 return 原始数据并通过 DataMapper->map(); 映射它。详情请参考 Christop Hofmanns 的回答。

这适用于 TYPO3 8。7.xx

use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper;

/**
 * The repository for Products
 */
class ProductRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
{

/*
 * @param int $uid id of record
 * @param int $langUid sys_language_uid of the record
 * @return \ITSHofmann\ItsProductfile\Domain\Mpdell\Product
 */
public function findByUidAndLanguageUid($uid,$langUid)
{
    $query = $this->createQuery();
    $object = $query->matching(
        $query->equals('uid', $uid)
        )->execute()->getFirst();
    if ($object) {
        $className =  get_class ($object);
        $dataMapper = $this->objectManager->get(DataMapper::class);
        $tableName = $dataMapper->getDataMap($className)->getTableName();
        $transOrigPointerField = $GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField'];
        $languageField   = $GLOBALS['TCA'][$tableName]['ctrl']['languageField'];
        $connection = GeneralUtility::makeInstance(ConnectionPool::class);
        $queryBuilder = $connection->getQueryBuilderForTable($tableName );
        $statement = $queryBuilder->select('*')
            ->from($tableName )
            ->where(
                $queryBuilder->expr()->eq(
                    $transOrigPointerField,$queryBuilder->createNamedParameter($object->getUid(), \PDO::PARAM_INT)),
                $queryBuilder->expr()->eq(
                    $languageField,$queryBuilder->createNamedParameter($langUid, \PDO::PARAM_INT))
            )->execute();
        $objectRow = $statement ->fetch();
        if ($objectRow) {
            $langObject = $dataMapper->map($className,[$objectRow]);
            if ($langObject ) {
                return reset ($langObject );
            }
        }
    }
    return $object;
}
}