From 7724b8fd4e605b5329a79ac75158caee981aa0d8 Mon Sep 17 00:00:00 2001 From: David <75451291+dulkoss@users.noreply.github.com> Date: Fri, 19 Apr 2024 19:09:33 +0200 Subject: [PATCH 1/4] wip --- src/CachedComponent.php | 12 +++++- src/CachesValue.php | 89 +++++++++++++++++++++++++++-------------- 2 files changed, 71 insertions(+), 30 deletions(-) diff --git a/src/CachedComponent.php b/src/CachedComponent.php index b1800b4..f410f2a 100644 --- a/src/CachedComponent.php +++ b/src/CachedComponent.php @@ -12,10 +12,20 @@ abstract class CachedComponent extends Component { use CachesValue; + protected function registerParameters(array $args): void + { + $parameters = (new \ReflectionClass(static::class))->getConstructor()->getParameters(); + $this->parameters = collect($args)->mapWithKeys(fn ($v, $k) => [$parameters[$k]->name => $v])->toArray(); + } + /** {@inheritdoc} */ public function resolveView() { - if (null !== $cache = $this->get()) { + if ($this->isUpdating()) { + return $this->get($this->parameters) ?? parent::resolveView(); + } + + if (null !== $cache = $this->get($this->parameters, update: true)) { return new HtmlString((string) $cache); } diff --git a/src/CachesValue.php b/src/CachesValue.php index c41a768..1873d8e 100644 --- a/src/CachesValue.php +++ b/src/CachesValue.php @@ -43,6 +43,11 @@ trait CachesValue */ protected $expression = null; + /** @var array */ + protected $parameters = []; + + private bool $updating = false; + /** * Update the cached value, this method expects an event if * the cacher is not static. @@ -51,28 +56,61 @@ trait CachesValue */ final public function handle($event = null): void { - [$driver, $ident] = self::store(); + $this->updating = true; + + [$driver, $ident] = self::store($this->parameters); $value = is_subclass_of(static::class, CachedComponent::class) ? Blade::renderComponent($this) : $this->run($event); - if (is_null($value)) { - return; - } + if (is_null($value)) return; Cache::driver($driver)->forever($ident, $value); + + $this->updating = false; + } + + final protected function isUpdating(): bool + { + return $this->updating; + } + + final protected function override($with): void + { + [$driver, $ident] = self::store($this->parameters); + Cache::driver($driver)->forever($ident, $with); + } + + /** + * Get the driver and identifier specified in the $store property. + * + * @return array{string, string} + */ + private static function store($parameters): array + { + $class = static::class; + + $store = (new ReflectionClass($class)) + ->getProperty('store') + ->getDefaultValue(); + + $extension = http_build_query($parameters); + + return self::parseCacheString($class, $store, '?'.$extension); } /** * Manually force a static cache to update. */ - final public static function update(array $parameters = []): ?PendingDispatch + final public static function update($parameters = []): ?PendingDispatch { $instance = app()->make(static::class, $parameters); - if (! is_a(static::class, ShouldQueue::class, true)) { - $instance->handle($parameters); + $instance->parameters = $parameters; + + if (! is_subclass_of(static::class, ShouldQueue::class)) { + $instance->handle(); return null; } @@ -87,14 +125,19 @@ final public static function update(array $parameters = []): ?PendingDispatch * when it doesn't hold the value yet. * @return V|mixed|null */ - final public static function get(array $parameters = [], $default = null, bool $update = false): mixed + final public static function get($default = null, bool $update = false): mixed { - [$driver, $ident] = self::store(); + if (is_subclass_of(static::class, CachedComponent::class)) { + $parameters = $default; + $default = null; + } + + [$driver, $ident] = self::store($parameters ?? []); $cache = Cache::driver($driver); if ($update && ! $cache->has($ident)) { - static::update($parameters)?->onConnection('sync'); + static::update($parameters ?? [])?->onConnection('sync'); } return $cache->get($ident, $default); @@ -111,7 +154,11 @@ final public static function get(array $parameters = [], $default = null, bool $ */ final protected function value($default = null): mixed { - [$driver, $ident] = self::store(); + if (is_subclass_of(static::class, CachedComponent::class) && !is_null($default)) { + throw new \Exception("A cached component can not have a default return value"); + } + + [$driver, $ident] = self::store($this->parameters); return Cache::driver($driver)->get( $ident, $default, @@ -168,7 +215,7 @@ private static function getUpdateMethodString(): string /** * @return array{string, string} */ - private static function parseCacheString($class, ?string $store): array + private static function parseCacheString($class, ?string $store, ?string $extension = null): array { if ($store && strpos($store, ':')) { $cacheDriver = substr($store, 0, strpos($store, ':')); @@ -182,22 +229,6 @@ private static function parseCacheString($class, ?string $store): array $cacheKey = preg_replace('/[^A-Za-z0-9]+/', '_', $cacheKey); - return [$cacheDriver, $cacheKey]; - } - - /** - * Get the driver and identifier specified in the $store property. - * - * @return array{string, string} - */ - private static function store(): array - { - $class = static::class; - - $store = (new ReflectionClass($class)) - ->getProperty('store') - ->getDefaultValue(); - - return self::parseCacheString($class, $store); + return [$cacheDriver, $cacheKey.$extension]; } } From 2b72c619bf3f0e168b2d560fdee9f752ea722d98 Mon Sep 17 00:00:00 2001 From: david-d-h Date: Fri, 19 Apr 2024 17:09:58 +0000 Subject: [PATCH 2/4] Fix styling --- src/CachesValue.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/CachesValue.php b/src/CachesValue.php index 1873d8e..a44cb64 100644 --- a/src/CachesValue.php +++ b/src/CachesValue.php @@ -64,7 +64,9 @@ final public function handle($event = null): void ? Blade::renderComponent($this) : $this->run($event); - if (is_null($value)) return; + if (is_null($value)) { + return; + } Cache::driver($driver)->forever($ident, $value); @@ -154,8 +156,8 @@ final public static function get($default = null, bool $update = false): mixed */ final protected function value($default = null): mixed { - if (is_subclass_of(static::class, CachedComponent::class) && !is_null($default)) { - throw new \Exception("A cached component can not have a default return value"); + if (is_subclass_of(static::class, CachedComponent::class) && ! is_null($default)) { + throw new \Exception('A cached component can not have a default return value'); } [$driver, $ident] = self::store($this->parameters); From 43e5f9e5ac34eedb4e991b050df903878918f1da Mon Sep 17 00:00:00 2001 From: David <75451291+dulkoss@users.noreply.github.com> Date: Fri, 19 Apr 2024 19:16:24 +0200 Subject: [PATCH 3/4] remove unused method --- src/CachesValue.php | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/CachesValue.php b/src/CachesValue.php index 1873d8e..35c6a72 100644 --- a/src/CachesValue.php +++ b/src/CachesValue.php @@ -58,7 +58,7 @@ final public function handle($event = null): void { $this->updating = true; - [$driver, $ident] = self::store($this->parameters); + [$driver, $ident] = $this->store($this->parameters); $value = is_subclass_of(static::class, CachedComponent::class) ? Blade::renderComponent($this) @@ -76,12 +76,6 @@ final protected function isUpdating(): bool return $this->updating; } - final protected function override($with): void - { - [$driver, $ident] = self::store($this->parameters); - Cache::driver($driver)->forever($ident, $with); - } - /** * Get the driver and identifier specified in the $store property. * @@ -121,7 +115,7 @@ final public static function update($parameters = []): ?PendingDispatch /** * Get the cached value this cacher provides. * - * @param bool $update Whether the cache should update + * @param bool $update Whether the cache should update * when it doesn't hold the value yet. * @return V|mixed|null */ @@ -154,11 +148,11 @@ final public static function get($default = null, bool $update = false): 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 not have a default return value"); } - [$driver, $ident] = self::store($this->parameters); + [$driver, $ident] = $this->store($this->parameters); return Cache::driver($driver)->get( $ident, $default, @@ -166,6 +160,7 @@ final protected function value($default = null): mixed } /// Default implementation for the `\Scheduled::schedule` method. + /** @param CallbackEvent $callback */ public static function schedule($callback) { From 64944b54c95b06ecd23a7b5ded368d6d4517ba76 Mon Sep 17 00:00:00 2001 From: David <75451291+dulkoss@users.noreply.github.com> Date: Sat, 20 Apr 2024 20:58:32 +0200 Subject: [PATCH 4/4] automatically resolve parameters --- src/CachedComponent.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/CachedComponent.php b/src/CachedComponent.php index f410f2a..2c456bc 100644 --- a/src/CachedComponent.php +++ b/src/CachedComponent.php @@ -12,17 +12,19 @@ abstract class CachedComponent extends Component { use CachesValue; - protected function registerParameters(array $args): void - { - $parameters = (new \ReflectionClass(static::class))->getConstructor()->getParameters(); - $this->parameters = collect($args)->mapWithKeys(fn ($v, $k) => [$parameters[$k]->name => $v])->toArray(); - } - /** {@inheritdoc} */ public function resolveView() { + $this->parameters = collect((new \ReflectionClass(static::class)) + ->getProperties(\ReflectionProperty::IS_PUBLIC)) + ->filter(fn (\ReflectionProperty $p) => $p->class === static::class) + ->mapWithKeys(fn (\ReflectionProperty $p) => [$p->name => $p->getValue($this)]) + ->toArray(); + if ($this->isUpdating()) { - return $this->get($this->parameters) ?? parent::resolveView(); + $value = $this->get($this->parameters); + + return is_null($value) ? parent::resolveView() : new HtmlString($value); } if (null !== $cache = $this->get($this->parameters, update: true)) {