Completed
Pull Request — master (#178)
by ignace nyamagana
40:39
created

AbstractCsv::createFromFileObject()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 5
Bugs 1 Features 0
Metric Value
c 5
b 1
f 0
dl 0
loc 12
ccs 5
cts 5
cp 1
rs 9.4285
cc 2
eloc 8
nc 2
nop 1
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.1.1
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;
14
15
use InvalidArgumentException;
16
use IteratorAggregate;
17
use League\Csv\Config\Controls;
18
use League\Csv\Config\StreamFilter;
19
use SplFileInfo;
20
use SplFileObject;
21
use SplTempFileObject;
22
23
/**
24
 *  An abstract class to enable basic CSV manipulation
25
 *
26
 * @package League.csv
27
 * @since  4.0.0
28
 *
29
 */
30
abstract class AbstractCsv implements IteratorAggregate
31
{
32
    use Controls;
33
34
    use StreamFilter;
35
36
    /**
37
     *  UTF-8 BOM sequence
38
     */
39
    const BOM_UTF8 = "\xEF\xBB\xBF";
40
41
    /**
42
     * UTF-16 BE BOM sequence
43
     */
44
    const BOM_UTF16_BE = "\xFE\xFF";
45
46
    /**
47
     * UTF-16 LE BOM sequence
48
     */
49
    const BOM_UTF16_LE = "\xFF\xFE";
50
51
    /**
52
     * UTF-32 BE BOM sequence
53
     */
54
    const BOM_UTF32_BE = "\x00\x00\xFE\xFF";
55
56
    /**
57
     * UTF-32 LE BOM sequence
58
     */
59
    const BOM_UTF32_LE = "\x00\x00\xFF\xFE";
60
61
    /**
62
     * The constructor path
63
     *
64
     * can be a SplFileInfo object or the string path to a file
65
     *
66
     * @var SplFileObject|string
67
     */
68
    protected $path;
69
70
    /**
71
     * The file open mode flag
72
     *
73
     * @var string
74
     */
75
    protected $open_mode;
76
77
    /**
78
     * Creates a new instance
79
     *
80
     * The path must be an SplFileInfo object
81
     * an object that implements the `__toString` method
82
     * a path to a file
83
     *
84
     * @param SplFileObject|string $path      The file path
85
     * @param string               $open_mode The file open mode flag
86
     */
87
    protected function __construct($path, $open_mode = 'r+')
88
    {
89
        $this->open_mode = strtolower($open_mode);
90
        $this->path = $path;
91
        $this->initStreamFilter($this->path);
92
    }
93
94
    /**
95
     * The destructor
96
     */
97
    public function __destruct()
98
    {
99
        $this->path = null;
100
    }
101
102
    /**
103
     * Return a new {@link AbstractCsv} from a SplFileObject
104
     *
105 357
     * @param SplFileObject $file
106
     *
107 357
     * @return static
108 357
     */
109 357
    public static function createFromFileObject(SplFileObject $file)
110 357
    {
111
        $csv = new static($file);
112
        $controls = $file->getCsvControl();
113
        $csv->setDelimiter($controls[0]);
114
        $csv->setEnclosure($controls[1]);
115 240
        if (isset($controls[2])) {
116
            $csv->setEscape($controls[2]);
117 240
        }
118 240
119
        return $csv;
120
    }
121
122
    /**
123
     * Return a new {@link AbstractCsv} from a string
124
     *
125
     * The string must be an object that implements the `__toString` method,
126
     * or a string
127 312
     *
128
     * @param string|object $str the string
129 312
     *
130
     * @return static
131
     */
132
    public static function createFromString($str)
133
    {
134
        $file = new SplTempFileObject();
135
        $file->fwrite(static::validateString($str));
136
137
        return new static($file);
138
    }
139
140
    /**
141
     * validate a string
142 27
     *
143
     * @param mixed $str the value to evaluate as a string
144 27
     *
145 27
     * @throws InvalidArgumentException if the submitted data can not be converted to string
146
     *
147 27
     * @return string
148
     */
149
    protected static function validateString($str)
150
    {
151
        if (is_string($str) || (is_object($str) && method_exists($str, '__toString'))) {
152
            return (string) $str;
153
        }
154
        throw new InvalidArgumentException('Expected data must be a string or stringable');
155
    }
156
157
    /**
158
     * Return a new {@link AbstractCsv} from a string
159 90
     *
160
     * @param mixed  $path      file path
161 90
     * @param string $open_mode the file open mode flag
162 87
     *
163
     * @throws InvalidArgumentException If $path is a SplTempFileObject object
164 3
     *
165
     * @return static
166
     */
167
    public static function createFromPath($path, $open_mode = 'r+')
168
    {
169
        if ($path instanceof SplTempFileObject) {
170
            throw new InvalidArgumentException('an `SplTempFileObject` object does not contain a valid path');
171
        }
172
173
        if ($path instanceof SplFileInfo) {
174
            $path = $path->getPath().'/'.$path->getBasename();
175
        }
176
177 54
        return new static(static::validateString($path), $open_mode);
178
    }
179 54
180 3
    /**
181
     * Return a new {@link AbstractCsv} instance from another {@link AbstractCsv} object
182
     *
183 51
     * @param string $class     the class to be instantiated
184 3
     * @param string $open_mode the file open mode flag
185 2
     *
186
     * @return static
187 51
     */
188
    protected function newInstance($class, $open_mode)
189
    {
190
        $csv = new $class($this->path, $open_mode);
191
        $csv->delimiter = $this->delimiter;
192
        $csv->enclosure = $this->enclosure;
193
        $csv->escape = $this->escape;
194
        $csv->input_encoding = $this->input_encoding;
195
        $csv->input_bom = $this->input_bom;
196
        $csv->output_bom = $this->output_bom;
197
        $csv->newline = $this->newline;
198 6
199
        return $csv;
200 6
    }
201 6
202 6
    /**
203 6
     * Return a new {@link Writer} instance from a {@link AbstractCsv} object
204 6
     *
205 6
     * @param string $open_mode the file open mode flag
206 6
     *
207 6
     * @return Writer
208
     */
209 6
    public function newWriter($open_mode = 'r+')
210
    {
211
        return $this->newInstance(Writer::class, $open_mode);
212
    }
213
214
    /**
215
     * Return a new {@link Reader} instance from a {@link AbstractCsv} object
216
     *
217
     * @param string $open_mode the file open mode flag
218
     *
219 3
     * @return Reader
220
     */
221 3
    public function newReader($open_mode = 'r+')
222
    {
223
        return $this->newInstance(Reader::class, $open_mode);
224
    }
225
226
    /**
227
     * Returns the inner SplFileObject
228
     *
229
     * @return SplFileObject
230
     */
231 3
    public function getIterator()
232
    {
233 3
        $iterator = $this->path;
234
        if (!$iterator instanceof SplFileObject) {
235
            $iterator = new SplFileObject($this->getStreamFilterPath(), $this->open_mode);
236
        }
237
        $iterator->setCsvControl($this->delimiter, $this->enclosure, $this->escape);
238
        $iterator->setFlags(SplFileObject::READ_CSV | SplFileObject::READ_AHEAD | SplFileObject::SKIP_EMPTY);
239
240
        return $iterator;
241 267
    }
242
243 267
    /**
244 267
     * Returns the Record object
245 33
     *
246 22
     * @param Query|null $query
247 267
     *
248 267
     * @return Records
249
     */
250 267
    public function getRecords(Query $query = null)
251
    {
252
        return new Records($this, $query ?: new Query());
253
    }
254
}
255