gluon-web-remote

Web remote Administration for big size of gluon routers
git clone git://archive.git.mtrnord.blog/MTRNord/gluon-web-remote.git
Log | Files | Refs | README

ClassLoader.php (12436B)


      1 <?php
      2 
      3 /*
      4  * This file is part of Composer.
      5  *
      6  * (c) Nils Adermann <naderman@naderman.de>
      7  *     Jordi Boggiano <j.boggiano@seld.be>
      8  *
      9  * For the full copyright and license information, please view the LICENSE
     10  * file that was distributed with this source code.
     11  */
     12 
     13 namespace Composer\Autoload;
     14 
     15 /**
     16  * ClassLoader implements a PSR-0 class loader
     17  *
     18  * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
     19  *
     20  *     $loader = new \Composer\Autoload\ClassLoader();
     21  *
     22  *     // register classes with namespaces
     23  *     $loader->add('Symfony\Component', __DIR__.'/component');
     24  *     $loader->add('Symfony',           __DIR__.'/framework');
     25  *
     26  *     // activate the autoloader
     27  *     $loader->register();
     28  *
     29  *     // to enable searching the include path (eg. for PEAR packages)
     30  *     $loader->setUseIncludePath(true);
     31  *
     32  * In this example, if you try to use a class in the Symfony\Component
     33  * namespace or one of its children (Symfony\Component\Console for instance),
     34  * the autoloader will first look for the class under the component/
     35  * directory, and it will then fallback to the framework/ directory if not
     36  * found before giving up.
     37  *
     38  * This class is loosely based on the Symfony UniversalClassLoader.
     39  *
     40  * @author Fabien Potencier <fabien@symfony.com>
     41  * @author Jordi Boggiano <j.boggiano@seld.be>
     42  */
     43 class ClassLoader
     44 {
     45     // PSR-4
     46     private $prefixLengthsPsr4 = array();
     47     private $prefixDirsPsr4 = array();
     48     private $fallbackDirsPsr4 = array();
     49 
     50     // PSR-0
     51     private $prefixesPsr0 = array();
     52     private $fallbackDirsPsr0 = array();
     53 
     54     private $useIncludePath = false;
     55     private $classMap = array();
     56 
     57     private $classMapAuthoritative = false;
     58 
     59     public function getPrefixes()
     60     {
     61         if (!empty($this->prefixesPsr0)) {
     62             return call_user_func_array('array_merge', $this->prefixesPsr0);
     63         }
     64 
     65         return array();
     66     }
     67 
     68     public function getPrefixesPsr4()
     69     {
     70         return $this->prefixDirsPsr4;
     71     }
     72 
     73     public function getFallbackDirs()
     74     {
     75         return $this->fallbackDirsPsr0;
     76     }
     77 
     78     public function getFallbackDirsPsr4()
     79     {
     80         return $this->fallbackDirsPsr4;
     81     }
     82 
     83     public function getClassMap()
     84     {
     85         return $this->classMap;
     86     }
     87 
     88     /**
     89      * @param array $classMap Class to filename map
     90      */
     91     public function addClassMap(array $classMap)
     92     {
     93         if ($this->classMap) {
     94             $this->classMap = array_merge($this->classMap, $classMap);
     95         } else {
     96             $this->classMap = $classMap;
     97         }
     98     }
     99 
    100     /**
    101      * Registers a set of PSR-0 directories for a given prefix, either
    102      * appending or prepending to the ones previously set for this prefix.
    103      *
    104      * @param string       $prefix  The prefix
    105      * @param array|string $paths   The PSR-0 root directories
    106      * @param bool         $prepend Whether to prepend the directories
    107      */
    108     public function add($prefix, $paths, $prepend = false)
    109     {
    110         if (!$prefix) {
    111             if ($prepend) {
    112                 $this->fallbackDirsPsr0 = array_merge(
    113                     (array) $paths,
    114                     $this->fallbackDirsPsr0
    115                 );
    116             } else {
    117                 $this->fallbackDirsPsr0 = array_merge(
    118                     $this->fallbackDirsPsr0,
    119                     (array) $paths
    120                 );
    121             }
    122 
    123             return;
    124         }
    125 
    126         $first = $prefix[0];
    127         if (!isset($this->prefixesPsr0[$first][$prefix])) {
    128             $this->prefixesPsr0[$first][$prefix] = (array) $paths;
    129 
    130             return;
    131         }
    132         if ($prepend) {
    133             $this->prefixesPsr0[$first][$prefix] = array_merge(
    134                 (array) $paths,
    135                 $this->prefixesPsr0[$first][$prefix]
    136             );
    137         } else {
    138             $this->prefixesPsr0[$first][$prefix] = array_merge(
    139                 $this->prefixesPsr0[$first][$prefix],
    140                 (array) $paths
    141             );
    142         }
    143     }
    144 
    145     /**
    146      * Registers a set of PSR-4 directories for a given namespace, either
    147      * appending or prepending to the ones previously set for this namespace.
    148      *
    149      * @param string       $prefix  The prefix/namespace, with trailing '\\'
    150      * @param array|string $paths   The PSR-0 base directories
    151      * @param bool         $prepend Whether to prepend the directories
    152      *
    153      * @throws \InvalidArgumentException
    154      */
    155     public function addPsr4($prefix, $paths, $prepend = false)
    156     {
    157         if (!$prefix) {
    158             // Register directories for the root namespace.
    159             if ($prepend) {
    160                 $this->fallbackDirsPsr4 = array_merge(
    161                     (array) $paths,
    162                     $this->fallbackDirsPsr4
    163                 );
    164             } else {
    165                 $this->fallbackDirsPsr4 = array_merge(
    166                     $this->fallbackDirsPsr4,
    167                     (array) $paths
    168                 );
    169             }
    170         } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
    171             // Register directories for a new namespace.
    172             $length = strlen($prefix);
    173             if ('\\' !== $prefix[$length - 1]) {
    174                 throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
    175             }
    176             $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
    177             $this->prefixDirsPsr4[$prefix] = (array) $paths;
    178         } elseif ($prepend) {
    179             // Prepend directories for an already registered namespace.
    180             $this->prefixDirsPsr4[$prefix] = array_merge(
    181                 (array) $paths,
    182                 $this->prefixDirsPsr4[$prefix]
    183             );
    184         } else {
    185             // Append directories for an already registered namespace.
    186             $this->prefixDirsPsr4[$prefix] = array_merge(
    187                 $this->prefixDirsPsr4[$prefix],
    188                 (array) $paths
    189             );
    190         }
    191     }
    192 
    193     /**
    194      * Registers a set of PSR-0 directories for a given prefix,
    195      * replacing any others previously set for this prefix.
    196      *
    197      * @param string       $prefix The prefix
    198      * @param array|string $paths  The PSR-0 base directories
    199      */
    200     public function set($prefix, $paths)
    201     {
    202         if (!$prefix) {
    203             $this->fallbackDirsPsr0 = (array) $paths;
    204         } else {
    205             $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
    206         }
    207     }
    208 
    209     /**
    210      * Registers a set of PSR-4 directories for a given namespace,
    211      * replacing any others previously set for this namespace.
    212      *
    213      * @param string       $prefix The prefix/namespace, with trailing '\\'
    214      * @param array|string $paths  The PSR-4 base directories
    215      *
    216      * @throws \InvalidArgumentException
    217      */
    218     public function setPsr4($prefix, $paths)
    219     {
    220         if (!$prefix) {
    221             $this->fallbackDirsPsr4 = (array) $paths;
    222         } else {
    223             $length = strlen($prefix);
    224             if ('\\' !== $prefix[$length - 1]) {
    225                 throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
    226             }
    227             $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
    228             $this->prefixDirsPsr4[$prefix] = (array) $paths;
    229         }
    230     }
    231 
    232     /**
    233      * Turns on searching the include path for class files.
    234      *
    235      * @param bool $useIncludePath
    236      */
    237     public function setUseIncludePath($useIncludePath)
    238     {
    239         $this->useIncludePath = $useIncludePath;
    240     }
    241 
    242     /**
    243      * Can be used to check if the autoloader uses the include path to check
    244      * for classes.
    245      *
    246      * @return bool
    247      */
    248     public function getUseIncludePath()
    249     {
    250         return $this->useIncludePath;
    251     }
    252 
    253     /**
    254      * Turns off searching the prefix and fallback directories for classes
    255      * that have not been registered with the class map.
    256      *
    257      * @param bool $classMapAuthoritative
    258      */
    259     public function setClassMapAuthoritative($classMapAuthoritative)
    260     {
    261         $this->classMapAuthoritative = $classMapAuthoritative;
    262     }
    263 
    264     /**
    265      * Should class lookup fail if not found in the current class map?
    266      *
    267      * @return bool
    268      */
    269     public function isClassMapAuthoritative()
    270     {
    271         return $this->classMapAuthoritative;
    272     }
    273 
    274     /**
    275      * Registers this instance as an autoloader.
    276      *
    277      * @param bool $prepend Whether to prepend the autoloader or not
    278      */
    279     public function register($prepend = false)
    280     {
    281         spl_autoload_register(array($this, 'loadClass'), true, $prepend);
    282     }
    283 
    284     /**
    285      * Unregisters this instance as an autoloader.
    286      */
    287     public function unregister()
    288     {
    289         spl_autoload_unregister(array($this, 'loadClass'));
    290     }
    291 
    292     /**
    293      * Loads the given class or interface.
    294      *
    295      * @param  string    $class The name of the class
    296      * @return bool|null True if loaded, null otherwise
    297      */
    298     public function loadClass($class)
    299     {
    300         if ($file = $this->findFile($class)) {
    301             includeFile($file);
    302 
    303             return true;
    304         }
    305     }
    306 
    307     /**
    308      * Finds the path to the file where the class is defined.
    309      *
    310      * @param string $class The name of the class
    311      *
    312      * @return string|false The path if found, false otherwise
    313      */
    314     public function findFile($class)
    315     {
    316         // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
    317         if ('\\' == $class[0]) {
    318             $class = substr($class, 1);
    319         }
    320 
    321         // class map lookup
    322         if (isset($this->classMap[$class])) {
    323             return $this->classMap[$class];
    324         }
    325         if ($this->classMapAuthoritative) {
    326             return false;
    327         }
    328 
    329         $file = $this->findFileWithExtension($class, '.php');
    330 
    331         // Search for Hack files if we are running on HHVM
    332         if ($file === null && defined('HHVM_VERSION')) {
    333             $file = $this->findFileWithExtension($class, '.hh');
    334         }
    335 
    336         if ($file === null) {
    337             // Remember that this class does not exist.
    338             return $this->classMap[$class] = false;
    339         }
    340 
    341         return $file;
    342     }
    343 
    344     private function findFileWithExtension($class, $ext)
    345     {
    346         // PSR-4 lookup
    347         $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
    348 
    349         $first = $class[0];
    350         if (isset($this->prefixLengthsPsr4[$first])) {
    351             foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
    352                 if (0 === strpos($class, $prefix)) {
    353                     foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
    354                         if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
    355                             return $file;
    356                         }
    357                     }
    358                 }
    359             }
    360         }
    361 
    362         // PSR-4 fallback dirs
    363         foreach ($this->fallbackDirsPsr4 as $dir) {
    364             if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
    365                 return $file;
    366             }
    367         }
    368 
    369         // PSR-0 lookup
    370         if (false !== $pos = strrpos($class, '\\')) {
    371             // namespaced class name
    372             $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
    373                 . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
    374         } else {
    375             // PEAR-like class name
    376             $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
    377         }
    378 
    379         if (isset($this->prefixesPsr0[$first])) {
    380             foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
    381                 if (0 === strpos($class, $prefix)) {
    382                     foreach ($dirs as $dir) {
    383                         if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
    384                             return $file;
    385                         }
    386                     }
    387                 }
    388             }
    389         }
    390 
    391         // PSR-0 fallback dirs
    392         foreach ($this->fallbackDirsPsr0 as $dir) {
    393             if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
    394                 return $file;
    395             }
    396         }
    397 
    398         // PSR-0 include paths.
    399         if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
    400             return $file;
    401         }
    402     }
    403 }
    404 
    405 /**
    406  * Scope isolated include.
    407  *
    408  * Prevents access to $this/self from included files.
    409  */
    410 function includeFile($file)
    411 {
    412     include $file;
    413 }