From d500946a27802ff9bb9c33e1bbdd28d756ded7d1 Mon Sep 17 00:00:00 2001 From: pxpm Date: Fri, 6 Jun 2025 15:08:14 +0100 Subject: [PATCH 1/6] wip --- .../Controllers/Operations/ListOperation.php | 13 +- src/app/Library/Support/DatatableCache.php | 196 ++++++++++++++++++ src/app/Library/Support/SetupCache.php | 108 ++++++++++ src/app/View/Components/Datatable.php | 123 +---------- 4 files changed, 324 insertions(+), 116 deletions(-) create mode 100644 src/app/Library/Support/DatatableCache.php create mode 100644 src/app/Library/Support/SetupCache.php diff --git a/src/app/Http/Controllers/Operations/ListOperation.php b/src/app/Http/Controllers/Operations/ListOperation.php index d6082fc4bd..1b2a00309c 100644 --- a/src/app/Http/Controllers/Operations/ListOperation.php +++ b/src/app/Http/Controllers/Operations/ListOperation.php @@ -4,6 +4,7 @@ use Backpack\CRUD\app\Library\CrudPanel\Hooks\Facades\LifecycleHook; use Illuminate\Support\Facades\Route; +use Backpack\CRUD\app\Library\Support\DatatableCache; trait ListOperation { @@ -78,7 +79,7 @@ public function search() // If there's a config closure in the cache for this CRUD, run that configuration closure. // This is done in order to allow the developer to configure the datatable component. - \Backpack\CRUD\app\View\Components\Datatable::applyCachedSetupClosure($this->crud); + $this->applyCachedDatatableSetup(); $this->crud->applyUnappliedFilters(); @@ -127,6 +128,16 @@ public function search() return $this->crud->getEntriesAsJsonForDatatables($entries, $totalEntryCount, $filteredEntryCount, $start); } + /** + * Apply the cached datatable setup configuration directly using DatatableCache. + * + * @return bool Whether the cached setup was successfully applied + */ + protected function applyCachedDatatableSetup() + { + return DatatableCache::instance()->applyFromRequest($this->crud); + } + /** * Used with AJAX in the list view (datatables) to show extra information about that row that didn't fit in the table. * It defaults to showing some dummy text. diff --git a/src/app/Library/Support/DatatableCache.php b/src/app/Library/Support/DatatableCache.php new file mode 100644 index 0000000000..7bb8206485 --- /dev/null +++ b/src/app/Library/Support/DatatableCache.php @@ -0,0 +1,196 @@ +cachePrefix = 'datatable_config_'; + $this->cacheDuration = 60; // 1 hour + } + + /** + * Get the instance of DatatableCache. + */ + public static function instance(): self + { + static $instance = null; + + if ($instance === null) { + $instance = new static(); + } + + return $instance; + } + + /** + * Cache setup closure for a datatable component. + * + * @param string $tableId The table ID to use as cache key + * @param string $controllerClass The controller class + * @param \Closure|null $setup The setup closure + * @param string|null $name The element name + * @param CrudPanel $crud The CRUD panel instance to update with datatable_id + * @return bool Whether the operation was successful + */ + public function cacheForComponent(string $tableId, string $controllerClass, ?\Closure $setup = null, ?string $name = null, ?CrudPanel $crud = null): bool + { + if (! $setup) { + return false; + } + + $cruds = CrudManager::getCrudPanels(); + $parentCrud = reset($cruds); + + if ($parentCrud && $parentCrud->getCurrentEntry()) { + $parentEntry = $parentCrud->getCurrentEntry(); + $parentController = $parentCrud->controller; + + // Store in cache + $this->store( + $tableId, + $controllerClass, + $parentController, + $parentEntry, + $name + ); + + // Set the datatable_id in the CRUD panel if provided + if ($crud) { + $crud->set('list.datatable_id', $tableId); + } + + return true; + } + + return false; + } + + /** + * Apply cached setup to a CRUD instance using the request's datatable_id. + * + * @param CrudPanel $crud The CRUD panel instance + * @return bool Whether the operation was successful + */ + public function applyFromRequest(CrudPanel $crud): bool + { + $tableId = request('datatable_id'); + + if (! $tableId) { + \Log::debug('Missing datatable_id in request parameters'); + return false; + } + + return $this->apply($tableId, $crud); + } + + /** + * Apply a setup closure to a CrudPanel instance. + * + * @param CrudPanel $crud The CRUD panel instance + * @param string $controllerClass The controller class + * @param \Closure $setupClosure The setup closure + * @param mixed $entry The entry to pass to the setup closure + * @return bool Whether the operation was successful + */ + public function applySetupClosure(CrudPanel $crud, string $controllerClass, \Closure $setupClosure, $entry = null): bool + { + $originalSetup = $setupClosure; + $modifiedSetup = function ($crud, $entry) use ($originalSetup, $controllerClass) { + CrudManager::setActiveController($controllerClass); + + // Run the original closure + return ($originalSetup)($crud, $entry); + }; + + try { + // Execute the modified closure + ($modifiedSetup)($crud, $entry); + + return true; + } finally { + // Clean up + CrudManager::unsetActiveController(); + } + } + + /** + * Prepare datatable data for storage in the cache. + * + * @param string $controllerClass The controller class + * @param string $parentController The parent controller + * @param mixed $parentEntry The parent entry + * @param string|null $elementName The element name + * @return array The data to be cached + */ + protected function prepareDataForStorage(...$args): array + { + [$controllerClass, $parentController, $parentEntry, $elementName] = $args; + + return [ + 'controller' => $controllerClass, + 'parentController' => $parentController, + 'parent_entry' => $parentEntry, + 'element_name' => $elementName, + 'operations' => CrudManager::getInitializedOperations($parentController), + ]; + } + + /** + * Apply data from the cache to configure a datatable. + * + * @param array $cachedData The cached data + * @param CrudPanel $crud The CRUD panel instance + * @return bool Whether the operation was successful + */ + protected function applyFromCache($cachedData, ...$args): bool + { + [$crud] = $args; + + try { + // Initialize operations for the parent controller + $this->initializeOperations($cachedData['parentController'], $cachedData['operations']); + $entry = $cachedData['parent_entry']; + $elementName = $cachedData['element_name']; + + $widgets = Widget::collection(); + $found = false; + + foreach ($widgets as $widget) { + if ($widget['type'] === 'datatable' && + (isset($widget['name']) && $widget['name'] === $elementName) && + (isset($widget['setup']) && $widget['setup'] instanceof \Closure)) { + + $this->applySetupClosure($crud, $cachedData['controller'], $widget['setup'], $entry); + $found = true; + break; + } + } + + return $found; + } catch (\Exception $e) { + \Log::error('Error applying cached datatable config: ' . $e->getMessage(), [ + 'exception' => $e, + ]); + return false; + } + } + + /** + * Initialize operations for a parent controller. + */ + private function initializeOperations(string $parentController, $operations): void + { + $parentCrud = CrudManager::setupCrudPanel($parentController); + + foreach ($operations as $operation) { + $parentCrud->initialized = false; + CrudManager::setupCrudPanel($parentController, $operation); + } + } +} \ No newline at end of file diff --git a/src/app/Library/Support/SetupCache.php b/src/app/Library/Support/SetupCache.php new file mode 100644 index 0000000000..6e791b6cfb --- /dev/null +++ b/src/app/Library/Support/SetupCache.php @@ -0,0 +1,108 @@ +cachePrefix . $identifier; + } + + /** + * Store data in the cache. + */ + public function store($identifier, ...$args) + { + $cacheKey = $this->generateCacheKey($identifier); + $data = $this->prepareDataForStorage(...$args); + + if ($data !== false && $data !== null) { + Cache::forget($cacheKey); + Cache::put($cacheKey, $data, now()->addMinutes($this->cacheDuration)); + return true; + } + + return false; + } + + /** + * Apply cached data. + */ + public function apply($identifier, ...$args) + { + $cacheKey = $this->generateCacheKey($identifier); + $cachedData = Cache::get($cacheKey); + + if (!$cachedData) { + return false; + } + + return $this->applyFromCache($cachedData, ...$args); + } + + /** + * Get cached data without applying it. + */ + public function get($identifier) + { + $cacheKey = $this->generateCacheKey($identifier); + return Cache::get($cacheKey); + } + + /** + * Check if cache exists for the given identifier. + */ + public function has($identifier): bool + { + $cacheKey = $this->generateCacheKey($identifier); + return Cache::has($cacheKey); + } + + /** + * Remove cached data. + */ + public function forget($identifier): bool + { + $cacheKey = $this->generateCacheKey($identifier); + return Cache::forget($cacheKey); + } + + /** + * Set the cache prefix. + */ + public function setCachePrefix(string $prefix): self + { + $this->cachePrefix = $prefix; + return $this; + } + + /** + * Set the cache duration in minutes. + */ + public function setCacheDuration(int $minutes): self + { + $this->cacheDuration = $minutes; + return $this; + } + + /** + * Prepare data for storage in the cache. + * This method should be implemented by child classes. + */ + abstract protected function prepareDataForStorage(...$args); + + /** + * Apply data from the cache. + * This method should be implemented by child classes. + */ + abstract protected function applyFromCache($cachedData, ...$args); +} \ No newline at end of file diff --git a/src/app/View/Components/Datatable.php b/src/app/View/Components/Datatable.php index e89a52a36b..6891dd4ccd 100644 --- a/src/app/View/Components/Datatable.php +++ b/src/app/View/Components/Datatable.php @@ -3,9 +3,8 @@ namespace Backpack\CRUD\app\View\Components; use Backpack\CRUD\app\Library\CrudPanel\CrudPanel; -use Backpack\CRUD\app\Library\Widget; +use Backpack\CRUD\app\Library\Support\DatatableCache; use Backpack\CRUD\CrudManager; -use Illuminate\Support\Facades\Cache; use Illuminate\View\Component; class Datatable extends Component @@ -27,9 +26,12 @@ public function __construct( $this->tableId = $this->generateTableId(); if ($this->setup) { - // Apply the configuration using the shared method - $this->applySetupClosure($this->crud, $this->controller, $this->setup, $this->getParentCrudEntry()); - $this->cacheSetupClosure(); + // Apply the configuration using DatatableCache + $cache = DatatableCache::instance(); + $cache->applySetupClosure($this->crud, $this->controller, $this->setup, $this->getParentCrudEntry()); + + // Cache the setup for later use + $cache->cacheForComponent($this->tableId, $this->controller, $this->setup, $this->name, $this->crud); } if (! $this->crud->has('list.datatablesUrl')) { @@ -40,27 +42,6 @@ public function __construct( CrudManager::unsetActiveController(); } - private function applySetupClosure(CrudPanel $crud, string $controllerClass, \Closure $setupClosure, $entry = null) - { - $originalSetup = $setupClosure; - $modifiedSetup = function ($crud, $entry) use ($originalSetup, $controllerClass) { - CrudManager::setActiveController($controllerClass); - - // Run the original closure - return ($originalSetup)($crud, $entry); - }; - - try { - // Execute the modified closure - ($modifiedSetup)($crud, $entry); - - return true; - } finally { - // Clean up - CrudManager::unsetActiveController(); - } - } - private function getParentCrudEntry() { $cruds = CrudManager::getCrudPanels(); @@ -87,94 +68,6 @@ private function generateTableId(): string return 'crudTable_'.$uniqueId; } - /** - * Store the datatable configuration in the cache for later use in Ajax requests. - */ - private function cacheSetupClosure() - { - if (! $this->setup) { - return; - } - - $controllerClass = $this->controller; - $cruds = CrudManager::getCrudPanels(); - $parentCrud = reset($cruds); - - if ($parentCrud && $parentCrud->getCurrentEntry()) { - $parentEntry = $parentCrud->getCurrentEntry(); - $parentController = $parentCrud->controller; - $cacheKey = 'datatable_config_'.$this->tableId; - - Cache::forget($cacheKey); - - // Store the controller class, parent entry, element type and name - Cache::put($cacheKey, [ - 'controller' => $controllerClass, - 'parentController' => $parentController, - 'parent_entry' => $parentEntry, - 'element_name' => $this->name, - 'operations' => CrudManager::getInitializedOperations($parentController), - ], now()->addHours(1)); - - $this->crud->set('list.datatable_id', $this->tableId); - } - } - - public static function applyCachedSetupClosure($crud) - { - $tableId = request('datatable_id'); - - if (! $tableId) { - \Log::debug('Missing datatable_id in request parameters'); - - return false; - } - - $cacheKey = 'datatable_config_'.$tableId; - $cachedData = Cache::get($cacheKey); - - if (! $cachedData) { - return false; - } - - try { - // Get the parent crud instance - self::initializeOperations($cachedData['parentController'], $cachedData['operations']); - $entry = $cachedData['parent_entry']; - $elementName = $cachedData['element_name']; - - $widgets = Widget::collection(); - - foreach ($widgets as $widget) { - if ($widget['type'] === 'datatable' && - (isset($widget['name']) && $widget['name'] === $elementName) && - (isset($widget['setup']) && $widget['setup'] instanceof \Closure)) { - $instance = new self($cachedData['controller']); - - $instance->applySetupClosure($crud, $cachedData['controller'], $widget['setup'], $entry); - } - } - - return false; - } catch (\Exception $e) { - \Log::error('Error applying cached datatable config: '.$e->getMessage(), [ - 'exception' => $e, - ]); - } - - return false; - } - - private static function initializeOperations(string $parentController, $operations) - { - $parentCrud = CrudManager::setupCrudPanel($parentController); - - foreach ($operations as $operation) { - $parentCrud->initialized = false; - CrudManager::setupCrudPanel($parentController, $operation); - } - } - public function render() { return view('crud::components.datatable.datatable', [ @@ -183,4 +76,4 @@ public function render() 'tableId' => $this->tableId, ]); } -} +} \ No newline at end of file From bb311c7bd0dc628abbfc512b1dd1b5e23bf494d7 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Fri, 6 Jun 2025 14:08:33 +0000 Subject: [PATCH 2/6] Apply fixes from StyleCI [ci skip] [skip ci] --- .../Controllers/Operations/ListOperation.php | 4 +- src/app/Library/Support/DatatableCache.php | 75 ++++++++++--------- src/app/Library/Support/SetupCache.php | 40 +++++----- src/app/View/Components/Datatable.php | 4 +- 4 files changed, 65 insertions(+), 58 deletions(-) diff --git a/src/app/Http/Controllers/Operations/ListOperation.php b/src/app/Http/Controllers/Operations/ListOperation.php index 1b2a00309c..ff571f6425 100644 --- a/src/app/Http/Controllers/Operations/ListOperation.php +++ b/src/app/Http/Controllers/Operations/ListOperation.php @@ -3,8 +3,8 @@ namespace Backpack\CRUD\app\Http\Controllers\Operations; use Backpack\CRUD\app\Library\CrudPanel\Hooks\Facades\LifecycleHook; -use Illuminate\Support\Facades\Route; use Backpack\CRUD\app\Library\Support\DatatableCache; +use Illuminate\Support\Facades\Route; trait ListOperation { @@ -130,7 +130,7 @@ public function search() /** * Apply the cached datatable setup configuration directly using DatatableCache. - * + * * @return bool Whether the cached setup was successfully applied */ protected function applyCachedDatatableSetup() diff --git a/src/app/Library/Support/DatatableCache.php b/src/app/Library/Support/DatatableCache.php index 7bb8206485..18ad2bd8cc 100644 --- a/src/app/Library/Support/DatatableCache.php +++ b/src/app/Library/Support/DatatableCache.php @@ -3,8 +3,8 @@ namespace Backpack\CRUD\app\Library\Support; use Backpack\CRUD\app\Library\CrudPanel\CrudPanel; -use Backpack\CRUD\CrudManager; use Backpack\CRUD\app\Library\Widget; +use Backpack\CRUD\CrudManager; class DatatableCache extends SetupCache { @@ -13,29 +13,29 @@ public function __construct() $this->cachePrefix = 'datatable_config_'; $this->cacheDuration = 60; // 1 hour } - + /** * Get the instance of DatatableCache. */ public static function instance(): self { static $instance = null; - + if ($instance === null) { $instance = new static(); } - + return $instance; } - + /** * Cache setup closure for a datatable component. - * - * @param string $tableId The table ID to use as cache key - * @param string $controllerClass The controller class - * @param \Closure|null $setup The setup closure - * @param string|null $name The element name - * @param CrudPanel $crud The CRUD panel instance to update with datatable_id + * + * @param string $tableId The table ID to use as cache key + * @param string $controllerClass The controller class + * @param \Closure|null $setup The setup closure + * @param string|null $name The element name + * @param CrudPanel $crud The CRUD panel instance to update with datatable_id * @return bool Whether the operation was successful */ public function cacheForComponent(string $tableId, string $controllerClass, ?\Closure $setup = null, ?string $name = null, ?CrudPanel $crud = null): bool @@ -50,7 +50,7 @@ public function cacheForComponent(string $tableId, string $controllerClass, ?\Cl if ($parentCrud && $parentCrud->getCurrentEntry()) { $parentEntry = $parentCrud->getCurrentEntry(); $parentController = $parentCrud->controller; - + // Store in cache $this->store( $tableId, @@ -70,11 +70,11 @@ public function cacheForComponent(string $tableId, string $controllerClass, ?\Cl return false; } - + /** * Apply cached setup to a CRUD instance using the request's datatable_id. - * - * @param CrudPanel $crud The CRUD panel instance + * + * @param CrudPanel $crud The CRUD panel instance * @return bool Whether the operation was successful */ public function applyFromRequest(CrudPanel $crud): bool @@ -83,19 +83,20 @@ public function applyFromRequest(CrudPanel $crud): bool if (! $tableId) { \Log::debug('Missing datatable_id in request parameters'); + return false; } return $this->apply($tableId, $crud); } - + /** * Apply a setup closure to a CrudPanel instance. - * - * @param CrudPanel $crud The CRUD panel instance - * @param string $controllerClass The controller class - * @param \Closure $setupClosure The setup closure - * @param mixed $entry The entry to pass to the setup closure + * + * @param CrudPanel $crud The CRUD panel instance + * @param string $controllerClass The controller class + * @param \Closure $setupClosure The setup closure + * @param mixed $entry The entry to pass to the setup closure * @return bool Whether the operation was successful */ public function applySetupClosure(CrudPanel $crud, string $controllerClass, \Closure $setupClosure, $entry = null): bool @@ -118,20 +119,20 @@ public function applySetupClosure(CrudPanel $crud, string $controllerClass, \Clo CrudManager::unsetActiveController(); } } - + /** * Prepare datatable data for storage in the cache. - * - * @param string $controllerClass The controller class - * @param string $parentController The parent controller - * @param mixed $parentEntry The parent entry - * @param string|null $elementName The element name + * + * @param string $controllerClass The controller class + * @param string $parentController The parent controller + * @param mixed $parentEntry The parent entry + * @param string|null $elementName The element name * @return array The data to be cached */ protected function prepareDataForStorage(...$args): array { [$controllerClass, $parentController, $parentEntry, $elementName] = $args; - + return [ 'controller' => $controllerClass, 'parentController' => $parentController, @@ -140,18 +141,18 @@ protected function prepareDataForStorage(...$args): array 'operations' => CrudManager::getInitializedOperations($parentController), ]; } - + /** * Apply data from the cache to configure a datatable. - * - * @param array $cachedData The cached data - * @param CrudPanel $crud The CRUD panel instance + * + * @param array $cachedData The cached data + * @param CrudPanel $crud The CRUD panel instance * @return bool Whether the operation was successful */ protected function applyFromCache($cachedData, ...$args): bool { [$crud] = $args; - + try { // Initialize operations for the parent controller $this->initializeOperations($cachedData['parentController'], $cachedData['operations']); @@ -165,7 +166,6 @@ protected function applyFromCache($cachedData, ...$args): bool if ($widget['type'] === 'datatable' && (isset($widget['name']) && $widget['name'] === $elementName) && (isset($widget['setup']) && $widget['setup'] instanceof \Closure)) { - $this->applySetupClosure($crud, $cachedData['controller'], $widget['setup'], $entry); $found = true; break; @@ -174,13 +174,14 @@ protected function applyFromCache($cachedData, ...$args): bool return $found; } catch (\Exception $e) { - \Log::error('Error applying cached datatable config: ' . $e->getMessage(), [ + \Log::error('Error applying cached datatable config: '.$e->getMessage(), [ 'exception' => $e, ]); + return false; } } - + /** * Initialize operations for a parent controller. */ @@ -193,4 +194,4 @@ private function initializeOperations(string $parentController, $operations): vo CrudManager::setupCrudPanel($parentController, $operation); } } -} \ No newline at end of file +} diff --git a/src/app/Library/Support/SetupCache.php b/src/app/Library/Support/SetupCache.php index 6e791b6cfb..b7aa259636 100644 --- a/src/app/Library/Support/SetupCache.php +++ b/src/app/Library/Support/SetupCache.php @@ -8,15 +8,15 @@ abstract class SetupCache { protected string $cachePrefix = 'setup_cache_'; protected int $cacheDuration = 60; // minutes - + /** * Generate a cache key for the given identifier. */ protected function generateCacheKey($identifier): string { - return $this->cachePrefix . $identifier; + return $this->cachePrefix.$identifier; } - + /** * Store data in the cache. */ @@ -24,16 +24,17 @@ public function store($identifier, ...$args) { $cacheKey = $this->generateCacheKey($identifier); $data = $this->prepareDataForStorage(...$args); - + if ($data !== false && $data !== null) { Cache::forget($cacheKey); Cache::put($cacheKey, $data, now()->addMinutes($this->cacheDuration)); + return true; } - + return false; } - + /** * Apply cached data. */ @@ -41,68 +42,73 @@ public function apply($identifier, ...$args) { $cacheKey = $this->generateCacheKey($identifier); $cachedData = Cache::get($cacheKey); - - if (!$cachedData) { + + if (! $cachedData) { return false; } - + return $this->applyFromCache($cachedData, ...$args); } - + /** * Get cached data without applying it. */ public function get($identifier) { $cacheKey = $this->generateCacheKey($identifier); + return Cache::get($cacheKey); } - + /** * Check if cache exists for the given identifier. */ public function has($identifier): bool { $cacheKey = $this->generateCacheKey($identifier); + return Cache::has($cacheKey); } - + /** * Remove cached data. */ public function forget($identifier): bool { $cacheKey = $this->generateCacheKey($identifier); + return Cache::forget($cacheKey); } - + /** * Set the cache prefix. */ public function setCachePrefix(string $prefix): self { $this->cachePrefix = $prefix; + return $this; } - + /** * Set the cache duration in minutes. */ public function setCacheDuration(int $minutes): self { $this->cacheDuration = $minutes; + return $this; } - + /** * Prepare data for storage in the cache. * This method should be implemented by child classes. */ abstract protected function prepareDataForStorage(...$args); - + /** * Apply data from the cache. * This method should be implemented by child classes. */ abstract protected function applyFromCache($cachedData, ...$args); -} \ No newline at end of file +} diff --git a/src/app/View/Components/Datatable.php b/src/app/View/Components/Datatable.php index 6891dd4ccd..1b53e5f41b 100644 --- a/src/app/View/Components/Datatable.php +++ b/src/app/View/Components/Datatable.php @@ -29,7 +29,7 @@ public function __construct( // Apply the configuration using DatatableCache $cache = DatatableCache::instance(); $cache->applySetupClosure($this->crud, $this->controller, $this->setup, $this->getParentCrudEntry()); - + // Cache the setup for later use $cache->cacheForComponent($this->tableId, $this->controller, $this->setup, $this->name, $this->crud); } @@ -76,4 +76,4 @@ public function render() 'tableId' => $this->tableId, ]); } -} \ No newline at end of file +} From a76362acc79dc7c0e9aaa6d181141d48e44900e9 Mon Sep 17 00:00:00 2001 From: pxpm Date: Mon, 9 Jun 2025 10:44:21 +0100 Subject: [PATCH 3/6] wip --- .../Controllers/Operations/ListOperation.php | 2 +- src/app/Library/Support/DatatableCache.php | 38 +++++++++++-------- src/app/View/Components/Datatable.php | 12 ++++-- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/app/Http/Controllers/Operations/ListOperation.php b/src/app/Http/Controllers/Operations/ListOperation.php index ff571f6425..743e61805e 100644 --- a/src/app/Http/Controllers/Operations/ListOperation.php +++ b/src/app/Http/Controllers/Operations/ListOperation.php @@ -135,7 +135,7 @@ public function search() */ protected function applyCachedDatatableSetup() { - return DatatableCache::instance()->applyFromRequest($this->crud); + return DatatableCache::applyFromRequest($this->crud); } /** diff --git a/src/app/Library/Support/DatatableCache.php b/src/app/Library/Support/DatatableCache.php index 18ad2bd8cc..767c4200be 100644 --- a/src/app/Library/Support/DatatableCache.php +++ b/src/app/Library/Support/DatatableCache.php @@ -14,20 +14,6 @@ public function __construct() $this->cacheDuration = 60; // 1 hour } - /** - * Get the instance of DatatableCache. - */ - public static function instance(): self - { - static $instance = null; - - if ($instance === null) { - $instance = new static(); - } - - return $instance; - } - /** * Cache setup closure for a datatable component. * @@ -71,14 +57,34 @@ public function cacheForComponent(string $tableId, string $controllerClass, ?\Cl return false; } + public static function applyAndStoreSetupClosure( + string $tableId, + string $controllerClass, + \Closure $setupClosure, + ?string $name = null, + ?CrudPanel $crud = null, + $parentEntry = null + ): bool { + $instance = new self(); + // Cache the setup closure for the datatable component + if ($instance->applySetupClosure($crud, $controllerClass, $setupClosure, $parentEntry)) { + // Apply the setup closure to the CrudPanel instance + return $instance->cacheForComponent($tableId, $controllerClass, $setupClosure, $name, $crud); + } + + return false; + } + /** * Apply cached setup to a CRUD instance using the request's datatable_id. * * @param CrudPanel $crud The CRUD panel instance * @return bool Whether the operation was successful */ - public function applyFromRequest(CrudPanel $crud): bool + public static function applyFromRequest(CrudPanel $crud): bool { + $instance = new self(); + // Check if the request has a datatable_id parameter $tableId = request('datatable_id'); if (! $tableId) { @@ -87,7 +93,7 @@ public function applyFromRequest(CrudPanel $crud): bool return false; } - return $this->apply($tableId, $crud); + return $instance->apply($tableId, $crud); } /** diff --git a/src/app/View/Components/Datatable.php b/src/app/View/Components/Datatable.php index 1b53e5f41b..ddd5f9fd4e 100644 --- a/src/app/View/Components/Datatable.php +++ b/src/app/View/Components/Datatable.php @@ -27,11 +27,15 @@ public function __construct( if ($this->setup) { // Apply the configuration using DatatableCache - $cache = DatatableCache::instance(); - $cache->applySetupClosure($this->crud, $this->controller, $this->setup, $this->getParentCrudEntry()); + DatatableCache::applyAndStoreSetupClosure( + $this->tableId, + $this->controller, + $this->setup, + $this->name, + $this->crud, + $this->getParentCrudEntry() + ); - // Cache the setup for later use - $cache->cacheForComponent($this->tableId, $this->controller, $this->setup, $this->name, $this->crud); } if (! $this->crud->has('list.datatablesUrl')) { From 2df96ae8c61323cf5b49fc4c578843389cc1df77 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Mon, 9 Jun 2025 09:44:40 +0000 Subject: [PATCH 4/6] Apply fixes from StyleCI [ci skip] [skip ci] --- src/app/View/Components/Datatable.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/View/Components/Datatable.php b/src/app/View/Components/Datatable.php index ddd5f9fd4e..b906c1be04 100644 --- a/src/app/View/Components/Datatable.php +++ b/src/app/View/Components/Datatable.php @@ -35,7 +35,6 @@ public function __construct( $this->crud, $this->getParentCrudEntry() ); - } if (! $this->crud->has('list.datatablesUrl')) { From cba3a71bd31ea07be75fd716a07f5d7c238e24b9 Mon Sep 17 00:00:00 2001 From: pxpm Date: Mon, 9 Jun 2025 10:45:00 +0100 Subject: [PATCH 5/6] make it final! --- src/app/Library/Support/DatatableCache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/Library/Support/DatatableCache.php b/src/app/Library/Support/DatatableCache.php index 767c4200be..9912436a38 100644 --- a/src/app/Library/Support/DatatableCache.php +++ b/src/app/Library/Support/DatatableCache.php @@ -6,7 +6,7 @@ use Backpack\CRUD\app\Library\Widget; use Backpack\CRUD\CrudManager; -class DatatableCache extends SetupCache +final class DatatableCache extends SetupCache { public function __construct() { From afc14539031d01d88e8af9786cd82558c6d436d6 Mon Sep 17 00:00:00 2001 From: pxpm Date: Mon, 9 Jun 2025 10:52:53 +0100 Subject: [PATCH 6/6] remove intermediary function --- .../Http/Controllers/Operations/ListOperation.php | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/app/Http/Controllers/Operations/ListOperation.php b/src/app/Http/Controllers/Operations/ListOperation.php index 743e61805e..f04a542568 100644 --- a/src/app/Http/Controllers/Operations/ListOperation.php +++ b/src/app/Http/Controllers/Operations/ListOperation.php @@ -79,7 +79,7 @@ public function search() // If there's a config closure in the cache for this CRUD, run that configuration closure. // This is done in order to allow the developer to configure the datatable component. - $this->applyCachedDatatableSetup(); + DatatableCache::applyFromRequest($this->crud); $this->crud->applyUnappliedFilters(); @@ -128,16 +128,6 @@ public function search() return $this->crud->getEntriesAsJsonForDatatables($entries, $totalEntryCount, $filteredEntryCount, $start); } - /** - * Apply the cached datatable setup configuration directly using DatatableCache. - * - * @return bool Whether the cached setup was successfully applied - */ - protected function applyCachedDatatableSetup() - { - return DatatableCache::applyFromRequest($this->crud); - } - /** * Used with AJAX in the list view (datatables) to show extra information about that row that didn't fit in the table. * It defaults to showing some dummy text.