Passed
Push — master ( 6ec87a...fbe757 )
by George
03:22
created

Analyse::instantiateValidator()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 25
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 7.0222

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 25
ccs 12
cts 13
cp 0.9231
rs 6.7272
cc 7
eloc 12
nc 6
nop 2
crap 7.0222
1
<?php
2
namespace JsonTable\Analyse;
3
4
use \JsonTable\Base;
5
6
/**
7
 * Analyse data to ensure it validates against a JSON table schema.
8
 *
9
 * @package    JSON table
10
 */
11
class Analyse extends Base implements AnalyseInterface
12
{
13
    /**
14
     * @var string The format validation type.
15
     */
16
    const VALIDATION_TYPE_FORMAT = 'Format';
17
    
18
    /**
19
     * @var string The foreign key validation type.
20
     */
21
    const VALIDATION_TYPE_FOREIGN_KEY = 'ForeignKey';
22
23
    /**
24
     * @var boolean Should the analysis stop when an error is found.
25
     */
26
    protected $stopIfInvalid;
27
28
    /**
29
     * @var Statistics  Statistics information regarding the analysis.
30
     */
31
    protected $statistics;
32
33
    /**
34
     * @var Error  Details of errors found during the analysis.
35
     */
36
    protected $error;
37
38
39
    /**
40
     * Set the dependencies if they've been provided.
41
     *
42
     * @param   Statistics  $statistics Statistics information regarding the analysis. Optional.
43
     * @param   Error       $error      Details of errors found during the analysis. Optional.
44
     */
45 44
    public function __construct(Statistics $statistics = null, Error $error = null)
46
    {
47 44
        $this->statistics = (is_null($statistics)) ? new Statistics() : $statistics;
48 44
        $this->error = (is_null($error)) ? new Error() : $error;
49 44
    }
50
51
52
    /**
53
     * Analyse the specified file against the loaded schema.
54
     *
55
     * @param   boolean $stopIfInvalid Should the analysis stop when the file is found to be invalid.
56
     *                                          The default is false.
57
     *
58
     * @return  boolean true if the file passes the validation and false if not.
59
     */
60 41
    public function validate($stopIfInvalid = false)
61
    {
62 41
        $this->stopIfInvalid = (bool) $stopIfInvalid;
63
64 41
        $continueAnalysis = true;
65
66 41
        self::openFile();
67 40
        self::setCsvHeaderColumns();
68
69 40
        $analyseColumns = new Column($this->statistics, $this->error);
70
71 40
        if (!$analyseColumns->validate()) {
72 2
            $continueAnalysis = false;
73 2
        }
74
75 40
        $analyseLexical = new Lexical($this->statistics, $this->error);
76
77 40
        if ($continueAnalysis && !$analyseLexical->validate() && $this->stopIfInvalid) {
78
            $continueAnalysis = false;
79
        }
80
81 39
        $analysePrimaryKey = new PrimaryKey($this->statistics, $this->error);
82
        
83 39
        if ($continueAnalysis && !$analysePrimaryKey->validate() && $this->stopIfInvalid) {
84
            $continueAnalysis = false;
85
        }
86
87 39
        if ($continueAnalysis) {
88 37
            $analyseForeignKey = new ForeignKey($this->statistics, $this->error);
89 37
            $analyseForeignKey->validate();
90 37
        }
91
92 39
        return $this->isFileValid();
93
    }
94
95
96
    /**
97
     * Return all errors.
98
     *
99
     * @return  array   The error messages.
100
     */
101 3
    public function getErrors()
102
    {
103 3
        return $this->error->getErrors();
104
    }
105
106
107
    /**
108
     * Return the statistics about this analysis.
109
     *
110
     * @return  array   The statistics.
111
     */
112 20
    public function getStatistics()
113
    {
114 20
        return $this->statistics->getStatistics();
115
    }
116
117
118
    /**
119
     * Check if the specified column is mandatory.
120
     *
121
     * @param   object  $schemaColumn    The schema column object to examine.
122
     *
123
     * @return  boolean Whether the column is mandatory.
124
     */
125 40
    protected function isColumnMandatory($schemaColumn)
126
    {
127 40
        $propertyExists = property_exists($schemaColumn, 'constraints') &&
128 40
                              property_exists($schemaColumn->constraints, 'required') &&
129 40
                              (true === $schemaColumn->constraints->required);
130 40
        return $propertyExists;
131
    }
132
133
134
    /**
135
     * Load and instantiate the specified validator.
136
     *
137
     * @param string $validationType The type of validator to load.
138
     * @param string $type The type being validated.
139
     *                            For formats this will be the field type.
140
     *                            For foreign keys this will be the datapackage type
141
     *
142
     * @return object The validation object. Throws an exception on error.
143
     *
144
     * @throws  \Exception if the validator file couldn't be loaded.
145
     * @throws  \Exception if the validator class definition couldn't be found.
146
     */
147 38
    protected function instantiateValidator($validationType, $type)
148
    {
149
        // For format validation, "Date", "datetime" and "time" all follow the same schema definition rules
150
        // so just use the datetime format for them all.
151 38
        if (Analyse::VALIDATION_TYPE_FORMAT === $validationType && ('date' === $type || 'time' === $type)) {
152 10
            $type = 'datetime';
153 10
        }
154
155 38
        $typeClassName = ucwords($type) . 'Validator';
156 38
        $validatorFile = dirname(dirname(__FILE__)) . "/Validate/$validationType/$typeClassName.php";
157
158 38
        if (!file_exists($validatorFile) || !is_readable($validatorFile)) {
159 1
            throw new \Exception("Could not load the validator file for $validationType $type.");
160
        }
161
162 37
        include_once $validatorFile;
163
164 37
        $validatorClass = "\\JsonTable\\Validate\\$validationType\\$typeClassName";
165
166 37
        if (!class_exists($validatorClass)) {
167
            throw new \Exception("Could not find the validator class $validatorClass");
168
        }
169
170 37
        return new $validatorClass($type);
171
    }
172
173
174
    /**
175
     * Check if the file was found to be valid.
176
     * This checks for any validation errors.
177
     *
178
     * @return  boolean Is the file valid.
179
     */
180 39
    private function isFileValid()
181
    {
182 39
        return (0 === count($this->error->getErrors()));
183
    }
184
}
185