[RELEASE] backport fixes from 1.10 release branch
[zend/radio.git] / bin / zf.php
blob90a0c611e07fc0c46aa1200e6d503fa0ad1bb7f0
1 <?php
2 /**
3 * Zend Framework
5 * LICENSE
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.
15 * @category Zend
16 * @package Zend_Tool
17 * @subpackage Framework
18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
19 * @license http://framework.zend.com/license/new-bsd New BSD License
20 * @version $Id$
23 /**
24 * ZF
26 * @category Zend
27 * @package Zend_Tool
28 * @subpackage Framework
29 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
30 * @license http://framework.zend.com/license/new-bsd New BSD License
32 class ZF
35 /**
36 * @var bool
38 protected $_clientLoaded = false;
40 /**
41 * @var string
43 protected $_mode = 'runTool';
45 /**
46 * @var array of messages
48 protected $_messages = array();
50 /**
51 * @var string
53 protected $_homeDirectory = null;
55 /**
56 * @var string
58 protected $_storageDirectory = null;
60 /**
61 * @var string
63 protected $_configFile = null;
65 /**
66 * main()
68 * @return void
70 public static function main()
72 $zf = new self();
73 $zf->bootstrap();
74 $zf->run();
77 /**
78 * bootstrap()
80 * @return ZF
82 public function bootstrap()
84 // detect settings
85 $this->_mode = $this->_detectMode();
86 $this->_homeDirectory = $this->_detectHomeDirectory();
87 $this->_storageDirectory = $this->_detectStorageDirectory();
88 $this->_configFile = $this->_detectConfigFile();
90 // setup
91 $this->_setupPHPRuntime();
92 $this->_setupToolRuntime();
95 /**
96 * run()
98 * @return ZF
100 public function run()
102 switch ($this->_mode) {
103 case 'runError':
104 $this->_runError();
105 $this->_runInfo();
106 break;
107 case 'runSetup':
108 if ($this->_runSetup() === false) {
109 $this->_runInfo();
111 break;
112 case 'runInfo':
113 $this->_runInfo();
114 break;
115 case 'runTool':
116 default:
117 $this->_runTool();
118 break;
121 return $this;
125 * _detectMode()
127 * @return ZF
129 protected function _detectMode()
131 $arguments = $_SERVER['argv'];
133 $mode = 'runTool';
135 if (!isset($arguments[0])) {
136 return $mode;
139 if ($arguments[0] == $_SERVER['PHP_SELF']) {
140 $this->_executable = array_shift($arguments);
143 if (!isset($arguments[0])) {
144 return $mode;
147 if ($arguments[0] == '--setup') {
148 $mode = 'runSetup';
149 } elseif ($arguments[0] == '--info') {
150 $mode = 'runInfo';
153 return $mode;
158 * _detectHomeDirectory() - detect the home directory in a variety of different places
160 * @param $mustExist Should the returned value already exist in the file system
161 * @param $returnMessages Should it log messages for output later
162 * @return string
164 protected function _detectHomeDirectory($mustExist = true, $returnMessages = true)
166 $homeDirectory = null;
168 $homeDirectory = getenv('ZF_HOME'); // check env var ZF_HOME
169 if ($homeDirectory) {
170 $this->_logMessage('Home directory found in environment variable ZF_HOME with value ' . $homeDirectory, $returnMessages);
171 if (!$mustExist || ($mustExist && file_exists($homeDirectory))) {
172 return $homeDirectory;
173 } else {
174 $this->_logMessage('Home directory does not exist at ' . $homeDirectory, $returnMessages);
178 $homeDirectory = getenv('HOME'); // HOME environment variable
180 if ($homeDirectory) {
181 $this->_logMessage('Home directory found in environment variable HOME with value ' . $homeDirectory, $returnMessages);
182 if (!$mustExist || ($mustExist && file_exists($homeDirectory))) {
183 return $homeDirectory;
184 } else {
185 $this->_logMessage('Home directory does not exist at ' . $homeDirectory, $returnMessages);
190 $homeDirectory = getenv('HOMEPATH');
192 if ($homeDirectory) {
193 $this->_logMessage('Home directory found in environment variable HOMEPATH with value ' . $homeDirectory, $returnMessages);
194 if (!$mustExist || ($mustExist && file_exists($homeDirectory))) {
195 return $homeDirectory;
196 } else {
197 $this->_logMessage('Home directory does not exist at ' . $homeDirectory, $returnMessages);
201 $homeDirectory = getenv('USERPROFILE');
203 if ($homeDirectory) {
204 $this->_logMessage('Home directory found in environment variable USERPROFILE with value ' . $homeDirectory, $returnMessages);
205 if (!$mustExist || ($mustExist && file_exists($homeDirectory))) {
206 return $homeDirectory;
207 } else {
208 $this->_logMessage('Home directory does not exist at ' . $homeDirectory, $returnMessages);
212 return false;
216 * _detectStorageDirectory() - Detect where the storage directory is from a variaty of possiblities
218 * @param $mustExist Should the returned value already exist in the file system
219 * @param $returnMessages Should it log messages for output later
220 * @return string
222 protected function _detectStorageDirectory($mustExist = true, $returnMessages = true)
224 $storageDirectory = false;
226 $storageDirectory = getenv('ZF_STORAGE_DIR');
227 if ($storageDirectory) {
228 $this->_logMessage('Storage directory path found in environment variable ZF_STORAGE_DIR with value ' . $storageDirectory, $returnMessages);
229 if (!$mustExist || ($mustExist && file_exists($storageDirectory))) {
230 return $storageDirectory;
231 } else {
232 $this->_logMessage('Storage directory does not exist at ' . $storageDirectory, $returnMessages);
236 $homeDirectory = ($this->_homeDirectory) ? $this->_homeDirectory : $this->_detectHomeDirectory(true, false);
238 if ($homeDirectory) {
239 $storageDirectory = $homeDirectory . '/.zf/';
240 $this->_logMessage('Storage directory assumed in home directory at location ' . $storageDirectory, $returnMessages);
241 if (!$mustExist || ($mustExist && file_exists($storageDirectory))) {
242 return $storageDirectory;
243 } else {
244 $this->_logMessage('Storage directory does not exist at ' . $storageDirectory, $returnMessages);
248 return false;
252 * _detectConfigFile() - Detect config file location from a variety of possibilities
254 * @param $mustExist Should the returned value already exist in the file system
255 * @param $returnMessages Should it log messages for output later
256 * @return string
258 protected function _detectConfigFile($mustExist = true, $returnMessages = true)
260 $configFile = null;
262 $configFile = getenv('ZF_CONFIG_FILE');
263 if ($configFile) {
264 $this->_logMessage('Config file found environment variable ZF_CONFIG_FILE at ' . $configFile, $returnMessages);
265 if (!$mustExist || ($mustExist && file_exists($configFile))) {
266 return $configFile;
267 } else {
268 $this->_logMessage('Config file does not exist at ' . $configFile, $returnMessages);
272 $homeDirectory = ($this->_homeDirectory) ? $this->_homeDirectory : $this->_detectHomeDirectory(true, false);
273 if ($homeDirectory) {
274 $configFile = $homeDirectory . '/.zf.ini';
275 $this->_logMessage('Config file assumed in home directory at location ' . $configFile, $returnMessages);
276 if (!$mustExist || ($mustExist && file_exists($configFile))) {
277 return $configFile;
278 } else {
279 $this->_logMessage('Config file does not exist at ' . $configFile, $returnMessages);
283 $storageDirectory = ($this->_storageDirectory) ? $this->_storageDirectory : $this->_detectStorageDirectory(true, false);
284 if ($storageDirectory) {
285 $configFile = $storageDirectory . '/zf.ini';
286 $this->_logMessage('Config file assumed in storage directory at location ' . $configFile, $returnMessages);
287 if (!$mustExist || ($mustExist && file_exists($configFile))) {
288 return $configFile;
289 } else {
290 $this->_logMessage('Config file does not exist at ' . $configFile, $returnMessages);
294 return false;
299 * _setupPHPRuntime() - parse the config file if it exists for php ini values to set
301 * @return void
303 protected function _setupPHPRuntime()
305 // set php runtime settings
306 ini_set('display_errors', true);
308 // support the changing of the current working directory, necessary for some providers
309 if (isset($_ENV['ZEND_TOOL_CURRENT_WORKING_DIRECTORY'])) {
310 chdir($_ENV['ZEND_TOOL_CURRENT_WORKING_DIRECTORY']);
313 if (!$this->_configFile) {
314 return;
316 $zfINISettings = parse_ini_file($this->_configFile);
317 $phpINISettings = ini_get_all();
318 foreach ($zfINISettings as $zfINIKey => $zfINIValue) {
319 if (substr($zfINIKey, 0, 4) === 'php.') {
320 $phpINIKey = substr($zfINIKey, 4);
321 if (array_key_exists($phpINIKey, $phpINISettings)) {
322 ini_set($phpINIKey, $zfINIValue);
327 return null;
331 * _setupToolRuntime() - setup the tools include_path and load the proper framwork parts that
332 * enable Zend_Tool to work.
334 * @return void
336 protected function _setupToolRuntime()
339 $includePathPrepend = getenv('ZEND_TOOL_INCLUDE_PATH_PREPEND');
340 $includePathFull = getenv('ZEND_TOOL_INCLUDE_PATH');
342 // check if the user has not provided anything
343 if (!($includePathPrepend || $includePathFull)) {
344 if ($this->_tryClientLoad()) {
345 return;
349 // if ZF is not in the include_path, but relative to this file, put it in the include_path
350 if ($includePathPrepend || $includePathFull) {
351 if (isset($includePathPrepend) && ($includePathPrepend !== false)) {
352 set_include_path($includePathPrepend . PATH_SEPARATOR . get_include_path());
353 } elseif (isset($includePathFull) && ($includePathFull !== false)) {
354 set_include_path($includePathFull);
358 if ($this->_tryClientLoad()) {
359 return;
362 $zfIncludePath['relativePath'] = dirname(__FILE__) . '/../library/';
363 if (file_exists($zfIncludePath['relativePath'] . 'Zend/Tool/Framework/Client/Console.php')) {
364 set_include_path(realpath($zfIncludePath['relativePath']) . PATH_SEPARATOR . get_include_path());
367 if (!$this->_tryClientLoad()) {
368 $this->_mode = 'runError';
369 return;
372 return null;
376 * _tryClientLoad() - Attempt to load the Zend_Tool_Framework_Client_Console to enable the tool to run.
378 * This method will return false if its not loaded to allow the consumer to alter the environment in such
379 * a way that it can be called again to try loading the proper file/class.
381 * @return bool if the client is actuall loaded or not
383 protected function _tryClientLoad()
385 $this->_clientLoaded = false;
386 $fh = @fopen('Zend/Tool/Framework/Client/Console.php', 'r', true);
387 if (!$fh) {
388 return $this->_clientLoaded; // false
389 } else {
390 fclose($fh);
391 unset($fh);
392 include 'Zend/Tool/Framework/Client/Console.php';
393 $this->_clientLoaded = class_exists('Zend_Tool_Framework_Client_Console');
396 return $this->_clientLoaded;
400 * _runError() - Output the error screen that tells the user that the tool was not setup
401 * in a sane way
403 * @return void
405 protected function _runError()
408 echo <<<EOS
410 ***************************** ZF ERROR ********************************
411 In order to run the zf command, you need to ensure that Zend Framework
412 is inside your include_path. There are a variety of ways that you can
413 ensure that this zf command line tool knows where the Zend Framework
414 library is on your system, but not all of them can be described here.
416 The easiest way to get the zf command running is to give it the include
417 path via an environment variable ZEND_TOOL_INCLUDE_PATH or
418 ZEND_TOOL_INCLUDE_PATH_PREPEND with the proper include path to use,
419 then run the command "zf --setup". This command is designed to create
420 a storage location for your user, as well as create the zf.ini file
421 that the zf command will consult in order to run properly on your
422 system.
424 Example you would run:
426 $ ZEND_TOOL_INCLUDE_PATH=/path/to/library zf --setup
428 Your are encourged to read more in the link that follows.
430 EOS;
432 return null;
436 * _runInfo() - this command will produce information about the setup of this script and
437 * Zend_Tool
439 * @return void
441 protected function _runInfo()
443 echo 'Zend_Tool & CLI Setup Information' . PHP_EOL
444 . '(available via the command line "zf --info")'
445 . PHP_EOL;
447 echo ' * ' . implode(PHP_EOL . ' * ', $this->_messages) . PHP_EOL;
449 echo PHP_EOL;
451 echo 'To change the setup of this tool, run: "zf --setup"';
453 echo PHP_EOL;
458 * _runSetup() - parse the request to see which setup command to run
460 * @return void
462 protected function _runSetup()
464 $setupCommand = (isset($_SERVER['argv'][2])) ? $_SERVER['argv'][2] : null;
466 switch ($setupCommand) {
467 case 'storage-directory':
468 $this->_runSetupStorageDirectory();
469 break;
470 case 'config-file':
471 $this->_runSetupConfigFile();
472 break;
473 default:
474 $this->_runSetupMoreInfo();
475 break;
478 return null;
482 * _runSetupStorageDirectory() - if the storage directory does not exist, create it
484 * @return void
486 protected function _runSetupStorageDirectory()
488 $storageDirectory = $this->_detectStorageDirectory(false, false);
490 if (file_exists($storageDirectory)) {
491 echo 'Directory already exists at ' . $storageDirectory . PHP_EOL
492 . 'Cannot create storage directory.';
493 return;
496 mkdir($storageDirectory);
498 echo 'Storage directory created at ' . $storageDirectory . PHP_EOL;
502 * _runSetupConfigFile()
504 * @return void
506 protected function _runSetupConfigFile()
508 $configFile = $this->_detectConfigFile(false, false);
510 if (file_exists($configFile)) {
511 echo 'File already exists at ' . $configFile . PHP_EOL
512 . 'Cannot write new config file.';
513 return;
516 $includePath = get_include_path();
518 $contents = 'php.include_path = "' . $includePath . '"';
520 file_put_contents($configFile, $contents);
522 $iniValues = ini_get_all();
523 if ($iniValues['include_path']['global_value'] != $iniValues['include_path']['local_value']) {
524 echo 'NOTE: the php include_path to be used with the tool has been written' . PHP_EOL
525 . 'to the config file, using ZF_INCLUDE_PATH (or other include_path setters)' . PHP_EOL
526 . 'is no longer necessary.' . PHP_EOL . PHP_EOL;
529 echo 'Config file written to ' . $configFile . PHP_EOL;
531 return null;
535 * _runSetupMoreInfo() - return more information about what can be setup, and what is setup
537 * @return void
539 protected function _runSetupMoreInfo()
541 $homeDirectory = $this->_detectHomeDirectory(false, false);
542 $storageDirectory = $this->_detectStorageDirectory(false, false);
543 $configFile = $this->_detectConfigFile(false, false);
545 echo <<<EOS
547 ZF Command Line Tool - Setup
548 ----------------------------
550 Current Paths (Existing or not):
551 Home Directory: {$homeDirectory}
552 Storage Directory: {$storageDirectory}
553 Config File: {$configFile}
555 Important Environment Variables:
556 ZF_HOME
557 - the directory this tool will look for a home directory
558 - directory must exist
559 ZF_STORAGE_DIRECTORY
560 - where this tool will look for a storage directory
561 - directory must exist
562 ZF_CONFIG_FILE
563 - where this tool will look for a configuration file
564 ZF_INCLUDE_PATH
565 - set the include_path for this tool to use this value
566 ZF_INCLUDE_PATH_PREPEND
567 - prepend the current php.ini include_path with this value
569 Search Order:
570 Home Directory:
571 - ZF_HOME, then HOME (*nix), then HOMEPATH (windows)
572 Storage Directory:
573 - ZF_STORAGE_DIR, then {home}/.zf/
574 Config File:
575 - ZF_CONFIG_FILE, then {home}/.zf.ini, then {home}/zf.ini,
576 then {storage}/zf.ini
578 Commands:
579 zf --setup storage-directory
580 - setup the storage directory, directory will be created
581 zf --setup config-file
582 - create the config file with some default values
585 EOS;
589 * _runTool() - This is where the magic happens, dispatch Zend_Tool
591 * @return void
593 protected function _runTool()
596 $configOptions = array();
597 if (isset($this->_configFile) && $this->_configFile) {
598 $configOptions['configOptions']['configFilepath'] = $this->_configFile;
600 if (isset($this->_storageDirectory) && $this->_storageDirectory) {
601 $configOptions['storageOptions']['directory'] = $this->_storageDirectory;
604 // ensure that zf.php loads the Zend_Tool_Project features
605 $configOptions['classesToLoad'] = 'Zend_Tool_Project_Provider_Manifest';
607 $console = new Zend_Tool_Framework_Client_Console($configOptions);
608 $console->dispatch();
609 return null;
613 * _logMessage() - Internal method used to log setup and information messages.
615 * @param $message
616 * @param $storeMessage
617 * @return void
619 protected function _logMessage($message, $storeMessage = true)
621 if (!$storeMessage) {
622 return;
625 $this->_messages[] = $message;
631 if (!getenv('ZF_NO_MAIN')) {
632 ZF::main();