Completed
Push — master ( 35ae7b...e23ec4 )
by Terzi
07:13 queued 02:37
created

Generic::hideOnPages()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
ccs 0
cts 0
cp 0
crap 2
1
<?php
2
3
namespace Terranet\Administrator\Field;
4
5
use Coduo\PHPHumanizer\StringHumanizer;
6
use Illuminate\Database\Eloquent\Model;
7
use Illuminate\Foundation\Auth\User;
8
use Illuminate\Support\Facades\View;
9
use Terranet\Administrator\Contracts\AutoTranslatable;
10
use Terranet\Administrator\Contracts\Sortable;
11
use Terranet\Administrator\Field\Traits\AcceptsCustomFormat;
12
use Terranet\Administrator\Field\Traits\AppliesSorting;
13
use Terranet\Administrator\Field\Traits\HasValuePresenter;
14
use Terranet\Administrator\Scaffolding;
15
use Terranet\Administrator\Traits\AutoTranslatesInstances;
16
17
abstract class Generic implements Sortable, AutoTranslatable
18
{
19
    use AcceptsCustomFormat, AppliesSorting, AutoTranslatesInstances, HasValuePresenter;
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 null|\Closure */
43
    protected $when;
44
45
    /** @var array */
46
    protected $visibility = [
47
        Scaffolding::PAGE_INDEX => true,
48
        Scaffolding::PAGE_EDIT => true,
49
        Scaffolding::PAGE_VIEW => true,
50
    ];
51
52
    /** @var array */
53
    protected $attributes = [
54
        'class' => 'form-control',
55
    ];
56
57
    /**
58 11
     * Generic constructor.
59
     *
60 11
     * @param string $title
61 11
     * @param null|string $id
62
     */
63
    private function __construct(string $title, string $id = null)
64 11
    {
65
        $this->setId(
66
            snake_case($id ?: $title)
67 11
        );
68 11
69
        if ($this->translator()->has($key = $this->translationKey())) {
70 11
            $this->setTitle((string) $this->translator()->trans($key));
71
        } else {
72
            $this->setTitle(
73
                'id' === $this->id
74 11
                    ? 'ID'
75
                    : StringHumanizer::humanize(str_replace(['_id', '-', '_'], ['', ' ', ' '], $this->id))
76
            );
77 11
        }
78
79
        if ($this->translator()->has($key = $this->descriptionKey())) {
80
            $this->setDescription((string) $this->translator()->trans($key));
81
        }
82
    }
83
84
    /**
85
     * @param $title
86 11
     * @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...
87
     * @param \Closure $callback
88 11
     *
89
     * @return static
90 11
     */
91
    public static function make($title, $id = null, \Closure $callback = null): self
92
    {
93
        $instance = new static($title, $id);
94 11
95
        if (null !== $callback) {
96
            $callback->call($instance, $instance);
97
        }
98
99
        return $instance;
100
    }
101
102
    /**
103
     * Create new element from another.
104
     *
105
     * @param Generic $element
106
     *
107
     * @return static
108
     */
109
    public static function makeFrom(self $element): self
110
    {
111
        return static::make($element->title(), $element->id());
112
    }
113
114
    /**
115
     * Switch to a new element type.
116
     *
117
     * @param string $className
118
     *
119
     * @return mixed
120
     */
121
    public function switchTo(string $className)
122
    {
123
        return forward_static_call_array([$className, 'make'], [$this->title(), $this->id()]);
124
    }
125
126
    /**
127
     * @param Model $model
128
     *
129
     * @return static
130
     */
131
    public function setModel(Model $model): self
132
    {
133
        $this->model = $model;
134
135
        return $this;
136
    }
137
138
    /**
139
     * @return Model
140
     */
141
    public function getModel()
142
    {
143
        return $this->model;
144
    }
145
146
    /**
147
     * Render Element.
148
     *
149
     * @param string $page
150
     *
151
     * @return mixed
152
     */
153
    final public function render(string $page = 'index')
154
    {
155
        if (\in_array($page, [Scaffolding::PAGE_INDEX, Scaffolding::PAGE_VIEW], true)) {
156
            if ($this->hasCustomFormat()) {
157
                return $this->callFormatter($this->model, $page);
158
            }
159
160
            if ($presenter = $this->hasPresenter($this->model, $this->id())) {
161
                return $this->callPresenter($presenter);
162
            }
163
        }
164
165
        $data = [
166
            'field' => $this,
167
            'model' => $this->model,
168
            'attributes' => $this->getAttributes(),
169
        ];
170
171
        if (method_exists($this, $dataGetter = 'on'.title_case($page))) {
172
            $data += \call_user_func([$this, $dataGetter]);
173
        }
174
175
        if (View::exists($view = $this->template($page))) {
176
            return View::make($view, $data);
177
        }
178
179
        return View::make($this->template($page, 'Key'), $data);
180
    }
181 24
182
    /**
183 24
     * Return Element ID.
184
     *
185
     * @return string
186
     */
187
    public function id(): string
188
    {
189
        return $this->id;
190
    }
191
192
    /**
193
     * Form name.
194
     *
195
     * @return string
196
     */
197
    public function name(): string
198
    {
199
        if (null === $this->name) {
200
            $parts = explode('.', $this->id());
201
202
            if (\count($parts) > 1) {
203
                $first = array_first($parts);
204
                $other = \array_slice($parts, 1);
205
206
                $other = array_map(function ($part) {
207
                    return "[$part]";
208
                }, $other);
209
210
                return $this->name = implode('', array_merge([$first], $other));
211
            }
212
213
            return $this->name = $this->id();
214
        }
215
216
        return $this->name;
217
    }
218
219
    /**
220
     * @param string $name
221
     *
222
     * @return Generic
223
     */
224
    public function setName(string $name): self
225
    {
226
        $this->name = $name;
227
228
        return $this;
229
    }
230 11
231
    /**
232 11
     * @param string $id
233
     *
234 11
     * @return static
235
     */
236
    public function setId(string $id): self
237
    {
238
        $this->id = $id;
239
240
        return $this;
241
    }
242 6
243
    /**
244 6
     * Return Element title.
245
     *
246
     * @return string
247
     */
248
    public function title(): string
249
    {
250 1
        return $this->title;
251
    }
252 1
253
    /**
254
     * @return string
255
     */
256
    public function getDescription(): ?string
257
    {
258
        return $this->description;
259
    }
260 16
261
    /**
262 16
     * @param string $title
263
     *
264 16
     * @return static
265
     */
266
    public function setTitle(string $title): self
267
    {
268
        $this->title = $title;
269
270
        return $this;
271
    }
272 1
273
    /**
274 1
     * @param null|string $description
275
     *
276 1
     * @return static
277
     */
278
    public function setDescription(?string $description): self
279
    {
280
        $this->description = $description;
281
282
        return $this;
283
    }
284
285
    /**
286
     * Make element translatable.
287
     *
288
     * @return Translatable
289
     */
290
    public function translatable()
291
    {
292
        return Translatable::make($this);
293
    }
294
295
    /**
296
     * @param bool $showLabel
297
     *
298
     * @return static
299
     */
300
    public function hideLabel(bool $hideLabel): self
301
    {
302
        $this->showLabel = !$hideLabel;
303
304
        return $this;
305
    }
306
307
    /**
308
     * @return bool
309
     */
310
    public function isHiddenLabel(): bool
311
    {
312
        return !$this->showLabel;
313
    }
314
315
    /**
316
     * string $page.
317
     *
318
     * @return bool
319
     */
320
    public function isVisibleOnPage(string $page): bool
321
    {
322
        return (bool) $this->visibility[$page] ?? false;
323
    }
324
325
    /**
326
     * @param array|string $pages
327
     *
328
     * @return static
329
     */
330
    public function hideOnPages($pages): self
331
    {
332
        return $this->setPagesVisibility((array) $pages, false);
333
    }
334
335
    /**
336
     * @param array|string $pages
337
     *
338
     * @return static
339
     */
340
    public function showOnPages($pages): self
341
    {
342
        return $this->setPagesVisibility((array) $pages, true);
343
    }
344
345
    /**
346 1
     * Make column sortable.
347
     *
348 1
     * @param null|\Closure $callback
349 1
     *
350 1
     * @return static
351
     */
352
    public function sortable(\Closure $callback = null): self
353 1
    {
354
        app('scaffold.module')->addSortable(
0 ignored issues
show
Bug introduced by
The method addSortable() does not exist on Illuminate\Foundation\Application. ( Ignorable by Annotation )

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

354
        app('scaffold.module')->/** @scrutinizer ignore-call */ addSortable(

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...
355
            $this->id(),
356
            $callback
357
        );
358
359
        return $this;
360
    }
361 1
362
    /**
363 1
     * Remove column from Sortable collection.
364
     *
365 1
     * @return static
366
     */
367
    public function disableSorting(): self
368
    {
369
        app('scaffold.module')->removeSortable($this->id());
0 ignored issues
show
Bug introduced by
The method removeSortable() does not exist on Illuminate\Foundation\Application. ( Ignorable by Annotation )

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

369
        app('scaffold.module')->/** @scrutinizer ignore-call */ removeSortable($this->id());

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...
370
371
        return $this;
372
    }
373
374
    /**
375
     * Set value.
376
     *
377
     * @param $value
378
     *
379
     * @return Generic
380
     */
381
    public function setValue($value): self
382
    {
383
        $this->value = $value;
384
385
        return $this;
386
    }
387
388
    /**
389
     * Extract Element value.
390
     *
391
     * @return mixed
392
     */
393
    public function value()
394
    {
395
        if (null !== $this->value) {
396
            return $this->value;
397
        }
398
399
        if (!$this->model) {
400
            return null;
401
        }
402
403
        return $this->model->getAttribute($this->id);
404
    }
405
406
    /**
407
     * @param $key
408
     * @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...
409
     * @param mixed $attribute
410
     *
411
     * @return static
412
     */
413
    public function setAttribute($attribute, $value = null): self
414
    {
415
        if (\is_array($attribute)) {
416
            foreach ($attribute as $key => $value) {
417
                $this->setAttribute($key, $value);
418
            }
419
        } else {
420
            $this->attributes[$attribute] = $value;
421
        }
422
423
        return $this;
424
    }
425
426
    /**
427
     * @return array
428
     */
429
    public function getAttributes(): array
430
    {
431 11
        return $this->attributes;
432
    }
433 11
434
    /**
435 11
     * @return string
436 11
     */
437
    public function translationKey()
438
    {
439 11
        $key = sprintf('administrator::columns.%s.%s', $this->translatableModule()->url(), $this->id);
0 ignored issues
show
Bug introduced by
The method url() does not exist on Illuminate\Foundation\Application. ( Ignorable by Annotation )

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

439
        $key = sprintf('administrator::columns.%s.%s', $this->translatableModule()->/** @scrutinizer ignore-call */ url(), $this->id);

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...
440
441
        if (!$this->translator()->has($key)) {
442
            $key = sprintf('administrator::columns.%s.%s', 'global', $this->id);
443
        }
444
445 11
        return $key;
446
    }
447 11
448
    /**
449 11
     * @return string
450 11
     */
451
    public function descriptionKey()
452
    {
453 11
        $key = sprintf('administrator::hints.%s.%s', $this->translatableModule()->url(), $this->id);
454
455
        if (!$this->translator()->has($key)) {
456
            $key = sprintf('administrator::hints.%s.%s', 'global', $this->id);
457
        }
458
459
        return $key;
460
    }
461
462
    /**
463
     * @param \Closure $condition
464
     *
465
     * @return self
466
     */
467
    public function when(\Closure $condition): self
468
    {
469
        $this->when = $condition;
470
471
        return $this;
472
    }
473
474
    /**
475
     * @param User $user
476
     *
477
     * @return mixed
478
     */
479
    public function visibleWhen()
480
    {
481
        return $this->when ? $this->when->call($this, request()) : true;
482
    }
483
484
    /**
485
     * @param mixed $pages
486
     * @param bool $visibility
487
     *
488
     * @return $this
489
     */
490
    protected function setPagesVisibility($pages, bool $visibility): self
491
    {
492
        $pages = array_intersect($pages, array_keys($this->visibility));
493
494
        foreach ($pages as $page) {
495
            $this->visibility[$page] = $visibility;
496
        }
497
498
        return $this;
499
    }
500
501
    /**
502
     * @param string $page
503
     * @param string $field
504
     *
505
     * @return string
506
     */
507
    protected function template(string $page, string $field = null): string
508
    {
509
        return sprintf(
510
            'administrator::fields.%s.%s',
511
            snake_case($field ?? class_basename($this)),
512
            $page
513
        );
514
    }
515
}
516