Advertisement
Guest User

Untitled

a guest
May 8th, 2017
565
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 12.52 KB | None | 0 0
  1. <?php
  2.  
  3.  
  4. /**
  5.  *
  6.  * @package exTSend
  7.  * @version SVN: $Id: NamespacePath.php 8 2009-12-14 20:55:14Z gabriel.schuster $
  8.  *
  9.  * @author Gabriel Schuster <sourcecode@extsend.com>
  10.  * @copyright Copyright 2009, actra.development, Korntal-Muenchingen
  11.  *
  12.  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  13.  *                               NEW BSD LICENSE                              
  14.  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  15.  *
  16.  *
  17.  * exTSend.com - Copyright (c) 2009, actra.development
  18.  * All rights reserved.
  19.  *
  20.  * Redistribution and use in source and binary forms, with or without
  21.  * modification, are permitted provided that the following conditions are met:
  22.  *    - Redistributions of source code must retain the above copyright notice,
  23.  *      this list of conditions and the following disclaimer.
  24.  *    - Redistributions in binary form must reproduce the above copyright
  25.  *      notice, this list of conditions and the following disclaimer in the
  26.  *      documentation and / or other materials provided with the
  27.  *      distribution.
  28.  *    - Neither the name of actra.development nor the names of its
  29.  *      contributors may be used to endorse or promote products derived from
  30.  *      this software without specific prior written permission.
  31.  *
  32.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  33.  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  34.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  35.  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  36.  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  37.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  38.  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  39.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  40.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  41.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  42.  * POSSIBILITY OF SUCH DAMAGE.
  43.  *
  44.  */
  45.  
  46.  
  47. /**
  48.  * An autoloader that supports specific paths for given class prefixes (namespaces)
  49.  * The longest match wins:
  50.  *     Given autoloader configuration:
  51.  *         MyApp_     => /path/to/myapp
  52.  *         MyApp_Abc_ => /path/to/other/abc
  53.  *     Requested class:
  54.  *         MyApp_Abc_Test
  55.  *     Loaded file:
  56.  *         /path/to/other/abc/Test.php
  57.  *
  58.  * @package exTSend_Loader_Autoloader_NamespacePath
  59.  * @author Gabriel Schuster <sourcecode@extsend.com>
  60.  * @copyright Copyright 2009, actra.development, Korntal-Muenchingen
  61.  */
  62. class exTSend_Loader_Autoloader_NamespacePath implements Zend_Loader_Autoloader_Interface {
  63.       /**
  64.        * @name $_instance
  65.        * @staticvar exTSend_Loader_Autoloader_NamespacePath
  66.        * @access protected
  67.        */
  68.       protected static $_instance = NULL;
  69.      
  70.      
  71.       /**
  72.        * @name $_namespaces
  73.        * @var array
  74.        * @access protected
  75.        */
  76.       protected $_namespaces = array();
  77.      
  78.      
  79.       /**
  80.        * Constructor
  81.        *
  82.        * @author Gabriel Schuster <sourcecode@extsend.com>
  83.        *
  84.        * @access public
  85.        * @return void
  86.        */
  87.       protected function __construct() {
  88.       }
  89.      
  90.      
  91.       /**
  92.        * Singleton instantiator
  93.        *
  94.        * @author Gabriel Schuster <sourcecode@extsend.com>
  95.        *
  96.        * @access
  97.        * @return unknown_type
  98.        */
  99.       public static function getInstance() {
  100.             if(is_null(self::$_instance) || TRUE !== (self::$_instance instanceof exTSend_Loader_Autoloader_NamespacePath)) {
  101.                   self::$_instance = new exTSend_Loader_Autoloader_NamespacePath();
  102.             }
  103.            
  104.             return self::$_instance;
  105.       }
  106.      
  107.      
  108.       /**
  109.        * Add a namespace (does not overwrite previously set namespace path)
  110.        *
  111.        * @author Gabriel Schuster <sourcecode@extsend.com>
  112.        *
  113.        * @access public
  114.        * @param string $namespace
  115.        * @param string $path
  116.        * @return exTSend_Loader_Autoloader_NamespacePath
  117.        */
  118.       public function addNamespace($namespace, $path) {
  119.             $namespace = trim($namespace, '_');
  120.             $segments  = preg_split('/_/', $namespace, NULL, PREG_SPLIT_NO_EMPTY);
  121.            
  122.             if(count($segments)) {
  123.                   $reference =& $this->_namespaces;
  124.                   foreach($segments as $index => $segment) {
  125.                         if(!array_key_exists($segment, $reference)) {
  126.                               $reference[$segment] = array('path' => NULL, 'sub' => array());
  127.                         }
  128.                        
  129.                         if($index === count($segments) - 1 && is_null($reference[$segment]['path'])) {
  130.                               Zend_Loader_Autoloader::getInstance()->unshiftAutoloader($this, implode('_', $segments).'_');
  131.                              
  132.                               $reference[$segment]['path'] = preg_replace(
  133.                                     '#[/\\\]+#',
  134.                                     DIRECTORY_SEPARATOR,
  135.                                     preg_replace(
  136.                                           '#^[/\\\]+#',
  137.                                           DIRECTORY_SEPARATOR,
  138.                                           preg_replace(
  139.                                                 '#[/\\\]+$#',
  140.                                                 '',
  141.                                                 (string)$path
  142.                                           )
  143.                                     )
  144.                               ).DIRECTORY_SEPARATOR;
  145.                         }
  146.                        
  147.                         $reference =& $reference[$segment]['sub'];
  148.                   }
  149.             }
  150.            
  151.             return $this;
  152.       }
  153.      
  154.      
  155.       /**
  156.        * Set a namespace (overwrites previously set namespace path)
  157.        *
  158.        * @author Gabriel Schuster <sourcecode@extsend.com>
  159.        *
  160.        * @access public
  161.        * @param string $namespace
  162.        * @param string $path
  163.        * @return exTSend_Loader_Autoloader_NamespacePath
  164.        */
  165.       public function setNamespace($namespace, $path) {
  166.             $namespace = trim($namespace, '_');
  167.             $segments  = preg_split('/_/', $namespace, NULL, PREG_SPLIT_NO_EMPTY);
  168.            
  169.             if(count($segments)) {
  170.                   $reference =& $this->_namespaces;
  171.                   foreach($segments as $index => $segment) {
  172.                         if(!array_key_exists($segment, $reference)) {
  173.                               $reference[$segment] = array('path' => NULL, 'sub' => array());
  174.                         }
  175.                        
  176.                         if($index === count($segments) - 1) {
  177.                               if(is_null($reference[$segment]['path'])) {
  178.                                     Zend_Loader_Autoloader::getInstance()->unshiftAutoloader($this, implode('_', $segments).'_');
  179.                               }
  180.                              
  181.                               $reference[$segment]['path'] = preg_replace(
  182.                                     '#[/\\\]+#',
  183.                                     DIRECTORY_SEPARATOR,
  184.                                     preg_replace(
  185.                                           '#^[/\\\]+#',
  186.                                           DIRECTORY_SEPARATOR,
  187.                                           preg_replace(
  188.                                                 '#[/\\\]+$#',
  189.                                                 '',
  190.                                                 (string)$path
  191.                                           )
  192.                                     )
  193.                               ).DIRECTORY_SEPARATOR;
  194.                         }
  195.                        
  196.                         $reference =& $reference[$segment]['sub'];
  197.                   }
  198.             }
  199.            
  200.             return $this;
  201.       }
  202.      
  203.      
  204.       /**
  205.        * Remove a namespace
  206.        *
  207.        * @author Gabriel Schuster <sourcecode@extsend.com>
  208.        *
  209.        * @access public
  210.        * @param string $namespace
  211.        * @param boolean $withChildren
  212.        * @return exTSend_Loader_Autoloader_NamespacePath
  213.        */
  214.       public function removeNamespace($namespace, $withChildren = FALSE) {
  215.             $namespace = trim($namespace, '_');
  216.             $segments  = preg_split('/_/', $namespace, NULL, PREG_SPLIT_NO_EMPTY);
  217.            
  218.             if(count($segments)) {
  219.                   $reference =& $this->_namespaces;
  220.                   foreach($segments as $index => $segment) {
  221.                         if(!array_key_exists($segment, $reference)) {
  222.                               break;
  223.                         }
  224.                        
  225.                         if($index === count($segments) - 1) {
  226.                               if(TRUE === (bool)$withChildren) {
  227.                                     unset($reference[$segment]);
  228.                               }
  229.                               else {
  230.                                     $reference[$segment]['path'] = NULL;
  231.                               }
  232.                         }
  233.                        
  234.                         if(!array_key_exists($segment, $reference)) {
  235.                               break;
  236.                         }
  237.                        
  238.                         $reference =& $reference[$segment]['sub'];
  239.                   }
  240.             }
  241.            
  242.             return $this;
  243.       }
  244.      
  245.      
  246.       /**
  247.        * Autoload a class
  248.        *
  249.        * @author Gabriel Schuster <sourcecode@extsend.com>
  250.        *
  251.        * @access
  252.        * @param string $class
  253.        * @return NULL|boolean|string
  254.        */
  255.       public function autoload($class) {
  256.             if(class_exists($class, FALSE) || interface_exists($class, FALSE)) {
  257.                   return;
  258.             }
  259.            
  260.             $class    = trim($class, '_');
  261.             $segments = preg_split('/_/', $class, NULL, PREG_SPLIT_NO_EMPTY);
  262.            
  263.             if(count($segments) && array_key_exists($segments[0], $this->_namespaces)) {
  264.                   $currentNamespace = $segments[0].'_';
  265.                   $lastNamespace    = !is_null($this->_namespaces[$segments[0]]['path']) ? $segments[0].'_' : NULL;
  266.                   $lastPath         = !is_null($this->_namespaces[$segments[0]]['path']) ? $this->_namespaces[$segments[0]]['path'] : NULL;
  267.                  
  268.                   $reference =& $this->_namespaces[$segments[0]]['sub'];
  269.                   foreach(array_slice($segments, 1) as $index => $segment) {
  270.                         if($index === count($segments) - 2) {
  271.                               break;
  272.                         }
  273.                        
  274.                         $currentNamespace .= $segment.'_';
  275.                        
  276.                         if(array_key_exists($segment, $reference)) {
  277.                               if(!is_null($reference[$segment]['path'])) {
  278.                                     $lastNamespace = $currentNamespace;
  279.                                     $lastPath      = $reference[$segment]['path'];
  280.                               }
  281.                         }
  282.                         else {
  283.                               break;
  284.                         }
  285.                        
  286.                         $reference =& $reference[$segment]['sub'];
  287.                   }
  288.                  
  289.                   if(is_null($lastNamespace) || is_null($lastPath)) {
  290.                         // No matching namespace with a configured path found
  291.                         return FALSE;
  292.                   }
  293.                  
  294.                   $filename = str_replace('_', DIRECTORY_SEPARATOR, substr(implode('_', $segments), strlen($lastNamespace))).'.php';
  295.                   if(preg_match('/[^a-z0-9\\/\\\\_.:-]/i', $filename)) {
  296.                         throw new exTSend_Loader_Autoloader_NamespacePath_Exception(
  297.                               'Illegal character in filename detected.',
  298.                               exTSend_Loader_Autoloader_NamespacePath_Exception::EXCEPTION_ILLEGAL_CHARACTER_IN_FILENAME
  299.                         );
  300.                   }
  301.                  
  302.                   if(!file_exists($lastPath.$filename)) {
  303.                         return FALSE;
  304.                   }
  305.                  
  306.                   return include_once $lastPath.$filename;
  307.             }
  308.            
  309.             return FALSE;
  310.       }
  311. }
  312.  
  313.  
  314. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement