Completed
Push — master ( 2ee94f...e70fcb )
by Terzi
06:41
created

Field::setModel()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Terranet\Administrator\Field;
4
5
use Illuminate\Database\Eloquent\Model;
0 ignored issues
show
Bug introduced by
The type Illuminate\Database\Eloquent\Model 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\View;
7
use Terranet\Administrator\Architect;
8
use Terranet\Administrator\Contracts\AutoTranslatable;
9
use Terranet\Administrator\Contracts\Sortable;
10
use Terranet\Administrator\Field\Traits\AcceptsCustomFormat;
11
use Terranet\Administrator\Field\Traits\AppliesSorting;
12
use Terranet\Administrator\Field\Traits\HandlesVisibility;
13
use Terranet\Administrator\Field\Traits\HasValuePresenter;
14
use Terranet\Administrator\Scaffolding;
15
use Terranet\Administrator\Traits\AutoTranslatesInstances;
16
17
abstract class Field implements Sortable, AutoTranslatable
18
{
19
    use AcceptsCustomFormat, AppliesSorting, AutoTranslatesInstances, HasValuePresenter, HandlesVisibility;
20
21
    /** @var string */
22
    protected $id;
23
24
    /** @var string */
25
    protected $title;
26
27
    /** @var string */
28
    protected $name;
29
30
    /** @var mixed */
31
    protected $value;
32
33
    /** @var string */
34
    protected $description;
35
36
    /** @var Model */
37
    protected $model;
38
39
    /** @var bool */
40
    protected $showLabel = true;
41
42
    /** @var array */
43
    protected $visibility = [
44
        Scaffolding::PAGE_INDEX => true,
45
        Scaffolding::PAGE_EDIT => true,
46
        Scaffolding::PAGE_VIEW => true,
47
    ];
48
49
    /** @var array */
50
    protected $attributes = [
51
        'class' => 'form-control',
52
    ];
53
54
    /**
55
     * Field constructor.
56
     *
57
     * @param string $title
58
     * @param null|string $id
59
     */
60
    private function __construct(string $title, string $id = null)
61
    {
62
        $this->setId(
63
            snake_case($id ?: $title)
0 ignored issues
show
Deprecated Code introduced by
The function snake_case() has been deprecated: Str::snake() should be used directly instead. Will be removed in Laravel 5.9. ( Ignorable by Annotation )

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

63
            /** @scrutinizer ignore-deprecated */ snake_case($id ?: $title)

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
64
        );
65
66
        if ($this->translator()->has($key = $this->translationKey())) {
67
            $this->setTitle((string)$this->translator()->trans($key));
68
        } else {
69
            $this->setTitle(Architect::humanize($title));
70
        }
71
72
        if ($this->translator()->has($key = $this->descriptionKey())) {
73
            $this->setDescription((string)$this->translator()->trans($key));
74
        }
75
    }
76
77
    /**
78
     * @param $title
79
     * @param null $id
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $id is correct as it would always require null to be passed?
Loading history...
80
     * @param \Closure $callback
81
     *
82
     * @return static
83
     */
84
    public static function make($title, $id = null, \Closure $callback = null): self
85
    {
86
        $instance = new static($title, $id);
87
88
        if (null !== $callback) {
89
            $callback->call($instance, $instance);
90
        }
91
92
        return $instance;
93
    }
94
95
    /**
96
     * Create new element from another.
97
     *
98
     * @param Field $element
99
     *
100
     * @return static
101
     */
102
    public static function makeFrom(self $element): self
103
    {
104
        return static::make($element->title(), $element->id());
105
    }
106
107
    /**
108
     * Switch to a new element type.
109
     *
110
     * @param string $className
111
     *
112
     * @return mixed
113
     */
114
    public function switchTo(string $className)
115
    {
116
        return forward_static_call_array([$className, 'make'], [$this->title(), $this->id()]);
117
    }
118
119
    /**
120
     * @param Model $model
121
     *
122
     * @return static
123
     */
124
    public function setModel(Model $model): self
125
    {
126
        $this->model = $model;
127
128
        return $this;
129
    }
130
131
    /**
132
     * @return Model
133
     */
134
    public function getModel()
135
    {
136
        return $this->model;
137
    }
138
139
    /**
140
     * Render Element.
141
     *
142
     * @param string $page
143
     *
144
     * @return mixed
145
     */
146
    final public function render(string $page = 'index')
147
    {
148
        if (\in_array($page, [Scaffolding::PAGE_INDEX, Scaffolding::PAGE_VIEW], true)) {
149
            if ($this->hasCustomFormat()) {
150
                return $this->callFormatter($this->model, $page);
151
            }
152
153
            if ($presenter = $this->hasPresenter($this->model, $this->id())) {
154
                return $this->callPresenter($presenter);
155
            }
156
        }
157
158
        $data = [
159
            'field' => $this,
160
            'model' => $this->model,
161
            'attributes' => $this->getAttributes(),
162
        ];
163
164
        if (method_exists($this, $dataGetter = 'on'.title_case($page))) {
0 ignored issues
show
Deprecated Code introduced by
The function title_case() has been deprecated: Str::title() should be used directly instead. Will be removed in Laravel 5.9. ( Ignorable by Annotation )

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

164
        if (method_exists($this, $dataGetter = 'on'./** @scrutinizer ignore-deprecated */ title_case($page))) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
165
            $data += \call_user_func([$this, $dataGetter]);
166
        }
167
168
        if (View::exists($view = $this->template($page))) {
169
            return View::make($view, $data);
170
        }
171
172
        return View::make($this->template($page, 'Key'), $data);
173
    }
174
175
    /**
176
     * Return Element ID.
177
     *
178
     * @return string
179
     */
180
    public function id(): string
181
    {
182
        return $this->id;
183
    }
184
185
    /**
186
     * Form name.
187
     *
188
     * @return string
189
     */
190
    public function name(): string
191
    {
192
        if (null === $this->name) {
193
            $parts = explode('.', $this->id());
194
195
            if (\count($parts) > 1) {
196
                $first = array_first($parts);
0 ignored issues
show
Deprecated Code introduced by
The function array_first() has been deprecated: Arr::first() should be used directly instead. Will be removed in Laravel 5.9. ( Ignorable by Annotation )

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

196
                $first = /** @scrutinizer ignore-deprecated */ array_first($parts);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
197
                $other = \array_slice($parts, 1);
198
199
                $other = array_map(function ($part) {
200
                    return "[$part]";
201
                }, $other);
202
203
                return $this->name = implode('', array_merge([$first], $other));
204
            }
205
206
            return $this->name = $this->id();
207
        }
208
209
        return $this->name;
210
    }
211
212
    /**
213
     * @param string $name
214
     *
215
     * @return Field
216
     */
217
    public function setName(string $name): self
218
    {
219
        $this->name = $name;
220
221
        return $this;
222
    }
223
224
    /**
225
     * @param string $id
226
     *
227
     * @return static
228
     */
229
    public function setId(string $id): self
230
    {
231
        $this->id = $id;
232
233
        return $this;
234
    }
235
236
    /**
237
     * Return Element title.
238
     *
239
     * @return string
240
     */
241
    public function title(): string
242
    {
243
        return $this->title;
244
    }
245
246
    /**
247
     * @return string
248
     */
249
    public function getDescription(): ?string
250
    {
251
        return $this->description;
252
    }
253
254
    /**
255
     * @param string $title
256
     *
257
     * @return static
258
     */
259
    public function setTitle(string $title): self
260
    {
261
        $this->title = $title;
262
263
        return $this;
264
    }
265
266
    /**
267
     * @param null|string $description
268
     *
269
     * @return static
270
     */
271
    public function setDescription(?string $description): self
272
    {
273
        $this->description = $description;
274
275
        return $this;
276
    }
277
278
    /**
279
     * Make element translatable.
280
     *
281
     * @return Translatable
282
     */
283
    public function translatable()
284
    {
285
        return Translatable::make($this);
286
    }
287
288
    /**
289
     * @param bool $showLabel
290
     *
291
     * @return static
292
     */
293
    public function hideLabel(bool $hideLabel): self
294
    {
295
        $this->showLabel = !$hideLabel;
296
297
        return $this;
298
    }
299
300
    /**
301
     * @return bool
302
     */
303
    public function isHiddenLabel(): bool
304
    {
305
        return !$this->showLabel;
306
    }
307
308
    /**
309
     * string $page.
310
     *
311
     * @return bool
312
     */
313
    public function isVisibleOnPage(string $page): bool
314
    {
315
        return (bool)$this->visibility[$page] ?? false;
316
    }
317
318
    /**
319
     * @param array|string $pages
320
     *
321
     * @return static
322
     */
323
    public function hideOnPages($pages): self
324
    {
325
        return $this->setPagesVisibility((array)$pages, false);
326
    }
327
328
    /**
329
     * @param array|string $pages
330
     *
331
     * @return static
332
     */
333
    public function showOnPages($pages): self
334
    {
335
        return $this->setPagesVisibility((array)$pages, true);
336
    }
337
338
    /**
339
     * Make column sortable.
340
     *
341
     * @param null|\Closure $callback
342
     *
343
     * @return static
344
     */
345
    public function sortable(\Closure $callback = null): self
346
    {
347
        app('scaffold.module')->addSortable(
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

347
        /** @scrutinizer ignore-call */ 
348
        app('scaffold.module')->addSortable(
Loading history...
348
            $this->id(),
349
            $callback
350
        );
351
352
        return $this;
353
    }
354
355
    /**
356
     * Remove column from Sortable collection.
357
     *
358
     * @return static
359
     */
360
    public function disableSorting(): self
361
    {
362
        app('scaffold.module')->removeSortable($this->id());
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

362
        /** @scrutinizer ignore-call */ 
363
        app('scaffold.module')->removeSortable($this->id());
Loading history...
363
364
        return $this;
365
    }
366
367
    /**
368
     * Set value.
369
     *
370
     * @param $value
371
     *
372
     * @return Field
373
     */
374
    public function setValue($value): self
375
    {
376
        $this->value = $value;
377
378
        return $this;
379
    }
380
381
    /**
382
     * Extract Element value.
383
     *
384
     * @return mixed
385
     */
386
    public function value()
387
    {
388
        if (null !== $this->value) {
389
            return $this->value;
390
        }
391
392
        if (!$this->model) {
393
            return null;
394
        }
395
396
        return $this->model->getAttribute($this->id);
397
    }
398
399
    /**
400
     * @param $key
401
     * @param null $value
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $value is correct as it would always require null to be passed?
Loading history...
402
     * @param mixed $attribute
403
     *
404
     * @return static
405
     */
406
    public function setAttribute($attribute, $value = null): self
407
    {
408
        if (\is_array($attribute)) {
409
            foreach ($attribute as $key => $value) {
410
                $this->setAttribute($key, $value);
411
            }
412
        } else {
413
            $this->attributes[$attribute] = $value;
414
        }
415
416
        return $this;
417
    }
418
419
    /**
420
     * @return array
421
     */
422
    public function getAttributes(): array
423
    {
424
        return $this->attributes;
425
    }
426
427
    /**
428
     * @return string
429
     */
430
    public function translationKey()
431
    {
432
        $key = sprintf('administrator::columns.%s.%s', $this->translatableModule()->url(), $this->id);
433
434
        if (!$this->translator()->has($key)) {
435
            $key = sprintf('administrator::columns.%s.%s', 'global', $this->id);
436
        }
437
438
        return $key;
439
    }
440
441
    /**
442
     * @return string
443
     */
444
    public function descriptionKey()
445
    {
446
        $key = sprintf('administrator::hints.%s.%s', $this->translatableModule()->url(), $this->id);
447
448
        if (!$this->translator()->has($key)) {
449
            $key = sprintf('administrator::hints.%s.%s', 'global', $this->id);
450
        }
451
452
        return $key;
453
    }
454
455
    /**
456
     * @param \Closure $condition
457
     *
458
     * @return self
459
     */
460
    public function when(\Closure $condition): self
461
    {
462
        $this->when = $condition;
463
464
        return $this;
465
    }
466
467
    /**
468
     * @param mixed $pages
469
     * @param bool $visibility
470
     *
471
     * @return $this
472
     */
473
    protected function setPagesVisibility($pages, bool $visibility): self
474
    {
475
        $pages = array_intersect($pages, array_keys($this->visibility));
476
477
        foreach ($pages as $page) {
478
            $this->visibility[$page] = $visibility;
479
        }
480
481
        return $this;
482
    }
483
484
    /**
485
     * @param string $page
486
     * @param string $field
487
     *
488
     * @return string
489
     */
490
    protected function template(string $page, string $field = null): string
491
    {
492
        return sprintf(
493
            'administrator::fields.%s.%s',
494
            snake_case($field ?? class_basename($this)),
0 ignored issues
show
Deprecated Code introduced by
The function snake_case() has been deprecated: Str::snake() should be used directly instead. Will be removed in Laravel 5.9. ( Ignorable by Annotation )

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

494
            /** @scrutinizer ignore-deprecated */ snake_case($field ?? class_basename($this)),

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
495
            $page
496
        );
497
    }
498
}
499