PageRenderTime 60ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/classes/console.php

http://github.com/fuel/oil
PHP | 306 lines | 235 code | 44 blank | 27 comment | 23 complexity | dd9c395175c837117824dc978505353e MD5 | raw file
  1. <?php
  2. /**
  3. * Fuel is a fast, lightweight, community driven PHP 5.4+ framework.
  4. *
  5. * @package Fuel
  6. * @version 1.9-dev
  7. * @author Fuel Development Team
  8. * @license MIT License
  9. * @copyright 2010 - 2019 Fuel Development Team
  10. * @link https://fuelphp.com
  11. */
  12. namespace Oil;
  13. /**
  14. * Oil\Console Class
  15. *
  16. * @package Fuel
  17. * @subpackage Oil
  18. * @category Core
  19. * @author Phil Sturgeon
  20. */
  21. class Console
  22. {
  23. protected const MAX_HISTORY = 99;
  24. protected $history = array();
  25. public function __construct()
  26. {
  27. error_reporting(E_ALL | E_STRICT);
  28. ini_set("error_log", NULL);
  29. ini_set("log_errors", 1);
  30. ini_set("html_errors", 0);
  31. ini_set("display_errors", 0);
  32. while (ob_get_level())
  33. {
  34. ob_end_clean();
  35. }
  36. ob_implicit_flush(true);
  37. // And, go!
  38. self::main();
  39. }
  40. public static function help()
  41. {
  42. $output = <<<HELP
  43. Usage:
  44. php oil [c|console]
  45. Description:
  46. Opens a commandline console to your FuelPHP installation. This allows
  47. you to run any FuelPHP command interactively.
  48. Examples:
  49. php oil console
  50. Documentation:
  51. https://fuelphp.com/docs/packages/oil/console.html
  52. HELP;
  53. \Cli::write($output);
  54. }
  55. protected function push_history($line)
  56. {
  57. // delimit each line, allowing for copy & paste of history back into Console
  58. $line .= ';';
  59. array_push($this->history, $line);
  60. $this->history = array_slice($this->history, -self::MAX_HISTORY);
  61. }
  62. protected function pop_history()
  63. {
  64. array_pop($this->history);
  65. }
  66. protected function show_history()
  67. {
  68. \Cli::write($this->history);
  69. \Cli::write('');
  70. }
  71. protected function main()
  72. {
  73. \Cli::write(sprintf(
  74. 'Fuel %s - PHP %s (%s) (%s) [%s]',
  75. \Fuel::VERSION,
  76. phpversion(),
  77. php_sapi_name(),
  78. self::build_date(),
  79. PHP_OS
  80. ));
  81. \Cli::write(array(
  82. '',
  83. 'Commands',
  84. ':q | quit - exit the console',
  85. ':h | history - show transcript',
  86. ''
  87. ));
  88. // Loop until they break it
  89. while (TRUE)
  90. {
  91. if (\Cli::$readline_support)
  92. {
  93. readline_completion_function(array(__CLASS__, 'tab_complete'));
  94. }
  95. if ( ! $__line = rtrim(trim(trim(\Cli::input('>>> ')), PHP_EOL), ';'))
  96. {
  97. continue;
  98. }
  99. if ($__line == ':q' or $__line == 'quit')
  100. {
  101. break;
  102. }
  103. elseif ($__line == ':h' or $__line == 'history')
  104. {
  105. $this->show_history();
  106. continue;
  107. }
  108. // Add this line to history
  109. $this->push_history($__line);
  110. if (\Cli::$readline_support)
  111. {
  112. readline_add_history($__line);
  113. }
  114. if (self::is_immediate($__line))
  115. {
  116. $__line = "return ($__line)";
  117. }
  118. ob_start();
  119. // Unset the previous line and execute the new one
  120. $random_ret = \Str::random();
  121. try
  122. {
  123. $ret = eval("unset(\$__line); $__line;");
  124. }
  125. catch(\Exception $e)
  126. {
  127. // Remove last (bad) line from history
  128. $this->pop_history();
  129. $ret = $random_ret;
  130. $__line = $e->getMessage();
  131. }
  132. catch(\Error $e)
  133. {
  134. // Remove last (bad) line from history
  135. $this->pop_history();
  136. $ret = $random_ret;
  137. $__line = $e->getMessage();
  138. }
  139. // Error was returned
  140. if ($ret === $random_ret)
  141. {
  142. \Cli::error('Parse Error - ' . $__line);
  143. \Cli::beep();
  144. }
  145. if (ob_get_length() == 0)
  146. {
  147. if (is_bool($ret))
  148. {
  149. echo $ret ? 'true' : 'false';
  150. }
  151. elseif (is_string($ret))
  152. {
  153. echo addcslashes($ret, "\0..\11\13\14\16..\37\177..\377");
  154. }
  155. elseif ( ! is_null($ret))
  156. {
  157. print_r($ret);
  158. }
  159. }
  160. unset($ret);
  161. $out = ob_get_contents();
  162. ob_end_clean();
  163. if ((strlen($out) > 0) && (substr($out, -1) != PHP_EOL))
  164. {
  165. $out .= PHP_EOL;
  166. }
  167. echo $out;
  168. unset($out);
  169. }
  170. }
  171. private static function is_immediate($line)
  172. {
  173. $skip = array(
  174. 'class', 'declare', 'die', 'echo', 'exit', 'for',
  175. 'foreach', 'function', 'global', 'if', 'include',
  176. 'include_once', 'print', 'require', 'require_once',
  177. 'return', 'static', 'switch', 'unset', 'while',
  178. );
  179. $okeq = array('===', '!==', '==', '!=', '<=', '>=');
  180. $code = '';
  181. $sq = false;
  182. $dq = false;
  183. for ($i = 0; $i < strlen($line); $i++)
  184. {
  185. $c = $line[$i];
  186. if ($c == "'")
  187. {
  188. $sq = !$sq;
  189. }
  190. elseif ($c == '"')
  191. {
  192. $dq = !$dq;
  193. }
  194. elseif ( ($sq) || ($dq) && $c == "\\")
  195. {
  196. ++$i;
  197. }
  198. else
  199. {
  200. $code .= $c;
  201. }
  202. }
  203. $code = str_replace($okeq, '', $code);
  204. if (strcspn($code, ';{=') != strlen($code))
  205. {
  206. return false;
  207. }
  208. $kw = preg_split("/[^a-z0-9_]/i", $code);
  209. foreach ($kw as $i)
  210. {
  211. if (in_array($i, $skip))
  212. {
  213. return false;
  214. }
  215. }
  216. return true;
  217. }
  218. public static function tab_complete($line, $pos, $cursor)
  219. {
  220. $const = array_keys(get_defined_constants());
  221. $var = array_keys($GLOBALS);
  222. $func = get_defined_functions();
  223. foreach ($func["user"] as $i)
  224. {
  225. $func["internal"][] = $i;
  226. }
  227. $func = $func["internal"];
  228. return array_merge($const, $var, $func);
  229. }
  230. private static function build_date()
  231. {
  232. ob_start();
  233. phpinfo(INFO_GENERAL);
  234. $x = ob_get_contents();
  235. ob_end_clean();
  236. $x = strip_tags($x);
  237. $x = explode("\n", $x); // PHP_EOL doesn't work on Windows
  238. $s = array('Build Date => ', 'Build Date ');
  239. foreach ($x as $i)
  240. {
  241. foreach ($s as $j)
  242. {
  243. if (substr($i, 0, strlen($j)) == $j)
  244. {
  245. return trim(substr($i, strlen($j)));
  246. }
  247. }
  248. }
  249. return '???';
  250. }
  251. }
  252. /* End of file oil/classes/console.php */