Projet

Général

Profil

Paste
Télécharger (5,53 ko) Statistiques
| Branche: | Révision:

root / drupal7 / misc / typo3 / phar-stream-wrapper / src / Helper.php @ cd5c298a

1
<?php
2
namespace TYPO3\PharStreamWrapper;
3

    
4
/*
5
 * This file is part of the TYPO3 project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under the terms
8
 * of the MIT License (MIT). For the full copyright and license information,
9
 * please read the LICENSE file that was distributed with this source code.
10
 *
11
 * The TYPO3 project - inspiring people to share!
12
 */
13

    
14
class Helper
15
{
16
    /*
17
     * Resets PHP's OPcache if enabled as work-around for issues in `include()`
18
     * or `require()` calls and OPcache delivering wrong results.
19
     *
20
     * @see https://bugs.php.net/bug.php?id=66569
21
     */
22
    public static function resetOpCache()
23
    {
24
        if (function_exists('opcache_reset')
25
            && function_exists('opcache_get_status')
26
        ) {
27
            $status = opcache_get_status();
28
            if (!empty($status['opcache_enabled'])) {
29
                opcache_reset();
30
            }
31
        }
32
    }
33

    
34
    /**
35
     * Determines base file that can be accessed using the regular file system.
36
     * For e.g. "phar:///home/user/bundle.phar/content.txt" that would result
37
     * into "/home/user/bundle.phar".
38
     *
39
     * @param string $path
40
     * @return string|null
41
     */
42
    public static function determineBaseFile($path)
43
    {
44
        $parts = explode('/', static::normalizePath($path));
45

    
46
        while (count($parts)) {
47
            $currentPath = implode('/', $parts);
48
            if (@is_file($currentPath)) {
49
                return $currentPath;
50
            }
51
            array_pop($parts);
52
        }
53

    
54
        return null;
55
    }
56

    
57
    /**
58
     * @param string $path
59
     * @return string
60
     */
61
    public static function removePharPrefix($path)
62
    {
63
        $path = trim($path);
64
        if (stripos($path, 'phar://') !== 0) {
65
            return $path;
66
        }
67
        return substr($path, 7);
68
    }
69

    
70
    /**
71
     * Normalizes a path, removes phar:// prefix, fixes Windows directory
72
     * separators. Result is without trailing slash.
73
     *
74
     * @param string $path
75
     * @return string
76
     */
77
    public static function normalizePath($path)
78
    {
79
        return rtrim(
80
            static::getCanonicalPath(
81
                static::removePharPrefix($path)
82
            ),
83
            '/'
84
        );
85
    }
86

    
87
    /**
88
     * Fixes a path for windows-backslashes and reduces double-slashes to single slashes
89
     *
90
     * @param string $path File path to process
91
     * @return string
92
     */
93
    private static function normalizeWindowsPath($path)
94
    {
95
        return str_replace('\\', '/', $path);
96
    }
97

    
98
    /**
99
     * Resolves all dots, slashes and removes spaces after or before a path...
100
     *
101
     * @param string $path Input string
102
     * @return string Canonical path, always without trailing slash
103
     */
104
    private static function getCanonicalPath($path)
105
    {
106
        $path = static::normalizeWindowsPath($path);
107

    
108
        $absolutePathPrefix = '';
109
        if (static::isAbsolutePath($path)) {
110
            if (static::isWindows() && strpos($path, ':/') === 1) {
111
                $absolutePathPrefix = substr($path, 0, 3);
112
                $path = substr($path, 3);
113
            } else {
114
                $path = ltrim($path, '/');
115
                $absolutePathPrefix = '/';
116
            }
117
        }
118

    
119
        $pathParts = explode('/', $path);
120
        $pathPartsLength = count($pathParts);
121
        for ($partCount = 0; $partCount < $pathPartsLength; $partCount++) {
122
            // double-slashes in path: remove element
123
            if ($pathParts[$partCount] === '') {
124
                array_splice($pathParts, $partCount, 1);
125
                $partCount--;
126
                $pathPartsLength--;
127
            }
128
            // "." in path: remove element
129
            if ((isset($pathParts[$partCount]) ? $pathParts[$partCount] : '') === '.') {
130
                array_splice($pathParts, $partCount, 1);
131
                $partCount--;
132
                $pathPartsLength--;
133
            }
134
            // ".." in path:
135
            if ((isset($pathParts[$partCount]) ? $pathParts[$partCount] : '') === '..') {
136
                if ($partCount === 0) {
137
                    array_splice($pathParts, $partCount, 1);
138
                    $partCount--;
139
                    $pathPartsLength--;
140
                } elseif ($partCount >= 1) {
141
                    // Rremove this and previous element
142
                    array_splice($pathParts, $partCount - 1, 2);
143
                    $partCount -= 2;
144
                    $pathPartsLength -= 2;
145
                } elseif ($absolutePathPrefix) {
146
                    // can't go higher than root dir
147
                    // simply remove this part and continue
148
                    array_splice($pathParts, $partCount, 1);
149
                    $partCount--;
150
                    $pathPartsLength--;
151
                }
152
            }
153
        }
154

    
155
        return $absolutePathPrefix . implode('/', $pathParts);
156
    }
157

    
158
    /**
159
     * Checks if the $path is absolute or relative (detecting either '/' or
160
     * 'x:/' as first part of string) and returns TRUE if so.
161
     *
162
     * @param string $path File path to evaluate
163
     * @return bool
164
     */
165
    private static function isAbsolutePath($path)
166
    {
167
        // Path starting with a / is always absolute, on every system
168
        // On Windows also a path starting with a drive letter is absolute: X:/
169
        return (isset($path[0]) ? $path[0] : null) === '/'
170
            || static::isWindows() && (
171
                strpos($path, ':/') === 1
172
                || strpos($path, ':\\') === 1
173
            );
174
    }
175

    
176
    /**
177
     * @return bool
178
     */
179
    private static function isWindows()
180
    {
181
        return stripos(PHP_OS, 'WIN') === 0;
182
    }
183
}