简体   繁体   English

Symfony 2.3 Gedmo学说扩展可翻译缓存

[英]Symfony 2.3 Gedmo doctrine extensions translatable caching

I'm using Gedmo Doctrine extensions 我正在使用Gedmo Doctrine扩展
All works well so far, except for translations caching. 到目前为止,所有工作都很顺利,除了翻译缓存。

$entity = $repository
            ->findByIdFullData($id)
            ->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker')
            ->useResultCache(true, $cache_time, $cache_name)
            ->getOneOrNullResult();

findByIdFullData() returns \\Doctrine\\ORM\\Query findByIdFullData()返回\\Doctrine\\ORM\\Query
But the translations aren't cached. 但翻译没有缓存。 In profiler I see queries like that: 在分析器中,我看到这样的查询:

SELECT 
  e0_.content AS content0, 
  e0_.field AS field1 
FROM 
  ext_translations e0_ 
WHERE 
  e0_.foreign_key = ? 
  AND e0_.locale = ? 
  AND e0_.object_class = ?

And all the queries in profiler are to get results from ext_translations . 并且探查器中的所有查询都是从ext_translations获取结果。 How can I cache the result already with the translated strings? 如何使用已翻译的字符串缓存结果?

Tried using Array Hydration and memCache, but ended messing up more, because my result item has uploaded media file which can't be serialized or something. 尝试使用Array Hydration和memCache,但结果搞砸了更多,因为我的结果项已经上传了无法序列化的媒体文件或其他东西。 Anyway I would end up rewriting most of the code. 无论如何,我最终会重写大部分代码。

Any help is appreciated. 任何帮助表示赞赏。


Edit : 编辑

I've tried Karol Wojciechowski's answer and it solved part of the problem. 我尝试了Karol Wojciechowski的答案,它解决了部分问题。 It caches when I use getOneOrNullResult() but not with getResult() . 当我使用getOneOrNullResult()但不使用getResult()时它会缓存。 Here's some code. 这是一些代码。

In a service: 在服务中:

$query = $this->em
    ->getRepository('MainBundle:Channels')
    ->findActiveChannelsByGroupId($id);
$this->container->get('my.translations')->addTranslationWalkerToQuery($query, $this->request);

$channels = $query
    ->useResultCache(true, 900, '1__channels__active_by_group_1')
    ->getResult();

Channels repository: 渠道存储库:

public function findActiveChannelsByGroupId($group_id, $limit = null)
{
    $rs = $this
        ->createQueryBuilder('c')
        ->select('c', 'm')
        ->leftJoin('c.media', 'm')
        ->leftJoin('c.group', 'g')
        ->where('c.active = 1')
        ->andWhere('g.id = :group_id')
        ->orderBy('c.sortOrder', 'asc')
        ->setParameter('group_id', $group_id)
        ->setMaxResults($limit);

    return $rs->getQuery();
}

If I change to findActiveChannelsByGroupId($id, 1) (notice limit param), it still doesn't cache, but then if I change to getOneOrNullResult() , query gets cached 如果我更改为findActiveChannelsByGroupId($id, 1) (通知限制参数),它仍然不缓存,但如果我更改为getOneOrNullResult() ,查询将被缓存

Our working code: 我们的工作代码:

    public function addTranslationWalkerToQuery($query, $request)
{
    $config = $this->container->get('doctrine')->getManager()->getConfiguration();
    if ($config->getCustomHydrationMode(TranslationWalker::HYDRATE_OBJECT_TRANSLATION) === null) {
        $config->addCustomHydrationMode(
            TranslationWalker::HYDRATE_OBJECT_TRANSLATION,
            'Gedmo\\Translatable\\Hydrator\\ORM\\ObjectHydrator'
        );
    }

    $query->setHint(
        \Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER,
        'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker'
    );
    $query->setHint(
        \Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE,
        $request->getLocale() // take locale from session or request etc.
    );
    $query->setHydrationMode(TranslationWalker::HYDRATE_OBJECT_TRANSLATION);
    $query->setHint(Query::HINT_REFRESH, true);
}

EDIT: And if you want to "getResult" 编辑:如果你想“getResult”

Performing getResult changes hydration mode. 执行getResult会改变水合模式。 Have look on AbstractQuery class method: 看看AbstractQuery类方法:

/**
     * Gets the list of results for the query.
     *
     * Alias for execute(null, $hydrationMode = HYDRATE_OBJECT).
     *
     * @param int $hydrationMode
     *
     * @return array
     */
    public function getResult($hydrationMode = self::HYDRATE_OBJECT)
    {
        return $this->execute(null, $hydrationMode);
    }

It works with getOneOrNullResult because it didn't changes hydration mode 它适用于getOneOrNullResult因为它没有改变水合模式

public function getOneOrNullResult($hydrationMode = null)

If you want to cache translatable queries you should change hydration mode during execution getResult method to TranslationWalker::HYDRATE_OBJECT_TRANSLATION . 如果要缓存可翻译查询,则应在执行getResult方法期间将水合模式更改为TranslationWalker::HYDRATE_OBJECT_TRANSLATION

Personally I'll wrap this method into service which will handle everything associated with translations. 我个人将这个方法包装成服务,它将处理与翻译相关的所有事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM