Completed
Push — develop ( 13c43e...daa4a6 )
by Nate
03:53
created

ElementQueryOptionsTrait::queryOptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 0
cts 10
cp 0
rs 9.9332
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
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
        }
98
        return $elementType;
99
    }
100
101
    /**
102
     * @return array
103
     */
104
    protected function queryConfig(): array
105
    {
106
        return $this->queryConfig ?? [];
107
    }
108
109
    /**
110
     * @inheritdoc
111
     */
112
    protected function queryOptions()
113
    {
114
        return [
115
            'queryId',
116
            'queryStatus',
117
            'queryWhere',
118
            'queryLimit',
119
            'queryOffset',
120
        ];
121
    }
122
123
    /**
124
     * @inheritdoc
125
     */
126
    protected function queryOptionAliases()
127
    {
128
        return [
129
            'id' => 'query-id',
130
            'status' => 'query-status',
131
            'where' => 'query-where',
132
            'limit' => 'query-limit',
133
            'offset' => 'query-offset',
134
        ];
135
    }
136
137
    /*******************************************
138
     * PREPARE
139
     *******************************************/
140
141
    /**
142
     * @throws Exception
143
     */
144
    protected function prepQuery()
145
    {
146
        $config = [];
147
148
        // Flip the array to grab the alias which matches the query method name
149
        $alias = array_flip($this->queryOptionAliases());
150
151
        // Defaults
152
        foreach ($this->getOptionValues($this->action->id) as $optionName => $optionValue) {
153
            // Convert CamelName to id-case
154
            $optionId  = Inflector::camel2id($optionName);
155
156
            // Only handle query params
157
            if (!array_key_exists($optionId, $alias)) {
158
                continue;
159
            }
160
161
            if (null !== ($queryMethod = $alias[$optionId] ?? null)) {
162
                try {
163
                    $optionValue = $this->prepOptionValue($optionName, $optionValue);
164
                    $config[$queryMethod] = $optionValue;
165
                } catch (InvalidArgumentException $e) {
166
                    // The option is ignored
167
                }
168
            }
169
        }
170
171
        QueryHelper::configure(
172
            $this->getQuery(
173
                $this->queryConfig()
174
            ),
175
            $config
176
        );
177
    }
178
179
    /**
180
     * @param $method
181
     * @param $value
182
     * @return mixed
183
     */
184
    private function prepOptionValue($method, $value)
185
    {
186
        // Add a specific prep method to the option
187
        $prepQueryOption = 'prep' . ucfirst($method);
188
        if (method_exists($this, $prepQueryOption)) {
189
            $value = $this->{$prepQueryOption}($value);
190
        }
191
192
        return $value;
193
    }
194
195
    /*******************************************
196
     * PREPARE SPECIFIC ATTRIBUTES
197
     *******************************************/
198
199
    /**
200
     * @param $value
201
     * @return null|array
202
     */
203
    protected function prepQueryId($value)
204
    {
205
        if (empty($value)) {
206
            return null;
207
        }
208
209
        return $value;
210
    }
211
212
    /**
213
     * @param $value
214
     * @return null|array
215
     */
216
    protected function prepQueryStatus($value)
217
    {
218
        if (empty($value)) {
219
            return null;
220
        }
221
222
        return $value;
223
    }
224
225
    /**
226
     * @param $value
227
     * @return null|array
228
     */
229
    protected function prepQueryWhere($value)
230
    {
231
        if (empty($value)) {
232
            return null;
233
        }
234
235
        return $value;
236
    }
237
238
    /**
239
     * @param array $config
240
     * @return ElementQuery|ElementQueryInterface
241
     * @throws Exception
242
     */
243
    protected function getQuery(array $config = []): ElementQueryInterface
244
    {
245
        if (null === $this->query) {
246
            /** @var ElementInterface $elementClass */
247
            $elementClass = $this->elementType();
248
249
            $this->query = $elementClass::find();
250
251
            QueryHelper::configure(
252
                $this->query,
253
                $config
254
            );
255
        }
256
257
        return $this->query;
258
    }
259
}
260