QueryObject::validateSortParams()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 19
rs 9.2
cc 4
eloc 12
nc 4
nop 4
1
<?php
2
/**
3
 * Author: Nil Portugués Calderó <[email protected]>
4
 * Date: 11/28/15
5
 * Time: 12:12 PM.
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace NilPortugues\Api\JsonApi\Server\Query;
11
12
use NilPortugues\Api\JsonApi\Http\Request\Parameters\Fields;
13
use NilPortugues\Api\JsonApi\Http\Request\Parameters\Included;
14
use NilPortugues\Api\JsonApi\Http\Request\Parameters\Sorting;
15
use NilPortugues\Api\JsonApi\JsonApiSerializer;
16
use NilPortugues\Api\JsonApi\Server\Errors\ErrorBag;
17
use NilPortugues\Api\JsonApi\Server\Errors\InvalidParameterError;
18
use NilPortugues\Api\JsonApi\Server\Errors\InvalidParameterMemberError;
19
use NilPortugues\Api\JsonApi\Server\Errors\InvalidSortError;
20
21
/**
22
 * Class QueryObject.
23
 */
24
class QueryObject
25
{
26
    /**
27
     * @param JsonApiSerializer $serializer
28
     * @param Fields            $fields
29
     * @param Included          $included
30
     * @param Sorting           $sort
31
     * @param ErrorBag          $errorBag
32
     * @param string            $className
33
     *
34
     * @throws QueryException
35
     */
36
    public static function assert(
37
        JsonApiSerializer $serializer,
38
        Fields $fields,
39
        Included $included,
40
        Sorting $sort,
41
        ErrorBag $errorBag,
42
        $className
43
    ) {
44
        self::validateQueryParamsTypes($serializer, $fields, 'Fields', $errorBag);
45
        self::validateIncludeParams($serializer, $included, 'include', $errorBag);
46
47
        if (!empty($className) && false === $sort->isEmpty()) {
48
            self::validateSortParams($serializer, $className, $sort, $errorBag);
49
        }
50
51
        if ($errorBag->count() > 0) {
52
            throw new QueryException();
53
        }
54
    }
55
56
    /**
57
     * @param JsonApiSerializer $serializer
58
     * @param Fields            $fields
59
     * @param                   $paramName
60
     * @param ErrorBag          $errorBag
61
     */
62
    protected static function validateQueryParamsTypes(
63
        JsonApiSerializer $serializer,
64
        Fields $fields,
65
        $paramName,
66
        ErrorBag $errorBag
67
    ) {
68
        if (false === $fields->isEmpty()) {
69
            $transformer = $serializer->getTransformer();
70
            $validateFields = $fields->types();
71
72
            foreach ($validateFields as $key => $type) {
73
                $mapping = $transformer->getMappingByAlias($type);
74
                if (null !== $mapping) {
75
                    $members = array_merge(
76
                        array_combine($mapping->getProperties(), $mapping->getProperties()),
77
                        $mapping->getAliasedProperties()
78
                    );
79
80
                    $invalidMembers = array_diff($fields->members($type), $members);
81
                    foreach ($invalidMembers as $extraField) {
82
                        $errorBag->offsetSet(null, new InvalidParameterMemberError($extraField, $type, strtolower($paramName)));
83
                    }
84
                    unset($validateFields[$key]);
85
                }
86
            }
87
88
            if (false === empty($validateFields)) {
89
                foreach ($validateFields as $type) {
90
                    $errorBag->offsetSet(null, new InvalidParameterError($type, strtolower($paramName)));
91
                }
92
            }
93
        }
94
    }
95
96
    /**
97
     * @param JsonApiSerializer $serializer
98
     * @param Included          $included
99
     * @param string            $paramName
100
     * @param ErrorBag          $errorBag
101
     */
102
    protected static function validateIncludeParams(
103
        JsonApiSerializer $serializer,
104
        Included $included,
105
        $paramName,
106
        ErrorBag $errorBag
107
    ) {
108
        $transformer = $serializer->getTransformer();
109
110
        foreach ($included->get() as $resource => $data) {
111 View Code Duplication
            if (null === $transformer->getMappingByAlias($resource)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
112
                $errorBag->offsetSet(null, new InvalidParameterError($resource, strtolower($paramName)));
113
                continue;
114
            }
115
116
            if (is_array($data)) {
117
                foreach ($data as $subResource) {
118 View Code Duplication
                    if (null === $transformer->getMappingByAlias($subResource)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
119
                        $errorBag->offsetSet(null, new InvalidParameterError($subResource, strtolower($paramName)));
120
                    }
121
                }
122
            }
123
        }
124
    }
125
126
    /**
127
     * @param JsonApiSerializer $serializer
128
     * @param string            $className
129
     * @param Sorting           $sorting
130
     * @param ErrorBag          $errorBag
131
     */
132
    protected static function validateSortParams(
133
        JsonApiSerializer $serializer,
134
        $className,
135
        Sorting $sorting,
136
        ErrorBag $errorBag
137
    ) {
138
        if (false === $sorting->isEmpty()) {
139
            if ($mapping = $serializer->getTransformer()->getMappingByClassName($className)) {
140
                $aliased = (array) $mapping->getAliasedProperties();
141
                $sortsFields = str_replace(array_values($aliased), array_keys($aliased), $sorting->fields());
142
143
                $invalidProperties = array_diff($sortsFields, $mapping->getProperties());
144
145
                foreach ($invalidProperties as $extraField) {
146
                    $errorBag->offsetSet(null, new InvalidSortError($extraField));
147
                }
148
            }
149
        }
150
    }
151
}
152