Completed
Push — master ( fafb06...e219aa )
by Nate
05:01 queued 03:27
created

Domains::normalizeQueryEmptyValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 2
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\fields;
10
11
use Craft;
12
use craft\base\Element;
13
use craft\base\ElementInterface;
14
use craft\base\Field;
15
use craft\elements\db\ElementQuery;
16
use craft\elements\db\ElementQueryInterface;
17
use craft\helpers\ArrayHelper;
18
use flipbox\domains\db\DomainsQuery;
19
use flipbox\domains\Domains as DomainsPlugin;
20
use flipbox\domains\models\Domain;
21
use flipbox\domains\validators\DomainsValidator;
22
23
/**
24
 * @author Flipbox Factory <[email protected]>
25
 * @since 1.0.0
26
 */
27
class Domains extends Field
28
{
29
    /**
30
     * @var bool
31
     */
32
    public $unique = true;
33
34
    /**
35
     * @var int|null The maximum number of relations this field can have (used if [[allowLimit]] is set to true)
36
     */
37
    public $limit;
38
39
    /**
40
     * @var bool Whether to allow the Limit setting
41
     */
42
    public $allowLimit = true;
43
44
    /**
45
     * @var string
46
     */
47
    public $defaultStatus = 'pending';
48
49
    /**
50
     * @inheritdoc
51
     */
52
    public static function displayName(): string
53
    {
54
        return Craft::t('domains', 'Domains');
55
    }
56
57
    /**
58
     * @return array
59
     */
60
    public function getStatuses(): array
61
    {
62
        return [
63
            'enabled' => Craft::t('domains', 'Enabled'),
64
            'pending' => Craft::t('domains', 'Pending'),
65
            'disabled' => Craft::t('domains', 'Disabled')
66
        ];
67
    }
68
69
    /**
70
     * @inheritdoc
71
     */
72
    public static function hasContentColumn(): bool
73
    {
74
        return false;
75
    }
76
77
78
    /*******************************************
79
     * ELEMENT
80
     *******************************************/
81
82
    /**
83
     * @inheritdoc
84
     */
85
    public function modifyElementsQuery(ElementQueryInterface $query, $value)
86
    {
87
        /** @var ElementQuery $query */
88
        if ($value === 'not :empty:') {
89
            $value = ':notempty:';
90
        }
91
92
        if ($value === ':notempty:' || $value === ':empty:') {
93
            $fieldService = DomainsPlugin::getInstance()->getField();
94
            $alias = $fieldService->getTableAlias($this);
95
            $name = $fieldService->getTableName($this);
96
            $operator = ($value === ':notempty:' ? '!=' : '=');
97
98
            $query->subQuery->andWhere([
99
                "(select count([[{$alias}.id]]) from " .
100
                $name .
101
                " {{{$alias}}} where [[{$alias}.elementId]] = [[elements.id]]) {$operator} 0"
102
            ]);
103
        } else {
104
            if ($value !== null) {
105
                return false;
106
            }
107
        }
108
109
        return null;
110
    }
111
112
    /**
113
     * @inheritdoc
114
     */
115
    public function getElementValidationRules(): array
116
    {
117
        $rules = parent::getElementValidationRules();
118
119
        $rules[] = [
120
            DomainsValidator::class,
121
            'field' => $this
122
        ];
123
124
        return $rules;
125
    }
126
127
128
    /*******************************************
129
     * NORMALIZE VALUE
130
     *******************************************/
131
132
    /**
133
     * @inheritdoc
134
     */
135
    public function normalizeValue($value, ElementInterface $element = null)
136
    {
137
        if ($value instanceof DomainsQuery) {
138
            return $value;
139
        }
140
141
        /** @var Element|null $element */
142
        $query = (new DomainsQuery($this))
143
            ->siteId($this->targetSiteId($element));
144
145
        // $value will be an array of domains
146
        $this->normalizeQueryValue($query, $value, $element);
147
148
        if ($this->allowLimit === true && $this->limit !== null) {
149
            $query->limit($this->limit);
150
        }
151
152
        return $query;
153
    }
154
155
    /**
156
     * @param DomainsQuery $query
157
     * @param $value
158
     * @param ElementInterface|null $element
159
     */
160
    private function normalizeQueryValue(DomainsQuery $query, $value, ElementInterface $element = null)
161
    {
162
        if (is_array($value)) {
163
            $this->normalizeQueryInputValue($query, $value, $element);
164
            return;
165
        }
166
167
        if ($value === '') {
168
            $this->normalizeQueryEmptyValue($query);
169
            return;
170
        }
171
172
        $this->normalizeQuery($query, $value, $element);
173
    }
174
175
    /**
176
     * @param DomainsQuery $query
177
     * @param array $value
178
     * @param ElementInterface|null $element
179
     */
180
    private function normalizeQueryInputValue(DomainsQuery $query, array $value, ElementInterface $element = null)
181
    {
182
        $models = [];
183
        $sortOrder = 0;
184
        foreach ($value as $val) {
185
            if (!is_array($val)) {
186
                $val = [
187
                    'domain' => $value,
188
                    'status' => $this->defaultStatus
189
                ];
190
            }
191
192
            $models[] = new Domain(
193
                $this,
194
                [
195
                    'domain' => ArrayHelper::getValue($val, 'domain'),
196
                    'status' => ArrayHelper::getValue($val, 'status'),
197
                    'element' => $element,
198
                    'sortOrder' => $sortOrder++
199
                ]
200
            );
201
        }
202
        $query->setCachedResult($models);
203
    }
204
205
    /**
206
     * @param DomainsQuery $query
207
     */
208
    private function normalizeQueryEmptyValue(DomainsQuery $query)
209
    {
210
        $query->setCachedResult([]);
211
    }
212
213
    /**
214
     * @param DomainsQuery $query
215
     * @param string $value
216
     * @param ElementInterface|null $element
217
     */
218
    private function normalizeQuery(DomainsQuery $query, string $value = null, ElementInterface $element = null)
219
    {
220
        if ($value !== '' && $element !== null && $element->getId() !== null) {
221
            $query->elementId($element->getId());
222
        } else {
223
            $query->elementId(false);
224
            $query->domain(false);
225
        }
226
    }
227
228
229
    /**
230
     * @param DomainsQuery $value
231
     * @inheritdoc
232
     */
233
    public function getSearchKeywords($value, ElementInterface $element): string
234
    {
235
        $domains = [];
236
237
        foreach ($value->all() as $domain) {
238
            array_push($domains, $domain->domain);
239
        }
240
241
        return parent::getSearchKeywords($domains, $element);
242
    }
243
244
245
    /*******************************************
246
     * VIEWS
247
     *******************************************/
248
249
    /**
250
     * @param DomainsQuery $value
251
     * @inheritdoc
252
     */
253
    public function getInputHtml($value, ElementInterface $element = null): string
254
    {
255
        return DomainsPlugin::getInstance()->getField()->getTableHtml($this, $value, false);
256
    }
257
258
259
    /*******************************************
260
     * EVENTS
261
     *******************************************/
262
263
    /**
264
     * @inheritdoc
265
     */
266
    public function afterSave(bool $isNew)
267
    {
268
        DomainsPlugin::getInstance()->getField()->save($this);
269
        parent::afterSave($isNew);
270
    }
271
272
    /**
273
     * @inheritdoc
274
     */
275
    public function afterDelete()
276
    {
277
        DomainsPlugin::getInstance()->getField()->delete($this);
278
        parent::afterDelete();
279
    }
280
281
    /**
282
     * @inheritdoc
283
     */
284
    public function afterElementSave(ElementInterface $element, bool $isNew)
285
    {
286
        DomainsPlugin::getInstance()->getDomainAssociations()->save(
287
            $this,
288
            $element->getFieldValue($this->handle),
289
            $element
290
        );
291
292
        parent::afterElementSave($element, $isNew);
293
    }
294
295
296
    /*******************************************
297
     * UTILITIES
298
     *******************************************/
299
300
    /**
301
     * Returns the site ID that target elements should have.
302
     *
303
     * @param ElementInterface|Element|null $element
304
     *
305
     * @return int
306
     */
307
    protected function targetSiteId(ElementInterface $element = null): int
308
    {
309
        /** @var Element $element */
310
        if (Craft::$app->getIsMultiSite() === true && $element !== null) {
311
            return $element->siteId;
312
        }
313
314
        return Craft::$app->getSites()->currentSite->id;
315
    }
316
}
317