PK PK8%
LICENSE.mdnu W+A Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
- Neither the name of Laminas Foundation nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
PK PF[ [ COPYRIGHT.mdnu W+A Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/)
PK PAé .travis.ymlnu W+A language: php
cache:
directories:
- $HOME/.composer/cache
env:
global:
- COMPOSER_ARGS="--no-interaction"
- COVERAGE_DEPS="php-coveralls/php-coveralls"
matrix:
fast_finish: true
include:
- php: 5.6
env:
- DEPS=lowest
- php: 5.6
env:
- DEPS=latest
- php: 7
env:
- DEPS=lowest
- php: 7
env:
- DEPS=latest
- php: 7.1
env:
- DEPS=lowest
- php: 7.1
env:
- DEPS=latest
- CS_CHECK=true
- TEST_COVERAGE=true
- php: 7.2
env:
- DEPS=lowest
- php: 7.2
env:
- DEPS=latest
- php: 7.3
env:
- DEPS=lowest
- php: 7.3
env:
- DEPS=latest
before_install:
- if [[ $TEST_COVERAGE != 'true' ]]; then phpenv config-rm xdebug.ini || return 0 ; fi
install:
- travis_retry composer install $COMPOSER_ARGS --ignore-platform-reqs
- if [[ $LEGACY_DEPS != '' ]]; then travis_retry composer update $COMPOSER_ARGS --with-dependencies $LEGACY_DEPS ; fi
- if [[ $DEPS == 'latest' ]]; then travis_retry composer update $COMPOSER_ARGS ; fi
- if [[ $DEPS == 'lowest' ]]; then travis_retry composer update --prefer-lowest --prefer-stable $COMPOSER_ARGS ; fi
- if [[ $TEST_COVERAGE == 'true' ]]; then travis_retry composer require --dev $COMPOSER_ARGS $COVERAGE_DEPS ; fi
- stty cols 120 && composer show
script:
- if [[ $TEST_COVERAGE == 'true' ]]; then composer test-coverage ; else composer test ; fi
- if [[ $CS_CHECK == 'true' ]]; then composer cs-check ; fi
after_script:
- if [[ $TEST_COVERAGE == 'true' ]]; then travis_retry php vendor/bin/php-coveralls -v ; fi
notifications:
email: false
PK Px= = .coveralls.ymlnu W+A coverage_clover: clover.xml
json_path: coveralls-upload.json
PK Pg/# phpcs.xmlnu W+A
/src/Exception/*
/src/SplAutoloader.php
/src/AutoloaderFactory.php
/src/ClassMapAutoloader.php
/src/ModuleAutoloader.php
/src/StandardAutoloader.php
src
test
*/TestAsset/*
*/_files/*
PK PxR\\ README.mdnu W+A # laminas-loader
[![Build Status](https://travis-ci.com/laminas/laminas-loader.svg?branch=master)](https://travis-ci.com/laminas/laminas-loader)
[![Coverage Status](https://coveralls.io/repos/github/laminas/laminas-loader/badge.svg?branch=master)](https://coveralls.io/github/laminas/laminas-loader?branch=master)
laminas-loader provides different strategies for autoloading PHP classes.
- File issues at https://github.com/laminas/laminas-loader/issues
- Documentation is at https://docs.laminas.dev/laminas-loader/
PK P@ݫ
.gitignorenu W+A /clover.xml
/composer.lock
/coveralls-upload.json
/docs/html/
/laminas-mkdoc-theme.tgz
/laminas-mkdoc-theme/
/phpunit.xml
/vendor/
PK PI " src/Exception/RuntimeException.phpnu W+A setOptions($options);
}
}
/**
* Configure the autoloader
*
* Proxies to {@link registerAutoloadMaps()}.
*
* @param array|Traversable $options
* @return ClassMapAutoloader
*/
public function setOptions($options)
{
$this->registerAutoloadMaps($options);
return $this;
}
/**
* Register an autoload map
*
* An autoload map may be either an associative array, or a file returning
* an associative array.
*
* An autoload map should be an associative array containing
* classname/file pairs.
*
* @param string|array $map
* @throws Exception\InvalidArgumentException
* @return ClassMapAutoloader
*/
public function registerAutoloadMap($map)
{
if (is_string($map)) {
$location = $map;
if ($this === ($map = $this->loadMapFromFile($location))) {
return $this;
}
}
if (! is_array($map)) {
require_once __DIR__ . '/Exception/InvalidArgumentException.php';
throw new Exception\InvalidArgumentException(sprintf(
'Map file provided does not return a map. Map file: "%s"',
(isset($location) && is_string($location) ? $location : 'unexpected type: ' . gettype($map))
));
}
$this->map = $map + $this->map;
if (isset($location)) {
$this->mapsLoaded[] = $location;
}
return $this;
}
/**
* Register many autoload maps at once
*
* @param array $locations
* @throws Exception\InvalidArgumentException
* @return ClassMapAutoloader
*/
public function registerAutoloadMaps($locations)
{
if (! is_array($locations) && ! ($locations instanceof Traversable)) {
require_once __DIR__ . '/Exception/InvalidArgumentException.php';
throw new Exception\InvalidArgumentException('Map list must be an array or implement Traversable');
}
foreach ($locations as $location) {
$this->registerAutoloadMap($location);
}
return $this;
}
/**
* Retrieve current autoload map
*
* @return array
*/
public function getAutoloadMap()
{
return $this->map;
}
/**
* {@inheritDoc}
*/
public function autoload($class)
{
if (isset($this->map[$class])) {
require_once $this->map[$class];
return $class;
}
return false;
}
/**
* Register the autoloader with spl_autoload registry
*
* @return void
*/
public function register()
{
spl_autoload_register([$this, 'autoload'], true, true);
}
/**
* Load a map from a file
*
* If the map has been previously loaded, returns the current instance;
* otherwise, returns whatever was returned by calling include() on the
* location.
*
* @param string $location
* @return ClassMapAutoloader|mixed
* @throws Exception\InvalidArgumentException for nonexistent locations
*/
protected function loadMapFromFile($location)
{
if (! file_exists($location)) {
require_once __DIR__ . '/Exception/InvalidArgumentException.php';
throw new Exception\InvalidArgumentException(sprintf(
'Map file provided does not exist. Map file: "%s"',
(is_string($location) ? $location : 'unexpected type: ' . gettype($location))
));
}
if (! $path = static::realPharPath($location)) {
$path = realpath($location);
}
if (in_array($path, $this->mapsLoaded)) {
// Already loaded this map
return $this;
}
$map = include $path;
return $map;
}
/**
* Resolve the real_path() to a file within a phar.
*
* @see https://bugs.php.net/bug.php?id=52769
* @param string $path
* @return string
*/
public static function realPharPath($path)
{
if (! preg_match('|^phar:(/{2,3})|', $path, $match)) {
return;
}
$prefixLength = 5 + strlen($match[1]);
$parts = explode('/', str_replace(['/', '\\'], '/', substr($path, $prefixLength)));
$parts = array_values(array_filter($parts, function ($p) {
return ($p !== '' && $p !== '.');
}));
array_walk($parts, function ($value, $key) use (&$parts) {
if ($value === '..') {
unset($parts[$key], $parts[$key - 1]);
$parts = array_values($parts);
}
});
if (file_exists($realPath = str_pad('phar:', $prefixLength, '/') . implode('/', $parts))) {
return $realPath;
}
}
}
PK Pp( ( src/StandardAutoloader.phpnu W+A setOptions($options);
}
}
/**
* Configure autoloader
*
* Allows specifying both "namespace" and "prefix" pairs, using the
* following structure:
*
* array(
* 'namespaces' => array(
* 'Laminas' => '/path/to/Laminas/library',
* 'Doctrine' => '/path/to/Doctrine/library',
* ),
* 'prefixes' => array(
* 'Phly_' => '/path/to/Phly/library',
* ),
* 'fallback_autoloader' => true,
* )
*
*
* @param array|\Traversable $options
* @throws Exception\InvalidArgumentException
* @return StandardAutoloader
*/
public function setOptions($options)
{
if (! is_array($options) && ! ($options instanceof \Traversable)) {
require_once __DIR__ . '/Exception/InvalidArgumentException.php';
throw new Exception\InvalidArgumentException('Options must be either an array or Traversable');
}
foreach ($options as $type => $pairs) {
switch ($type) {
case self::AUTOREGISTER_LAMINAS:
if ($pairs) {
$this->registerNamespace('Laminas', dirname(__DIR__));
}
break;
case self::LOAD_NS:
if (is_array($pairs) || $pairs instanceof \Traversable) {
$this->registerNamespaces($pairs);
}
break;
case self::LOAD_PREFIX:
if (is_array($pairs) || $pairs instanceof \Traversable) {
$this->registerPrefixes($pairs);
}
break;
case self::ACT_AS_FALLBACK:
$this->setFallbackAutoloader($pairs);
break;
default:
// ignore
}
}
return $this;
}
/**
* Set flag indicating fallback autoloader status
*
* @param bool $flag
* @return StandardAutoloader
*/
public function setFallbackAutoloader($flag)
{
$this->fallbackAutoloaderFlag = (bool) $flag;
return $this;
}
/**
* Is this autoloader acting as a fallback autoloader?
*
* @return bool
*/
public function isFallbackAutoloader()
{
return $this->fallbackAutoloaderFlag;
}
/**
* Register a namespace/directory pair
*
* @param string $namespace
* @param string $directory
* @return StandardAutoloader
*/
public function registerNamespace($namespace, $directory)
{
$namespace = rtrim($namespace, self::NS_SEPARATOR) . self::NS_SEPARATOR;
$this->namespaces[$namespace] = $this->normalizeDirectory($directory);
return $this;
}
/**
* Register many namespace/directory pairs at once
*
* @param array $namespaces
* @throws Exception\InvalidArgumentException
* @return StandardAutoloader
*/
public function registerNamespaces($namespaces)
{
if (! is_array($namespaces) && ! $namespaces instanceof \Traversable) {
require_once __DIR__ . '/Exception/InvalidArgumentException.php';
throw new Exception\InvalidArgumentException('Namespace pairs must be either an array or Traversable');
}
foreach ($namespaces as $namespace => $directory) {
$this->registerNamespace($namespace, $directory);
}
return $this;
}
/**
* Register a prefix/directory pair
*
* @param string $prefix
* @param string $directory
* @return StandardAutoloader
*/
public function registerPrefix($prefix, $directory)
{
$prefix = rtrim($prefix, self::PREFIX_SEPARATOR). self::PREFIX_SEPARATOR;
$this->prefixes[$prefix] = $this->normalizeDirectory($directory);
return $this;
}
/**
* Register many namespace/directory pairs at once
*
* @param array $prefixes
* @throws Exception\InvalidArgumentException
* @return StandardAutoloader
*/
public function registerPrefixes($prefixes)
{
if (! is_array($prefixes) && ! $prefixes instanceof \Traversable) {
require_once __DIR__ . '/Exception/InvalidArgumentException.php';
throw new Exception\InvalidArgumentException('Prefix pairs must be either an array or Traversable');
}
foreach ($prefixes as $prefix => $directory) {
$this->registerPrefix($prefix, $directory);
}
return $this;
}
/**
* Defined by Autoloadable; autoload a class
*
* @param string $class
* @return false|string
*/
public function autoload($class)
{
$isFallback = $this->isFallbackAutoloader();
if (false !== strpos($class, self::NS_SEPARATOR)) {
if ($this->loadClass($class, self::LOAD_NS)) {
return $class;
} elseif ($isFallback) {
return $this->loadClass($class, self::ACT_AS_FALLBACK);
}
return false;
}
if (false !== strpos($class, self::PREFIX_SEPARATOR)) {
if ($this->loadClass($class, self::LOAD_PREFIX)) {
return $class;
} elseif ($isFallback) {
return $this->loadClass($class, self::ACT_AS_FALLBACK);
}
return false;
}
if ($isFallback) {
return $this->loadClass($class, self::ACT_AS_FALLBACK);
}
return false;
}
/**
* Register the autoloader with spl_autoload
*
* @return void
*/
public function register()
{
spl_autoload_register([$this, 'autoload']);
}
/**
* Transform the class name to a filename
*
* @param string $class
* @param string $directory
* @return string
*/
protected function transformClassNameToFilename($class, $directory)
{
// $class may contain a namespace portion, in which case we need
// to preserve any underscores in that portion.
$matches = [];
preg_match('/(?P.+\\\)?(?P[^\\\]+$)/', $class, $matches);
$class = (isset($matches['class'])) ? $matches['class'] : '';
$namespace = (isset($matches['namespace'])) ? $matches['namespace'] : '';
return $directory
. str_replace(self::NS_SEPARATOR, '/', $namespace)
. str_replace(self::PREFIX_SEPARATOR, '/', $class)
. '.php';
}
/**
* Load a class, based on its type (namespaced or prefixed)
*
* @param string $class
* @param string $type
* @return bool|string
* @throws Exception\InvalidArgumentException
*/
protected function loadClass($class, $type)
{
if (! in_array($type, [self::LOAD_NS, self::LOAD_PREFIX, self::ACT_AS_FALLBACK])) {
require_once __DIR__ . '/Exception/InvalidArgumentException.php';
throw new Exception\InvalidArgumentException();
}
// Fallback autoloading
if ($type === self::ACT_AS_FALLBACK) {
// create filename
$filename = $this->transformClassNameToFilename($class, '');
$resolvedName = stream_resolve_include_path($filename);
if ($resolvedName !== false) {
return include $resolvedName;
}
return false;
}
// Namespace and/or prefix autoloading
foreach ($this->$type as $leader => $path) {
if (0 === strpos($class, $leader)) {
// Trim off leader (namespace or prefix)
$trimmedClass = substr($class, strlen($leader));
// create filename
$filename = $this->transformClassNameToFilename($trimmedClass, $path);
if (file_exists($filename)) {
return include $filename;
}
}
}
return false;
}
/**
* Normalize the directory to include a trailing directory separator
*
* @param string $directory
* @return string
*/
protected function normalizeDirectory($directory)
{
$last = $directory[strlen($directory) - 1];
if (in_array($last, ['/', '\\'])) {
$directory[strlen($directory) - 1] = DIRECTORY_SEPARATOR;
return $directory;
}
$directory .= DIRECTORY_SEPARATOR;
return $directory;
}
}
PK P src/PluginClassLocator.phpnu W+A
* spl_autoload_register(array($this, 'autoload'));
*
*
* @return void
*/
public function register();
}
PK PfJV V src/ShortNameLocator.phpnu W+A path
*/
protected $explicitPaths = [];
/**
* @var array An array of namespaceName => namespacePath
*/
protected $namespacedPaths = [];
/**
* @var string Will contain the absolute phar:// path to the executable when packaged as phar file
*/
protected $pharBasePath = "";
/**
* @var array An array of supported phar extensions (filled on constructor)
*/
protected $pharExtensions = [];
/**
* @var array An array of module classes to their containing files
*/
protected $moduleClassMap = [];
/**
* Constructor
*
* Allow configuration of the autoloader via the constructor.
*
* @param null|array|Traversable $options
*/
public function __construct($options = null)
{
if (extension_loaded('phar')) {
$this->pharBasePath = Phar::running(true);
$this->pharExtensions = [
'phar',
'phar.tar',
'tar',
];
// ext/zlib enabled -> phar can read gzip & zip compressed files
if (extension_loaded('zlib')) {
$this->pharExtensions[] = 'phar.gz';
$this->pharExtensions[] = 'phar.tar.gz';
$this->pharExtensions[] = 'tar.gz';
$this->pharExtensions[] = 'phar.zip';
$this->pharExtensions[] = 'zip';
}
// ext/bzip2 enabled -> phar can read bz2 compressed files
if (extension_loaded('bzip2')) {
$this->pharExtensions[] = 'phar.bz2';
$this->pharExtensions[] = 'phar.tar.bz2';
$this->pharExtensions[] = 'tar.bz2';
}
}
if (null !== $options) {
$this->setOptions($options);
}
}
/**
* Configure the autoloader
*
* In most cases, $options should be either an associative array or
* Traversable object.
*
* @param array|Traversable $options
* @return ModuleAutoloader
*/
public function setOptions($options)
{
$this->registerPaths($options);
return $this;
}
/**
* Retrieves the class map for all loaded modules.
*
* @return array
*/
public function getModuleClassMap()
{
return $this->moduleClassMap;
}
/**
* Sets the class map used to speed up the module autoloading.
*
* @param array $classmap
* @return ModuleAutoloader
*/
public function setModuleClassMap(array $classmap)
{
$this->moduleClassMap = $classmap;
return $this;
}
/**
* Autoload a class
*
* @param $class
* @return mixed
* False [if unable to load $class]
* get_class($class) [if $class is successfully loaded]
*/
public function autoload($class)
{
// Limit scope of this autoloader
if (substr($class, -7) !== '\Module') {
return false;
}
if (isset($this->moduleClassMap[$class])) {
require_once $this->moduleClassMap[$class];
return $class;
}
$moduleName = substr($class, 0, -7);
if (isset($this->explicitPaths[$moduleName])) {
$classLoaded = $this->loadModuleFromDir($this->explicitPaths[$moduleName], $class);
if ($classLoaded) {
return $classLoaded;
}
$classLoaded = $this->loadModuleFromPhar($this->explicitPaths[$moduleName], $class);
if ($classLoaded) {
return $classLoaded;
}
}
if (count($this->namespacedPaths) >= 1) {
foreach ($this->namespacedPaths as $namespace => $path) {
if (false === strpos($moduleName, $namespace)) {
continue;
}
$moduleNameBuffer = str_replace($namespace . "\\", "", $moduleName);
$path .= DIRECTORY_SEPARATOR . $moduleNameBuffer . DIRECTORY_SEPARATOR;
$classLoaded = $this->loadModuleFromDir($path, $class);
if ($classLoaded) {
return $classLoaded;
}
$classLoaded = $this->loadModuleFromPhar($path, $class);
if ($classLoaded) {
return $classLoaded;
}
}
}
$moduleClassPath = str_replace('\\', DIRECTORY_SEPARATOR, $moduleName);
$pharSuffixPattern = null;
if ($this->pharExtensions) {
$pharSuffixPattern = '(' . implode('|', array_map('preg_quote', $this->pharExtensions)) . ')';
}
foreach ($this->paths as $path) {
$path = $path . $moduleClassPath;
if ($path == '.' || substr($path, 0, 2) == './' || substr($path, 0, 2) == '.\\') {
if (! $basePath = $this->pharBasePath) {
$basePath = realpath('.');
}
if (false === $basePath) {
$basePath = getcwd();
}
$path = rtrim($basePath, '\/\\') . substr($path, 1);
}
$classLoaded = $this->loadModuleFromDir($path, $class);
if ($classLoaded) {
return $classLoaded;
}
// No directory with Module.php, searching for phars
if ($pharSuffixPattern) {
foreach (new GlobIterator($path . '.*') as $entry) {
if ($entry->isDir()) {
continue;
}
if (! preg_match('#.+\.' . $pharSuffixPattern . '$#', $entry->getPathname())) {
continue;
}
$classLoaded = $this->loadModuleFromPhar($entry->getPathname(), $class);
if ($classLoaded) {
return $classLoaded;
}
}
}
}
return false;
}
/**
* loadModuleFromDir
*
* @param string $dirPath
* @param string $class
* @return mixed
* False [if unable to load $class]
* get_class($class) [if $class is successfully loaded]
*/
protected function loadModuleFromDir($dirPath, $class)
{
$modulePath = $dirPath . '/Module.php';
if (substr($modulePath, 0, 7) === 'phar://') {
$file = new PharFileInfo($modulePath);
} else {
$file = new SplFileInfo($modulePath);
}
if (($file->isReadable() && $file->isFile())) {
// Found directory with Module.php in it
$absModulePath = $this->pharBasePath ? (string) $file : $file->getRealPath();
require_once $absModulePath;
if (class_exists($class)) {
$this->moduleClassMap[$class] = $absModulePath;
return $class;
}
}
return false;
}
/**
* loadModuleFromPhar
*
* @param string $pharPath
* @param string $class
* @return mixed
* False [if unable to load $class]
* get_class($class) [if $class is successfully loaded]
*/
protected function loadModuleFromPhar($pharPath, $class)
{
$pharPath = static::normalizePath($pharPath, false);
$file = new SplFileInfo($pharPath);
if (! $file->isReadable() || ! $file->isFile()) {
return false;
}
$fileRealPath = $file->getRealPath();
// Phase 0: Check for executable phar with Module class in stub
if (strpos($fileRealPath, '.phar') !== false) {
// First see if the stub makes the Module class available
require_once $fileRealPath;
if (class_exists($class)) {
$this->moduleClassMap[$class] = $fileRealPath;
return $class;
}
}
// Phase 1: Not executable phar, no stub, or stub did not provide Module class; try Module.php directly
$moduleClassFile = 'phar://' . $fileRealPath . '/Module.php';
$moduleFile = new SplFileInfo($moduleClassFile);
if ($moduleFile->isReadable() && $moduleFile->isFile()) {
require_once $moduleClassFile;
if (class_exists($class)) {
$this->moduleClassMap[$class] = $moduleClassFile;
return $class;
}
}
// Phase 2: Check for nested module directory within archive
// Checks for /path/to/MyModule.tar/MyModule/Module.php
// (shell-integrated zip/tar utilities wrap directories like this)
$pharBaseName = $this->pharFileToModuleName($fileRealPath);
$moduleClassFile = 'phar://' . $fileRealPath . '/' . $pharBaseName . '/Module.php';
$moduleFile = new SplFileInfo($moduleClassFile);
if ($moduleFile->isReadable() && $moduleFile->isFile()) {
require_once $moduleClassFile;
if (class_exists($class)) {
$this->moduleClassMap[$class] = $moduleClassFile;
return $class;
}
}
return false;
}
/**
* Register the autoloader with spl_autoload registry
*
* @return void
*/
public function register()
{
spl_autoload_register([$this, 'autoload']);
}
/**
* Unregister the autoloader with spl_autoload registry
*
* @return void
*/
public function unregister()
{
spl_autoload_unregister([$this, 'autoload']);
}
/**
* registerPaths
*
* @param array|Traversable $paths
* @throws \InvalidArgumentException
* @return ModuleAutoloader
*/
public function registerPaths($paths)
{
if (! is_array($paths) && ! $paths instanceof Traversable) {
require_once __DIR__ . '/Exception/InvalidArgumentException.php';
throw new Exception\InvalidArgumentException(
'Parameter to \\Laminas\\Loader\\ModuleAutoloader\'s '
. 'registerPaths method must be an array or '
. 'implement the Traversable interface'
);
}
foreach ($paths as $module => $path) {
if (is_string($module)) {
$this->registerPath($path, $module);
} else {
$this->registerPath($path);
}
}
return $this;
}
/**
* registerPath
*
* @param string $path
* @param bool|string $moduleName
* @throws \InvalidArgumentException
* @return ModuleAutoloader
*/
public function registerPath($path, $moduleName = false)
{
if (! is_string($path)) {
require_once __DIR__ . '/Exception/InvalidArgumentException.php';
throw new Exception\InvalidArgumentException(sprintf(
'Invalid path provided; must be a string, received %s',
gettype($path)
));
}
if ($moduleName) {
if (in_array(substr($moduleName, -2), ['\\*', '\\%'])) {
$this->namespacedPaths[substr($moduleName, 0, -2)] = static::normalizePath($path);
} else {
$this->explicitPaths[$moduleName] = static::normalizePath($path);
}
} else {
$this->paths[] = static::normalizePath($path);
}
return $this;
}
/**
* getPaths
*
* This is primarily for unit testing, but could have other uses.
*
* @return array
*/
public function getPaths()
{
return $this->paths;
}
/**
* Returns the base module name from the path to a phar
*
* @param string $pharPath
* @return string
*/
protected function pharFileToModuleName($pharPath)
{
do {
$pathinfo = pathinfo($pharPath);
$pharPath = $pathinfo['filename'];
} while (isset($pathinfo['extension']));
return $pathinfo['filename'];
}
/**
* Normalize a path for insertion in the stack
*
* @param string $path
* @param bool $trailingSlash Whether trailing slash should be included
* @return string
*/
public static function normalizePath($path, $trailingSlash = true)
{
$path = rtrim($path, '/');
$path = rtrim($path, '\\');
if ($trailingSlash) {
$path .= DIRECTORY_SEPARATOR;
}
return $path;
}
}
PK Pw src/AutoloaderFactory.phpnu W+A
* array(
* '' => $autoloaderOptions,
* )
*
*
* The factory will then loop through and instantiate each autoloader with
* the specified options, and register each with the spl_autoloader.
*
* You may retrieve the concrete autoloader instances later using
* {@link getRegisteredAutoloaders()}.
*
* Note that the class names must be resolvable on the include_path or via
* the Laminas library, using PSR-0 rules (unless the class has already been
* loaded).
*
* @param array|Traversable $options (optional) options to use. Defaults to Laminas\Loader\StandardAutoloader
* @return void
* @throws Exception\InvalidArgumentException for invalid options
* @throws Exception\InvalidArgumentException for unloadable autoloader classes
* @throws Exception\DomainException for autoloader classes not implementing SplAutoloader
*/
public static function factory($options = null)
{
if (null === $options) {
if (! isset(static::$loaders[static::STANDARD_AUTOLOADER])) {
$autoloader = static::getStandardAutoloader();
$autoloader->register();
static::$loaders[static::STANDARD_AUTOLOADER] = $autoloader;
}
// Return so we don't hit the next check's exception (we're done here anyway)
return;
}
if (! is_array($options) && ! ($options instanceof Traversable)) {
require_once __DIR__ . '/Exception/InvalidArgumentException.php';
throw new Exception\InvalidArgumentException(
'Options provided must be an array or Traversable'
);
}
foreach ($options as $class => $autoloaderOptions) {
if (! isset(static::$loaders[$class])) {
$autoloader = static::getStandardAutoloader();
if (! class_exists($class) && ! $autoloader->autoload($class)) {
require_once 'Exception/InvalidArgumentException.php';
throw new Exception\InvalidArgumentException(
sprintf('Autoloader class "%s" not loaded', $class)
);
}
if (! is_subclass_of($class, 'Laminas\Loader\SplAutoloader')) {
require_once 'Exception/InvalidArgumentException.php';
throw new Exception\InvalidArgumentException(
sprintf('Autoloader class %s must implement Laminas\\Loader\\SplAutoloader', $class)
);
}
if ($class === static::STANDARD_AUTOLOADER) {
$autoloader->setOptions($autoloaderOptions);
} else {
$autoloader = new $class($autoloaderOptions);
}
$autoloader->register();
static::$loaders[$class] = $autoloader;
} else {
static::$loaders[$class]->setOptions($autoloaderOptions);
}
}
}
/**
* Get a list of all autoloaders registered with the factory
*
* Returns an array of autoloader instances.
*
* @return array
*/
public static function getRegisteredAutoloaders()
{
return static::$loaders;
}
/**
* Retrieves an autoloader by class name
*
* @param string $class
* @return SplAutoloader
* @throws Exception\InvalidArgumentException for non-registered class
*/
public static function getRegisteredAutoloader($class)
{
if (! isset(static::$loaders[$class])) {
require_once 'Exception/InvalidArgumentException.php';
throw new Exception\InvalidArgumentException(sprintf('Autoloader class "%s" not loaded', $class));
}
return static::$loaders[$class];
}
/**
* Unregisters all autoloaders that have been registered via the factory.
* This will NOT unregister autoloaders registered outside of the fctory.
*
* @return void
*/
public static function unregisterAutoloaders()
{
foreach (static::getRegisteredAutoloaders() as $class => $autoloader) {
spl_autoload_unregister([$autoloader, 'autoload']);
unset(static::$loaders[$class]);
}
}
/**
* Unregister a single autoloader by class name
*
* @param string $autoloaderClass
* @return bool
*/
public static function unregisterAutoloader($autoloaderClass)
{
if (! isset(static::$loaders[$autoloaderClass])) {
return false;
}
$autoloader = static::$loaders[$autoloaderClass];
spl_autoload_unregister([$autoloader, 'autoload']);
unset(static::$loaders[$autoloaderClass]);
return true;
}
/**
* Get an instance of the standard autoloader
*
* Used to attempt to resolve autoloader classes, using the
* StandardAutoloader. The instance is marked as a fallback autoloader, to
* allow resolving autoloaders not under the "Laminas" namespace.
*
* @return SplAutoloader
*/
protected static function getStandardAutoloader()
{
if (null !== static::$standardAutoloader) {
return static::$standardAutoloader;
}
if (! class_exists(static::STANDARD_AUTOLOADER)) {
// Extract the filename from the classname
$stdAutoloader = substr(strrchr(static::STANDARD_AUTOLOADER, '\\'), 1);
require_once __DIR__ . "/$stdAutoloader.php";
}
$loader = new StandardAutoloader();
static::$standardAutoloader = $loader;
return static::$standardAutoloader;
}
/**
* Checks if the object has this class as one of its parents
*
* @see https://bugs.php.net/bug.php?id=53727
* @see https://github.com/zendframework/zf2/pull/1807
*
* @deprecated since laminas 2.3 requires PHP >= 5.3.23
*
* @param string $className
* @param string $type
* @return bool
*/
protected static function isSubclassOf($className, $type)
{
return is_subclass_of($className, $type);
}
}
PK P n src/PluginClassLoader.phpnu W+A class name pairs
* @var array
*/
protected $plugins = [];
/**
* Static map allow global seeding of plugin loader
* @var array
*/
protected static $staticMap = [];
/**
* Constructor
*
* @param null|array|Traversable $map If provided, seeds the loader with a map
*/
public function __construct($map = null)
{
// Merge in static overrides
if (! empty(static::$staticMap)) {
$this->registerPlugins(static::$staticMap);
}
// Merge in constructor arguments
if ($map !== null) {
$this->registerPlugins($map);
}
}
/**
* Add a static map of plugins
*
* A null value will clear the static map.
*
* @param null|array|Traversable $map
* @throws Exception\InvalidArgumentException
* @return void
*/
public static function addStaticMap($map)
{
if (null === $map) {
static::$staticMap = [];
return;
}
if (! is_array($map) && ! $map instanceof Traversable) {
throw new Exception\InvalidArgumentException('Expects an array or Traversable object');
}
foreach ($map as $key => $value) {
static::$staticMap[$key] = $value;
}
}
/**
* Register a class to a given short name
*
* @param string $shortName
* @param string $className
* @return PluginClassLoader
*/
public function registerPlugin($shortName, $className)
{
$this->plugins[strtolower($shortName)] = $className;
return $this;
}
/**
* Register many plugins at once
*
* If $map is a string, assumes that the map is the class name of a
* Traversable object (likely a ShortNameLocator); it will then instantiate
* this class and use it to register plugins.
*
* If $map is an array or Traversable object, it will iterate it to
* register plugin names/classes.
*
* For all other arguments, or if the string $map is not a class or not a
* Traversable class, an exception will be raised.
*
* @param string|array|Traversable $map
* @return PluginClassLoader
* @throws Exception\InvalidArgumentException
*/
public function registerPlugins($map)
{
if (is_string($map)) {
if (! class_exists($map)) {
throw new Exception\InvalidArgumentException('Map class provided is invalid');
}
$map = new $map;
}
if (is_array($map)) {
$map = new ArrayIterator($map);
}
if (! $map instanceof Traversable) {
throw new Exception\InvalidArgumentException('Map provided is invalid; must be traversable');
}
// iterator_apply doesn't work as expected with IteratorAggregate
if ($map instanceof IteratorAggregate) {
$map = $map->getIterator();
}
foreach ($map as $name => $class) {
if (is_int($name) || is_numeric($name)) {
if (! is_object($class) && class_exists($class)) {
$class = new $class();
}
if ($class instanceof Traversable) {
$this->registerPlugins($class);
continue;
}
}
$this->registerPlugin($name, $class);
}
return $this;
}
/**
* Unregister a short name lookup
*
* @param mixed $shortName
* @return PluginClassLoader
*/
public function unregisterPlugin($shortName)
{
$lookup = strtolower($shortName);
if (array_key_exists($lookup, $this->plugins)) {
unset($this->plugins[$lookup]);
}
return $this;
}
/**
* Get a list of all registered plugins
*
* @return array|Traversable
*/
public function getRegisteredPlugins()
{
return $this->plugins;
}
/**
* Whether or not a plugin by a specific name has been registered
*
* @param string $name
* @return bool
*/
public function isLoaded($name)
{
$lookup = strtolower($name);
return isset($this->plugins[$lookup]);
}
/**
* Return full class name for a named helper
*
* @param string $name
* @return string|false
*/
public function getClassName($name)
{
return $this->load($name);
}
/**
* Load a helper via the name provided
*
* @param string $name
* @return string|false
*/
public function load($name)
{
if (! $this->isLoaded($name)) {
return false;
}
return $this->plugins[strtolower($name)];
}
/**
* Defined by IteratorAggregate
*
* Returns an instance of ArrayIterator, containing a map of
* all plugins
*
* @return ArrayIterator
*/
public function getIterator()
{
return new ArrayIterator($this->plugins);
}
}
PK Pf>
mkdocs.ymlnu W+A docs_dir: docs/book
site_dir: docs/html
nav:
- Home: index.md
- Reference:
- AutoloaderFactory: autoloader-factory.md
- StandardAutoloader: standard-autoloader.md
- ClassMapAutoloader: class-map-autoloader.md
- ModuleAutoloader: module-autoloader.md
- SplAutoloader: spl-autoloader.md
- PluginClassLoader: plugin-class-loader.md
- ShortNameLocator: short-name-locator.md
- PluginClassLocator: plugin-class-locator.md
- "ClassMap Generator": classmap-generator.md
site_name: laminas-loader
site_description: 'Autoloading and plugin loading strategies'
repo_url: 'https://github.com/laminas/laminas-loader'
extra:
project: Components
PK P;bJ J .github/workflows/docs-build.ymlnu W+A name: docs-build
on:
push:
branches:
- master
repository_dispatch:
types: docs-build
jobs:
build-deploy:
runs-on: ubuntu-latest
steps:
- name: Build Docs
uses: laminas/documentation-theme/github-actions/docs@master
env:
DOCS_DEPLOY_KEY: ${{ secrets.DOCS_DEPLOY_KEY }}
PK PRa .gitattributesnu W+A /.coveralls.yml export-ignore
/.gitattributes export-ignore
/.github/ export-ignore
/.gitignore export-ignore
/.travis.yml export-ignore
/docs/ export-ignore
/mkdocs.yml export-ignore
/phpcs.xml export-ignore
/phpunit.xml.dist export-ignore
/test/ export-ignore
PK PQ test/AutoloaderFactoryTest.phpnu W+A loaders = spl_autoload_functions();
if (! is_array($this->loaders)) {
// spl_autoload_functions does not return empty array when no
// autoloaders registered...
$this->loaders = [];
}
// Store original include_path
$this->includePath = get_include_path();
}
public function tearDown()
{
AutoloaderFactory::unregisterAutoloaders();
// Restore original autoloaders
$loaders = spl_autoload_functions();
if (is_array($loaders)) {
foreach ($loaders as $loader) {
spl_autoload_unregister($loader);
}
}
foreach ($this->loaders as $loader) {
spl_autoload_register($loader);
}
// Restore original include_path
set_include_path($this->includePath);
}
public function testRegisteringValidMapFilePopulatesAutoloader()
{
AutoloaderFactory::factory([
'Laminas\Loader\ClassMapAutoloader' => [
__DIR__ . '/_files/goodmap.php',
],
]);
$loader = AutoloaderFactory::getRegisteredAutoloader('Laminas\Loader\ClassMapAutoloader');
$map = $loader->getAutoloadMap();
$this->assertInternalType('array', $map);
$this->assertCount(2, $map);
}
/**
* This tests checks if invalid autoloaders cause exceptions
*
* @expectedException InvalidArgumentException
*/
public function testFactoryCatchesInvalidClasses()
{
include __DIR__ . '/_files/InvalidInterfaceAutoloader.php';
AutoloaderFactory::factory([
'InvalidInterfaceAutoloader' => []
]);
}
public function testFactoryDoesNotRegisterDuplicateAutoloaders()
{
AutoloaderFactory::factory([
'Laminas\Loader\StandardAutoloader' => [
'namespaces' => [
'TestNamespace' => __DIR__ . '/TestAsset/TestNamespace',
],
],
]);
$this->assertCount(1, AutoloaderFactory::getRegisteredAutoloaders());
AutoloaderFactory::factory([
'Laminas\Loader\StandardAutoloader' => [
'namespaces' => [
'LaminasTest\Loader\TestAsset\TestPlugins' => __DIR__ . '/TestAsset/TestPlugins',
],
],
]);
$this->assertCount(1, AutoloaderFactory::getRegisteredAutoloaders());
$this->assertTrue(class_exists('TestNamespace\NoDuplicateAutoloadersCase'));
$this->assertTrue(class_exists('LaminasTest\Loader\TestAsset\TestPlugins\Foo'));
}
public function testCanUnregisterAutoloaders()
{
AutoloaderFactory::factory([
'Laminas\Loader\StandardAutoloader' => [
'namespaces' => [
'TestNamespace' => __DIR__ . '/TestAsset/TestNamespace',
],
],
]);
AutoloaderFactory::unregisterAutoloaders();
$this->assertCount(0, AutoloaderFactory::getRegisteredAutoloaders());
}
public function testCanUnregisterAutoloadersByClassName()
{
AutoloaderFactory::factory([
'Laminas\Loader\StandardAutoloader' => [
'namespaces' => [
'TestNamespace' => __DIR__ . '/TestAsset/TestNamespace',
],
],
]);
AutoloaderFactory::unregisterAutoloader('Laminas\Loader\StandardAutoloader');
$this->assertCount(0, AutoloaderFactory::getRegisteredAutoloaders());
}
public function testCanGetValidRegisteredAutoloader()
{
AutoloaderFactory::factory([
'Laminas\Loader\StandardAutoloader' => [
'namespaces' => [
'TestNamespace' => __DIR__ . '/TestAsset/TestNamespace',
],
],
]);
$autoloader = AutoloaderFactory::getRegisteredAutoloader('Laminas\Loader\StandardAutoloader');
$this->assertInstanceOf('Laminas\Loader\StandardAutoloader', $autoloader);
}
public function testDefaultAutoloader()
{
AutoloaderFactory::factory();
$autoloader = AutoloaderFactory::getRegisteredAutoloader('Laminas\Loader\StandardAutoloader');
$this->assertInstanceOf('Laminas\Loader\StandardAutoloader', $autoloader);
$this->assertCount(1, AutoloaderFactory::getRegisteredAutoloaders());
}
public function testGetInvalidAutoloaderThrowsException()
{
$this->expectException(InvalidArgumentException::class);
$loader = AutoloaderFactory::getRegisteredAutoloader('InvalidAutoloader');
}
public function testFactoryWithInvalidArgumentThrowsException()
{
$this->expectException(InvalidArgumentException::class);
AutoloaderFactory::factory('InvalidArgument');
}
public function testFactoryWithInvalidAutoloaderClassThrowsException()
{
$this->expectException(InvalidArgumentException::class);
AutoloaderFactory::factory(['InvalidAutoloader' => []]);
}
public function testCannotBeInstantiatedViaConstructor()
{
$reflection = new ReflectionClass('Laminas\Loader\AutoloaderFactory');
$constructor = $reflection->getConstructor();
$this->assertNull($constructor);
}
public function testPassingNoArgumentsToFactoryInstantiatesAndRegistersStandardAutoloader()
{
AutoloaderFactory::factory();
$loaders = AutoloaderFactory::getRegisteredAutoloaders();
$this->assertCount(1, $loaders);
$loader = array_shift($loaders);
$this->assertInstanceOf('Laminas\Loader\StandardAutoloader', $loader);
$test = [$loader, 'autoload'];
$found = false;
foreach (spl_autoload_functions() as $function) {
if ($function === $test) {
$found = true;
break;
}
}
$this->assertTrue($found, 'StandardAutoloader not registered with spl_autoload');
}
}
PK P8WT ! test/TestAsset/Child/Subclass.phpnu W+A namespaces;
}
/**
* Get registered prefixes
*
* @return array
*/
public function getPrefixes()
{
return $this->prefixes;
}
}
PK PE%} } " test/TestAsset/TestPlugins/Foo.phpnu W+A services[$name])) {
return null;
}
return $this->services[$name];
}
public function has($name)
{
return (isset($this->services[$name]));
}
public function set($name, $object)
{
$this->services[$name] = $object;
}
}
PK Py.! # test/TestAsset/ClassMappedClass.phpnu W+A options = $options;
}
}
PK P%k k % test/TestAsset/plugins/second/Bat.phpnu W+A options = $options;
}
}
PK P4z32 2 test/TestAsset/TestPluginMap.phpnu W+A __CLASS__,
'test' => 'LaminasTest\Loader\PluginClassLoaderTest',
'loader' => 'Laminas\Loader\PluginClassLoader',
);
/**
* Return iterator
*
* @return Traversable
*/
public function getIterator()
{
return new \ArrayIterator($this->map);
}
}
PK Pn~ ~ # test/TestAsset/TestPlugins2/Foo.phpnu W+A 'Laminas\Loader\PluginClassLoader',
);
protected static $staticMap = array();
}
PK PJ} } " test/TestAsset/NamespacedClass.phpnu W+A loaders = spl_autoload_functions();
if (! is_array($this->loaders)) {
// spl_autoload_functions does not return empty array when no
// autoloaders registered...
$this->loaders = [];
}
// Store original include_path
$this->includePath = get_include_path();
}
public function tearDown()
{
// Restore original autoloaders
$loaders = spl_autoload_functions();
if (is_array($loaders)) {
foreach ($loaders as $loader) {
spl_autoload_unregister($loader);
}
}
foreach ($this->loaders as $loader) {
spl_autoload_register($loader);
}
// Restore original include_path
set_include_path($this->includePath);
}
public function testFallbackAutoloaderFlagDefaultsToFalse()
{
$loader = new StandardAutoloader();
$this->assertFalse($loader->isFallbackAutoloader());
}
public function testFallbackAutoloaderStateIsMutable()
{
$loader = new StandardAutoloader();
$loader->setFallbackAutoloader(true);
$this->assertTrue($loader->isFallbackAutoloader());
$loader->setFallbackAutoloader(false);
$this->assertFalse($loader->isFallbackAutoloader());
}
public function testPassingNonTraversableOptionsToSetOptionsRaisesException()
{
$loader = new StandardAutoloader();
$obj = new \stdClass();
foreach ([true, 'foo', $obj] as $arg) {
try {
$loader->setOptions(true);
$this->fail('Setting options with invalid type should fail');
} catch (InvalidArgumentException $e) {
$this->assertContains('array or Traversable', $e->getMessage());
}
}
}
public function testPassingArrayOptionsPopulatesProperties()
{
$options = [
'namespaces' => [
'Laminas\\' => dirname(__DIR__) . DIRECTORY_SEPARATOR,
],
'prefixes' => [
'Laminas_' => dirname(__DIR__) . DIRECTORY_SEPARATOR,
],
'fallback_autoloader' => true,
];
$loader = new TestAsset\StandardAutoloader();
$loader->setOptions($options);
$this->assertEquals($options['namespaces'], $loader->getNamespaces());
$this->assertEquals($options['prefixes'], $loader->getPrefixes());
$this->assertTrue($loader->isFallbackAutoloader());
}
public function testPassingTraversableOptionsPopulatesProperties()
{
$namespaces = new \ArrayObject([
'Laminas\\' => dirname(__DIR__) . DIRECTORY_SEPARATOR,
]);
$prefixes = new \ArrayObject([
'Laminas_' => dirname(__DIR__) . DIRECTORY_SEPARATOR,
]);
$options = new \ArrayObject([
'namespaces' => $namespaces,
'prefixes' => $prefixes,
'fallback_autoloader' => true,
]);
$loader = new TestAsset\StandardAutoloader();
$loader->setOptions($options);
$this->assertEquals((array) $options['namespaces'], $loader->getNamespaces());
$this->assertEquals((array) $options['prefixes'], $loader->getPrefixes());
$this->assertTrue($loader->isFallbackAutoloader());
}
public function testAutoloadsNamespacedClasses()
{
$loader = new StandardAutoloader();
$loader->registerNamespace('LaminasTest\UnusualNamespace', __DIR__ . '/TestAsset');
$loader->autoload('LaminasTest\UnusualNamespace\NamespacedClass');
$this->assertTrue(class_exists('LaminasTest\UnusualNamespace\NamespacedClass', false));
}
public function testAutoloadsVendorPrefixedClasses()
{
$loader = new StandardAutoloader();
$loader->registerPrefix('LaminasTest_UnusualPrefix', __DIR__ . '/TestAsset');
$loader->autoload('LaminasTest_UnusualPrefix_PrefixedClass');
$this->assertTrue(class_exists('LaminasTest_UnusualPrefix_PrefixedClass', false));
}
public function testCanActAsFallbackAutoloader()
{
$loader = new StandardAutoloader();
$loader->setFallbackAutoloader(true);
set_include_path(__DIR__ . '/TestAsset/' . PATH_SEPARATOR . $this->includePath);
$loader->autoload('TestNamespace\FallbackCase');
$this->assertTrue(class_exists('TestNamespace\FallbackCase', false));
}
public function testReturnsFalseForUnresolveableClassNames()
{
$loader = new StandardAutoloader();
$this->assertFalse($loader->autoload('Some\Fake\Classname'));
}
public function testReturnsFalseForInvalidClassNames()
{
$loader = new StandardAutoloader();
$loader->setFallbackAutoloader(true);
$this->assertFalse($loader->autoload('Some\Invalid\Classname\\'));
}
public function testRegisterRegistersCallbackWithSplAutoload()
{
$loader = new StandardAutoloader();
$loader->register();
$loaders = spl_autoload_functions();
$this->assertGreaterThan(count($this->loaders), count($loaders));
$test = array_pop($loaders);
$this->assertEquals([$loader, 'autoload'], $test);
}
public function testAutoloadsNamespacedClassesWithUnderscores()
{
$loader = new StandardAutoloader();
$loader->registerNamespace('LaminasTest\UnusualNamespace', __DIR__ . '/TestAsset');
$loader->autoload('LaminasTest\UnusualNamespace\Name_Space\Namespaced_Class');
$this->assertTrue(class_exists('LaminasTest\UnusualNamespace\Name_Space\Namespaced_Class', false));
}
public function testLaminasNamespaceIsNotLoadedByDefault()
{
$loader = new StandardAutoloader();
$expected = [];
$this->assertAttributeEquals($expected, 'namespaces', $loader);
}
public function testCanTellAutoloaderToRegisterLaminasNamespaceAtInstantiation()
{
$loader = new StandardAutoloader(['autoregister_laminas' => true]);
$r = new ReflectionClass($loader);
$file = $r->getFileName();
$expected = [
'Laminas\\' => dirname(dirname($file)) . DIRECTORY_SEPARATOR,
];
$this->assertAttributeEquals($expected, 'namespaces', $loader);
}
public function testWillLoopThroughAllNamespacesUntilMatchIsFoundWhenAutoloading()
{
$loader = new StandardAutoloader();
$loader->registerNamespace('LaminasTest\Loader\TestAsset\Parent', __DIR__ . '/TestAsset/Parent');
$loader->registerNamespace('LaminasTest\Loader\TestAsset\Parent\Child', __DIR__ . '/TestAsset/Child');
$result = $loader->autoload('LaminasTest\Loader\TestAsset\Parent\Child\Subclass');
$this->assertNotFalse($result);
$this->assertTrue(class_exists('LaminasTest\Loader\TestAsset\Parent\Child\Subclass', false));
}
}
PK PT,~# # test/PluginClassLoaderTest.phpnu W+A loader = new PluginClassLoader();
}
public function testPluginClassLoaderHasNoAssociationsByDefault()
{
$plugins = $this->loader->getRegisteredPlugins();
$this->assertEmpty($plugins);
}
public function testRegisterPluginRegistersShortNameClassNameAssociation()
{
$this->loader->registerPlugin('loader', __CLASS__);
$plugins = $this->loader->getRegisteredPlugins();
$this->assertArrayHasKey('loader', $plugins);
$this->assertEquals(__CLASS__, $plugins['loader']);
}
public function testCallingRegisterPluginWithAnExistingPluginNameOverwritesThatMapAssociation()
{
$this->testRegisterPluginRegistersShortNameClassNameAssociation();
$this->loader->registerPlugin('loader', 'Laminas\Loader\PluginClassLoader');
$plugins = $this->loader->getRegisteredPlugins();
$this->assertArrayHasKey('loader', $plugins);
$this->assertEquals('Laminas\Loader\PluginClassLoader', $plugins['loader']);
}
public function testCallingRegisterPluginsWithInvalidStringMapRaisesException()
{
$this->expectException(InvalidArgumentException::class);
$this->loader->registerPlugins('__foobar__');
}
public function testCallingRegisterPluginsWithStringMapResolvingToNonTraversableClassRaisesException()
{
$this->expectException(InvalidArgumentException::class);
$this->loader->registerPlugins('stdClass');
}
public function testCallingRegisterPluginsWithValidStringMapResolvingToTraversableClassRegistersPlugins()
{
$this->loader->registerPlugins('LaminasTest\Loader\TestAsset\TestPluginMap');
$pluginMap = new TestAsset\TestPluginMap;
$this->assertEquals($pluginMap->map, $this->loader->getRegisteredPlugins());
}
/**
* @dataProvider invalidMaps
*/
public function testCallingRegisterPluginsWithNonArrayNonStringNonTraversableValueRaisesException($arg)
{
$this->expectException(InvalidArgumentException::class);
$this->loader->registerPlugins($arg);
}
public function invalidMaps()
{
return [
[null],
[true],
[1],
[1.0],
[new \stdClass],
];
}
public function testCallingRegisterPluginsWithArrayRegistersMap()
{
$map = ['test' => __CLASS__];
$this->loader->registerPlugins($map);
$test = $this->loader->getRegisteredPlugins();
$this->assertEquals($map, $test);
}
public function testCallingRegisterPluginsWithTraversableObjectRegistersMap()
{
$map = new TestAsset\TestPluginMap();
$this->loader->registerPlugins($map);
$test = $this->loader->getRegisteredPlugins();
$this->assertEquals($map->map, $test);
}
public function testUnregisterPluginRemovesPluginFromMap()
{
$map = new TestAsset\TestPluginMap();
$this->loader->registerPlugins($map);
$this->loader->unregisterPlugin('test');
$test = $this->loader->getRegisteredPlugins();
$this->assertArrayNotHasKey('test', $test);
}
public function testIsLoadedReturnsFalseIfPluginIsNotInMap()
{
$this->assertFalse($this->loader->isLoaded('test'));
}
public function testIsLoadedReturnsTrueIfPluginIsInMap()
{
$this->loader->registerPlugin('test', __CLASS__);
$this->assertTrue($this->loader->isLoaded('test'));
}
public function testGetClassNameReturnsFalseIfPluginIsNotInMap()
{
$this->assertFalse($this->loader->getClassName('test'));
}
public function testGetClassNameReturnsClassNameIfPluginIsInMap()
{
$this->loader->registerPlugin('test', __CLASS__);
$this->assertEquals(__CLASS__, $this->loader->getClassName('test'));
}
public function testLoadReturnsFalseIfPluginIsNotInMap()
{
$this->assertFalse($this->loader->load('test'));
}
public function testLoadReturnsClassNameIfPluginIsInMap()
{
$this->loader->registerPlugin('test', __CLASS__);
$this->assertEquals(__CLASS__, $this->loader->load('test'));
}
public function testIteratingLoaderIteratesPluginMap()
{
$map = new TestAsset\TestPluginMap();
$this->loader->registerPlugins($map);
$test = [];
foreach ($this->loader as $name => $class) {
$test[$name] = $class;
}
$this->assertEquals($map->map, $test);
}
public function testPluginRegistrationIsCaseInsensitive()
{
$map = [
'foo' => __CLASS__,
'FOO' => __NAMESPACE__ . '\TestAsset\TestPluginMap',
];
$this->loader->registerPlugins($map);
$this->assertEquals($map['FOO'], $this->loader->getClassName('foo'));
}
public function testAddingStaticMapDoesNotAffectExistingInstances()
{
PluginClassLoader::addStaticMap([
'test' => __CLASS__,
]);
$this->assertFalse($this->loader->getClassName('test'));
}
public function testAllowsSettingStaticMapForSeedingInstance()
{
PluginClassLoader::addStaticMap([
'test' => __CLASS__,
]);
$loader = new PluginClassLoader();
$this->assertEquals(__CLASS__, $loader->getClassName('test'));
}
public function testPassingNullToStaticMapClearsMap()
{
$this->testAllowsSettingStaticMapForSeedingInstance();
PluginClassLoader::addStaticMap(null);
$loader = new PluginClassLoader();
$this->assertFalse($loader->getClassName('test'));
}
public function testAllowsPassingTraversableObjectToStaticMap()
{
$map = new \ArrayObject([
'test' => __CLASS__,
]);
PluginClassLoader::addStaticMap($map);
$loader = new PluginClassLoader();
$this->assertEquals(__CLASS__, $loader->getClassName('test'));
}
public function testMultipleCallsToAddStaticMapMergeMap()
{
PluginClassLoader::addStaticMap([
'test' => __CLASS__,
]);
PluginClassLoader::addStaticMap([
'loader' => 'Laminas\Loader\PluginClassLoader',
]);
$loader = new PluginClassLoader();
$this->assertEquals(__CLASS__, $loader->getClassName('test'));
$this->assertEquals('Laminas\Loader\PluginClassLoader', $loader->getClassName('loader'));
}
public function testStaticMapUsesLateStaticBinding()
{
TestAsset\ExtendedPluginClassLoader::addStaticMap(['test' => __CLASS__]);
$loader = new PluginClassLoader();
$this->assertFalse($loader->getClassName('test'));
$loader = new TestAsset\ExtendedPluginClassLoader();
$this->assertEquals(__CLASS__, $loader->getClassName('test'));
}
public function testMapPrecedenceIsExplicitTrumpsConstructorTrumpsStaticTrumpsInternal()
{
$loader = new TestAsset\ExtendedPluginClassLoader();
$this->assertEquals('Laminas\Loader\PluginClassLoader', $loader->getClassName('loader'));
TestAsset\ExtendedPluginClassLoader::addStaticMap(['loader' => __CLASS__]);
$loader = new TestAsset\ExtendedPluginClassLoader();
$this->assertEquals(__CLASS__, $loader->getClassName('loader'));
$loader = new TestAsset\ExtendedPluginClassLoader(
['loader' => 'LaminasTest\Loader\TestAsset\ExtendedPluginClassLoader']
);
$this->assertEquals('LaminasTest\Loader\TestAsset\ExtendedPluginClassLoader', $loader->getClassName('loader'));
$loader->registerPlugin('loader', __CLASS__);
$this->assertEquals(__CLASS__, $loader->getClassName('loader'));
}
public function testRegisterPluginsCanAcceptArrayElementWithClassNameProvidingAMap()
{
$pluginMap = new TestAsset\TestPluginMap;
$this->loader->registerPlugins(['LaminasTest\Loader\TestAsset\TestPluginMap']);
$this->assertEquals($pluginMap->map, $this->loader->getRegisteredPlugins());
}
public function testRegisterPluginsCanAcceptArrayElementWithObjectProvidingAMap()
{
$pluginMap = new TestAsset\TestPluginMap;
$this->loader->registerPlugins([$pluginMap]);
$this->assertEquals($pluginMap->map, $this->loader->getRegisteredPlugins());
}
}
PK PN]3 3 test/ClassMapAutoloaderTest.phpnu W+A loaders = spl_autoload_functions();
if (! is_array($this->loaders)) {
// spl_autoload_functions does not return empty array when no
// autoloaders registered...
$this->loaders = [];
}
// Store original include_path
$this->includePath = get_include_path();
$this->loader = new ClassMapAutoloader();
}
public function tearDown()
{
// Restore original autoloaders
$loaders = spl_autoload_functions();
if (is_array($loaders)) {
foreach ($loaders as $loader) {
spl_autoload_unregister($loader);
}
}
foreach ($this->loaders as $loader) {
spl_autoload_register($loader);
}
// Restore original include_path
set_include_path($this->includePath);
}
public function testRegisteringNonExistentAutoloadMapRaisesInvalidArgumentException()
{
$dir = __DIR__ . '__foobar__';
$this->expectException(InvalidArgumentException::class);
$this->loader->registerAutoloadMap($dir);
}
public function testValidMapFileNotReturningMapRaisesInvalidArgumentException()
{
$this->expectException(InvalidArgumentException::class);
$this->loader->registerAutoloadMap(__DIR__ . '/_files/badmap.php');
}
public function testAllowsRegisteringArrayAutoloadMapDirectly()
{
$map = [
// @codingStandardsIgnoreStart
'Laminas\Loader\Exception\ExceptionInterface' => __DIR__ . '/../../../library/Laminas/Loader/Exception/ExceptionInterface.php',
// @codingStandardsIgnoreEnd
];
$this->loader->registerAutoloadMap($map);
$test = $this->loader->getAutoloadMap();
$this->assertSame($map, $test);
}
public function testAllowsRegisteringArrayAutoloadMapViaConstructor()
{
$map = [
// @codingStandardsIgnoreStart
'Laminas\Loader\Exception\ExceptionInterface' => __DIR__ . '/../../../library/Laminas/Loader/Exception/ExceptionInterface.php',
// @codingStandardsIgnoreEnd
];
$loader = new ClassMapAutoloader([$map]);
$test = $loader->getAutoloadMap();
$this->assertSame($map, $test);
}
public function testRegisteringValidMapFilePopulatesAutoloader()
{
$this->loader->registerAutoloadMap(__DIR__ . '/_files/goodmap.php');
$map = $this->loader->getAutoloadMap();
$this->assertInternalType('array', $map);
$this->assertCount(2, $map);
// Just to make sure nothing changes after loading the same map again
// (loadMapFromFile should just return)
$this->loader->registerAutoloadMap(__DIR__ . '/_files/goodmap.php');
$map = $this->loader->getAutoloadMap();
$this->assertInternalType('array', $map);
$this->assertCount(2, $map);
}
public function testRegisteringMultipleMapsMergesThem()
{
$map = [
// @codingStandardsIgnoreStart
'Laminas\Loader\Exception\ExceptionInterface' => __DIR__ . '/../../../library/Laminas/Loader/Exception/ExceptionInterface.php',
// @codingStandardsIgnoreEnd
'LaminasTest\Loader\StandardAutoloaderTest' => 'some/bogus/path.php',
];
$this->loader->registerAutoloadMap($map);
$this->loader->registerAutoloadMap(__DIR__ . '/_files/goodmap.php');
$test = $this->loader->getAutoloadMap();
$this->assertInternalType('array', $test);
$this->assertCount(3, $test);
$this->assertNotEquals(
$map['LaminasTest\Loader\StandardAutoloaderTest'],
$test['LaminasTest\Loader\StandardAutoloaderTest']
);
}
public function testCanRegisterMultipleMapsAtOnce()
{
$map = [
// @codingStandardsIgnoreStart
'Laminas\Loader\Exception\ExceptionInterface' => __DIR__ . '/../../../library/Laminas/Loader/Exception/ExceptionInterface.php',
// @codingStandardsIgnoreEnd
'LaminasTest\Loader\StandardAutoloaderTest' => 'some/bogus/path.php',
];
$maps = [$map, __DIR__ . '/_files/goodmap.php'];
$this->loader->registerAutoloadMaps($maps);
$test = $this->loader->getAutoloadMap();
$this->assertInternalType('array', $test);
$this->assertCount(3, $test);
}
public function testRegisterMapsThrowsExceptionForNonTraversableArguments()
{
$tests = [true, 'string', 1, 1.0, new \stdClass];
foreach ($tests as $test) {
try {
$this->loader->registerAutoloadMaps($test);
$this->fail('Should not register non-traversable arguments');
} catch (InvalidArgumentException $e) {
$this->assertContains('array or implement Traversable', $e->getMessage());
}
}
}
public function testAutoloadLoadsClasses()
{
$map = ['LaminasTest\UnusualNamespace\ClassMappedClass' => __DIR__ . '/TestAsset/ClassMappedClass.php'];
$this->loader->registerAutoloadMap($map);
$loaded = $this->loader->autoload('LaminasTest\UnusualNamespace\ClassMappedClass');
$this->assertSame('LaminasTest\UnusualNamespace\ClassMappedClass', $loaded);
$this->assertTrue(class_exists('LaminasTest\UnusualNamespace\ClassMappedClass', false));
}
public function testIgnoresClassesNotInItsMap()
{
$map = ['LaminasTest\UnusualNamespace\ClassMappedClass' => __DIR__ . '/TestAsset/ClassMappedClass.php'];
$this->loader->registerAutoloadMap($map);
$this->assertFalse($this->loader->autoload('LaminasTest\UnusualNamespace\UnMappedClass'));
$this->assertFalse(class_exists('LaminasTest\UnusualNamespace\UnMappedClass', false));
}
public function testRegisterRegistersCallbackWithSplAutoload()
{
$this->loader->register();
$loaders = spl_autoload_functions();
$this->assertGreaterThan(count($this->loaders), count($loaders));
$test = array_shift($loaders);
$this->assertEquals([$this->loader, 'autoload'], $test);
}
public function testCanLoadClassMapFromPhar()
{
// @codingStandardsIgnoreStart
$map = 'phar://' . str_replace('/', DIRECTORY_SEPARATOR, __DIR__ . '/_files/classmap.phar/test/.//../autoload_classmap.php');
// @codingStandardsIgnoreEnd
$this->loader->registerAutoloadMap($map);
$loaded = $this->loader->autoload('some\loadedclass');
$this->assertSame('some\loadedclass', $loaded);
$this->assertTrue(class_exists('some\loadedclass', false));
// will not register duplicate, even with a different relative path
// @codingStandardsIgnoreStart
$map = 'phar://' . str_replace('/', DIRECTORY_SEPARATOR, __DIR__ . '/_files/classmap.phar/test/./foo/../../autoload_classmap.php');
// @codingStandardsIgnoreEnd
$this->loader->registerAutoloadMap($map);
$test = $this->loader->getAutoloadMap();
$this->assertCount(1, $test);
}
}
PK PR
" " test/ModuleAutoloaderTest.phpnu W+A loaders = spl_autoload_functions();
if (! is_array($this->loaders)) {
// spl_autoload_functions does not return empty array when no
// autoloaders registered...
$this->loaders = [];
}
// Store original include_path
$this->includePath = get_include_path();
}
public function tearDown()
{
// Restore original autoloaders
$loaders = spl_autoload_functions();
if (is_array($loaders)) {
foreach ($loaders as $loader) {
spl_autoload_unregister($loader);
}
}
foreach ($this->loaders as $loader) {
spl_autoload_register($loader);
}
// Restore original include_path
set_include_path($this->includePath);
}
public function testCanRegisterPathsFromConstructor()
{
$paths = [__DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR];
$loader = new ModuleAutoloader($paths);
$registeredPaths = $loader->getPaths();
$this->assertSame($paths, $registeredPaths);
}
public function testPathsNormalizedWithTrailingSlash()
{
$paths = [
__DIR__ . DIRECTORY_SEPARATOR . '_files',
__DIR__ . DIRECTORY_SEPARATOR . '_files///',
__DIR__ . DIRECTORY_SEPARATOR . '_files\\\\',
];
$loader = new ModuleAutoloader($paths);
$registeredPaths = $loader->getPaths();
$this->assertSame(__DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR, $registeredPaths[0]);
$this->assertSame(__DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR, $registeredPaths[1]);
$this->assertSame(__DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR, $registeredPaths[2]);
}
public function testCanAutoloadModule()
{
$loader = new ModuleAutoloader;
$loader->registerPath(__DIR__ . '/_files/');
$moduleClass = $loader->autoload('FooModule\Module');
$this->assertSame('FooModule\Module', $moduleClass);
$module = new \FooModule\Module;
$this->assertInstanceOf('FooModule\Module', $module);
}
public function testCanAutoloadSubModule()
{
$loader = new ModuleAutoloader;
$loader->registerPath(__DIR__ . '/_files/');
$loader->register();
$subModule = new \FooModule\SubModule\Module;
$this->assertInstanceOf('FooModule\SubModule\Module', $subModule);
$loader->unregister();
}
public function testCanAutoloadPharModules()
{
$loader = new ModuleAutoloader;
$loader->registerPath(__DIR__ . '/_files/');
$loader->register();
$this->assertTrue(class_exists('PharModule\Module'));
$this->assertTrue(class_exists('PharModuleTar\Module'));
$this->assertTrue(class_exists('PharModulePharTar\Module'));
$this->assertTrue(class_exists('PharModuleNested\Module'));
// gzip / zip
if (extension_loaded('zlib')) {
// gzip
$this->assertTrue(class_exists('PharModuleGz\Module'));
$this->assertTrue(class_exists('PharModulePharTarGz\Module'));
$this->assertTrue(class_exists('PharModuleTarGz\Module'));
// zip
$this->assertTrue(class_exists('PharModulePharZip\Module'));
$this->assertTrue(class_exists('PharModuleZip\Module'));
} else {
$this->assertFalse(class_exists('PharModuleGz\Module'));
$this->assertFalse(class_exists('PharModulePharTarGz\Module'));
$this->assertFalse(class_exists('PharModuleTarGz\Module'));
$this->assertFalse(class_exists('PharModulePharZip\Module'));
$this->assertFalse(class_exists('PharModuleZip\Module'));
}
// bzip2
if (extension_loaded('bzip2')) {
$this->assertTrue(class_exists('PharModuleBz2\Module'));
$this->assertTrue(class_exists('PharModulePharTarBz2\Module'));
$this->assertTrue(class_exists('PharModuleTarBz2\Module'));
} else {
$this->assertFalse(class_exists('PharModuleBz2\Module'));
$this->assertFalse(class_exists('PharModulePharTarBz2\Module'));
$this->assertFalse(class_exists('PharModuleTarBz2\Module'));
}
$loader->unregister();
}
public function testCanAutoloadModulesFromWithinExecutedPhar()
{
$loader = new ModuleAutoloader;
$class = new \ReflectionClass('Laminas\Loader\ModuleAutoloader');
$property = $class->getProperty("pharBasePath");
$property->setAccessible(true);
$property->setValue($loader, 'phar://' . __DIR__ . '/_files/ApplicationModulePhar.phar');
$loader->registerPath('./module');
$loader->register();
$this->assertTrue(class_exists('Application\Module'));
}
public function testProvidesFluidInterface()
{
$loader = new ModuleAutoloader;
$this->assertInstanceOf('Laminas\Loader\ModuleAutoloader', $loader->setOptions(['foo']));
$this->assertInstanceOf('Laminas\Loader\ModuleAutoloader', $loader->registerPaths(['foo']));
$this->assertInstanceOf('Laminas\Loader\ModuleAutoloader', $loader->registerPath('foo'));
}
public function testReturnsFalseForNonModuleClass()
{
$loader = new ModuleAutoloader;
$loader->registerPath(__DIR__ . '/_files/');
$moduleClass = $loader->autoload('FooModule\NotModule');
$this->assertFalse($moduleClass);
}
public function testReturnsFalseForNonExistantModuleClass()
{
$loader = new ModuleAutoloader;
$loader->registerPath(__DIR__ . '/_files/');
$moduleClass = $loader->autoload('NonExistantModule\Module');
$this->assertFalse($moduleClass);
$loader->registerPath(__DIR__ . '/_files/NonExistantModule', 'NonExistantModule');
$moduleClass = $loader->autoload('NonExistantModule\Module');
$this->assertFalse($moduleClass);
$moduleClass = $loader->autoload('NoModuleClassModule\Module');
$this->assertFalse($moduleClass);
}
public function testReturnsFalseForNonModulePhar()
{
$loader = new ModuleAutoloader;
$loader->registerPath(__DIR__ . '/_files/');
$moduleClass = $loader->autoload('PharModuleFake\Module');
$moduleClass = $loader->autoload('PharModuleNestedFake\Module');
$this->assertFalse($moduleClass);
}
public function testInvalidPathThrowsException()
{
$loader = new ModuleAutoloader;
$this->expectException(InvalidArgumentException::class);
$loader->registerPath(123);
}
public function testInvalidPathsThrowsException()
{
$loader = new ModuleAutoloader;
$this->expectException(InvalidArgumentException::class);
$loader->registerPaths(123);
}
public function testCanLoadModulesFromExplicitLocation()
{
$loader = new ModuleAutoloader([
'My\NonmatchingModule' => __DIR__ . '/_files/NonmatchingModule',
'PharModuleExplicit' => __DIR__ . '/_files/PharModuleExplicit.phar',
]);
$loader->register();
$this->assertTrue(class_exists('My\NonmatchingModule\Module'));
$this->assertTrue(class_exists('PharModuleExplicit\Module'));
}
public function testCanLoadModulesFromClassMap()
{
$loader = new ModuleAutoloader();
$loader->setModuleClassMap([
'BarModule\Module' => __DIR__ . '/_files/BarModule/Module.php',
'PharModuleMap\Module' => __DIR__ . '/_files/PharModuleMap.phar',
]);
$loader->register();
$this->assertTrue(class_exists('BarModule\Module'));
$this->assertTrue(class_exists('PharModuleMap\Module'));
}
public function testCanLoadModulesFromNamespace()
{
$loader = new ModuleAutoloader([
'FooModule\*' => __DIR__ . '/_files/FooModule',
'FooModule' => __DIR__ . '/_files/FooModule',
]);
$loader->register();
$this->assertTrue(class_exists('FooModule\BarModule\Module'));
$this->assertTrue(class_exists('FooModule\SubModule\Module'));
$this->assertTrue(class_exists('FooModule\Module'));
}
}
PK Pn>m " test/_files/PharModuleTarGz.tar.gznu W+A O)I+(`0 333``f`hhfbhj`jnn7354U0$h%=
\\yɩ
ETX^eŕX\ 㪮h'Q0
F( C PK P&` test/_files/PharModuleFake.zipnu W+A PK 7>?2%
Module.phpnu W+A ?2%
Module.phpnu W+A PK J O PK P" # test/_files/PharModuleNested.tar.gznu W+A H,O)IK-.IMчp
2
80U
͍<$h%=
\\yɩ
h)+9'X"U];n`Q@9 PK P-v>2 2 ! test/_files/AutoloaderClosure.phpnu W+A 2,
'c' => 'text/plain',
'cc' => 'text/plain',
'cpp' => 'text/plain',
'c++' => 'text/plain',
'dtd' => 'text/plain',
'h' => 'text/plain',
'log' => 'text/plain',
'rng' => 'text/plain',
'txt' => 'text/plain',
'xsd' => 'text/plain',
'php' => 1,
'inc' => 1,
'avi' => 'video/avi',
'bmp' => 'image/bmp',
'css' => 'text/css',
'gif' => 'image/gif',
'htm' => 'text/html',
'html' => 'text/html',
'htmls' => 'text/html',
'ico' => 'image/x-ico',
'jpe' => 'image/jpeg',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'js' => 'application/x-javascript',
'midi' => 'audio/midi',
'mid' => 'audio/midi',
'mod' => 'audio/mod',
'mov' => 'movie/quicktime',
'mp3' => 'audio/mp3',
'mpg' => 'video/mpeg',
'mpeg' => 'video/mpeg',
'pdf' => 'application/pdf',
'png' => 'image/png',
'swf' => 'application/shockwave-flash',
'tif' => 'image/tiff',
'tiff' => 'image/tiff',
'wav' => 'audio/wav',
'xbm' => 'image/xbm',
'xml' => 'text/xml',
);
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
$basename = basename(__FILE__);
if (!strpos($_SERVER['REQUEST_URI'], $basename)) {
chdir(Extract_Phar::$temp);
include $web;
return;
}
$pt = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $basename) + strlen($basename));
if (!$pt || $pt == '/') {
$pt = $web;
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . $_SERVER['REQUEST_URI'] . '/' . $pt);
exit;
}
$a = realpath(Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt);
if (!$a || strlen(dirname($a)) < strlen(Extract_Phar::$temp)) {
header('HTTP/1.0 404 Not Found');
echo "\n \n File Not Found\n \n \n 404 - File ", $pt, " Not Found
\n \n";
exit;
}
$b = pathinfo($a);
if (!isset($b['extension'])) {
header('Content-Type: text/plain');
header('Content-Length: ' . filesize($a));
readfile($a);
exit;
}
if (isset($mimes[$b['extension']])) {
if ($mimes[$b['extension']] === 1) {
include $a;
exit;
}
if ($mimes[$b['extension']] === 2) {
highlight_file($a);
exit;
}
header('Content-Type: ' .$mimes[$b['extension']]);
header('Content-Length: ' . filesize($a));
readfile($a);
exit;
}
}
class Extract_Phar
{
static $temp;
static $origdir;
const GZ = 0x1000;
const BZ2 = 0x2000;
const MASK = 0x3000;
const START = 'Module.php';
const LEN = 6687;
static function go($return = false)
{
$fp = fopen(__FILE__, 'rb');
fseek($fp, self::LEN);
$L = unpack('V', $a = (binary)fread($fp, 4));
$m = (binary)'';
do {
$read = 8192;
if ($L[1] - strlen($m) < 8192) {
$read = $L[1] - strlen($m);
}
$last = (binary)fread($fp, $read);
$m .= $last;
} while (strlen($last) && strlen($m) < $L[1]);
if (strlen($m) < $L[1]) {
die('ERROR: manifest length read was "' .
strlen($m) .'" should be "' .
$L[1] . '"');
}
$info = self::_unpack($m);
$f = $info['c'];
if ($f & self::GZ) {
if (!function_exists('gzinflate')) {
die('Error: zlib extension is not enabled -' .
' gzinflate() function needed for zlib-compressed .phars');
}
}
if ($f & self::BZ2) {
if (!function_exists('bzdecompress')) {
die('Error: bzip2 extension is not enabled -' .
' bzdecompress() function needed for bz2-compressed .phars');
}
}
$temp = self::tmpdir();
if (!$temp || !is_writable($temp)) {
$sessionpath = session_save_path();
if (strpos ($sessionpath, ";") !== false)
$sessionpath = substr ($sessionpath, strpos ($sessionpath, ";")+1);
if (!file_exists($sessionpath) || !is_dir($sessionpath)) {
die('Could not locate temporary directory to extract phar');
}
$temp = $sessionpath;
}
$temp .= '/pharextract/'.basename(__FILE__, '.phar');
self::$temp = $temp;
self::$origdir = getcwd();
@mkdir($temp, 0777, true);
$temp = realpath($temp);
if (!file_exists($temp . DIRECTORY_SEPARATOR . md5_file(__FILE__))) {
self::_removeTmpFiles($temp, getcwd());
@mkdir($temp, 0777, true);
@file_put_contents($temp . '/' . md5_file(__FILE__), '');
foreach ($info['m'] as $path => $file) {
$a = !file_exists(dirname($temp . '/' . $path));
@mkdir(dirname($temp . '/' . $path), 0777, true);
clearstatcache();
if ($path[strlen($path) - 1] == '/') {
@mkdir($temp . '/' . $path, 0777);
} else {
file_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp));
@chmod($temp . '/' . $path, 0666);
}
}
}
chdir($temp);
if (!$return) {
include self::START;
}
}
static function tmpdir()
{
if (strpos(PHP_OS, 'WIN') !== false) {
if ($var = getenv('TMP') ? getenv('TMP') : getenv('TEMP')) {
return $var;
}
if (is_dir('/temp') || mkdir('/temp')) {
return realpath('/temp');
}
return false;
}
if ($var = getenv('TMPDIR')) {
return $var;
}
return realpath('/tmp');
}
static function _unpack($m)
{
$info = unpack('V', substr($m, 0, 4));
$l = unpack('V', substr($m, 10, 4));
$m = substr($m, 14 + $l[1]);
$s = unpack('V', substr($m, 0, 4));
$o = 0;
$start = 4 + $s[1];
$ret['c'] = 0;
for ($i = 0; $i < $info[1]; $i++) {
$len = unpack('V', substr($m, $start, 4));
$start += 4;
$savepath = substr($m, $start, $len[1]);
$start += $len[1];
$ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24)));
$ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3]
& 0xffffffff);
$ret['m'][$savepath][7] = $o;
$o += $ret['m'][$savepath][2];
$start += 24 + $ret['m'][$savepath][5];
$ret['c'] |= $ret['m'][$savepath][4] & self::MASK;
}
return $ret;
}
static function extractFile($path, $entry, $fp)
{
$data = '';
$c = $entry[2];
while ($c) {
if ($c < 8192) {
$data .= @fread($fp, $c);
$c = 0;
} else {
$c -= 8192;
$data .= @fread($fp, 8192);
}
}
if ($entry[4] & self::GZ) {
$data = gzinflate($data);
} elseif ($entry[4] & self::BZ2) {
$data = bzdecompress($data);
}
if (strlen($data) != $entry[0]) {
die("Invalid internal .phar file (size error " . strlen($data) . " != " .
$stat[7] . ")");
}
if ($entry[3] != sprintf("%u", crc32((binary)$data) & 0xffffffff)) {
die("Invalid internal .phar file (checksum error)");
}
return $data;
}
static function _removeTmpFiles($temp, $origdir)
{
chdir($temp);
foreach (glob('*') as $f) {
if (file_exists($f)) {
is_dir($f) ? @rmdir($f) : @unlink($f);
if (file_exists($f) && is_dir($f)) {
self::_removeTmpFiles($f, getcwd());
}
}
}
@rmdir($temp);
clearstatcache();
chdir($origdir);
}
}
Extract_Phar::go();
__HALT_COMPILER(); ?>
8
Module.php1 P1 CTC 0) {
foreach ($glob as $file) {
if (!is_dir($file)) {
unlink($file);
}
}
}
$filename = $name . '.phar';
$phar = new Phar($filename);
switch ($mode) {
case 'normal':
$phar['Module.php'] = "convertToData($format, $compression);
} else {
$phar->setDefaultStub('Module.php', 'Module.php');
if ($format !== Phar::PHAR || $compression !== Phar::NONE) {
$phar->convertToExecutable($format, $compression);
}
}
if ($format !== Phar::PHAR || $compression !== Phar::NONE) {
unlink($filename);
}
echo "Done!\n";
}
PK PB)Yv * test/_files/NoModuleClassModule/Module.phpnu W+A X|Yh|6tYڄ%?<[op,||4y"'צ.Kc47ظXq:;Z2=O4|mxv>6