Skip to content

Instantly share code, notes, and snippets.

@muratsplat
Created July 13, 2015 18:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save muratsplat/a3ffb25135fa1d41afa6 to your computer and use it in GitHub Desktop.
Save muratsplat/a3ffb25135fa1d41afa6 to your computer and use it in GitHub Desktop.
FileBindingOnModel Repository Class For Laravel
<?php namespace Muratsplat\Repository;
use Muratsplat\Repository\IFileRepository;
use Illuminate\Database\DatabaseManager;
use Illuminate\Support\Collection;
use Illuminate\Cache\Repository as Cache;
use Illuminate\Config\Repository as Config;
use Illuminate\Events\Dispatcher;
use RuntimeException;
use Exception;
/**
* File Repository for all models
*
* This repository can bind file paths on every model.
*
* @author Murat Ödünç <murat.asya@gmail.com>
* @copyright (c) 2015, Murat Ödünç
* @license http://www.gnu.org/licenses/gpl-3.0.html GPLv3
* @package Repository
*/
class FileRepository implements IFileRepository {
/**
* @var \Illuminate\Database\Connection
*/
private $connection;
/**
* @var \Illuminate\Database\Query\Builder
*/
private $builder;
/**
* Remember Time for caching database
*
* @var int duration is minutes
*/
private $rememberTime;
/**
* @var \Illuminate\Cache\Repository
*/
private $cache;
/**
*
* @var \Illuminate\Config\Repository
*/
private $config;
/**
* Table Name
*
* @var string
*/
private $table = 'file_paths';
/** The event dispatcher instance.
*
* @var \Illuminate\Events\Dispatcher
*/
protected static $distpatcher;
/**
* Create a new file Repository instance.
*
* @param \Illuminate\Database\DatabaseManager $db
* @param \Illuminate\Cache\Repository $cache
* @param \Illuminate\Config\Repository $config
*/
public function __construct(DatabaseManager $db, Cache $cache, Config $config) {
$this->connection = $db->connection();
$this->builder = $this->connection->table($this->getTableName());
$this->cache = $cache;
$this->config = $config;
$this->rememberTime = $this->config->get('app.cachedDuration');
static::boot();
}
/**
* to get all images in a file collection object
*
* @return Illuminate\Support\Collection;
*/
public function all() {
list($key, $time) = $this->getCachingParameters();
$results = $this->cache->remember($key, $time, function() {
return $this->builder->get();
});
return new Collection($results);
}
/**
* to get row by model
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return \Illuminate\Database\Eloquent\Collection
* @throws Exception
*/
public function getByModel($model) {
$key = $this->makeHashToModel($model);
return $this->find($key);
}
/**
* To find items by given key
*
* @param string $key
* @return \Illuminate\Database\Eloquent\Collection
*/
protected function find($key) {
return $this->all()->filter(function($item) use($key) {
if ($item->hash_id === $key) {
return true;
}
});
}
/**
* To create model
*
* @param \Illuminate\Database\Eloquent\Model
* @param array $filePaths
* @return bool
*/
public function create($model, array $filePaths = array()) {
$key = $this->makeHashToModel($model);
if (is_null($key)) { return false; }
return $this->insert($key, $filePaths);
}
/**
* To insert file paths to database
*
* @param string $key
* @param array $filePaths
* @return bool
*/
protected function insert($key, array $filePaths = array()) {
$results = [];
foreach ($filePaths as $v) {
$results[] = $this->insertOne($key, $v);
}
// it takes changes in db, so we should delete it's records on the cache
$this->fireOnAnyChanges();
return empty($filePaths) ? true : !in_array(false, $results);
}
/**
* To insert a path
*
* @param string $key
* @param string $path
* @return bool
*/
private function insertOne($key, $path) {
// it takes changes in db, so we should delete it's records on the cache
$this->fireOnAnyChanges();
return $this->builder->insert(['hash_id' => $key, 'path' => $path]);
}
/**
* To update files
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param array $filePaths
* @return boolean
*/
public function update($model, array $filePaths = array()) {
// delete all records of given model
$this->delete($model);
return $this->create($model, $filePaths);
}
/**
* to delete all file paths
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return bool
*/
public function delete($model){
$key = $this->makeHashToModel($model);
$this->builder->where('hash_id', $key)->delete();
$this->fireOnAnyChanges();
return $this->getByModel($model)->isEmpty();
}
/**
* Getter for remember time
*
* @return int
*/
protected function getRememberTime() {
$time = $this->rememberTime;
return is_null($time) ? 5 : $time;
}
/**
* To get hashed table name to store the table on cache driver
*
* @return string
*/
protected function getCachingKey() {
$name = $this->getTableName();
return md5($name);
}
/**
* To get table name
*
* @return string table name on db
* @throws RuntimeException
*/
protected function getTableName() {
$name = $this->table;
if (is_null($name) || trim($name) === '') {
throw new RuntimeException('Table name is not valid!');
}
return $name;
}
/**
* To get caching parameter
*
* @return array first one is key, other one is time
*/
protected function getCachingParameters() {
$key = $this->getCachingKey();
$time = $this->getRememberTime();
return [$key, $time];
}
/**
* To make hash given model class with id
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return string
* @throws Exception
*/
protected function makeHashToModel($model) {
if (is_object($model) && is_subclass_of($model, 'Illuminate\Database\Eloquent\Model')) {
$class = get_class($model);
$id = $model->id;
return md5($class . $id);
}
throw new Exception('Given parameter does not instance of Eloquent!');
}
/**
* To forget cached table
*
* @return void
*/
public function forgetCachedFiles() {
list($key, $time) = $this->getCachingParameters();
$this->cache->forget($key);
}
/**
* To fire event for changes tables
*
* @return mixed
*/
protected function fireOnAnyChanges() {
if ( ! isset(static::$distpatcher)) { return true; }
$event = "fileRepository.onChanges";
return static::$distpatcher->fire($event, $this);
}
/**
* To add listener to forget key on cache driver
* @return void
*/
protected static function boot() {
static::$distpatcher->listen('fileRepository.onChanges', function(FileRepository $object) {
$object->forgetCachedFiles();
});
}
/**
* Set the event dispatcher instance.
*
* Note: This method was copied from Laravel Eloquent's Model class!!!
*
* @param \Illuminate\Events\Dispatcher $dispatcher
* @return void
*/
public static function setEventDispatcher(Dispatcher $dispatcher) {
static::$distpatcher = $dispatcher;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment