Completed
Push — master ( 13c43e...29019e )
by Nate
02:09 queued 01:00
created

ElementQueryOptionsTrait::prepQuery()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 34
ccs 0
cts 24
cp 0
rs 9.0648
c 0
b 0
f 0
cc 5
nc 6
nop 0
crap 30
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://github.com/flipboxfactory/craft-ember/blob/master/LICENSE
6
 * @link       https://github.com/flipboxfactory/craft-ember/
7
 */
8
9
namespace flipbox\craft\ember\cli;
10
11
use craft\base\ElementInterface;
12
use craft\elements\db\ElementQuery;
13
use craft\elements\db\ElementQueryInterface;
14
use flipbox\craft\ember\helpers\QueryHelper;
15
use yii\base\Action;
16
use yii\base\Exception;
17
use yii\base\InvalidArgumentException;
18
use yii\helpers\Inflector;
19
20
/**
21
 * @property string $elementType
22
 * @property array $queryConfig
23
 * @property Action $action
24
 */
25
trait ElementQueryOptionsTrait
26
{
27
    /**
28
     * @var array
29
     * The query conditional id logic for (ElementQuery only) used to source the sync operation.
30
     * example: -id=1,2,4
31
     */
32
    public $queryId = [];
33
34
    /**
35
     * @var array
36
     * The query conditional status logic for (ElementQuery only) used to source the sync operation.
37
     * example: -status=active,pending
38
     */
39
    public $queryStatus = [];
40
41
    /**
42
     * @var array
43
     * The query conditional used to source the sync operation.
44
     * example: -where='and,elements.dateUpdated > "2000-01-01",elements.dateCreated < "2010-01-01"'
45
     */
46
    public $queryWhere = [];
47
48
    /**
49
     * @var int
50
     * The query limit logic used to source the sync operation. Set to -1 to remove limit.
51
     * example: -limit=10
52
     */
53
    public $queryLimit = 100;
54
55
    /**
56
     * @var int
57
     * The query offset logic used to source the sync operation.
58
     * example: -limit=0
59
     */
60
    public $queryOffset = 0;
61
62
    /**
63
     * @var ElementQueryInterface|ElementQuery
64
     */
65
    private $query;
66
67
    /**
68
     * Returns properties corresponding to the options for the action id
69
     * Child classes may override this method to specify possible properties.
70
     *
71
     * @param string $actionID the action id of the current request
72
     * @return array properties corresponding to the options for the action
73
     */
74
    abstract public function getOptionValues($actionID);
75
76
    /**
77
     * Returns option alias names.
78
     * Child classes may override this method to specify alias options.
79
     *
80
     * @return array the options alias names valid for the action
81
     * where the keys is alias name for option and value is option name.
82
     *
83
     * @since 2.0.8
84
     * @see options()
85
     */
86
    abstract public function optionAliases();
87
88
    /**
89
     * @return string
90
     * @throws Exception
91
     */
92
    protected function elementType(): string
93
    {
94
        if (null === ($elementType = $this->elementType ?? null)) {
95
            throw new Exception("Invalid element type.");
96
        }
97
        return $elementType;
98
    }
99
100
    /**
101
     * @return array
102
     */
103
    protected function queryConfig(): array
104
    {
105
        return $this->queryConfig ?? [];
106
    }
107
108
    /**
109
     * @inheritdoc
110
     */
111
    protected function queryOptions()
112
    {
113
        return [
114
            'queryId',
115
            'queryStatus',
116
            'queryWhere',
117
            'queryLimit',
118
            'queryOffset',
119
        ];
120
    }
121
122
    /**
123
     * @inheritdoc
124
     */
125
    protected function queryOptionAliases()
126
    {
127
        return [
128
            'id' => 'query-id',
129
            'status' => 'query-status',
130
            'where' => 'query-where',
131
            'limit' => 'query-limit',
132
            'offset' => 'query-offset',
133
        ];
134
    }
135
136
    /*******************************************
137
     * PREPARE
138
     *******************************************/
139
140
    /**
141
     * @throws Exception
142
     */
143
    protected function prepQuery()
144
    {
145
        $config = [];
146
147
        // Flip the array to grab the alias which matches the query method name
148
        $alias = array_flip($this->queryOptionAliases());
149
150
        // Defaults
151
        foreach ($this->getOptionValues($this->action->id) as $optionName => $optionValue) {
152
            // Convert CamelName to id-case
153
            $optionId  = Inflector::camel2id($optionName);
154
155
            // Only handle query params
156
            if (!array_key_exists($optionId, $alias)) {
157
                continue;
158
            }
159
160
            if (null !== ($queryMethod = $alias[$optionId] ?? null)) {
161
                try {
162
                    $optionValue = $this->prepOptionValue($optionName, $optionValue);
163
                    $config[$queryMethod] = $optionValue;
164
                } catch (InvalidArgumentException $e) {
165
                    // The option is ignored
166
                }
167
            }
168
        }
169
170
        QueryHelper::configure(
171
            $this->getQuery(
172
                $this->queryConfig()
173
            ),
174
            $config
175
        );
176
    }
177
178
    /**
179
     * @param $method
180
     * @param $value
181
     * @return mixed
182
     */
183
    private function prepOptionValue($method, $value)
184
    {
185
        // Add a specific prep method to the option
186
        $prepQueryOption = 'prep' . ucfirst($method);
187
        if (method_exists($this, $prepQueryOption)) {
188
            $value = $this->{$prepQueryOption}($value);
189
        }
190
191
        return $value;
192
    }
193
194
    /*******************************************
195
     * PREPARE SPECIFIC ATTRIBUTES
196
     *******************************************/
197
198
    /**
199
     * @param $value
200
     * @return null|array
201
     */
202
    protected function prepQueryId($value)
203
    {
204
        if (empty($value)) {
205
            return null;
206
        }
207
208
        return $value;
209
    }
210
211
    /**
212
     * @param $value
213
     * @return null|array
214
     */
215
    protected function prepQueryStatus($value)
216
    {
217
        if (empty($value)) {
218
            return null;
219
        }
220
221
        return $value;
222
    }
223
224
    /**
225
     * @param $value
226
     * @return null|array
227
     */
228
    protected function prepQueryWhere($value)
229
    {
230
        if (empty($value)) {
231
            return null;
232
        }
233
234
        return $value;
235
    }
236
237
    /**
238
     * @param array $config
239
     * @return ElementQuery|ElementQueryInterface
240
     * @throws Exception
241
     */
242
    protected function getQuery(array $config = []): ElementQueryInterface
243
    {
244
        if (null === $this->query) {
245
            /** @var ElementInterface $elementClass */
246
            $elementClass = $this->elementType();
247
248
            $this->query = $elementClass::find();
249
250
            QueryHelper::configure(
251
                $this->query,
252
                $config
253
            );
254
        }
255
256
        return $this->query;
257
    }
258
}
259