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 Setup Failed
Pull Request — master (#3981)
by Cristian
12:34
created

FetchOperation::setupFetchOperationRoutes()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 3
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Backpack\CRUD\app\Http\Controllers\Operations;
4
5
use Illuminate\Support\Facades\Route;
6
use Illuminate\Support\Str;
7
8
trait FetchOperation
9
{
10
    /**
11
     * Define which routes are needed for this operation.
12
     *
13
     * @param  string  $segment  Name of the current entity (singular). Used as first URL segment.
14
     * @param  string  $routeName  Prefix of the route name.
15
     * @param  string  $controller  Name of the current CrudController.
16
     */
17
    protected function setupFetchOperationRoutes($segment, $routeName, $controller)
18
    {
19
        // get all method names on the current model that start with "fetch" (ex: fetchCategory)
20
        // if a method that looks like that is present, it means we need to add the routes that fetch that entity
21
        preg_match_all('/(?<=^|;)fetch([^;]+?)(;|$)/', implode(';', get_class_methods($this)), $matches);
22
23
        if (count($matches[1])) {
24
            foreach ($matches[1] as $methodName) {
25
                Route::post($segment.'/fetch/'.Str::kebab($methodName), [
26
                    'as'        => $segment.'.fetch'.Str::studly($methodName),
27
                    'uses'      => $controller.'@fetch'.$methodName,
28
                    'operation' => 'FetchOperation',
29
                ]);
30
            }
31
        }
32
    }
33
34
    /**
35
     * Gets items from database and returns to selects.
36
     *
37
     * @param  string|array  $arg
38
     * @return \Illuminate\Http\JsonResponse|Illuminate\Database\Eloquent\Collection|Illuminate\Pagination\LengthAwarePaginator
0 ignored issues
show
Bug introduced by
The type Backpack\CRUD\app\Http\C...on\LengthAwarePaginator was not found. Did you mean Illuminate\Pagination\LengthAwarePaginator? If so, make sure to prefix the type with \.
Loading history...
Bug introduced by
The type Backpack\CRUD\app\Http\C...ase\Eloquent\Collection was not found. Did you mean Illuminate\Database\Eloquent\Collection? If so, make sure to prefix the type with \.
Loading history...
39
     */
40
    private function fetch($arg)
41
    {
42
        // get the actual words that were used to search for an item (the search term / search string)
43
        $search_string = request()->input('q') ?? false;
44
45
        // if the Class was passed as the sole argument, use that as the configured Model
46
        // otherwise assume the arguments are actually the configuration array
47
        $config = [];
48
49
        if (! is_array($arg)) {
50
            if (! class_exists($arg)) {
51
                return response()->json(['error' => 'Class: '.$arg.' does not exists'], 500);
52
            }
53
            $config['model'] = $arg;
54
        } else {
55
            $config = $arg;
56
        }
57
58
        $model_instance = new $config['model'];
59
        // set configuration defaults
60
        $config['paginate'] = isset($config['paginate']) ? $config['paginate'] : 10;
61
        $config['searchable_attributes'] = $config['searchable_attributes'] ?? $model_instance->identifiableAttribute();
62
        $config['query'] = isset($config['query']) && is_callable($config['query']) ? $config['query']($model_instance) : $model_instance; // if a closure that has been passed as "query", use the closure - otherwise use the model
63
64
        // FetchOperation sends an empty query to retrieve the default entry for select when field is not nullable.
65
        // Also sends an empty query in case we want to load all entities to emulate non-ajax fields
66
        // when using InlineCreate.
67
68
        if ($search_string === false) {
69
            return ($config['paginate'] !== false) ?
70
            $config['query']->paginate($config['paginate']) :
71
            $config['query']->get();
72
        }
73
74
        $textColumnTypes = ['string', 'json_string', 'text', 'longText', 'json_array', 'json'];
75
76
        // if the query builder brings any where clause already defined by the user we must
77
        // ensure that the where prevails and we should only use our search as a complement to the query constraints.
78
        // e.g user want only the active products, so in fetch they would return something like:
79
        // .... 'query' => function($model) { return $model->where('active', 1); }
80
        // So it reads: SELECT ... WHERE active = 1 AND (XXX = x OR YYY = y) and not SELECT ... WHERE active = 1 AND XXX = x OR YYY = y;
81
82
        if (! empty($config['query']->getQuery()->wheres)) {
83
            $config['query'] = $config['query']->where(function ($query) use ($model_instance, $config, $search_string, $textColumnTypes) {
84
                foreach ((array) $config['searchable_attributes'] as $k => $searchColumn) {
85
                    $operation = ($k == 0) ? 'where' : 'orWhere';
86
                    $columnType = $model_instance->getColumnType($searchColumn);
87
88
                    if (in_array($columnType, $textColumnTypes)) {
89
                        $tempQuery = $query->{$operation}($searchColumn, 'LIKE', '%'.$search_string.'%');
90
                    } else {
91
                        $tempQuery = $query->{$operation}($searchColumn, $search_string);
92
                    }
93
                }
94
                // If developer provide an empty searchable_attributes array it means they don't want us to search
95
                // in any specific column, or try to guess the column from model identifiableAttribute.
96
                // In that scenario we will not have any $tempQuery here, so we just return the query, is up to the developer
97
                // to do their own search.
98
                return $tempQuery ?? $query;
99
            });
100
        } else {
101
            foreach ((array) $config['searchable_attributes'] as $k => $searchColumn) {
102
                $operation = ($k == 0) ? 'where' : 'orWhere';
103
                $columnType = $model_instance->getColumnType($searchColumn);
104
105
                if (in_array($columnType, $textColumnTypes)) {
106
                    $config['query'] = $config['query']->{$operation}($searchColumn, 'LIKE', '%'.$search_string.'%');
107
                } else {
108
                    $config['query'] = $config['query']->{$operation}($searchColumn, $search_string);
109
                }
110
            }
111
        }
112
113
        // return the results with or without pagination
114
        return ($config['paginate'] !== false) ?
115
                    $config['query']->paginate($config['paginate']) :
116
                    $config['query']->get();
117
    }
118
}
119