5 * handles the cli features of Flexy Framework.
10 * $x = new HTML_FlexyFramework_Cli($ff);
11 * $x->cliHelp(); // summary of all classes which can be run with cli.
12 * (contain static $cli_desc)
13 * $x->cliParse($classname);
17 class HTML_FlexyFramework_Cli
21 * Default options that allow modification of the framewoek behaviour
27 static $cli_opts = array(
29 // this is a flag argument
30 'pman-nodatabase' => array(
31 'desc' => 'Turn off database',
43 var $ff; // the Framework instance.
46 function __construct($ff)
51 * looks for Cli.php files and runs available() on them
52 * this should return a list of classes that can be used.
53 * - we should the load each one, and find the summary..
60 $fn = basename($_SERVER["SCRIPT_FILENAME"]);
62 echo "\n-------------------------------------------------
63 FlexyFramework Cli Application Usage:
65 #php -d include_path=.:/var/www/pear $fn [COMMAND] --help
67 #php $fn [COMMAND] --help
69 -------------------------------------------------
74 //$this->cliShortHelp('Database');
77 $p = dirname(realpath($_SERVER["SCRIPT_FILENAME"]));
78 $pr = $this->ff->project;
80 $this->cliHelpSearch($p,$pr);
81 if (!empty($this->ff->projectExtends)) {
82 foreach($this->ff->projectExtends as $pr) {
83 $this->cliHelpSearch($p,$pr);
92 function cliHelpSearch($p,$pr, $path=false) {
96 $full_path = array($p,$pr);
97 $class_path = array();
98 if ($path !== false) {
99 $full_path= array_merge($full_path, $path);
100 $class_path = array_merge($class_path, $path);
102 //print_r("CHKDIR: ". implode('/', $full_path)."\n");
104 foreach(scandir(implode('/', $full_path)) as $d) {
106 if (!strlen($d) || $d[0] == '.') {
116 //print_r("CHK: " . implode('/', $chk)."\n");
117 // is it a file.. and .PHP...
118 if (!is_dir(implode('/', $chk))) {
119 if (!preg_match('/\.php$/',$d)) {
122 $clp[] = preg_replace('/\.php$/','', $d);
124 //print_r("CLP: " . implode('/', $clp)."\n");
125 $this->cliShortHelp(implode('/', $clp ));
128 // skip special directories..
129 if ($d == 'templates') {
132 if ($d == 'DataObjects') {
138 // otherwise recurse...
139 //print_r("RECURSE: " . implode('/', $clp)."\n");
141 $this->cliHelpSearch($p,$pr, $clp);
146 //print_r("COMPLETE: ". implode('/', $full_path)."\n");
157 * creates an instance of all the CLI classes and prints out class + title..
160 function cliShortHelp($p) {
161 ////print_r("CHKFILE: $p\n ");
162 list($classname,$subRequest) = $this->ff->requestToClassName($p,FALSE);
163 //var_dump($classname);
164 // does it have a description.
166 $cls = new ReflectionClass($classname);
167 $val = $cls->getStaticPropertyValue('cli_desc');
168 } catch (Exception $e) {
174 echo str_pad($p,40," ") . $val ."\n";
181 * cliParse - parse command line arguments, and return the values.
182 * Will die with help message if --help or error is found..
184 * @param {String} $classname name of class - should be loaded..
185 * @return {Array|false} array of key=>value arguments.. or false if not parsed
188 function cliParse($classname)
191 // cli static $classname::$cli_opts
194 // look up the parent tree for core opts.
196 //var_dump($classname);
197 $cls = new ReflectionClass($classname);
198 if (method_exists($classname, 'cli_opts')) {
199 $val = $classname::cli_opts();
201 $ar = $cls->getStaticProperties();
202 if (isset($ar['cli_opts'])) {
203 //echo "getting cli opts?\n";
204 $val = $cls->getStaticPropertyValue('cli_opts');
208 $val = is_array($val) ? $val : array();
209 while ($cls = $cls->getParentClass()) {
210 //var_dump($cls->name);
214 if (method_exists($cls->name, 'cli_opts')) {
216 $vadd = $cn::cli_opts();
218 $ar = $cls->getStaticProperties();
219 if (isset($ar['cli_opts'])) {
220 $vadd = $cls->getStaticPropertyValue('cli_opts');
224 $val = array_merge($val, is_array($vadd) ? $vadd : array() );
225 } catch (ReflectionException $e) {
232 } catch (ReflectionException $e) {
234 echo "cliParse:Warning: {$e->getMessage()}\n";
241 $val = array_merge(self::$cli_opts, $val);
244 require_once 'Console/Getargs.php';
245 $ar = $_SERVER['argv'];
246 $call = array(array_shift($ar)); // remove index.php
247 $call[] = array_shift($ar); // remove our class...
250 $newargs = Console_Getargs::factory($val, $ar);
252 if (!is_a($newargs, 'PEAR_Error')) {
253 return $newargs->getValues();
256 list($optional, $required, $params) = Console_Getargs::getOptionalRequired($val);
258 $helpHeader = 'Usage: php ' . implode (' ', $call) . ' '.
259 $optional . ' ' . $required . ' ' . $params . "\n\n";
262 if ($newargs->getCode() === CONSOLE_GETARGS_ERROR_USER) {
263 // User put illegal values on the command line.
264 echo Console_Getargs::getHelp($val,
265 $helpHeader, "\n\n".$newargs->getMessage(), 78, 4)."\n\n";
268 if ($newargs->getCode() === CONSOLE_GETARGS_HELP) {
270 echo Console_Getargs::getHelp($val,
271 $helpHeader, NULL, 78, 4)."\n\n";
275 die($newargs->getMessage());
283 * the framework can be run without a database even if it's configured.
284 * to support this, we need to handle things like
285 * --pman-nodatabase=1 on the command line.
288 * @returns array() - args, false - nothing matched / invalid, true = help!
292 function parseDefaultOpts()
294 require_once 'Console/Getargs.php';
295 $ar = $_SERVER['argv'];
296 $call = array(array_shift($ar)); // remove index.php
298 if (isset($ar[0]) && $ar[0][0] != '-') {
299 $call[] = array_shift($ar); // remove our class...
302 $val = self::$cli_opts;
304 $newargs = Console_Getargs::factory($val, $ar);
306 if (is_a($newargs, 'PEAR_Error')) {
307 list($optional, $required, $params) = Console_Getargs::getOptionalRequired($val);
309 $helpHeader = 'Usage: php ' . implode (' ', $call) . ' '.
310 $optional . ' ' . $required . ' ' . $params . "\n\n";
312 if ($newargs->getCode() === CONSOLE_GETARGS_ERROR_USER) {
313 // since we do not handle all the arguemnts here...
314 // skip errors if we find unknown arguments.
315 if (preg_match('/^Unknown argument/', $newargs->getMessage())) {
319 // User put illegal values on the command line.
320 echo Console_Getargs::getHelp($val,
321 $helpHeader, "\n\n".$newargs->getMessage(), 78, 4)."\n\n";
324 if ($newargs->getCode() === CONSOLE_GETARGS_HELP) {
327 echo Console_Getargs::getHelp($val,
328 $helpHeader, NULL, 78, 4)."\n\n";
331 return true;// help is handled later in the flow?
338 // now handle real arguments..
341 $ret = $newargs->getValues();
345 foreach($ret as $k=>$v) {
347 case 'pman-nodatabase':
348 echo "Turning off database\n";
349 $this->ff->nodatabase = true;
354 die("need to fix option $k");