a tiny mvc framework for php using php-activerecord
at v1 184 lines 4.3 kB view raw
1<?php 2/* 3 based on phpa by David Phillips <david@acz.org> 4 http://david.acz.org/phpa/ says "This software is public domain." 5*/ 6 7namespace HalfMoon; 8 9class Console { 10 private $args; 11 public static $have_readline; 12 public $line; 13 public $history; 14 15 public function __construct($args) { 16 $this->args = $args; 17 18 Console::$have_readline = function_exists("readline"); 19 20 for ($x = 1; $x < count($args); $x++) 21 switch ($args[$x]) { 22 case "-h": 23 case "--help": 24 $this->usage(); 25 break; 26 27 default: 28 if (substr($args[$x], 0, 1) == "-") 29 $this->usage(); 30 elseif (defined("HALFMOON_ENV")) 31 $this->usage(); 32 else 33 define("HALFMOON_ENV", $args[$x]); 34 } 35 36 require_once(__DIR__ . "/../halfmoon.php"); 37 38 error_reporting(E_ALL | E_STRICT); 39 40 ini_set("error_log", NULL); 41 ini_set("log_errors", 1); 42 ini_set("html_errors", 0); 43 ini_set("display_errors", 0); 44 45 while (ob_get_level()) 46 ob_end_clean(); 47 48 ob_implicit_flush(true); 49 50 /* TODO: forcibly load models so they're in the tab-completion cache */ 51 52 print "Loaded " . HALFMOON_ENV . " environment (halfmoon)\n"; 53 54 $this->loop(); 55 } 56 57 public function usage() { 58 die("usage: " . $this->args[0] . " [-h] [environment]\n"); 59 } 60 61 public function readline_complete($line, $pos, $cursor) { 62 $consts = array_keys(get_defined_constants()); 63 $vars = array_keys($GLOBALS); 64 $funcs = get_defined_functions(); 65 $classes = get_declared_classes(); 66 67 return array_merge($consts, $vars, $funcs, $classes); 68 } 69 70 public function loop() { 71 for (;;) { 72 if (Console::$have_readline) { 73 readline_completion_function(array($this, 74 "readline_complete")); 75 $this->line = @readline(">> "); 76 } else { 77 print ">> "; 78 $this->line = trim(fgets(STDIN)); 79 } 80 81 if ($this->line === false || 82 (!Console::$have_readline && feof(STDIN))) { 83 echo "\n"; 84 break; 85 } 86 87 if (strlen($this->line) == 0) 88 continue; 89 90 if (Console::$have_readline && (!isset($this->history) || 91 ($this->line != $this->history))) { 92 readline_add_history($this->line); 93 $this->history = $this->line; 94 } 95 96 if ($this->is_immediate($this->line)) 97 $this->line = "return (" . $this->line . ")"; 98 99 ob_start(); 100 101 try { 102 $ret = @eval($this->line . ";"); 103 104 if (ob_get_length() == 0) { 105 if (is_bool($ret)) 106 echo ($ret ? "true" : "false"); 107 else if (is_string($ret)) 108 echo "'" . addcslashes($ret, "\0..\37\177..\377") . "'"; 109 else if (!is_null($ret)) 110 print_r($ret); 111 } 112 113 unset($ret); 114 } catch (\Exception $exception) { 115 $title = get_class($exception); 116 117 /* activerecord includes the stack trace in the message, so strip 118 * it out */ 119 if ($exception instanceof \ActiveRecord\DatabaseException) 120 $title .= ": " . preg_replace("/\nStack trace:.*/s", "", 121 $exception->getMessage()); 122 elseif ($exception->getMessage()) 123 $title .= ": " . $exception->getMessage() . " in " 124 . $exception->getFile() . " on line " 125 . $exception->getLine(); 126 127 print $title . "\n"; 128 129 foreach ($exception->getTrace() as $call) 130 print " " 131 . (isset($call["file"]) ? $call["file"] : $call["class"]) 132 . ":" 133 . (isset($call["line"]) ? $call["line"] : "") 134 . " in " . $call["function"] . "()\n"; 135 } 136 137 $out = ob_get_contents(); 138 ob_end_clean(); 139 140 if ((strlen($out) > 0) && (substr($out, -1) != "\n")) 141 $out .= "\n"; 142 143 echo $out; 144 145 unset($out); 146 } 147 } 148 149 public function is_immediate($line) { 150 $skip = array("class", "declare", "die", "echo", "exit", "for", 151 "foreach", "function", "global", "if", "include", 152 "include_once", "print", "require", "require_once", 153 "return", "static", "switch", "unset", "while"); 154 $okeq = array("===", "!==", "==", "!=", "<=", ">="); 155 $code = ""; 156 $sq = false; 157 $dq = false; 158 for ($i = 0; $i < strlen($line); $i++) { 159 $c = $line{$i}; 160 if ($c == "'") 161 $sq = !$sq; 162 else if ($c == '"') 163 $dq = !$dq; 164 else if (($sq) || ($dq)) { 165 if ($c == "\\") 166 $i++; 167 } else 168 $code .= $c; 169 } 170 171 $code = str_replace($okeq, "", $code); 172 173 if (strcspn($code, ";{=") != strlen($code)) 174 return false; 175 176 foreach (preg_split("/[^A-Za-z0-9_]/", $code) as $i) 177 if (in_array($i, $skip)) 178 return false; 179 180 return true; 181 } 182} 183 184?>