|
1 <?php |
|
2 /** |
|
3 * Zend Framework |
|
4 * |
|
5 * LICENSE |
|
6 * |
|
7 * This source file is subject to the new BSD license that is bundled |
|
8 * with this package in the file LICENSE.txt. |
|
9 * It is also available through the world-wide-web at this URL: |
|
10 * http://framework.zend.com/license/new-bsd |
|
11 * If you did not receive a copy of the license and are unable to |
|
12 * obtain it through the world-wide-web, please send an email |
|
13 * to license@zend.com so we can send you a copy immediately. |
|
14 * |
|
15 * @category Zend |
|
16 * @package Zend_Application |
|
17 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
18 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
19 * @version $Id: Application.php 23163 2010-10-19 16:30:26Z matthew $ |
|
20 */ |
|
21 |
|
22 /** |
|
23 * @category Zend |
|
24 * @package Zend_Application |
|
25 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
26 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
27 */ |
|
28 class Zend_Application |
|
29 { |
|
30 /** |
|
31 * Autoloader to use |
|
32 * |
|
33 * @var Zend_Loader_Autoloader |
|
34 */ |
|
35 protected $_autoloader; |
|
36 |
|
37 /** |
|
38 * Bootstrap |
|
39 * |
|
40 * @var Zend_Application_Bootstrap_BootstrapAbstract |
|
41 */ |
|
42 protected $_bootstrap; |
|
43 |
|
44 /** |
|
45 * Application environment |
|
46 * |
|
47 * @var string |
|
48 */ |
|
49 protected $_environment; |
|
50 |
|
51 /** |
|
52 * Flattened (lowercase) option keys |
|
53 * |
|
54 * @var array |
|
55 */ |
|
56 protected $_optionKeys = array(); |
|
57 |
|
58 /** |
|
59 * Options for Zend_Application |
|
60 * |
|
61 * @var array |
|
62 */ |
|
63 protected $_options = array(); |
|
64 |
|
65 /** |
|
66 * Constructor |
|
67 * |
|
68 * Initialize application. Potentially initializes include_paths, PHP |
|
69 * settings, and bootstrap class. |
|
70 * |
|
71 * @param string $environment |
|
72 * @param string|array|Zend_Config $options String path to configuration file, or array/Zend_Config of configuration options |
|
73 * @throws Zend_Application_Exception When invalid options are provided |
|
74 * @return void |
|
75 */ |
|
76 public function __construct($environment, $options = null) |
|
77 { |
|
78 $this->_environment = (string) $environment; |
|
79 |
|
80 require_once 'Zend/Loader/Autoloader.php'; |
|
81 $this->_autoloader = Zend_Loader_Autoloader::getInstance(); |
|
82 |
|
83 if (null !== $options) { |
|
84 if (is_string($options)) { |
|
85 $options = $this->_loadConfig($options); |
|
86 } elseif ($options instanceof Zend_Config) { |
|
87 $options = $options->toArray(); |
|
88 } elseif (!is_array($options)) { |
|
89 throw new Zend_Application_Exception('Invalid options provided; must be location of config file, a config object, or an array'); |
|
90 } |
|
91 |
|
92 $this->setOptions($options); |
|
93 } |
|
94 } |
|
95 |
|
96 /** |
|
97 * Retrieve current environment |
|
98 * |
|
99 * @return string |
|
100 */ |
|
101 public function getEnvironment() |
|
102 { |
|
103 return $this->_environment; |
|
104 } |
|
105 |
|
106 /** |
|
107 * Retrieve autoloader instance |
|
108 * |
|
109 * @return Zend_Loader_Autoloader |
|
110 */ |
|
111 public function getAutoloader() |
|
112 { |
|
113 return $this->_autoloader; |
|
114 } |
|
115 |
|
116 /** |
|
117 * Set application options |
|
118 * |
|
119 * @param array $options |
|
120 * @throws Zend_Application_Exception When no bootstrap path is provided |
|
121 * @throws Zend_Application_Exception When invalid bootstrap information are provided |
|
122 * @return Zend_Application |
|
123 */ |
|
124 public function setOptions(array $options) |
|
125 { |
|
126 if (!empty($options['config'])) { |
|
127 if (is_array($options['config'])) { |
|
128 $_options = array(); |
|
129 foreach ($options['config'] as $tmp) { |
|
130 $_options = $this->mergeOptions($_options, $this->_loadConfig($tmp)); |
|
131 } |
|
132 $options = $this->mergeOptions($_options, $options); |
|
133 } else { |
|
134 $options = $this->mergeOptions($this->_loadConfig($options['config']), $options); |
|
135 } |
|
136 } |
|
137 |
|
138 $this->_options = $options; |
|
139 |
|
140 $options = array_change_key_case($options, CASE_LOWER); |
|
141 |
|
142 $this->_optionKeys = array_keys($options); |
|
143 |
|
144 if (!empty($options['phpsettings'])) { |
|
145 $this->setPhpSettings($options['phpsettings']); |
|
146 } |
|
147 |
|
148 if (!empty($options['includepaths'])) { |
|
149 $this->setIncludePaths($options['includepaths']); |
|
150 } |
|
151 |
|
152 if (!empty($options['autoloadernamespaces'])) { |
|
153 $this->setAutoloaderNamespaces($options['autoloadernamespaces']); |
|
154 } |
|
155 |
|
156 if (!empty($options['autoloaderzfpath'])) { |
|
157 $autoloader = $this->getAutoloader(); |
|
158 if (method_exists($autoloader, 'setZfPath')) { |
|
159 $zfPath = $options['autoloaderzfpath']; |
|
160 $zfVersion = !empty($options['autoloaderzfversion']) |
|
161 ? $options['autoloaderzfversion'] |
|
162 : 'latest'; |
|
163 $autoloader->setZfPath($zfPath, $zfVersion); |
|
164 } |
|
165 } |
|
166 |
|
167 if (!empty($options['bootstrap'])) { |
|
168 $bootstrap = $options['bootstrap']; |
|
169 |
|
170 if (is_string($bootstrap)) { |
|
171 $this->setBootstrap($bootstrap); |
|
172 } elseif (is_array($bootstrap)) { |
|
173 if (empty($bootstrap['path'])) { |
|
174 throw new Zend_Application_Exception('No bootstrap path provided'); |
|
175 } |
|
176 |
|
177 $path = $bootstrap['path']; |
|
178 $class = null; |
|
179 |
|
180 if (!empty($bootstrap['class'])) { |
|
181 $class = $bootstrap['class']; |
|
182 } |
|
183 |
|
184 $this->setBootstrap($path, $class); |
|
185 } else { |
|
186 throw new Zend_Application_Exception('Invalid bootstrap information provided'); |
|
187 } |
|
188 } |
|
189 |
|
190 return $this; |
|
191 } |
|
192 |
|
193 /** |
|
194 * Retrieve application options (for caching) |
|
195 * |
|
196 * @return array |
|
197 */ |
|
198 public function getOptions() |
|
199 { |
|
200 return $this->_options; |
|
201 } |
|
202 |
|
203 /** |
|
204 * Is an option present? |
|
205 * |
|
206 * @param string $key |
|
207 * @return bool |
|
208 */ |
|
209 public function hasOption($key) |
|
210 { |
|
211 return in_array(strtolower($key), $this->_optionKeys); |
|
212 } |
|
213 |
|
214 /** |
|
215 * Retrieve a single option |
|
216 * |
|
217 * @param string $key |
|
218 * @return mixed |
|
219 */ |
|
220 public function getOption($key) |
|
221 { |
|
222 if ($this->hasOption($key)) { |
|
223 $options = $this->getOptions(); |
|
224 $options = array_change_key_case($options, CASE_LOWER); |
|
225 return $options[strtolower($key)]; |
|
226 } |
|
227 return null; |
|
228 } |
|
229 |
|
230 /** |
|
231 * Merge options recursively |
|
232 * |
|
233 * @param array $array1 |
|
234 * @param mixed $array2 |
|
235 * @return array |
|
236 */ |
|
237 public function mergeOptions(array $array1, $array2 = null) |
|
238 { |
|
239 if (is_array($array2)) { |
|
240 foreach ($array2 as $key => $val) { |
|
241 if (is_array($array2[$key])) { |
|
242 $array1[$key] = (array_key_exists($key, $array1) && is_array($array1[$key])) |
|
243 ? $this->mergeOptions($array1[$key], $array2[$key]) |
|
244 : $array2[$key]; |
|
245 } else { |
|
246 $array1[$key] = $val; |
|
247 } |
|
248 } |
|
249 } |
|
250 return $array1; |
|
251 } |
|
252 |
|
253 /** |
|
254 * Set PHP configuration settings |
|
255 * |
|
256 * @param array $settings |
|
257 * @param string $prefix Key prefix to prepend to array values (used to map . separated INI values) |
|
258 * @return Zend_Application |
|
259 */ |
|
260 public function setPhpSettings(array $settings, $prefix = '') |
|
261 { |
|
262 foreach ($settings as $key => $value) { |
|
263 $key = empty($prefix) ? $key : $prefix . $key; |
|
264 if (is_scalar($value)) { |
|
265 ini_set($key, $value); |
|
266 } elseif (is_array($value)) { |
|
267 $this->setPhpSettings($value, $key . '.'); |
|
268 } |
|
269 } |
|
270 |
|
271 return $this; |
|
272 } |
|
273 |
|
274 /** |
|
275 * Set include path |
|
276 * |
|
277 * @param array $paths |
|
278 * @return Zend_Application |
|
279 */ |
|
280 public function setIncludePaths(array $paths) |
|
281 { |
|
282 $path = implode(PATH_SEPARATOR, $paths); |
|
283 set_include_path($path . PATH_SEPARATOR . get_include_path()); |
|
284 return $this; |
|
285 } |
|
286 |
|
287 /** |
|
288 * Set autoloader namespaces |
|
289 * |
|
290 * @param array $namespaces |
|
291 * @return Zend_Application |
|
292 */ |
|
293 public function setAutoloaderNamespaces(array $namespaces) |
|
294 { |
|
295 $autoloader = $this->getAutoloader(); |
|
296 |
|
297 foreach ($namespaces as $namespace) { |
|
298 $autoloader->registerNamespace($namespace); |
|
299 } |
|
300 |
|
301 return $this; |
|
302 } |
|
303 |
|
304 /** |
|
305 * Set bootstrap path/class |
|
306 * |
|
307 * @param string $path |
|
308 * @param string $class |
|
309 * @return Zend_Application |
|
310 */ |
|
311 public function setBootstrap($path, $class = null) |
|
312 { |
|
313 // setOptions() can potentially send a null value; specify default |
|
314 // here |
|
315 if (null === $class) { |
|
316 $class = 'Bootstrap'; |
|
317 } |
|
318 |
|
319 if (!class_exists($class, false)) { |
|
320 require_once $path; |
|
321 if (!class_exists($class, false)) { |
|
322 throw new Zend_Application_Exception('Bootstrap class not found'); |
|
323 } |
|
324 } |
|
325 $this->_bootstrap = new $class($this); |
|
326 |
|
327 if (!$this->_bootstrap instanceof Zend_Application_Bootstrap_Bootstrapper) { |
|
328 throw new Zend_Application_Exception('Bootstrap class does not implement Zend_Application_Bootstrap_Bootstrapper'); |
|
329 } |
|
330 |
|
331 return $this; |
|
332 } |
|
333 |
|
334 /** |
|
335 * Get bootstrap object |
|
336 * |
|
337 * @return Zend_Application_Bootstrap_BootstrapAbstract |
|
338 */ |
|
339 public function getBootstrap() |
|
340 { |
|
341 if (null === $this->_bootstrap) { |
|
342 $this->_bootstrap = new Zend_Application_Bootstrap_Bootstrap($this); |
|
343 } |
|
344 return $this->_bootstrap; |
|
345 } |
|
346 |
|
347 /** |
|
348 * Bootstrap application |
|
349 * |
|
350 * @param null|string|array $resource |
|
351 * @return Zend_Application |
|
352 */ |
|
353 public function bootstrap($resource = null) |
|
354 { |
|
355 $this->getBootstrap()->bootstrap($resource); |
|
356 return $this; |
|
357 } |
|
358 |
|
359 /** |
|
360 * Run the application |
|
361 * |
|
362 * @return void |
|
363 */ |
|
364 public function run() |
|
365 { |
|
366 $this->getBootstrap()->run(); |
|
367 } |
|
368 |
|
369 /** |
|
370 * Load configuration file of options |
|
371 * |
|
372 * @param string $file |
|
373 * @throws Zend_Application_Exception When invalid configuration file is provided |
|
374 * @return array |
|
375 */ |
|
376 protected function _loadConfig($file) |
|
377 { |
|
378 $environment = $this->getEnvironment(); |
|
379 $suffix = strtolower(pathinfo($file, PATHINFO_EXTENSION)); |
|
380 |
|
381 switch ($suffix) { |
|
382 case 'ini': |
|
383 $config = new Zend_Config_Ini($file, $environment); |
|
384 break; |
|
385 |
|
386 case 'xml': |
|
387 $config = new Zend_Config_Xml($file, $environment); |
|
388 break; |
|
389 |
|
390 case 'json': |
|
391 $config = new Zend_Config_Json($file, $environment); |
|
392 break; |
|
393 |
|
394 case 'yaml': |
|
395 $config = new Zend_Config_Yaml($file, $environment); |
|
396 break; |
|
397 |
|
398 case 'php': |
|
399 case 'inc': |
|
400 $config = include $file; |
|
401 if (!is_array($config)) { |
|
402 throw new Zend_Application_Exception('Invalid configuration file provided; PHP file does not return array value'); |
|
403 } |
|
404 return $config; |
|
405 break; |
|
406 |
|
407 default: |
|
408 throw new Zend_Application_Exception('Invalid configuration file provided; unknown config type'); |
|
409 } |
|
410 |
|
411 return $config->toArray(); |
|
412 } |
|
413 } |