CsvValidator::validateEmptyColumns()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
c 0
b 0
f 0
rs 9.8333
cc 3
nc 2
nop 2
1
<?php
2
3
namespace Toa\Component\Validator\Constraints;
4
5
use Symfony\Component\Validator\Constraint;
6
use Symfony\Component\Validator\Constraints\FileValidator;
7
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
8
use Toa\Component\Validator\Provider\CsvProviderInterface;
9
10
/**
11
 * Class CsvValidator
12
 *
13
 * @author Enrico Thies <[email protected]>
14
 */
15
class CsvValidator extends FileValidator
16
{
17
    /** @var ProviderInterface */
18
    protected $provider;
19
20
    /**
21
     * @param CsvProviderInterface $provider
22
     */
23
    public function __construct(CsvProviderInterface $provider)
24
    {
25
        $this->provider = $provider;
0 ignored issues
show
Documentation Bug introduced by
It seems like $provider of type object<Toa\Component\Val...r\CsvProviderInterface> is incompatible with the declared type object<Toa\Component\Val...ints\ProviderInterface> of property $provider.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
26
    }
27
28
    /**
29
     * {@inheritdoc}
30
     */
31
    public function validate($value, Constraint $constraint)
32
    {
33
        $violations = count($this->context->getViolations());
34
35
        parent::validate($value, $constraint);
36
37
        $failed = count($this->context->getViolations()) !== $violations;
38
39
        if ($failed || null === $value || '' === $value) {
40
            return;
41
        }
42
43
        $path = $value instanceof \SplFileInfo ? $value->getPathname() : (string) $value;
44
45
        $this->validateDelimiter($constraint);
46
        $this->validateEnclosure($constraint);
47
        $this->validateEscape($constraint);
48
49
        $config = array(
50
            'delimiter' => $constraint->delimiter,
51
            'enclosure' => $constraint->enclosure,
52
            'escape'    => $constraint->escape,
53
        );
54
55
        $rows = $this->provider->countRows($path, $config);
56
57
        if ($this->validateMaxRows($rows, $constraint)) {
58
            return;
59
        }
60
61
        if ($this->validateMinRows($rows, $constraint)) {
62
            return;
63
        }
64
65
        $columnsSizes = $this->provider->collectColumnSizes($path, $config);
66
67
        if ($this->validateEmptyColumns($columnsSizes, $constraint)) {
68
            return;
69
        }
70
71
        if ($this->validateMaxColumns($columnsSizes, $constraint)) {
72
            return;
73
        }
74
75
        if ($this->validateMinColumns($columnsSizes, $constraint)) {
76
            return;
77
        }
78
    }
79
80
    /**
81
     * @param Constraint $constraint
82
     *
83
     * @throws ConstraintDefinitionException
84
     */
85
    protected function validateDelimiter(Constraint $constraint)
86
    {
87
        if (strlen($constraint->delimiter) > 2) {
88
            throw new ConstraintDefinitionException(sprintf('"%s" is not a valid delimiter', $constraint->delimiter));
89
        }
90
    }
91
92
    /**
93
     * @param Constraint $constraint
94
     *
95
     * @throws ConstraintDefinitionException
96
     */
97
    protected function validateEnclosure(Constraint $constraint)
98
    {
99
        if (strlen($constraint->enclosure) > 2) {
100
            throw new ConstraintDefinitionException(sprintf('"%s" is not a valid enclosure', $constraint->enclosure));
101
        }
102
    }
103
104
    /**
105
     * @param Constraint $constraint
106
     *
107
     * @throws ConstraintDefinitionException
108
     */
109
    protected function validateEscape(Constraint $constraint)
110
    {
111
        if (strlen($constraint->escape) > 2) {
112
            throw new ConstraintDefinitionException(sprintf('"%s" is not a valid escape', $constraint->escape));
113
        }
114
    }
115
116
    /**
117
     * @param array      $columnsSizes
118
     * @param Constraint $constraint
119
     *
120
     * @throws ConstraintDefinitionException
121
     * @return boolean
122
     */
123
    protected function validateEmptyColumns($columnsSizes, Constraint $constraint)
124
    {
125
        if (!$constraint->ignoreEmptyColumns && isset($columnsSizes[0])) {
126
            $this->context->addViolation(
127
                $constraint->emptyColumnsMessage,
128
                array(
129
                    '{{ occurrences }}' => implode(',', $columnsSizes[0])
130
                )
131
            );
132
133
            return true;
134
        }
135
    }
136
137
    /**
138
     * @param array      $columnsSizes
139
     * @param Constraint $constraint
140
     *
141
     * @throws ConstraintDefinitionException
142
     * @return boolean
143
     */
144
    protected function validateMaxColumns($columnsSizes, Constraint $constraint)
145
    {
146
        if (null !== $constraint->maxColumns) {
147
            if (!ctype_digit((string) $constraint->maxColumns)) {
148
                throw new ConstraintDefinitionException(
149
                    sprintf(
150
                        '"%s" is not a valid column size',
151
                        $constraint->maxColumns
152
                    )
153
                );
154
            }
155
156
            foreach ($columnsSizes as $size => $occurrences) {
157
                if ($size > $constraint->maxColumns) {
158
                    $this->context->addViolation(
159
                        $constraint->maxColumnsMessage,
160
                        array(
161
                            '{{ max_columns }}' => $constraint->maxColumns,
162
                            '{{ occurrences }}' => implode(',', $occurrences)
163
                        )
164
                    );
165
166
                    return true;
167
                }
168
            }
169
        }
170
    }
171
172
    /**
173
     * @param array      $columnsSizes
174
     * @param Constraint $constraint
175
     *
176
     * @throws ConstraintDefinitionException
177
     * @return boolean
178
     */
179
    protected function validateMinColumns($columnsSizes, Constraint $constraint)
180
    {
181
        if (null !== $constraint->minColumns) {
182
            if (!ctype_digit((string) $constraint->minColumns)) {
183
                throw new ConstraintDefinitionException(
184
                    sprintf(
185
                        '"%s" is not a valid column size',
186
                        $constraint->minColumns
187
                    )
188
                );
189
            }
190
191
            foreach ($columnsSizes as $size => $occurrences) {
192
                if (0 !== $size && $size < $constraint->minColumns) {
193
                    $this->context->addViolation(
194
                        $constraint->minColumnsMessage,
195
                        array(
196
                            '{{ min_columns }}' => $constraint->minColumns,
197
                            '{{ occurrences }}' => implode(',', $occurrences)
198
                        )
199
                    );
200
201
                    return true;
202
                }
203
            }
204
        }
205
    }
206
207
    /**
208
     * @param integer    $rows
209
     * @param Constraint $constraint
210
     *
211
     * @throws ConstraintDefinitionException
212
     * @return boolean
213
     */
214
    protected function validateMaxRows($rows, Constraint $constraint)
215
    {
216
        if (null !== $constraint->maxRows) {
217
            if (!ctype_digit((string) $constraint->maxRows)) {
218
                throw new ConstraintDefinitionException(
219
                    sprintf(
220
                        '"%s" is not a valid row size',
221
                        $constraint->maxRows
222
                    )
223
                );
224
            }
225
226
            if ($rows > $constraint->maxRows) {
227
                $this->context->addViolation(
228
                    $constraint->maxRowsMessage,
229
                    array(
230
                        '{{ max_rows }}' => $constraint->maxRows,
231
                    )
232
                );
233
234
                return true;
235
            }
236
        }
237
    }
238
239
    /**
240
     * @param integer    $rows
241
     * @param Constraint $constraint
242
     *
243
     * @throws ConstraintDefinitionException
244
     * @return boolean
245
     */
246
    protected function validateminRows($rows, Constraint $constraint)
247
    {
248
        if (null !== $constraint->minRows) {
249
            if (!ctype_digit((string) $constraint->minRows)) {
250
                throw new ConstraintDefinitionException(
251
                    sprintf(
252
                        '"%s" is not a valid row size',
253
                        $constraint->minRows
254
                    )
255
                );
256
            }
257
258
            if ($rows < $constraint->minRows) {
259
                $this->context->addViolation(
260
                    $constraint->minRowsMessage,
261
                    array(
262
                        '{{ min_rows }}' => $constraint->minRows,
263
                    )
264
                );
265
266
                return true;
267
            }
268
        }
269
    }
270
}
271