Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Passed
Push — datatable-single-component ( 0a47c0...3b89f2 )
by Pedro
11:14
created

Datatable::applyCachedSetupClosure()   B

Complexity

Conditions 10
Paths 14

Size

Total Lines 43
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 24
nc 14
nop 1
dl 0
loc 43
rs 7.6666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Backpack\CRUD\app\View\Components;
4
5
use Backpack\CRUD\app\Library\CrudPanel\CrudPanel;
6
use Backpack\CRUD\app\Library\Widget;
7
use Backpack\CRUD\CrudManager;
8
use Illuminate\Support\Facades\Cache;
9
use Illuminate\View\Component;
10
11
class Datatable extends Component
12
{
13
    protected string $tableId;
14
15
    public function __construct(
16
        private string $controller,
17
        private ?CrudPanel $crud = null,
18
        private bool $modifiesUrl = false,
19
        private ?\Closure $setup = null,
20
        private ?string $name = null,
21
    ) {
22
        // Set active controller for proper context
23
        CrudManager::setActiveController($controller);
0 ignored issues
show
Bug introduced by
The method setActiveController() does not exist on Backpack\CRUD\CrudManager. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

23
        CrudManager::/** @scrutinizer ignore-call */ 
24
                     setActiveController($controller);
Loading history...
24
25
        $this->crud ??= CrudManager::setupCrudPanel($controller, 'list');
0 ignored issues
show
Bug introduced by
The method setupCrudPanel() does not exist on Backpack\CRUD\CrudManager. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

25
        $this->crud ??= CrudManager::/** @scrutinizer ignore-call */ setupCrudPanel($controller, 'list');
Loading history...
26
27
        $this->tableId = $this->generateTableId();
28
29
        if ($this->setup) {
30
            // Apply the configuration using the shared method
31
            $this->applySetupClosure($this->crud, $this->controller, $this->setup, $this->getParentCrudEntry());
0 ignored issues
show
Bug introduced by
It seems like $this->crud can also be of type null; however, parameter $crud of Backpack\CRUD\app\View\C...le::applySetupClosure() does only seem to accept Backpack\CRUD\app\Library\CrudPanel\CrudPanel, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

31
            $this->applySetupClosure(/** @scrutinizer ignore-type */ $this->crud, $this->controller, $this->setup, $this->getParentCrudEntry());
Loading history...
32
            $this->cacheSetupClosure();
33
        }
34
35
        if (! $this->crud->has('list.datatablesUrl')) {
0 ignored issues
show
Bug introduced by
The method has() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

35
        if (! $this->crud->/** @scrutinizer ignore-call */ has('list.datatablesUrl')) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
36
            $this->crud->set('list.datatablesUrl', $this->crud->getRoute());
37
        }
38
39
        // Reset the active controller
40
        CrudManager::unsetActiveController();
0 ignored issues
show
Bug introduced by
The method unsetActiveController() does not exist on Backpack\CRUD\CrudManager. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

40
        CrudManager::/** @scrutinizer ignore-call */ 
41
                     unsetActiveController();
Loading history...
41
    }
42
43
    private function applySetupClosure(CrudPanel $crud, string $controllerClass, \Closure $setupClosure, $entry = null)
44
    {
45
        $originalSetup = $setupClosure;
46
        $modifiedSetup = function ($crud, $entry) use ($originalSetup, $controllerClass) {
47
            CrudManager::setActiveController($controllerClass);
48
49
            // Run the original closure
50
            return ($originalSetup)($crud, $entry);
51
        };
52
53
        try {
54
            // Execute the modified closure
55
            ($modifiedSetup)($crud, $entry);
56
57
            return true;
58
        } finally {
59
            // Clean up
60
            CrudManager::unsetActiveController();
61
        }
62
    }
63
64
    private function getParentCrudEntry()
65
    {
66
        $cruds = CrudManager::getCrudPanels();
0 ignored issues
show
Bug introduced by
The method getCrudPanels() does not exist on Backpack\CRUD\CrudManager. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

66
        /** @scrutinizer ignore-call */ 
67
        $cruds = CrudManager::getCrudPanels();
Loading history...
67
        $parentCrud = reset($cruds);
68
69
        if ($parentCrud && $parentCrud->getCurrentEntry()) {
70
            CrudManager::storeInitializedOperation(
0 ignored issues
show
Bug introduced by
The method storeInitializedOperation() does not exist on Backpack\CRUD\CrudManager. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

70
            CrudManager::/** @scrutinizer ignore-call */ 
71
                         storeInitializedOperation(
Loading history...
71
                $parentCrud->controller,
72
                $parentCrud->getCurrentOperation()
73
            );
74
75
            return $parentCrud->getCurrentEntry();
76
        }
77
78
        return null;
79
    }
80
81
    private function generateTableId(): string
82
    {
83
        $controllerPart = str_replace('\\', '_', $this->controller);
84
        $namePart = $this->name ?? 'default';
85
        $uniqueId = md5($controllerPart.'_'.$namePart);
86
87
        return 'crudTable_'.$uniqueId;
88
    }
89
90
    /**
91
     * Store the datatable configuration in the cache for later use in Ajax requests.
92
     */
93
    private function cacheSetupClosure()
94
    {
95
        if (! $this->setup) {
96
            return;
97
        }
98
99
        $controllerClass = $this->controller;
100
        $cruds = CrudManager::getCrudPanels();
101
        $parentCrud = reset($cruds);
102
103
        if ($parentCrud && $parentCrud->getCurrentEntry()) {
104
            $parentEntry = $parentCrud->getCurrentEntry();
105
            $parentController = $parentCrud->controller;
106
            $cacheKey = 'datatable_config_'.$this->tableId;
107
108
            Cache::forget($cacheKey);
109
110
            // Store the controller class, parent entry, element type and name
111
            Cache::put($cacheKey, [
112
                'controller' => $controllerClass,
113
                'parentController' => $parentController,
114
                'parent_entry' => $parentEntry,
115
                'element_name' => $this->name,
116
                'operations' => CrudManager::getInitializedOperations($parentController),
0 ignored issues
show
Bug introduced by
The method getInitializedOperations() does not exist on Backpack\CRUD\CrudManager. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

116
                'operations' => CrudManager::/** @scrutinizer ignore-call */ getInitializedOperations($parentController),
Loading history...
117
            ], now()->addHours(1));
118
119
            $this->crud->set('list.datatable_id', $this->tableId);
120
        }
121
    }
122
123
    public static function applyCachedSetupClosure($crud)
124
    {
125
        $tableId = request('datatable_id');
126
127
        if (! $tableId) {
128
            \Log::debug('Missing datatable_id in request parameters');
129
130
            return false;
131
        }
132
133
        $cacheKey = 'datatable_config_'.$tableId;
134
        $cachedData = Cache::get($cacheKey);
135
136
        if (! $cachedData) {
137
            return false;
138
        }
139
140
        try {
141
            // Get the parent crud instance
142
            self::initializeOperations($cachedData['parentController'], $cachedData['operations']);
143
            $entry = $cachedData['parent_entry'];
144
            $elementName = $cachedData['element_name'];
145
146
            $widgets = Widget::collection();
147
148
            foreach ($widgets as $widget) {
149
                if ($widget['type'] === 'datatable' &&
150
                    (isset($widget['name']) && $widget['name'] === $elementName) &&
151
                    (isset($widget['setup']) && $widget['setup'] instanceof \Closure)) {
152
                    $instance = new self($cachedData['controller']);
153
154
                    $instance->applySetupClosure($crud, $cachedData['controller'], $widget['setup'], $entry);
155
                }
156
            }
157
158
            return false;
159
        } catch (\Exception $e) {
160
            \Log::error('Error applying cached datatable config: '.$e->getMessage(), [
161
                'exception' => $e,
162
            ]);
163
        }
164
165
        return false;
166
    }
167
168
    private static function initializeOperations(string $parentController, $operations)
169
    {
170
        $parentCrud = CrudManager::setupCrudPanel($parentController);
171
172
        foreach ($operations as $operation) {
173
            $parentCrud->initialized = false;
174
            CrudManager::setupCrudPanel($parentController, $operation);
175
        }
176
    }
177
178
    public function render()
179
    {
180
        return view('crud::components.datatable.datatable', [
181
            'crud' => $this->crud,
182
            'modifiesUrl' => $this->modifiesUrl,
183
            'tableId' => $this->tableId,
184
        ]);
185
    }
186
}
187