Skip to content

Commit 7324bc8

Browse files
committed
Add HeaderStrategy
1 parent f335368 commit 7324bc8

3 files changed

Lines changed: 150 additions & 0 deletions

File tree

src/HeaderStrategy.php

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
namespace SubjectivePHP\Csv;
4+
5+
use SplFileObject;
6+
7+
final class HeaderStrategy implements HeaderStrategyInterface
8+
{
9+
/**
10+
* @var callable
11+
*/
12+
private $getHeadersCallable;
13+
14+
private function __construct(callable $getHeadersCallable)
15+
{
16+
$this->getHeadersCallable = $getHeadersCallable;
17+
}
18+
19+
/**
20+
* Create header strategy which derives the headers from the first line of the file.
21+
*
22+
* @return HeaderstrategyInterface
23+
*/
24+
public static function derive() : HeaderStrategyInterface
25+
{
26+
return new self(
27+
function (SplFileObject $fileObject) : array {
28+
$row = $fileObject->fgetcsv();
29+
$fileObject->rewind();
30+
return $row;
31+
}
32+
);
33+
}
34+
35+
/**
36+
* Create header strategy which uses the provided headers array.
37+
*
38+
* @return HeaderstrategyInterface
39+
*/
40+
public static function provide(array $headers) : HeaderStrategyInterface
41+
{
42+
return new self(
43+
function () use ($headers) : array {
44+
return $headers;
45+
}
46+
);
47+
}
48+
49+
/**
50+
* Create header strategy which generates a numeric array whose size is the number of columns in the given file.
51+
*
52+
* @return HeaderstrategyInterface
53+
*/
54+
public static function none() : HeaderStrategyInterface
55+
{
56+
return new self(
57+
function (SplFileObject $fileObject) : array {
58+
$firstRow = $fileObject->fgetcsv();
59+
$headers = array_keys($firstRow);
60+
$fileObject->rewind();
61+
return $headers;
62+
}
63+
);
64+
}
65+
66+
/**
67+
* Extracts headers from the given SplFileObject.
68+
*
69+
* @param SplFileObject $fileObject The delimited file containing the headers.
70+
*
71+
* @return array
72+
*/
73+
public function getHeaders(SplFileObject $fileObject) : array
74+
{
75+
return ($this->getHeadersCallable)($fileObject);
76+
}
77+
}

src/HeaderStrategyInterface.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace SubjectivePHP\Csv;
4+
5+
use SplFileObject;
6+
7+
interface HeaderStrategyInterface
8+
{
9+
public function getHeaders(SplFileObject $fileObject) : array;
10+
}

tests/HeaderStrategyTest.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
namespace SubjectivePHPTest\Csv;
4+
5+
use SplFileObject;
6+
use SubjectivePHP\Csv\HeaderStrategy;
7+
use PHPUnit\Framework\TestCase;
8+
9+
/**
10+
* @coversDefaultClass \SubjectivePHP\Csv\HeaderStrategy
11+
* @covers ::getHeaders
12+
* @covers ::<private>
13+
*/
14+
final class HeaderStrategyTest extends TestCase
15+
{
16+
/**
17+
* @test
18+
* @covers ::derive
19+
*/
20+
public function derive()
21+
{
22+
$fileObject = $this->getFileObject('pipe_delimited.txt', '|');
23+
$strategy = HeaderStrategy::derive();
24+
$this->assertSame(
25+
['id', 'author', 'title', 'genre', 'price', 'publish_date', 'description'],
26+
$strategy->getHeaders($fileObject)
27+
);
28+
}
29+
30+
/**
31+
* @test
32+
* @covers ::provide
33+
*/
34+
public function provide()
35+
{
36+
$headers = ['id', 'author', 'title', 'genre', 'price', 'publish_date', 'description'];
37+
$fileObject = $this->getFileObject('basic.csv');
38+
$strategy = HeaderStrategy::provide($headers);
39+
$this->assertSame($headers, $strategy->getHeaders($fileObject));
40+
}
41+
42+
/**
43+
* @test
44+
* @covers ::none
45+
*/
46+
public function none()
47+
{
48+
$fileObject = $this->getFileObject('no_headers.csv');
49+
$strategy = HeaderStrategy::none();
50+
$this->assertSame(
51+
[0, 1, 2, 3, 4, 5, 6],
52+
$strategy->getHeaders($fileObject)
53+
);
54+
}
55+
56+
public function getFileObject(string $fileName, string $delimiter = ',') : SplFileObject
57+
{
58+
$fileObject = new SplFileObject(__DIR__ . "/_files/{$fileName}");
59+
$fileObject->setFlags(SplFileObject::READ_CSV);
60+
$fileObject->setCsvControl($delimiter);
61+
return $fileObject;
62+
}
63+
}

0 commit comments

Comments
 (0)