Completed
Push — master ( 062b68...81f5ad )
by Terzi
08:48
created

Generic::setValue()   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\Field\Traits\AcceptsCustomFormat;
9
use Terranet\Administrator\Scaffolding;
10
11
abstract class Generic
12
{
13
    use AcceptsCustomFormat;
14
15
    /** @var string */
16
    protected $id;
17
18
    /** @var string */
19
    protected $title;
20
21
    /** @var mixed */
22
    protected $value;
23
24
    /** @var string */
25
    protected $description;
26
27
    /** @var Model */
28
    protected $model;
29
30
    /** @var bool */
31
    protected $showLabel = true;
32
33
    /** @var array */
34
    protected $visibility = [
35
        Scaffolding::PAGE_INDEX => true,
36
        Scaffolding::PAGE_EDIT => true,
37
        Scaffolding::PAGE_VIEW => true,
38
    ];
39
40
    /** @var array */
41
    protected $attributes = [];
42
43
    /**
44
     * Generic constructor.
45
     *
46
     * @param $title
47
     * @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...
48
     */
49
    private function __construct($title, $id = null)
50
    {
51
        $this->title = StringHumanizer::humanize($title);
52
        $this->id = snake_case($id ?: $this->title);
53
    }
54
55
    /**
56
     * @param $title
57
     * @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...
58
     * @param \Closure $callback
59
     *
60
     * @return static
61
     */
62
    public static function make($title, $id = null, \Closure $callback = null): self
63
    {
64
        $instance = new static($title, $id);
65
66
        if (null !== $callback) {
67
            $callback->call($instance, $instance);
68
        }
69
70
        return $instance;
71
    }
72
73
    /**
74
     * @param Model $model
75
     *
76
     * @return self
77
     */
78
    public function setModel(Model $model): self
79
    {
80
        $this->model = $model;
81
82
        return $this;
83
    }
84
85
    /**
86
     * Render Element.
87
     *
88
     * @param string $page
89
     *
90
     * @return mixed
91
     */
92
    final public function render(string $page = 'index')
93
    {
94
        if ($this->format) {
95
            // Each Field can define its own data for custom formatter.
96
            $withData = method_exists($this, 'renderWith')
97
                ? $this->renderWith()
98
                : [$this->value(), $this->model];
99
100
            return $this->callFormatter($withData);
101
        }
102
103
        $data = [
104
            'field' => $this,
105
            'model' => $this->model,
106
        ];
107
108
        if (method_exists($this, $dataGetter = 'on'.title_case($page))) {
109
            $data += call_user_func([$this, $dataGetter]);
110
        }
111
112
        if (View::exists($view = $this->template($page))) {
113
            return View::make($view, $data);
114
        }
115
116
        return View::make($this->template($page, 'Key'), $data);
117
    }
118
119
    /**
120
     * Return Element ID.
121
     *
122
     * @return string
123
     */
124
    public function id(): string
125
    {
126
        return $this->id;
127
    }
128
129
    /**
130
     * Form name.
131
     *
132
     * @return string
133
     */
134
    public function name()
135
    {
136
        $parts = explode('.', $this->id());
137
138
        if (count($parts) > 1) {
139
            $first = array_first($parts);
140
            $other = array_slice($parts, 1);
141
142
            $other = array_map(function ($part) {
143
                return "[$part]";
144
            }, $other);
145
146
            return join('', array_merge([$first], $other));
147
        }
148
149
        return $this->id();
150
    }
151
152
    /**
153
     * @param string $id
154
     * @return self
155
     */
156
    public function setId(string $id): self
157
    {
158
        $this->id = $id;
159
160
        return $this;
161
    }
162
163
    /**
164
     * Return Element title.
165
     *
166
     * @return string
167
     */
168
    public function title(): string
169
    {
170
        return $this->title;
171
    }
172
173
    /**
174
     * @return string
175
     */
176
    public function getDescription(): ?string
177
    {
178
        return $this->description;
179
    }
180
181
    /**
182
     * @param string $title
183
     *
184
     * @return self
185
     */
186
    public function setTitle(string $title): self
187
    {
188
        $this->title = $title;
189
190
        return $this;
191
    }
192
193
    /**
194
     * @param string $description
195
     * @return self
196
     */
197
    public function setDescription(string $description): self
198
    {
199
        $this->description = $description;
200
201
        return $this;
202
    }
203
204
    /**
205
     * @param bool $showLabel
206
     *
207
     * @return self
208
     */
209
    public function hideLabel(bool $hideLabel): self
210
    {
211
        $this->showLabel = !$hideLabel;
212
213
        return $this;
214
    }
215
216
    /**
217
     * @return bool
218
     */
219
    public function isHiddenLabel(): bool
220
    {
221
        return !$this->showLabel;
222
    }
223
224
    /**
225
     * string $page.
226
     *
227
     * @return bool
228
     */
229
    public function isVisibleOnPage(string $page): bool
230
    {
231
        return (bool) $this->visibility[$page] ?? false;
232
    }
233
234
    /**
235
     * @param array|string $pages
236
     *
237
     * @return self
238
     */
239
    public function hideOnPages($pages): self
240
    {
241
        return $this->setPagesVisibility((array) $pages, false);
242
    }
243
244
    /**
245
     * @param array|string $pages
246
     *
247
     * @return self
248
     */
249
    public function showOnPages($pages): self
250
    {
251
        return $this->setPagesVisibility((array) $pages, true);
252
    }
253
254
    /**
255
     * Make column sortable.
256
     *
257
     * @param null|\Closure $callback
258
     *
259
     * @return self
260
     */
261
    public function sortable(\Closure $callback = null): self
262
    {
263
        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

263
        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...
264
            $this->id(),
265
            $callback
266
        );
267
268
        return $this;
269
    }
