Completed
Push — master ( d8a5e5...b3757c )
by ignace nyamagana
03:17
created

Controls::validateInteger()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 9.4286
cc 2
eloc 4
nc 2
nop 3
crap 2
1
<?php
2
/**
3
* This file is part of the League.csv library
4
*
5
* @license http://opensource.org/licenses/MIT
6
* @link https://github.com/thephpleague/csv/
7
* @version 8.0.0
8
* @package League.csv
9
*
10
* For the full copyright and license information, please view the LICENSE
11
* file that was distributed with this source code.
12
*/
13
namespace League\Csv\Config;
14
15
use CallbackFilterIterator;
16
use InvalidArgumentException;
17
use LimitIterator;
18
use SplFileObject;
19
20
/**
21
 *  A trait to configure and check CSV file and content
22
 *
23
 * @package League.csv
24
 * @since  6.0.0
25
 *
26
 */
27
trait Controls
28
{
29
    /**
30
     * the field delimiter (one character only)
31
     *
32
     * @var string
33
     */
34
    protected $delimiter = ',';
35
36
    /**
37
     * the field enclosure character (one character only)
38
     *
39
     * @var string
40
     */
41
    protected $enclosure = '"';
42
43
    /**
44
     * the field escape character (one character only)
45
     *
46
     * @var string
47
     */
48
    protected $escape = '\\';
49
50
    /**
51
     * newline character
52
     *
53
     * @var string
54
     */
55
    protected $newline = "\n";
56
57
    /**
58
     * Sets the field delimiter
59
     *
60
     * @param string $delimiter
61
     *
62
     * @throws InvalidArgumentException If $delimiter is not a single character
63
     *
64
     * @return $this
65
     */
66 2
    public function setDelimiter($delimiter)
67
    {
68 2
        if (!$this->isValidCsvControls($delimiter)) {
69 2
            throw new InvalidArgumentException('The delimiter must be a single character');
70
        }
71 2
        $this->delimiter = $delimiter;
72
73 2
        return $this;
74
    }
75
76
    /**
77
     * Tell whether the submitted string is a valid CSV Control character
78
     *
79
     * @param string $str The submitted string
80
     *
81
     * @return bool
82
     */
83 12
    protected function isValidCsvControls($str)
84
    {
85 12
        return 1 == mb_strlen($str);
86
    }
87
88
    /**
89
     * Returns the current field delimiter
90
     *
91
     * @return string
92
     */
93 2
    public function getDelimiter()
94
    {
95 2
        return $this->delimiter;
96
    }
97
98
    /**
99
     * Detect Delimiters occurences in the CSV
100
     *
101
     * Returns a associative array where each key represents
102
     * a valid delimiter and each value the number of occurences
103
     *
104
     * @param string[] $delimiters the delimiters to consider
105
     * @param int      $nb_rows    Detection is made using $nb_rows of the CSV
106
     *
107
     * @return array
108
     */
109 8
    public function fetchDelimitersOccurrence(array $delimiters, $nb_rows = 1)
110
    {
111 8
        $nb_rows = $this->validateInteger($nb_rows, 1, 'The number of rows to consider must be a valid positive integer');
112 6
        $filterRow = function ($row) {
113 6
            return is_array($row) && count($row) > 1;
114 6
        };
115 6
        $delimiters = array_unique(array_filter($delimiters, [$this, 'isValidCsvControls']));
116 6
        $csv = $this->getIterator();
117 6
        $res = [];
118 6
        foreach ($delimiters as $delim) {
119 6
            $csv->setCsvControl($delim, $this->enclosure, $this->escape);
120 6
            $iterator = new CallbackFilterIterator(new LimitIterator($csv, 0, $nb_rows), $filterRow);
121 6
            $res[$delim] = count(iterator_to_array($iterator, false), COUNT_RECURSIVE);
122 6
        }
123 6
        arsort($res, SORT_NUMERIC);
124
125 6
        return $res;
126
    }
127
128
    /**
129
     * Validate an integer
130
     *
131
     * @param int    $int
132
     * @param int    $minValue
133
     * @param string $errorMessage
134
     *
135
     * @throws InvalidArgumentException If the value is invalid
136
     *
137
     * @return int
138
     */
139 76
    protected function validateInteger($int, $minValue, $errorMessage)
140
    {
141 76
        if (false === ($int = filter_var($int, FILTER_VALIDATE_INT, ['options' => ['min_range' => $minValue]]))) {
142 12
            throw new InvalidArgumentException($errorMessage);
143
        }
144 66
        return $int;
145
    }
146
147
    /**
148
     * Returns the CSV Iterator
149
     *
150
     * @return SplFileObject
151
     */
152
    abstract public function getIterator();
153
154
    /**
155
     * Sets the field enclosure
156
     *
157
     * @param string $enclosure
158
     *
159
     * @throws InvalidArgumentException If $enclosure is not a single character
160
     *
161
     * @return $this
162
     */
163 2
    public function setEnclosure($enclosure)
164
    {
165 2
        if (!$this->isValidCsvControls($enclosure)) {
166 2
            throw new InvalidArgumentException('The enclosure must be a single character');
167
        }
168 2
        $this->enclosure = $enclosure;
169
170 2
        return $this;
171
    }
172
173
    /**
174
     * Returns the current field enclosure
175
     *
176
     * @return string
177
     */
178 16
    public function getEnclosure()
179
    {
180 16
        return $this->enclosure;
181
    }
182
183
    /**
184
     * Sets the field escape character
185
     *
186
     * @param string $escape
187
     *
188
     * @throws InvalidArgumentException If $escape is not a single character
189
     *
190
     * @return $this
191
     */
192 2
    public function setEscape($escape)
193
    {
194 2
        if (!$this->isValidCsvControls($escape)) {
195 2
            throw new InvalidArgumentException('The escape character must be a single character');
196
        }
197 2
        $this->escape = $escape;
198
199 2
        return $this;
200
    }
201
202
    /**
203
     * Returns the current field escape character
204
     *
205
     * @return string
206
     */
207 2
    public function getEscape()
208
    {
209 2
        return $this->escape;
210
    }
211
212
    /**
213
     * Sets the newline sequence characters
214
     *
215
     * @param string $newline
216
     *
217
     * @return static
218
     */
219 4
    public function setNewline($newline)
220
    {
221 4
        $this->newline = (string) $newline;
222
223 4
        return $this;
224
    }
225
226
    /**
227
     * Returns the current newline sequence characters
228
     *
229
     * @return string
230
     */
231 4
    public function getNewline()
232
    {
233 4
        return $this->newline;
234
    }
235
}
236