Association   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 201
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 9

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 17
lcom 2
cbo 9
dl 0
loc 201
ccs 0
cts 114
cp 0
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A find() 0 6 1
A rules() 0 30 1
A attributeLabels() 0 8 1
A beforeSave() 0 14 2
A afterSave() 0 15 2
A afterDelete() 0 15 2
A getSortableField() 0 13 2
A resolveElementFromIdAttribute() 0 8 2
A resolveElement() 0 16 4
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://github.com/flipboxfactory/craft-element-lists/LICENSE
6
 * @link       https://github.com/flipboxfactory/craft-element-lists/
7
 */
8
9
namespace flipbox\craft\element\lists\records;
10
11
use Craft;
12
use craft\base\Element;
13
use craft\base\ElementInterface;
14
use craft\errors\FieldNotFoundException;
15
use flipbox\craft\element\lists\fields\SortableInterface;
16
use flipbox\craft\ember\records\ActiveRecord;
17
use flipbox\craft\ember\records\FieldAttributeTrait;
18
use flipbox\craft\ember\records\SortableTrait;
19
use flipbox\craft\element\lists\queries\AssociationQuery;
20
21
/**
22
 * @author Flipbox Factory <[email protected]>
23
 * @since 1.0.0
24
 *
25
 * @property int $targetId
26
 * @property int $sourceId
27
 * @property int $sortOrder
28
 */
29
class Association extends ActiveRecord
30
{
31
    use SourceAttributeTrait,
32
        TargetAttributeTrait,
33
        SourceSiteAttributeTrait,
34
        FieldAttributeTrait,
35
        SortableTrait;
36
37
    /**
38
     * @inheritdoc
39
     */
40
    const TABLE_ALIAS = 'relations';
41
42
    /**
43
     * @inheritdoc
44
     */
45
    protected $getterPriorityAttributes = ['fieldId', 'siteId', 'sourceSiteId', 'sourceId', 'targetId'];
46
47
    /**
48
     * @noinspection PhpDocMissingThrowsInspection
49
     * @return AssociationQuery
50
     */
51
    public static function find(): AssociationQuery
52
    {
53
        /** @noinspection PhpIncompatibleReturnTypeInspection */
54
        /** @noinspection PhpUnhandledExceptionInspection */
55
        return Craft::createObject(AssociationQuery::class, [get_called_class()]);
56
    }
57
58
59
    /*******************************************
60
     * RULES
61
     *******************************************/
62
63
    /**
64
     * @return array
65
     */
66
    public function rules(): array
67
    {
68
        return array_merge(
69
            parent::rules(),
70
            $this->sourceSiteRules(),
71
            $this->fieldRules(),
72
            $this->sourceRules(),
73
            $this->targetRules(),
74
            [
75
                [
76
                    [
77
                        'targetId',
78
                        'sourceId',
79
                        'fieldId',
80
                    ],
81
                    'required'
82
                ],
83
                [
84
                    'targetId',
85
                    'unique',
86
                    'targetAttribute' => [
87
                        'targetId',
88
                        'sourceId',
89
                        'fieldId',
90
                        'sourceSiteId'
91
                    ]
92
                ]
93
            ]
94
        );
95
    }
96
97
    /**
98
     * @return array
99
     */
100
    public function attributeLabels()
101
    {
102
        return array_merge(
103
            parent::attributeLabels(),
104
            $this->sourceAttributeLabels(),
105
            $this->targetAttributeLabels()
106
        );
107
    }
108
109
    /**
110
     * @inheritdoc
111
     *
112
     * @throws FieldNotFoundException
113
     */
114
    public function beforeSave($insert)
115
    {
116
        if ($this->getSortableField()->ensureSortOrder()) {
117
            $this->ensureSortOrder(
118
                [
119
                    'sourceId' => $this->sourceId,
120
                    'fieldId' => $this->fieldId,
121
                    'sourceSiteId' => $this->sourceSiteId
122
                ]
123
            );
124
        }
125
126
        return parent::beforeSave($insert);
127
    }
128
129
    /**
130
     * @inheritdoc
131
     *
132
     * @throws FieldNotFoundException
133
     * @throws \yii\db\Exception
134
     */
135
    public function afterSave($insert, $changedAttributes)
136
    {
137
        if ($this->getSortableField()->ensureSortOrder()) {
138
            $this->autoReOrder(
139
                'targetId',
140
                [
141
                    'sourceId' => $this->sourceId,
142
                    'fieldId' => $this->fieldId,
143
                    'sourceSiteId' => $this->sourceSiteId
144
                ]
145
            );
146
        }
147
148
        parent::afterSave($insert, $changedAttributes);
149
    }
150
151
    /**
152
     * @inheritdoc
153
     *
154
     * @throws FieldNotFoundException
155
     * @throws \yii\db\Exception
156
     */
157
    public function afterDelete()
158
    {
159
        if ($this->getSortableField()->ensureSortOrder()) {
160
            $this->sequentialOrder(
161
                'targetId',
162
                [
163
                    'sourceId' => $this->sourceId,
164
                    'fieldId' => $this->fieldId,
165
                    'sourceSiteId' => $this->sourceSiteId
166
                ]
167
            );
168
        }
169
170
        parent::afterDelete();
171
    }
172
173
    /**
174
     * @return SortableInterface
175
     * @throws FieldNotFoundException
176
     */
177
    protected function getSortableField(): SortableInterface
178
    {
179
        if (!$this->getField() instanceof SortableInterface) {
180
            throw new FieldNotFoundException(sprintf(
181
                "Field must be an instance of '%s', '%s' given.",
182
                SortableInterface::class,
183
                get_class($this->getField())
184
            ));
185
        }
186
187
        /** @noinspection PhpIncompatibleReturnTypeInspection */
188
        return $this->getField();
189
    }
190
191
192
    /*******************************************
193
     * RESOLVERS
194
     *******************************************/
195
196
    /**
197
     * @param string $attribute
198
     * @return Element|ElementInterface|null
199
     */
200
    protected function resolveElementFromIdAttribute(string $attribute)
201
    {
202
        if (null === $this->{$attribute}) {
203
            return null;
204
        }
205
206
        return Craft::$app->getElements()->getElementById($this->{$attribute});
207
    }
208
209
    /**
210
     * @param mixed $element
211
     * @return Element|ElementInterface|null
212
     */
213
    protected function resolveElement($element = null)
214
    {
215
        if ($element === null) {
216
            return null;
217
        }
218
219
        if ($element instanceof ElementInterface) {
220
            return $element;
221
        }
222
223
        if (is_numeric($element)) {
224
            return Craft::$app->getElements()->getElementById($element);
225
        }
226
227
        return null;
228
    }
229
}
230