From 5ecd24d89f74bd22fa040e6c94cfda4dc93ecc1e Mon Sep 17 00:00:00 2001 From: Miguel Angel Date: Fri, 29 Nov 2024 11:25:29 -0400 Subject: [PATCH 1/4] feat: add a custom cache class structure --- ProcessMaker/Cache/CacheInterface.php | 63 +++++++++++++++++++ ProcessMaker/Cache/SettingCacheFacade.php | 20 ++++++ ProcessMaker/Cache/SettingCacheManager.php | 50 +++++++++++++++ .../Providers/ProcessMakerServiceProvider.php | 5 ++ 4 files changed, 138 insertions(+) create mode 100644 ProcessMaker/Cache/CacheInterface.php create mode 100644 ProcessMaker/Cache/SettingCacheFacade.php create mode 100644 ProcessMaker/Cache/SettingCacheManager.php diff --git a/ProcessMaker/Cache/CacheInterface.php b/ProcessMaker/Cache/CacheInterface.php new file mode 100644 index 0000000000..a89024c9d5 --- /dev/null +++ b/ProcessMaker/Cache/CacheInterface.php @@ -0,0 +1,63 @@ +cacheManager = $cacheManager; + } + + public function __call($method, $arguments) + { + return $this->cacheManager->$method(...$arguments); + } + + public function get(string $key, mixed $default = null): mixed + { + return $this->cacheManager->get($key, $default); + } + + public function set(string $key, mixed $value, null|int|\DateInterval $ttl = null): bool + { + return $this->cacheManager->put($key, $value, $ttl); + } + + public function delete(string $key): bool + { + return $this->cacheManager->forget($key); + } + + public function clear(): bool + { + return $this->cacheManager->flush(); + } + + public function has(string $key): bool + { + return $this->cacheManager->has($key); + } + + public function missing(string $key): bool + { + return !$this->has($key); + } +} diff --git a/ProcessMaker/Providers/ProcessMakerServiceProvider.php b/ProcessMaker/Providers/ProcessMakerServiceProvider.php index ce11b8e437..6307f62570 100644 --- a/ProcessMaker/Providers/ProcessMakerServiceProvider.php +++ b/ProcessMaker/Providers/ProcessMakerServiceProvider.php @@ -15,6 +15,7 @@ use Laravel\Horizon\Horizon; use Laravel\Passport\Passport; use Lavary\Menu\Menu; +use ProcessMaker\Cache\SettingCacheManager; use ProcessMaker\Console\Migration\ExtendedMigrateCommand; use ProcessMaker\Events\ActivityAssigned; use ProcessMaker\Events\ScreenBuilderStarting; @@ -164,6 +165,10 @@ public function register(): void $this->app->singleton('compiledscreen', function ($app) { return new ScreenCompiledManager(); }); + + $this->app->singleton('setting.cache', function ($app) { + return new SettingCacheManager($app->make('cache')); + }); } /** From e4deb5aaf40fada7ea98e548c0373690ca45e4e0 Mon Sep 17 00:00:00 2001 From: Miguel Angel Date: Fri, 29 Nov 2024 11:33:31 -0400 Subject: [PATCH 2/4] test: add tests for SettingCache methods --- tests/Feature/Cache/SettingCacheTest.php | 102 +++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 tests/Feature/Cache/SettingCacheTest.php diff --git a/tests/Feature/Cache/SettingCacheTest.php b/tests/Feature/Cache/SettingCacheTest.php new file mode 100644 index 0000000000..56288bec63 --- /dev/null +++ b/tests/Feature/Cache/SettingCacheTest.php @@ -0,0 +1,102 @@ +with($key, $default) + ->andReturn($expected); + + $result = \SettingCache::get($key, $default); + + $this->assertEquals($expected, $result); + } + + public function testSet() + { + $key = 'test_key'; + $value = 'test_value'; + $ttl = 60; + + \SettingCache::shouldReceive('set') + ->with($key, $value, $ttl) + ->andReturn(true); + + $result = \SettingCache::set($key, $value, $ttl); + + $this->assertTrue($result); + } + + public function testDelete() + { + $key = 'test_key'; + + \SettingCache::shouldReceive('delete') + ->with($key) + ->andReturn(true); + + $result = \SettingCache::delete($key); + + $this->assertTrue($result); + } + + public function testClear() + { + \SettingCache::shouldReceive('clear') + ->andReturn(true); + + $result = \SettingCache::clear(); + + $this->assertTrue($result); + } + + public function testHas() + { + $key = 'test_key'; + + \SettingCache::shouldReceive('has') + ->with($key) + ->andReturn(true); + + $result = \SettingCache::has($key); + + $this->assertTrue($result); + } + + public function testMissing() + { + $key = 'test_key'; + + \SettingCache::shouldReceive('missing') + ->with($key) + ->andReturn(false); + + $result = \SettingCache::missing($key); + + $this->assertFalse($result); + } + + public function testCall() + { + $method = 'add'; + $arguments = ['arg1', 'arg2']; + $expected = 'cached_value'; + + \SettingCache::shouldReceive($method) + ->with(...$arguments) + ->andReturn($expected); + + $result = \SettingCache::__call($method, $arguments); + + $this->assertEquals($expected, $result); + } +} From b2b983dee1324162218b7bc730771eef074a7c84 Mon Sep 17 00:00:00 2001 From: Miguel Angel Date: Fri, 29 Nov 2024 11:42:48 -0400 Subject: [PATCH 3/4] feat: organize cache classes --- ProcessMaker/Cache/SettingCacheManager.php | 50 --------- .../{ => Settings}/SettingCacheFacade.php | 4 +- .../Cache/Settings/SettingCacheManager.php | 101 ++++++++++++++++++ .../Providers/ProcessMakerServiceProvider.php | 2 +- config/app.php | 3 +- 5 files changed, 106 insertions(+), 54 deletions(-) delete mode 100644 ProcessMaker/Cache/SettingCacheManager.php rename ProcessMaker/Cache/{ => Settings}/SettingCacheFacade.php (72%) create mode 100644 ProcessMaker/Cache/Settings/SettingCacheManager.php diff --git a/ProcessMaker/Cache/SettingCacheManager.php b/ProcessMaker/Cache/SettingCacheManager.php deleted file mode 100644 index 8beb156e3e..0000000000 --- a/ProcessMaker/Cache/SettingCacheManager.php +++ /dev/null @@ -1,50 +0,0 @@ -cacheManager = $cacheManager; - } - - public function __call($method, $arguments) - { - return $this->cacheManager->$method(...$arguments); - } - - public function get(string $key, mixed $default = null): mixed - { - return $this->cacheManager->get($key, $default); - } - - public function set(string $key, mixed $value, null|int|\DateInterval $ttl = null): bool - { - return $this->cacheManager->put($key, $value, $ttl); - } - - public function delete(string $key): bool - { - return $this->cacheManager->forget($key); - } - - public function clear(): bool - { - return $this->cacheManager->flush(); - } - - public function has(string $key): bool - { - return $this->cacheManager->has($key); - } - - public function missing(string $key): bool - { - return !$this->has($key); - } -} diff --git a/ProcessMaker/Cache/SettingCacheFacade.php b/ProcessMaker/Cache/Settings/SettingCacheFacade.php similarity index 72% rename from ProcessMaker/Cache/SettingCacheFacade.php rename to ProcessMaker/Cache/Settings/SettingCacheFacade.php index ead258311a..ce0609010b 100644 --- a/ProcessMaker/Cache/SettingCacheFacade.php +++ b/ProcessMaker/Cache/Settings/SettingCacheFacade.php @@ -1,13 +1,13 @@ cacheManager = $cacheManager; + } + + /** + * Dynamically pass method calls to the cache manager. + * + * @param string $method + * @param array $arguments + * @return mixed + */ + public function __call($method, $arguments): mixed + { + return $this->cacheManager->$method(...$arguments); + } + + /** + * Get a value from the settings cache. + * + * @param string $key + * @param mixed $default + * + * @return mixed + */ + public function get(string $key, mixed $default = null): mixed + { + return $this->cacheManager->get($key, $default); + } + + /** + * Store a value in the settings cache. + * + * @param string $key + * @param mixed $value + * @param null|int|\DateInterval $ttl + * + * @return bool + */ + public function set(string $key, mixed $value, null|int|\DateInterval $ttl = null): bool + { + return $this->cacheManager->put($key, $value, $ttl); + } + + /** + * Delete a value from the settings cache. + * + * @param string $key + * + * @return bool + */ + public function delete(string $key): bool + { + return $this->cacheManager->forget($key); + } + + /** + * Clear the settings cache. + * + * @return bool + */ + public function clear(): bool + { + return $this->cacheManager->flush(); + } + + /** + * Check if a value exists in the settings cache. + * + * @param string $key + * + * @return bool + */ + public function has(string $key): bool + { + return $this->cacheManager->has($key); + } + + /** + * Check if a value is missing from the settings cache. + * + * @param string $key + * + * @return bool + */ + public function missing(string $key): bool + { + return !$this->has($key); + } +} diff --git a/ProcessMaker/Providers/ProcessMakerServiceProvider.php b/ProcessMaker/Providers/ProcessMakerServiceProvider.php index 6307f62570..da4ba49270 100644 --- a/ProcessMaker/Providers/ProcessMakerServiceProvider.php +++ b/ProcessMaker/Providers/ProcessMakerServiceProvider.php @@ -15,7 +15,7 @@ use Laravel\Horizon\Horizon; use Laravel\Passport\Passport; use Lavary\Menu\Menu; -use ProcessMaker\Cache\SettingCacheManager; +use ProcessMaker\Cache\Settings\SettingCacheManager; use ProcessMaker\Console\Migration\ExtendedMigrateCommand; use ProcessMaker\Events\ActivityAssigned; use ProcessMaker\Events\ScreenBuilderStarting; diff --git a/config/app.php b/config/app.php index a011248e48..07a788a4b1 100644 --- a/config/app.php +++ b/config/app.php @@ -203,6 +203,7 @@ 'SkinManager' => ProcessMaker\Facades\SkinManager::class, 'Theme' => Igaster\LaravelTheme\Facades\Theme::class, 'WorkspaceManager' => ProcessMaker\Facades\WorkspaceManager::class, + 'SettingCache' => ProcessMaker\Cache\Settings\SettingCacheFacade::class, ])->toArray(), 'debug_blacklist' => [ @@ -246,7 +247,7 @@ // Process Request security log rate limit: 1 per day (86400 seconds) 'process_request_errors_rate_limit' => env('PROCESS_REQUEST_ERRORS_RATE_LIMIT', 1), 'process_request_errors_rate_limit_duration' => env('PROCESS_REQUEST_ERRORS_RATE_LIMIT_DURATION', 86400), - + 'default_colors' => [ 'primary' => '#2773F3', 'secondary' => '#728092', From 2a1b3b5e28195e91f31a8c7d6c9e12b18e20185e Mon Sep 17 00:00:00 2001 From: Miguel Angel Date: Fri, 29 Nov 2024 14:53:26 -0400 Subject: [PATCH 4/4] fix(cr): enhance settings cache error handling and configuration check --- ProcessMaker/Cache/Settings/SettingCacheManager.php | 10 +++++++++- ProcessMaker/Providers/ProcessMakerServiceProvider.php | 7 ++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ProcessMaker/Cache/Settings/SettingCacheManager.php b/ProcessMaker/Cache/Settings/SettingCacheManager.php index fb73907373..a330ac5cb6 100644 --- a/ProcessMaker/Cache/Settings/SettingCacheManager.php +++ b/ProcessMaker/Cache/Settings/SettingCacheManager.php @@ -2,7 +2,9 @@ namespace ProcessMaker\Cache\Settings; +use Exception; use Illuminate\Cache\CacheManager; +use Illuminate\Support\Facades\Log; use ProcessMaker\Cache\CacheInterface; class SettingCacheManager implements CacheInterface @@ -36,7 +38,13 @@ public function __call($method, $arguments): mixed */ public function get(string $key, mixed $default = null): mixed { - return $this->cacheManager->get($key, $default); + try { + return $this->cacheManager->get($key, $default); + } catch (Exception $e) { + Log::error('Cache error: ' . $e->getMessage()); + } + + return null; } /** diff --git a/ProcessMaker/Providers/ProcessMakerServiceProvider.php b/ProcessMaker/Providers/ProcessMakerServiceProvider.php index da4ba49270..4c8af989f3 100644 --- a/ProcessMaker/Providers/ProcessMakerServiceProvider.php +++ b/ProcessMaker/Providers/ProcessMakerServiceProvider.php @@ -30,6 +30,7 @@ use ProcessMaker\Models; use ProcessMaker\Observers; use ProcessMaker\PolicyExtension; +use RuntimeException; /** * Provide our ProcessMaker specific services. @@ -167,7 +168,11 @@ public function register(): void }); $this->app->singleton('setting.cache', function ($app) { - return new SettingCacheManager($app->make('cache')); + if ($app['config']->get('cache.default')) { + return new SettingCacheManager($app->make('cache')); + } else { + throw new RuntimeException('Cache configuration is missing.'); + } }); }