Test Failed
Push — master ( d27946...98f74e )
by Terzi
08:07
created

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

329
        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...
330
            $this->id(),
331
            $callback
332
        );
333
334
        return $this;
335
    }
336
337
    /**
338
     * Remove column from Sortable collection.
339
     *
340
     * @return static
341
     */
342
    public function disableSorting(): self
343
    {
344
        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

344
        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...
345
346
        return $this;
347
    }
348
349
    /**
350
     * Set value.
351
     *
352
     * @param $value
353
     *
354
     * @return Generic
355
     */
356
    public function setValue($value): self
357
    {
358
        $this->value = $value;
0 ignored issues
show
Bug Best Practice introduced by
The property value does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
359
360
        return $this;
361
    }
362
363
    /**
364
     * Extract Element value.
365
     *
366
     * @return mixed
367
     */
368
    public function value()
369
    {
370
        if (!$this->model) {
371
            return null;
372
        }
373
374
        return $this->model->getAttribute($this->id);
375
    }
376
377
    /**
378
     * @param $key
379
     * @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...
380
     * @param mixed $attribute
381
     *
382
     * @return static
383
     */
384
    public function setAttribute($attribute, $value = null): self
385
    {
386
        if (is_array($attribute)) {
387
            foreach ($attribute as $key => $value) {
388
                $this->setAttribute($key, $value);
389
            }
390
        } else {
391
            if (!array_key_exists($key, $this->attributes)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $key seems to be never defined.
Loading history...
392
                throw new Exception("Unknown attribute {$key}");
0 ignored issues
show
Bug introduced by
The type Terranet\Administrator\Field\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
393
            }
394
            $this->attributes[$key] = $value;
395
        }
396
397
        return $this;
398
    }
399
400
    /**
401
     * @param mixed $pages
402
     * @param bool $visibility
403
     *
404
     * @return $this
405
     */
406
    protected function setPagesVisibility($pages, bool $visibility): self
407
    {
408
        $pages = array_intersect($pages, array_keys($this->visibility));
409
410
        foreach ($pages as $page) {
411
            $this->visibility[$page] = $visibility;
412
        }
413
414
        return $this;
415
    }
416
417
    /**
418
     * @param string $page
419
     * @param string $field
420
     *
421
     * @return string
422
     */
423
    protected function template(string $page, string $field = null): string
424
    {
425
        return sprintf(
426
            'administrator::fields.%s.%s',
427
            snake_case($field ?? class_basename($this)),
428
            $page
429
        );
430
    }
431
432
    /**
433
     * @return string
434
     */
435
    public function translationKey()
436
    {
437
        $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

437
        $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...
438
439
        if (!$this->translator()->has($key)) {
440
            $key = sprintf('administrator::columns.%s.%s', 'global', $this->id);
441
        }
442
443
        return $key;
444
    }
445
446
    /**
447
     * @return string
448
     */
449
    public function descriptionKey()
450
    {
451
        $key = sprintf('administrator::hints.%s.%s', $this->translatableModule()->url(), $this->id);
452
453
        if (!$this->translator()->has($key)) {
454
            $key = sprintf('administrator::hints.%s.%s', 'global', $this->id);
455
        }
456
457
        return $key;
458
    }
459
}
460