1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Coco\SourceWatcher\Core\Extractors; |
4
|
|
|
|
5
|
|
|
use Coco\SourceWatcher\Core\Extractor; |
6
|
|
|
use Coco\SourceWatcher\Core\Row; |
7
|
|
|
|
8
|
|
|
use Exception; |
9
|
|
|
|
10
|
|
|
class CsvExtractor extends Extractor |
11
|
|
|
{ |
12
|
|
|
private array $columns; |
13
|
|
|
private string $delimiter; |
14
|
|
|
private string $enclosure; |
15
|
|
|
|
16
|
|
|
public function __construct () |
17
|
|
|
{ |
18
|
|
|
$this->columns = array(); |
19
|
|
|
$this->delimiter = ","; |
20
|
|
|
$this->enclosure = "\""; |
21
|
|
|
} |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* @return array |
25
|
|
|
*/ |
26
|
|
|
public function getColumns () : array |
27
|
|
|
{ |
28
|
|
|
return $this->columns; |
29
|
|
|
} |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* @param array $columns |
33
|
|
|
*/ |
34
|
|
|
public function setColumns ( array $columns ) : void |
35
|
|
|
{ |
36
|
|
|
$this->columns = $columns; |
37
|
|
|
} |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* @return string |
41
|
|
|
*/ |
42
|
|
|
public function getDelimiter () : string |
43
|
|
|
{ |
44
|
|
|
return $this->delimiter; |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* @param string $delimiter |
49
|
|
|
*/ |
50
|
|
|
public function setDelimiter ( string $delimiter ) : void |
51
|
|
|
{ |
52
|
|
|
$this->delimiter = $delimiter; |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* @return string |
57
|
|
|
*/ |
58
|
|
|
public function getEnclosure () : string |
59
|
|
|
{ |
60
|
|
|
return $this->enclosure; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* @param string $enclosure |
65
|
|
|
*/ |
66
|
|
|
public function setEnclosure ( string $enclosure ) : void |
67
|
|
|
{ |
68
|
|
|
$this->enclosure = $enclosure; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
public function extract () : array |
72
|
|
|
{ |
73
|
|
|
if ( $this->input == null ) { |
74
|
|
|
throw new Exception( "An input must be provided." ); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
$result = array(); |
78
|
|
|
|
79
|
|
|
$fileHandler = fopen( $this->input, "r" ); |
80
|
|
|
|
81
|
|
|
$columns = $this->generateColumns( $fileHandler ); |
82
|
|
|
|
83
|
|
|
while ( $currentFileLine = fgets( $fileHandler ) ) { |
|
|
|
|
84
|
|
|
$currentRowArray = $this->generateRow( $currentFileLine, $columns ); |
85
|
|
|
|
86
|
|
|
array_push( $result, new Row( $currentRowArray ) ); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
fclose( $fileHandler ); |
|
|
|
|
90
|
|
|
|
91
|
|
|
return $result; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
private function generateColumns ( $fileHandler ) : array |
95
|
|
|
{ |
96
|
|
|
// The goal will be to represent the keys in format [key1 -> 1, key2 -> 2, ... keyN -> N] |
97
|
|
|
$columnsArrayFlipped = array_flip( str_getcsv( fgets( $fileHandler ), $this->delimiter, $this->enclosure ) ); |
98
|
|
|
|
99
|
|
|
foreach ( $columnsArrayFlipped as $key => $index ) { |
100
|
|
|
$columnsArrayFlipped[$key] = $index + 1; |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
// If no columns have been defined, make the columns attribute equal to the ones with format [key1 -> 1, key2 -> 2, ... keyN -> n] |
104
|
|
|
if ( empty( $this->columns ) ) { |
105
|
|
|
return $columnsArrayFlipped; |
|
|
|
|
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
// If the keys of the columns attribute equal to an array in format [0, 1, ... N] then they need to be reformatted as an intersection of the ones found and the ones requested. |
109
|
|
|
if ( array_keys( $this->columns ) === range( 0, count( $this->columns ) - 1 ) ) { |
110
|
|
|
return array_intersect_key( $columnsArrayFlipped, array_flip( $this->columns ) ); |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
$result = array(); |
114
|
|
|
|
115
|
|
|
foreach ( $this->columns as $key => $value ) { |
116
|
|
|
$result[$value] = $columnsArrayFlipped[$key]; |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
return $result; |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
private function generateRow ( string $rowString, array $columns ) : array |
123
|
|
|
{ |
124
|
|
|
$resultRow = array(); |
125
|
|
|
|
126
|
|
|
$rowArray = str_getcsv( $rowString, $this->delimiter, $this->enclosure ); |
127
|
|
|
|
128
|
|
|
foreach ( $columns as $column => $index ) { |
129
|
|
|
$resultRow[$column] = $rowArray[$index - 1]; |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
return $resultRow; |
133
|
|
|
} |
134
|
|
|
} |
135
|
|
|
|