      1: <?php
      2:
      3: /**
      4:  *
      5:  * A singleton config class
      6:  *
      7:  * @package alpha::util
      8:  * @since 1.0
      9:  * @author John Collins <dev@alphaframework.org>
     10:  * @version $Id: AlphaConfig.inc 1583 2012-11-05 23:05:20Z alphadevx $
     11:  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
     12:  * @copyright Copyright (c) 2012, John Collins (founder of Alpha Framework).
     13:  * All rights reserved.
     14:  *
     15:  * <pre>
     16:  * Redistribution and use in source and binary forms, with or
     17:  * without modification, are permitted provided that the
     18:  * following conditions are met:
     19:  *
     20:  * * Redistributions of source code must retain the above
     21:  *   copyright notice, this list of conditions and the
     22:  *   following disclaimer.
     23:  * * Redistributions in binary form must reproduce the above
     24:  *   copyright notice, this list of conditions and the
     25:  *   following disclaimer in the documentation and/or other
     26:  *   materials provided with the distribution.
     27:  * * Neither the name of the Alpha Framework nor the names
     28:  *   of its contributors may be used to endorse or promote
     29:  *   products derived from this software without specific
     30:  *   prior written permission.
     31:  *
     32:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
     33:  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
     34:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     35:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     36:  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     37:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     38:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     39:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     40:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     41:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     42:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     43:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     44:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     45:  * </pre>
     46:  *
     47:  */
     48: class AlphaConfig {
     49:     /**
     50:      * Array to store the config variables
     51:      *
     52:      * @var array
     53:      * @since 1.0
     54:      */
     55:     private $configVars = array();
     56:
     57:     /**
     58:      * The config object singleton
     59:      *
     60:      * @var AlphaConfig
     61:      * @since 1.0
     62:      */
     63:     private static $instance;
     64:
     65:     /**
     66:      * Private constructor means the class cannot be instantiated from elsewhere
     67:      *
     68:      * @since 1.0
     69:      */
     70:     private function __construct () {}
     71:
     72:     /**
     73:      * Get the config object instance
     74:      *
     75:      * @return AlphaConfig
     76:      * @since 1.0
     77:      */
     78:     public static function getInstance() {
     79:         if (!isset(self::$instance)) {
     80:             self::$instance = new AlphaConfig();
     81:             self::$instance->setRootPath();
     82:             self::$instance->setIncludePath();
     83:
     84:             // check to see if a child class with callbacks has been implemented
     85:             if(file_exists(self::$instance->get('rootPath').'config/ConfigCallbacks.inc')) {
     86:                 require_once self::$instance->get('rootPath').'config/ConfigCallbacks.inc';
     87:
     88:                 self::$instance = new ConfigCallbacks();
     89:                 self::$instance->setRootPath();
     90:                 self::$instance->setIncludePath();
     91:             }
     92:
     93:             // populate the config from the ini file
     94:             self::$instance->loadConfig();
     95:         }
     96:         return self::$instance;
     97:     }
     98:
     99:     /**
    100:      * Get config value
    101:      *
    102:      * @param $key string
    103:      * @return string
    104:      * @throws IllegalArguementException
    105:      * @since 1.0
    106:      */
    107:     public function get($key) {
    108:         if(array_key_exists($key, $this->configVars))
    109:             return $this->configVars[$key];
    110:         else
    111:             throw new IllegalArguementException('The config property ['.$key.'] is not set in the .ini config file');
    112:     }
    113:
    114:     /**
    115:      * Set config value
    116:      *
    117:      * @param $key string
    118:      * @param $val string
    119:      * @since 1.0
    120:      */
    121:     public function set($key, $val) {
    122:         /*
    123:          * If you need to alter a config option after it has been set in the .ini
    124:          * files, you can override this class and implement this callback method
    125:          */
    126:         if(method_exists($this, 'before_set_callback'))
    127:             $val = $this->before_set_callback($key, $val, $this->configVars);
    128:
    129:         $this->configVars[$key] = $val;
    130:     }
    131:
    132:     /**
    133:      * Sets the root directory of the application
    134:      *
    135:      * @since 1.0
    136:      */
    137:     private function setRootPath() {
    138:         $currentScript = __FILE__;
    139:
    140:         // reverse the slashes in case we are running on Windows
    141:         $currentScript = str_replace('\\', '/', $currentScript);
    142:
    143:         $rootPath = '';
    144:
    145:         if(strrpos($currentScript, 'alpha/view/widgets/') !== false) {
    146:             // set path for widgets
    147:             $rootPath = substr($currentScript, 0, strrpos($currentScript, 'alpha/view/widgets/'));
    148:         }elseif(strrpos($currentScript, 'alpha/util/') !== false) {
    149:             // set the path for util scripts
    150:             $rootPath = substr($currentScript, 0, strrpos($currentScript, 'alpha/util/'));
    151:         }elseif(strrpos($currentScript, 'alpha/') !== false) {
    152:             // check to see if it is a controller under /alpha
    153:             $rootPath = substr($currentScript, 0, strrpos($currentScript, 'alpha/'));
    154:         }elseif(!strrpos($currentScript, 'alpha/') && strrpos($currentScript, 'controller/') != false) {
    155:             // handle custom controllers at a lower level
    156:             $rootPath = substr($currentScript, 0, strrpos($currentScript, 'controller/'));
    157:         }elseif(strrpos($currentScript, 'config/css/') !== false) {
    158:             // set path for CSS files
    159:             $rootPath = substr($currentScript, 0, strrpos($currentScript, 'config/css/'));
    160:         }elseif(strrpos($currentScript, 'AlphaCronManager') !== false) {
    161:             // set the path for the AlphaCronManager being run from CLI
    162:             $rootPath = '../../';
    163:         }else{
    164:             $rootPath = '';
    165:         }
    166:
    167:         $this->set('rootPath', $rootPath);
    168:     }
    169:
    170:     /**
    171:      * Attempt to set the include_path to include the alpha/lib directory
    172:      *
    173:      * @since 1.0
    174:      */
    175:     private function setIncludePath() {
    176:         $config = AlphaConfig::getInstance();
    177:         $rootPath = $config->get('rootPath');
    178:
    179:         ini_set('include_path', ini_get('include_path').PATH_SEPARATOR.$rootPath.'alpha/lib/');
    180:     }
    181:
    182:     /**
    183:      * Loads the config from the relevent .ini file, dependant upon the current
    184:      * environment (hostname).  Note that this method will die() on failure!
    185:      *
    186:      * @since 1.0
    187:      */
    188:     private function loadConfig() {
    189:         $rootPath = $this->get('rootPath');
    190:
    191:         // first we need to see if we are in dev, pro or test environment
    192:         if(isset($_SERVER['SERVER_NAME'])) {
    193:             $server = $_SERVER['SERVER_NAME'];
    194:         }elseif(isset($_ENV['HOSTNAME'])){
    195:             // we may be running in CLI mode
    196:             $server = $_ENV['HOSTNAME'];
    197:          }elseif(php_uname('n') != ''){
    198:             // CLI on Linux or Windows should have this
    199:             $server = php_uname('n');
    200:         }else{
    201:             die('Unable to determine the server name');
    202:         }
    203:
    204:         // Load the servers to see which environment the current server is set as
    205:         $serverIni = $rootPath.'config/servers.ini';
    206:
    207:         if(file_exists($serverIni)) {
    208:             $envs = parse_ini_file($serverIni);
    209:             $environment = '';
    210:
    211:             foreach ($envs as $env => $serversList) {
    212:                 $servers = explode(',', $serversList);
    213:
    214:                 if(in_array($server, $servers))
    215:                     $environment = $env;
    216:             }
    217:
    218:             if($environment == '')
    219:                 die('No environment configured for the server '.$server);
    220:         }else{
    221:             die('Failed to load the config file ['.$serverIni.']');
    222:         }
    223:
    224:         if(substr($environment, -3) == 'CLI') // CLI mode
    225:             $envIni = $rootPath.'config/'.substr($environment, 0, 3).'.ini';
    226:         else
    227:             $envIni = $rootPath.'config/'.$environment.'.ini';
    228:
    229:         if(!file_exists($envIni)) {
    230:             die('Failed to load the config file ['.$envIni.']');
    231:         }
    232:
    233:         $configArray = parse_ini_file($envIni);
    234:
    235:         foreach(array_keys($configArray) as $key) {
    236:             $this->set($key, $configArray[$key]);
    237:         }
    238:     }
    239: }
    240:
    241: ?>