Completed
Push — feature/EVO-10087-patch-reques... ( 44f0ca )
by
unknown
11:56
created

JsonPatchValidator::validate()   C

Complexity

Conditions 10
Paths 64

Size

Total Lines 52
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 10.3638

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 52
rs 6.2553
c 1
b 0
f 0
ccs 22
cts 26
cp 0.8462
cc 10
eloc 28
nc 64
nop 3
crap 10.3638

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Class for validation JSON Patch for target document using JSON Pointer
4
 */
5
6
namespace Graviton\RestBundle\Service;
7
8
use Graviton\ExceptionBundle\Exception\InvalidJsonPatchException;
9
use Graviton\SchemaBundle\Constraint\VersionServiceConstraint;
10
use Graviton\SchemaBundle\Document\Schema;
11
use Rs\Json\Pointer;
12
use Rs\Json\Pointer\InvalidPointerException;
13
use Rs\Json\Pointer\NonexistentValueReferencedException;
14
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
15
16
class JsonPatchValidator
17
{
18
    /**
19
     * @param string $targetDocument JSON of target document
20
     * @param string $jsonPatch      Patch string
21
     * @param Object $schema         stdClass schema For Validation
0 ignored issues
show
Documentation introduced by
Should the type for parameter $schema not be object|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
22
     * @return boolean
23
     * @throws InvalidJsonPatchException
24
     */
25 18
    public function validate($targetDocument, $jsonPatch, $schema = null)
26
    {
27 18
        $schema = ($schema instanceof \stdClass) ? $schema : new \stdClass();
28 18
        $versioning = property_exists($schema, 'x-versioning') ? (boolean) $schema->{'x-versioning'} : false;
29
30 18
        $operations = json_decode($jsonPatch, true);
31 18
        $pointer = new Pointer($targetDocument);
32
33 18
        $paths = [];
34
35 18
        foreach ($operations as $op) {
36
            try {
37 18
                $pointer->get($op['path']);
38 4
                $paths[] = $op['path'];
39 14
            } catch (InvalidPointerException $e) {
40 6
                throw new InvalidJsonPatchException($e);
41 8
            } catch (NonexistentValueReferencedException $e) {
42 8
                $pathParts = explode('/', $op['path']);
43 8
                $lastPart = end($pathParts);
44
45 8
                if (is_numeric($lastPart)) {
46
                    /**
47
                     * JSON Pointer library throws an Exception when INDEX is equal to number of elements in array
48
                     * But JSON Patch allow this as described in RFC
49
                     *
50
                     * http://tools.ietf.org/html/rfc6902#section-4.1
51
                     * "The specified index MUST NOT be greater than the number of elements in the array."
52
                     */
53
54
                    // Try to check previous element
55 6
                    array_pop($pathParts);
56 6
                    array_push($pathParts, $lastPart - 1);
57
58
                    try {
59 6
                        $pointer->get(implode('/', $pathParts));
60 4
                    } catch (NonexistentValueReferencedException $e) {
61 8
                        throw new InvalidJsonPatchException($e);
62
                    }
63
                }
64
            }
65
        }
66
67 8
        if ($versioning &&!in_array('/'.VersionServiceConstraint::FIELD_NAME, $paths)) {
68
            $msg = sprintf(
69
                'Versioned documents require that the field \'%s\' is in each patch request. ',
70
                VersionServiceConstraint::FIELD_NAME
71
            );
72
            throw new InvalidJsonPatchException($msg);
73
        }
74
75 8
        return true;
76
    }
77
}
78