PharInvocationResolver.php in Drupal 7
File
misc/typo3/phar-stream-wrapper/src/Resolver/PharInvocationResolver.php
View source
<?php
namespace TYPO3\PharStreamWrapper\Resolver;
use TYPO3\PharStreamWrapper\Helper;
use TYPO3\PharStreamWrapper\Manager;
use TYPO3\PharStreamWrapper\Phar\Reader;
use TYPO3\PharStreamWrapper\Phar\ReaderException;
use TYPO3\PharStreamWrapper\Resolvable;
class PharInvocationResolver implements Resolvable {
const RESOLVE_REALPATH = 1;
const RESOLVE_ALIAS = 2;
const ASSERT_INTERNAL_INVOCATION = 32;
private $invocationFunctionNames = array(
'include',
'include_once',
'require',
'require_once',
);
private $baseNames = array();
public function resolve($path, $flags = null) {
$hasPharPrefix = Helper::hasPharPrefix($path);
if ($flags === null) {
$flags = static::RESOLVE_REALPATH | static::RESOLVE_ALIAS;
}
if ($hasPharPrefix && $flags & static::RESOLVE_ALIAS) {
$invocation = $this
->findByAlias($path);
if ($invocation !== null) {
return $invocation;
}
}
$baseName = $this
->resolveBaseName($path, $flags);
if ($baseName === null) {
return null;
}
if ($flags & static::RESOLVE_REALPATH) {
$baseName = $this->baseNames[$baseName];
}
return $this
->retrieveInvocation($baseName, $flags);
}
private function retrieveInvocation($baseName, $flags) {
$invocation = $this
->findByBaseName($baseName);
if ($invocation !== null) {
return $invocation;
}
if ($flags & static::RESOLVE_ALIAS) {
$reader = new Reader($baseName);
$alias = $reader
->resolveContainer()
->getAlias();
}
else {
$alias = '';
}
$invocation = new PharInvocation($baseName, $alias);
Manager::instance()
->getCollection()
->collect($invocation);
return $invocation;
}
private function resolveBaseName($path, $flags) {
$baseName = $this
->findInBaseNames($path);
if ($baseName !== null) {
return $baseName;
}
$baseName = Helper::determineBaseFile($path);
if ($baseName !== null) {
$this
->addBaseName($baseName);
return $baseName;
}
$possibleAlias = $this
->resolvePossibleAlias($path);
if (!($flags & static::RESOLVE_ALIAS) || $possibleAlias === null) {
return null;
}
$trace = debug_backtrace();
foreach ($trace as $item) {
if (!isset($item['function']) || !isset($item['args'][0]) || !in_array($item['function'], $this->invocationFunctionNames, true)) {
continue;
}
$currentPath = $item['args'][0];
if (Helper::hasPharPrefix($currentPath)) {
continue;
}
$currentBaseName = Helper::determineBaseFile($currentPath);
if ($currentBaseName === null) {
continue;
}
try {
$reader = new Reader($currentBaseName);
$currentAlias = $reader
->resolveContainer()
->getAlias();
} catch (ReaderException $exception) {
continue;
}
if (empty($currentAlias) || $currentAlias !== $possibleAlias) {
continue;
}
$this
->addBaseName($currentBaseName);
return $currentBaseName;
}
return null;
}
private function resolvePossibleAlias($path) {
$normalizedPath = Helper::normalizePath($path);
return strstr($normalizedPath, '/', true) ?: null;
}
private function findByBaseName($baseName) {
return Manager::instance()
->getCollection()
->findByCallback(function (PharInvocation $candidate) use ($baseName) {
return $candidate
->getBaseName() === $baseName;
}, true);
}
private function findInBaseNames($path) {
if (in_array($path, $this->baseNames, true)) {
return $path;
}
$parts = explode('/', Helper::normalizePath($path));
while (count($parts)) {
$currentPath = implode('/', $parts);
if (isset($this->baseNames[$currentPath])) {
return $currentPath;
}
array_pop($parts);
}
return null;
}
private function addBaseName($baseName) {
if (isset($this->baseNames[$baseName])) {
return;
}
$this->baseNames[$baseName] = Helper::normalizeWindowsPath(realpath($baseName));
}
private function findByAlias($path) {
$possibleAlias = $this
->resolvePossibleAlias($path);
if ($possibleAlias === null) {
return null;
}
return Manager::instance()
->getCollection()
->findByCallback(function (PharInvocation $candidate) use ($possibleAlias) {
return $candidate
->isConfirmed() && $candidate
->getAlias() === $possibleAlias;
}, true);
}
}