zf.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  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_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$
  21. */
  22. /**
  23. * ZF
  24. *
  25. * @category Zend
  26. * @package Zend_Tool
  27. * @subpackage Framework
  28. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  29. * @license http://framework.zend.com/license/new-bsd New BSD License
  30. */
  31. class ZF
  32. {
  33. /**
  34. * @var bool
  35. */
  36. protected $_clientLoaded = false;
  37. /**
  38. * @var string
  39. */
  40. protected $_mode = 'runTool';
  41. /**
  42. * @var array of messages
  43. */
  44. protected $_messages = array();
  45. /**
  46. * @var string
  47. */
  48. protected $_homeDirectory = null;
  49. /**
  50. * @var string
  51. */
  52. protected $_storageDirectory = null;
  53. /**
  54. * @var string
  55. */
  56. protected $_configFile = null;
  57. /**
  58. * main()
  59. *
  60. * @return void
  61. */
  62. public static function main()
  63. {
  64. $zf = new self();
  65. $zf->bootstrap();
  66. $zf->run();
  67. }
  68. /**
  69. * bootstrap()
  70. *
  71. * @return ZF
  72. */
  73. public function bootstrap()
  74. {
  75. // detect settings
  76. $this->_mode = $this->_detectMode();
  77. $this->_homeDirectory = $this->_detectHomeDirectory();
  78. $this->_storageDirectory = $this->_detectStorageDirectory();
  79. $this->_configFile = $this->_detectConfigFile();
  80. // setup
  81. $this->_setupPHPRuntime();
  82. $this->_setupToolRuntime();
  83. }
  84. /**
  85. * run()
  86. *
  87. * @return ZF
  88. */
  89. public function run()
  90. {
  91. switch ($this->_mode) {
  92. case 'runError':
  93. $this->_runError();
  94. $this->_runInfo();
  95. break;
  96. case 'runSetup':
  97. if ($this->_runSetup() === false) {
  98. $this->_runInfo();
  99. }
  100. break;
  101. case 'runInfo':
  102. $this->_runInfo();
  103. break;
  104. case 'runTool':
  105. default:
  106. $this->_runTool();
  107. break;
  108. }
  109. return $this;
  110. }
  111. /**
  112. * _detectMode()
  113. *
  114. * @return ZF
  115. */
  116. protected function _detectMode()
  117. {
  118. $arguments = $_SERVER['argv'];
  119. $mode = 'runTool';
  120. if (!isset($arguments[0])) {
  121. return $mode;
  122. }
  123. if ($arguments[0] == $_SERVER['PHP_SELF']) {
  124. $this->_executable = array_shift($arguments);
  125. }
  126. if (!isset($arguments[0])) {
  127. return $mode;
  128. }
  129. if ($arguments[0] == '--setup') {
  130. $mode = 'runSetup';
  131. } elseif ($arguments[0] == '--info') {
  132. $mode = 'runInfo';
  133. }
  134. return $mode;
  135. }
  136. /**
  137. * _detectHomeDirectory() - detect the home directory in a variety of different places
  138. *
  139. * @param $mustExist Should the returned value already exist in the file system
  140. * @param $returnMessages Should it log messages for output later
  141. * @return string
  142. */
  143. protected function _detectHomeDirectory($mustExist = true, $returnMessages = true)
  144. {
  145. $homeDirectory = null;
  146. $homeDirectory = getenv('ZF_HOME'); // check env var ZF_HOME
  147. if ($homeDirectory) {
  148. $this->_logMessage('Home directory found in environment variable ZF_HOME with value ' . $homeDirectory, $returnMessages);
  149. if (!$mustExist || ($mustExist && file_exists($homeDirectory))) {
  150. return $homeDirectory;
  151. } else {
  152. $this->_logMessage('Home directory does not exist at ' . $homeDirectory, $returnMessages);
  153. }
  154. }
  155. $homeDirectory = getenv('HOME'); // HOME environment variable
  156. if ($homeDirectory) {
  157. $this->_logMessage('Home directory found in environment variable HOME with value ' . $homeDirectory, $returnMessages);
  158. if (!$mustExist || ($mustExist && file_exists($homeDirectory))) {
  159. return $homeDirectory;
  160. } else {
  161. $this->_logMessage('Home directory does not exist at ' . $homeDirectory, $returnMessages);
  162. }
  163. }
  164. $homeDirectory = getenv('HOMEPATH');
  165. if ($homeDirectory) {
  166. $this->_logMessage('Home directory found in environment variable HOMEPATH with value ' . $homeDirectory, $returnMessages);
  167. if (!$mustExist || ($mustExist && file_exists($homeDirectory))) {
  168. return $homeDirectory;
  169. } else {
  170. $this->_logMessage('Home directory does not exist at ' . $homeDirectory, $returnMessages);
  171. }
  172. }
  173. $homeDirectory = getenv('USERPROFILE');
  174. if ($homeDirectory) {
  175. $this->_logMessage('Home directory found in environment variable USERPROFILE with value ' . $homeDirectory, $returnMessages);
  176. if (!$mustExist || ($mustExist && file_exists($homeDirectory))) {
  177. return $homeDirectory;
  178. } else {
  179. $this->_logMessage('Home directory does not exist at ' . $homeDirectory, $returnMessages);
  180. }
  181. }
  182. return false;
  183. }
  184. /**
  185. * _detectStorageDirectory() - Detect where the storage directory is from a variaty of possiblities
  186. *
  187. * @param $mustExist Should the returned value already exist in the file system
  188. * @param $returnMessages Should it log messages for output later
  189. * @return string
  190. */
  191. protected function _detectStorageDirectory($mustExist = true, $returnMessages = true)
  192. {
  193. $storageDirectory = false;
  194. $storageDirectory = getenv('ZF_STORAGE_DIR');
  195. if ($storageDirectory) {
  196. $this->_logMessage('Storage directory path found in environment variable ZF_STORAGE_DIR with value ' . $storageDirectory, $returnMessages);
  197. if (!$mustExist || ($mustExist && file_exists($storageDirectory))) {
  198. return $storageDirectory;
  199. } else {
  200. $this->_logMessage('Storage directory does not exist at ' . $storageDirectory, $returnMessages);
  201. }
  202. }
  203. $homeDirectory = ($this->_homeDirectory) ? $this->_homeDirectory : $this->_detectHomeDirectory(true, false);
  204. if ($homeDirectory) {
  205. $storageDirectory = $homeDirectory . '/.zf/';
  206. $this->_logMessage('Storage directory assumed in home directory at location ' . $storageDirectory, $returnMessages);
  207. if (!$mustExist || ($mustExist && file_exists($storageDirectory))) {
  208. return $storageDirectory;
  209. } else {
  210. $this->_logMessage('Storage directory does not exist at ' . $storageDirectory, $returnMessages);
  211. }
  212. }
  213. return false;
  214. }
  215. /**
  216. * _detectConfigFile() - Detect config file location from a variety of possibilities
  217. *
  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
  221. */
  222. protected function _detectConfigFile($mustExist = true, $returnMessages = true)
  223. {
  224. $configFile = null;
  225. $configFile = getenv('ZF_CONFIG_FILE');
  226. if ($configFile) {
  227. $this->_logMessage('Config file found environment variable ZF_CONFIG_FILE at ' . $configFile, $returnMessages);
  228. if (!$mustExist || ($mustExist && file_exists($configFile))) {
  229. return $configFile;
  230. } else {
  231. $this->_logMessage('Config file does not exist at ' . $configFile, $returnMessages);
  232. }
  233. }
  234. $homeDirectory = ($this->_homeDirectory) ? $this->_homeDirectory : $this->_detectHomeDirectory(true, false);
  235. if ($homeDirectory) {
  236. $configFile = $homeDirectory . '/.zf.ini';
  237. $this->_logMessage('Config file assumed in home directory at location ' . $configFile, $returnMessages);
  238. if (!$mustExist || ($mustExist && file_exists($configFile))) {
  239. return $configFile;
  240. } else {
  241. $this->_logMessage('Config file does not exist at ' . $configFile, $returnMessages);
  242. }
  243. }
  244. $storageDirectory = ($this->_storageDirectory) ? $this->_storageDirectory : $this->_detectStorageDirectory(true, false);
  245. if ($storageDirectory) {
  246. $configFile = $storageDirectory . '/zf.ini';
  247. $this->_logMessage('Config file assumed in storage directory at location ' . $configFile, $returnMessages);
  248. if (!$mustExist || ($mustExist && file_exists($configFile))) {
  249. return $configFile;
  250. } else {
  251. $this->_logMessage('Config file does not exist at ' . $configFile, $returnMessages);
  252. }
  253. }
  254. return false;
  255. }
  256. /**
  257. * _setupPHPRuntime() - parse the config file if it exists for php ini values to set
  258. *
  259. * @return void
  260. */
  261. protected function _setupPHPRuntime()
  262. {
  263. // set php runtime settings
  264. ini_set('display_errors', true);
  265. // support the changing of the current working directory, necessary for some providers
  266. if (isset($_ENV['ZEND_TOOL_CURRENT_WORKING_DIRECTORY'])) {
  267. chdir($_ENV['ZEND_TOOL_CURRENT_WORKING_DIRECTORY']);
  268. }
  269. if (!$this->_configFile) {
  270. return;
  271. }
  272. $zfINISettings = parse_ini_file($this->_configFile);
  273. $phpINISettings = ini_get_all();
  274. foreach ($zfINISettings as $zfINIKey => $zfINIValue) {
  275. if (substr($zfINIKey, 0, 4) === 'php.') {
  276. $phpINIKey = substr($zfINIKey, 4);
  277. if (array_key_exists($phpINIKey, $phpINISettings)) {
  278. ini_set($phpINIKey, $zfINIValue);
  279. }
  280. }
  281. }
  282. return null;
  283. }
  284. /**
  285. * _setupToolRuntime() - setup the tools include_path and load the proper framwork parts that
  286. * enable Zend_Tool to work.
  287. *
  288. * @return void
  289. */
  290. protected function _setupToolRuntime()
  291. {
  292. $includePathPrepend = getenv('ZEND_TOOL_INCLUDE_PATH_PREPEND');
  293. $includePathFull = getenv('ZEND_TOOL_INCLUDE_PATH');
  294. // check if the user has not provided anything
  295. if (!($includePathPrepend || $includePathFull)) {
  296. if ($this->_tryClientLoad()) {
  297. return;
  298. }
  299. }
  300. // if ZF is not in the include_path, but relative to this file, put it in the include_path
  301. if ($includePathPrepend || $includePathFull) {
  302. if (isset($includePathPrepend) && ($includePathPrepend !== false)) {
  303. set_include_path($includePathPrepend . PATH_SEPARATOR . get_include_path());
  304. } elseif (isset($includePathFull) && ($includePathFull !== false)) {
  305. set_include_path($includePathFull);
  306. }
  307. }
  308. if ($this->_tryClientLoad()) {
  309. return;
  310. }
  311. $zfIncludePath['relativePath'] = dirname(__FILE__) . '/../library/';
  312. if (file_exists($zfIncludePath['relativePath'] . 'Zend/Tool/Framework/Client/Console.php')) {
  313. set_include_path(realpath($zfIncludePath['relativePath']) . PATH_SEPARATOR . get_include_path());
  314. }
  315. if (!$this->_tryClientLoad()) {
  316. $this->_mode = 'runError';
  317. return;
  318. }
  319. return null;
  320. }
  321. /**
  322. * _tryClientLoad() - Attempt to load the Zend_Tool_Framework_Client_Console to enable the tool to run.
  323. *
  324. * This method will return false if its not loaded to allow the consumer to alter the environment in such
  325. * a way that it can be called again to try loading the proper file/class.
  326. *
  327. * @return bool if the client is actuall loaded or not
  328. */
  329. protected function _tryClientLoad()
  330. {
  331. $this->_clientLoaded = false;
  332. $fh = @fopen('Zend/Tool/Framework/Client/Console.php', 'r', true);
  333. if (!$fh) {
  334. return $this->_clientLoaded; // false
  335. } else {
  336. fclose($fh);
  337. unset($fh);
  338. include 'Zend/Tool/Framework/Client/Console.php';
  339. $this->_clientLoaded = class_exists('Zend_Tool_Framework_Client_Console');
  340. }
  341. return $this->_clientLoaded;
  342. }
  343. /**
  344. * _runError() - Output the error screen that tells the user that the tool was not setup
  345. * in a sane way
  346. *
  347. * @return void
  348. */
  349. protected function _runError()
  350. {
  351. echo <<<EOS
  352. ***************************** ZF ERROR ********************************
  353. In order to run the zf command, you need to ensure that Zend Framework
  354. is inside your include_path. There are a variety of ways that you can
  355. ensure that this zf command line tool knows where the Zend Framework
  356. library is on your system, but not all of them can be described here.
  357. The easiest way to get the zf command running is to give it the include
  358. path via an environment variable ZEND_TOOL_INCLUDE_PATH or
  359. ZEND_TOOL_INCLUDE_PATH_PREPEND with the proper include path to use,
  360. then run the command "zf --setup". This command is designed to create
  361. a storage location for your user, as well as create the zf.ini file
  362. that the zf command will consult in order to run properly on your
  363. system.
  364. Example you would run:
  365. $ ZEND_TOOL_INCLUDE_PATH=/path/to/library zf --setup
  366. Your are encourged to read more in the link that follows.
  367. EOS;
  368. return null;
  369. }
  370. /**
  371. * _runInfo() - this command will produce information about the setup of this script and
  372. * Zend_Tool
  373. *
  374. * @return void
  375. */
  376. protected function _runInfo()
  377. {
  378. echo 'Zend_Tool & CLI Setup Information' . PHP_EOL
  379. . '(available via the command line "zf --info")'
  380. . PHP_EOL;
  381. echo ' * ' . implode(PHP_EOL . ' * ', $this->_messages) . PHP_EOL;
  382. echo PHP_EOL;
  383. echo 'To change the setup of this tool, run: "zf --setup"';
  384. echo PHP_EOL;
  385. }
  386. /**
  387. * _runSetup() - parse the request to see which setup command to run
  388. *
  389. * @return void
  390. */
  391. protected function _runSetup()
  392. {
  393. $setupCommand = (isset($_SERVER['argv'][2])) ? $_SERVER['argv'][2] : null;
  394. switch ($setupCommand) {
  395. case 'storage-directory':
  396. $this->_runSetupStorageDirectory();
  397. break;
  398. case 'config-file':
  399. $this->_runSetupConfigFile();
  400. break;
  401. default:
  402. $this->_runSetupMoreInfo();
  403. break;
  404. }
  405. return null;
  406. }
  407. /**
  408. * _runSetupStorageDirectory() - if the storage directory does not exist, create it
  409. *
  410. * @return void
  411. */
  412. protected function _runSetupStorageDirectory()
  413. {
  414. $storageDirectory = $this->_detectStorageDirectory(false, false);
  415. if (file_exists($storageDirectory)) {
  416. echo 'Directory already exists at ' . $storageDirectory . PHP_EOL
  417. . 'Cannot create storage directory.';
  418. return;
  419. }
  420. mkdir($storageDirectory);
  421. echo 'Storage directory created at ' . $storageDirectory . PHP_EOL;
  422. }
  423. /**
  424. * _runSetupConfigFile()
  425. *
  426. * @return void
  427. */
  428. protected function _runSetupConfigFile()
  429. {
  430. $configFile = $this->_detectConfigFile(false, false);
  431. if (file_exists($configFile)) {
  432. echo 'File already exists at ' . $configFile . PHP_EOL
  433. . 'Cannot write new config file.';
  434. return;
  435. }
  436. $includePath = get_include_path();
  437. $contents = 'php.include_path = "' . $includePath . '"';
  438. file_put_contents($configFile, $contents);
  439. $iniValues = ini_get_all();
  440. if ($iniValues['include_path']['global_value'] != $iniValues['include_path']['local_value']) {
  441. echo 'NOTE: the php include_path to be used with the tool has been written' . PHP_EOL
  442. . 'to the config file, using ZF_INCLUDE_PATH (or other include_path setters)' . PHP_EOL
  443. . 'is no longer necessary.' . PHP_EOL . PHP_EOL;
  444. }
  445. echo 'Config file written to ' . $configFile . PHP_EOL;
  446. return null;
  447. }
  448. /**
  449. * _runSetupMoreInfo() - return more information about what can be setup, and what is setup
  450. *
  451. * @return void
  452. */
  453. protected function _runSetupMoreInfo()
  454. {
  455. $homeDirectory = $this->_detectHomeDirectory(false, false);
  456. $storageDirectory = $this->_detectStorageDirectory(false, false);
  457. $configFile = $this->_detectConfigFile(false, false);
  458. echo <<<EOS
  459. ZF Command Line Tool - Setup
  460. ----------------------------
  461. Current Paths (Existing or not):
  462. Home Directory: {$homeDirectory}
  463. Storage Directory: {$storageDirectory}
  464. Config File: {$configFile}
  465. Important Environment Variables:
  466. ZF_HOME
  467. - the directory this tool will look for a home directory
  468. - directory must exist
  469. ZF_STORAGE_DIRECTORY
  470. - where this tool will look for a storage directory
  471. - directory must exist
  472. ZF_CONFIG_FILE
  473. - where this tool will look for a configuration file
  474. ZF_INCLUDE_PATH
  475. - set the include_path for this tool to use this value
  476. ZF_INCLUDE_PATH_PREPEND
  477. - prepend the current php.ini include_path with this value
  478. Search Order:
  479. Home Directory:
  480. - ZF_HOME, then HOME (*nix), then HOMEPATH (windows)
  481. Storage Directory:
  482. - ZF_STORAGE_DIR, then {home}/.zf/
  483. Config File:
  484. - ZF_CONFIG_FILE, then {home}/.zf.ini, then {home}/zf.ini,
  485. then {storage}/zf.ini
  486. Commands:
  487. zf --setup storage-directory
  488. - setup the storage directory, directory will be created
  489. zf --setup config-file
  490. - create the config file with some default values
  491. EOS;
  492. }
  493. /**
  494. * _runTool() - This is where the magic happens, dispatch Zend_Tool
  495. *
  496. * @return void
  497. */
  498. protected function _runTool()
  499. {
  500. $configOptions = array();
  501. if (isset($this->_configFile) && $this->_configFile) {
  502. $configOptions['configOptions']['configFilepath'] = $this->_configFile;
  503. }
  504. if (isset($this->_storageDirectory) && $this->_storageDirectory) {
  505. $configOptions['storageOptions']['directory'] = $this->_storageDirectory;
  506. }
  507. // ensure that zf.php loads the Zend_Tool_Project features
  508. $configOptions['classesToLoad'] = 'Zend_Tool_Project_Provider_Manifest';
  509. $console = new Zend_Tool_Framework_Client_Console($configOptions);
  510. $console->dispatch();
  511. return null;
  512. }
  513. /**
  514. * _logMessage() - Internal method used to log setup and information messages.
  515. *
  516. * @param $message
  517. * @param $storeMessage
  518. * @return void
  519. */
  520. protected function _logMessage($message, $storeMessage = true)
  521. {
  522. if (!$storeMessage) {
  523. return;
  524. }
  525. $this->_messages[] = $message;
  526. }
  527. }
  528. if (!getenv('ZF_NO_MAIN')) {
  529. ZF::main();
  530. }