以不同语言查询实体

时间:2017-10-30 13:03:42

标签: typo3 extbase

我正在尝试使用某种语言查询entietes,而不是系统默认语言,我的存储库方法看起来像这样,

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 i查询是什么,都会发生这种情况。我究竟做错了什么?

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

2 个答案:

答案 0 :(得分:1)

这与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;
}
}

答案 1 :(得分:0)

作为一个肮脏的修复,我通过将sys_language_uid作为约束来帮助自己。有更好的解决方案吗?

public function findOneByMaterialnumber( $materialnumber, $sysLanguageUid=NULL ){
    $query = $this->createQuery();
    $query->getQuerySettings()->setIgnoreEnableFields(true);
    $query->getQuerySettings()->setRespectStoragePage(false);

    // Wenn eine bestimmte Sprache abgefragt wurde, 
    if(!is_null($sysLanguageUid)){
        $query->getQuerySettings()->setRespectSysLanguage(false);
        $query->matching(
            $query->logicalAnd(array(
                $query->like('materialnumber',$materialnumber),
                $query->equals('sys_language_uid',$sysLanguageUid)
            ))
        );
    } else {
        $query->matching($query->like('materialnumber',$materialnumber));
    }
    return $query->execute()->getFirst();
}

<击>

原来这不起作用。

我最终做的是写一个自定义语句,执行它以返回原始数据并映射它,通过DataMapper-&gt; map();