Completed
Branch master (0e4525)
by
unknown
01:49
created

BaseQueryParserTrait::getFields()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
nc 4
nop 2
dl 0
loc 13
ccs 8
cts 8
cp 1
crap 5
rs 9.5222
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Neomerx\JsonApi\Http\Query;
4
5
/**
6
 * Copyright 2015-2020 [email protected]
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 * http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
21
use Neomerx\JsonApi\Contracts\Http\Query\BaseQueryParserInterface as P;
22
use Neomerx\JsonApi\Contracts\Schema\ErrorInterface;
23
use Neomerx\JsonApi\Exceptions\JsonApiException;
24
use Neomerx\JsonApi\Schema\Error;
25
26
/**
27
 * @package Neomerx\JsonApi
28
 */
29
trait BaseQueryParserTrait
30
{
31
    /**
32
     * @param array  $parameters
33
     * @param string $errorTitle
34
     *
35
     * @return iterable
36
     */
37 11
    protected function getIncludes(array $parameters, string $errorTitle): iterable
38
    {
39 11
        if (\array_key_exists(P::PARAM_INCLUDE, $parameters) === true) {
40 10
            $includes = $parameters[P::PARAM_INCLUDE];
41 10
            $paths    = $this->splitCommaSeparatedStringAndCheckNoEmpties(P::PARAM_INCLUDE, $includes, $errorTitle);
42 10
            foreach ($paths as $path) {
43 6
                yield $path => $this->splitStringAndCheckNoEmpties(P::PARAM_INCLUDE, $path, '.', $errorTitle);
44
            }
45
        }
46 6
    }
47
48
    /**
49
     * @param array  $parameters
50
     * @param string $errorTitle
51
     *
52
     * @return iterable
53
     */
54 1
    protected function getIncludePaths(array $parameters, string $errorTitle): iterable
55
    {
56 1
        $aIncludes = $this->getIncludes($parameters, $errorTitle);
57 1
        foreach ($aIncludes as $path => $parsed) {
58 1
            \assert($parsed !== null);
59 1
            yield $path;
60
        }
61 1
    }
62
63
    /**
64
     * @param array  $parameters
65
     * @param string $errorTitle
66
     *
67
     * @return iterable
68
     */
69 4
    protected function getFields(array $parameters, string $errorTitle): iterable
70
    {
71 4
        if (\array_key_exists(P::PARAM_FIELDS, $parameters) === true) {
72 3
            $fields = $parameters[P::PARAM_FIELDS];
73 3
            if (\is_array($fields) === false || empty($fields) === true) {
74 1
                throw new JsonApiException($this->createParameterError(P::PARAM_FIELDS, $errorTitle));
75
            }
76
77 2
            foreach ($fields as $type => $fieldList) {
78 2
                yield $type => $this->splitCommaSeparatedStringAndCheckNoEmpties($type, $fieldList, $errorTitle);
79
            }
80
        }
81 3
    }
82
83
    /**
84
     * @param array  $parameters
85
     * @param string $errorTitle
86
     *
87
     * @return iterable
88
     */
89 2
    protected function getSorts(array $parameters, string $errorTitle): iterable
90
    {
91 2
        if (\array_key_exists(P::PARAM_SORT, $parameters) === true) {
92 2
            $sorts  = $parameters[P::PARAM_SORT];
93 2
            $values = $this->splitCommaSeparatedStringAndCheckNoEmpties(P::PARAM_SORT, $sorts, $errorTitle);
94 2
            foreach ($values as $orderAndField) {
95 2
                switch ($orderAndField[0]) {
96 2
                    case '-':
97 2
                        $isAsc = false;
98 2
                        $field = \substr($orderAndField, 1);
99 2
                        break;
100 2
                    case '+':
101 2
                        $isAsc = true;
102 2
                        $field = \substr($orderAndField, 1);
103 2
                        break;
104
                    default:
105 2
                        $isAsc = true;
106 2
                        $field = $orderAndField;
107 2
                        break;
108
                }
109
110 2
                yield $field => $isAsc;
111
            }
112
        }
113 2
    }
114
115
    /**
116
     * @param array  $parameters
117
     * @param string $errorTitle
118
     *
119
     * @return iterable
120
     */
121 1
    protected function getProfileUrls(array $parameters, string $errorTitle): iterable
122
    {
123 1
        if (\array_key_exists(P::PARAM_PROFILE, $parameters) === true) {
124 1
            $encodedUrls = $parameters[P::PARAM_PROFILE];
125 1
            $decodedUrls = \urldecode($encodedUrls);
126 1
            yield from $this->splitSpaceSeparatedStringAndCheckNoEmpties(
127 1
                P::PARAM_PROFILE,
128 1
                $decodedUrls,
129 1
                $errorTitle
130
            );
131
        }
132 1
    }
133
134
    /**
135
     * @param string       $paramName
136
     * @param string|mixed $shouldBeString
137
     * @param string       $errorTitle
138
     *
139
     * @return iterable
140
     */
141 12
    private function splitCommaSeparatedStringAndCheckNoEmpties(
142
        string $paramName,
143
        $shouldBeString,
144
        string $errorTitle
145
    ): iterable {
146 12
        return $this->splitStringAndCheckNoEmpties($paramName, $shouldBeString, ',', $errorTitle);
147
    }
148
149
    /**
150
     * @param string       $paramName
151
     * @param string|mixed $shouldBeString
152
     * @param string       $errorTitle
153
     *
154
     * @return iterable
155
     */
156 1
    private function splitSpaceSeparatedStringAndCheckNoEmpties(
157
        string $paramName,
158
        $shouldBeString,
159
        string $errorTitle
160
    ): iterable {
161 1
        return $this->splitStringAndCheckNoEmpties($paramName, $shouldBeString, ' ', $errorTitle);
162
    }
163
164
    /**
165
     * @param string       $paramName
166
     * @param string|mixed $shouldBeString
167
     * @param string       $separator
168
     * @param string       $errorTitle
169
     *
170
     * @return iterable
171
     *
172
     * @SuppressWarnings(PHPMD.IfStatementAssignment)
173
     */
174 12
    private function splitStringAndCheckNoEmpties(
175
        string $paramName,
176
        $shouldBeString,
177
        string $separator,
178
        string $errorTitle
179
    ): iterable {
180 12
        if (\is_string($shouldBeString) === false || ($trimmed = \trim($shouldBeString)) === '') {
181 4
            throw new JsonApiException($this->createParameterError($paramName, $errorTitle));
182
        }
183
184 8
        foreach (\explode($separator, $trimmed) as $value) {
185 8
            $trimmedValue = \trim($value);
186 8
            if ($trimmedValue === '') {
187 1
                throw new JsonApiException($this->createParameterError($paramName, $errorTitle));
188
            }
189
190 8
            yield $trimmedValue;
191
        }
192 8
    }
193
194
    /**
195
     * @param string $paramName
196
     * @param string $errorTitle
197
     *
198
     * @return ErrorInterface
199
     */
200 6
    private function createParameterError(string $paramName, string $errorTitle): ErrorInterface
201
    {
202 6
        $source = [Error::SOURCE_PARAMETER => $paramName];
203 6
        $error  = new Error(null, null, null, null, null, $errorTitle, null, $source);
204
205 6
        return $error;
206
    }
207
}
208