1<?php
2
3namespace Box\Spout\Common\Helper;
4
5/**
6 * Class GlobalFunctionsHelper
7 * This class wraps global functions to facilitate testing
8 *
9 * @codeCoverageIgnore
10 */
11class GlobalFunctionsHelper
12{
13    /**
14     * Wrapper around global function fopen()
15     * @see fopen()
16     *
17     * @param string $fileName
18     * @param string $mode
19     * @return resource|bool
20     */
21    public function fopen($fileName, $mode)
22    {
23        return fopen($fileName, $mode);
24    }
25
26    /**
27     * Wrapper around global function fgets()
28     * @see fgets()
29     *
30     * @param resource $handle
31     * @param int|null $length
32     * @return string
33     */
34    public function fgets($handle, $length = null)
35    {
36        return fgets($handle, $length);
37    }
38
39    /**
40     * Wrapper around global function fputs()
41     * @see fputs()
42     *
43     * @param resource $handle
44     * @param string $string
45     * @return int
46     */
47    public function fputs($handle, $string)
48    {
49        return fputs($handle, $string);
50    }
51
52    /**
53     * Wrapper around global function fflush()
54     * @see fflush()
55     *
56     * @param resource $handle
57     * @return bool
58     */
59    public function fflush($handle)
60    {
61        return fflush($handle);
62    }
63
64    /**
65     * Wrapper around global function fseek()
66     * @see fseek()
67     *
68     * @param resource $handle
69     * @param int $offset
70     * @return int
71     */
72    public function fseek($handle, $offset)
73    {
74        return fseek($handle, $offset);
75    }
76
77    /**
78     * Wrapper around global function fgetcsv()
79     * @see fgetcsv()
80     *
81     * @param resource $handle
82     * @param int|null $length
83     * @param string|null $delimiter
84     * @param string|null $enclosure
85     * @return array
86     */
87    public function fgetcsv($handle, $length = null, $delimiter = null, $enclosure = null)
88    {
89        // PHP uses '\' as the default escape character. This is not RFC-4180 compliant...
90        // To fix that, simply disable the escape character.
91        // @see https://bugs.php.net/bug.php?id=43225
92        // @see http://tools.ietf.org/html/rfc4180
93        $escapeCharacter = "\0";
94
95        return fgetcsv($handle, $length, $delimiter, $enclosure, $escapeCharacter);
96    }
97
98    /**
99     * Wrapper around global function fputcsv()
100     * @see fputcsv()
101     *
102     * @param resource $handle
103     * @param array $fields
104     * @param string|null $delimiter
105     * @param string|null $enclosure
106     * @return int
107     */
108    public function fputcsv($handle, array $fields, $delimiter = null, $enclosure = null)
109    {
110        // PHP uses '\' as the default escape character. This is not RFC-4180 compliant...
111        // To fix that, simply disable the escape character.
112        // @see https://bugs.php.net/bug.php?id=43225
113        // @see http://tools.ietf.org/html/rfc4180
114        $escapeCharacter = "\0";
115
116        return fputcsv($handle, $fields, $delimiter, $enclosure, $escapeCharacter);
117    }
118
119    /**
120     * Wrapper around global function fwrite()
121     * @see fwrite()
122     *
123     * @param resource $handle
124     * @param string $string
125     * @return int
126     */
127    public function fwrite($handle, $string)
128    {
129        return fwrite($handle, $string);
130    }
131
132    /**
133     * Wrapper around global function fclose()
134     * @see fclose()
135     *
136     * @param resource $handle
137     * @return bool
138     */
139    public function fclose($handle)
140    {
141        return fclose($handle);
142    }
143
144    /**
145     * Wrapper around global function rewind()
146     * @see rewind()
147     *
148     * @param resource $handle
149     * @return bool
150     */
151    public function rewind($handle)
152    {
153        return rewind($handle);
154    }
155
156    /**
157     * Wrapper around global function file_exists()
158     * @see file_exists()
159     *
160     * @param string $fileName
161     * @return bool
162     */
163    public function file_exists($fileName)
164    {
165        return file_exists($fileName);
166    }
167
168    /**
169     * Wrapper around global function file_get_contents()
170     * @see file_get_contents()
171     *
172     * @param string $filePath
173     * @return string
174     */
175    public function file_get_contents($filePath)
176    {
177        $realFilePath = $this->convertToUseRealPath($filePath);
178
179        return file_get_contents($realFilePath);
180    }
181
182    /**
183     * Updates the given file path to use a real path.
184     * This is to avoid issues on some Windows setup.
185     *
186     * @param string $filePath File path
187     * @return string The file path using a real path
188     */
189    protected function convertToUseRealPath($filePath)
190    {
191        $realFilePath = $filePath;
192
193        if ($this->isZipStream($filePath)) {
194            if (preg_match('/zip:\/\/(.*)#(.*)/', $filePath, $matches)) {
195                $documentPath = $matches[1];
196                $documentInsideZipPath = $matches[2];
197                $realFilePath = 'zip://' . realpath($documentPath) . '#' . $documentInsideZipPath;
198            }
199        } else {
200            $realFilePath = realpath($filePath);
201        }
202
203        return $realFilePath;
204    }
205
206    /**
207     * Returns whether the given path is a zip stream.
208     *
209     * @param string $path Path pointing to a document
210     * @return bool TRUE if path is a zip stream, FALSE otherwise
211     */
212    protected function isZipStream($path)
213    {
214        return (strpos($path, 'zip://') === 0);
215    }
216
217    /**
218     * Wrapper around global function feof()
219     * @see feof()
220     *
221     * @param resource $handle
222     * @return bool
223     */
224    public function feof($handle)
225    {
226        return feof($handle);
227    }
228
229    /**
230     * Wrapper around global function is_readable()
231     * @see is_readable()
232     *
233     * @param string $fileName
234     * @return bool
235     */
236    public function is_readable($fileName)
237    {
238        return is_readable($fileName);
239    }
240
241    /**
242     * Wrapper around global function basename()
243     * @see basename()
244     *
245     * @param string $path
246     * @param string|null $suffix
247     * @return string
248     */
249    public function basename($path, $suffix = null)
250    {
251        return basename($path, $suffix);
252    }
253
254    /**
255     * Wrapper around global function header()
256     * @see header()
257     *
258     * @param string $string
259     * @return void
260     */
261    public function header($string)
262    {
263        header($string);
264    }
265
266    /**
267     * Wrapper around global function ob_end_clean()
268     * @see ob_end_clean()
269     *
270     * @return void
271     */
272    public function ob_end_clean()
273    {
274        if (ob_get_length() > 0) {
275            ob_end_clean();
276        }
277    }
278
279    /**
280     * Wrapper around global function iconv()
281     * @see iconv()
282     *
283     * @param string $string The string to be converted
284     * @param string $sourceEncoding The encoding of the source string
285     * @param string $targetEncoding The encoding the source string should be converted to
286     * @return string|bool the converted string or FALSE on failure.
287     */
288    public function iconv($string, $sourceEncoding, $targetEncoding)
289    {
290        return iconv($sourceEncoding, $targetEncoding, $string);
291    }
292
293    /**
294     * Wrapper around global function mb_convert_encoding()
295     * @see mb_convert_encoding()
296     *
297     * @param string $string The string to be converted
298     * @param string $sourceEncoding The encoding of the source string
299     * @param string $targetEncoding The encoding the source string should be converted to
300     * @return string|bool the converted string or FALSE on failure.
301     */
302    public function mb_convert_encoding($string, $sourceEncoding, $targetEncoding)
303    {
304        return mb_convert_encoding($string, $targetEncoding, $sourceEncoding);
305    }
306
307    /**
308     * Wrapper around global function stream_get_wrappers()
309     * @see stream_get_wrappers()
310     *
311     * @return array
312     */
313    public function stream_get_wrappers()
314    {
315        return stream_get_wrappers();
316    }
317
318    /**
319     * Wrapper around global function function_exists()
320     * @see function_exists()
321     *
322     * @param string $functionName
323     * @return bool
324     */
325    public function function_exists($functionName)
326    {
327        return function_exists($functionName);
328    }
329}
330