Completed
Pull Request — develop (#609)
by Narcotic
12:02 queued 07:18
created

ConstraintUtils::getCurrentRequestContent()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
rs 9.4285
ccs 0
cts 7
cp 0
cc 2
eloc 4
nc 2
nop 0
crap 6
1
<?php
2
/**
3
 * Common functions for constraints, mostly here for performance reasons
4
 */
5
6
namespace Graviton\SchemaBundle\Constraint;
7
8
use Doctrine\ODM\MongoDB\DocumentManager;
9
use Graviton\JsonSchemaBundle\Validator\Constraint\Event\ConstraintEventSchema;
10
use Graviton\RestBundle\Service\RestUtils;
11
use JsonSchema\Entity\JsonPointer;
12
use Symfony\Component\HttpFoundation\Request;
13
use Symfony\Component\HttpFoundation\RequestStack;
14
15
/**
16
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
17
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
18
 * @link     http://swisscom.ch
19
 */
20
class ConstraintUtils
21
{
22
23
    /**
24
     * @var array
25
     */
26
    private $entities = [];
27
28
    /**
29
     * @var \stdClass
30
     */
31
    private $currentSchema;
32
33
    /**
34
     * @var \stdClass
35
     */
36
    private $currentData;
37
38
    /**
39
     * @var RequestStack
40
     */
41
    private $requestStack;
42
43
    /**
44
     * Constructor.
45
     *
46
     * @param DocumentManager $dm           DocumentManager
47
     * @param RestUtils       $restUtils    RestUtils
48
     * @param RequestStack    $requestStack RequestStack
49
     *
50
     */
51
    public function __construct(DocumentManager $dm, RestUtils $restUtils, RequestStack $requestStack)
52
    {
53
        $this->dm = $dm;
54
        $this->restUtils = $restUtils;
55
        $this->requestStack = $requestStack;
56
    }
57
58
    /**
59
     * Gets a entity from the database as a generic object. All constraints that need the saved data to compare
60
     * values or anything should call this function to get what they need. As this is cached in the instance,
61
     * it will fetched only once even if multiple constraints need that object.
62
     *
63
     * @param string $documentClass document class
64
     * @param string $recordId      record id
65
     *
66
     * @throws \Doctrine\ODM\MongoDB\LockException
67
     * @throws \Exception
68
     *
69
     * @return object|null entity
70
     */
71
    public function getSerializedEntity($documentClass, $recordId)
72
    {
73
        if (!isset($this->entities[$documentClass][$recordId])) {
74
            $current = $this->dm->getRepository($documentClass)->find($recordId);
75
76
            if (is_null($current)) {
77
                $this->entities[$documentClass][$recordId] = null;
78
            } else {
79
                $this->entities[$documentClass][$recordId] = json_decode($this->restUtils->serializeContent($current));
80
            }
81
        }
82
83
        return $this->entities[$documentClass][$recordId];
84
    }
85
86
    /**
87
     * Returns the current request entity (as \stdClass) if possible
88
     *
89
     * @return null|object
90
     */
91
    public function getCurrentEntity()
92
    {
93
        $currentRecordId = null;
94
95
        // first, let's the one from the payload..
96
        if (isset($this->currentData->id)) {
97
            $currentRecordId = $this->currentData->id;
98
        }
99
100
        // if we have a request, it must override it..
101
        if ($this->requestStack->getCurrentRequest() instanceof Request &&
102
            $this->requestStack->getCurrentRequest()->attributes->has('id')
103
        ) {
104
            $currentRecordId = $this->requestStack->getCurrentRequest()->attributes->get('id');
105
        }
106
107
        if (isset($this->currentSchema->{'x-documentClass'}) &&
108
            !empty($this->currentSchema->{'x-documentClass'}) &&
109
            !is_null($currentRecordId)
110
        ) {
111
            return $this->getSerializedEntity($this->currentSchema->{'x-documentClass'}, $currentRecordId);
112
        }
113
114
        return null;
115
    }
116
117
    /**
118
     * Returns the request method of the current request
119
     *
120
     * @return null|string the request method
121
     */
122
    public function getCurrentRequestMethod()
123
    {
124
        if ($this->requestStack->getCurrentRequest() instanceof Request) {
125
            return $this->requestStack->getCurrentRequest()->getMethod();
126
        }
127
        return null;
128
    }
129
130
    /**
131
     * Returns the current request content
132
     *
133
     * @return bool|null|resource|string the content
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use resource|string|null.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
134
     */
135
    public function getCurrentRequestContent()
136
    {
137
        if ($this->requestStack->getCurrentRequest() instanceof Request) {
138
            return $this->requestStack->getCurrentRequest()->getContent();
139
        }
140
        return null;
141
    }
142
143
    /**
144
     * gets the current schema. helpful for field schema validators that need access to the whole schema in some way.
145
     *
146
     * @return \stdClass
147
     */
148
    public function getCurrentSchema()
149
    {
150
        return $this->currentSchema;
151
    }
152
153
    /**
154
     * gets the current data from the client (the whole object).
155
     * helpful for field schema validators that need access to the whole data in some way.
156
     *
157
     * @return \stdClass
158
     */
159
    public function getCurrentData()
160
    {
161
        return $this->currentData;
162
    }
163
164
    /**
165
     * own function to get standard path from a JsonPointer object
166
     *
167
     * @param JsonPointer|null $pointer pointer
168
     *
169
     * @return string path as string
170
     */
171
    public function getNormalizedPathFromPointer(JsonPointer $pointer = null)
172
    {
173
        $result = array_map(
174
            function ($path) {
175
                return sprintf(is_numeric($path) ? '[%d]' : '.%s', $path);
176
            },
177
            $pointer->getPropertyPaths()
0 ignored issues
show
Bug introduced by
It seems like $pointer is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
178
        );
179
        return trim(implode('', $result), '.');
180
    }
181
182
    /**
183
     * called on the first schema validation, before anything else.
184
     *
185
     * @param ConstraintEventSchema $event event
186
     *
187
     * @return void
188
     */
189
    public function onSchemaValidation(ConstraintEventSchema $event)
190
    {
191
        $this->currentSchema = $event->getSchema();
192
        $this->currentData = $event->getElement();
193
    }
194
}
195