Passed
Branch develop (1d1e3b)
by Igor
02:57
created

BaseModel::fill()   B

Complexity

Conditions 7
Paths 20

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 7

Importance

Changes 2
Bugs 1 Features 1
Metric Value
cc 7
eloc 16
c 2
b 1
f 1
nc 20
nop 1
dl 0
loc 29
ccs 17
cts 17
cp 1
crap 7
rs 8.8333
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
78 94
            if (array_key_exists($property, $this->modelCollectionProperties)) {
79 43
                $this->fillModelCollectionProperty($property, $value);
80 43
                continue;
81
            }
82
83 94
            if (array_key_exists($property, $this->modelProperties)) {
84 41
                $this->fillModelProperty($property, $value);
85 41
                continue;
86
            }
87
88 94
            if (in_array($property, $this->dates)) {
89 63
                $value = Carbon::parse($value);
90
            }
91
92 94
            $this->{$property} = $value ?? null;
93
        }
94
95 94
        if (!empty($seoProperties)) {
96 56
            $this->seo = new Seo($seoProperties);
97
        }
98
    }
99
100
    /**
101
     * Fill a model property with a collection of models, when $property is inside $modelCollectionProperties keys
102
     *
103
     * @param  string  $property
104
     * @param  mixed  $value
105
     * @return void
106
     */
107 43
    private function fillModelCollectionProperty($property, $value)
108
    {
109 43
        $propertyModel = $this->modelCollectionProperties[$property];
110
111 43
        $this->{$property} = collect($value)->map(function ($item) use (&$propertyModel) {
112 41
            return new $propertyModel($item);
113
        });
114
    }
115
116
    /**
117
     * Fill a model property with a specific model, when $property is inside $modelProperties keys
118
     *
119
     * @param  string  $property
120
     * @param  mixed  $value
121
     * @return void
122
     */
123 41
    private function fillModelProperty($property, $value)
124
    {
125 41
        $propertyModel = $this->modelProperties[$property];
126 41
        $this->{$property} = !empty($value) ? new $propertyModel($value) : null;
127
    }
128
}
129