PK 3GPڤ
LICENSE.mdnu W+A Copyright (c) 2019, Laminas Foundation
All rights reserved.
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 3GPKW W COPYRIGHT.mdnu W+A Copyright (c) 2019, Laminas Foundation.
All rights reserved. (https://getlaminas.org/)
PK 3GPO'_ README.mdnu W+A # laminas-loader
[![Build Status](https://travis-ci.org/laminas/laminas-loader.svg?branch=master)](https://travis-ci.org/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 3GPI " 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 3GPp( ( 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 3GP src/PluginClassLocator.phpnu W+A
* spl_autoload_register(array($this, 'autoload'));
*
*
* @return void
*/
public function register();
}
PK 3GPfJV 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 3GPw 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 3GP 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 3GPv/ CHANGELOG.mdnu W+A # Changelog
All notable changes to this project will be documented in this file, in reverse chronological order by release.
## 2.6.1 - 2019-09-04
### Added
- [zendframework/zend-loader#18](https://github.com/zendframework/zend-loader/pull/18) adds support for PHP 7.3.
### Changed
- Nothing.
### Deprecated
- Nothing.
### Removed
- Nothing.
### Fixed
- Nothing.
## 2.6.0 - 2018-04-30
### Added
- [zendframework/zend-loader#16](https://github.com/zendframework/zend-loader/pull/16) adds support for PHP 7.1 and 7.2.
- [zendframework/zend-loader#8](https://github.com/zendframework/zend-loader/pull/8) adds documentation at https://docs.laminas.dev/laminas-loader/
### Changed
- Nothing.
### Deprecated
- Nothing.
### Removed
- [zendframework/zend-loader#16](https://github.com/zendframework/zend-loader/pull/16) removes support for PHP 5.5.
- [zendframework/zend-loader#16](https://github.com/zendframework/zend-loader/pull/16) removes support for HHVM.
### Fixed
- Nothing.
PK 3GP;I I
composer.jsonnu W+A {
"name": "laminas/laminas-loader",
"description": "Autoloading and plugin loading strategies",
"license": "BSD-3-Clause",
"keywords": [
"laminas",
"loader"
],
"homepage": "https://laminas.dev",
"support": {
"docs": "https://docs.laminas.dev/laminas-loader/",
"issues": "https://github.com/laminas/laminas-loader/issues",
"source": "https://github.com/laminas/laminas-loader",
"rss": "https://github.com/laminas/laminas-loader/releases.atom",
"chat": "https://laminas.dev/chat",
"forum": "https://discourse.laminas.dev"
},
"config": {
"sort-packages": true
},
"extra": {
"branch-alias": {
"dev-master": "2.6.x-dev",
"dev-develop": "2.7.x-dev"
}
},
"require": {
"php": "^5.6 || ^7.0",
"laminas/laminas-zendframework-bridge": "^1.0"
},
"require-dev": {
"laminas/laminas-coding-standard": "~1.0.0",
"phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.4"
},
"autoload": {
"psr-4": {
"Laminas\\Loader\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"LaminasTest\\Loader\\": "test/"
}
},
"scripts": {
"check": [
"@cs-check",
"@test"
],
"cs-check": "phpcs",
"cs-fix": "phpcbf",
"test": "phpunit --colors=always",
"test-coverage": "phpunit --colors=always --coverage-clover clover.xml"
},
"replace": {
"zendframework/zend-loader": "self.version"
}
}
PK 3GPڤ
LICENSE.mdnu W+A PK 3GPKW W COPYRIGHT.mdnu W+A PK 3GPO'_ README.mdnu W+A PK 3GPI " src/Exception/RuntimeException.phpnu W+A PK 3GPI+Ex !
src/Exception/DomainException.phpnu W+A PK 3GPb b $
src/Exception/ExceptionInterface.phpnu W+A PK 3GPد ( src/Exception/BadMethodCallException.phpnu W+A PK 3GPm0% * src/Exception/InvalidArgumentException.phpnu W+A PK 3GP) 3 ( src/Exception/MissingResourceNamespaceException.phpnu W+A PK 3GP.A ' \ src/Exception/PluginLoaderException.phpnu W+A PK 3GPB8/ # src/Exception/SecurityException.phpnu W+A PK 3GPd &