270
271
    /**
272
     * Remove column from Sortable collection.
273
     *
274
     * @return self
275
     */
276
    public function disableSorting(): self
277
    {
278
        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

278
        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...
279
280
        return $this;
281
    }
282
283
    /**
284
     * Set value.
285
     *
286
     * @param $value
287
     * @return Generic
288
     */
289
    public function setValue($value): self
290
    {
291
        $this->value = $value;
292
293
        return $this;
294
    }
295
296
    /**
297
     * Extract Element value.
298
     *
299
     * @return mixed
300
     */
301
    public function value()
302
    {
303
        if (!$this->model) {
304
            return null;
305
        }
306
307
        if (null === $this->value) {
308
            $this->value = $this->model->getAttribute($this->id);
309
        }
310
311
        return $this->value;
312
    }
313
314
    /**
315
     * @param $key
316
     * @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...
317
     * @return self
318
     */
319
    public function setAttribute($attribute, $value = null): self
320
    {
321
        if (is_array($attribute)) {
322
            foreach ($attribute as $key => $value) {
323
                $this->setAttribute($key, $value);
324
            }
325
        } else {
326
            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...
327
                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...
328
            }
329
            $this->attributes[$key] = $value;
330
        }
331
332
        return $this;
333
    }
334
335
    /**
336
     * @param mixed $pages
337
     * @param bool $visibility
338
     *
339
     * @return $this
340
     */
341
    protected function setPagesVisibility($pages, bool $visibility): self
342
    {
343
        $pages = array_intersect($pages, array_keys($this->visibility));
344
345
        foreach ($pages as $page) {
346
            $this->visibility[$page] = $visibility;
347
        }
348
349
        return $this;
350
    }
351
352
    /**
353
     * @param string $page
354
     * @param string $field
355
     *
356
     * @return string
357
     */
358
    protected function template(string $page, string $field = null): string
359
    {
360
        return sprintf(
361
            'administrator::fields.%s.%s',
362
            snake_case($field ?? class_basename($this)),
363
            $page
364
        );
365
    }
366
}
367