171 lines
3.9 KiB
PHP
171 lines
3.9 KiB
PHP
<?php
|
|
/**
|
|
* This file is part of the League.csv library
|
|
*
|
|
* @license http://opensource.org/licenses/MIT
|
|
* @link https://github.com/thephpleague/csv/
|
|
* @version 8.2.3
|
|
* @package League.csv
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
namespace League\Csv;
|
|
|
|
use InvalidArgumentException;
|
|
use League\Csv\Modifier\RowFilter;
|
|
use League\Csv\Modifier\StreamIterator;
|
|
use ReflectionMethod;
|
|
use RuntimeException;
|
|
use SplFileObject;
|
|
use Traversable;
|
|
|
|
/**
|
|
* A class to manage data insertion into a CSV
|
|
*
|
|
* @package League.csv
|
|
* @since 4.0.0
|
|
*
|
|
*/
|
|
class Writer extends AbstractCsv
|
|
{
|
|
use RowFilter;
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
protected $stream_filter_mode = STREAM_FILTER_WRITE;
|
|
|
|
/**
|
|
* The CSV object holder
|
|
*
|
|
* @var SplFileObject|StreamIterator
|
|
*/
|
|
protected $csv;
|
|
|
|
/**
|
|
* fputcsv method from SplFileObject or StreamIterator
|
|
*
|
|
* @var ReflectionMethod
|
|
*/
|
|
protected $fputcsv;
|
|
|
|
/**
|
|
* Nb parameters for SplFileObject::fputcsv method
|
|
*
|
|
* @var integer
|
|
*/
|
|
protected $fputcsv_param_count;
|
|
|
|
/**
|
|
* Adds multiple lines to the CSV document
|
|
*
|
|
* a simple wrapper method around insertOne
|
|
*
|
|
* @param Traversable|array $rows a multidimensional array or a Traversable object
|
|
*
|
|
* @throws InvalidArgumentException If the given rows format is invalid
|
|
*
|
|
* @return static
|
|
*/
|
|
public function insertAll($rows)
|
|
{
|
|
if (!is_array($rows) && !$rows instanceof Traversable) {
|
|
throw new InvalidArgumentException(
|
|
'the provided data must be an array OR a `Traversable` object'
|
|
);
|
|
}
|
|
|
|
foreach ($rows as $row) {
|
|
$this->insertOne($row);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Adds a single line to a CSV document
|
|
*
|
|
* @param string[]|string $row a string, an array or an object implementing to '__toString' method
|
|
*
|
|
* @return static
|
|
*/
|
|
public function insertOne($row)
|
|
{
|
|
if (!is_array($row)) {
|
|
$row = str_getcsv($row, $this->delimiter, $this->enclosure, $this->escape);
|
|
}
|
|
$row = $this->formatRow($row);
|
|
$this->validateRow($row);
|
|
$this->addRow($row);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Add new record to the CSV document
|
|
*
|
|
* @param array $row record to add
|
|
*/
|
|
protected function addRow(array $row)
|
|
{
|
|
$this->initCsv();
|
|
if (!$this->fputcsv->invokeArgs($this->csv, $this->getFputcsvParameters($row))) {
|
|
throw new RuntimeException('Unable to write record to the CSV document.');
|
|
}
|
|
|
|
if ("\n" !== $this->newline) {
|
|
$this->csv->fseek(-1, SEEK_CUR);
|
|
$this->csv->fwrite($this->newline, strlen($this->newline));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initialize the CSV object and settings
|
|
*/
|
|
protected function initCsv()
|
|
{
|
|
if (null !== $this->csv) {
|
|
return;
|
|
}
|
|
|
|
$this->csv = $this->getIterator();
|
|
$this->fputcsv = new ReflectionMethod(get_class($this->csv), 'fputcsv');
|
|
$this->fputcsv_param_count = $this->fputcsv->getNumberOfParameters();
|
|
}
|
|
|
|
/**
|
|
* returns the parameters for SplFileObject::fputcsv
|
|
*
|
|
* @param array $fields The fields to be add
|
|
*
|
|
* @return array
|
|
*/
|
|
protected function getFputcsvParameters(array $fields)
|
|
{
|
|
$parameters = [$fields, $this->delimiter, $this->enclosure];
|
|
if (4 == $this->fputcsv_param_count) {
|
|
$parameters[] = $this->escape;
|
|
}
|
|
|
|
return $parameters;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function isActiveStreamFilter()
|
|
{
|
|
return parent::isActiveStreamFilter() && null === $this->csv;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function __destruct()
|
|
{
|
|
$this->csv = null;
|
|
parent::__destruct();
|
|
}
|
|
}
|