Compare commits
No commits in common. "master" and "v2" have entirely different histories.
14
.php-censor.yml
Normal file
14
.php-censor.yml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
build_settings:
|
||||||
|
verbose: true
|
||||||
|
prefer_symlink: false
|
||||||
|
|
||||||
|
setup:
|
||||||
|
composer:
|
||||||
|
action: "install"
|
||||||
|
|
||||||
|
test:
|
||||||
|
php_unit:
|
||||||
|
directory: "tests/"
|
||||||
|
args: "--configuration 'phpunit.xml'"
|
||||||
|
|
||||||
|
complete:
|
|
@ -1,17 +0,0 @@
|
||||||
matrix:
|
|
||||||
PHP_VERSION:
|
|
||||||
- 7.3
|
|
||||||
- 7.4
|
|
||||||
- 8.0
|
|
||||||
- 8.1
|
|
||||||
|
|
||||||
pipeline:
|
|
||||||
dependencies:
|
|
||||||
image: gitnet.fr/deblan/php:${PHP_VERSION}
|
|
||||||
commands:
|
|
||||||
- php /usr/local/bin/composer install
|
|
||||||
- php /usr/local/bin/composer require --dev phpunit/phpunit
|
|
||||||
tests:
|
|
||||||
image: gitnet.fr/deblan/php:${PHP_VERSION}
|
|
||||||
commands:
|
|
||||||
- php ./vendor/bin/phpunit
|
|
32
README.md
32
README.md
|
@ -1,20 +1,14 @@
|
||||||
CSV parser/generator
|
CSV parser/generator
|
||||||
====================
|
====================
|
||||||
|
|
||||||
[![Build Status](https://ci.gitnet.fr/api/badges/deblan/csv/status.svg)](https://ci.gitnet.fr/deblan/csv)
|
<a href="https://phpci.gitnet.fr/build-status/view/2">![](https://phpci.gitnet.fr/build-status/image/2?branch=master&label=PHPCensor&style=flat-square)</a>
|
||||||
|
|
||||||
A simple PHP library to:
|
A simple PHP library to parse and generate CSV files.
|
||||||
|
|
||||||
* parse a CSV file
|
|
||||||
* parse a stream as CSV datas
|
|
||||||
* generate CSV files.
|
|
||||||
|
|
||||||
PHP >= 7.1 required.
|
|
||||||
|
|
||||||
## Composer installation
|
## Composer installation
|
||||||
|
|
||||||
```
|
```
|
||||||
$ composer require deblan/csv "~3"
|
$ composer require deblan/csv "~2"
|
||||||
```
|
```
|
||||||
|
|
||||||
Or in your composer.json:
|
Or in your composer.json:
|
||||||
|
@ -22,7 +16,7 @@ Or in your composer.json:
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"require": {
|
"require": {
|
||||||
"deblan/csv": "~3"
|
"deblan/csv": "~2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -73,7 +67,7 @@ $result = $csv->render('products.csv');
|
||||||
$result = $csv->render('products.csv', FILE_APPEND);
|
$result = $csv->render('products.csv', FILE_APPEND);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Parse a file
|
### Parser
|
||||||
|
|
||||||
```php
|
```php
|
||||||
use Deblan\Csv\CsvParser;
|
use Deblan\Csv\CsvParser;
|
||||||
|
@ -102,19 +96,3 @@ $csv->parseString($myString);
|
||||||
$headers = $csv->getHeaders();
|
$headers = $csv->getHeaders();
|
||||||
$products = $csv->getDatas();
|
$products = $csv->getDatas();
|
||||||
```
|
```
|
||||||
|
|
||||||
### Parse a stream
|
|
||||||
|
|
||||||
```php
|
|
||||||
use Deblan\Csv\CsvStreamParser;
|
|
||||||
|
|
||||||
// CsvStreamParser is a CsvParser
|
|
||||||
$csv = new CsvStreamParser();
|
|
||||||
|
|
||||||
// Parse a stream
|
|
||||||
$csv->parseStream(fopen('products.csv', 'r'));
|
|
||||||
|
|
||||||
while ($data = $csv->getData()) {
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
convertWarningsToExceptions = "true"
|
convertWarningsToExceptions = "true"
|
||||||
processIsolation = "false"
|
processIsolation = "false"
|
||||||
stopOnFailure = "false"
|
stopOnFailure = "false"
|
||||||
|
syntaxCheck = "true"
|
||||||
bootstrap = "vendor/autoload.php" >
|
bootstrap = "vendor/autoload.php" >
|
||||||
|
|
||||||
<testsuites>
|
<testsuites>
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Deblan\Csv;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class Csv.
|
|
||||||
*
|
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
|
||||||
*/
|
|
||||||
class CsvStreamParser extends CsvParser
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var resource
|
|
||||||
*/
|
|
||||||
protected $resource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
protected $length;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a stream.
|
|
||||||
*
|
|
||||||
* @param resource $resource
|
|
||||||
* @param int $length
|
|
||||||
*/
|
|
||||||
public function parseStream($resource, ? int $length = 0): void
|
|
||||||
{
|
|
||||||
if (!is_resource($resource)) {
|
|
||||||
throw new \InvalidArgumentException('First argument must be a valid resource.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->resource = $resource;
|
|
||||||
$this->length = $length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get data of the stream parsing.
|
|
||||||
*
|
|
||||||
* @return null|array
|
|
||||||
*/
|
|
||||||
public function getData(): ? array
|
|
||||||
{
|
|
||||||
$csv = fgetcsv($this->resource, $this->length, $this->delimiter, $this->enclosure);
|
|
||||||
|
|
||||||
if ($csv === false) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$isHeaders = $this->hasHeaders && empty($this->headers);
|
|
||||||
|
|
||||||
if ($isHeaders) {
|
|
||||||
$this->headers = $csv;
|
|
||||||
|
|
||||||
return $csv;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$isHeaders && $this->hasHeaders && !empty($this->headers)) {
|
|
||||||
foreach ($this->headers as $key => $header) {
|
|
||||||
$csv[$header] = isset($csv[$key]) ? $csv[$key] : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->datas[] = $csv;
|
|
||||||
|
|
||||||
return $csv;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Deblan\Csv\CsvParser;
|
use Deblan\Csv\CsvParser;
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
|
|
||||||
class CsvParserTest extends TestCase
|
class CsvParserParserTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
public function testGettersAndSettersAndDefaultValues()
|
public function testGettersAndSettersAndDefaultValues()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,176 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Deblan\Csv\CsvParser;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
use Deblan\Csv\CsvStreamParser;
|
|
||||||
|
|
||||||
class CsvParserParserTest extends CsvParserTest
|
|
||||||
{
|
|
||||||
public function testStreamParser()
|
|
||||||
{
|
|
||||||
$parser = new CsvStreamParser();
|
|
||||||
$this->assertEquals([], $parser->getDatas());
|
|
||||||
$this->assertEquals([], $parser->getHeaders());
|
|
||||||
|
|
||||||
$parser = new CsvStreamParser();
|
|
||||||
$this->expectException('\InvalidArgumentException');
|
|
||||||
$parser->parseStream(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testStreamParser2()
|
|
||||||
{
|
|
||||||
$parser = new CsvStreamParser();
|
|
||||||
$parser->setHasHeaders(true);
|
|
||||||
|
|
||||||
$parser->parseStream(fopen(__DIR__.'/fixtures/example.csv', 'r'));
|
|
||||||
$this->assertEquals([], $parser->getDatas());
|
|
||||||
$this->assertEquals([], $parser->getHeaders());
|
|
||||||
|
|
||||||
$this->assertEquals([
|
|
||||||
'FOO',
|
|
||||||
'BAR',
|
|
||||||
], $parser->getData());
|
|
||||||
$this->assertEquals([], $parser->getDatas());
|
|
||||||
$this->assertEquals(['FOO', 'BAR'], $parser->getHeaders());
|
|
||||||
|
|
||||||
$this->assertEquals([
|
|
||||||
'foo 1',
|
|
||||||
'bar 1',
|
|
||||||
'FOO' => 'foo 1',
|
|
||||||
'BAR' => 'bar 1',
|
|
||||||
], $parser->getData());
|
|
||||||
$this->assertEquals([
|
|
||||||
[
|
|
||||||
'foo 1',
|
|
||||||
'bar 1',
|
|
||||||
'FOO' => 'foo 1',
|
|
||||||
'BAR' => 'bar 1',
|
|
||||||
],
|
|
||||||
], $parser->getDatas());
|
|
||||||
$this->assertEquals(['FOO', 'BAR'], $parser->getHeaders());
|
|
||||||
|
|
||||||
$parser->getData();
|
|
||||||
$this->assertEquals([
|
|
||||||
[
|
|
||||||
'foo 1',
|
|
||||||
'bar 1',
|
|
||||||
'FOO' => 'foo 1',
|
|
||||||
'BAR' => 'bar 1',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'foo 2',
|
|
||||||
'bar 2',
|
|
||||||
'FOO' => 'foo 2',
|
|
||||||
'BAR' => 'bar 2',
|
|
||||||
],
|
|
||||||
], $parser->getDatas());
|
|
||||||
$this->assertEquals(['FOO', 'BAR'], $parser->getHeaders());
|
|
||||||
|
|
||||||
$parser->getData();
|
|
||||||
$this->assertEquals([
|
|
||||||
[
|
|
||||||
'foo 1',
|
|
||||||
'bar 1',
|
|
||||||
'FOO' => 'foo 1',
|
|
||||||
'BAR' => 'bar 1',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'foo 2',
|
|
||||||
'bar 2',
|
|
||||||
'FOO' => 'foo 2',
|
|
||||||
'BAR' => 'bar 2',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'foo 3',
|
|
||||||
'bar 3',
|
|
||||||
'FOO' => 'foo 3',
|
|
||||||
'BAR' => 'bar 3',
|
|
||||||
],
|
|
||||||
], $parser->getDatas());
|
|
||||||
$this->assertEquals(['FOO', 'BAR'], $parser->getHeaders());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testStreamParser3()
|
|
||||||
{
|
|
||||||
$parser = new CsvStreamParser();
|
|
||||||
$parser->setHasHeaders(false);
|
|
||||||
|
|
||||||
$parser->parseStream(fopen(__DIR__.'/fixtures/example.csv', 'r'));
|
|
||||||
$this->assertEquals([], $parser->getDatas());
|
|
||||||
$this->assertEquals([], $parser->getHeaders());
|
|
||||||
|
|
||||||
$this->assertEquals([
|
|
||||||
'FOO',
|
|
||||||
'BAR'
|
|
||||||
], $parser->getData());
|
|
||||||
$this->assertEquals([
|
|
||||||
[
|
|
||||||
'FOO',
|
|
||||||
'BAR'
|
|
||||||
]
|
|
||||||
], $parser->getDatas());
|
|
||||||
$this->assertEquals([], $parser->getHeaders());
|
|
||||||
|
|
||||||
$this->assertEquals([
|
|
||||||
'foo 1',
|
|
||||||
'bar 1',
|
|
||||||
], $parser->getData());
|
|
||||||
$this->assertEquals([
|
|
||||||
[
|
|
||||||
'FOO',
|
|
||||||
'BAR',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'foo 1',
|
|
||||||
'bar 1',
|
|
||||||
],
|
|
||||||
], $parser->getDatas());
|
|
||||||
$this->assertEquals([], $parser->getHeaders());
|
|
||||||
|
|
||||||
$this->assertEquals([
|
|
||||||
'foo 2',
|
|
||||||
'bar 2',
|
|
||||||
], $parser->getData());
|
|
||||||
$this->assertEquals([
|
|
||||||
[
|
|
||||||
'FOO',
|
|
||||||
'BAR',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'foo 1',
|
|
||||||
'bar 1',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'foo 2',
|
|
||||||
'bar 2',
|
|
||||||
],
|
|
||||||
], $parser->getDatas());
|
|
||||||
$this->assertEquals([], $parser->getHeaders());
|
|
||||||
|
|
||||||
$this->assertEquals([
|
|
||||||
'foo 3',
|
|
||||||
'bar 3',
|
|
||||||
], $parser->getData());
|
|
||||||
$this->assertEquals([
|
|
||||||
[
|
|
||||||
'FOO',
|
|
||||||
'BAR',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'foo 1',
|
|
||||||
'bar 1',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'foo 2',
|
|
||||||
'bar 2',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'foo 3',
|
|
||||||
'bar 3',
|
|
||||||
],
|
|
||||||
], $parser->getDatas());
|
|
||||||
$this->assertEquals([], $parser->getHeaders());
|
|
||||||
|
|
||||||
$this->assertEquals(null, $parser->getData());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +1,13 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Deblan\Csv\Csv;
|
use Deblan\Csv\Csv;
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* class CsvTest.
|
* class CsvTest.
|
||||||
*
|
*
|
||||||
* @author Simon Vieille <simon@deblan.fr>
|
* @author Simon Vieille <simon@deblan.fr>
|
||||||
*/
|
*/
|
||||||
class CsvTest extends TestCase
|
class CsvTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
public function testGettersAndSettersAndDefaultValues()
|
public function testGettersAndSettersAndDefaultValues()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue