Passed
Push — master ( 6bbf15...aead9d )
by Jonathan
19:29
created

Uccello::getDatatableColumns()   D

Complexity

Conditions 15
Paths 219

Size

Total Lines 75
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 41
c 2
b 0
f 0
dl 0
loc 75
rs 4.8458
cc 15
nc 219
nop 3

How to fix   Long Method    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 Uccello\Core\Helpers;
4
5
use Illuminate\Support\Collection;
0 ignored issues
show
Bug introduced by
The type Illuminate\Support\Collection was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use Illuminate\Support\Facades\Auth;
0 ignored issues
show
Bug introduced by
The type Illuminate\Support\Facades\Auth was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use Illuminate\Support\Facades\Cache;
0 ignored issues
show
Bug introduced by
The type Illuminate\Support\Facades\Cache was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Uccello\Core\Models\Domain;
9
use Uccello\Core\Models\Module;
10
use Uccello\Core\Models\Uitype;
11
use Uccello\Core\Models\Displaytype;
12
use Uccello\Core\Models\Capability;
13
use Uccello\Core\Models\Entity;
14
use Uccello\Core\Models\Filter;
15
16
class Uccello
17
{
18
    /**
19
     * Returns true if multi domains are used, false else.
20
     *
21
     * @return void
22
     */
23
    public function useMultiDomains()
24
    {
25
        return env('UCCELLO_MULTI_DOMAINS', true) !== false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return env('UCCELLO_MULT...MAINS', true) !== false returns the type boolean which is incompatible with the documented return type void.
Loading history...
Bug introduced by
The function env was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

25
        return /** @scrutinizer ignore-call */ env('UCCELLO_MULTI_DOMAINS', true) !== false;
Loading history...
26
    }
27
28
    /**
29
     * Retrieve prefix and translate the given message.
30
     * If the translation does not exist try to find a default one.
31
     * If no translation exists display only the key.
32
     *
33
     * Priority:
34
     * 1 - Translation overrided in app
35
     * 2 - Translation in package
36
     * 3 - Default translation overrided in app
37
     * 4 - Default translation in uccello
38
     * 5 - No translation
39
     *
40
     * @param  string  $key
41
     * @param  Module|null  $module
42
     * @param  array   $replace
43
     * @param  string  $locale
44
     * @return \Illuminate\Contracts\Translation\Translator|string|array|null
0 ignored issues
show
Bug introduced by
The type Illuminate\Contracts\Translation\Translator was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
45
     */
46
    public function trans($key = null, ?Module $module = null, $replace = [ ], $locale = null)
47
    {
48
        $translator = app('translator');
0 ignored issues
show
Bug introduced by
The function app was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

48
        $translator = /** @scrutinizer ignore-call */ app('translator');
Loading history...
49
50
        if (is_null($key)) {
51
            return $translator;
52
        }
53
54
        // If $module is an instance of Module class, add a prefix before the key
55
        if (!is_null($module) && Module::class == get_class($module))
56
        {
57
            // By default prefix is same as the module's name
58
            $prefix = $module->name.'.';
59
60
            // 1. Get translation in app
61
            $translation = $translator->trans($prefix.$key, $replace, $locale);
62
63
            if ($translation !== $prefix.$key) {
64
                return $translation;
65
            }
66
67
            // 2. Get translation in package
68
            if (!empty($module->package)) {
69
                // If a package name is defined add it before
70
                $prefix = $module->package.'::'.$prefix;
71
72
                $translation = $translator->trans($prefix.$key, $replace, $locale);
73
                if ($translation !== $prefix.$key) {
74
                    return $translation;
75
                }
76
            }
77
78
            // 3. Try with default translation in app
79
            $appDefaultTranslation = $translator->trans('default.'.$key, $replace, $locale);
80
            if ($appDefaultTranslation !== 'default.'.$key) { // If default translation exists then use it
81
                return $appDefaultTranslation;
82
            }
83
84
            // 4. Try with default translation in uccello
85
            $uccelloDefaultTranslation = $translator->trans('uccello::default.'.$key, $replace, $locale);
86
            if ($uccelloDefaultTranslation !== 'uccello::default.'.$key) { // If default translation exists then use it
87
                return $uccelloDefaultTranslation;
88
            }
89
90
            // 5. If translation does not exist, display only the key
91
            return $key;
92
        }
93
94
        // Default behaviour
95
        return $translator->trans($key, $replace, $locale);
96
    }
97
98
    /**
99
     * Detects which view it must use and returns the evaluated view contents.
100
     *
101
     * Priority:
102
     * 1 - Module view overrided in app
103
     * 2 - Default view overrided in app
104
     * 3 - Module view ovverrided in package
105
     * 4 - Default view defined in package
106
     * 5 - Module view ovverrided in uccello
107
     * 6 - Default view defined in uccello
108
     * 7 - Fallback view if defined
109
     *
110
     * @param string $package
111
     * @param Module $module
112
     * @param string $viewName
113
     * @param string|null $fallbackView
114
     * @return string|null
115
     */
116
    public function view(string $package, Module $module, string $viewName, ?string $fallbackView = null): ?string
117
    {
118
        // Module view overrided in app
119
        $appModuleView = 'uccello.modules.'.$module->name.'.'.$viewName;
120
121
        // Default view overrided in app
122
        $appDefaultView = 'uccello.modules.default.'.$viewName;
123
124
        // Module view ovverrided in package
125
        $packageModuleView = $package.'::modules.'.$module->name.'.'.$viewName;
126
127
        // Default view defined in package
128
        $packageDefaultView = $package.'::modules.default.'.$viewName;
129
130
        // Module view ovverrided in uccello
131
        $uccelloModuleView = 'uccello::modules.'.$module->name.'.'.$viewName;
132
133
        // Default view defined in uccello
134
        $uccelloDefaultView = 'uccello::modules.default.'.$viewName;
135
136
        $viewToInclude = null;
137
        if (view()->exists($appModuleView)) {
0 ignored issues
show
Bug introduced by
The function view was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

137
        if (/** @scrutinizer ignore-call */ view()->exists($appModuleView)) {
Loading history...
138
            $viewToInclude = $appModuleView;
139
        } elseif (view()->exists($appDefaultView)) {
140
            $viewToInclude = $appDefaultView;
141
        } elseif (view()->exists($packageModuleView)) {
142
            $viewToInclude = $packageModuleView;
143
        } elseif (view()->exists($packageDefaultView)) {
144
            $viewToInclude = $packageDefaultView;
145
        } elseif (view()->exists($uccelloModuleView)) {
146
            $viewToInclude = $uccelloModuleView;
147
        } elseif (view()->exists($uccelloDefaultView)) {
148
            $viewToInclude = $uccelloDefaultView;
149
        } elseif (!is_null($fallbackView)) {
150
            $viewToInclude = $fallbackView;
151
        }
152
153
        return $viewToInclude;
154
    }
155
156
    /**
157
     * Makes route automaticaly and add module parameter.
158
     *
159
     * @param array|string $name
160
     * @param Domain|string|null $domain
161
     * @param Module|string|null $module
162
     * @param mixed $parameters
163
     * @param boolean $absolute
164
     * @return string
165
     */
166
    public function route($name, $domain = null, $module = null, $parameters = [ ], $absolute = true) : string
167
    {
168
        if (is_a($domain, Domain::class)) {
169
            $domain = $domain->slug;
170
        } else {
171
            $domain = $this->getDomain($domain)->slug ?? null;
172
        }
173
174
        if (is_a($module, Module::class)) {
175
            $module = $module->name;
176
        } else {
177
            $module = $this->getModule($module)->name ?? null;
178
        }
179
180
        // Get route uri to check if domain and module parameters are needed
181
        $routeUri = \Route::getRoutes()->getByName($name)->uri ?? null;
0 ignored issues
show
Bug introduced by
The type Route was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
182
183
        // Add domain to route if we use multi domains and if the parameter is needed
184
        if (!is_null($domain) && uccello()->useMultiDomains() && preg_match('`{domain}`', $routeUri)) {
0 ignored issues
show
Bug introduced by
Are you sure the usage of uccello() is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
185
            $parameters[ 'domain' ] = $domain;
186
        }
187
188
        // Add module to route if the parameter is needed
189
        if (!is_null($module) && preg_match('`{module}`', $routeUri)) {
190
            $parameters[ 'module' ] = $module;
191
        }
192
193
        return route($name, $parameters, $absolute);
0 ignored issues
show
Bug introduced by
The function route was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

193
        return /** @scrutinizer ignore-call */ route($name, $parameters, $absolute);
Loading history...
194
    }
195
196
    /**
197
     * Returns the list of capabilities.
198
     *
199
     * @return \Illuminate\Database\Eloquent\Collection
0 ignored issues
show
Bug introduced by
The type Illuminate\Database\Eloquent\Collection was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
200
     *
201
     * @see Uccello\Core\Models\Permission
202
     */
203
    public function getCapabilities(): Collection
204
    {
205
        return Capability::all();
206
    }
207
208
    /**
209
     * Get a domain instance by slug or id
210
     *
211
     * @param string|int $slugOrId
212
     * @return Domain|null
213
     */
214
    public function getDomain($slugOrId): ?Domain
215
    {
216
        if (is_numeric($slugOrId)) {
217
            return Domain::find($slugOrId);
218
        } else {
219
            return Domain::where('slug', (string)$slugOrId)->first();
220
        }
221
    }
222
223
    /**
224
     * Get a module instance by name or id
225
     *
226
     * @param string|int $nameOrId
227
     * @return Module|null
228
     */
229
    public function getModule($nameOrId): ?Module
230
    {
231
        if (!$nameOrId) {
232
            return null;
233
        }
234
235
        if (is_numeric($nameOrId)) {
236
            // Use cache
237
            $modules = Cache::rememberForever('modules_by_id', function () {
238
                $modulesGroupedById = collect();
0 ignored issues
show
Bug introduced by
The function collect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

238
                $modulesGroupedById = /** @scrutinizer ignore-call */ collect();
Loading history...
239
                Module::all()->map(function($item) use($modulesGroupedById) {
240
                    $modulesGroupedById[$item->id] = $item;
241
                    return $modulesGroupedById;
242
                });
243
                return $modulesGroupedById;
244
            });
245
            return $modules[(string) $nameOrId] ?? null;
246
        } else {
247
            // Use cache
248
            $modules = Cache::rememberForever('modules_by_name', function () {
249
                $modulesGroupedByName = collect();
0 ignored issues
show
Bug introduced by
The function collect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

249
                $modulesGroupedByName = /** @scrutinizer ignore-call */ collect();
Loading history...
250
                Module::all()->map(function($item) use($modulesGroupedByName) {
251
                    $modulesGroupedByName[$item->name] = $item;
252
                    return $modulesGroupedByName;
253
                });
254
                return $modulesGroupedByName;
255
            });
256
            return $modules[(string) $nameOrId] ?? null;
257
        }
258
    }
259
260
    /**
261
     * Get an Uitype instance by name or id
262
     *
263
     * @param string|int $nameOrId
264
     * @return Uitype|null
265
     */
266
    public function getUitype($nameOrId): ?Uitype
267
    {
268
        if (!$nameOrId) {
269
            return null;
270
        }
271
272
        if (is_numeric($nameOrId)) {
273
            // Use cache
274
            $uitypes = Cache::rememberForever('uitypes_by_id', function () {
275
                $uitypesGroupedById = collect();
0 ignored issues
show
Bug introduced by
The function collect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

275
                $uitypesGroupedById = /** @scrutinizer ignore-call */ collect();
Loading history...
276
                Uitype::all()->map(function($item) use($uitypesGroupedById) {
277
                    $uitypesGroupedById[$item->id] = $item;
278
                    return $uitypesGroupedById;
279
                });
280
                return $uitypesGroupedById;
281
            });
282
            return $uitypes[(string) $nameOrId] ?? null;
283
        } else {
284
            // Use cache
285
            $uitypes = Cache::rememberForever('uitypes_by_name', function () {
286
                $uitypesGroupedByName = collect();
0 ignored issues
show
Bug introduced by
The function collect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

286
                $uitypesGroupedByName = /** @scrutinizer ignore-call */ collect();
Loading history...
287
                Uitype::all()->map(function($item) use($uitypesGroupedByName) {
288
                    $uitypesGroupedByName[$item->name] = $item;
289
                    return $uitypesGroupedByName;
290
                });
291
                return $uitypesGroupedByName;
292
            });
293
            return $uitypes[(string) $nameOrId] ?? null;
294
        }
295
    }
296
297
    /**
298
     * Get a display type instance by name or id
299
     *
300
     * @param string|int $nameOrId
301
     * @return Uitype|null
302
     */
303
    public function getDisplaytype($nameOrId): ?Displaytype
304
    {
305
        if (!$nameOrId) {
306
            return null;
307
        }
308
309
        if (is_numeric($nameOrId)) {
310
            // Use cache
311
            $displaytypes = Cache::rememberForever('displaytypes_by_id', function () {
312
                $displaytypesGroupedById = collect();
0 ignored issues
show
Bug introduced by
The function collect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

312
                $displaytypesGroupedById = /** @scrutinizer ignore-call */ collect();
Loading history...
313
                Displaytype::all()->map(function($item) use($displaytypesGroupedById) {
314
                    $displaytypesGroupedById[$item->id] = $item;
315
                    return $displaytypesGroupedById;
316
                });
317
                return $displaytypesGroupedById;
318
            });
319
            return $displaytypes[(string) $nameOrId] ?? null;
320
        } else {
321
            // Use cache
322
            $displaytypes = Cache::rememberForever('displaytypes_by_name', function () {
323
                $displaytypesGroupedByName = collect();
0 ignored issues
show
Bug introduced by
The function collect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

323
                $displaytypesGroupedByName = /** @scrutinizer ignore-call */ collect();
Loading history...
324
                Displaytype::all()->map(function($item) use($displaytypesGroupedByName) {
325
                    $displaytypesGroupedByName[$item->name] = $item;
326
                    return $displaytypesGroupedByName;
327
                });
328
                return $displaytypesGroupedByName;
329
            });
330
            return $displaytypes[(string) $nameOrId] ?? null;
331
        }
332
    }
333
334
    /**
335
     * Get a capability instance by name or id
336
     *
337
     * @param string|int $nameOrId
338
     * @return Uitype|null
339
     */
340
    public function getCapability($nameOrId): ?Capability
341
    {
342
        if (!$nameOrId) {
343
            return null;
344
        }
345
346
        if (is_numeric($nameOrId)) {
347
            // Use cache
348
            $capabilities = Cache::rememberForever('capabilities_by_id', function () {
349
                $capabilitiesGroupedById = collect();
0 ignored issues
show
Bug introduced by
The function collect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

349
                $capabilitiesGroupedById = /** @scrutinizer ignore-call */ collect();
Loading history...
350
                Capability::all()->map(function($item) use($capabilitiesGroupedById) {
351
                    $capabilitiesGroupedById[$item->id] = $item;
352
                    return $capabilitiesGroupedById;
353
                });
354
                return $capabilitiesGroupedById;
355
            });
356
            return $capabilities[(string) $nameOrId] ?? null;
357
        } else {
358
            // Use cache
359
            $capabilities = Cache::rememberForever('capabilities_by_name', function () {
360
                $capabilitiesGroupedByName = collect();
0 ignored issues
show
Bug introduced by
The function collect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

360
                $capabilitiesGroupedByName = /** @scrutinizer ignore-call */ collect();
Loading history...
361
                Capability::all()->map(function($item) use($capabilitiesGroupedByName) {
362
                    $capabilitiesGroupedByName[$item->name] = $item;
363
                    return $capabilitiesGroupedByName;
364
                });
365
                return $capabilitiesGroupedByName;
366
            });
367
            return $capabilities[(string) $nameOrId] ?? null;
368
        }
369
    }
370
371
    /**
372
     * Returns all domains without parents
373
     *
374
     * @return Collection
375
     */
376
    public function getRootDomains(): Collection
377
    {
378
        return Domain::getRoots()->get();
379
    }
380
381
    /**
382
     * Get last domain visited by the connected user, or the first one available
383
     * Priority:
384
     * 1. Last domain visited
385
     * 2. Domain where the user was created into
386
     * 3. First root domain
387
     *
388
     * @return Domain|null
389
     */
390
    public function getLastOrDefaultDomain(): ?Domain
391
    {
392
        $domain = Auth::user()->lastDomain ?? Auth::user()->domain ?? null; // On login page user is not authenticated
393
394
        if (!$domain) {
395
            $domain = $this->getRootDomains()[ 0 ];
396
        }
397
398
        return $domain;
399
    }
400
401
    /**
402
     * Retrieve columns to display in a datatable table
403
     *
404
     * @param Module $module
405
     * @param integer $filterId
406
     * @param string $type
407
     * @return array
408
     */
409
    public function getDatatableColumns(Module $module, $filterId=null, $type='list'): array
410
    {
411
        $columns = [ ];
412
413
        // Get default filter
414
        if ($filterId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $filterId of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
415
            $filter = Filter::find($filterId);
416
        } else {
417
            $filter = Filter::where('module_id', $module->id)
418
                ->where('type', $type)
419
                ->first();
420
421
            // If there is not result, try with type = list
422
            if (empty($filter) && $type !== 'list') {
423
                $filter = Filter::where('module_id', $module->id)
424
                ->where('type', 'list')
425
                ->first();
426
            }
427
        }
428
429
        if (empty($filter)) {
430
            return [ ];
431
        }
432
433
        $fieldsAdded = [ ];
434
435
        $seeDescendants = request()->hasSession() && request()->session()->get('descendants') ? true : false;
0 ignored issues
show
Bug introduced by
The function request was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

435
        $seeDescendants = /** @scrutinizer ignore-call */ request()->hasSession() && request()->session()->get('descendants') ? true : false;
Loading history...
436
437
        // Get filter fields
438
        foreach ($filter->columns as $fieldName) {
439
            $field = $module->fields->where('name', $fieldName)->first();
440
441
            // If the field does not exist or is not listable, continue
442
            if (!$field  || !$field->isListable() || in_array($fieldName, $fieldsAdded)) {
443
                continue;
444
            }
445
446
            $uitype = uitype($field->uitype_id);
447
448
            // Add the field as a new column
449
            $columns[ ] = [
450
                'name' => $field->name,
451
                'db_column' => $field->column,
452
                'uitype' => $uitype->name,
453
                'package' => $uitype->package,
454
                'data' => $field->data,
455
                'visible' => true
456
            ];
457
458
            $fieldsAdded[ ] = $fieldName;
459
        }
460
461
        // Get all other fields
462
        $otherFields = $module->fields->whereNotIn('name', $fieldsAdded);
463
464
        foreach ($otherFields as $field) {
465
            // If the field is not listable, continue
466
            if (!$field->isListable()) {
467
                continue;
468
            }
469
470
            $uitype = uitype($field->uitype_id);
471
472
            // Add the field as a new column
473
            $columns[ ] = [
474
                'name' => $field->name,
475
                'db_column' => $field->column,
476
                'uitype' => $uitype->name,
477
                'package' => $uitype->package,
478
                'data' => $field->data,
479
                'visible' => $field->name === 'domain' && $seeDescendants ? true : false
480
            ];
481
        }
482
483
        return $columns;
484
    }
485
486
    /**
487
     * Returns the module's default filter according to the type.
488
     *
489
     * @param Module $module
490
     * @param string $type
491
     * @return Filter
492
     */
493
    public function getDefaultFilter(Module $module, $type="list")
494
    {
495
        $filter = Filter::where('module_id', $module->id)
496
        ->where('type', $type)
497
        ->first();
498
499
        // If there is not result, try with type = list
500
        if (empty($filter) && $type !== 'list') {
501
            $filter = Filter::where('module_id', $module->id)
502
            ->where('type', 'list')
503
            ->first();
504
        }
505
506
        return $filter;
507
    }
508
509
    /**
510
     * Returns a record attribute value.
511
     * It is able to follow a complex path according to models definition (e.g. 'domain.parent.name')
512
     *
513
     * @param Object $record
514
     * @param string $attribute
515
     * @return string|Object|Array|null
516
     */
517
    public function getRecordAttribute($record, string $attribute) {
518
519
        $attributeParts = explode('.', $attribute);
520
521
        if (count($attributeParts) > 0) {
522
            $value = $record;
523
524
            foreach ($attributeParts as $part) {
525
                // Get attribute value if exists
526
                if (isset($value->{$part})) {
527
                    $value = $value->{$part};
528
                }
529
                // If property does not exist return an empty value
530
                else {
531
                    $value = null;
532
                    break;
533
                }
534
            }
535
        } else {
536
            $value = $record->{$attribute};
537
        }
538
539
        return $value;
540
    }
541
542
    /**
543
     * Retrieves a record by its id or uuid
544
     *
545
     * @param int|string $idOrUuid
546
     * @param string $className
547
     * @return mixed
548
     */
549
    public function getRecordByIdOrUuid($idOrUuid, $className)
550
    {
551
        $record = null;
552
553
        if (is_numeric($idOrUuid)) {
554
            $record = $className::find($idOrUuid);
555
        } else {
556
            $record = $this->getRecordByUuid($idOrUuid);
557
        }
558
559
        return $record;
560
    }
561
562
    /**
563
     * Retrieves a record by its uuid
564
     *
565
     * @param string $uuid
566
     * @return mixed
567
     */
568
    public function getRecordByUuid($uuid)
569
    {
570
        $record = null;
571
572
        $entity = Entity::find($uuid);
573
        if ($entity) {
574
            $record = $entity->record;
575
        }
576
577
        return $record;
578
    }
579
}