      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 1701 2013-12-18 22:33:25Z alphadevx $
     14:  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
     15:  * @copyright Copyright (c) 2013, 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/util/search/',
     96:                     $config->get('app.root').'alpha/tests/',
     97:                     $config->get('app.root').'controller/',
     98:                     $config->get('app.root').'model/',
     99:                     $config->get('app.root').'view/'
    100:                 );
    101:     }
    102:
    103:     /**
    104:      * Load the file based on the class name provided.  The file is assumed to be called "className.[inc|php]".
    105:      *
    106:      * @param string $className
    107:      * @since 1.2
    108:      */
    109:     public static function loadClass($className) {
    110:         global $config;
    111:
    112:         if(!isset(self::$scannedDirs))
    113:             self::initFolderList();
    114:
    115:         // lets try to guess the correct dir to save time, based on the name of the class
    116:         $skipDirs = array();
    117:
    118:         if(mb_strpos($className, 'Controller') !== false) {
    119:             if(self::loadFile($config->get('app.root').'alpha/controller/', $className)) {
    120:                 // it was found and inclued by loadFile() so we can return
    121:                 return;
    122:             }else{
    123:                 // it was NOT found by loadFile() in this dir, so we can skip a scan of this dir on the full scan
    124:                 array_push($skipDirs, $config->get('app.root').'alpha/controller/');
    125:             }
    126:
    127:             if(self::loadFile($config->get('app.root').'alpha/controller/front/', $className)) {
    128:                 return;
    129:             }else{
    130:                 array_push($skipDirs, $config->get('app.root').'alpha/controller/front/');
    131:             }
    132:         }
    133:
    134:         if(mb_strpos($className, 'Exception') !== false) {
    135:             if(self::loadFile($config->get('app.root').'alpha/exceptions/', $className)) {
    136:                 return;
    137:             }else{
    138:                 array_push($skipDirs, $config->get('app.root').'alpha/exceptions/');
    139:             }
    140:         }
    141:
    142:         if(mb_strpos($className, 'DAO') !== false) {
    143:             if(self::loadFile($config->get('app.root').'alpha/model/', $className)) {
    144:                 return;
    145:             }else{
    146:                 array_push($skipDirs, $config->get('app.root').'alpha/model/');
    147:             }
    148:         }
    149:
    150:         if(mb_strpos($className, 'Object') !== false) {
    151:             if(self::loadFile($config->get('app.root').'alpha/model/', $className)) {
    152:                 return;
    153:             }else{
    154:                 array_push($skipDirs, $config->get('app.root').'alpha/model/');
    155:             }
    156:         }
    157:
    158:         if(mb_strpos($className, 'View') !== false) {
    159:             if(self::loadFile($config->get('app.root').'alpha/view/', $className)) {
    160:                 return;
    161:             }else{
    162:                 array_push($skipDirs, $config->get('app.root').'alpha/view/');
    163:             }
    164:         }
    165:
    166:         if(mb_strpos($className, 'Utils') !== false) {
    167:             if(self::loadFile($config->get('app.root').'alpha/util/', $className)) {
    168:                 return;
    169:             }else{
    170:                 array_push($skipDirs, $config->get('app.root').'alpha/util/');
    171:             }
    172:         }
    173:
    174:         // do a full folder scan
    175:         foreach (self::$scannedDirs as $dir) {
    176:             if(!in_array($dir, $skipDirs)) {
    177:                 $loaded = self::loadFile($dir, $className);
    178:
    179:                 if($loaded) {
    180:                     if(isset(self::$logger))
    181:                         self::$logger->debug('Had to do a full scan to find the class ['.$className.'] in the dir ['.$dir.']');
    182:
    183:                     return;
    184:                 }
    185:             }
    186:         }
    187:
    188:         if(isset(self::$logger))
    189:             self::$logger->fatal('Unable to load the required class ['.$className.']');
    190:     }
    191:
    192:     /**
    193:      * Loads the lib file from the lib dir based on the filename provided.
    194:      *
    195:      * @param string $fileName
    196:      * @throws LibraryNotInstalledException
    197:      * @since 1.2
    198:      */
    199:     public static function loadLib($fileName) {
    200:         global $config;
    201:
    202:         // Libraries shipped with Alpha
    203:         $iterator = new RecursiveDirectoryIterator($config->get('app.root').'alpha/lib/');
    204:
    205:         foreach (new RecursiveIteratorIterator($iterator) as $name => $file) {
    206:             if($file->getBaseName() == $fileName) {
    207:                 if(isset(self::$logger))
    208:                     self::$logger->debug('Found the library file ['.$fileName.'] in the location ['.$name.']');
    209:
    210:                 require_once $name;
    211:                 return;
    212:             }
    213:         }
    214:
    215:         // custom libs
    216:         $iterator = new RecursiveDirectoryIterator($config->get('app.root').'lib/');
    217:
    218:         foreach (new RecursiveIteratorIterator($iterator) as $name => $file) {
    219:             if($file->getBaseName() == $fileName) {
    220:                 if(isset(self::$logger))
    221:                     self::$logger->debug('Found the library file ['.$fileName.'] in the location ['.$name.']');
    222:
    223:                 require_once $name;
    224:                 return;
    225:             }
    226:         }
    227:
    228:         throw new LibraryNotInstalledException('Cannot find the library file ['.$fileName.'] in the lib dir!');
    229:     }
    230:
    231:     /**
    232:      * Attempts to load the file for the class in the directory indicated.
    233:      *
    234:      * @param string $dir
    235:      * @param string $className
    236:      * @return bool
    237:      * @since 1.2
    238:      */
    239:     private static function loadFile($dir, $className) {
    240:         global $config;
    241:
    242:         // we're doing .inc first, as most classes in Alpha use this extension
    243:         $path = $dir.$className.'.inc';
    244:         if (file_exists($path) && is_readable($path)) {
    245:             if(isset(self::$logger))
    246:                 self::$logger->debug('Loaded the class ['.$className.'] in the location ['.$path.']');
    247:             include_once $path;
    248:             return true;
    249:         }
    250:
    251:         $path = $dir.$className.'.php';
    252:         if (file_exists($path) && is_readable($path)) {
    253:             if(isset(self::$logger))
    254:                 self::$logger->debug('Loaded the class ['.$className.'] in the location ['.$path.']');
    255:             include_once $path;
    256:             return true;
    257:         }
    258:
    259:         return false;
    260:     }
    261: }
    262:
    263: spl_autoload_register('AlphaAutoLoader::loadClass');
    264:
    265: ?>