Completed
Push — feature/EVO-5751-text-index-mo... ( 0ab3ac...8fecb1 )
by
unknown
62:16 queued 57:01
created

ReadOnlyFieldConstraint::checkReadOnlyFields()   C

Complexity

Conditions 10
Paths 14

Size

Total Lines 50
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 27
CRAP Score 10.2146

Importance

Changes 4
Bugs 0 Features 2
Metric Value
c 4
b 0
f 2
dl 0
loc 50
ccs 27
cts 31
cp 0.871
rs 5.7647
cc 10
eloc 26
nc 14
nop 1
crap 10.2146

How to fix   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
 * Schema constraint that validates if readOnly: true fields are manipulated and rejects changes on those.
4
 */
5
6
namespace Graviton\SchemaBundle\Constraint;
7
8
use Graviton\JsonSchemaBundle\Validator\Constraint\Event\ConstraintEventSchema;
9
use Symfony\Component\PropertyAccess\PropertyAccess;
10
11
/**
12
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
13
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
14
 * @link     http://swisscom.ch
15
 */
16
class ReadOnlyFieldConstraint
17
{
18
19
    /**
20
     * @var array
21
     */
22
    private $fieldMap;
23
24
    /**
25
     * ReadOnlyFieldConstraint constructor.
26
     *
27
     * @param ConstraintUtils $utils             Utils
28
     * @param array           $readOnlyFieldsMap field map from compiler pass
29
     */
30 4
    public function __construct(ConstraintUtils $utils, array $readOnlyFieldsMap)
31
    {
32 4
        $this->utils = $utils;
33 4
        $this->fieldMap = $readOnlyFieldsMap;
34 4
    }
35
36
    /**
37
     * Checks the readOnly fields and sets error in event if needed
38
     *
39
     * @param ConstraintEventSchema $event event class
40
     *
41
     * @return void
42
     */
43 4
    public function checkReadOnlyFields(ConstraintEventSchema $event)
44
    {
45 4
        $schema = $event->getSchema();
46 4
        $data = $event->getElement();
47
48 4
        if (!isset($schema->{'x-documentClass'}) || !isset($data->id)) {
49
            return;
50
        }
51
52 4
        $documentClass = $schema->{'x-documentClass'};
53
54 4
        if (!isset($this->fieldMap[$documentClass])) {
55
            return;
56
        }
57
58 4
        $readOnlyFields = $this->fieldMap[$documentClass];
59
60
        // get the current record
61 4
        $currentRecord = $this->utils->getCurrentEntity();
62
63 4
        if (is_null($currentRecord)) {
64
            return;
65
        }
66
67
        // compare fields in both objects
68 4
        $accessor = PropertyAccess::createPropertyAccessor();
69 4
        foreach ($readOnlyFields as $fieldName) {
70 4
            $storedValue = null;
71 4
            if ($accessor->isReadable($currentRecord, $fieldName)) {
72 4
                $storedValue = $accessor->getValue($currentRecord, $fieldName);
73 2
            }
74
75 4
            if (is_object($storedValue)) {
76
                // skip objects as a whole, we will test their readOnly properties instead
77
                continue;
78
            }
79
80 4
            $setValue = null;
81 4
            if ($accessor->isReadable($data, $fieldName)) {
82 4
                $setValue = $accessor->getValue($data, $fieldName);
83 2
            }
84
85 4
            if ($storedValue != $setValue) {
86 2
                $event->addError(
87 3
                    sprintf('The value %s is read only.', json_encode($accessor->getValue($currentRecord, $fieldName))),
88
                    $fieldName
89 1
                );
90 1
            }
91 2
        }
92 4
    }
93
}
94