Completed
Pull Request — develop (#342)
by Alexander
17:05
created

ReadOnlyValidator::validate()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 27
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 8.0313

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 27
rs 8.5806
ccs 7
cts 19
cp 0.3684
cc 4
eloc 15
nc 5
nop 2
crap 8.0313
1
<?php
2
/**
3
 * Validator for read only
4
 */
5
6
namespace Graviton\RestBundle\Validator\Constraints\ReadOnly;
7
8
use Symfony\Component\Validator\Constraint;
9
use Symfony\Component\Validator\ConstraintValidator;
10
use Doctrine\ODM\MongoDB\DocumentManager;
11
use Graviton\I18nBundle\Document\TranslatableDocumentInterface;
12
13
/**
14
 * Validator for read only
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 ReadOnlyValidator extends ConstraintValidator
21
{
22
    private $dm;
23
24
    /**
25
     * Creates a new ReadOnlyValidator instance
26
     *
27
     * @param DocumentManager $dm Document manager
28
     */
29 1
    public function __construct(DocumentManager $dm)
30
    {
31 1
        $this->dm = $dm;
32 1
    }
33
34
    /**
35
     * Checks read only
36
     *
37
     * @param string     $value      Input value
38
     * @param Constraint $constraint Constraint instance
39
     *
40
     * @return void
41
     */
42 1
    public function validate($value, Constraint $constraint)
43
    {
44 1
        $submittedData = $this->context->getRoot()->getData();
45
46
        // if the structure is nested it can't access the id via getObject()
47 1
        $recordClass = get_class($submittedData);
48 1
        $recordId = $this->context->getRoot()->getData()->getId();
49
50 1
        $record = $this->dm->find($recordClass, $recordId);
51
52 1
        if ($record) {
53
            $storedValue = $this->getStoredValueByPath($this->context->getPropertyPath(), $record);
54
55
            if ($storedValue instanceof \DateTime) {
56
                $isEqual = ($storedValue == $value);
57
            } else {
58
                $isEqual = ($value === $storedValue);
59
            }
60
61
            if (!$isEqual) {
62
                $this->context->addViolation(
63
                    $constraint->message,
64
                    array('%string%' => $this->context->getPropertyPath())
65
                );
66
            }
67
        }
68 1
    }
69
70
    /**
71
     * Gets the stored value from a path
72
     *
73
     * @param string                        $path   Value path
74
     * @param TranslatableDocumentInterface $record Record
75
     * @return mixed
76
     */
77
    public function getStoredValueByPath($path, $record)
78
    {
79
        $path = explode('.', $path);
80
81
        $pathCount = count($path);
82
83
        for ($i = 1; $i < $pathCount; $i++) {
84
            if (is_int($path[$i])) {
85
                $record = $record[$path[$i]];
86
            } else {
87
                $record = $record->{'get' . $path[$i]}();
88
            }
89
        }
90
91
        return $record;
92
    }
93
}
94