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