Completed
Push — master ( 1049ef...ba8cbe )
by Portey
7s
created

ConfigValidator::validate()   C

Complexity

Conditions 13
Paths 28

Size

Total Lines 46
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 13

Importance

Changes 3
Bugs 1 Features 2
Metric Value
c 3
b 1
f 2
dl 0
loc 46
ccs 24
cts 24
cp 1
rs 5.1118
cc 13
eloc 24
nc 28
nop 3
crap 13

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
* This file is a part of graphql-youshido project.
4
*
5
* @author Alexandr Viniychuk <[email protected]>
6
* created: 11/28/15 2:25 AM
7
*/
8
9
namespace Youshido\GraphQL\Validator\ConfigValidator;
10
11
12
use Youshido\GraphQL\Validator\ConfigValidator\Rules\TypeValidationRule;
13
use Youshido\GraphQL\Validator\ConfigValidator\Rules\ValidationRuleInterface;
14
use Youshido\GraphQL\Validator\ErrorContainer\ErrorContainerTrait;
15
use Youshido\GraphQL\Validator\Exception\ValidationException;
16
17
class ConfigValidator implements ConfigValidatorInterface
18
{
19
20
    use ErrorContainerTrait;
21
22
    protected $rules = [];
23
24
    protected $extraFieldsAllowed = false;
25
26
    /** @var ValidationRuleInterface[] */
27
    protected $validationRules = [];
28
29
    /** @var  ConfigValidator */
30
    protected static $instance;
31
32
    private function __construct()
33
    {
34
        $this->initializeRules();
35
    }
36
37
    /**
38
     * @return ConfigValidator
39
     */
40 125
    public static function getInstance()
41
    {
42 125
        if (empty(self::$instance)) {
43
            self::$instance = new self();
44
        }
45
46 125
        self::$instance->clearErrors();
47
48 125
        return self::$instance;
49
    }
50
51 99
    public function validate($data, $rules = [], $extraFieldsAllowed = null)
52
    {
53 99
        if ($extraFieldsAllowed !== null) $this->setExtraFieldsAllowed($extraFieldsAllowed);
54
55 99
        $processedFields = [];
56 99
        foreach ($rules as $fieldName => $fieldRules) {
57 99
            $processedFields[] = $fieldName;
58
59
            /** Custom validation of 'required' property */
60 99
            if (array_key_exists('required', $fieldRules)) {
61 86
                unset($fieldRules['required']);
62
63 86
                if (!array_key_exists($fieldName, $data)) {
64 12
                    $this->addError(new ValidationException(sprintf('Field "%s" is required', $fieldName)));
65
66 86
                    continue;
67
                }
68 98
            } elseif (!array_key_exists($fieldName, $data)) {
69 94
                continue;
70
            }
71 98
            if (!empty($fieldRules['final'])) unset($fieldRules['final']);
72
73
            /** Validation of all other rules*/
74 98
            foreach ($fieldRules as $ruleName => $ruleInfo) {
75 98
                if (!array_key_exists($ruleName, $this->validationRules)) {
76 1
                    $this->addError(new ValidationException(sprintf('Field "%s" has invalid rule "%s"', $fieldName, $ruleInfo)));
77
78 1
                    continue;
79
                }
80
81 98
                if (!$this->validationRules[$ruleName]->validate($data[$fieldName], $ruleInfo)) {
82 98
                    $this->addError(new ValidationException(sprintf('Field "%s" expected to be "%s" but got "%s"', $fieldName, $ruleName, gettype($data[$fieldName]))));
83
                }
84
            }
85
        }
86
87 99
        if (!$this->isExtraFieldsAllowed()) {
88 3
            foreach (array_keys($data) as $fieldName) {
89 3
                if (!in_array($fieldName, $processedFields)) {
90 3
                    $this->addError(new ValidationException(sprintf('Field "%s" is not expected', $fieldName)));
91
                }
92
            }
93
        }
94
95 99
        return $this->isValid();
96
    }
97
98
    protected function initializeRules()
99
    {
100
        $this->validationRules['type'] = new TypeValidationRule($this);
101
    }
102
103
    public function addRule($name, ValidationRuleInterface $rule)
104
    {
105
        $this->validationRules[$name] = $rule;
106
    }
107
108 99
    public function isValid()
109
    {
110 99
        return !$this->hasErrors();
111
    }
112
113
114
    /**
115
     * @return boolean
116
     */
117 99
    public function isExtraFieldsAllowed()
118
    {
119 99
        return $this->extraFieldsAllowed;
120
    }
121
122
    /**
123
     * @param boolean $extraFieldsAllowed
124
     *
125
     * @return ConfigValidator
126
     */
127 1
    public function setExtraFieldsAllowed($extraFieldsAllowed)
128
    {
129 1
        $this->extraFieldsAllowed = $extraFieldsAllowed;
130
131 1
        return $this;
132
    }
133
134
}
135