Completed
Pull Request — master (#49)
by John
04:06 queued 01:33
created

RequestValidator::setOperationObject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
/*
3
 * This file is part of the KleijnWeb\SwaggerBundle package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace KleijnWeb\SwaggerBundle\Request;
10
11
use KleijnWeb\SwaggerBundle\Document\OperationObject;
12
use KleijnWeb\SwaggerBundle\Exception\UnsupportedException;
13
use Symfony\Component\HttpFoundation\Request;
14
use JsonSchema\Validator;
15
use KleijnWeb\SwaggerBundle\Exception\InvalidParametersException;
16
17
/**
18
 * @author John Kleijn <[email protected]>
19
 */
20
class RequestValidator
21
{
22
    /**
23
     * @var OperationObject
24
     */
25
    private $operationObject;
26
27
    /**
28
     * @param OperationObject $operationObject
29
     */
30
    public function __construct(OperationObject $operationObject = null)
31
    {
32
        if ($operationObject) {
33
            $this->setOperationObject($operationObject);
34
        }
35
    }
36
37
    /**
38
     * @param OperationObject $operationObject
39
     *
40
     * @return $this
41
     */
42
    public function setOperationObject(OperationObject $operationObject)
43
    {
44
        $this->operationObject = $operationObject;
45
46
        return $this;
47
    }
48
49
    /**
50
     * @param Request $request
51
     *
52
     * @throws InvalidParametersException
53
     * @throws UnsupportedException
54
     */
55
    public function validateRequest(Request $request)
56
    {
57
        $validator = new Validator();
58
59
        $validator->check(
60
            $this->assembleParameterDataForValidation($request),
61
            $this->operationObject->getRequestSchema()
62
        );
63
64
        if (!$validator->isValid()) {
65
            throw new InvalidParametersException(
66
                "Parameters incompatible with operation schema: "
67
                . implode(', ', $validator->getErrors()[0]),
68
                $validator->getErrors()
69
            );
70
        }
71
    }
72
73
    /**
74
     * @param Request $request
75
     *
76
     * @return \stdClass
77
     * @throws UnsupportedException
78
     */
79
    private function assembleParameterDataForValidation(Request $request)
80
    {
81
        if (!isset($this->operationObject->getDefinition()->parameters)) {
82
            return new \stdClass;
83
        }
84
85
        /**
86
         * TODO Hack
87
         * @see https://github.com/kleijnweb/swagger-bundle/issues/24
88
         */
89
        $content = null;
90
        if ($request->getContent()) {
91
            $content = json_decode($request->getContent());
92
            //TODO UT this
93
            $content = (is_array($content) && isset($content[0])) ? $content : (object)$content;
94
        }
95
96
        $parameters = new \stdClass;
97
98
        $paramBagMapping = [
99
            'query'  => 'query',
100
            'path'   => 'attributes',
101
            'body'   => 'attributes',
102
            'header' => 'headers'
103
        ];
104
        foreach ($this->operationObject->getDefinition()->parameters as $paramDefinition) {
105
            $paramName = $paramDefinition->name;
106
107
            if (!isset($paramBagMapping[$paramDefinition->in])) {
108
                throw new UnsupportedException(
109
                    "Unsupported parameter 'in' value in definition '{$paramDefinition->in}'"
110
                );
111
            }
112
            if (!$request->attributes->has($paramName)) {
113
                continue;
114
            }
115
            if ($paramDefinition->in === 'body' && $content !== null) {
116
                $parameters->$paramName = $content;
117
                continue;
118
            }
119
            $parameters->$paramName = $request->attributes->get($paramName);
120
121
            /**
122
             * If value already coerced into \DateTime object, use any non-empty value for validation
123
             */
124
            if ($parameters->$paramName instanceof \DateTime) {
125
                if (isset($paramDefinition->format)) {
126
                    if ($paramDefinition->format === 'date') {
127
                        $parameters->$paramName = '1970-01-01';
128
                    }
129
                    if ($paramDefinition->format === 'date-time') {
130
                        $parameters->$paramName = '1970-01-01T00:00:00Z';
131
                    }
132
                }
133
            }
134
        }
135
136
        return $parameters;
137
    }
138
}
139