1 | <?php |
||
29 | class RFC4180Field extends php_user_filter |
||
30 | { |
||
31 | const FILTERNAME = 'convert.league.csv.rfc4180'; |
||
32 | |||
33 | /** |
||
34 | * the filter name used to instantiate the class with |
||
35 | * |
||
36 | * @var string |
||
37 | */ |
||
38 | public $filtername; |
||
39 | |||
40 | /** |
||
41 | * Contents of the params parameter passed to stream_filter_append |
||
42 | * or stream_filter_prepend functions |
||
43 | * |
||
44 | * @var mixed |
||
45 | */ |
||
46 | public $params; |
||
47 | |||
48 | /** |
||
49 | * The value being search for |
||
50 | * |
||
51 | * @var string[] |
||
52 | */ |
||
53 | protected $search; |
||
54 | |||
55 | /** |
||
56 | * The replacement value that replace found $search values |
||
57 | * |
||
58 | * @var string[] |
||
59 | */ |
||
60 | protected $replace; |
||
61 | |||
62 | /** |
||
63 | * Characters that triggers enclosure with PHP fputcsv |
||
64 | * |
||
65 | * @var string |
||
66 | */ |
||
67 | protected static $force_enclosure = "\n\r\t "; |
||
68 | |||
69 | /** |
||
70 | * Static method to add the stream filter to a {@link AbstractCsv} object |
||
71 | * |
||
72 | * @param AbstractCsv $csv |
||
73 | * @param string $whitespace_replace |
||
74 | * |
||
75 | * @return AbstractCsv |
||
76 | */ |
||
77 | 10 | public static function addTo(AbstractCsv $csv, string $whitespace_replace = ''): AbstractCsv |
|
78 | { |
||
79 | 10 | self::register(); |
|
80 | |||
81 | $params = [ |
||
82 | 10 | 'enclosure' => $csv->getEnclosure(), |
|
83 | 10 | 'escape' => $csv->getEscape(), |
|
84 | 10 | 'mode' => $csv->getStreamFilterMode(), |
|
85 | ]; |
||
86 | |||
87 | 10 | if ($csv instanceof Writer && '' != $whitespace_replace) { |
|
88 | 4 | self::addFormatterTo($csv, $whitespace_replace); |
|
89 | 2 | $params['whitespace_replace'] = $whitespace_replace; |
|
90 | } |
||
91 | |||
92 | 8 | return $csv->addStreamFilter(self::FILTERNAME, $params); |
|
93 | } |
||
94 | |||
95 | /** |
||
96 | * Add a formatter to the {@link Writer} object to format the record |
||
97 | * field to avoid enclosure around a field with an empty space |
||
98 | * |
||
99 | * @param Writer $csv |
||
100 | * @param string $whitespace_replace |
||
101 | * |
||
102 | * @return Writer |
||
103 | */ |
||
104 | 4 | public static function addFormatterTo(Writer $csv, string $whitespace_replace): Writer |
|
105 | { |
||
106 | 4 | if ('' == $whitespace_replace || strlen($whitespace_replace) != strcspn($whitespace_replace, self::$force_enclosure)) { |
|
107 | 2 | throw new InvalidArgumentException('The sequence contains a character that enforces enclosure or is a CSV control character or is the empty string.'); |
|
108 | } |
||
109 | |||
110 | 2 | $mapper = function ($value) use ($whitespace_replace) { |
|
111 | 2 | if (is_string($value)) { |
|
112 | 2 | return str_replace(' ', $whitespace_replace, $value); |
|
113 | } |
||
114 | |||
115 | 2 | return $value; |
|
116 | 2 | }; |
|
117 | |||
118 | 2 | $formatter = function (array $record) use ($mapper): array { |
|
119 | 2 | return array_map($mapper, $record); |
|
120 | 2 | }; |
|
121 | |||
122 | 2 | return $csv->addFormatter($formatter); |
|
123 | } |
||
124 | |||
125 | /** |
||
126 | * Static method to register the class as a stream filter |
||
127 | */ |
||
128 | 6 | public static function register() |
|
129 | { |
||
130 | 6 | if (!in_array(self::FILTERNAME, stream_get_filters())) { |
|
131 | 2 | stream_filter_register(self::FILTERNAME, __CLASS__); |
|
132 | } |
||
133 | 6 | } |
|
134 | |||
135 | /** |
||
136 | * Static method to return the stream filter filtername |
||
137 | * |
||
138 | * @return string |
||
139 | */ |
||
140 | 4 | public static function getFiltername(): string |
|
144 | |||
145 | /** |
||
146 | * @inheritdoc |
||
147 | */ |
||
148 | 8 | public function filter($in, $out, &$consumed, $closing) |
|
158 | |||
159 | /** |
||
160 | * @inheritdoc |
||
161 | */ |
||
162 | 20 | public function onCreate() |
|
183 | |||
184 | /** |
||
185 | * Validate params property |
||
186 | * |
||
187 | * @param array $params |
||
188 | * |
||
189 | * @return bool |
||
190 | */ |
||
191 | 16 | protected function isValidParams(array $params): bool |
|
199 | |||
200 | /** |
||
201 | * Is Valid White space replaced sequence |
||
202 | * |
||
203 | * @param array $params |
||
204 | * |
||
205 | * @return bool |
||
206 | */ |
||
207 | 2 | protected function isValidSequence(array $params) |
|
212 | } |
||
213 |