PageRenderTime 27ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/cake/console/cake.php

https://github.com/hack521/contenidopago
PHP | 667 lines | 430 code | 61 blank | 176 comment | 71 complexity | a8f46dbca91fbcdc7f5c830a8084c0b9 MD5 | raw file
  1. #!/usr/bin/php -q
  2. <?php
  3. /**
  4. * Command-line code generation utility to automate programmer chores.
  5. *
  6. * Shell dispatcher class
  7. *
  8. * PHP versions 4 and 5
  9. *
  10. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  11. * Copyright 2005-2011, Cake Software Foundation, Inc.
  12. *
  13. * Licensed under The MIT License
  14. * Redistributions of files must retain the above copyright notice.
  15. *
  16. * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  17. * @link http://cakephp.org CakePHP(tm) Project
  18. * @package cake
  19. * @subpackage cake.cake.console
  20. * @since CakePHP(tm) v 1.2.0.5012
  21. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  22. */
  23. if (!defined('E_DEPRECATED')) {
  24. define('E_DEPRECATED', 8192);
  25. }
  26. /**
  27. * Shell dispatcher
  28. *
  29. * @package cake
  30. * @subpackage cake.cake.console
  31. */
  32. class ShellDispatcher {
  33. /**
  34. * Standard input stream.
  35. *
  36. * @var filehandle
  37. * @access public
  38. */
  39. var $stdin;
  40. /**
  41. * Standard output stream.
  42. *
  43. * @var filehandle
  44. * @access public
  45. */
  46. var $stdout;
  47. /**
  48. * Standard error stream.
  49. *
  50. * @var filehandle
  51. * @access public
  52. */
  53. var $stderr;
  54. /**
  55. * Contains command switches parsed from the command line.
  56. *
  57. * @var array
  58. * @access public
  59. */
  60. var $params = array();
  61. /**
  62. * Contains arguments parsed from the command line.
  63. *
  64. * @var array
  65. * @access public
  66. */
  67. var $args = array();
  68. /**
  69. * The file name of the shell that was invoked.
  70. *
  71. * @var string
  72. * @access public
  73. */
  74. var $shell = null;
  75. /**
  76. * The class name of the shell that was invoked.
  77. *
  78. * @var string
  79. * @access public
  80. */
  81. var $shellClass = null;
  82. /**
  83. * The command called if public methods are available.
  84. *
  85. * @var string
  86. * @access public
  87. */
  88. var $shellCommand = null;
  89. /**
  90. * The path locations of shells.
  91. *
  92. * @var array
  93. * @access public
  94. */
  95. var $shellPaths = array();
  96. /**
  97. * The path to the current shell location.
  98. *
  99. * @var string
  100. * @access public
  101. */
  102. var $shellPath = null;
  103. /**
  104. * The name of the shell in camelized.
  105. *
  106. * @var string
  107. * @access public
  108. */
  109. var $shellName = null;
  110. /**
  111. * Constructor
  112. *
  113. * The execution of the script is stopped after dispatching the request with
  114. * a status code of either 0 or 1 according to the result of the dispatch.
  115. *
  116. * @param array $args the argv
  117. * @return void
  118. * @access public
  119. */
  120. function ShellDispatcher($args = array()) {
  121. set_time_limit(0);
  122. $this->__initConstants();
  123. $this->parseParams($args);
  124. $this->_initEnvironment();
  125. $this->__buildPaths();
  126. $this->_stop($this->dispatch() === false ? 1 : 0);
  127. }
  128. /**
  129. * Defines core configuration.
  130. *
  131. * @access private
  132. */
  133. function __initConstants() {
  134. if (function_exists('ini_set')) {
  135. ini_set('display_errors', '1');
  136. ini_set('error_reporting', E_ALL & ~E_DEPRECATED);
  137. ini_set('html_errors', false);
  138. ini_set('implicit_flush', true);
  139. ini_set('max_execution_time', 0);
  140. }
  141. if (!defined('CAKE_CORE_INCLUDE_PATH')) {
  142. define('PHP5', (PHP_VERSION >= 5));
  143. define('DS', DIRECTORY_SEPARATOR);
  144. define('CAKE_CORE_INCLUDE_PATH', dirname(dirname(dirname(__FILE__))));
  145. define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
  146. define('DISABLE_DEFAULT_ERROR_HANDLING', false);
  147. define('CAKEPHP_SHELL', true);
  148. }
  149. require_once(CORE_PATH . 'cake' . DS . 'basics.php');
  150. }
  151. /**
  152. * Defines current working environment.
  153. *
  154. * @access protected
  155. */
  156. function _initEnvironment() {
  157. $this->stdin = fopen('php://stdin', 'r');
  158. $this->stdout = fopen('php://stdout', 'w');
  159. $this->stderr = fopen('php://stderr', 'w');
  160. if (!$this->__bootstrap()) {
  161. $this->stderr("\nCakePHP Console: ");
  162. $this->stderr("\nUnable to load Cake core:");
  163. $this->stderr("\tMake sure " . DS . 'cake' . DS . 'libs exists in ' . CAKE_CORE_INCLUDE_PATH);
  164. $this->_stop();
  165. }
  166. if (!isset($this->args[0]) || !isset($this->params['working'])) {
  167. $this->stderr("\nCakePHP Console: ");
  168. $this->stderr('This file has been loaded incorrectly and cannot continue.');
  169. $this->stderr('Please make sure that ' . DIRECTORY_SEPARATOR . 'cake' . DIRECTORY_SEPARATOR . 'console is in your system path,');
  170. $this->stderr('and check the manual for the correct usage of this command.');
  171. $this->stderr('(http://manual.cakephp.org/)');
  172. $this->_stop();
  173. }
  174. if (basename(__FILE__) != basename($this->args[0])) {
  175. $this->stderr("\nCakePHP Console: ");
  176. $this->stderr('Warning: the dispatcher may have been loaded incorrectly, which could lead to unexpected results...');
  177. if ($this->getInput('Continue anyway?', array('y', 'n'), 'y') == 'n') {
  178. $this->_stop();
  179. }
  180. }
  181. $this->shiftArgs();
  182. }
  183. /**
  184. * Builds the shell paths.
  185. *
  186. * @access private
  187. * @return void
  188. */
  189. function __buildPaths() {
  190. $paths = array();
  191. if (!class_exists('Folder')) {
  192. require LIBS . 'folder.php';
  193. }
  194. $plugins = App::objects('plugin', null, false);
  195. foreach ((array)$plugins as $plugin) {
  196. $pluginPath = App::pluginPath($plugin);
  197. $path = $pluginPath . 'vendors' . DS . 'shells' . DS;
  198. if (file_exists($path)) {
  199. $paths[] = $path;
  200. }
  201. }
  202. $vendorPaths = array_values(App::path('vendors'));
  203. foreach ($vendorPaths as $vendorPath) {
  204. $path = rtrim($vendorPath, DS) . DS . 'shells' . DS;
  205. if (file_exists($path)) {
  206. $paths[] = $path;
  207. }
  208. }
  209. $this->shellPaths = array_values(array_unique(array_merge($paths, App::path('shells'))));
  210. }
  211. /**
  212. * Initializes the environment and loads the Cake core.
  213. *
  214. * @return boolean Success.
  215. * @access private
  216. */
  217. function __bootstrap() {
  218. define('ROOT', $this->params['root']);
  219. define('APP_DIR', $this->params['app']);
  220. define('APP_PATH', $this->params['working'] . DS);
  221. define('WWW_ROOT', APP_PATH . $this->params['webroot'] . DS);
  222. if (!is_dir(ROOT . DS . APP_DIR . DS . 'tmp')) {
  223. define('TMP', CORE_PATH . 'cake' . DS . 'console' . DS . 'templates' . DS . 'skel' . DS . 'tmp' . DS);
  224. }
  225. $includes = array(
  226. CORE_PATH . 'cake' . DS . 'config' . DS . 'paths.php',
  227. CORE_PATH . 'cake' . DS . 'libs' . DS . 'object.php',
  228. CORE_PATH . 'cake' . DS . 'libs' . DS . 'inflector.php',
  229. CORE_PATH . 'cake' . DS . 'libs' . DS . 'configure.php',
  230. CORE_PATH . 'cake' . DS . 'libs' . DS . 'file.php',
  231. CORE_PATH . 'cake' . DS . 'libs' . DS . 'cache.php',
  232. CORE_PATH . 'cake' . DS . 'libs' . DS . 'string.php',
  233. CORE_PATH . 'cake' . DS . 'libs' . DS . 'class_registry.php',
  234. CORE_PATH . 'cake' . DS . 'console' . DS . 'error.php'
  235. );
  236. foreach ($includes as $inc) {
  237. if (!require($inc)) {
  238. $this->stderr("Failed to load Cake core file {$inc}");
  239. return false;
  240. }
  241. }
  242. Configure::getInstance(file_exists(CONFIGS . 'bootstrap.php'));
  243. if (!file_exists(APP_PATH . 'config' . DS . 'core.php')) {
  244. include_once CORE_PATH . 'cake' . DS . 'console' . DS . 'templates' . DS . 'skel' . DS . 'config' . DS . 'core.php';
  245. App::build();
  246. }
  247. return true;
  248. }
  249. /**
  250. * Clear the console
  251. *
  252. * @return void
  253. * @access public
  254. */
  255. function clear() {
  256. if (empty($this->params['noclear'])) {
  257. if ( DS === '/') {
  258. passthru('clear');
  259. } else {
  260. passthru('cls');
  261. }
  262. }
  263. }
  264. /**
  265. * Dispatches a CLI request
  266. *
  267. * @return boolean
  268. * @access public
  269. */
  270. function dispatch() {
  271. $arg = $this->shiftArgs();
  272. if (!$arg) {
  273. $this->help();
  274. return false;
  275. }
  276. if ($arg == 'help') {
  277. $this->help();
  278. return true;
  279. }
  280. list($plugin, $shell) = pluginSplit($arg);
  281. $this->shell = $shell;
  282. $this->shellName = Inflector::camelize($shell);
  283. $this->shellClass = $this->shellName . 'Shell';
  284. $arg = null;
  285. if (isset($this->args[0])) {
  286. $arg = $this->args[0];
  287. $this->shellCommand = Inflector::variable($arg);
  288. }
  289. $Shell = $this->_getShell($plugin);
  290. if (!$Shell) {
  291. $title = sprintf(__('Error: Class %s could not be loaded.', true), $this->shellClass);
  292. $this->stderr($title . "\n");
  293. return false;
  294. }
  295. $methods = array();
  296. if (is_a($Shell, 'Shell')) {
  297. $Shell->initialize();
  298. $Shell->loadTasks();
  299. foreach ($Shell->taskNames as $task) {
  300. if (is_a($Shell->{$task}, 'Shell')) {
  301. $Shell->{$task}->initialize();
  302. $Shell->{$task}->loadTasks();
  303. }
  304. }
  305. $task = Inflector::camelize($arg);
  306. if (in_array($task, $Shell->taskNames)) {
  307. $this->shiftArgs();
  308. $Shell->{$task}->startup();
  309. if (isset($this->args[0]) && $this->args[0] == 'help') {
  310. if (method_exists($Shell->{$task}, 'help')) {
  311. $Shell->{$task}->help();
  312. } else {
  313. $this->help();
  314. }
  315. return true;
  316. }
  317. return $Shell->{$task}->execute();
  318. }
  319. $methods = array_diff(get_class_methods('Shell'), array('help'));
  320. }
  321. $methods = array_diff(get_class_methods($Shell), $methods);
  322. $added = in_array(strtolower($arg), array_map('strtolower', $methods));
  323. $private = $arg[0] == '_' && method_exists($Shell, $arg);
  324. if (!$private) {
  325. if ($added) {
  326. $this->shiftArgs();
  327. $Shell->startup();
  328. return $Shell->{$arg}();
  329. }
  330. if (method_exists($Shell, 'main')) {
  331. $Shell->startup();
  332. return $Shell->main();
  333. }
  334. }
  335. $title = sprintf(__('Error: Unknown %1$s command %2$s.', true), $this->shellName, $arg);
  336. $message = sprintf(__('For usage try `cake %s help`', true), $this->shell);
  337. $this->stderr($title . "\n" . $message . "\n");
  338. return false;
  339. }
  340. /**
  341. * Get shell to use, either plugin shell or application shell
  342. *
  343. * All paths in the shellPaths property are searched.
  344. * shell, shellPath and shellClass properties are taken into account.
  345. *
  346. * @param string $plugin Optionally the name of a plugin
  347. * @return mixed False if no shell could be found or an object on success
  348. * @access protected
  349. */
  350. function _getShell($plugin = null) {
  351. foreach ($this->shellPaths as $path) {
  352. $this->shellPath = $path . $this->shell . '.php';
  353. $pluginShellPath = DS . $plugin . DS . 'vendors' . DS . 'shells' . DS;
  354. if ((strpos($path, $pluginShellPath) !== false || !$plugin) && file_exists($this->shellPath)) {
  355. $loaded = true;
  356. break;
  357. }
  358. }
  359. if (!isset($loaded)) {
  360. return false;
  361. }
  362. if (!class_exists('Shell')) {
  363. require CONSOLE_LIBS . 'shell.php';
  364. }
  365. if (!class_exists($this->shellClass)) {
  366. require $this->shellPath;
  367. }
  368. if (!class_exists($this->shellClass)) {
  369. return false;
  370. }
  371. $Shell = new $this->shellClass($this);
  372. return $Shell;
  373. }
  374. /**
  375. * Prompts the user for input, and returns it.
  376. *
  377. * @param string $prompt Prompt text.
  378. * @param mixed $options Array or string of options.
  379. * @param string $default Default input value.
  380. * @return Either the default value, or the user-provided input.
  381. * @access public
  382. */
  383. function getInput($prompt, $options = null, $default = null) {
  384. if (!is_array($options)) {
  385. $printOptions = '';
  386. } else {
  387. $printOptions = '(' . implode('/', $options) . ')';
  388. }
  389. if ($default === null) {
  390. $this->stdout($prompt . " $printOptions \n" . '> ', false);
  391. } else {
  392. $this->stdout($prompt . " $printOptions \n" . "[$default] > ", false);
  393. }
  394. $result = fgets($this->stdin);
  395. if ($result === false) {
  396. exit;
  397. }
  398. $result = trim($result);
  399. if ($default != null && empty($result)) {
  400. return $default;
  401. }
  402. return $result;
  403. }
  404. /**
  405. * Outputs to the stdout filehandle.
  406. *
  407. * @param string $string String to output.
  408. * @param boolean $newline If true, the outputs gets an added newline.
  409. * @return integer Returns the number of bytes output to stdout.
  410. * @access public
  411. */
  412. function stdout($string, $newline = true) {
  413. if ($newline) {
  414. return fwrite($this->stdout, $string . "\n");
  415. } else {
  416. return fwrite($this->stdout, $string);
  417. }
  418. }
  419. /**
  420. * Outputs to the stderr filehandle.
  421. *
  422. * @param string $string Error text to output.
  423. * @access public
  424. */
  425. function stderr($string) {
  426. fwrite($this->stderr, $string);
  427. }
  428. /**
  429. * Parses command line options
  430. *
  431. * @param array $params Parameters to parse
  432. * @access public
  433. */
  434. function parseParams($params) {
  435. $this->__parseParams($params);
  436. $defaults = array('app' => 'app', 'root' => dirname(dirname(dirname(__FILE__))), 'working' => null, 'webroot' => 'webroot');
  437. $params = array_merge($defaults, array_intersect_key($this->params, $defaults));
  438. $isWin = false;
  439. foreach ($defaults as $default => $value) {
  440. if (strpos($params[$default], '\\') !== false) {
  441. $isWin = true;
  442. break;
  443. }
  444. }
  445. $params = str_replace('\\', '/', $params);
  446. if (isset($params['working'])) {
  447. $params['working'] = trim($params['working']);
  448. }
  449. if (!empty($params['working']) && (!isset($this->args[0]) || isset($this->args[0]) && $this->args[0]{0} !== '.')) {
  450. if (empty($this->params['app']) && $params['working'] != $params['root']) {
  451. $params['root'] = dirname($params['working']);
  452. $params['app'] = basename($params['working']);
  453. } else {
  454. $params['root'] = $params['working'];
  455. }
  456. }
  457. if ($params['app'][0] == '/' || preg_match('/([a-z])(:)/i', $params['app'], $matches)) {
  458. $params['root'] = dirname($params['app']);
  459. } elseif (strpos($params['app'], '/')) {
  460. $params['root'] .= '/' . dirname($params['app']);
  461. }
  462. $params['app'] = basename($params['app']);
  463. $params['working'] = rtrim($params['root'], '/');
  464. if (!$isWin || !preg_match('/^[A-Z]:$/i', $params['app'])) {
  465. $params['working'] .= '/' . $params['app'];
  466. }
  467. if (!empty($matches[0]) || !empty($isWin)) {
  468. $params = str_replace('/', '\\', $params);
  469. }
  470. $this->params = array_merge($this->params, $params);
  471. }
  472. /**
  473. * Helper for recursively parsing params
  474. *
  475. * @return array params
  476. * @access private
  477. */
  478. function __parseParams($params) {
  479. $count = count($params);
  480. for ($i = 0; $i < $count; $i++) {
  481. if (isset($params[$i])) {
  482. if ($params[$i]{0} === '-') {
  483. $key = substr($params[$i], 1);
  484. $this->params[$key] = true;
  485. unset($params[$i]);
  486. if (isset($params[++$i])) {
  487. if ($params[$i]{0} !== '-') {
  488. $this->params[$key] = str_replace('"', '', $params[$i]);
  489. unset($params[$i]);
  490. } else {
  491. $i--;
  492. $this->__parseParams($params);
  493. }
  494. }
  495. } else {
  496. $this->args[] = $params[$i];
  497. unset($params[$i]);
  498. }
  499. }
  500. }
  501. }
  502. /**
  503. * Removes first argument and shifts other arguments up
  504. *
  505. * @return mixed Null if there are no arguments otherwise the shifted argument
  506. * @access public
  507. */
  508. function shiftArgs() {
  509. return array_shift($this->args);
  510. }
  511. /**
  512. * Shows console help
  513. *
  514. * @access public
  515. */
  516. function help() {
  517. $this->clear();
  518. $this->stdout("\nWelcome to CakePHP v" . Configure::version() . " Console");
  519. $this->stdout("---------------------------------------------------------------");
  520. $this->stdout("Current Paths:");
  521. $this->stdout(" -app: ". $this->params['app']);
  522. $this->stdout(" -working: " . rtrim($this->params['working'], DS));
  523. $this->stdout(" -root: " . rtrim($this->params['root'], DS));
  524. $this->stdout(" -core: " . rtrim(CORE_PATH, DS));
  525. $this->stdout("");
  526. $this->stdout("Changing Paths:");
  527. $this->stdout("your working path should be the same as your application path");
  528. $this->stdout("to change your path use the '-app' param.");
  529. $this->stdout("Example: -app relative/path/to/myapp or -app /absolute/path/to/myapp");
  530. $this->stdout("\nAvailable Shells:");
  531. $shellList = array();
  532. foreach ($this->shellPaths as $path) {
  533. if (!is_dir($path)) {
  534. continue;
  535. }
  536. $shells = App::objects('file', $path);
  537. if (empty($shells)) {
  538. continue;
  539. }
  540. if (preg_match('@plugins[\\\/]([^\\\/]*)@', $path, $matches)) {
  541. $type = Inflector::camelize($matches[1]);
  542. } elseif (preg_match('@([^\\\/]*)[\\\/]vendors[\\\/]@', $path, $matches)) {
  543. $type = $matches[1];
  544. } elseif (strpos($path, CAKE_CORE_INCLUDE_PATH . DS . 'cake') === 0) {
  545. $type = 'CORE';
  546. } else {
  547. $type = 'app';
  548. }
  549. foreach ($shells as $shell) {
  550. if ($shell !== 'shell.php') {
  551. $shell = str_replace('.php', '', $shell);
  552. $shellList[$shell][$type] = $type;
  553. }
  554. }
  555. }
  556. if ($shellList) {
  557. ksort($shellList);
  558. if (DS === '/') {
  559. $width = exec('tput cols') - 2;
  560. }
  561. if (empty($width)) {
  562. $width = 80;
  563. }
  564. $columns = max(1, floor($width / 30));
  565. $rows = ceil(count($shellList) / $columns);
  566. foreach ($shellList as $shell => $types) {
  567. sort($types);
  568. $shellList[$shell] = str_pad($shell . ' [' . implode ($types, ', ') . ']', $width / $columns);
  569. }
  570. $out = array_chunk($shellList, $rows);
  571. for ($i = 0; $i < $rows; $i++) {
  572. $row = '';
  573. for ($j = 0; $j < $columns; $j++) {
  574. if (!isset($out[$j][$i])) {
  575. continue;
  576. }
  577. $row .= $out[$j][$i];
  578. }
  579. $this->stdout(" " . $row);
  580. }
  581. }
  582. $this->stdout("\nTo run a command, type 'cake shell_name [args]'");
  583. $this->stdout("To get help on a specific command, type 'cake shell_name help'");
  584. }
  585. /**
  586. * Stop execution of the current script
  587. *
  588. * @param $status see http://php.net/exit for values
  589. * @return void
  590. * @access protected
  591. */
  592. function _stop($status = 0) {
  593. exit($status);
  594. }
  595. }
  596. if (!defined('DISABLE_AUTO_DISPATCH')) {
  597. $dispatcher = new ShellDispatcher($argv);
  598. }