Passed
Branch develop (9abca1)
by Igor
06:46 queued 03:42
created

BaseModel::fill()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 3
Bugs 1 Features 1
Metric Value
cc 4
eloc 8
c 3
b 1
f 1
nc 8
nop 1
dl 0
loc 14
ccs 9
cts 9
cp 1
crap 4
rs 10
1
<?php
2
3
namespace Igorsgm\Ghost\Models;
4
5
use Carbon\Carbon;
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Str;
8
9
abstract class BaseModel
10
{
11
    /**
12
     * @var array|string[]
13
     */
14
    private array $modelCollectionProperties = [
15
        'authors' => \Igorsgm\Ghost\Models\Resources\Author::class,
16
        'roles' => \Igorsgm\Ghost\Models\Role::class,
17
        'labels' => \Igorsgm\Ghost\Models\Label::class,
18
        'subscriptions' => \Igorsgm\Ghost\Models\Subscription::class,
19
        'tags' => \Igorsgm\Ghost\Models\Resources\Tag::class,
20
        'navigation' => \Igorsgm\Ghost\Models\Navigation::class,
21
        'benefits' => \Igorsgm\Ghost\Models\Benefit::class,
22
    ];
23
24
    /**
25
     * @var array|string[]
26
     */
27
    private array $modelProperties = [
28
        'tier' => \Igorsgm\Ghost\Models\Resources\Tier::class,
29
        'primaryAuthor' => \Igorsgm\Ghost\Models\Resources\Author::class,
30
        'primaryTag' => \Igorsgm\Ghost\Models\Resources\Tag::class,
31
        'monthlyPrice' => \Igorsgm\Ghost\Models\Price::class,
32
        'yearlyPrice' => \Igorsgm\Ghost\Models\Price::class,
33
        'stripePrices' => \Igorsgm\Ghost\Models\Price::class,
34
        'price' => \Igorsgm\Ghost\Models\Price::class,
35
        'offer' => \Igorsgm\Ghost\Models\Resources\Offer::class,
36
    ];
37
38
    /**
39
     * The attributes that should be mutated to Carbon dates.
40
     *
41
     * @var array
42
     */
43
    private array $dates = [
44
        'createdAt',
45
        'updatedAt',
46
        'publishedAt',
47
    ];
48
49
    /**
50
     * @var Seo $seo
51
     */
52
    protected $seo;
53
54
    /**
55
     * @param  array  $data
56
     */
57 123
    public function __construct(array $data = [])
58
    {
59 123
        if (!empty($data)) {
60 94
            $this->fill($data);
61
        }
62
    }
63
64
    /**
65
     * @param  array  $data
66
     * @return void
67
     */
68 94
    private function fill(array $data)
69
    {
70 94
        if (in_array(get_class($this), config('ghost.seo.models-with'))) {
71 56
            $seoProperties = Arr::only($data, config('ghost.seo.properties'));
72 56
            $data = Arr::except($data, config('ghost.seo.properties'));
73
        }
74
75 94
        foreach ($data as $key => $value) {
76 94
            $property = Str::camel($key);
77 94
            $this->{$property} = $this->getCastedValue($property, $value) ?? null;
78
        }
79
80 94
        if (!empty($seoProperties)) {
81 56
            $this->seo = new Seo($seoProperties);
82
        }
83
    }
84
85
    /**
86
     * Fill a model property with a collection of models, when $property is inside $modelCollectionProperties keys
87
     *
88
     * @param  string  $property
89
     * @param  mixed  $value
90
     * @return \Illuminate\Support\Collection
91
     */
92 43
    private function castModelCollectionProperty($property, $value)
93
    {
94 43
        $propertyModel = $this->modelCollectionProperties[$property];
95
96 43
        return collect($value)->map(function ($item) use (&$propertyModel) {
97 41
            return new $propertyModel($item);
98
        });
99
    }
100
101
    /**
102
     * Fill a model property with a specific model, when $property is inside $modelProperties keys
103
     *
104
     * @param  string  $property
105
     * @param  mixed  $value
106
     * @return BaseModel|null
107
     */
108 41
    private function castModelProperty($property, $value)
109
    {
110 41
        $propertyModel = $this->modelProperties[$property];
111 41
        return !empty($value) ? new $propertyModel($value) : null;
112
    }
113
114
    /**
115
     * @param  string  $property
116
     * @param  string|array  $value
117
     * @return Carbon|BaseModel|\Illuminate\Support\Collection|mixed|null
118
     */
119 94
    private function getCastedValue(string $property, $value)
120
    {
121 94
        if (array_key_exists($property, $this->modelCollectionProperties)) {
122 43
            $value = $this->castModelCollectionProperty($property, $value);
123
        }
124
125 94
        if (array_key_exists($property, $this->modelProperties)) {
126 41
            $value = $this->castModelProperty($property, $value);
127
        }
128
129 94
        if (in_array($property, $this->dates)) {
130 63
            $value = Carbon::parse($value);
131
        }
132
133 94
        return $value;
134
    }
135
}
136