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


Symfony 2.3 Gedmo doctrine extensions translatable caching

我正在使用 Gedmo Doctrine 扩展
到目前为止,除了翻译缓存外,一切运行良好。

$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()返回'Doctrine'ORM'Query
但翻译不会被缓存。在探查器中,我看到这样的查询:

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

并且探查器中的所有查询都是从ext_translations获取结果。如何使用翻译后的字符串缓存结果?

尝试使用数组水合和 memCache,但最终搞砸了更多,因为我的结果项上传了无法序列化的媒体文件或其他东西。无论如何,我最终会重写大部分代码。

任何帮助,不胜感激。


编辑

我尝试过Karol Wojciechowski的答案,它解决了部分问题。当我使用 getOneOrNullResult() 但不使用 getResult() 时它会缓存。下面是一些代码。

在服务中:

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

频道存储库:

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

如果我更改为findActiveChannelsByGroupId($id, 1)(注意限制参数),它仍然不缓存,但是如果我更改为getOneOrNullResult(),查询将被缓存

我们的工作代码:

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

编辑:如果你想"得到结果"

执行 getResult 会更改水合模式。看看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);
    }

它适用于getOneOrNullResult,因为它没有改变水合模式

public function getOneOrNullResult($hydrationMode = null)

如果要缓存可翻译的查询,则应在执行期间将水合模式 getResult 方法更改为 TranslationWalker::HYDRATE_OBJECT_TRANSLATION

就个人而言,我将此方法包装到服务中,它将处理与翻译相关的所有内容。