Rasmus Vind
Well-known member
I wrote a neat little function that allows you to fetch from a finder, but only if it is not cached.
It could be rewritten to extend the
I use it to cache results for widgets:
I feel like this could be integrated into XenForo with a
@Kier, @Mike, what do you think?
PHP:
class Util
{
public static function cachedFinderFetch(\XF\Mvc\Entity\Finder $finder, $cacheKey, $lifeTime = 0)
{
$app = \XF::app();
$em = $app->em();
$cache = $app->cache();
if (!$cache || !$cache->contains($cacheKey)) {
$hydrationMap = $finder->getHydrationMap();
$results = $app->db()->query($finder->getQuery());
$rawItems = [];
while ($row = $results->fetchAliasGrouped()) {
$rawItems[] = $row;
}
if ($cache) {
$cacheData = ['items' => $rawItems, 'hydrationMap' => $hydrationMap];
$cache->save($cacheKey, $cacheData, $lifeTime);
}
} else {
$cacheData = $cache->fetch($cacheKey);
$rawItems = $cacheData['items'];
$hydrationMap = $cacheData['hydrationMap'];
}
$items = array_map(function (array $item) use ($em, $hydrationMap) {
return $em->hydrateFromGrouped($item, $hydrationMap);
}, $rawItems);
return $em->getBasicCollection($items);
}
}
It could be rewritten to extend the
\XF\Mvc\Entity\Finder
but this is the one I use.I use it to cache results for widgets:
PHP:
$widgetKey = $this->widgetConfig->widgetKey;
$cacheKey = "widget_cache_{$widgetKey}";
$finder = $this->finder('VindIT\Repository:Bundle')
->with(['PrimaryImage', 'PrimaryImage.ImageData'])
->where('Thread.node_id', $this->options['node_id'])
->where('Thread.discussion_state', 'visible')
->where('Thread.discussion_type', '')
->where('review_state', ['pending', 'approved', 'awaiting_update'])
->order('post_date', 'DESC')
->limit($bundlesPerPanel * $panelCount);
$bundles = \VindIT\Repository\Util::cachedFinderFetch($finder, $cacheKey, 600);
I feel like this could be integrated into XenForo with a
Finder::fetchCached($lifeTime)
method or something to simplify the caching workflow.@Kier, @Mike, what do you think?