Completed
Push — master ( 69e260...c7a5d3 )
by Nate
10:40
created

ElementMetric::getDateCalculated()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.7333
c 0
b 0
f 0
cc 4
nc 3
nop 0
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://flipboxfactory.com/software/scorecard/license
6
 * @link       https://www.flipboxfactory.com/software/scorecard/
7
 */
8
9
namespace flipbox\craft\scorecard\records;
10
11
use Craft;
12
use craft\helpers\DateTimeHelper;
13
use craft\helpers\StringHelper;
14
use flipbox\ember\helpers\ModelHelper;
15
use flipbox\ember\records\ActiveRecordWithId;
16
use flipbox\ember\records\traits\ElementAttribute;
17
use flipbox\craft\scorecard\queries\ElementMetricQuery;
18
use flipbox\craft\scorecard\helpers\MetricHelper;
19
use flipbox\craft\scorecard\metrics\SavableMetricInterface;
20
use flipbox\craft\scorecard\validators\ElementMetricValidator;
21
22
/**
23
 * @author Flipbox Factory <[email protected]>
24
 * @since 1.0.0
25
 *
26
 * @property int $parentId
27
 * @property string $class
28
 * @property float $score
29
 * @property float $weight
30
 * @property string $version
31
 * @property array|null $settings
32
 * @property \DateTime $dateCalculated
33
 */
34
abstract class ElementMetric extends ActiveRecordWithId implements SavableMetricInterface
35
{
36
    use ElementAttribute;
37
38
    /**
39
     * The default score weight
40
     */
41
    const WEIGHT = 1;
42
43
    /**
44
     * The default metric version
45
     */
46
    const VERSION = '1.0';
47
48
    /**
49
     * The table alias
50
     */
51
    const TABLE_ALIAS = 'scorecard_element_metrics';
52
53
    /**
54
     * The Active Query class
55
     */
56
    const ACTIVE_QUERY_CLASS = ElementMetricQuery::class;
57
58
    /**
59
     * @inheritdoc
60
     */
61
    protected $getterPriorityAttributes = ['elementId', 'score', 'dateCalculated'];
62
63
    /**
64
     * @return float
65
     */
66
    abstract protected function calculateScore(): float;
67
68
    /**
69
     * @inheritdoc
70
     */
71
    public function init()
72
    {
73
        parent::init();
74
75
        $this->setAttribute(
76
            'settings',
77
            MetricHelper::resolveSettings(
78
                $this->getAttribute('settings')
79
            )
80
        );
81
82
        // Always this class
83
        $this->class = static::class;
84
85
        // Defaults
86
        if ($this->getIsNewRecord()) {
87
            $this->weight = $this->weight ?: static::WEIGHT;
88
            $this->version = $this->version ?: static::VERSION;
89
            $this->dateCalculated = $this->dateCalculated ?: DateTimeHelper::currentUTCDateTime();
90
        }
91
    }
92
93
    /**
94
     * @inheritdoc
95
     */
96
    public static function find()
97
    {
98
        /** @noinspection PhpUnhandledExceptionInspection */
99
        /** @noinspection PhpIncompatibleReturnTypeInspection */
100
        return Craft::createObject(
101
            static::ACTIVE_QUERY_CLASS,
102
            [
103
                get_called_class(),
104
                [
105
                    'class' => static::class
106
                ]
107
            ]
108
        );
109
    }
110
111
    /**
112
     * @inheritdoc
113
     */
114
    public static function instantiate($row)
115
    {
116
        $class = $row['class'] ?? static::class;
117
        return new $class;
118
    }
119
120
    /**
121
     * @inheritdoc
122
     */
123
    public function rules()
124
    {
125
        return array_merge(
126
            parent::rules(),
127
            $this->elementRules(),
128
            [
129
                [
130
                    [
131
                        'class'
132
                    ],
133
                    ElementMetricValidator::class
134
                ],
135
                [
136
                    [
137
                        'parentId',
138
                    ],
139
                    'number',
140
                    'integerOnly' => true
141
                ],
142
                [
143
                    [
144
                        'score',
145
                        'weight',
146
                    ],
147
                    'number'
148
                ],
149
                [
150
                    [
151
                        'elementId',
152
                        'class',
153
                        'weight',
154
                        'version',
155
                    ],
156
                    'required'
157
                ],
158
                [
159
                    [
160
                        'class',
161
                        'settings',
162
                        'score',
163
                        'weight',
164
                        'version',
165
                        'dateCalculated'
166
                    ],
167
                    'safe',
168
                    'on' => [
169
                        ModelHelper::SCENARIO_DEFAULT
170
                    ]
171
                ]
172
            ]
173
        );
174
    }
175
176
177
    /*******************************************
178
     * METRIC INTERFACE
179
     *******************************************/
180
181
    /**
182
     * @inheritdoc
183
     * @throws \ReflectionException
184
     */
185
    public static function displayName(): string
186
    {
187
        return StringHelper::titleize(
188
            (new \ReflectionClass(static::class))
189
                ->getShortName()
190
        );
191
    }
192
193
    /**
194
     * @inheritdoc
195
     */
196
    public function getWeight(): float
197
    {
198
        return (float)$this->getAttribute('weight');
199
    }
200
201
    /**
202
     * @inheritdoc
203
     */
204
    public function getVersion(): string
205
    {
206
        return (string)$this->getAttribute('version');
207
    }
208
209
    /**
210
     * @inheritdoc
211
     */
212
    public function getScore(): float
213
    {
214
        if ($this->getAttribute('score') === null) {
215
            $this->setAttribute('score', $this->calculateScore() * $this->getWeight());
216
        }
217
218
        return (float)$this->getAttribute('score');
219
    }
220
221
    /**
222
     * @return \DateTime|null
223
     */
224
    public function getDateCalculated()
225
    {
226
        $dateCalculated = $this->getAttribute('dateCalculated');
227
228
        if ($dateCalculated !== null && !$dateCalculated instanceof \DateTime) {
229
            if(is_array($dateCalculated)) {
230
                $dateCalculated = $dateCalculated['date'] ?? $dateCalculated;
231
            }
232
233
            $dateCalculated = DateTimeHelper::toDateTime($dateCalculated);
234
235
            $this->setAttribute('dateCalculated', $dateCalculated);
236
        }
237
238
        return $dateCalculated;
239
    }
240
241
242
    /*******************************************
243
     * SETTINGS
244
     *******************************************/
245
246
    /**
247
     * @param string $attribute
248
     * @return mixed
249
     */
250
    public function getSettingsValue(string $attribute)
251
    {
252
        $settings = MetricHelper::resolveSettings(
253
            $this->getAttribute('settings')
254
        );
255
256
        return $settings[$attribute] ?? null;
257
    }
258
259
    /**
260
     * @param string $attribute
261
     * @param $value
262
     * @return $this
263
     */
264
    public function setSettingsValue(string $attribute, $value)
265
    {
266
        $settings = MetricHelper::resolveSettings(
267
            $this->getAttribute('settings')
268
        );
269
        $settings[$attribute] = $value;
270
        $this->setAttribute('settings', $settings);
271
272
        return $this;
273
    }
274
275
276
    /*******************************************
277
     * CONFIGURATION
278
     *******************************************/
279
280
    /**
281
     * @return array
282
     */
283
    public function toConfig(): array
284
    {
285
        return $this->toArray();
286
    }
287
}
288