#!/usr/bin/env php _exec(); } public function __construct() { error_reporting(E_ALL | E_STRICT); ini_set('display_errors', true); ini_set('html_errors', false); $this->_setArgv(); $this->_setVendor(); $this->_setSystem(); $this->_setVerbose(); $this->_setIncludePath(); $this->_setConfig(); } protected function _setArgv() { $this->_argv = empty($_SERVER['argv']) ? array(0 => '') : $_SERVER['argv']; } protected function _setVendor() { // get the last part of the command used to invoke this script and // use as the vendor name. e.g., './scripts/solar' => 'solar' $path = explode(DIRECTORY_SEPARATOR, $this->_argv[0]); $this->_vendor = end($path); // change vendor name to a class name prefix: // 'foo' => 'Foo' // 'foo-bar' => 'FooBar' // 'foo_bar' => 'FooBar' $this->_vendor = str_replace(array('-', '_'), ' ', $this->_vendor); $this->_vendor = ucwords($this->_vendor); $this->_vendor = str_replace(' ', '', $this->_vendor); } protected function _setSystem() { // what is the solar system root, if anywhere? $dirs = array( // symlink solar "/source/solar/script/solar", // symlink vendor "/source/{$this->_vendor}/script/{$this->_vendor}", // copy solar "/script/solar", // copy vendor "/script/{$this->_vendor}", ); $this->_system = false; $file = __FILE__; foreach ($dirs as $dir) { // make comparison windows-friendly $dir = str_replace('/', DIRECTORY_SEPARATOR, $dir); $len = -1 * strlen($dir); if (substr($file, $len) == $dir) { $this->_system = substr($file, 0, $len); break; } } } protected function _setVerbose() { $this->_verbose = false; foreach ($this->_argv as $val) { $long = $val == '--verbose'; $short = strlen($val) > 1 // at least 2 chars && $val[0] == '-' // short option && $val[1] != '-' // not long option && strpos($val, 'v'); // 'v' in there somewhere if ($long || $short) { // found the argument $this->_verbose = true; break; } } } /** * * Discover and set the include-path. This is *not* the same as a php.ini * include-path, in the sense that '.' and '..' will be fully-resolved * and will not be used in relation to the current PHP script's file path. * */ protected function _setIncludePath() { if ($this->_system) { $include = $this->_system . DIRECTORY_SEPARATOR . 'include' . PATH_SEPARATOR . '.'; } else { $include = get_include_path(); } // manually look for a --include-path argument that overrides the default $found = false; foreach ($this->_argv as $val) { if ($val == '--include-path') { // found the argument $found = true; // reset the default in preparation for the next argument $include = false; continue; } if ($found && substr($val, 0, 1) != '-') { $include = $val; break; } if (substr($val, 0, 15) == '--include-path=') { $found = true; $include = substr($val, 15); break; } } // if there was an --include-path but no param, that's a failure if ($found && ! $include) { echo "Please specify an include-path after the --include-path option." . PHP_EOL; exit(1); } set_include_path($include); if ($this->_verbose) { echo "Using include_path '" . get_include_path() . "'." . PHP_EOL; } } /** * * Discover the config file. * * Override with the value of --config, if any. * */ protected function _setConfig() { if ($this->_system) { $config = $this->_system . DIRECTORY_SEPARATOR . 'config.php'; } else { $config = false; } // manually look for a --config argument that overrides the default $found = false; foreach ($this->_argv as $val) { if ($val == '--config') { // found the argument $found = true; // reset the default in preparation for the next argument $config = false; continue; } if ($found && substr($val, 0, 1) != '-') { $config = $val; break; } if (substr($val, 0, 9) == '--config=') { $found = true; $config = substr($val, 9); break; } } // if there was a --config but no param, that's a failure if ($found && ! $config) { echo "Please specify a config file path after the --config option." . PHP_EOL; exit(1); } // was there a config file at all? if ($config) { $realpath = realpath($config); if ($realpath) { $this->_config = $realpath; $text = "Using config file '$realpath'." . PHP_EOL; } else { echo "Could not resolve real path to config file '$config'." . PHP_EOL; exit(1); } } else { $text = "Not using a config file." . PHP_EOL; } if ($this->_verbose) { echo $text; } } /** * Main */ protected function _exec() { // Start Solar with the requested config file (if any) require 'Solar.php'; Solar::start($this->_config); // is there a config for the console? if (Solar_Config::get('Solar_Controller_Console')) { // use the config as-is and create the console $console = Solar::factory('Solar_Controller_Console'); } else { // create a config for the console $config = array( 'classes' => "{$this->_vendor}_Cli", 'default' => 'base' ); // create the console $console = Solar::factory('Solar_Controller_Console', $config); } // execute the requested command try { $console->exec(); Solar::stop(); exit(0); } catch (Exception $e) { // stop Solar Solar::stop(); // find an exit code, if any $exit = false; if ($e instanceof Solar_Exception) { $info = $e->getInfo(); if (array_key_exists('exit', $info)) { $exit = (int) $info['exit']; } } // disallow empty or zero exit codes if (! $exit) { $exit = 1; } // how to print the exception message? switch (true) { case $e instanceof Solar_Controller_Command_Exception_InvalidOptions: echo $e->getMessageInvalid(); break; case $e instanceof Solar_Controller_Console_Exception: echo $e->getMessage(); break; case $e instanceof Solar_Exception: if ($this->_verbose || $e->getCode() == $e->getMessage()) { echo $e; } else { echo $e->getMessage(); } break; default: echo $e; } echo PHP_EOL; exit((int) $exit); } } }