Test Failed
Push — master ( bfaa9c...b480ce )
by Terzi
11:11
created

Generic::translatable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
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 mixed */
29
    protected $value;
30
31
    /** @var string */
32
    protected $description;
33
34
    /** @var Model */
35
    protected $model;
36
37
    /** @var bool */
38
    protected $showLabel = true;
39
40
    /** @var array */
41
    protected $visibility = [
42
        Scaffolding::PAGE_INDEX => true,
43
        Scaffolding::PAGE_EDIT => true,
44
        Scaffolding::PAGE_VIEW => true,
45
    ];
46
47
    /** @var array */
48
    protected $attributes = [
49
        'class' => 'form-control',
50
    ];
51
52
    /**
53
     * Generic constructor.
54
     *
55
     * @param string $title
56
     * @param null|string $id
57
     */
58
    private function __construct(string $title, string $id = null)
59
    {
60
        $this->setId(
61
            snake_case($id ?: $title)
62
        );
63
64
        if ($this->translator()->has($key = $this->translationKey())) {
65
            $this->setTitle((string) $this->translator()->trans($key));
66
        } else {
67
            $this->setTitle(
68
                'id' === $this->id
69
                    ? 'ID'
70
                    : StringHumanizer::humanize(str_replace(['_id', '-', '_'], ['', ' ', ' '], $this->id))
71
            );
72
        }
73
74
        if ($this->translator()->has($key = $this->descriptionKey())) {
75
            $this->setDescription((string) $this->translator()->trans($key));
76
        }
77
    }
78
79
    /**
80
     * @param $title
81
     * @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...
82
     * @param \Closure $callback
83
     *
84
     * @return static
85
     */
86
    public static function make($title, $id = null, \Closure $callback = null): self
87
    {
88
        $instance = new static($title, $id);
89
90
        if (null !== $callback) {
91
            $callback->call($instance, $instance);
92
        }
93
94
        return $instance;
95
    }
96
97
    /**
98
     * Create new element from another.
99
     *
100
     * @param Generic $element
101
     * @return static
102
     */
103
    public static function makeFrom(Generic $element): self
104
    {
105
        return static::make($element->title(), $element->id());
106
    }
107
108
    /**
109
     * Switch to a new element type.
110
     *
111
     * @param string $className
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 ($this->format) {
149
            // Each Field can define its own data for custom formatter.
150
            $withData = method_exists($this, 'renderWith')
151
                ? $this->renderWith()
152
                : [$this->value(), $this->model];
153
154
            return $this->callFormatter($withData);
155
        }
156
157
        $data = [
158
            'field' => $this,
159
            'model' => $this->model,
160
            'attributes' => $this->getAttributes(),
161
        ];
162
163
        if (method_exists($this, $dataGetter = 'on'.title_case($page))) {
164
            $data += call_user_func([$this, $dataGetter]);
165
        }
166
167
        if (View::exists($view = $this->template($page))) {
168
            return View::make($view, $data);
169
        }
170
171
        return View::make($this->template($page, 'Key'), $data);
172
    }
173
174
    /**
175
     * Return Element ID.
176
     *
177
     * @return string
178
     */
179
    public function id(): string
180
    {
181
        return $this->id;
182
    }
183
184
    /**
185
     * Form name.
186
     *
187
     * @return string
188
     */
189
    public function name(): string
190
    {
191
        if (null === $this->name) {
192
            $parts = explode('.', $this->id());
193
194
            if (count($parts) > 1) {
195
                $first = array_first($parts);
196
                $other = array_slice($parts, 1);
197
198
                $other = array_map(function ($part) {
199
                    return "[$part]";
200
                }, $other);
201
202
                return $this->name = implode('', array_merge([$first], $other));
203
            }
204
205
            return $this->name = $this->id();
206
        }
207
208
        return $this->name;
209
    }
210
211
    /**
212
     * @param string $name
213
     * @return Generic
214
     */
215
    public function setName(string $name): self
216
    {
217
        $this->name = $name;
218
219
        return $this;
220
    }
221
222
    /**
223
     * @param string $id
224
     *
225
     * @return static
226
     */
227
    public function setId(string $id): self
228
    {
229
        $this->id = $id;
230
231
        return $this;
232
    }
233
234
    /**
235
     * Return Element title.
236
     *
237
     * @return string
238
     */
239
    public function title(): string
240
    {
241
        return $this->title;
242
    }
243
244
    /**
245
     * @return string
246
     */
247
    public function getDescription(): ?string
248
    {
249
        return $this->description;
250
    }
251
252
    /**
253
     * @param string $title
254
     *
255
     * @return static
256
     */
257
    public function setTitle(string $title): self
258
    {
259
        $this->title = $title;
260
261
        return $this;
262
    }
