From a96b50baca86e7f7d70c0d9d48ed9e31df778a8c Mon Sep 17 00:00:00 2001 From: MHortulanus Date: Mon, 3 Jun 2024 11:44:19 +0200 Subject: [PATCH 01/11] Add example route --- .DS_Store | Bin 0 -> 6148 bytes src/CachesValue.php | 31 +++++++++++++++----------- src/PermanentCacheServiceProvider.php | 10 ++++++--- src/Routes/web.php | 7 ++++++ 4 files changed, 32 insertions(+), 16 deletions(-) create mode 100644 .DS_Store create mode 100644 src/Routes/web.php diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..453d537005272042fb6656819891c59cce0e5735 GIT binary patch literal 6148 zcmeH~O-chn5QVEWkpVYZiQuLW;3hX{!+3&RK;nol5+?|{?wh%D<7GU8uewTQk^y%? zxj`0+JIkdQXxM(CF8c+U8UbH?P>!<22nq66w00|5U9D8?W=l?Z+nb9PF7{VS2 zkib79pp$mlF7Q!tw(fnNowW(&2F1+$iZx(p4=w@d*gkSzCw)Fy8-6*oxY{Zhas($cacheKey) + !$cache->has($cacheKey) ) { return static::updateAndGet($parameters ?? []); } @@ -189,14 +189,15 @@ final public function getMeta($parameters = []): mixed */ final protected function value($default = null): mixed { - if (is_subclass_of(static::class, CachedComponent::class) && ! is_null($default)) { + if (is_subclass_of(static::class, CachedComponent::class) && !is_null($default)) { throw new \Exception("A cached component can't have a default return value"); } [$store, $cacheKey] = $this->store($this->getParameters()); return Cache::store($store)->get( - $cacheKey, $default, + $cacheKey, + $default, )?->value; } @@ -214,8 +215,8 @@ public function getShortName(): string /** @param CallbackEvent $callback */ public static function schedule($callback) { - if (! is_a(static::class, Scheduled::class, true)) { - throw new \Exception("Can't schedule a cacher that does not implement the [".Scheduled::class.'] interface'); + if (!is_a(static::class, Scheduled::class, true)) { + throw new \Exception("Can't schedule a cacher that does not implement the [" . Scheduled::class . '] interface'); } $reflection = new ReflectionClass(static::class); @@ -223,7 +224,7 @@ public static function schedule($callback) $concrete = $reflection->getProperty('expression')->getDefaultValue(); if (is_null($concrete)) { - throw new \Exception('Either the Cached::$expression property or the ['.__METHOD__.'] method must be overridden by the user.'); + throw new \Exception('Either the Cached::$expression property or the [' . __METHOD__ . '] method must be overridden by the user.'); } $callback->cron($concrete); @@ -266,7 +267,7 @@ public static function getCacheKey(?array $parameters = [], ?string $store = nul ->getDefaultValue(); if ( - ! is_null($store) && + !is_null($store) && strpos($store, ':') ) { $cacheStore = substr($store, 0, strpos($store, ':')); @@ -279,7 +280,7 @@ public static function getCacheKey(?array $parameters = [], ?string $store = nul $cacheKey ??= preg_replace('/[^A-Za-z0-9]+/', '_', strtolower(Str::snake($class))); if ($parameters) { - $cacheKey .= ':'.http_build_query($parameters); + $cacheKey .= ':' . http_build_query($parameters); } return [$cacheStore, $cacheKey]; @@ -289,24 +290,28 @@ public function getMarker(array $parameters = [], $close = false): string { [$cacheStore, $cacheKey] = $this::store($parameters ?? $this->getParameters()); - $marker = $cacheStore.':'.$cacheKey; + $marker = $cacheStore . ':' . $cacheKey; if (config('permanent-cache.components.markers.hash')) { $marker = md5($marker); } - return ''; + return ''; } public function addMarkers($value): mixed { if ( - ! config('permanent-cache.components.markers.enabled') || - ! is_subclass_of($this, CachedComponent::class) + !config('permanent-cache.components.markers.enabled') || + !is_subclass_of($this, CachedComponent::class) ) { return $value; } - return $this->getMarker().$value.$this->getMarker(close: true); + return $this->getMarker() . $value . $this->getMarker(close: true); + } + + public function getRefreshRoute() + { } } diff --git a/src/PermanentCacheServiceProvider.php b/src/PermanentCacheServiceProvider.php index 97102f7..3a0cdb5 100644 --- a/src/PermanentCacheServiceProvider.php +++ b/src/PermanentCacheServiceProvider.php @@ -27,9 +27,13 @@ public function registeringPackage() public function bootingPackage() { - $this->callAfterResolving(Schedule::class, fn (Schedule $schedule) => collect(Facades\PermanentCache::configuredCaches()) - ->filter(fn ($cacher) => is_a($cacher, Scheduled::class)) - ->each(fn ($cacher) => $cacher->schedule($schedule->job($cacher))) + $this->loadRoutesFrom(__DIR__ . '/Routes/web.php'); + + $this->callAfterResolving( + Schedule::class, + fn (Schedule $schedule) => collect(Facades\PermanentCache::configuredCaches()) + ->filter(fn ($cacher) => is_a($cacher, Scheduled::class)) + ->each(fn ($cacher) => $cacher->schedule($schedule->job($cacher))) ); } } diff --git a/src/Routes/web.php b/src/Routes/web.php new file mode 100644 index 0000000..1154688 --- /dev/null +++ b/src/Routes/web.php @@ -0,0 +1,7 @@ + Date: Mon, 3 Jun 2024 11:48:24 +0200 Subject: [PATCH 02/11] wip --- src/CachesValue.php | 1 + src/Routes/web.php | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/CachesValue.php b/src/CachesValue.php index 424be4e..bc13fd5 100644 --- a/src/CachesValue.php +++ b/src/CachesValue.php @@ -313,5 +313,6 @@ public function addMarkers($value): mixed public function getRefreshRoute() { + return route('permanent-cache.update', ['parameter' => 'test']); } } diff --git a/src/Routes/web.php b/src/Routes/web.php index 1154688..e567b90 100644 --- a/src/Routes/web.php +++ b/src/Routes/web.php @@ -2,6 +2,6 @@ use Illuminate\Support\Facades\Route; -Route::get('/example', function () { - return 'This is an example route from my package!'; -}); +Route::get('/permanent-cache/update/{parameter}', function ($parameter) { + return $parameter; +})->name('permanent-cache.update'); From 946866490d871ad98151464068f1d55818b1c29b Mon Sep 17 00:00:00 2001 From: MHortulanus Date: Mon, 3 Jun 2024 12:21:20 +0200 Subject: [PATCH 03/11] wip --- src/CachesValue.php | 4 +++- src/Routes/web.php | 10 ++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/CachesValue.php b/src/CachesValue.php index bc13fd5..2d3468d 100644 --- a/src/CachesValue.php +++ b/src/CachesValue.php @@ -311,8 +311,10 @@ public function addMarkers($value): mixed return $this->getMarker() . $value . $this->getMarker(close: true); } + public function getRefreshRoute() { - return route('permanent-cache.update', ['parameter' => 'test']); + $class = (new ReflectionClass($this))->name;; + return route('permanent-cache.update', encrypt([$class])); } } diff --git a/src/Routes/web.php b/src/Routes/web.php index e567b90..e332e3a 100644 --- a/src/Routes/web.php +++ b/src/Routes/web.php @@ -2,6 +2,12 @@ use Illuminate\Support\Facades\Route; -Route::get('/permanent-cache/update/{parameter}', function ($parameter) { - return $parameter; +Route::get('/permanent-cache/update/', function () { + $vars = decrypt(array_key_first(request()->all())); + extract($vars); + [$class] = $vars; + $class = new \ReflectionClass($class); + $staticClass = $class->getName(); + + return response($staticClass::updateAndGet(), 200, []); })->name('permanent-cache.update'); From e968ee22c2dedc0c85b5ceed6cb0e752dc30fb59 Mon Sep 17 00:00:00 2001 From: MHortulanus Date: Mon, 3 Jun 2024 14:00:10 +0200 Subject: [PATCH 04/11] wip --- src/CachesValue.php | 10 ++++++++-- src/Routes/web.php | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/CachesValue.php b/src/CachesValue.php index 2d3468d..d597b20 100644 --- a/src/CachesValue.php +++ b/src/CachesValue.php @@ -314,7 +314,13 @@ public function addMarkers($value): mixed public function getRefreshRoute() { - $class = (new ReflectionClass($this))->name;; - return route('permanent-cache.update', encrypt([$class])); + $class = get_class($this); + $props = + collect((new ReflectionClass($this))->getProperties(\ReflectionProperty::IS_PUBLIC)) + ->where('class', __CLASS__) + ->mapWithKeys(fn ($prop) => [$prop->name => $this->{$prop->name}]) + ->toArray(); + + return route('permanent-cache.update', ['data' => encrypt([$class, $props])]); } } diff --git a/src/Routes/web.php b/src/Routes/web.php index e332e3a..a435750 100644 --- a/src/Routes/web.php +++ b/src/Routes/web.php @@ -9,5 +9,7 @@ $class = new \ReflectionClass($class); $staticClass = $class->getName(); - return response($staticClass::updateAndGet(), 200, []); + $staticClass::update(); + + return \Illuminate\Support\Facades\Blade::renderComponent(app()->make($class, $props)); })->name('permanent-cache.update'); From 15f8db4faa18f74506299543c4c9d59ef6cc8ad4 Mon Sep 17 00:00:00 2001 From: MHortulanus Date: Mon, 3 Jun 2024 14:01:53 +0200 Subject: [PATCH 05/11] wip --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a7f372d..f997af6 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ phpstan.neon testbench.yaml vendor node_modules +.DS_Store \ No newline at end of file From 32345cef909eb74875ce934a1bdf02c278131dd7 Mon Sep 17 00:00:00 2001 From: MHortulanus Date: Mon, 3 Jun 2024 14:02:26 +0200 Subject: [PATCH 06/11] Delete .DS_Store --- .DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 453d537005272042fb6656819891c59cce0e5735..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~O-chn5QVEWkpVYZiQuLW;3hX{!+3&RK;nol5+?|{?wh%D<7GU8uewTQk^y%? zxj`0+JIkdQXxM(CF8c+U8UbH?P>!<22nq66w00|5U9D8?W=l?Z+nb9PF7{VS2 zkib79pp$mlF7Q!tw(fnNowW(&2F1+$iZx(p4=w@d*gkSzCw)Fy8-6*oxY{Z Date: Mon, 3 Jun 2024 14:02:54 +0200 Subject: [PATCH 07/11] Delete .DS_Store --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f997af6..e26945a 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,4 @@ phpstan.neon testbench.yaml vendor node_modules -.DS_Store \ No newline at end of file +.DS_Store From 668fa2f45405c85cf3b7a5d2b88a179934529faa Mon Sep 17 00:00:00 2001 From: Mark van Eijk Date: Thu, 6 Jun 2024 13:13:57 +0200 Subject: [PATCH 08/11] wip --- src/PermanentCacheServiceProvider.php | 3 +-- src/{Routes/web.php => routes/api.php} | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) rename src/{Routes/web.php => routes/api.php} (60%) diff --git a/src/PermanentCacheServiceProvider.php b/src/PermanentCacheServiceProvider.php index 3a0cdb5..ba41104 100644 --- a/src/PermanentCacheServiceProvider.php +++ b/src/PermanentCacheServiceProvider.php @@ -17,6 +17,7 @@ public function configurePackage(Package $package): void PermanentCachesStatusCommand::class, UpdatePermanentCachesCommand::class ) + ->hasRoute('api') ->hasConfigFile(); } @@ -27,8 +28,6 @@ public function registeringPackage() public function bootingPackage() { - $this->loadRoutesFrom(__DIR__ . '/Routes/web.php'); - $this->callAfterResolving( Schedule::class, fn (Schedule $schedule) => collect(Facades\PermanentCache::configuredCaches()) diff --git a/src/Routes/web.php b/src/routes/api.php similarity index 60% rename from src/Routes/web.php rename to src/routes/api.php index a435750..113bbd5 100644 --- a/src/Routes/web.php +++ b/src/routes/api.php @@ -2,14 +2,13 @@ use Illuminate\Support\Facades\Route; -Route::get('/permanent-cache/update/', function () { +Route::get('permanent-cache/update/', function () { $vars = decrypt(array_key_first(request()->all())); extract($vars); [$class] = $vars; + $class = new \ReflectionClass($class); $staticClass = $class->getName(); - $staticClass::update(); - - return \Illuminate\Support\Facades\Blade::renderComponent(app()->make($class, $props)); + return $staticClass::updateAndGet($parameters); })->name('permanent-cache.update'); From c8ad011dc76362b4f7bb1d757583276271fd2d20 Mon Sep 17 00:00:00 2001 From: Mark van Eijk Date: Thu, 6 Jun 2024 14:03:05 +0200 Subject: [PATCH 09/11] move routes folder --- {src/routes => routes}/api.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {src/routes => routes}/api.php (100%) diff --git a/src/routes/api.php b/routes/api.php similarity index 100% rename from src/routes/api.php rename to routes/api.php From ea67f6dfc3493d24690827f3699e96968c0abe14 Mon Sep 17 00:00:00 2001 From: David <75451291+david-d-h@users.noreply.github.com> Date: Sat, 15 Jun 2024 15:54:05 +0200 Subject: [PATCH 10/11] finish route that allows for updating a permanent cache --- routes/api.php | 14 --------- routes/permanent-cache.php | 27 +++++++++++++++++ src/CachesValue.php | 42 ++++++++++++--------------- src/PermanentCache.php | 2 +- src/PermanentCacheServiceProvider.php | 9 +++--- tests/TestCase.php | 1 - 6 files changed, 51 insertions(+), 44 deletions(-) delete mode 100644 routes/api.php create mode 100644 routes/permanent-cache.php diff --git a/routes/api.php b/routes/api.php deleted file mode 100644 index 113bbd5..0000000 --- a/routes/api.php +++ /dev/null @@ -1,14 +0,0 @@ -all())); - extract($vars); - [$class] = $vars; - - $class = new \ReflectionClass($class); - $staticClass = $class->getName(); - - return $staticClass::updateAndGet($parameters); -})->name('permanent-cache.update'); diff --git a/routes/permanent-cache.php b/routes/permanent-cache.php new file mode 100644 index 0000000..d5f0b30 --- /dev/null +++ b/routes/permanent-cache.php @@ -0,0 +1,27 @@ + $class */ + $class = decrypt($class); + + $parameters = ($parameters = $request->query('parameters')) + ? Arr::wrap(decrypt($parameters)) + : []; + + if ( + ! class_exists($class) || + ! in_array(CachesValue::class, class_uses_recursive($class)) + ) { + return response()->json([ + 'error' => 'the given class does not exist or does not use the ['.CachesValue::class.'] trait', + ], 400); + } + + $data = $class::updateAndGet($parameters ?? []); + + return response()->json(compact('data')); +})->name('permanent-cache.update'); diff --git a/src/CachesValue.php b/src/CachesValue.php index d597b20..9e8b0f8 100644 --- a/src/CachesValue.php +++ b/src/CachesValue.php @@ -127,9 +127,7 @@ final public static function update($parameters = []) { $instance = app()->make(static::class, $parameters); - dispatch( - $instance - ); + dispatch($instance); } /** @@ -139,9 +137,7 @@ final public static function updateAndGet($parameters = []) { $instance = app()->make(static::class, $parameters); - dispatch( - $instance - )->onConnection('sync'); + dispatch($instance)->onConnection('sync'); return static::get($parameters); } @@ -161,7 +157,7 @@ final public static function get($parameters = [], $default = null, bool $update if ( $update || - !$cache->has($cacheKey) + ! $cache->has($cacheKey) ) { return static::updateAndGet($parameters ?? []); } @@ -189,7 +185,7 @@ final public function getMeta($parameters = []): mixed */ final protected function value($default = null): mixed { - if (is_subclass_of(static::class, CachedComponent::class) && !is_null($default)) { + if (is_subclass_of(static::class, CachedComponent::class) && ! is_null($default)) { throw new \Exception("A cached component can't have a default return value"); } @@ -212,11 +208,12 @@ public function getShortName(): string } /// Default implementation for the `\Scheduled::schedule` method. - /** @param CallbackEvent $callback */ + + /** @param CallbackEvent $callback */ public static function schedule($callback) { - if (!is_a(static::class, Scheduled::class, true)) { - throw new \Exception("Can't schedule a cacher that does not implement the [" . Scheduled::class . '] interface'); + if (! is_a(static::class, Scheduled::class, true)) { + throw new \Exception("Can't schedule a cacher that does not implement the [".Scheduled::class.'] interface'); } $reflection = new ReflectionClass(static::class); @@ -224,7 +221,7 @@ public static function schedule($callback) $concrete = $reflection->getProperty('expression')->getDefaultValue(); if (is_null($concrete)) { - throw new \Exception('Either the Cached::$expression property or the [' . __METHOD__ . '] method must be overridden by the user.'); + throw new \Exception('Either the Cached::$expression property or the ['.__METHOD__.'] method must be overridden by the user.'); } $callback->cron($concrete); @@ -267,7 +264,7 @@ public static function getCacheKey(?array $parameters = [], ?string $store = nul ->getDefaultValue(); if ( - !is_null($store) && + ! is_null($store) && strpos($store, ':') ) { $cacheStore = substr($store, 0, strpos($store, ':')); @@ -280,7 +277,7 @@ public static function getCacheKey(?array $parameters = [], ?string $store = nul $cacheKey ??= preg_replace('/[^A-Za-z0-9]+/', '_', strtolower(Str::snake($class))); if ($parameters) { - $cacheKey .= ':' . http_build_query($parameters); + $cacheKey .= ':'.http_build_query($parameters); } return [$cacheStore, $cacheKey]; @@ -290,36 +287,35 @@ public function getMarker(array $parameters = [], $close = false): string { [$cacheStore, $cacheKey] = $this::store($parameters ?? $this->getParameters()); - $marker = $cacheStore . ':' . $cacheKey; + $marker = $cacheStore.':'.$cacheKey; if (config('permanent-cache.components.markers.hash')) { $marker = md5($marker); } - return ''; + return ''; } public function addMarkers($value): mixed { if ( - !config('permanent-cache.components.markers.enabled') || - !is_subclass_of($this, CachedComponent::class) + ! config('permanent-cache.components.markers.enabled') || + ! is_subclass_of($this, CachedComponent::class) ) { return $value; } - return $this->getMarker() . $value . $this->getMarker(close: true); + return $this->getMarker().$value.$this->getMarker(close: true); } - public function getRefreshRoute() { $class = get_class($this); $props = collect((new ReflectionClass($this))->getProperties(\ReflectionProperty::IS_PUBLIC)) - ->where('class', __CLASS__) - ->mapWithKeys(fn ($prop) => [$prop->name => $this->{$prop->name}]) - ->toArray(); + ->where('class', __CLASS__) + ->mapWithKeys(fn ($prop) => [$prop->name => $this->{$prop->name}]) + ->toArray(); return route('permanent-cache.update', ['data' => encrypt([$class, $props])]); } diff --git a/src/PermanentCache.php b/src/PermanentCache.php index 265b403..4cfa216 100755 --- a/src/PermanentCache.php +++ b/src/PermanentCache.php @@ -45,7 +45,7 @@ public function caches($registeredCaches): self $cacheInstance = $this->app->make($cache, $parameters); if ([] !== $events = $cacheInstance->getListenerEvents()) { - foreach($events as $event) { + foreach ($events as $event) { Event::listen($event, fn ($e) => $cacheInstance->handle($e)); } } diff --git a/src/PermanentCacheServiceProvider.php b/src/PermanentCacheServiceProvider.php index ba41104..a35d080 100644 --- a/src/PermanentCacheServiceProvider.php +++ b/src/PermanentCacheServiceProvider.php @@ -15,9 +15,9 @@ public function configurePackage(Package $package): void $package->name('laravel-permanent-cache') ->hasCommands( PermanentCachesStatusCommand::class, - UpdatePermanentCachesCommand::class + UpdatePermanentCachesCommand::class, ) - ->hasRoute('api') + ->hasRoute('permanent-cache') ->hasConfigFile(); } @@ -28,11 +28,10 @@ public function registeringPackage() public function bootingPackage() { - $this->callAfterResolving( - Schedule::class, + $this->callAfterResolving(Schedule::class, fn (Schedule $schedule) => collect(Facades\PermanentCache::configuredCaches()) ->filter(fn ($cacher) => is_a($cacher, Scheduled::class)) - ->each(fn ($cacher) => $cacher->schedule($schedule->job($cacher))) + ->each(fn ($cacher) => $cacher->schedule($schedule->job($cacher))), ); } } diff --git a/tests/TestCase.php b/tests/TestCase.php index f807998..1ce7e92 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -2,7 +2,6 @@ namespace Vormkracht10\PermanentCache\Tests; -use Illuminate\Database\Eloquent\Factories\Factory; use Orchestra\Testbench\TestCase as Orchestra; use Vormkracht10\PermanentCache\PermanentCacheServiceProvider; From 1031a7905e8e54fe65f9f8c3b115157d65893bdf Mon Sep 17 00:00:00 2001 From: David <75451291+david-d-h@users.noreply.github.com> Date: Sat, 15 Jun 2024 16:32:55 +0200 Subject: [PATCH 11/11] don't `unserialize` because we can't trust user input, force `encrypt(..., serialize: false)` to be used instead --- routes/permanent-cache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/permanent-cache.php b/routes/permanent-cache.php index d5f0b30..d3f2207 100644 --- a/routes/permanent-cache.php +++ b/routes/permanent-cache.php @@ -6,7 +6,7 @@ Route::get('/permanent-cache/{class}/update', function (Request $request, string $class) { /** @var class-string $class */ - $class = decrypt($class); + $class = decrypt($class, false); $parameters = ($parameters = $request->query('parameters')) ? Arr::wrap(decrypt($parameters))