Passed
Pull Request — master (#4)
by
unknown
13:45
created

Util::getStreamSize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 5
rs 10
1
<?php
2
3
namespace League\Flysystem;
4
5
use League\Flysystem\Util\MimeType;
6
use LogicException;
7
8
class Util
9
{
10
    /**
11
     * Get normalized pathinfo.
12
     *
13
     * @param string $path
14
     *
15
     * @return array pathinfo
16
     */
17
    public static function pathinfo($path)
18
    {
19
        $pathinfo = pathinfo($path) + compact('path');
20
        $pathinfo['dirname'] = array_key_exists('dirname', $pathinfo)
21
            ? static::normalizeDirname($pathinfo['dirname']) : '';
22
23
        return $pathinfo;
24
    }
25
26
    /**
27
     * Normalize a dirname return value.
28
     *
29
     * @param string $dirname
30
     *
31
     * @return string normalized dirname
32
     */
33
    public static function normalizeDirname($dirname)
34
    {
35
        return $dirname === '.' ? '' : $dirname;
36
    }
37
38
    /**
39
     * Get a normalized dirname from a path.
40
     *
41
     * @param string $path
42
     *
43
     * @return string dirname
44
     */
45
    public static function dirname($path)
46
    {
47
        return static::normalizeDirname(dirname($path));
48
    }
49
50
    /**
51
     * Map result arrays.
52
     *
53
     * @param array $object
54
     * @param array $map
55
     *
56
     * @return array mapped result
57
     */
58
    public static function map(array $object, array $map)
59
    {
60
        $result = [];
61
62
        foreach ($map as $from => $to) {
63
            if ( ! isset($object[$from])) {
64
                continue;
65
            }
66
67
            $result[$to] = $object[$from];
68
        }
69
70
        return $result;
71
    }
72
73
    /**
74
     * Normalize path.
75
     *
76
     * @param string $path
77
     *
78
     * @throws LogicException
79
     *
80
     * @return string
81
     */
82
    public static function normalizePath($path)
83
    {
84
        return static::normalizeRelativePath($path);
85
    }
86
87
    /**
88
     * Normalize relative directories in a path.
89
     *
90
     * @param string $path
91
     *
92
     * @throws LogicException
93
     *
94
     * @return string
95
     */
96
    public static function normalizeRelativePath($path)
97
    {
98
        $path = str_replace('\\', '/', $path);
99
        $path = static::removeFunkyWhiteSpace($path);
100
101
        $parts = [];
102
103
        foreach (explode('/', $path) as $part) {
104
            switch ($part) {
105
                case '':
106
                case '.':
107
                break;
108
109
            case '..':
110
                if (empty($parts)) {
111
                    throw new LogicException(
112
                        'Path is outside of the defined root, path: [' . $path . ']'
113
                    );
114
                }
115
                array_pop($parts);
116
                break;
117
118
            default:
119
                $parts[] = $part;
120
                break;
121
            }
122
        }
123
124
        return implode('/', $parts);
125
    }
126
127
    /**
128
     * Removes unprintable characters and invalid unicode characters.
129
     *
130
     * @param string $path
131
     *
132
     * @return string $path
133
     */
134
    protected static function removeFunkyWhiteSpace($path) {
135
        // We do this check in a loop, since removing invalid unicode characters
136
        // can lead to new characters being created.
137
        while (preg_match('#\p{C}+|^\./#u', $path)) {
138
            $path = preg_replace('#\p{C}+|^\./#u', '', $path);
139
        }
140
141
        return $path;
142
    }
143
144
    /**
145
     * Normalize prefix.
146
     *
147
     * @param string $prefix
148
     * @param string $separator
149
     *
150
     * @return string normalized path
151
     */
152
    public static function normalizePrefix($prefix, $separator)
153
    {
154
        return rtrim($prefix, $separator) . $separator;
155
    }
156
157
    /**
158
     * Get content size.
159
     *
160
     * @param string $contents
161
     *
162
     * @return int content size
163
     */
164
    public static function contentSize($contents)
165
    {
166
        return defined('MB_OVERLOAD_STRING') ? mb_strlen($contents, '8bit') : strlen($contents);
167
    }
168
169
    /**
170
     * Guess MIME Type based on the path of the file and it's content.
171
     *
172
     * @param string $path
173
     * @param string|resource $content
174
     *
175
     * @return string|null MIME Type or NULL if no extension detected
176
     */
177
    public static function guessMimeType($path, $content)
178
    {
179
        $mimeType = MimeType::detectByContent($content);
180
181
        if ( ! (empty($mimeType) || in_array($mimeType, ['application/x-empty', 'text/plain', 'text/x-asm']))) {
182
            return $mimeType;
183
        }
184
185
        return MimeType::detectByFilename($path);
186
    }
187
188
    /**
189
     * Emulate directories.
190
     *
191
     * @param array $listing
192
     *
193
     * @return array listing with emulated directories
194
     */
195
    public static function emulateDirectories(array $listing)
196
    {
197
        $directories = [];
198
        $listedDirectories = [];
199
200
        foreach ($listing as $object) {
201
            list($directories, $listedDirectories) = static::emulateObjectDirectories(
202
                $object,
203
                $directories,
204
                $listedDirectories
205
            );
206
        }
207
208
        $directories = array_diff(array_unique($directories), array_unique($listedDirectories));
209
210
        foreach ($directories as $directory) {
211
            $listing[] = static::pathinfo($directory) + ['type' => 'dir'];
212
        }
213
214
        return $listing;
215
    }
216
217
    /**
218
     * Ensure a Config instance.
219
     *
220
     * @param null|array|Config $config
221
     *
222
     * @return Config config instance
223
     *
224
     * @throw  LogicException
225
     */
226
    public static function ensureConfig($config)
227
    {
228
        if ($config === null) {
229
            return new Config();
230
        }
231
232
        if ($config instanceof Config) {
233
            return $config;
234
        }
235
236
        if (is_array($config)) {
0 ignored issues
show
introduced by
The condition is_array($config) is always true.
Loading history...
237
            return new Config($config);
238
        }
239
240
        throw new LogicException('A config should either be an array or a Flysystem\Config object.');
241
    }
242
243
    /**
244
     * Rewind a stream.
245
     *
246
     * @param resource $resource
247
     */
248
    public static function rewindStream($resource)
249
    {
250
        if (ftell($resource) !== 0 && static::isSeekableStream($resource)) {
251
            rewind($resource);
252
        }
253
    }
254
255
    public static function isSeekableStream($resource)
256
    {
257
        $metadata = stream_get_meta_data($resource);
258
259
        return $metadata['seekable'];
260
    }
261
262
    /**
263
     * Get the size of a stream.
264
     *
265
     * @param resource $resource
266
     *
267
     * @return int stream size
268
     */
269
    public static function getStreamSize($resource)
270
    {
271
        $stat = fstat($resource);
272
273
        return $stat['size'];
274
    }
275
276
    /**
277
     * Emulate the directories of a single object.
278
     *
279
     * @param array $object
280
     * @param array $directories
281
     * @param array $listedDirectories
282
     *
283
     * @return array
284
     */
285
    protected static function emulateObjectDirectories(array $object, array $directories, array $listedDirectories)
286
    {
287
        if ($object['type'] === 'dir') {
288
            $listedDirectories[] = $object['path'];
289
        }
290
291
        if (empty($object['dirname'])) {
292
            return [$directories, $listedDirectories];
293
        }
294
295
        $parent = $object['dirname'];
296
297
        while ( ! empty($parent) && ! in_array($parent, $directories)) {
298
            $directories[] = $parent;
299
            $parent = static::dirname($parent);
300
        }
301
302
        if (isset($object['type']) && $object['type'] === 'dir') {
303
            $listedDirectories[] = $object['path'];
304
305
            return [$directories, $listedDirectories];
306
        }
307
308
        return [$directories, $listedDirectories];
309
    }
310
}
311