. */ /** * Doctrine_Cli * * @package Doctrine * @subpackage Cli * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @link www.phpdoctrine.com * @since 1.0 * @version $Revision: 2761 $ * @author Jonathan H. Wage */ class Doctrine_Cli { protected $_tasks = array(), $_taskInstance = null, $_formatter = null, $_scriptName = null, $_message = null, $_config = array(); /** * __construct * * @param string $config * @return void */ public function __construct($config = array()) { $this->_config = $config; $this->_formatter = new Doctrine_Cli_AnsiColorFormatter(); $this->loadTasks(); } /** * notify * * @param string $notification * @return void */ public function notify($notification = null, $style = 'HEADER') { echo $this->_formatter->format($this->_taskInstance->getTaskName(), 'INFO') . ' - ' . $this->_formatter->format($notification, $style) . "\n"; } /** * notifyException * * @param string $exception * @return void */ public function notifyException($exception) { echo $this->_formatter->format($exception->getMessage(), 'ERROR') . "\n"; } /** * run * * @param string $args * @return void * @throws new Doctrine_Cli_Exception */ public function run($args) { try { $this->_run($args); } catch (Exception $exception) { $this->notifyException($exception); } } /** * _getTaskClassFromArgs * * Get the task class from an array of cli arguments * * @param string $args * @return void */ protected function _getTaskClassFromArgs($args) { $taskName = str_replace('-', '_', $args[1]); $taskClass = 'Doctrine_Task_' . Doctrine::classify($taskName); return $taskClass; } /** * _run * * @param string $args * @return void */ protected function _run($args) { $this->_scriptName = $args[0]; $arg1 = isset($args[1]) ? $args[1]:null; if ( ! $arg1 || $arg1 == 'help') { echo $this->printTasks(null, $arg1 == 'help' ? true:false); return; } if (isset($args[1]) && isset($args[2]) && $args[2] == 'help') { echo $this->printTasks($args[1], true); return; } $taskClass = $this->_getTaskClassFromArgs($args); if ( ! class_exists($taskClass)) { throw new Doctrine_Cli_Exception('Cli task could not be found: ' . $taskClass); } unset($args[0]); unset($args[1]); $this->_taskInstance = new $taskClass($this); $args = $this->prepareArgs($args); $this->_taskInstance->setArguments($args); try { if ($this->_taskInstance->validate()) { $this->_taskInstance->execute(); } else { echo $this->_formatter->format('Requires arguments missing!!', 'ERROR') . "\n\n"; echo $this->printTasks($arg1, true); } } catch (Exception $e) { throw new Doctrine_Cli_Exception($e->getMessage()); } } /** * prepareArgs * * @param string $args * @return array $prepared */ protected function prepareArgs($args) { $taskInstance = $this->_taskInstance; $args = array_values($args); // First lets load populate an array with all the possible arguments. required and optional $prepared = array(); $requiredArguments = $taskInstance->getRequiredArguments(); foreach ($requiredArguments as $key => $arg) { $prepared[$arg] = null; } $optionalArguments = $taskInstance->getOptionalArguments(); foreach ($optionalArguments as $key => $arg) { $prepared[$arg] = null; } // If we have a config array then lets try and fill some of the arguments with the config values if (is_array($this->_config) && !empty($this->_config)) { foreach ($this->_config as $key => $value) { if (array_key_exists($key, $prepared)) { $prepared[$key] = $value; } } } // Now lets fill in the entered arguments to the prepared array $copy = $args; foreach ($prepared as $key => $value) { if ( ! $value && !empty($copy)) { $prepared[$key] = $copy[0]; unset($copy[0]); $copy = array_values($copy); } } return $prepared; } /** * printTasks * * Prints an index of all the available tasks in the CLI instance * * @return void */ public function printTasks($task = null, $full = false) { $task = Doctrine::classify(str_replace('-', '_', $task)); $tasks = $this->getLoadedTasks(); echo $this->_formatter->format("Doctrine Command Line Interface", 'HEADER') . "\n\n"; foreach ($tasks as $taskName) { if ($task != null && strtolower($task) != strtolower($taskName)) { continue; } $className = 'Doctrine_Task_' . $taskName; $taskInstance = new $className(); $taskInstance->taskName = str_replace('_', '-', Doctrine::tableize($taskName)); $syntax = $this->_scriptName . ' ' . $taskInstance->getTaskName(); echo $this->_formatter->format($syntax, 'INFO'); if ($full) { echo " - " . $taskInstance->getDescription() . "\n"; $args = null; $requiredArguments = $taskInstance->getRequiredArgumentsDescriptions(); if ( ! empty($requiredArguments)) { foreach ($requiredArguments as $name => $description) { $args .= $this->_formatter->format($name, "ERROR"); if (isset($this->_config[$name])) { $args .= " - " . $this->_formatter->format($this->_config[$name], 'COMMENT'); } else { $args .= " - " . $description; } $args .= "\n"; } } $optionalArguments = $taskInstance->getOptionalArgumentsDescriptions(); if ( ! empty($optionalArguments)) { foreach ($optionalArguments as $name => $description) { $args .= $name . ' - ' . $description."\n"; } } if ($args) { echo "\n" . $this->_formatter->format('Arguments:', 'HEADER') . "\n" . $args; } } echo "\n"; } } /** * loadTasks * * @param string $directory * @return array $loadedTasks */ public function loadTasks($directory = null) { if ($directory === null) { $directory = Doctrine::getPath() . DIRECTORY_SEPARATOR . 'Doctrine' . DIRECTORY_SEPARATOR . 'Task'; } $parent = new ReflectionClass('Doctrine_Task'); $tasks = array(); foreach ((array) $directory as $dir) { $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir), RecursiveIteratorIterator::LEAVES_ONLY); foreach ($it as $file) { $e = explode('.', $file->getFileName()); if (end($e) === 'php' && strpos($file->getFileName(), '.inc') === false) { $className = 'Doctrine_Task_' . $e[0]; if ( ! class_exists($className)) { require_once($file->getPathName()); $class = new ReflectionClass($className); if ($class->isSubClassOf($parent)) { $tasks[$e[0]] = $e[0]; } } } } } $this->_tasks = array_merge($this->_tasks, $tasks); return $this->_tasks; } public function getLoadedTasks() { $parent = new ReflectionClass('Doctrine_Task'); $classes = get_declared_classes(); $tasks = array(); foreach ($classes as $className) { $class = new ReflectionClass($className); if ($class->isSubClassOf($parent)) { $task = str_replace('Doctrine_Task_', '', $className); $tasks[$task] = $task; } } return array_merge($this->_tasks, $tasks); } }