Skip to content

Commit

Permalink
storing cache feature
Browse files Browse the repository at this point in the history
  • Loading branch information
hkp22 committed Sep 20, 2018
1 parent c0a249c commit f063970
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 2 deletions.
77 changes: 77 additions & 0 deletions src/CacheBladeDirective.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace Hkp22\CacheLaraViewFragments;

class CacheBladeDirective
{
/**
* The cache instance.
*
* @var FragmentCaching
*/
protected $cache;
/**
* A list of model cache keys.
*
* @param array $keys
*/
protected $keys = [];

/**
* Create a new instance.
*
* @param FragmentCaching $cache
*/
public function __construct(FragmentCaching $cache)
{
$this->cache = $cache;
}

/**
* Handle the @cache setup.
*
* @param mixed $model
* @param string|null $key
*/
public function setUp($model, $key = null)
{
ob_start();

$this->keys[] = $key = $this->normalizeKey($model, $key);

return $this->cache->has($key);
}

/**
* Handle the @endcache teardown.
*/
public function tearDown()
{
$html = ob_get_clean();

return $this->cache->put(array_pop($this->keys), $html);
}

/**
* Normalize the cache key.
*
* @param mixed $item
* @param string|null $key
*/
protected function normalizeKey($item, $key = null)
{
if (is_string($item) || is_string($key)) {
return is_string($item) ? $item : $key;
}

if (is_object($item) && method_exists($item, 'getCacheKey')) {
return $item->getCacheKey();
}

if ($item instanceof \Illuminate\Support\Collection) {
return md5($item);
}

throw new \Exception('Could not determine an appropriate cache key.');
}
}
11 changes: 9 additions & 2 deletions src/CacheLaraViewFragmentServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Hkp22\CacheLaraViewFragments;

use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;

class CacheLaraViewFragmentServiceProvider extends ServiceProvider
Expand All @@ -13,7 +14,13 @@ class CacheLaraViewFragmentServiceProvider extends ServiceProvider
*/
public function boot()
{
//
Blade::directive('cache', function ($expression) {
return "<?php if (! app('Hkp22\CacheLaraViewFragments\CacheBladeDirective')->setUp({$expression})) : ?>";
});

Blade::directive('endcache', function ($expression) {
return "<?php endif; echo app('Hkp22\CacheLaraViewFragments\CacheBladeDirective')->tearDown() ?>";
});
}

/**
Expand All @@ -23,6 +30,6 @@ public function boot()
*/
public function register()
{
//
$this->app->singleton(CacheBladeDirective::class);
}
}
120 changes: 120 additions & 0 deletions tests/CacheBladeDirectiveTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php

namespace Hkp22\Tests\CacheLaraViewFragments;

use Exception;
use Hkp22\CacheLaraViewFragments\CacheBladeDirective;
use Hkp22\CacheLaraViewFragments\FragmentCaching;
use Hkp22\Tests\CacheLaraViewFragments\Stubs\Models\UnCacheablePost;
use Illuminate\Cache\ArrayStore;
use Illuminate\Cache\Repository;

class CacheBladeDirectiveTest extends TestCase
{
protected $cache;

/** @test **/
public function it_can_cache_html_in_the_cache_directive()
{
$directive = $this->createNewCacheDirective();

$post = $this->makePost();

$isCached = $directive->setUp($post);

$this->assertFalse($isCached);

echo '<div>fragment</div>';

$cachedFragment = $directive->tearDown();

$this->assertEquals('<div>fragment</div>', $cachedFragment);

$this->assertTrue($this->cache->has($post));
}

/** @test */
public function it_can_use_a_string_as_the_cache_key()
{
$cache = $this->prophesize(FragmentCaching::class);

$directive = new CacheBladeDirective($cache->reveal());

$cache->has('foo')->shouldBeCalled();

$directive->setUp('foo');

ob_end_clean(); // Since we're not doing teardown.
}

/** @test */
public function it_can_use_a_collection_as_the_cache_key()
{
$cache = $this->prophesize(FragmentCaching::class);

$directive = new CacheBladeDirective($cache->reveal());

$collection = collect(['one', 'two']);

$cache->has(md5($collection))->shouldBeCalled();

$directive->setUp($collection);

ob_end_clean(); // Since we're not doing teardown.
}

/** @test */
public function it_can_use_the_model_to_determine_the_cache_key()
{
$cache = $this->prophesize(FragmentCaching::class);

$directive = new CacheBladeDirective($cache->reveal());

$post = $this->makePost();

$cache->has(get_class($post) . '/1-' . $post->updated_at->timestamp)->shouldBeCalled();

$directive->setUp($post);

ob_end_clean(); // Since we're not doing teardown.
}

/** @test */
public function it_can_use_a_string_to_override_the_models_cache_key()
{
$cache = $this->prophesize(FragmentCaching::class);

$directive = new CacheBladeDirective($cache->reveal());

$cache->has('override-key')->shouldBeCalled();

$directive->setUp($this->makePost(), 'override-key');

ob_end_clean(); // Since we're not doing teardown.
}

/** @test **/
public function it_throws_an_exception_if_it_cannot_determine_the_cache_key()
{
$this->expectException(Exception::class);

$directive = $this->createNewCacheDirective();

$unCacheablePost = new UnCacheablePost;
$unCacheablePost->title = 'Some title';
$unCacheablePost->save();

$directive->setUp($unCacheablePost);

ob_end_clean(); // Since we're not doing teardown.
}

protected function createNewCacheDirective()
{
$cacheStore = new Repository(new ArrayStore);

$this->cache = new FragmentCaching($cacheStore);

return new CacheBladeDirective($this->cache);
}
}
10 changes: 10 additions & 0 deletions tests/Stubs/Models/UnCacheablePost.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Hkp22\Tests\CacheLaraViewFragments\Stubs\Models;

use Illuminate\Database\Eloquent\Model;

class UnCacheablePost extends Model
{
protected $table = 'posts';
}

0 comments on commit f063970

Please sign in to comment.