Skip to content

Commit

Permalink
[#13439] - Cache work on the main view
Browse files Browse the repository at this point in the history
  • Loading branch information
niden committed May 2, 2019
1 parent 16b3579 commit e8f3243
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 134 deletions.
116 changes: 37 additions & 79 deletions phalcon/Mvc/View.zep
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@

namespace Phalcon\Mvc;

use Phalcon\Cache\Adapter\AdapterInterface;
use Phalcon\DiInterface;
use Phalcon\Di\Injectable;
use Phalcon\Events\ManagerInterface;
use Phalcon\Helper\Arr;
use Phalcon\Helper\Str;
use Phalcon\Mvc\View\Exception;
use Phalcon\Mvc\ViewInterface;
use Phalcon\Cache\BackendInterface;
use Phalcon\Events\ManagerInterface;
use Phalcon\Mvc\View\Engine\Php as PhpEngine;

/**
Expand Down Expand Up @@ -170,7 +171,7 @@ class View extends Injectable implements ViewInterface
*/
public function cache(var options = true) -> <View>
{
var viewOptions, cacheOptions, key, value, cacheLevel;
var viewOptions, cacheOptions, key, value;

if typeof options == "array" {
let viewOptions = this->options;
Expand All @@ -182,9 +183,7 @@ class View extends Injectable implements ViewInterface
/**
* Get the default cache options
*/
if !fetch cacheOptions, viewOptions["cache"] {
let cacheOptions = [];
}
let cacheOptions = Arr::get(viewOptions, "cache", []);

for key, value in options {
let cacheOptions[key] = value;
Expand All @@ -194,14 +193,9 @@ class View extends Injectable implements ViewInterface
* Check if the user has defined a default cache level or use
* self::LEVEL_MAIN_LAYOUT as default
*/
if fetch cacheLevel, cacheOptions["level"] {
let this->cacheLevel = cacheLevel;
} else {
let this->cacheLevel = self::LEVEL_MAIN_LAYOUT;
}

let viewOptions["cache"] = cacheOptions;
let this->options = viewOptions;
let this->cacheLevel = Arr::get(cacheOptions, "level", self::LEVEL_MAIN_LAYOUT),
viewOptions["cache"] = cacheOptions,
this->options = viewOptions;
} else {
/**
* If 'options' isn't an array we enable the cache with default
Expand Down Expand Up @@ -360,9 +354,9 @@ class View extends Injectable implements ViewInterface
/**
* Returns the cache instance used to cache
*/
public function getCache() -> <BackendInterface>
public function getCache() -> <AdapterInterface>
{
if !this->cache || typeof this->cache != "object" {
if !this->cache || typeof this->cache !== "object" {
let this->cache = this->createCache();
}

Expand Down Expand Up @@ -1200,7 +1194,7 @@ class View extends Injectable implements ViewInterface
/**
* Create a Phalcon\Cache based on the internal cache options
*/
protected function createCache() -> <BackendInterface>
protected function createCache() -> <AdapterInterface>
{
var container, cacheService, viewCache, viewOptions, cacheOptions;

Expand All @@ -1212,20 +1206,14 @@ class View extends Injectable implements ViewInterface
);
}

let cacheService = "viewCache";

let viewOptions = this->options;

if fetch cacheOptions, viewOptions["cache"] {
if isset cacheOptions["service"] {
let cacheService = cacheOptions["service"];
}
}
let viewOptions = this->options,
cacheOptions = Arr::get(viewOptions, "cache", []);

/**
* The injected service must be an object
*/
let viewCache = <BackendInterface> container->getShared(cacheService);
let cacheService = Arr::get(cacheOptions, "service" , "viewCache"),
viewCache = <AdapterInterface> container->getShared(cacheService);

if typeof viewCache != "object" {
throw new Exception("The injected caching service is invalid");
Expand All @@ -1237,19 +1225,28 @@ class View extends Injectable implements ViewInterface
/**
* Checks whether view exists on registered extensions and render it
*/
protected function engineRender(array engines, string viewPath, bool silence, bool mustClean, <BackendInterface> cache = null)
{
protected function engineRender(
array engines,
string viewPath,
bool silence,
bool mustClean,
<AdapterInterface> cache = null
) {
bool notExists;
int renderLevel, cacheLevel;
var key, lifetime, viewsDir, basePath, viewsDirPath, viewOptions,
cacheOptions, cachedView, viewParams, eventsManager, extension,
engine, viewEnginePath, viewEnginePaths;

let notExists = true,
basePath = this->basePath,
viewParams = this->viewParams,
eventsManager = <ManagerInterface> this->eventsManager,
viewEnginePaths = [];
let notExists = true,
basePath = this->basePath,
viewParams = this->viewParams,
eventsManager = <ManagerInterface> this->eventsManager,
viewEnginePaths = [],
viewOptions = this->options,
cacheOptions = Arr::get(viewOptions, "cache", []),
key = Arr::get(cacheOptions, "key", md5(viewPath)),
lifetime = Arr::get(cacheOptions, "lifetime", 3600);

for viewsDir in this->getViewsDirs() {
if !this->isAbsolutePath(viewPath) {
Expand All @@ -1260,53 +1257,14 @@ class View extends Injectable implements ViewInterface

if typeof cache == "object" {
let renderLevel = (int) this->renderLevel,
cacheLevel = (int) this->cacheLevel;
cacheLevel = (int) this->cacheLevel;

if renderLevel >= cacheLevel {
/**
* Check if the cache is started, the first time a cache is
* started we start the cache
*/
if !cache->isStarted() {
let key = null,
lifetime = null;

let viewOptions = this->options;

/**
* Check if the user has defined a different options to
* the default
*/
if fetch cacheOptions, viewOptions["cache"] {
if typeof cacheOptions == "array" {
fetch key, cacheOptions["key"];
fetch lifetime, cacheOptions["lifetime"];
}
}

/**
* If a cache key is not set we create one using a md5
*/
if key === null {
let key = md5(viewPath);
}

/**
* We start the cache using the key set
*/
let cachedView = cache->start(key, lifetime);

if cachedView !== null {
let this->content = cachedView;
return null;
}
}

/**
* This method only returns true if the cache has not
* expired
*/
if !cache->isFresh() {
let cachedView = cache->get(key);
if null !== cachedView {
let this->content = cachedView;
return;
} else {
return null;
}
}
Expand Down
5 changes: 3 additions & 2 deletions phalcon/Mvc/View/Simple.zep
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Phalcon\Mvc\View;

use Closure;
use Phalcon\Cache\Adapter\AdapterInterface;
use Phalcon\DiInterface;
use Phalcon\Di\Injectable;
use Phalcon\Helper\Arr;
use Phalcon\Helper\Str;
Expand Down Expand Up @@ -446,7 +447,7 @@ class Simple extends Injectable implements ViewBaseInterface
{
var container, cacheService, cacheOptions, viewCache;

let container = this->container;
let container = <DiInterface> this->container;

if typeof container != "object" {
throw new Exception(
Expand All @@ -456,7 +457,7 @@ class Simple extends Injectable implements ViewBaseInterface

let cacheOptions = this->cacheOptions;

if typeof cacheOptions == "array" {
if typeof cacheOptions !== "array" {
let cacheOptions = [];
}

Expand Down
4 changes: 2 additions & 2 deletions phalcon/Mvc/ViewBaseInterface.zep
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace Phalcon\Mvc;

use Phalcon\Cache\BackendInterface;
use Phalcon\Cache\Adapter\AdapterInterface;

/**
* Phalcon\Mvc\ViewInterface
Expand All @@ -27,7 +27,7 @@ interface ViewBaseInterface
/**
* Returns the cache instance used to cache
*/
public function getCache() -> <BackendInterface>;
public function getCache() -> <AdapterInterface>;

/**
* Returns cached output from another view stage
Expand Down
23 changes: 22 additions & 1 deletion tests/integration/Mvc/View/GetCacheCest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,24 @@

namespace Phalcon\Test\Integration\Mvc\View;

use function dataDir;
use IntegrationTester;
use Phalcon\Storage\Adapter\Stream;
use Phalcon\Test\Fixtures\Traits\DiTrait;

/**
* Class GetCacheCest
*/
class GetCacheCest
{
use DiTrait;

public function _before(IntegrationTester $I)
{
$this->setNewFactoryDefault();
$this->setDiView();
}

/**
* Tests Phalcon\Mvc\View :: getCache()
*
Expand All @@ -30,6 +41,16 @@ class GetCacheCest
public function mvcViewGetCache(IntegrationTester $I)
{
$I->wantToTest('Mvc\View - getCache()');
$I->skipTest('Need implementation');

$view = $this->container->get('view');
$view->setViewsDir(dataDir('fixtures/views/'));

$cache = $this->getAndSetViewCacheStream();
$I->assertInstanceOf(Stream::class, $cache);

$I->assertEquals($view, $view->cache(['key' => 'view_simple_cache']));

$cache = $view->getCache();
$I->assertInstanceOf(Stream::class, $cache);
}
}
50 changes: 0 additions & 50 deletions tests/integration/Mvc/View/SimpleCest.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,56 +237,6 @@ public function testSetVars(IntegrationTester $I)
$I->assertEquals($another_var, $view->getVar('another_var'));
}

public function testRenderWithCache(IntegrationTester $I)
{
$I->wantToTest('Render by using simple view with cache');

if (PHP_MAJOR_VERSION == 7) {
$I->skipTest(
'Skipped in view of the experimental support for PHP 7.'
);
}

// Create cache at first run
$view = new Simple();
codecept_debug(gettype($view->getParamsToView()));
$view->setViewsDir(dataDir('fixtures/views/'));

// No cache before DI is set
$I->assertFalse($view->getCache());

$view->setDI($this->getDi());
$I->assertEquals($view, $view->cache(['key' => 'view_simple_cache']));

$cache = $view->getCache();
$I->assertInstanceOf('Phalcon\Cache\BackendInterface', $cache);

$timeNow = time();
$view->setParamToView('a_cool_var', $timeNow);

$I->assertEquals("<p>$timeNow</p>", rtrim($view->render('test3/coolVar')));

$I->amInPath(cacheDir());
$I->seeFileFound('view_simple_cache');
$I->seeInThisFile("<p>$timeNow</p>");

unset($view, $cache);

// Re-use the cached contents
$view = new Simple;
$view->setViewsDir(dataDir('fixtures/views/'));
$view->setDI($this->getDi());
$view->cache(['key' => 'view_simple_cache']);

$I->assertEmpty($view->getContent());
$I->assertEquals("<p>$timeNow</p>", rtrim($view->render('test3/coolVar')));

$I->assertNotEmpty($view->getContent());
$I->assertEquals("<p></p>", rtrim($view->render('test3/coolVar')));

$I->safeDeleteFile('view_simple_cache');
}

/**
* Setup viewCache service and DI
*
Expand Down

0 comments on commit e8f3243

Please sign in to comment.