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

Test Failed
Push — datatable-single-component ( c12786...e77738 )
by Pedro
10:32
created

Datatable::getParentCrudEntry()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 3
eloc 8
c 1
b 1
f 0
nc 2
nop 0
dl 0
loc 15
rs 10
1
<?php
2
3
namespace Backpack\CRUD\app\Library\Datatable;
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\Librar...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
          
48
            CrudManager::setActiveController($controllerClass);            
49
            // Run the original closure
50
            return ($originalSetup)($crud, $entry);
51
        };
52
        
53
        try {
54
            // Execute the modified closure
55
            ($modifiedSetup)($crud, $entry);
56
            return true;
57
        } finally {
58
            // Clean up
59
            CrudManager::unsetActiveController();
60
        }
61
    }
62
63
    private function getParentCrudEntry()
64
    {
65
        $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

65
        /** @scrutinizer ignore-call */ 
66
        $cruds = CrudManager::getCrudPanels();
Loading history...
66
        $parentCrud = reset($cruds);
67
68
        if ($parentCrud && $parentCrud->getCurrentEntry()) {
69
            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

69
            CrudManager::/** @scrutinizer ignore-call */ 
70
                         storeInitializedOperation(
Loading history...
70
                $parentCrud->controller,
71
                $parentCrud->getCurrentOperation()
72
            );
73
74
            return $parentCrud->getCurrentEntry();
75
        }
76
77
        return null;
78
    }
79
80
    private function generateTableId(): string
81
    {
82
        $controllerPart = str_replace('\\', '_', $this->controller);
83
        $namePart = $this->name ?? 'default';
84
        $uniqueId = md5($controllerPart.'_'.$namePart);
85
86
        return 'crudTable_'.$uniqueId;
87
    }
88
89
    /**
90
     * Store the datatable configuration in the cache for later use in Ajax requests.
91
     */
92
    private function cacheSetupClosure()
93
    {
94
        if (! $this->setup) {
95
            return;
96
        }
97
98
        $controllerClass = $this->controller;
99
        $cruds = CrudManager::getCrudPanels();
100
        $parentCrud = reset($cruds);
101
102
        if ($parentCrud && $parentCrud->getCurrentEntry()) {
103
            $parentEntry = $parentCrud->getCurrentEntry();
104
            $parentController = $parentCrud->controller;
105
            $cacheKey = 'datatable_config_'.$this->tableId;
106
107
            Cache::forget($cacheKey);
108
109
            // Store the controller class, parent entry, element type and name
110
            Cache::put($cacheKey, [
111
                'controller' => $controllerClass,
112
                'parentController' => $parentController,
113
                'parent_entry' => $parentEntry,
114
                'element_name' => $this->name,
115
                '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

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