class Helper

Helper provides low-level tools on file name resolving. However it does not (and should not) maintain any runtime state information. In order to resolve Phar archive paths according resolvers have to be used.

Hierarchy

  • class \TYPO3\PharStreamWrapper\Helper

Expanded class hierarchy of Helper

See also

\TYPO3\PharStreamWrapper\Resolvable::resolve()

2 files declare their use of Helper
PharExtensionInterceptor.php in misc/typo3/drupal-security/PharExtensionInterceptor.php
PharInvocationResolver.php in misc/typo3/phar-stream-wrapper/src/Resolver/PharInvocationResolver.php

File

misc/typo3/phar-stream-wrapper/src/Helper.php, line 21

Namespace

TYPO3\PharStreamWrapper
View source
class Helper {
    
    /*
     * Resets PHP's OPcache if enabled as work-around for issues in `include()`
     * or `require()` calls and OPcache delivering wrong results.
     *
     * @see https://bugs.php.net/bug.php?id=66569
     */
    public static function resetOpCache() {
        if (function_exists('opcache_reset') && function_exists('opcache_get_status')) {
            $status = opcache_get_status();
            if (!empty($status['opcache_enabled'])) {
                opcache_reset();
            }
        }
    }
    
    /**
     * Determines base file that can be accessed using the regular file system.
     * For e.g. "phar:///home/user/bundle.phar/content.txt" that would result
     * into "/home/user/bundle.phar".
     *
     * @param string $path
     * @return string|null
     */
    public static function determineBaseFile($path) {
        $parts = explode('/', static::normalizePath($path));
        while (count($parts)) {
            $currentPath = implode('/', $parts);
            if (@is_file($currentPath) && realpath($currentPath) !== false) {
                return $currentPath;
            }
            array_pop($parts);
        }
        return null;
    }
    
    /**
     * @param string $path
     * @return bool
     */
    public static function hasPharPrefix($path) {
        return stripos($path, 'phar://') === 0;
    }
    
    /**
     * @param string $path
     * @return string
     */
    public static function removePharPrefix($path) {
        $path = trim($path);
        if (!static::hasPharPrefix($path)) {
            return $path;
        }
        return substr($path, 7);
    }
    
    /**
     * Normalizes a path, removes phar:// prefix, fixes Windows directory
     * separators. Result is without trailing slash.
     *
     * @param string $path
     * @return string
     */
    public static function normalizePath($path) {
        return rtrim(static::normalizeWindowsPath(static::removePharPrefix($path)), '/');
    }
    
    /**
     * Fixes a path for windows-backslashes and reduces double-slashes to single slashes
     *
     * @param string $path File path to process
     * @return string
     */
    public static function normalizeWindowsPath($path) {
        return str_replace('\\', '/', $path);
    }
    
    /**
     * Resolves all dots, slashes and removes spaces after or before a path...
     *
     * @param string $path Input string
     * @return string Canonical path, always without trailing slash
     */
    private static function getCanonicalPath($path) {
        $path = static::normalizeWindowsPath($path);
        $absolutePathPrefix = '';
        if (static::isAbsolutePath($path)) {
            if (static::isWindows() && strpos($path, ':/') === 1) {
                $absolutePathPrefix = substr($path, 0, 3);
                $path = substr($path, 3);
            }
            else {
                $path = ltrim($path, '/');
                $absolutePathPrefix = '/';
            }
        }
        $pathParts = explode('/', $path);
        $pathPartsLength = count($pathParts);
        for ($partCount = 0; $partCount < $pathPartsLength; $partCount++) {
            // double-slashes in path: remove element
            if ($pathParts[$partCount] === '') {
                array_splice($pathParts, $partCount, 1);
                $partCount--;
                $pathPartsLength--;
            }
            // "." in path: remove element
            if ((isset($pathParts[$partCount]) ? $pathParts[$partCount] : '') === '.') {
                array_splice($pathParts, $partCount, 1);
                $partCount--;
                $pathPartsLength--;
            }
            // ".." in path:
            if ((isset($pathParts[$partCount]) ? $pathParts[$partCount] : '') === '..') {
                if ($partCount === 0) {
                    array_splice($pathParts, $partCount, 1);
                    $partCount--;
                    $pathPartsLength--;
                }
                elseif ($partCount >= 1) {
                    // Rremove this and previous element
                    array_splice($pathParts, $partCount - 1, 2);
                    $partCount -= 2;
                    $pathPartsLength -= 2;
                }
                elseif ($absolutePathPrefix) {
                    // can't go higher than root dir
                    // simply remove this part and continue
                    array_splice($pathParts, $partCount, 1);
                    $partCount--;
                    $pathPartsLength--;
                }
            }
        }
        return $absolutePathPrefix . implode('/', $pathParts);
    }
    
    /**
     * Checks if the $path is absolute or relative (detecting either '/' or
     * 'x:/' as first part of string) and returns TRUE if so.
     *
     * @param string $path File path to evaluate
     * @return bool
     */
    private static function isAbsolutePath($path) {
        // Path starting with a / is always absolute, on every system
        // On Windows also a path starting with a drive letter is absolute: X:/
        return (isset($path[0]) ? $path[0] : null) === '/' || static::isWindows() && (strpos($path, ':/') === 1 || strpos($path, ':\\') === 1);
    }
    
    /**
     * @return bool
     */
    private static function isWindows() {
        return stripos(PHP_OS, 'WIN') === 0;
    }

}

Members

Title Sort descending Modifiers Object type Summary
Helper::determineBaseFile public static function Determines base file that can be accessed using the regular file system.
For e.g. &quot;phar:///home/user/bundle.phar/content.txt&quot; that would result
into &quot;/home/user/bundle.phar&quot;.
Helper::getCanonicalPath private static function Resolves all dots, slashes and removes spaces after or before a path...
Helper::hasPharPrefix public static function
Helper::isAbsolutePath private static function Checks if the $path is absolute or relative (detecting either &#039;/&#039; or
&#039;x:/&#039; as first part of string) and returns TRUE if so.
Helper::isWindows private static function
Helper::normalizePath public static function Normalizes a path, removes phar:// prefix, fixes Windows directory
separators. Result is without trailing slash.
Helper::normalizeWindowsPath public static function Fixes a path for windows-backslashes and reduces double-slashes to single slashes
Helper::removePharPrefix public static function
Helper::resetOpCache public static function

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.