Skip to content

Commit

Permalink
Merge pull request #6 from mostafaznv/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
mostafaznv authored Jun 12, 2022
2 parents 8b9923d + cf378e0 commit b95d071
Show file tree
Hide file tree
Showing 32 changed files with 1,483 additions and 572 deletions.
143 changes: 124 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,25 +109,34 @@ Manually updating the cache entities of models after dispatching model events (c
- [Update Cache Manually](#update-cache-manually)
- [Update an Entity](#update-an-entity)
- [Update all Entities](#update-all-entities)
- [Update all LaraCache Entities](#update-all-laracache-entities)
- [Delete Cache Manually](#delete-cache-manually)
- [Delete an Entity](#delete-an-entity)
- [Delete an Entity Forever](#delete-an-entity-forever)
- [Delete all Model Entities](#delete-all-model-entities)
- [Delete all Model Entities Forever](#delete-all-model-entities-forever)
- [Delete all LaraCache Entities](#delete-all-laracache-entities)
- [Config Properties](#config-properties)
- [Complete Example](#complete-example)



## CacheEntity Methods

| method | Arguments | description |
|---------------------|----------------------------------------|-------------------------------------------------------------------------------|
| refreshAfterCreate | status (type: `bool`, default: `true`) | Specifies if the cache should refresh after create a record |
| refreshAfterUpdate | status (type: `bool`, default: `true`) | Specifies if the cache should refresh after update a record |
| refreshAfterDelete | status (type: `bool`, default: `true`) | Specifies if the cache should refresh after delete a record |
| refreshAfterRestore | status (type: `bool`, default: `true`) | Specifies if the cache should refresh after restore a record |
| forever | | Specifies that the cache should be valid forever |
| validForRestOfDay | | Specify that cache entity should be valid till end of day |
| validForRestOfWeek | | Specify that cache entity should be valid till end of week |
| ttl | seconds (type: `int`) | Specifies cache time to live in second |
| setDefault | defaultValue (type: `mixed`) | Specifies default value for the case that cache entity doesn't have any value |
| cache | Closure | **Main** part of each cache entity. defines cache content |
| method | Arguments | description |
|----------------------|-----------------------------------------|-------------------------------------------------------------------------------|
| setDriver | driver (type: `string`) | Specifies custom driver for cache entity |
| isQueueable | status (type: `bool`, default: 'true') | Specifies if cache operation should perform in the background or not |
| refreshAfterCreate | status (type: `bool`, default: `true`) | Specifies if the cache should refresh after create a record |
| refreshAfterUpdate | status (type: `bool`, default: `true`) | Specifies if the cache should refresh after update a record |
| refreshAfterDelete | status (type: `bool`, default: `true`) | Specifies if the cache should refresh after delete a record |
| refreshAfterRestore | status (type: `bool`, default: `true`) | Specifies if the cache should refresh after restore a record |
| forever | | Specifies that the cache should be valid forever |
| validForRestOfDay | | Specify that cache entity should be valid till end of day |
| validForRestOfWeek | | Specify that cache entity should be valid till end of week |
| ttl | seconds (type: `int`) | Specifies cache time to live in second |
| setDefault | defaultValue (type: `mixed`) | Specifies default value for the case that cache entity doesn't have any value |
| cache | Closure | **Main** part of each cache entity. defines cache content |
## Disable/Enable Cache
Expand Down Expand Up @@ -184,17 +193,111 @@ use Mostafaznv\LaraCache\Facades\LaraCache;
Article::cache()->updateAll();
// or
LaraCache::updateAll(Article::class, 'latest');
LaraCache::updateAll(Article::class);
```
### Update all LaraCache Entities
This will update all cache entities that stored using LaraCache (across all models)
```php
use App\Models\Article;
use Mostafaznv\LaraCache\Facades\LaraCache;
LaraCache::updateAll();
```
## Delete Cache Manually
Sometimes you want to delete cache entities manually. using these methods, you can do it.
### Delete an Entity
Using this feature, you can delete cache entities temporary. after spending ttl, cache entity will be generated again.
```php
use App\Models\Article;
use Mostafaznv\LaraCache\Facades\LaraCache;
Article::cache()->delete('latest');
// or
LaraCache::delete(Article::class, 'latest');
```
### Delete an Entity Forever
Using this feature, you can delete cache entities permanently. Cache item will be deleted forever and whenever you try to retrieve it, you will get null (or default value).
```php
use App\Models\Article;
use Mostafaznv\LaraCache\Facades\LaraCache;
Article::cache()->delete('latest', true);
// or
LaraCache::delete(Article::class, 'latest', true);
```
> Note: Cache Entity will update after creating or updating records in your model
### Delete all Model Entities
```php
use App\Models\Article;
use Mostafaznv\LaraCache\Facades\LaraCache;
Article::cache()->deleteAll();
// or
LaraCache::deleteAll(Article::class);
```
### Delete all Model Entities Forever
```php
use App\Models\Article;
use Mostafaznv\LaraCache\Facades\LaraCache;
Article::cache()->deleteAll(true);
// or
LaraCache::deleteAll(Article::class, true);
```
### Delete all LaraCache Entities
This will delete all cache entities that stored using LaraCache (across all models)
```php
use App\Models\Article;
use Mostafaznv\LaraCache\Facades\LaraCache;
LaraCache::deleteAll();
// forever
LaraCache::deleteAll(forever: true);
```
## Config Properties
| method | Type | description |
|-------------------|--------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| driver | string (default: `null`) | The default mechanism for handling cache storage.<br>If you keep this option `null`, LaraCache will use the default cache storage from `config/cache.php` |
| first-day-of-week | integer (default: `0`) | In some regions, saturday is first day of the week and in another regions it may be different. you can change the first day of a week by changing this property |
| last-day-of-week | integer (default: `6`) | In some regions, friday is last day of the week and in another regions it may be different. you can change the last day of a week by changing this property |
| queue | bool (default: `false`) | Sometimes caching process is very heavy, so you have to queue the process and do it in background. |
| method | Type | description |
|--------------------------|--------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| driver | string (default: `null`) | The default mechanism for handling cache storage.<br>If you keep this option `null`, LaraCache will use the default cache storage from `config/cache.php` |
| laracache-list | string (default: `laracache.list`) | LaraCache uses a separate list to store name of all entities. using these keys, we can perform some actions to all entities (such as update or delete them) |
| first-day-of-week | integer (default: `0`) | In some regions, saturday is first day of the week and in another regions it may be different. you can change the first day of a week by changing this property |
| last-day-of-week | integer (default: `6`) | In some regions, friday is last day of the week and in another regions it may be different. you can change the last day of a week by changing this property |
| queue | bool (default: `false`) | Sometimes caching process is very heavy, so you have to queue the process and do it in background. |
## Complete Example
Expand All @@ -220,11 +323,13 @@ class Article extends Model
return [
CacheEntity::make('list.forever')
->forever()
->setDriver('redis')
->cache(function() {
return Article::query()->latest()->get();
}),
CacheEntity::make('list.day')
->isQueueable()
->validForRestOfDay()
->cache(function() {
return Article::query()->latest()->get();
Expand Down
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@
"autoload": {
"psr-4": {
"Mostafaznv\\LaraCache\\": "src/"
}
},
"files": [
"src/Utils/Helpers.php"
]
},
"autoload-dev": {
"psr-4": {
Expand Down
12 changes: 12 additions & 0 deletions config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@

'driver' => null,

/*
|--------------------------------------------------------------------------
| Cache List Key
|--------------------------------------------------------------------------
|
| LaraCache uses a separate list to store name of all entities. using these
| keys, we can perform some actions to all entities (such as update or delete them)
|
*/

'laracache-list' => 'laracache.list',

/*
|--------------------------------------------------------------------------
| First Day of Week
Expand Down
142 changes: 28 additions & 114 deletions src/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,153 +2,67 @@

namespace Mostafaznv\LaraCache;

use Exception;
use Illuminate\Support\Facades\Cache as CacheFacade;
use Illuminate\Database\Eloquent\Model;
use Mostafaznv\LaraCache\CacheEntity;
use Mostafaznv\LaraCache\DTOs\CacheData;
use Mostafaznv\LaraCache\DTOs\CacheEvent;
use Mostafaznv\LaraCache\Jobs\RefreshCache;
use Mostafaznv\LaraCache\Utils\Helpers;
use Mostafaznv\LaraCache\Traits\InteractsWithCache;

class Cache
{
public static string $created = 'created';
public static string $updated = 'updated';
public static string $deleted = 'deleted';
public static string $restored = 'restored';
use InteractsWithCache;

private mixed $model;

public function __construct(string $model)
{
$this->model = $model;
}


private function driver(): ?string
public function get(string $name, bool $withCacheData = false): mixed
{
return config('laracache.driver') ?? config('cache.default');
}
$cache = $this->retrieve($name);

private function findCacheEntity(string $name, ?CacheEntity $entity = null): ?CacheEntity
{
if (is_null($entity)) {
foreach ($this->model::cacheEntities() as $cacheEntity) {
if ($cacheEntity->name === $name) {
return $cacheEntity;
}
}
if ($withCacheData) {
return $cache;
}

return $entity;
return $cache->value;
}

private function entityIsCallable(CacheEntity $entity, string $event = ''): bool
public function update(string $name): CacheData
{
return $event == ''
or ($event == self::$created and $entity->refreshAfterCreate)
or ($event == self::$updated and $entity->refreshAfterUpdate)
or ($event == self::$deleted and $entity->refreshAfterDelete)
or ($event == self::$restored and $entity->refreshAfterRestore);
return $this->updateCacheEntity($name);
}

private function isQueueable(): bool
public function updateAll(): void
{
return config('laracache.queue') ?? false;
foreach ($this->model::cacheEntities() as $entity) {
$this->updateCacheEntity(
name: $entity->name,
entity: $entity
);
}
}

private function updateCacheEntity(string $name, string $event = '', CacheEntity $entity = null): mixed
public function delete(string $name, bool $forever = false): CacheData
{
$entity = $this->findCacheEntity($name, $entity);

if ($entity) {
$driver = $this->driver();

if ($this->entityIsCallable($entity, $event)) {
$value = $entity->cacheClosure ? call_user_func($entity->cacheClosure) : null;

if ($entity->forever) {
CacheFacade::store($driver)->forever($entity->name, $value);
}
else {
if ($entity->validForRestOfDay) {
$ttl = Helpers::timeToEndOfDay();
}
else if ($entity->validForRestOfWeek) {
$ttl = Helpers::timeToEndOfWeek();
}
else {
$ttl = $entity->ttl;
}

CacheFacade::store($driver)->put($entity->name, $value, $ttl);
}

return $value;
}
else {
return CacheFacade::store($driver)->get($entity->name, $entity->default);
}
}
else {
throw new Exception("Cache entity [$name] not found. please check if [$name] exists in " . $this->model);
}
return $this->deleteCacheEntity($name, $forever);
}

private function retrieve(string $name): mixed
public function deleteAll(bool $forever = false): void
{
$driver = $this->driver();

foreach ($this->model::cacheEntities() as $entity) {
if ($entity->name == $name) {
$value = CacheFacade::store($driver)->get($entity->name, $entity->default);

if ($value) {
return $value;
}
else {
return $this->updateCacheEntity($name, '', $entity);
}
}
$this->deleteCacheEntity($entity->name, $forever, $entity);
}

throw new Exception("Cache entity [$name] not found. please check if [$name] exists in " . $this->model);
}


public function refresh(Model $model, string $event): void
public function refresh(CacheEvent $event): void
{
if ($this->model::$isEnabled) {
if ($this->isQueueable()) {
RefreshCache::dispatch($model, $event);
}
else {
foreach ($this->model::cacheEntities() as $entity) {
foreach ($this->model::cacheEntities() as $entity) {
if ($entity->isQueueable) {
RefreshCache::dispatch($this->model, $entity->name, $event);
}
else {
$this->updateCacheEntity($entity->name, $event, $entity);
}
}
}
}

public function get(string $name): mixed
{
return $this->retrieve($name);
}

public function update(string $name): mixed
{
return $this->updateCacheEntity($name);
}

public function updateAll(): void
{
foreach ($this->model::cacheEntities() as $entity) {
$this->updateCacheEntity(
name: $entity->name,
entity: $entity
);
}
}

public function disable(): void
{
$this->model::$isEnabled = false;
Expand Down
Loading

0 comments on commit b95d071

Please sign in to comment.