/**
* Returns a rendered view. If we find html behind the given cache
* it returns this directly. This is a couple os ms faster than `renderCached`
* since the template engine is never used when there's a valid cache.
*
* Example:
*
* return $this->renderFullCached('myCache', 'plugin1/default.tpl', function(){
* return array('items' => heavyDbQuery());
* });
*
* Note: The $data callable is only called if the cache needs to regenerate (when it has been
* invalidated or empty, or the view file changed).
*
* If the callable $data returns NULL, then this will return NULL, too, without entering
* the actual rendering process.
*
* You should use this method in your plugins instead of writing your own cache mechanism,
* because this method handles PageResponse merging. Means: If templates used in this
* $view are changing somehow the PageResponse ({{loadAsset('style.css')}} calls) then
* this information (diff to current PageResponse) is stored and restored when we found
* a html cache. The diff is beside the actual rendered HTML also stored in the cache
* to keep this possible.
*
* @param string $cacheKey
* @param string $view
* @param array|callable $data Pass the data as array or a data provider function.
* @param integer $lifeTime In seconds. Default is one hour/3600 seconds.
* @param bool $force Force to bypass the cache and always call $data. For debuggin purposes.
*
* @see method `render` to get more information.
*
* @return string
*/
public function renderFullCached($cacheKey, $view, $data = null, $lifeTime = null, $force = false)
{
$cache = $this->cacher->getDistributedCache($cacheKey);
$mTime = $this->getViewMTime($view);
if (!is_string($cache)) {
$cache = null;
} else {
$cache = @unserialize($cache);
}
if ($force || !$cache || !$cache['content'] || !is_array($cache) || $mTime != $cache['fileMTime']) {
$oldResponse = clone $this->pageStack->getPageResponse();
$data2 = $data;
if (is_callable($data)) {
$data2 = call_user_func($data, $view);
if (null === $data2) {
//the data callback returned NULL so this means
//we aren't the correct controller for this request
//or the request contains invalid input
return null;
}
}
$content = $this->templating->render($view, $data2);
$response = $this->pageStack->getPageResponse();
$diff = $oldResponse->diff($response);
$cache = array('content' => $content, 'fileMTime' => $mTime, 'responseDiff' => $diff);
$this->cacher->setDistributedCache($cacheKey, serialize($cache), $lifeTime ?: 3600);
} else {
if ($cache['responseDiff']) {
$this->pageStack->getPageResponse()->patch($cache['responseDiff']);
}
}
return $this->pageResponseFactory->createPluginResponse($cache['content']);
}