*/ /** Allow to interract with controllers and models from the CLI */ class cli { /** Run in CLI mode with parameters Example of cli code : #!/usr/bin/php5 run(); */ public function run () { global $argv; $launcher = $argv[0]; chdir (dirname ($argv[0])."/.."); array_shift ($argv); if (isset ($argv[0]) && $argv[0] === "-h") { echo "Execute in CLI a controller or a model (in expert mode)\n"; echo " $launcher -h : display this help\n"; echo " $launcher -list : display controllers\n"; echo " $launcher -expert -list : display controllers and models\n"; echo " $launcher -listmethods : \n"; echo " display the methods available the controller class\n"; echo " $launcher -expert -listmethods :\n"; echo " display the methods available the model or controller class\n"; echo " $launcher -listmethodsdetails : \n"; echo " display the methods available the controller class\n"; echo " $launcher -expert -listmethodsdetails :\n"; echo " display the methods available the model or controller class\n"; echo " $launcher [args]\n"; echo " execute the method with the provided args\n"; echo " $launcher -expert [args]\n"; echo " execute the method with the provided args\n"; echo "You can replace ONE arg by a dash (-) to read from stdin\n"; exit; } $EXPERT = FALSE; if (isset ($argv[0]) && $argv[0] === "-expert") { $EXPERT = TRUE; array_shift ($argv); } // List the controllers and the models if the expert mode is activated $files = glob ("controllers/*.php"); if ($EXPERT) $files = array_merge ($files, glob ("models/*.php")); if (count ($files) === 0 && $EXPERT === FALSE) die ("No controllers available in ".getcwd()."\n"); if (count ($files) === 0 && $EXPERT === TRUE) die ("No controllers/models available in ".getcwd()."\n"); foreach ($files as $file) $classes[$file] = substr (strstr ($file, "_"), 1, -4); if (isset ($argv[0]) && $argv[0] === "-list") { // Lists the classes available in controllers and models if expert mode echo "List of classes available :\n"; echo " ".implode ("\n ", $classes)."\n"; echo "Usage : ".$launcher; if ($EXPERT) echo " -expert"; echo " -listmethods \n"; exit; } if (isset ($argv[0]) && $argv[0] === "-listmethods" || isset ($argv[0]) && $argv[0] === "-listmethodsdetails") { // Lists the methods of a class if (!isset ($argv[1])) die ("Missing parameter 'class'\n"); $class = $argv[1]; if (!in_array ($class, $classes)) die ("Unknown class '$class'\n"); $file = reset (array_keys ($classes, $class)); require_once ($file); $refclass = new ReflectionClass ($class); // Look at constructor parameters // PARAMETERS MUST NOT BE OPTIONNAL $constParams = ""; try { $r = new ReflectionMethod ($class, "__construct"); $params = $r->getParameters(); foreach ($params as $param) { $constParams .= " "; $constParams .= " <"; $constParams .= $param->name; $constParams .= ">"; } } catch (Exception $e) { // No constructor } // Look at methods $methods = $refclass->getMethods(); echo "List of methods available in the class '$class' :\n"; foreach ($methods as $key=>$method) { if ($method->name === "__construct") continue; if ($key > 0) echo "\n"; echo " ".$method->name.$constParams; $r = new ReflectionMethod ($class, $method->name); $params = $r->getParameters(); foreach ($params as $param) { echo " "; if ($param->isOptional()) echo "["; else echo " <"; echo $param->name; if ($param->isOptional()) echo "]"; else echo ">"; } if ($argv[0] === "-listmethodsdetails") { echo "\n"; echo trim (substr ($method->getDocComment(), 3, -2)); } echo "\n"; } exit; } // Execution of the class->method if (!isset ($argv[0])) die ("No class to execute provided\n"); $class = $argv[0]; if (!in_array ($class, $classes)) die ("Unknown class '$class'\n"); array_shift ($argv); $file = reset (array_keys ($classes, $class)); require_once ($file); if (!isset ($argv[0])) die ("No method for class '$class' to execute\n"); $method = $argv[0]; array_shift ($argv); $refclass = new ReflectionClass ($class); $methods = $refclass->getMethods(); $found = FALSE; foreach ($methods as $meth) { if ($meth->name === $method) { $found = TRUE; break; } } if ($found === FALSE) die ("Method '$method' not available in class '$class'\n"); $min = 0; $max = 0; try { $r = new ReflectionMethod ($class, "__construct"); $paramsConst = $r->getParameters(); $min = $max = count ($paramsConst); } catch (Exception $e) { // No constructor available in class } $r = new ReflectionMethod ($class, $method); $params = $r->getParameters(); foreach ($params as $param) { if (!$param->isOptional()) $min++; $max++; } unset ($r); if (count ($argv) < $min) die ("Not enough parameters provided to method\n"); if (in_array ("-", $argv)) { $key = reset (array_keys ($argv, "-")); $argv[$key] = file_get_contents ("php://stdin"); } // Convert "toto=ror&ypyp=oo" arg to array("toto"=>"ror","ypyp"=>"oo") // (Array management in CLI) foreach ($argv as $key=>$arg) { $val = null; parse_str ($arg, $val); if (count ($val) === 1 && reset ($val) === "") $val = $arg; $argv[$key] = $val; } // Manage a parameter in the constructor of the class $paramConst = array (); if (count ($paramsConst) > 0) { $paramConst = array_slice ($argv, 0, count ($paramsConst)); $argv = array_slice ($argv, count ($paramsConst)); } try { $classReflection = new ReflectionClass($class); $r = $classReflection->newInstanceArgs($paramConst); $s = call_user_func_array(array($r, $method), $argv); var_dump ($s); } catch (Exception $e) { file_put_contents("php://stderr", $e->getMessage()."\n"); if ($EXPERT) file_put_contents ("php://stderr", $e->getTraceAsString()."\n"); } exit; } }