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: ?>