      1: <?php
      2:
      3: require_once $config->get('app.root').'alpha/util/AlphaErrorHandlers.inc';
      4:
      5: /**
      6:  *
      7:  * A class for auto-loading classes in the Alpha Framework, as well as
      8:  * custom classses and files in 3rd party libraries.
      9:  *
     10:  * @package alpha::util
     11:  * @since 1.2
     12:  * @author John Collins <dev@alphaframework.org>
     13:  * @version $Id: AlphaAutoLoader.inc 1548 2012-07-29 17:07:07Z alphadevx $
     14:  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
     15:  * @copyright Copyright (c) 2012, John Collins (founder of Alpha Framework).
     16:  * All rights reserved.
     17:  *
     18:  * <pre>
     19:  * Redistribution and use in source and binary forms, with or
     20:  * without modification, are permitted provided that the
     21:  * following conditions are met:
     22:  *
     23:  * * Redistributions of source code must retain the above
     24:  *   copyright notice, this list of conditions and the
     25:  *   following disclaimer.
     26:  * * Redistributions in binary form must reproduce the above
     27:  *   copyright notice, this list of conditions and the
     28:  *   following disclaimer in the documentation and/or other
     29:  *   materials provided with the distribution.
     30:  * * Neither the name of the Alpha Framework nor the names
     31:  *   of its contributors may be used to endorse or promote
     32:  *   products derived from this software without specific
     33:  *   prior written permission.
     34:  *
     35:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
     36:  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
     37:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     38:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     39:  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     40:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     41:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     42:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     43:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     44:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     45:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     46:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     47:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     48:  * </pre>
     49:  *
     50:  */
     51: class AlphaAutoLoader {
     52:     /**
     53:      * Hash array of the directories to scan
     54:      *
     55:      * @var array
     56:      */
     57:     private static $scannedDirs;
     58:
     59:     /**
     60:      * Logger
     61:      *
     62:      * @var Logger
     63:      */
     64:     private static $logger;
     65:
     66:     /**
     67:      * Sets up the list of directories to scan.
     68:      *
     69:      * @since 1.2
     70:      */
     71:     private static function initFolderList() {
     72:         global $config;
     73:
     74:         if(!isset(self::$logger) && class_exists('Logger'))
     75:             self::$logger = new Logger('AlphaAutoLoader');
     76:
     77:         self::$scannedDirs = array(
     78:                     $config->get('app.root').'alpha/controller/',
     79:                     $config->get('app.root').'alpha/controller/front/',
     80:                     $config->get('app.root').'alpha/exceptions/',
     81:                     $config->get('app.root').'alpha/model/',
     82:                     $config->get('app.root').'alpha/model/types/',
     83:                     $config->get('app.root').'alpha/view/',
     84:                     $config->get('app.root').'alpha/view/widgets/',
     85:                     $config->get('app.root').'alpha/view/renderers/',
     86:                     $config->get('app.root').'alpha/util/',
     87:                     $config->get('app.root').'alpha/util/cache/',
     88:                     $config->get('app.root').'alpha/util/codehighlight/',
     89:                     $config->get('app.root').'alpha/util/convertors/',
     90:                     $config->get('app.root').'alpha/util/feeds/',
     91:                     $config->get('app.root').'alpha/util/graphs/',
     92:                     $config->get('app.root').'alpha/util/helpers/',
     93:                     $config->get('app.root').'alpha/util/metrics/',
     94:                     $config->get('app.root').'alpha/util/filters/',
     95:                     $config->get('app.root').'alpha/tests/',
     96:                     $config->get('app.root').'controller/',
     97:                     $config->get('app.root').'model/',
     98:                     $config->get('app.root').'view/'
     99:                 );
    100:     }
    101:
    102:     /**
    103:      * Load the file based on the class name provided.  The file is assumed to be called "className.[inc|php]".
    104:      *
    105:      * @param string $className
    106:      * @since 1.2
    107:      */
    108:     public static function loadClass($className) {
    109:         global $config;
    110:
    111:         if(!isset(self::$scannedDirs))
    112:             self::initFolderList();
    113:
    114:         // lets try to guess the correct dir to save time, based on the name of the class
    115:         $skipDirs = array();
    116:
    117:         if(strpos($className, 'Controller') !== false) {
    118:             if(self::loadFile($config->get('app.root').'alpha/controller/', $className)) {
    119:                 // it was found and inclued by loadFile() so we can return
    120:                 return;
    121:             }else{
    122:                 // it was NOT found by loadFile() in this dir, so we can skip a scan of this dir on the full scan
    123:                 array_push($skipDirs, $config->get('app.root').'alpha/controller/');
    124:             }
    125:
    126:             if(self::loadFile($config->get('app.root').'alpha/controller/front/', $className)) {
    127:                 return;
    128:             }else{
    129:                 array_push($skipDirs, $config->get('app.root').'alpha/controller/front/');
    130:             }
    131:         }
    132:
    133:         if(strpos($className, 'Exception') !== false) {
    134:             if(self::loadFile($config->get('app.root').'alpha/exceptions/', $className)) {
    135:                 return;
    136:             }else{
    137:                 array_push($skipDirs, $config->get('app.root').'alpha/exceptions/');
    138:             }
    139:         }
    140:
    141:         if(strpos($className, 'DAO') !== false) {
    142:             if(self::loadFile($config->get('app.root').'alpha/model/', $className)) {
    143:                 return;
    144:             }else{
    145:                 array_push($skipDirs, $config->get('app.root').'alpha/model/');
    146:             }
    147:         }
    148:
    149:         if(strpos($className, 'Object') !== false) {
    150:             if(self::loadFile($config->get('app.root').'alpha/model/', $className)) {
    151:                 return;
    152:             }else{
    153:                 array_push($skipDirs, $config->get('app.root').'alpha/model/');
    154:             }
    155:         }
    156:
    157:         if(strpos($className, 'View') !== false) {
    158:             if(self::loadFile($config->get('app.root').'alpha/view/', $className)) {
    159:                 return;
    160:             }else{
    161:                 array_push($skipDirs, $config->get('app.root').'alpha/view/');
    162:             }
    163:         }
    164:
    165:         if(strpos($className, 'Utils') !== false) {
    166:             if(self::loadFile($config->get('app.root').'alpha/util/', $className)) {
    167:                 return;
    168:             }else{
    169:                 array_push($skipDirs, $config->get('app.root').'alpha/util/');
    170:             }
    171:         }
    172:
    173:         // do a full folder scan
    174:         foreach (self::$scannedDirs as $dir) {
    175:             if(!in_array($dir, $skipDirs)) {
    176:                 $loaded = self::loadFile($dir, $className);
    177:
    178:                 if($loaded) {
    179:                     if(isset(self::$logger))
    180:                         self::$logger->debug('Had to do a full scan to find the class ['.$className.'] in the dir ['.$dir.']');
    181:
    182:                     return;
    183:                 }
    184:             }
    185:         }
    186:
    187:         if(isset(self::$logger))
    188:             self::$logger->fatal('Unable to load the required class ['.$className.']');
    189:     }
    190:
    191:     /**
    192:      * Loads the lib file from the lib dir based on the filename provided.
    193:      *
    194:      * @param string $fileName
    195:      * @throws LibraryNotInstalledException
    196:      * @since 1.2
    197:      */
    198:     public static function loadLib($fileName) {
    199:         global $config;
    200:
    201:         // Libraries shipped with Alpha
    202:         $iterator = new RecursiveDirectoryIterator($config->get('app.root').'alpha/lib/');
    203:
    204:         foreach (new RecursiveIteratorIterator($iterator) as $name => $file) {
    205:             if($file->getBaseName() == $fileName) {
    206:                 if(isset(self::$logger))
    207:                     self::$logger->debug('Found the library file ['.$fileName.'] in the location ['.$name.']');
    208:
    209:                 require_once $name;
    210:                 return;
    211:             }
    212:         }
    213:
    214:         // custom libs
    215:         $iterator = new RecursiveDirectoryIterator($config->get('app.root').'lib/');
    216:
    217:         foreach (new RecursiveIteratorIterator($iterator) as $name => $file) {
    218:             if($file->getBaseName() == $fileName) {
    219:                 if(isset(self::$logger))
    220:                     self::$logger->debug('Found the library file ['.$fileName.'] in the location ['.$name.']');
    221:
    222:                 require_once $name;
    223:                 return;
    224:             }
    225:         }
    226:
    227:         throw new LibraryNotInstalledException('Cannot find the library file ['.$fileName.'] in the lib dir!');
    228:     }
    229:
    230:     /**
    231:      * Attempts to load the file for the class in the directory indicated.
    232:      *
    233:      * @param string $dir
    234:      * @param string $className
    235:      * @return bool
    236:      * @since 1.2
    237:      */
    238:     private static function loadFile($dir, $className) {
    239:         global $config;
    240:
    241:         // we're doing .inc first, as most classes in Alpha use this extension
    242:         $path = $dir.$className.'.inc';
    243:         if (file_exists($path) && is_readable($path)) {
    244:             if(isset(self::$logger))
    245:                 self::$logger->debug('Loaded the class ['.$className.'] in the location ['.$path.']');
    246:             include_once $path;
    247:             return true;
    248:         }
    249:
    250:         $path = $dir.$className.'.php';
    251:         if (file_exists($path) && is_readable($path)) {
    252:             if(isset(self::$logger))
    253:                 self::$logger->debug('Loaded the class ['.$className.'] in the location ['.$path.']');
    254:             include_once $path;
    255:             return true;
    256:         }
    257:
    258:         return false;
    259:     }
    260: }
    261:
    262: spl_autoload_register('AlphaAutoLoader::loadClass');
    263:
    264: ?>
    265: