Symfony 2.3 Gedmo 学说扩展可翻译缓存
我正在使用 Gedmo Doctrine 扩展
到目前为止,一切都运行良好,除了翻译缓存.
I'm using Gedmo Doctrine extensions
All works well so far, except for translations caching.
$entity = $repository
->findByIdFullData($id)
->setHint(DoctrineORMQuery::HINT_CUSTOM_OUTPUT_WALKER, 'Gedmo\Translatable\Query\TreeWalker\TranslationWalker')
->useResultCache(true, $cache_time, $cache_name)
->getOneOrNullResult();
findByIdFullData()
返回 DoctrineORMQuery
但是翻译不会被缓存.在探查器中,我看到这样的查询:
findByIdFullData()
returns DoctrineORMQuery
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 = ?
Profiler 中的所有查询都是从 ext_translations
获取结果.如何使用翻译后的字符串缓存结果?
And all the queries in profiler are to get results from ext_translations
. How can I cache the result already with the translated strings?
尝试使用 Array Hydration 和 memCache,但结果更加混乱,因为我的结果项上传了无法序列化的媒体文件或其他内容.无论如何,我最终会重写大部分代码.
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. Anyway I would end up rewriting most of the code.
感谢任何帮助.
编辑:
我尝试了 Karol Wojciechowski 的回答,它解决了部分问题.当我使用 getOneOrNullResult()
而不是 getResult()
时,它会缓存.这是一些代码.
I've tried Karol Wojciechowski's answer and it solved part of the problem. It caches when I use getOneOrNullResult()
but not with getResult()
. Here's some code.
在服务中:
$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()
, 查询被缓存
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
推荐答案
我们的工作代码:
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(
DoctrineORMQuery::HINT_CUSTOM_OUTPUT_WALKER,
'Gedmo\Translatable\Query\TreeWalker\TranslationWalker'
);
$query->setHint(
GedmoTranslatableTranslatableListener::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"
And if you want to "getResult"
执行 getResult 会更改水合模式.查看 AbstractQuery 类方法:
Performing getResult changes hydration mode. Have look on AbstractQuery class method:
/**
* 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
一起使用,因为它没有改变水合模式
It works with getOneOrNullResult
because it didn't changes hydration mode
public function getOneOrNullResult($hydrationMode = null)
如果您想缓存可翻译的查询,您应该在执行 getResult 方法期间将 hydration 模式更改为 TranslationWalker::HYDRATE_OBJECT_TRANSLATION
.
If you want to cache translatable queries you should change hydration mode during execution getResult method to TranslationWalker::HYDRATE_OBJECT_TRANSLATION
.
我个人会将此方法包装到服务中,该服务将处理与翻译相关的所有事情.
Personally I'll wrap this method into service which will handle everything associated with translations.
相关文章