--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/lib/Zend/Service/Console/Command.php Thu May 07 15:16:02 2015 +0200
@@ -0,0 +1,413 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Service_Console
+ * @version $Id$
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @copyright Copyright (c) 2009 - 2011, RealDolmen (http://www.realdolmen.com)
+ * @license http://phpazure.codeplex.com/license
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Service_Console
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @copyright Copyright (c) 2009 - 2011, RealDolmen (http://www.realdolmen.com)
+ * @license http://phpazure.codeplex.com/license
+ */
+class Zend_Service_Console_Command
+{
+ /**
+ * The handler.
+ *
+ * @var array
+ */
+ protected $_handler;
+
+ /**
+ * Gets the handler.
+ *
+ * @return array
+ */
+ public function getHandler()
+ {
+ return $this->_handler;
+ }
+
+ /**
+ * Sets the handler.
+ *
+ * @param array $handler
+ * @return Zend_Service_Console_Command
+ */
+ public function setHandler($handler)
+ {
+ $this->_handler = $handler;
+ return $this;
+ }
+
+ /**
+ * Replaces PHP's error handler
+ *
+ * @param mixed $errno
+ * @param mixed $errstr
+ * @param mixed $errfile
+ * @param mixed $errline
+ */
+ public static function phpstderr($errno, $errstr, $errfile, $errline)
+ {
+ self::stderr($errno . ': Error in ' . $errfile . ':' . $errline . ' - ' . $errstr);
+ }
+
+ /**
+ * Replaces PHP's exception handler
+ *
+ * @param Exception $exception
+ */
+ public static function phpstdex($exception)
+ {
+ self::stderr('Error: ' . $exception->getMessage());
+ }
+
+ /**
+ * Writes output to STDERR, followed by a newline (optional)
+ *
+ * @param string $errorMessage
+ * @param string $newLine
+ */
+ public static function stderr($errorMessage, $newLine = true)
+ {
+ if (error_reporting() === 0) {
+ return;
+ }
+ file_put_contents('php://stderr', $errorMessage . ($newLine ? "\r\n" : ''));
+ }
+
+ /**
+ * Bootstrap the shell command.
+ *
+ * @param array $argv PHP argument values.
+ */
+ public static function bootstrap($argv)
+ {
+ // Abort bootstrapping depending on the MICROSOFT_CONSOLE_COMMAND_HOST constant.
+ if (defined('MICROSOFT_CONSOLE_COMMAND_HOST') && strtolower(MICROSOFT_CONSOLE_COMMAND_HOST) != 'console') {
+ return;
+ }
+
+ // Replace error handler
+ set_error_handler(array('Zend_Service_Console_Command', 'phpstderr'));
+ set_exception_handler(array('Zend_Service_Console_Command', 'phpstdex'));
+
+ // Build the application model
+ $model = self::_buildModel();
+
+ // Find a class that corresponds to the $argv[0] script name
+ $requiredHandlerName = str_replace('.bat', '', str_replace('.sh', '', str_replace('.php', '', strtolower(basename($argv[0])))));
+ $handler = null;
+ foreach ($model as $possibleHandler) {
+ if ($possibleHandler->handler == strtolower($requiredHandlerName)) {
+ $handler = $possibleHandler;
+ break;
+ }
+ }
+ if (is_null($handler)) {
+ self::stderr("No class found that implements handler '" . $requiredHandlerName . "'. Create a class that is named '" . $requiredHandlerName . "' and extends Zend_Service_Console_Command or is decorated with a docblock comment '@command-handler " . $requiredHandlerName . "'. Make sure it is loaded either through an autoloader or explicitly using require_once().");
+ die();
+ }
+
+ // Find a method that matches the command name
+ $command = null;
+ foreach ($handler->commands as $possibleCommand) {
+ if (in_array(strtolower(isset($argv[1]) ? $argv[1] : '<default>'), $possibleCommand->aliases)) {
+ $command = $possibleCommand;
+ break;
+ }
+ }
+ if (is_null($command)) {
+ $commandName = (isset($argv[1]) ? $argv[1] : '<default>');
+ self::stderr("No method found that implements command " . $commandName . ". Create a method in class '" . $handler->class . "' that is named '" . strtolower($commandName) . "Command' or is decorated with a docblock comment '@command-name " . $commandName . "'.");
+ die();
+ }
+
+ // Parse parameter values
+ $parameterValues = array();
+ $missingParameterValues = array();
+ $parameterInputs = array_splice($argv, 2);
+ foreach ($command->parameters as $parameter) {
+ // Default value: null
+ $value = null;
+
+ // Consult value providers for value. First one wins.
+ foreach ($parameter->valueproviders as $valueProviderName) {
+ if (!class_exists($valueProviderName)) {
+ $valueProviderName = 'Zend_Service_Console_Command_ParameterSource_' . $valueProviderName;
+ }
+ $valueProvider = new $valueProviderName();
+
+ $value = $valueProvider->getValueForParameter($parameter, $parameterInputs);
+ if (!is_null($value)) {
+ break;
+ }
+ }
+ if (is_null($value) && $parameter->required) {
+ $missingParameterValues[] = $parameter->aliases[0];
+ } else if (is_null($value)) {
+ $value = $parameter->defaultvalue;
+ }
+
+ // Set value
+ $parameterValues[] = $value;
+ $argvValues[$parameter->aliases[0]] = $value;
+ }
+
+ // Mising parameters?
+ if (count($missingParameterValues) > 0) {
+ self::stderr("Some parameters are missing:\r\n" . implode("\r\n", $missingParameterValues));
+ die();
+ }
+
+ // Supply argv in a nice way
+ $parameterValues['argv'] = $parameterInputs;
+
+ // Run the command
+ $className = $handler->class;
+ $classInstance = new $className();
+ $classInstance->setHandler($handler);
+ call_user_func_array(array($classInstance, $command->method), $parameterValues);
+
+ // Restore error handler
+ restore_exception_handler();
+ restore_error_handler();
+ }
+
+ /**
+ * Builds the handler model.
+ *
+ * @return array
+ */
+ protected static function _buildModel()
+ {
+ $model = array();
+
+ $classes = get_declared_classes();
+ foreach ($classes as $class) {
+ $type = new ReflectionClass($class);
+
+ $handlers = self::_findValueForDocComment('@command-handler', $type->getDocComment());
+ if (count($handlers) == 0 && $type->isSubclassOf('Zend_Service_Console_Command')) {
+ // Fallback: if the class extends Zend_Service_Console_Command, register it as
+ // a command handler.
+ $handlers[] = $class;
+ }
+ $handlerDescriptions = self::_findValueForDocComment('@command-handler-description', $type->getDocComment());
+ $handlerHeaders = self::_findValueForDocComment('@command-handler-header', $type->getDocComment());
+ $handlerFooters = self::_findValueForDocComment('@command-handler-footer', $type->getDocComment());
+
+ for ($hi = 0; $hi < count($handlers); $hi++) {
+ $handler = $handlers[$hi];
+ $handlerDescription = isset($handlerDescriptions[$hi]) ? $handlerDescriptions[$hi] : isset($handlerDescriptions[0]) ? $handlerDescriptions[0] : '';
+ $handlerDescription = str_replace('\r\n', "\r\n", $handlerDescription);
+ $handlerDescription = str_replace('\n', "\n", $handlerDescription);
+
+ $handlerModel = (object)array(
+ 'handler' => strtolower($handler),
+ 'description' => $handlerDescription,
+ 'headers' => $handlerHeaders,
+ 'footers' => $handlerFooters,
+ 'class' => $class,
+ 'commands' => array()
+ );
+
+ $methods = $type->getMethods();
+ foreach ($methods as $method) {
+ $commands = self::_findValueForDocComment('@command-name', $method->getDocComment());
+ if (substr($method->getName(), -7) == 'Command' && !in_array(substr($method->getName(), 0, -7), $commands)) {
+ // Fallback: if the method is named <commandname>Command,
+ // register it as a command.
+ $commands[] = substr($method->getName(), 0, -7);
+ }
+ for ($x = 0; $x < count($commands); $x++) {
+ $commands[$x] = strtolower($commands[$x]);
+ }
+ $commands = array_unique($commands);
+ $commandDescriptions = self::_findValueForDocComment('@command-description', $method->getDocComment());
+ $commandExamples = self::_findValueForDocComment('@command-example', $method->getDocComment());
+
+ if (count($commands) > 0) {
+ $command = $commands[0];
+ $commandDescription = isset($commandDescriptions[0]) ? $commandDescriptions[0] : '';
+
+ $commandModel = (object)array(
+ 'command' => $command,
+ 'aliases' => $commands,
+ 'description' => $commandDescription,
+ 'examples' => $commandExamples,
+ 'class' => $class,
+ 'method' => $method->getName(),
+ 'parameters' => array()
+ );
+
+ $parameters = $method->getParameters();
+ $parametersFor = self::_findValueForDocComment('@command-parameter-for', $method->getDocComment());
+ for ($pi = 0; $pi < count($parameters); $pi++) {
+ // Initialize
+ $parameter = $parameters[$pi];
+ $parameterFor = null;
+ $parameterForDefaultValue = null;
+
+ // Is it a "catch-all" parameter?
+ if ($parameter->getName() == 'argv') {
+ continue;
+ }
+
+ // Find the $parametersFor with the same name defined
+ foreach ($parametersFor as $possibleParameterFor) {
+ $possibleParameterFor = explode(' ', $possibleParameterFor, 4);
+ if ($possibleParameterFor[0] == '$' . $parameter->getName()) {
+ $parameterFor = $possibleParameterFor;
+ break;
+ }
+ }
+ if (is_null($parameterFor)) {
+ die('@command-parameter-for missing for parameter $' . $parameter->getName());
+ }
+
+ if (is_null($parameterForDefaultValue) && $parameter->isOptional()) {
+ $parameterForDefaultValue = $parameter->getDefaultValue();
+ }
+
+ $parameterModel = (object)array(
+ 'name' => '$' . $parameter->getName(),
+ 'defaultvalue' => $parameterForDefaultValue,
+ 'valueproviders' => explode('|', $parameterFor[1]),
+ 'aliases' => explode('|', $parameterFor[2]),
+ 'description' => (isset($parameterFor[3]) ? $parameterFor[3] : ''),
+ 'required' => (isset($parameterFor[3]) ? strpos(strtolower($parameterFor[3]), 'required') !== false && strpos(strtolower($parameterFor[3]), 'required if') === false : false),
+ );
+
+ // Add to model
+ $commandModel->parameters[] = $parameterModel;
+ }
+
+ // Add to model
+ $handlerModel->commands[] = $commandModel;
+ }
+ }
+
+ // Add to model
+ $model[] = $handlerModel;
+ }
+ }
+
+ return $model;
+ }
+
+ /**
+ * Finds the value for a specific docComment.
+ *
+ * @param string $docCommentName Comment name
+ * @param unknown_type $docComment Comment object
+ * @return array
+ */
+ protected static function _findValueForDocComment($docCommentName, $docComment)
+ {
+ $returnValue = array();
+
+ $commentLines = explode("\n", $docComment);
+ foreach ($commentLines as $commentLine) {
+ if (strpos($commentLine, $docCommentName . ' ') !== false) {
+ $returnValue[] = trim(substr($commentLine, strpos($commentLine, $docCommentName) + strlen($docCommentName) + 1));
+ }
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * Display information on an object
+ *
+ * @param object $object Object
+ * @param array $propertiesToDump Property names to display
+ */
+ protected function _displayObjectInformation($object, $propertiesToDump = array())
+ {
+ foreach ($propertiesToDump as $property) {
+ printf('%-16s: %s' . "\r\n", $property, $object->$property);
+ }
+ printf("\r\n");
+ }
+
+ /**
+ * Displays the help information.
+ *
+ * @command-name <default>
+ * @command-name -h
+ * @command-name -help
+ * @command-description Displays the current help information.
+ */
+ public function helpCommand() {
+ $handler = $this->getHandler();
+ $newline = "\r\n";
+
+ if (count($handler->headers) > 0) {
+ foreach ($handler->headers as $header) {
+ printf('%s%s', $header, $newline);
+ }
+ printf($newline);
+ }
+ printf('%s%s', $handler->description, $newline);
+ printf($newline);
+ printf('Available commands:%s', $newline);
+ foreach ($handler->commands as $command) {
+ $description = str_split($command->description, 50);
+ printf(' %-25s %s%s', implode(', ', $command->aliases), $description[0], $newline);
+ for ($di = 1; $di < count($description); $di++) {
+ printf(' %-25s %s%s', '', $description[$di], $newline);
+ }
+ printf($newline);
+
+ if (count($command->parameters) > 0) {
+ foreach ($command->parameters as $parameter) {
+ $description = str_split($parameter->description, 50);
+ printf(' %-23s %s%s', implode(', ', $parameter->aliases), $description[0], $newline);
+ for ($di = 1; $di < count($description); $di++) {
+ printf(' %-23s %s%s', '', $description[$di], $newline);
+ }
+ printf($newline);
+ }
+ }
+ printf($newline);
+
+ if (count($command->examples) > 0) {
+ printf(' Example usage:%s', $newline);
+ foreach ($command->examples as $example) {
+ printf(' %s%s', $example, $newline);
+ }
+ printf($newline);
+ }
+ }
+
+ if (count($handler->footers) > 0) {
+ printf($newline);
+ foreach ($handler->footers as $footer) {
+ printf('%s%s', $footer, $newline);
+ }
+ printf($newline);
+ }
+ }
+}