263
264
    /**
265
     * @param null|string $description
266
     *
267
     * @return static
268
     */
269
    public function setDescription(?string $description): self
270
    {
271
        $this->description = $description;
272
273
        return $this;
274
    }
275
276
    /**
277
     * Make element translatable.
278
     *
279
     * @return Translatable
280
     */
281
    public function translatable()
282
    {
283
        return Translatable::make($this);
284
    }
285
286
    /**
287
     * @param bool $showLabel
288
     *
289
     * @return static
290
     */
291
    public function hideLabel(bool $hideLabel): self
292
    {
293
        $this->showLabel = !$hideLabel;
294
295
        return $this;
296
    }
297
298
    /**
299
     * @return bool
300
     */
301
    public function isHiddenLabel(): bool
302
    {
303
        return !$this->showLabel;
304
    }
305
306
    /**
307
     * string $page.
308
     *
309
     * @return bool
310
     */
311
    public function isVisibleOnPage(string $page): bool
312
    {
313
        return (bool) $this->visibility[$page] ?? false;
314
    }
315
316
    /**
317
     * @param array|string $pages
318
     *
319
     * @return static
320
     */
321
    public function hideOnPages($pages): self
322
    {
323
        return $this->setPagesVisibility((array) $pages, false);
324
    }
325
326
    /**
327
     * @param array|string $pages
328
     *
329
     * @return static
330
     */
331
    public function showOnPages($pages): self
332
    {
333
        return $this->setPagesVisibility((array) $pages, true);
334
    }
335
336
    /**
337
     * Make column sortable.
338
     *
339
     * @param null|\Closure $callback
340
     *
341
     * @return static
342
     */
343
    public function sortable(\Closure $callback = null): self
344
    {
345
        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

345
        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...
346
            $this->id(),
347
            $callback
348
        );
349
350
        return $this;
351
    }
352
353
    /**
354
     * Remove column from Sortable collection.
355
     *
356
     * @return static
357
     */
358
    public function disableSorting(): self
359
    {
360
        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

360
        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...
361
362
        return $this;
363
    }
364
365
    /**
366
     * Set value.
367
     *
368
     * @param $value
369
     *
370
     * @return Generic
371
     */
372
    public function setValue($value): self
373
    {
374
        $this->value = $value;
375
376
        return $this;
377
    }
378
379
    /**
380
     * Extract Element value.
381
     *
382
     * @return mixed
383
     */
384
    public function value()
385
    {
386
        if (null !== $this->value) {
387
            return $this->value;
388
        }
389
390
        if (!$this->model) {
391
            return null;
392
        }
393
394
        return $this->model->getAttribute($this->id);
395
    }
396
397
    /**
398
     * @param $key
399
     * @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...
400
     * @param mixed $attribute
401
     *
402
     * @return static
403
     */
404
    public function setAttribute($attribute, $value = null): self
405
    {
406
        if (is_array($attribute)) {
407
            foreach ($attribute as $key => $value) {
408
                $this->setAttribute($key, $value);
409
            }
410
        } else {
411
            $this->attributes[$attribute] = $value;
412
        }
413
414
        return $this;
415
    }
416
417
    /**
418
     * @return array
419
     */
420
    public function getAttributes(): array
421
    {
422
        return $this->attributes;
423
    }
424
425
    /**
426
     * @param mixed $pages
427
     * @param bool $visibility
428
     *
429
     * @return $this
430
     */
431
    protected function setPagesVisibility($pages, bool $visibility): self
432
    {
433
        $pages = array_intersect($pages, array_keys($this->visibility));
434
435
        foreach ($pages as $page) {
436
            $this->visibility[$page] = $visibility;
437
        }
438
439
        return $this;
440
    }
441
442
    /**
443
     * @param string $page
444
     * @param string $field
445
     *
446
     * @return string
447
     */
448
    protected function template(string $page, string $field = null): string
449
    {
450
        return sprintf(
451
            'administrator::fields.%s.%s',
452
            snake_case($field ?? class_basename($this)),
453
            $page
454
        );
455
    }
456
457
    /**
458
     * @return string
459
     */
460
    public function translationKey()
461
    {
462
        $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

462
        $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...
463
464
        if (!$this->translator()->has($key)) {
465
            $key = sprintf('administrator::columns.%s.%s', 'global', $this->id);
466
        }
467
468
        return $key;
469
    }
470
471
    /**
472
     * @return string
473
     */
474
    public function descriptionKey()
475
    {
476
        $key = sprintf('administrator::hints.%s.%s', $this->translatableModule()->url(), $this->id);
477
478
        if (!$this->translator()->has($key)) {
479
            $key = sprintf('administrator::hints.%s.%s', 'global', $this->id);
480
        }
481
482
        return $key;
483
    }
484
}
485