├── composer.json ├── readme.md └── src ├── CacheServiceProvider.php ├── Command ├── FileCommand.php ├── Functions │ ├── MainFunction.php │ └── Traits │ │ └── SerializeHelpers.php ├── Interfaces │ └── CommandInterface.php └── RedisCommand.php ├── Console └── PublishConfig.php ├── Facades ├── CacheBuilder.php ├── CacheFile.php └── CacheRedis.php ├── Serializer ├── Abstracts │ └── Serializer.php ├── CollectSerializer.php ├── DefaultSerializer.php ├── Interfaces │ └── SerializerInterface.php └── ResponseSerializer.php ├── Services ├── Builder │ ├── CacheBuilderInterface.php │ ├── FileBuilder.php │ └── RedisBuilder.php └── CacheFactory.php └── config ├── cache.php └── database.php /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kosmosx/cache", 3 | "description": "Cache service for Laravel / Lumen Framework.", 4 | "keywords": ["framework", "laravel", "lumen", "cache", "redis"], 5 | "license": "MIT", 6 | "type": "lumen-package", 7 | "authors": [ 8 | { 9 | "name": "Fabrizio Cafolla", 10 | "email": "info@fabriziocafolla.com" 11 | } 12 | ], 13 | 14 | "require": { 15 | "php": ">=7.1.3", 16 | "laravel/lumen-framework": ">=5.7", 17 | "illuminate/redis": ">=5.7", 18 | "predis/predis": "^1.1", 19 | "kosmosx/helpers": "1.0.*" 20 | }, 21 | 22 | "autoload": { 23 | "psr-4": { 24 | "Kosmosx\\Cache\\": "src/" 25 | } 26 | }, 27 | 28 | "extra": { 29 | "branch-alias": { 30 | "dev-master": "1.0-dev" 31 | }, 32 | "laravel": { 33 | "providers": [ 34 | "Kosmosx\\Cache\\CacheServiceProvider" 35 | ], 36 | "aliases": { 37 | "CacheBuilder": "Kosmosx\\Cache\\Facades\\CacheBuilder", 38 | "CacheFile": "Kosmosx\\Cache\\Facades\\CacheFile", 39 | "CacheRedis": "Kosmosx\\Cache\\Facades\\CacheRedis" 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Cache System 2 | 3 | ![](https://img.shields.io/badge/version-1.0.0-green.svg) ![](https://img.shields.io/badge/laravel->=5.7-blue.svg) ![](https://img.shields.io/badge/lumen->=5.7-blue.svg) 4 | 5 | ##### Why use it? 6 | >Manage your cache easily. 7 | This package is useful for better managing the File or Redis cache. Implements the functions for creating and returning caches using json-encoded serialization to make the cache transportable and usable by other external microservices. 8 | 9 | 10 | ##### Install & Configuration 11 | 12 | composer require kosmosx/cache 13 | 14 | You must enter the following provider in the bootstrap/app.php file: 15 | Uncomment the function 16 | 17 | $app->withFacades(); 18 | 19 | Load configuration in boostrap file 20 | 21 | $this->configure('cache'); 22 | $this->configure('database'); 23 | Or publish config in your Service Provider 24 | 25 | $this->publishes([ 26 | 'Kosmosx/Cache/config/cache.php' => config_path('cache.php') 27 | ], 'config'); 28 | 29 | $this->publishes([ 30 | 'Kosmosx/Cache/config/database.php' => config_path('database.php') 31 | ], 'config'); 32 | 33 | Register service provider 34 | 35 | $app->register(Kosmosx\Cache\CacheServiceProvider::class); 36 | 37 | #### Documentation 38 | Once you have cofigured using it: 39 | 40 | $factory = app('factory.cache'); //return CacheFactory 41 | $builderFile = $factory->file(); //return FileBuilder 42 | $builderRedis = $factory->redis(); //return RedisBuilder 43 | 44 | $file = app('service.cache.file'); //FileCommand 45 | $redis = app('service.cache.redis'); //RedisCommand 46 | 47 | **SET** 48 | 49 | //If you use builder obj 50 | $builderRedis->default()->set($key, $value, $ttl); //build FileCommand with DefaultSerializer and set cache 51 | $builderRedis->response()->set($response, $value, $ttl); 52 | $builderRedis->collect()->set($collect, $value, $ttl); 53 | 54 | //With services 55 | $file->set($key, $value, $ttl); 56 | $redis->set($key, $value, $ttl); 57 | 58 | **SET MANY** 59 | 60 | //array example: ["key" => $value, "key2" => $value2 ...] 61 | //$ttl for all values 62 | 63 | $builderFile->default()->setMany(array $values, $ttl); 64 | 65 | $file->setMany(array $values, $ttl); 66 | $redis->setMany(array $values, $ttl); 67 | 68 | **GET** 69 | 70 | $file->get($key, $serializer); 71 | $redis->get($key, $serializer); 72 | 73 | **GET MANY** 74 | 75 | //array example: ["key", "key2", "keyN" ...] 76 | 77 | $file->getMany(array $keys); 78 | $redis->getMany(array $keys); 79 | 80 | **SERIALIZER** 81 | 82 | All data stored in cache (redis / file) are serialized with the json coding, so as to make them transportable by other languages. 83 | it is possible to use typed serializers, so that when it is recovered it is possible to reconstruct the initial object. 84 | 85 | //Serializer 86 | ResponseSerializer() //If you want cache Response object 87 | CollectSerializer() //If you want cache Collect object 88 | DefaultSerializer() //default cache 89 | 90 | ...->setSerializer(new ResponseSerializer()); 91 | 92 | **Own Serializer** 93 | 94 | If you want to create your own serializer, just create a class that extends SerializerAbstract 95 | 96 | use Kosmosx\Cache\Serializer\Abstracts\Serializer; 97 | use Kosmosx\Cache\Serializer\Interfaces\SerializerInterface; 98 | 99 | class {name} extends Serializer implements SerializerInterface 100 | 101 | **Other function** 102 | 103 | //Use class cache manager 104 | ...->manager() //return istance of Illuminate/Redis or CacheManager 105 | 106 | ...->forget(string $keys) 107 | ...->forgetMany(array $keys) 108 | 109 | ...->setAutodetect($bool) 110 | ...->getAutodetect() 111 | 112 | ...->clear() 113 | 114 | -------------------------------------------------------------------------------- /src/CacheServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->alias('cache', \Illuminate\Cache\CacheManager::class); 38 | 39 | $this->app->register('Illuminate\Redis\RedisServiceProvider'); 40 | 41 | try { 42 | $this->app->configure('cache'); 43 | $this->app->configure('database'); 44 | } catch (\Exception $e) { 45 | 46 | } 47 | 48 | $this->app->bind('factory.cache', function ($app) { 49 | return new CacheFactory(); 50 | }); 51 | 52 | $this->app->bind('service.cache.file', function ($app) { 53 | return new FileCommand(new DefaultSerializer()); 54 | }); 55 | 56 | $this->app->bind('service.cache.redis', function ($app) { 57 | return new RedisCommand(new DefaultSerializer()); 58 | }); 59 | 60 | $this->commands(\Kosmosx\Cache\Console\PublishConfig::class); 61 | } 62 | 63 | /** 64 | * Get the services provided by the provider. 65 | * 66 | * @return array 67 | */ 68 | public function provides() 69 | { 70 | return ['service.cache.builder', 'service.cache.file', 'service.cache.redis']; 71 | } 72 | } -------------------------------------------------------------------------------- /src/Command/FileCommand.php: -------------------------------------------------------------------------------- 1 | $data) 23 | $this->set($key, $data, $minutes); 24 | 25 | return $this; 26 | } 27 | 28 | public function set(string $key, $data, int $minutes = 0) 29 | { 30 | $rawData = $this->_serializeData($data); 31 | 32 | $minutes <= 0 ? $this->manager->forever($key, $rawData) : $this->manager->put($key, $rawData, $minutes); 33 | 34 | return $this; 35 | } 36 | 37 | public function getMany(array $keys, ?SerializerInterface $serializer = null): array 38 | { 39 | $data = array(); 40 | foreach ($keys as $key) 41 | $data[$key] = $this->get($key, $serializer); 42 | return $data; 43 | } 44 | 45 | public function get($key, ?SerializerInterface $serializer = null) 46 | { 47 | $rawData = $this->manager->get($key); 48 | return $this->_unserializeData($rawData, $serializer); 49 | } 50 | 51 | public function forgetMany($keys, ...$otherKeys): array 52 | { 53 | $forgets = array(); 54 | 55 | if (!is_array($keys)) 56 | $forgets = (array)$keys; 57 | 58 | if (!empty($otherKeys)) 59 | $forgets = array_unique(array_merge($forgets, $otherKeys)); 60 | 61 | unset($keys, $otherKeys); 62 | 63 | $checks = array(); 64 | 65 | foreach ($forgets as $index => $key) 66 | if (is_string($key) && !array_key_exists($key, $checks)) 67 | $checks[$key] = $this->manager->forget($key); 68 | 69 | return $checks; 70 | } 71 | 72 | /** 73 | * @param string $key 74 | * @return bool 75 | */ 76 | public function forget(string $key): bool 77 | { 78 | return $this->manager->forget($key); 79 | } 80 | 81 | /** 82 | * @return FileCommand 83 | */ 84 | public function clear(): self 85 | { 86 | $this->manager->flush(); 87 | return $this; 88 | } 89 | } -------------------------------------------------------------------------------- /src/Command/Functions/MainFunction.php: -------------------------------------------------------------------------------- 1 | manager = $service; 40 | $this->setSerializer($serializer); 41 | } 42 | 43 | /** 44 | * Return class manager 45 | * 46 | * @return \Laravel\Lumen\Application|mixed 47 | */ 48 | public function manager(): object 49 | { 50 | return $this->manager; 51 | } 52 | } -------------------------------------------------------------------------------- /src/Command/Functions/Traits/SerializeHelpers.php: -------------------------------------------------------------------------------- 1 | autodetect = $autodetect; 22 | return $this; 23 | } 24 | 25 | public function getAutodetect() 26 | { 27 | return $this->autodetect; 28 | } 29 | 30 | /** Function in beta 31 | * 32 | * @return null|string 33 | * protected function _createdAt(): ?string 34 | * { 35 | * $arg = $this->serializer->getArgs('created_at'); 36 | * 37 | * if (array_key_exists('created_ad', $arg)) 38 | * return $arg['created_at']; 39 | * 40 | * return null; 41 | * } 42 | * 43 | * @param $rawData 44 | * @param SerializerInterface|null $serializer 45 | * @return mixed 46 | */ 47 | protected function _unserializeData($rawData, ?SerializerInterface $serializer = null) 48 | { 49 | if ($serializer instanceof SerializerInterface) 50 | $this->setSerializer($serializer, $rawData); 51 | elseif (true === $this->autodetect) 52 | $this->setSerializerAutodetect($rawData); 53 | else 54 | $this->serializer->setRawData($rawData); 55 | 56 | return $this->serializer->get(); 57 | } 58 | 59 | /** 60 | * @param $data 61 | * 62 | * @return mixed 63 | */ 64 | protected function _serializeData($data): ?string 65 | { 66 | $rawData = $this->serializer->make($data); 67 | return $rawData; 68 | } 69 | 70 | /** 71 | * autodetect serializer from cached data 72 | * 73 | * @param null $rawData 74 | */ 75 | public function setSerializerAutodetect($rawData = null): void 76 | { 77 | $args = $this->serializer->getArgs('serializer'); 78 | 79 | if (array_key_exists('serializer', $args) && $args['serializer'] !== get_class($this->serializer)){ 80 | try { 81 | if((new $args['serializer']) instanceof SerializerInterface) 82 | $this->serializer = new $args['serializer']($rawData); 83 | } catch (\Exception $e) { 84 | throw new $e; 85 | } 86 | } 87 | } 88 | 89 | /** 90 | * Private function to _set Serializer 91 | * 92 | * @param SerializerInterface $serializer 93 | * @param null $rawData 94 | * @return SerializeHelpers 95 | */ 96 | public function setSerializer(SerializerInterface $serializer, $rawData = null): self 97 | { 98 | $this->serializer = $serializer; 99 | 100 | if (null != $rawData) 101 | $this->serializer->setRawData($rawData); 102 | 103 | return $this; 104 | } 105 | } -------------------------------------------------------------------------------- /src/Command/Interfaces/CommandInterface.php: -------------------------------------------------------------------------------- 1 | $value, 'key2' => $value2] 22 | * 23 | * @param array $values 24 | * @param int $minutes 25 | */ 26 | public function setMany(array $values, int $minutes = 0) 27 | { 28 | foreach ($values as $key => $data) 29 | $this->set($key, $data, $minutes); 30 | 31 | return $this; 32 | } 33 | 34 | /** 35 | * Cache creation through serialization in json coding. 36 | * If you want to cache response you pass the $data parameter as a Response instance 37 | * 38 | * @param string $key 39 | * @param $data 40 | * @param int $minutes 41 | * @return mixed 42 | */ 43 | public function set(string $key, $data, int $minutes = 0) 44 | { 45 | $rawData = $this->_serializeData($data); 46 | 47 | $this->manager->set($key, $rawData, $minutes); 48 | 49 | return $this; 50 | } 51 | 52 | /** 53 | * Method for taking multiple keys together, returns an associative array 54 | * Example ['key' => 'value'] 55 | * 56 | * @param array $keys 57 | * @return mixed 58 | */ 59 | public function getMany(array $keys, ?SerializerInterface $serializer = null): array 60 | { 61 | $data = array(); 62 | foreach ($keys as $key) 63 | $data[$key] = $this->get($key, $serializer); 64 | return $data; 65 | } 66 | 67 | /** 68 | * Method to recover the cache from file or redis 69 | * 70 | * @param $key 71 | * @return $this|string|Response 72 | */ 73 | public function get($key, ?SerializerInterface $serializer = null) 74 | { 75 | $rawData = $this->manager->get($key); 76 | return $this->_unserializeData($rawData, $serializer); 77 | } 78 | 79 | /** 80 | * Example use: 81 | * forget('key2'); // return 1 82 | * forget(['key3', 'key4']); // return 2 83 | * 84 | * @param string $key 85 | * @return bool 86 | */ 87 | public function forget($key, ...$otersKey) 88 | { 89 | return $this->manager->del($key, ...$otersKey); 90 | } 91 | 92 | /** 93 | * Delete all file cache 94 | */ 95 | public function clear() 96 | { 97 | $this->manager->flushDB(); 98 | } 99 | } -------------------------------------------------------------------------------- /src/Console/PublishConfig.php: -------------------------------------------------------------------------------- 1 | destination) 33 | * 34 | * @var array 35 | */ 36 | protected $fileMap = []; 37 | 38 | public function __construct(Filesystem $files) 39 | { 40 | parent::__construct(); 41 | $this->files = $files; 42 | 43 | $fromPath = str_replace('Console/Commands','config',__DIR__); 44 | 45 | $this->fileMap = [ 46 | $fromPath.'/cache.php' => app()->basePath('config/cache.php'), 47 | $fromPath.'/database.php' => app()->basePath('config/database.php'), 48 | ]; 49 | } 50 | 51 | /** 52 | * Execute the console command. 53 | * 54 | * @return mixed 55 | */ 56 | public function handle() 57 | { 58 | foreach ($this->fileMap as $from => $to) { 59 | if ($this->files->exists($to) && !$this->option('force')) { 60 | continue; 61 | } 62 | $this->createParentDirectory(dirname($to)); 63 | $this->files->copy($from, $to); 64 | $this->status($from, $to, 'File'); 65 | } 66 | } 67 | 68 | /** 69 | * Create the directory to house the published files if needed. 70 | * 71 | * @param string $directory 72 | * @return void 73 | */ 74 | protected function createParentDirectory($directory) 75 | { 76 | if (!$this->files->isDirectory($directory)) { 77 | $this->files->makeDirectory($directory, 0755, true); 78 | } 79 | } 80 | 81 | /** 82 | * Write a status message to the console. 83 | * 84 | * @param string $from 85 | * @param string $to 86 | * @return void 87 | */ 88 | protected function status($from, $to) 89 | { 90 | $from = str_replace(base_path(), '', realpath($from)); 91 | $to = str_replace(base_path(), '', realpath($to)); 92 | $this->line("Copied File [{$from}] To [{$to}]"); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/Facades/CacheBuilder.php: -------------------------------------------------------------------------------- 1 | rawData = $rawData; 23 | } 24 | 25 | /** 26 | * @param null $args 27 | * @return array 28 | * @throws \Exception 29 | */ 30 | public function getArgs($args = null): array 31 | { 32 | $args = $this->_unserialize($args); 33 | 34 | return $args; 35 | } 36 | 37 | /** 38 | * @param null $rawData 39 | * @throws \Exception 40 | */ 41 | public function setRawData($rawData = null): void 42 | { 43 | if (is_string($rawData)) { 44 | json_decode($rawData); 45 | 46 | if (0 !== json_last_error()) 47 | throw new \Exception("Serialized Data error json: " . json_last_error_msg()); 48 | } else { 49 | $rawData = json_encode(array("serializer" => "", "data" => [], "created_at" => ""), JSON_FORCE_OBJECT); 50 | } 51 | 52 | $this->rawData = $rawData; 53 | } 54 | 55 | /** 56 | * Unserialize cache and return array with Serializer and $data 57 | * 58 | * @param null|array|string $only 59 | * 60 | * @return array 61 | * @throws \Exception 62 | */ 63 | protected function _unserialize($only = null): array 64 | { 65 | try { 66 | $data = json_decode($this->rawData, true); 67 | } catch (\Exception $e) { 68 | throw new \Exception("Serialized Data error json: " . json_last_error_msg()); 69 | } 70 | 71 | if (!empty($data) && (!empty($only) || null != $only)) { 72 | if (is_string($only)) 73 | $only = (array)$only; 74 | return array_only($data, $only); 75 | } 76 | 77 | return is_array($data) ?: array(); 78 | } 79 | 80 | /** 81 | * Create array with type of Serializer and $data, in json encode 82 | * 83 | * @param $data 84 | * @param bool $isRawData 85 | * @param string $serializer 86 | * @return string|null 87 | * @throws \Exception 88 | */ 89 | protected function _serialize($data, bool $isRawData = false, string $serializer = DefaultSerializer::class): ?string 90 | { 91 | if (false === $isRawData) 92 | $data = array('serializer' => $serializer, 'data' => $data, 'created_at' => Carbon::now()->toDateTimeString()); 93 | 94 | $rawData = json_encode($data, JSON_FORCE_OBJECT); 95 | 96 | $this->setRawData($rawData); 97 | 98 | return $rawData; 99 | } 100 | } -------------------------------------------------------------------------------- /src/Serializer/CollectSerializer.php: -------------------------------------------------------------------------------- 1 | _serialize($data, $isRawData, self::SERIALIZER); 25 | } 26 | 27 | public function get() 28 | { 29 | $data = $this->_unserialize('data'); 30 | 31 | return collect($data['data']); 32 | } 33 | } -------------------------------------------------------------------------------- /src/Serializer/DefaultSerializer.php: -------------------------------------------------------------------------------- 1 | _serialize($data, $isRawData, self::SERIALIZER); 21 | 22 | return $rawData; 23 | } 24 | 25 | public function get() 26 | { 27 | $data = $this->_unserialize('data'); 28 | return $data['data']; 29 | } 30 | } -------------------------------------------------------------------------------- /src/Serializer/Interfaces/SerializerInterface.php: -------------------------------------------------------------------------------- 1 | $data->headers->all(), 25 | 'status' => $data->getStatusCode(), 26 | 'content' => $data->getContent(), 27 | ]; 28 | 29 | return $this->_serialize($data, $isRawData,self::SERIALIZER); 30 | } 31 | 32 | public function get() 33 | { 34 | $data = $this->_unserialize('data'); 35 | $data = $data['data']; 36 | 37 | if (class_exists(\Kosmosx\Response\RestResponse::class)) 38 | return new \Kosmosx\Response\RestResponse($data['content'], $data['status'], $data['headers']); 39 | 40 | return response()->json($data['content'], $data['status'], $data['headers']); 41 | } 42 | } -------------------------------------------------------------------------------- /src/Services/Builder/CacheBuilderInterface.php: -------------------------------------------------------------------------------- 1 | env('CACHE_DRIVER', 'file'), 5 | 6 | 'stores' => [ 7 | 'file' => [ 8 | 'driver' => 'file', 9 | 'path' => storage_path('framework/cache'), 10 | ], 11 | 'array' => [ 12 | 'driver' => 'array', 13 | ], 14 | ], 15 | ]; -------------------------------------------------------------------------------- /src/config/database.php: -------------------------------------------------------------------------------- 1 | [ 14 | 'cluster' => false, 15 | 'client' => 'phpredis', 16 | 'default' => [ 17 | 'host' => env('REDIS_HOST', 'redis'), 18 | 'password' => env('REDIS_PASSWORD', null), 19 | 'port' => env('REDIS_PORT', 6379), 20 | 'database' => 0, 21 | ], 22 | ], 23 | ]; 24 | --------------------------------------------------------------------------------