Completed
Push — master ( e1fcb3...04b0bc )
by Nate
04:43 queued 03:24
created

Associations::save()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 23
ccs 0
cts 20
cp 0
rs 8.7972
c 0
b 0
f 0
cc 4
eloc 16
nc 3
nop 2
crap 20
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://flipboxfactory.com/software/domains/license
6
 * @link       https://www.flipboxfactory.com/software/domains/
7
 */
8
9
namespace flipbox\domains\services;
10
11
use craft\helpers\Json;
12
use flipbox\craft\sortable\associations\db\SortableAssociationQueryInterface;
13
use flipbox\craft\sortable\associations\records\SortableAssociationInterface;
14
use flipbox\craft\sortable\associations\services\SortableAssociations;
15
use flipbox\domains\db\DomainsQuery;
16
use flipbox\domains\records\Domain;
17
use flipbox\domains\validators\MinMaxValidator;
18
use yii\db\ActiveQuery;
19
use flipbox\domains\Domains as DomainsPlugin;
20
21
/**
22
 * @author Flipbox Factory <[email protected]>
23
 * @since 1.0.0
24
 */
25
class Associations extends SortableAssociations
26
{
27
    /**
28
     * @inheritdoc
29
     */
30
    const SOURCE_ATTRIBUTE = Domain::SOURCE_ATTRIBUTE;
31
32
    /**
33
     * @inheritdoc
34
     */
35
    const TARGET_ATTRIBUTE = Domain::TARGET_ATTRIBUTE;
36
37
    /**
38
     * @inheritdoc
39
     */
40
    protected static function tableAlias(): string
41
    {
42
        return Domain::tableAlias();
43
    }
44
45
    /**
46
     * @inheritdoc
47
     * @return DomainsQuery
48
     */
49
    public function getQuery($config = []): SortableAssociationQueryInterface
50
    {
51
        return new DomainsQuery(Domain::class, $config);
52
    }
53
54
    /**
55
     * @param SortableAssociationInterface|Domain $record
56
     * @return SortableAssociationQueryInterface|DomainsQuery
57
     */
58
    protected function associationQuery(
59
        SortableAssociationInterface $record
60
    ): SortableAssociationQueryInterface {
61
        return $this->query(
62
            $record->{static::SOURCE_ATTRIBUTE},
63
            $record->fieldId,
64
            $record->siteId
65
        );
66
    }
67
68
    /**
69
     * @param SortableAssociationQueryInterface|DomainsQuery $query
70
     * @return array
71
     */
72
    protected function existingAssociations(
73
        SortableAssociationQueryInterface $query
74
    ): array {
75
        $source = $this->resolveStringAttribute($query, static::SOURCE_ATTRIBUTE);
76
        $field = $this->resolveStringAttribute($query, 'fieldId');
77
        $site = $this->resolveStringAttribute($query, 'siteId');
78
79
        if ($source === null || $field === null || $site === null) {
80
            return [];
81
        }
82
83
        return $this->associations($source, $field, $site);
84
    }
85
86
    /**
87
     * @param $source
88
     * @param int $fieldId
89
     * @param int $siteId
90
     * @return SortableAssociationQueryInterface|ActiveQuery
91
     */
92
    private function query(
93
        $source,
94
        int $fieldId,
95
        int $siteId
96
    ): SortableAssociationQueryInterface {
97
        return $this->getQuery()
98
            ->where([
99
                static::SOURCE_ATTRIBUTE => $source,
100
                'fieldId' => $fieldId,
101
                'siteId' => $siteId
102
            ])
103
            ->orderBy(['sortOrder' => SORT_ASC]);
104
    }
105
106
    /**
107
     * @param $source
108
     * @param int $fieldId
109
     * @param int $siteId
110
     * @return array
111
     */
112
    private function associations(
113
        $source,
114
        int $fieldId,
115
        int $siteId
116
    ): array {
117
        return $this->query($source, $fieldId, $siteId)
118
            ->indexBy(static::TARGET_ATTRIBUTE)
119
            ->all();
120
    }
121
122
    /**
123
     * @param SortableAssociationQueryInterface $query
124
     * @return \flipbox\domains\fields\Domains|null
125
     */
126
    protected function resolveFieldFromQuery(
127
        SortableAssociationQueryInterface $query
128
    ) {
129
        if (null === ($fieldId = $this->resolveStringAttribute($query, 'fieldId'))) {
130
            return null;
131
        }
132
133
        return DomainsPlugin::getInstance()->getFields()->findById($fieldId);
134
    }
135
136
    /**
137
     * @inheritdoc
138
     * @param bool $validate
139
     * @throws \Exception
140
     */
141
    public function save(
142
        SortableAssociationQueryInterface $query,
143
        bool $validate = true
144
    ): bool {
145
        if ($validate === true && null !== ($field = $this->resolveFieldFromQuery($query))) {
146
            $error = '';
147
148
            (new MinMaxValidator([
149
                'min' => $field->min,
150
                'max' => $field->max
151
            ]))->validate($query, $error);
152
153
            if (!empty($error)) {
154
                DomainsPlugin::error(sprintf(
155
                    "Domains failed to save due to the following validation errors: '%s'",
156
                    Json::encode($error)
157
                ));
158
                return false;
159
            }
160
        }
161
162
        return parent::save($query);
163
    }
164
}
165