trm42 / CacheDecorator by trm42

Magical (as in saves manual work quite a lot) Cache Decorator for Laravel 5. Designed for usage with repositories but easily usable for other uses. If there's enough interest, can be made framework agnostic.
239
4
1
Package Data
Maintainer Username: trm42
Maintainer Contact: matias.maki@gmail.com (Matias Mäki)
Package Create Date: 2015-10-04
Package Last Update: 2017-04-30
Language: PHP
License: GPL-2.0
Last Refreshed: 2024-11-22 03:05:50
Package Statistics
Total Downloads: 239
Monthly Downloads: 1
Daily Downloads: 0
Total Stars: 4
Total Watchers: 1
Total Forks: 1
Total Open Issues: 1

(Magical) Cache Decorator for Laravel Repositories

Repositories are really, really nice thing that solves real-world issues and follows the idea of DRY (Don't Repeat Yourself), but making similar classes for repository caching and repeating yourself over and over again for code like this:

namespace something\nice;

class CachedUserRepository {
	
	protected $repository;
	protected $cache;

	public function __construct(UserRepository $users, Cache $cache) {
		$this->repository = $users;
		$this->cache = $cache;
	}

	function all()
	{
		if (!$this->cache->has('all')) {
			$results = $this->repository->all();
			$this->cache->save('all', $results);
		} else {
			$results = $this->cache->get('all');
		}

		return $results;

	}

	function findByX($x)
	{
		$key = 'find-' . $x;
		if (!$this->cache->has($key)) {
			$results = $this->repository->findByX($x);
			$this->cache->save($key, $results);
		} else {
			$results = $this->cache->get($key);
		}

		return $results;
	}
}

And repeat this for every repository class in your project. Lots of dull repetition. Also, it doesn't help to make the caching code as part of your repository base class as it violates the single responsibility principle.

Cue (Magical) Cache Decorator which handles these things automatically for you with just few lines of class declaration:

namespace My\Repositories;

use Trm42\CacheDecorator\CacheDecorator;

class CachedUserRepository extends CacheDecorator {
	
	protected $ttl = 5; // cache ttl in minutes
	protected $prefix_key = 'users';
	protected $excludes = ['all']; // these methods are not cached

	public function repository()
	{
		return UserRepository::class;
	}

}

Aand you're set! The Cache Decorator caches every method call not in the $excludes array.

Please note this the current version doesn't support objects as part of the method call. It will be added to v1.0.0.

If you need something really special handling for some methods you can always override them in the Cached Repository class like this (simple example):

public function findByX($x)
{

	$key = $this->generateCacheKey(__FUNCTION__, compact($x));

	$res = $this->getCache($key);

	if (!$res) {
		$results = $this->repository->findX($x);
		
		$this->putCache($key, $results);
	}

	return $res;

}

If you happen to use a cache driver that enables you to use cache tags, you can clear the cache automatically when the data changes:

// Additional properties to add to the earlier example
// with class decoration
protected $tag_cleaners = ['create'];
protected $tags = ['users'];

Aaand you're set!

Install

Install with composer:

composer require trm42/cache-decorator

Copy the default configuration:

cp vendor/trm42/cache-decorator/config/repository_cache.php ./config/

Tested with Laravel 5.1 and 5.2.