1
0
mirror of synced 2024-12-05 03:06:05 +03:00

[2.0] Incorporated CLI refactorings. Added support to namespaces and unlimited depth namespaces. Dropped globalArguments for now, since they interfer in DAG implementation.

This commit is contained in:
guilhermeblanco 2009-12-21 17:38:14 +00:00
parent 60b9fb7c5b
commit bf0cfba239
22 changed files with 1328 additions and 768 deletions

View File

@ -6,8 +6,12 @@
## CLI Controller changes
CLI main object changed its name and namespace. Renamed from Doctrine\ORM\Tools\Cli to Doctrine\ORM\Tools\Cli\CliController.
Doctrine\ORM\Tools\Cli\CliController methods addTasks and addTask are now fluent.
CLI main object changed its name and namespace. Renamed from Doctrine\ORM\Tools\Cli to Doctrine\Common\Cli\CliController.
Doctrine\Common\Cli\CliController now only deals with namespaces. Ready to go, Core, Dbal and Orm are available and you can subscribe new tasks by retrieving the namespace and including new task. Example:
[php]
$cli->getNamespace('Core')->addTask('my-example', '\MyProject\Tools\Cli\Tasks\MyExampleTask');
## CLI Tasks documentation

View File

@ -1,9 +1,12 @@
<?php
require 'Doctrine/Common/ClassLoader.php';
require_once __DIR__ . '/../lib/Doctrine/Common/ClassLoader.php';
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine');
$classLoader->setIncludePath(__DIR__ . '/../lib');
$classLoader->register();
$cli = new \Doctrine\ORM\Tools\Cli\CliController();
$configuration = new \Doctrine\Common\Cli\Configuration();
$cli = new \Doctrine\Common\Cli\CliController($configuration);
$cli->run($_SERVER['argv']);

View File

@ -0,0 +1,235 @@
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cli;
use Doctrine\Common\Util\Inflector,
Doctrine\Common\DoctrineException;
/**
* Abstract CLI Namespace class
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
abstract class AbstractNamespace
{
/**
* @var Configuration CLI Configuration instance
*/
private $_configuration = null;
/**
* @var AbstractPrinter CLI Printer instance
*/
private $_printer = null;
/**
* @var AbstractNamespace CLI Namespace instance
*/
private $_parentNamespace = null;
/**
* @var array Available namespaces
*/
private $_namespaces = array();
/**
* Add a single namespace to CLI.
* Example of inclusion support to a single namespace:
*
* [php]
* $cliOrmNamespace->addNamespace('my-custom-namespace');
*
* @param string $name CLI Namespace name
*
* @return CliController This object instance
*/
public function addNamespace($name)
{
$name = self::formatName($name);
if ($this->hasNamespace($name)) {
throw DoctrineException::cannotOverrideNamespace($name);
}
return $this->overrideNamespace($name);
}
/**
* Overrides a namespace to CLI.
* Example of inclusion support to a single namespace:
*
* [php]
* $cli->overrideNamespace('orm');
*
* @param string $name CLI Namespace name
*
* @return AbstractNamespace Newly created CLI Namespace
*/
public function overrideNamespace($name)
{
$taskNamespace = new TaskNamespace($name);
$taskNamespace->setParentNamespace($this);
$taskNamespace->setPrinter($this->_printer);
$taskNamespace->setConfiguration($this->_configuration);
$this->_namespaces[$taskNamespace->getName()] = $taskNamespace;
return $taskNamespace;
}
/**
* Retrieve CLI Namespace.
* Example of usage:
*
* [php]
* $cliOrmNamespace = $cli->getNamespace('ORM');
*
* @param string $name CLI Namespace name
*
* @return TaskNamespace CLI Namespace
*/
public function getNamespace($name)
{
$name = self::formatName($name);
return isset($this->_namespaces[$name])
? $this->_namespaces[$name] : null;
}
/**
* Check existance of a CLI Namespace
*
* @param string CLI Namespace name
*
* @return boolean TRUE if namespace if defined, false otherwise
*/
public function hasNamespace($name)
{
return ($this->getNamespace($name) !== null);
}
/**
* Defines the parent CLI Namespace
*
* @return AbstractNamespace
*/
public function setParentNamespace(AbstractNamespace $namespace)
{
$this->_parentNamespace = $namespace;
return $this;
}
/**
* Retrieves currently parent CLI Namespace
*
* @return AbstractNamespace
*/
public function getParentNamespace()
{
return $this->_parentNamespace;
}
/**
* Retrieve all defined CLI Tasks
*
* @return array
*/
public function getAvailableTasks()
{
$tasks = array();
foreach ($this->_namespaces as $namespace) {
$tasks = array_merge($tasks, $namespace->getAvailableTasks());
}
return $tasks;
}
/**
* Defines the CLI Output Printer
*
* @param AbstractPrinter $printer CLI Output Printer
*
* @return AbstractNamespace
*/
public function setPrinter(Printers\AbstractPrinter $printer = null)
{
$this->_printer = $printer ?: new Printers\AnsiColorPrinter;
return $this;
}
/**
* Retrieves currently used CLI Output Printer
*
* @return AbstractPrinter
*/
public function getPrinter()
{
return $this->_printer;
}
/**
* Defines the CLI Configuration
*
* #param Configuration $configuration CLI Configuration
*
* @return AbstractNamespace
*/
public function setConfiguration(Configuration $config)
{
$this->_configuration = $config;
return $this;
}
/**
* Retrieves currently used CLI Configuration
*
* @return Configuration
*/
public function getConfiguration()
{
return $this->_configuration;
}
/**
* Formats the CLI Namespace name into a camel-cased name
*
* @param string $name CLI Namespace name
*
* @return string Formatted CLI Namespace name
*/
public static function formatName($name)
{
return Inflector::classify($name);
}
}

View File

@ -0,0 +1,297 @@
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cli;
/**
* Generic CLI Controller of Tasks execution
*
* To include a new Task support, create a task:
*
* [php]
* class MyProject\Tools\Cli\Tasks\MyTask extends Doctrine\ORM\Tools\Cli\Tasks\AbstractTask
* {
* public function run();
* public function basicHelp();
* public function extendedHelp();
* public function validate();
* }
*
* And then, load the namespace assoaicated an include the support to it in your command-line script:
*
* [php]
* $cli = new Doctrine\Common\Cli\CliController();
* $cliNS = $cli->getNamespace('custom');
* $cliNS->addTask('myTask', 'MyProject\Tools\Cli\Tasks\MyTask');
*
* To execute, just type any classify-able name:
*
* $ cli.php custom:my-task
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class CliController extends AbstractNamespace
{
/**
* The CLI processor of tasks
*
* @param AbstractPrinter $printer CLI Output printer
*/
public function __construct(Configuration $config, AbstractPrinter $printer = null)
{
$this->setPrinter($printer);
$this->setConfiguration($config);
// Include core namespaces of tasks
$ns = '\Doctrine\Common\Cli\Tasks';
$this->addNamespace('Core')
->addTask('help', $ns . '\HelpTask');
$ns = '\Doctrine\ORM\Tools\Cli\Tasks';
$this->addNamespace('Orm')
->addTask('clear-cache', $ns . '\ClearCacheTask')
->addTask('convert-mapping', $ns . '\ConvertMappingTask')
->addTask('ensure-production-settings', $ns . '\EnsureProductionSettingsTask')
->addTask('generate-proxies', $ns . '\GenerateProxiesTask')
->addTask('run-dql', $ns . '\RunDqlTask')
->addTask('schema-tool', $ns . '\SchemaToolTask')
->addTask('version', $ns . '\VersionTask');
$ns = '\Doctrine\DBAL\Tools\Cli\Tasks';
$this->addNamespace('Dbal')
->addTask('run-sql', $ns . '\RunSqlTask');
}
/**
* Add a single task to CLI Core Namespace. This method acts as a delegate.
* Example of inclusion support to a single task:
*
* [php]
* $cli->addTask('my-custom-task', 'MyProject\Cli\Tasks\MyCustomTask');
*
* @param string $name CLI Task name
* @param string $class CLI Task class (FQCN - Fully Qualified Class Name)
*
* @return CliController This object instance
*/
public function addTask($name, $class)
{
$this->getNamespace('Core')->addTask($name, $class);
return $this;
}
/**
* Processor of CLI Tasks. Handles multiple task calls, instantiate
* respective classes and run them.
*
* @param array $args CLI Arguments
*/
public function run($args = array())
{
// Remove script file argument
$scriptFile = array_shift($args);
// If not arguments are defined, include "help"
if (empty($args)) {
array_unshift($args, 'Core:Help');
}
// Process all sent arguments
$args = $this->_processArguments($args);
try {
$this->getPrinter()->writeln('Doctrine Command Line Interface' . PHP_EOL, 'HEADER');
// Handle possible multiple tasks on a single command
foreach($args as $taskData) {
$taskName = $taskData['name'];
$taskArguments = $taskData['args'];
$this->runTask($taskName, $taskArguments);
}
} catch (\Exception $e) {
$message = $taskName . ' => ' . $e->getMessage();
if (isset($taskArguments['trace']) && $taskArguments['trace']) {
$message .= PHP_EOL . PHP_EOL . $e->getTraceAsString();
}
$this->getPrinter()->writeln($message, 'ERROR');
}
}
/**
* Executes a given CLI Task
*
* @param atring $name CLI Task name
* @param array $args CLI Arguments
*/
public function runTask($name, $args = array())
{
// Retrieve namespace name, task name and arguments
$taskPath = explode(':', $name);
// Find the correct namespace where the task is defined
$taskName = array_pop($taskPath);
$taskNamespace = $this->_retrieveTaskNamespace($taskPath);
$taskNamespace->runTask($taskName, $args);
}
/**
* Processes arguments and returns a structured hierachy.
* Example:
*
* cli.php foo -abc --option=value bar --option -a=value --optArr=value1,value2
*
* Returns:
*
* array(
* 0 => array(
* 'name' => 'foo',
* 'args' => array(
* 'a' => true,
* 'b' => true,
* 'c' => true,
* 'option' => 'value',
* ),
* ),
* 1 => array(
* 'name' => 'bar',
* 'args' => array(
* 'option' => true,
* 'a' => 'value',
* 'optArr' => array(
* 'value1', 'value2'
* ),
* ),
* ),
* )
*
* Based on implementation of Patrick Fisher <patrick@pwfisher.com> available at:
* http://pwfisher.com/nucleus/index.php?itemid=45
*
* @param array $args
*
* @return array
*/
private function _processArguments($args = array())
{
$flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE;
$regex = '/\s*[,]?\s*"([^"]*)"|\s*[,]?\s*([^,]*)/i';
$preparedArgs = array();
$out = & $preparedArgs;
foreach ($args as $arg){
// --foo --bar=baz
if (substr($arg, 0, 2) == '--'){
$eqPos = strpos($arg, '=');
// --foo
if ($eqPos === false){
$key = substr($arg, 2);
$out[$key] = isset($out[$key]) ? $out[$key] : true;
// --bar=baz
} else {
$key = substr($arg, 2, $eqPos - 2);
$value = substr($arg, $eqPos + 1);
$value = (strpos($value, ' ') !== false) ? $value : array_values(array_filter(
explode(',', $value), function ($v) { return trim($v) != ''; }
));
$out[$key] = ( ! is_array($value) || (is_array($value) && count($value) > 1))
? $value : $value[0];
}
// -k=value -abc
} else if (substr($arg, 0, 1) == '-'){
// -k=value
if (substr($arg, 2, 1) == '='){
$key = substr($arg, 1, 1);
$value = substr($arg, 3);
$value = (strpos($value, ' ') !== false) ? $value : array_values(array_filter(
explode(',', $value), function ($v) { return trim($v) != ''; }
));
$out[$key] = ( ! is_array($value) || (is_array($value) && count($value) > 1))
? $value : $value[0];
// -abc
} else {
$chars = str_split(substr($arg, 1));
foreach ($chars as $char){
$key = $char;
$out[$key] = isset($out[$key]) ? $out[$key] : true;
}
}
// plain-arg
} else {
$key = count($preparedArgs);
$preparedArgs[$key] = array(
'name' => $arg,
'args' => array()
);
$out = & $preparedArgs[$key]['args'];
}
}
return $preparedArgs;
}
/**
* Retrieve the correct namespace given a namespace path
*
* @param array $namespacePath CLI Namespace path
*
* @return AbstractNamespace
*/
private function _retrieveTaskNamespace($namespacePath)
{
$taskNamespace = $this;
$currentNamespacePath = '';
// Consider possible missing namespace (ie. "help") and forward to "core"
if (count($namespacePath) == 0) {
$namespacePath = array('Core');
}
// Loop through each namespace
foreach ($namespacePath as $namespaceName) {
$taskNamespace = $taskNamespace->getNamespace($namespaceName);
// If the given namespace returned "null", throw exception
if ($taskNamespace === null) {
throw CliException::namespaceDoesNotExist($namespaceName, $currentNamespacePath);
}
$currentNamespacePath = (( ! empty($currentNamespacePath)) ? ':' : '')
. $taskNamespace->getName();
}
return $taskNamespace;
}
}

View File

@ -0,0 +1,57 @@
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cli;
use Doctrine\Common\DoctrineException;
/**
* CLI Exception class
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class CliException extends DoctrineException
{
public static function namespaceDoesNotExist($namespaceName, $namespacePath = '')
{
return new self(
"Namespace '{$namespaceName}' does not exist" .
(( ! empty($namespacePath)) ? " in '{$namespacePath}'." : '.')
);
}
public static function taskDoesNotExist($taskName, $namespacePath)
{
return new self("Task '{$taskName}' does not exist in '{$namespacePath}'.");
}
public static function cannotOverrideTask($taskName)
{
return new self("Task '{$taskName}' cannot be overriden.");
}
}

View File

@ -0,0 +1,86 @@
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cli;
/**
* CLI Configuration class
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class Configuration
{
/**
* @var array Configuration attributes
*/
private $_attributes = array();
/**
* Defines a new configuration attribute
*
* @param string $name Attribute name
* @param mixed $value Attribute value
*
* @return Configuration This object instance
*/
public function setAttribute($name, $value = null)
{
$this->_attributes[$name] = $value;
if ($value === null) {
unset($this->_attributes[$name]);
}
return $this;
}
/**
* Retrieves a configuration attribute
*
* @param string $name Attribute name
*
* @return mixed Attribute value
*/
public function getAttribute($name)
{
return isset($this->_attributes[$name])
? $this->_attributes[$name] : null;
}
/**
* Checks if configuration attribute is defined
*
* @param string $name Attribute name
*
* @return boolean TRUE if attribute exists, FALSE otherwise
*/
public function hasAttribute($name)
{
return isset($this->_attribute[$name]);
}
}

View File

@ -40,6 +40,9 @@ class TaskDocumentation
{
/** @var AbstractPrinter CLI Printer */
private $_printer;
/** @var AbstractNamespace CLI Namespace */
private $_namespace;
/** @var string CLI Task name */
private $_name;
@ -53,14 +56,25 @@ class TaskDocumentation
/**
* Constructs a new CLI Task Documentation
*
* @param AbstractPrinter CLI Printer
* @param AbstractNamespace CLI Namespace
*/
public function __construct(AbstractPrinter $printer)
public function __construct(AbstractNamespace $namespace)
{
$this->_printer = $printer;
$this->_namespace = $namespace;
$this->_printer = $namespace->getPrinter();
$this->_optionGroup = new OptionGroup(OptionGroup::CARDINALITY_M_N);
}
/**
* Retrieves the CLI Namespace
*
* @return AbstractNamespace
*/
public function getNamespace()
{
return $this->_namespace;
}
/**
* Defines the CLI Task name
*
@ -84,6 +98,16 @@ class TaskDocumentation
return $this->_name;
}
/**
* Retrieves the full CLI Task name
*
* @return string Task full name
*/
public function getFullName()
{
return $this->getNamespace()->getFullName() . ':' . $this->_name;
}
/**
* Defines the CLI Task description
*
@ -139,7 +163,7 @@ class TaskDocumentation
*/
public function getSynopsis()
{
return $this->_printer->format($this->_name, 'KEYWORD') . ' '
return $this->_printer->format($this->getFullName(), 'KEYWORD') . ' '
. trim($this->_optionGroup->formatPlain($this->_printer));
}
@ -153,7 +177,7 @@ class TaskDocumentation
$printer = $this->_printer;
return $printer->format('Task: ')
. $printer->format($this->_name, 'KEYWORD')
. $printer->format($this->getFullName(), 'KEYWORD')
. $printer->format(PHP_EOL)
. $printer->format('Synopsis: ')
. $this->getSynopsis()

View File

@ -0,0 +1,245 @@
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cli;
/**
* CLI Namespace class
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class TaskNamespace extends AbstractNamespace
{
/**
* @var boolean CLI Tasks flag to check if they are already initialized
*/
private $_initialized = false;
/**
* @var string CLI Namespace full name
*/
private $_fullName = null;
/**
* @var string CLI Namespace name
*/
private $_name = null;
/**
* @var array Available tasks
*/
private $_tasks = array();
/**
* The CLI namespace
*
* @param string $name CLI Namespace name
*/
public function __construct($name)
{
$this->_name = self::formatName($name);
}
/**
* Retrieve an instantiated CLI Task by given its name.
*
* @param string $name CLI Task name
*
* @return AbstractTask
*/
public function getTask($name)
{
// Check if task exists in namespace
if ($this->hasTask($name)) {
$taskClass = $this->_tasks[self::formatName($name)];
return new $taskClass($this);
}
throw CliException::taskDoesNotExist($name, $this->getFullName());
}
/**
* Retrieve all CLI Task in this Namespace.
*
* @return array
*/
public function getTasks()
{
return $this->_tasks;
}
/**
* Retrieve all defined CLI Tasks
*
* @return array
*/
public function getAvailableTasks()
{
$tasks = parent::getAvailableTasks();
foreach ($this->_tasks as $taskName => $taskClass) {
$fullName = $this->getFullName() . ':' . $taskName;
$tasks[$fullName] = $taskClass;
}
return $tasks;
}
/**
* Add a single task to CLI Namespace.
* Example of inclusion support to a single task:
*
* [php]
* $cliOrmNamespace->addTask('my-custom-task', 'MyProject\Cli\Tasks\MyCustomTask');
*
* @param string $name CLI Task name
* @param string $class CLI Task class (FQCN - Fully Qualified Class Name)
*
* @return TaskNamespace This object instance
*/
public function addTask($name, $class)
{
$name = self::formatName($name);
if ($this->hasTask($name)) {
throw DoctrineException::cannotOverrideTask($name);
}
return $this->overrideTask($name, $class);
}
/**
* Overrides task on CLI Namespace.
* Example of inclusion support to a single task:
*
* [php]
* $cliOrmNamespace->overrideTask('schema-tool', 'MyProject\Cli\Tasks\MyCustomTask');
*
* @param string $name CLI Task name
* @param string $class CLI Task class (FQCN - Fully Qualified Class Name)
*
* @return TaskNamespace This object instance
*/
public function overrideTask($name, $class)
{
$name = self::formatName($name);
$this->_tasks[$name] = $class;
return $this;
}
/**
* Check existance of a CLI Task
*
* @param string CLI Task name
*
* @return boolean TRUE if CLI Task if defined, false otherwise
*/
public function hasTask($name)
{
$name = self::formatName($name);
return isset($this->_tasks[$name]);
}
/**
* Retrieves the CLI Namespace name
*
* @return string CLI Namespace name
*/
public function getName()
{
return $this->_name;
}
/**
* Retrieves the full CLI Namespace name
*
* @return string CLI Namespace full name
*/
public function getFullName()
{
if ($this->_fullName === null) {
$str = $this->_name;
while (
($parentNamespace = $this->getParentNamespace()) !== null &&
! ($parentNamespace instanceof CliController)
) {
$str = $parentNamespace->getFullName() . ':' . $str;
}
$this->_fullName = $str;
}
return $this->_fullName;
}
/**
* Effectively instantiate and execute a given CLI Task
*
* @param string $name CLI Task name
* @param array $arguments CLI Task arguments
*/
public function runTask($name, $arguments = array())
{
try {
$task = $this->getTask($name);
$task->setArguments($arguments);
if ((isset($arguments['help']) && $arguments['help']) || (isset($arguments['h']) && $arguments['h'])) {
$task->extendedHelp(); // User explicitly asked for help option
} else if (isset($arguments['basic-help']) && $arguments['basic-help']) {
$task->basicHelp(); // User explicitly asked for basic help option
} else if ($task->validate()) {
$task->run();
}
} catch (DoctrineException $e) {
$message = $this->getFullName() . ':' . $name . ' => ' . $e->getMessage();
$printer = $this->getPrinter();
// If we want the trace of calls, append to error message
if (isset($arguments['trace']) && $arguments['trace']) {
$message .= PHP_EOL . PHP_EOL . $e->getTraceAsString();
}
$printer->writeln($messageMessage, 'ERROR');
// Unable instantiate task or task is not valid
if ($task !== null) {
$printer->write(PHP_EOL);
$task->basicHelp(); // Fallback of not-valid task arguments
}
$printer->write(PHP_EOL);
}
}
}

View File

@ -19,29 +19,21 @@
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Tools\Cli\Tasks;
namespace Doctrine\Common\Cli\Tasks;
use Doctrine\Common\Cli\Printers\AbstractPrinter,
Doctrine\Common\Cli\TaskDocumentation,
Doctrine\Common\Cli\OptionGroup,
Doctrine\Common\Cli\Option;
use Doctrine\Common\Cli\AbstractNamespace,
Doctrine\Common\Cli\TaskDocumentation;
/**
* Base class for CLI Tasks.
* Provides basic methods and requires implementation of methods that
* each task should implement in order to correctly work.
*
* The following arguments are common to all tasks:
*
* Argument: --config=<path>
* Description: Specifies the path to the configuration file to use. The configuration file
* can bootstrap an EntityManager as well as provide defaults for any cli
* arguments.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
@ -49,119 +41,42 @@ use Doctrine\Common\Cli\Printers\AbstractPrinter,
abstract class AbstractTask
{
/**
* @var AbstractPrinter CLI Output Printer
* @var AbstractNamespace CLI Namespace
*/
protected $_printer;
/**
* @var TaskDocumentation CLI Task Documentation
*/
protected $_documentation;
/**
* @var array CLI argument options
* @var array CLI Task arguments
*/
protected $_arguments;
/**
* @var array Available CLI tasks
*/
protected $_availableTasks;
/**
* @var EntityManager The EntityManager instance
*/
protected $_em;
protected $_arguments = array();
/**
* Constructor of CLI Task
*
* @param AbstractPrinter CLI Output Printer
* @param AbstractNamespace CLI Namespace
*/
public function __construct(AbstractPrinter $printer)
public function __construct(AbstractNamespace $namespace)
{
$this->_printer = $printer;
$this->_documentation = new TaskDocumentation($printer);
// Include configuration option
$configGroup = new OptionGroup(OptionGroup::CARDINALITY_0_1);
$configGroup->addOption(
new Option('config', '<FILE_PATH>', 'Configuration file for EntityManager.')
);
$this->_documentation->addOption($configGroup);
$this->_namespace = $namespace;
$this->_documentation = new TaskDocumentation($namespace);
// Complete the CLI Task Documentation creation
$this->buildDocumentation();
}
/**
* Retrieves currently used CLI Output Printer
* Retrieves the CLI Namespace
*
* @return AbstractPrinter
* @return AbstractNamespace
*/
public function getPrinter()
public function getNamespace()
{
return $this->_printer;
}
/**
* Defines the CLI arguments
*
* @param array CLI argument options
*/
public function setArguments($arguments)
{
$this->_arguments = $arguments;
}
/**
* Retrieves current CLI arguments
*
* @return array
*/
public function getArguments()
{
return $this->_arguments;
}
/**
* Defines the available CLI tasks
*
* @param array Available CLI tasks
*/
public function setAvailableTasks($availableTasks)
{
$this->_availableTasks = $availableTasks;
}
/**
* Retrieves the available CLI tasks
*
* @return array
*/
public function getAvailableTasks()
{
return $this->_availableTasks;
}
/**
* Defines the EntityManager
*
* @param EntityManager The EntityManager instance
*/
public function setEntityManager($em)
{
$this->_em = $em;
}
/**
* Retrieves current EntityManager
*
* @return EntityManager
*/
public function getEntityManager()
{
return $this->_em;
return $this->_namespace;
}
/**
@ -174,6 +89,50 @@ abstract class AbstractTask
return $this->_documentation;
}
/**
* Defines the CLI Task arguments
*
* @param array $arguments CLI Task arguments
*
* @return AbstractTask
*/
public function setArguments(array $arguments = array())
{
$this->_arguments = $arguments;
return $this;
}
/**
* Retrieves the CLI Task arguments
*
* @return array
*/
public function getArguments()
{
return $this->_arguments;
}
/**
* Retrieves currently used CLI Output Printer
*
* @return AbstractPrinter
*/
public function getPrinter()
{
return $this->_namespace->getPrinter();
}
/**
* Retrieves current used CLI Configuration
*
* @return Configuration
*/
public function getConfiguration()
{
return $this->_namespace->getConfiguration();
}
/**
* Expose to CLI Output Printer the extended help of the given task.
* This means it should detail all parameters, options and the meaning
@ -186,7 +145,7 @@ abstract class AbstractTask
*/
public function extendedHelp()
{
$this->_printer->output($this->_documentation->getCompleteDocumentation());
$this->getPrinter()->output($this->_documentation->getCompleteDocumentation());
}
/**
@ -207,7 +166,7 @@ abstract class AbstractTask
*/
public function basicHelp()
{
$this->_printer
$this->getPrinter()
->output($this->_documentation->getSynopsis())
->output(PHP_EOL)
->output(' ' . $this->_documentation->getDescription())
@ -221,7 +180,11 @@ abstract class AbstractTask
*
* @return boolean
*/
abstract public function validate();
public function validate()
{
// TODO implement DAG here!
return true;
}
/**
* Safely execution of task.
@ -234,4 +197,4 @@ abstract class AbstractTask
* Generate the CLI Task Documentation
*/
abstract public function buildDocumentation();
}
}

View File

@ -19,9 +19,9 @@
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Tools\Cli\Tasks;
namespace Doctrine\Common\Cli\Tasks;
use Doctrine\Common\Util\Inflector;
use Doctrine\Common\Cli\CliException;
/**
* CLI Task to display available commands help
@ -30,6 +30,7 @@ use Doctrine\Common\Util\Inflector;
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
@ -60,38 +61,25 @@ class HelpTask extends AbstractTask
$this->run();
}
/**
* @inheritdoc
*/
public function validate()
{
return true;
}
/**
* Exposes the available tasks
*
*/
public function run()
{
$this->getPrinter()->writeln('Available Tasks:', 'NONE');
$this->getPrinter()->writeln('Available Tasks:', 'HEADER')->write(PHP_EOL);
// Find the CLI Controller
$cliController = $this->getNamespace()->getParentNamespace();
// Switch between ALL available tasks and display the basic Help of each one
$availableTasks = $this->getAvailableTasks();
$helpTaskName = Inflector::classify(str_replace('-', '_', 'help'));
unset($availableTasks[$helpTaskName]);
$availableTasks = $cliController->getAvailableTasks();
unset($availableTasks['Core:Help']);
ksort($availableTasks);
foreach ($availableTasks as $taskName => $taskClass) {
$task = new $taskClass($this->getPrinter());
$task->setAvailableTasks($availableTasks);
$task->setEntityManager($this->getEntityManager());
$task->setArguments($this->getArguments());
$task->basicHelp();
foreach (array_keys($availableTasks) as $taskName) {
$cliController->runTask($taskName, array('basic-help' => true));
}
}
}

View File

@ -56,19 +56,7 @@ class Inflector
*/
public static function classify($word)
{
$word = preg_replace('/[$]/', '', $word);
return preg_replace_callback('~(_?)(_)([\w])~', array(__CLASS__, "classifyCallback"), ucfirst(strtolower($word)));
}
/**
* Callback function to classify a classname properly.
*
* @param array $matches An array of matches from a pcre_replace call
* @return string $string A string with matches 1 and mathces 3 in upper case.
*/
public static function classifyCallback($matches)
{
return $matches[1] . strtoupper($matches[3]);
return str_replace(" ", "", ucwords(strtr($word, "_-", " ")));
}
/**

View File

@ -19,9 +19,10 @@
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Tools\Cli\Tasks;
namespace Doctrine\DBAL\Tools\Cli\Tasks;
use Doctrine\Common\DoctrineException,
use Doctrine\Common\Cli\Tasks\AbstractTask,
Doctrine\Common\Cli\CliException,
Doctrine\Common\Util\Debug,
Doctrine\Common\Cli\Option,
Doctrine\Common\Cli\OptionGroup;
@ -47,13 +48,11 @@ class RunSqlTask extends AbstractTask
{
$dqlAndFile = new OptionGroup(OptionGroup::CARDINALITY_1_1, array(
new Option(
'sql', '<DQL>',
'The SQL to execute.' . PHP_EOL .
'sql', '<SQL>', 'The SQL to execute.' . PHP_EOL .
'If defined, --file can not be requested on same task.'
),
new Option(
'file', '<FILE_PATH>',
'The path to the file with the SQL to execute.' . PHP_EOL .
'file', '<PATH>', 'The path to the file with the SQL to execute.' . PHP_EOL .
'If defined, --sql can not be requested on same task.'
)
));
@ -75,15 +74,17 @@ class RunSqlTask extends AbstractTask
*/
public function validate()
{
$args = $this->getArguments();
$printer = $this->getPrinter();
$arguments = $this->getArguments();
$em = $this->getConfiguration()->getAttribute('em');
$isSql = isset($args['sql']);
$isFile = isset($args['file']);
if ($em === null) {
throw new CliException(
"Attribute 'em' of CLI Configuration is not defined or it is not a valid EntityManager."
);
}
if ( ! ($isSql ^ $isFile)) {
$printer->writeln("One of --sql or --file required, and only one.", 'ERROR');
return false;
if ( ! (isset($arguments['sql']) ^ isset($arguments['file']))) {
throw new CliException('One of --sql or --file required, and only one.');
}
return true;
@ -95,27 +96,23 @@ class RunSqlTask extends AbstractTask
*/
public function run()
{
$args = $this->getArguments();
$arguments = $this->getArguments();
try {
if (isset($args['file'])) {
//TODO
} else if (isset($args['sql'])) {
$conn = $this->getEntityManager()->getConnection();
if (isset($arguments['file'])) {
//TODO
} else if (isset($arguments['sql'])) {
$em = $this->getConfiguration()->getAttribute('em');
if (preg_match('/^select/i', $args['sql'])) {
$stmt = $conn->execute($args['sql']);
$resultSet = $stmt->fetchAll(\Doctrine\DBAL\Connection::FETCH_ASSOC);
} else {
$resultSet = $conn->executeUpdate($args['sql']);
}
$maxDepth = isset($args['depth']) ? $args['depth'] : 7;
Debug::dump($resultSet, $maxDepth);
if (preg_match('/^select/i', $arguments['sql'])) {
$stmt = $em->getConnection()->execute($arguments['sql']);
$resultSet = $stmt->fetchAll(\Doctrine\DBAL\Connection::FETCH_ASSOC);
} else {
$resultSet = $em->getConnection()->executeUpdate($arguments['sql']);
}
} catch (\Exception $ex) {
throw new DoctrineException($ex);
$maxDepth = isset($args['arguments']) ? $arguments['depth'] : 7;
Debug::dump($resultSet, $maxDepth);
}
}
}

View File

@ -1,364 +0,0 @@
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Tools\Cli;
use Doctrine\Common\Util\Inflector,
Doctrine\Common\Cli\Printers\AbstractPrinter,
Doctrine\Common\Cli\Printers\AnsiColorPrinter,
Doctrine\ORM\Tools\Cli\Tasks\AbstractTask;
/**
* Generic CLI Controller of Tasks execution
*
* To include a new Task support, create a task:
*
* [php]
* class MyProject\Tools\Cli\Tasks\MyTask extends Doctrine\ORM\Tools\Cli\Tasks\AbstractTask
* {
* public function run();
* public function basicHelp();
* public function extendedHelp();
* public function validate();
* }
*
* And then, include the support to it in your command-line script:
*
* [php]
* $cli = new Doctrine\ORM\Tools\Cli\CliController();
* $cli->addTask('myTask', 'MyProject\Tools\Cli\Tasks\MyTask');
*
* To execute, just type any classify-able name:
*
* $ cli.php my-task
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class CliController
{
/**
* @var AbstractPrinter CLI Printer instance
*/
private $_printer = null;
/**
* @var array Available tasks
*/
private $_tasks = array();
/**
* The CLI processor of tasks
*
* @param AbstractPrinter $printer CLI Output printer
*/
public function __construct(AbstractPrinter $printer = null)
{
//$this->_printer = new Printer\Normal();
$this->_printer = $printer ?: new AnsiColorPrinter;
// Include core tasks
$ns = 'Doctrine\ORM\Tools\Cli\Tasks';
$this->addTasks(array(
'help' => $ns . '\HelpTask',
'version' => $ns . '\VersionTask',
'schema-tool' => $ns . '\SchemaToolTask',
'run-sql' => $ns . '\RunSqlTask',
'run-dql' => $ns . '\RunDqlTask',
'convert-mapping' => $ns . '\ConvertMappingTask',
'generate-proxies' => $ns . '\GenerateProxiesTask',
'clear-cache' => $ns . '\ClearCacheTask',
'ensure-production-settings' => $ns . '\EnsureProductionSettingsTask'
));
}
/**
* Add a collection of tasks to the CLI.
* To include them, just call the method with the following structure:
*
* [php]
* $cli->addTasks(array(
* 'my-custom-task' => 'MyProject\Cli\Tasks\MyCustomTask',
* ...
* ));
*
* @param array $tasks CLI Tasks to be included
* @return CliController This object instance
*/
public function addTasks($tasks)
{
foreach ($tasks as $name => $class) {
$this->addTask($name, $class);
}
return $this;
}
/**
* Add a single task to CLI.
* Example of inclusion support to a single task:
*
* [php]
* $cli->addTask('my-custom-task', 'MyProject\Cli\Tasks\MyCustomTask');
*
* @param string $name CLI Task name
* @param string $class CLI Task class (FQCN - Fully Qualified Class Name)
* @return CliController This object instance
*/
public function addTask($name, $class)
{
// Convert $name into a class equivalent
// (ie. 'show_version' => 'showVersion')
$name = $this->_processTaskName($name);
$this->_tasks[$name] = $class;
return $this;
}
/**
* Processor of CLI Tasks. Handles multiple task calls, instantiate
* respective classes and run them.
*
* @param array $args CLI Arguments
*/
public function run($args = array())
{
// Remove script file argument
$scriptFile = array_shift($args);
// Automatically prepend 'help' task if:
// 1- No arguments were passed
// 2- First item is not a valid task name
if (empty($args) || ! isset($this->_tasks[$this->_processTaskName($args[0])])) {
array_unshift($args, 'help');
}
// Process all sent arguments
$processedArgs = $this->_processArguments($args);
try {
$this->_printer->writeln('Doctrine Command Line Interface' . PHP_EOL, 'HEADER');
// Handle possible multiple tasks on a single command
foreach($processedArgs as $taskData) {
// Retrieve the task name and arguments
$taskName = $this->_processTaskName($taskData['name']);
$taskArguments = $taskData['args'];
// Check if task exists
if (isset($this->_tasks[$taskName]) && class_exists($this->_tasks[$taskName], true)) {
// Initializing EntityManager
$em = $this->_initializeEntityManager($processedArgs, $taskArguments);
// Instantiate and execute the task
$task = new $this->_tasks[$taskName]($this->_printer);
$task->setAvailableTasks($this->_tasks);
$task->setEntityManager($em);
$task->setArguments($taskArguments);
if (
(isset($taskArguments['help']) && $taskArguments['help']) ||
(isset($taskArguments['h']) && $taskArguments['h'])
) {
$task->extendedHelp(); // User explicitly asked for help option
} else if ($this->_isTaskValid($task)) {
$task->run();
} else {
$this->_printer->write(PHP_EOL);
$task->basicHelp(); // Fallback of not-valid task arguments
$this->_printer->write(PHP_EOL);
}
} else {
throw \Doctrine\Common\DoctrineException::taskDoesNotExist($taskName);
}
}
} catch (\Doctrine\Common\DoctrineException $e) {
$this->_printer->writeln(
$taskName . ': ' . $e->getMessage() . PHP_EOL . PHP_EOL . $e->getTraceAsString(), 'ERROR'
);
}
}
/**
* Processes the given task name and return it formatted
*
* @param string $taskName Task name
* @return string
*/
private function _processTaskName($taskName)
{
$taskName = str_replace('-', '_', $taskName);
return Inflector::classify($taskName);
}
/**
* Processes arguments and returns a structured hierachy.
* Example:
*
* cli.php foo -abc --option=value bar --option -a=value --optArr=value1,value2
*
* Returns:
*
* array(
* 0 => array(
* 'name' => 'foo',
* 'args' => array(
* 'a' => true,
* 'b' => true,
* 'c' => true,
* 'option' => 'value',
* ),
* ),
* 1 => array(
* 'name' => 'bar',
* 'args' => array(
* 'option' => true,
* 'a' => 'value',
* 'optArr' => array(
* 'value1', 'value2'
* ),
* ),
* ),
* )
*
* Based on implementation of Patrick Fisher <patrick@pwfisher.com> available at:
*
* http://pwfisher.com/nucleus/index.php?itemid=45
*
* @param array $args
* @return array
*/
private function _processArguments($args = array())
{
$flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE;
$regex = '/\s*[,]?\s*"([^"]*)"|\s*[,]?\s*([^,]*)/i';
$preparedArgs = array();
$out = & $preparedArgs;
foreach ($args as $arg){
// --foo --bar=baz
if (substr($arg, 0, 2) == '--'){
$eqPos = strpos($arg, '=');
// --foo
if ($eqPos === false){
$key = substr($arg, 2);
$out[$key] = isset($out[$key]) ? $out[$key] : true;
// --bar=baz
} else {
$key = substr($arg, 2, $eqPos - 2);
$value = substr($arg, $eqPos + 1);
$value = (strpos($value, ' ') !== false) ? $value
: array_values(array_filter(explode(',', $value), function ($v) { return trim($v) != ''; }));
$out[$key] = ( ! is_array($value) || (is_array($value) && count($value) > 1))
? $value : $value[0];
}
// -k=value -abc
} else if (substr($arg, 0, 1) == '-'){
// -k=value
if (substr($arg, 2, 1) == '='){
$key = substr($arg, 1, 1);
$value = substr($arg, 3);
$value = (strpos($value, ' ') !== false) ? $value
: array_values(array_filter(explode(',', $value), function ($v) { return trim($v) != ''; }));
$out[$key] = ( ! is_array($value) || (is_array($value) && count($value) > 1))
? $value : $value[0];
// -abc
} else {
$chars = str_split(substr($arg, 1));
foreach ($chars as $char){
$key = $char;
$out[$key] = isset($out[$key]) ? $out[$key] : true;
}
}
// plain-arg
} else {
$key = count($preparedArgs);
$preparedArgs[$key] = array(
'name' => $arg,
'args' => array()
);
$out = & $preparedArgs[$key]['args'];
}
}
return $preparedArgs;
}
/**
* Checks if CLI Task is valid based on given arguments.
*
* @param AbstractTask $task CLI Task instance
*/
private function _isTaskValid(AbstractTask $task)
{
// TODO: Should we change the behavior and check for
// required and optional arguments here?
return $task->validate();
}
/**
* Initialized Entity Manager for Tasks
*
* @param array CLI Task arguments
* @return EntityManager
*/
private function _initializeEntityManager(array $args, array &$taskArgs)
{
// Initialize EntityManager
$configFile = ( ! isset($taskArgs['config'])) ? './cli-config.php' : $taskArgs['config'];
if (file_exists($configFile)) {
// Including configuration file
require $configFile;
// Check existance of EntityManager
if ( ! isset($em)) {
throw new \Doctrine\Common\DoctrineException(
'No EntityManager created in configuration'
);
}
// Check for gloal argument options here
if (isset($globalArguments)) {
// Merge arguments. Values specified via the CLI take preference.
$taskArgs = array_merge($globalArguments, $taskArgs);
}
return $em;
} else {
throw new \Doctrine\Common\DoctrineException(
'Requested configuration file [' . $configFile . '] does not exist'
);
}
return null;
}
}

View File

@ -21,8 +21,8 @@
namespace Doctrine\ORM\Tools\Cli\Tasks;
use Doctrine\Common\DoctrineException,
Doctrine\Common\Util\Debug,
use Doctrine\Common\Cli\Tasks\AbstractTask,
Doctrine\Common\Cli\CliException,
Doctrine\Common\Cli\Option,
Doctrine\Common\Cli\OptionGroup,
Doctrine\Common\Cache\AbstractDriver;
@ -56,7 +56,7 @@ class ClearCacheTask extends AbstractTask
new Option('id', '<ID>', 'The id of the cache entry to delete (accepts * wildcards).'),
new Option('regex', '<REGEX>', 'Delete cache entries that match the given regular expression.'),
new Option('prefix', '<PREFIX>', 'Delete cache entries that have the given prefix.'),
new Option('suffic', '<SUFFIX>', 'Delete cache entries that have the given suffix.')
new Option('suffix', '<SUFFIX>', 'Delete cache entries that have the given suffix.')
))
))
));
@ -68,43 +68,52 @@ class ClearCacheTask extends AbstractTask
->addOption($cacheOptions);
}
/**
* @inheritdoc
*/
public function validate()
{
$printer = $this->getPrinter();
$args = $this->getArguments();
$arguments = $this->getArguments();
// Check if we have an active EntityManager
$em = $this->getConfiguration()->getAttribute('em');
if ($em === null) {
throw new CliException(
"Attribute 'em' of CLI Configuration is not defined or it is not a valid EntityManager."
);
}
// When clearing the query cache no need to specify
// id, regex, prefix or suffix.
if ((isset($args['query']) || isset($args['metadata']))
&& (isset($args['id'])
|| isset($args['regex'])
|| isset($args['prefix'])
|| isset($args['suffix']))) {
$printer->writeln(
if (
(isset($arguments['query']) || isset($arguments['metadata'])) && (isset($arguments['id']) ||
isset($args['regex']) || isset($args['prefix']) || isset($args['suffix']))
) {
throw new CliException(
'When clearing the query or metadata cache do not ' .
'specify any --id, --regex, --prefix or --suffix.',
'ERROR'
'specify any --id, --regex, --prefix or --suffix.'
);
return false;
}
return true;
}
/**
* @inheritdoc
*/
public function run()
{
$arguments = $this->getArguments();
$printer = $this->getPrinter();
$args = $this->getArguments();
$query = isset($args['query']);
$result = isset($args['result']);
$metadata = isset($args['metadata']);
$id = isset($args['id']) ? $args['id'] : null;
$regex = isset($args['regex']) ? $args['regex'] : null;
$prefix = isset($args['prefix']) ? $args['prefix'] : null;
$suffix = isset($args['suffix']) ? $args['suffix'] : null;
$query = isset($arguments['query']);
$result = isset($arguments['result']);
$metadata = isset($arguments['metadata']);
$id = isset($arguments['id']) ? $arguments['id'] : null;
$regex = isset($arguments['regex']) ? $arguments['regex'] : null;
$prefix = isset($arguments['prefix']) ? $arguments['prefix'] : null;
$suffix = isset($arguments['suffix']) ? $arguments['suffix'] : null;
$all = false;
@ -112,38 +121,24 @@ class ClearCacheTask extends AbstractTask
$all = true;
}
$configuration = $this->getEntityManager()->getConfiguration();
$em = $this->getConfiguration()->getAttribute('em');
$configuration = $em->getConfiguration();
if ($query || $all) {
$this->_doDelete(
'query',
$configuration->getQueryCacheImpl(),
$id,
$regex,
$prefix,
$suffix
'query', $configuration->getQueryCacheImpl(), $id, $regex, $prefix, $suffix
);
}
if ($result || $all) {
$this->_doDelete(
'result',
$configuration->getResultCacheImpl(),
$id,
$regex,
$prefix,
$suffix
'result', $configuration->getResultCacheImpl(), $id, $regex, $prefix, $suffix
);
}
if ($metadata || $all) {
$this->_doDelete(
'metadata',
$configuration->getMetadataCacheImpl(),
$id,
$regex,
$prefix,
$suffix
'metadata', $configuration->getMetadataCacheImpl(), $id, $regex, $prefix, $suffix
);
}
}
@ -153,54 +148,56 @@ class ClearCacheTask extends AbstractTask
$printer = $this->getPrinter();
if ( ! $cacheDriver) {
$printer->writeln('No driver has been configured for the ' . $type . ' cache.', 'ERROR');
return false;
throw new CliException('No driver has been configured for the ' . $type . ' cache.');
}
if ($id) {
$printer->writeln('Clearing ' . $type . ' cache entries that match the id "' . $id . '"', 'INFO');
$printer->writeln('Clearing ' . $type . ' cache entries that match the id "' . $id . '".', 'INFO');
$deleted = $cacheDriver->delete($id);
if (is_array($deleted)) {
$this->_printDeleted($printer, $type, $deleted);
$this->_printDeleted($type, $deleted);
} else if (is_bool($deleted) && $deleted) {
$this->_printDeleted($printer, $type, array($id));
$this->_printDeleted($type, array($id));
}
}
if ($regex) {
$printer->writeln('Clearing ' . $type . ' cache entries that match the regular expression "' . $regex . '"', 'INFO');
$printer->writeln('Clearing ' . $type . ' cache entries that match the regular expression ".' . $regex . '"', 'INFO');
$this->_printDeleted($printer, $type, $cacheDriver->deleteByRegex('/' . $regex. '/'));
$this->_printDeleted($type, $cacheDriver->deleteByRegex('/' . $regex. '/'));
}
if ($prefix) {
$printer->writeln('Clearing ' . $type . ' cache entries that have the prefix "' . $prefix . '"', 'INFO');
$printer->writeln('Clearing ' . $type . ' cache entries that have the prefix "' . $prefix . '".', 'INFO');
$this->_printDeleted($printer, $type, $cacheDriver->deleteByPrefix($prefix));
$this->_printDeleted($type, $cacheDriver->deleteByPrefix($prefix));
}
if ($suffix) {
$printer->writeln('Clearing ' . $type . ' cache entries that have the suffix "' . $suffix . '"', 'INFO');
$printer->writeln('Clearing ' . $type . ' cache entries that have the suffix "' . $suffix . '".', 'INFO');
$this->_printDeleted($printer, $type, $cacheDriver->deleteBySuffix($suffix));
$this->_printDeleted($type, $cacheDriver->deleteBySuffix($suffix));
}
if ( ! $id && ! $regex && ! $prefix && ! $suffix) {
$printer->writeln('Clearing all ' . $type . ' cache entries', 'INFO');
$printer->writeln('Clearing all ' . $type . ' cache entries.', 'INFO');
$this->_printDeleted($printer, $type, $cacheDriver->deleteAll());
$this->_printDeleted($type, $cacheDriver->deleteAll());
}
}
private function _printDeleted($printer, $type, array $ids)
private function _printDeleted($type, array $ids)
{
$printer = $this->getPrinter();
if ( ! empty($ids)) {
foreach ($ids as $id) {
$printer->writeln(' - ' . $id);
}
} else {
$printer->writeln('No ' . $type . ' cache entries found', 'ERROR');
throw new CliException('No ' . $type . ' cache entries found.');
}
$printer->write(PHP_EOL);

View File

@ -21,7 +21,8 @@
namespace Doctrine\ORM\Tools\Cli\Tasks;
use Doctrine\Common\DoctrineException,
use Doctrine\Common\Cli\Tasks\AbstractTask,
Doctrine\Common\Cli\CliException,
Doctrine\Common\Cli\Option,
Doctrine\Common\Cli\OptionGroup,
Doctrine\ORM\Tools\Export\ClassMetadataExporter;
@ -65,48 +66,65 @@ class ConvertMappingTask extends AbstractTask
*/
public function validate()
{
$args = $this->getArguments();
$printer = $this->getPrinter();
if (array_key_exists('from-database', $args)) {
$args['from'][0] = 'database';
$this->setArguments($args);
$arguments = $this->getArguments();
if (isset($arguments['from-database']) && $arguments['from-database']) {
$arguments['from'] = 'database';
$this->setArguments($arguments);
}
if (!(isset($args['from']) && isset($args['to']) && isset($args['dest']))) {
$printer->writeln('You must include a value for all three options: --from, --to and --dest', 'ERROR');
return false;
if (!(isset($arguments['from']) && isset($arguments['to']) && isset($arguments['dest']))) {
throw new CliException(
'You must include a value for all three options: --from, --to and --dest.'
);
}
if ($args['to'] != 'annotation' && isset($args['extend'])) {
$printer->writeln('You can only use the --extend argument when converting to annoations.', 'ERROR');
return false;
if (strtolower($arguments['to']) != 'annotation' && isset($arguments['extend'])) {
throw new CliException(
'You can only use the --extend argument when converting to annotations.'
);
}
if ($args['from'][0] == 'database') {
$em = $this->getEntityManager();
if (strtolower($arguments['from']) == 'database') {
// Check if we have an active EntityManager
$em = $this->getConfiguration()->getAttribute('em');
if ($em === null) {
throw new CliException(
"Attribute 'em' of CLI Configuration is not defined or it is not a valid EntityManager."
);
}
$config = $em->getConfiguration();
$config->setMetadataDriverImpl(new \Doctrine\ORM\Mapping\Driver\DatabaseDriver($em->getConnection()->getSchemaManager()));
$config->setMetadataDriverImpl(
new \Doctrine\ORM\Mapping\Driver\DatabaseDriver(
$em->getConnection()->getSchemaManager()
)
);
}
return true;
}
public function run()
{
$printer = $this->getPrinter();
$args = $this->getArguments();
$arguments = $this->getArguments();
$cme = new ClassMetadataExporter();
$printer = $this->getPrinter();
// Get exporter and configure it
$exporter = $cme->getExporter($args['to'], $args['dest']);
$exporter = $cme->getExporter($arguments['to'], $arguments['dest']);
if (isset($args['extend'])) {
$exporter->setClassToExtend($args['extend']);
if (isset($arguments['extend']) && $arguments['extend']) {
$exporter->setClassToExtend($arguments['extend']);
}
if (isset($args['num-spaces'])) {
$exporter->setNumSpaces($args['num-spaces']);
if (isset($arguments['num-spaces']) && $arguments['extend']) {
$exporter->setNumSpaces($arguments['num-spaces']);
}
$from = (array) $args['from'];
$from = (array) $arguments['from'];
if ($this->_isDoctrine1Schema($from)) {
$printer->writeln('Converting Doctrine 1 schema to Doctrine 2 mapping files', 'INFO');
@ -116,40 +134,38 @@ class ConvertMappingTask extends AbstractTask
} else {
foreach ($from as $source) {
$sourceArg = $source;
$type = $this->_determineSourceType($sourceArg);
if ( ! $type) {
throw DoctrineException::invalidMappingSourceType($sourceArg);
}
$source = $this->_getSourceByType($type, $sourceArg);
$printer->writeln(
sprintf(
'Adding "%s" mapping source which contains the "%s" format',
$printer->format($sourceArg, 'KEYWORD'),
$printer->format($type, 'KEYWORD')
$printer->format($sourceArg, 'KEYWORD'), $printer->format($type, 'KEYWORD')
)
);
$cme->addMappingSource($source, $type);
}
$metadatas = $cme->getMetadatasForMappingSources();
}
foreach ($metadatas as $metadata) {
$printer->writeln(
sprintf(
'Processing entity "%s"',
$printer->format($metadata->name, 'KEYWORD')
)
sprintf('Processing entity "%s"', $printer->format($metadata->name, 'KEYWORD'))
);
}
$printer->writeln(
sprintf(
'Exporting "%s" mapping information to directory "%s"',
$printer->format($args['to'], 'KEYWORD'),
$printer->format($args['dest'], 'KEYWORD')
$printer->format($arguments['to'], 'KEYWORD'),
$printer->format($arguments['dest'], 'KEYWORD')
)
);
@ -167,9 +183,11 @@ class ConvertMappingTask extends AbstractTask
}
$files = glob(current($from) . '/*.yml');
if ($files) {
$array = \sfYaml::load($files[0]);
$first = current($array);
// We're dealing with a Doctrine 1 schema if you have
// a columns index in the first model array
return isset($first['columns']);
@ -185,6 +203,7 @@ class ConvertMappingTask extends AbstractTask
if (is_dir($source)) {
// Find the files in the directory
$files = glob($source . '/*.*');
if ( ! $files) {
throw new \InvalidArgumentException(
sprintf('No mapping files found in "%s"', $source)
@ -201,6 +220,7 @@ class ConvertMappingTask extends AbstractTask
// first file in the directory (yml, xml, etc)
} else {
$info = pathinfo($files[0]);
return $info['extension'];
}
// Nothing special for database
@ -214,7 +234,9 @@ class ConvertMappingTask extends AbstractTask
// If --from==database then the source is an instance of SchemaManager
// for the current EntityMAnager
if ($type == 'database') {
return $this->_em->getConnection()->getSchemaManager();
$em = $this->getConfiguration->getAttribute('em');
return $em->getConnection()->getSchemaManager();
} else {
return $source;
}

View File

@ -21,7 +21,8 @@
namespace Doctrine\ORM\Tools\Cli\Tasks;
use Doctrine\Common\Cache\AbstractDriver;
use Doctrine\Common\Cli\Tasks\AbstractTask,
Doctrine\Common\Cli\CliException;
/**
* CLI Task to ensure that Doctrine is properly configured for a production environment.
@ -30,6 +31,7 @@ use Doctrine\Common\Cache\AbstractDriver;
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
@ -51,17 +53,24 @@ class EnsureProductionSettingsTask extends AbstractTask
*/
public function validate()
{
// Check if we have an active EntityManager
$em = $this->getConfiguration()->getAttribute('em');
if ($em === null) {
throw new CliException(
"Attribute 'em' of CLI Configuration is not defined or it is not a valid EntityManager."
);
}
return true;
}
/**
* @inheritdoc
*/
public function run()
{
$printer = $this->getPrinter();
try {
$this->getEntityManager()->getConfiguration()->ensureProductionSettings();
} catch (\Doctrine\Common\DoctrineException $e) {
$printer->writeln($e->getMessage(), 'ERROR');
}
$em = $this->getConfiguration()->getAttribute('em');
$em->getConfiguration()->ensureProductionSettings();
}
}

View File

@ -2,7 +2,8 @@
namespace Doctrine\ORM\Tools\Cli\Tasks;
use Doctrine\Common\DoctrineException,
use Doctrine\Common\Cli\Tasks\AbstractTask,
Doctrine\Common\Cli\CliException,
Doctrine\Common\Cli\Option,
Doctrine\Common\Cli\OptionGroup;
@ -24,6 +25,10 @@ class GenerateProxiesTask extends AbstractTask
*/
public function buildDocumentation()
{
$classDir = new OptionGroup(OptionGroup::CARDINALITY_1_1, array(
new Option('class-dir', '<PATH>', 'Specified directory where mapping classes are located.')
));
$toDir = new OptionGroup(OptionGroup::CARDINALITY_0_1, array(
new Option('to-dir', '<PATH>', 'Generates the classes in the specified directory.')
));
@ -32,6 +37,7 @@ class GenerateProxiesTask extends AbstractTask
$doc->setName('generate-proxies')
->setDescription('Generates proxy classes for entity classes.')
->getOptionGroup()
->addOption($classDir)
->addOption($toDir);
}
@ -40,18 +46,25 @@ class GenerateProxiesTask extends AbstractTask
*/
public function validate()
{
$args = $this->getArguments();
$printer = $this->getPrinter();
$arguments = $this->getArguments();
$em = $this->getConfiguration()->getAttribute('em');
$metadataDriver = $this->getEntityManager()->getConfiguration()->getMetadataDriverImpl();
if ($em === null) {
throw new CliException(
"Attribute 'em' of CLI Configuration is not defined or it is not a valid EntityManager."
);
}
$metadataDriver = $em->getConfiguration()->getMetadataDriverImpl();
if ($metadataDriver instanceof \Doctrine\ORM\Mapping\Driver\AnnotationDriver) {
if ( ! isset($args['class-dir'])) {
$printer->writeln("The supplied configuration uses the annotation metadata driver."
. " The 'class-dir' argument is required for this driver.", 'ERROR');
return false;
} else {
if (isset($arguments['class-dir'])) {
$metadataDriver->setClassDirectory($args['class-dir']);
} else {
throw new CliException(
'The supplied configuration uses the annotation metadata driver. ' .
"The 'class-dir' argument is required for this driver."
);
}
}
@ -59,30 +72,29 @@ class GenerateProxiesTask extends AbstractTask
}
/**
* Executes the task.
* @inheritdoc
*/
public function run()
{
$args = $this->getArguments();
$em = $this->getEntityManager();
$cmf = $em->getMetadataFactory();
$classes = $cmf->getAllMetadata();
$arguments = $this->getArguments();
$printer = $this->getPrinter();
$em = $this->getConfiguration->getAttribute('em');
$cmf = $em->getMetadataFactory();
$classes = $cmf->getAllMetadata();
$factory = $em->getProxyFactory();
if (empty($classes)) {
$printer->writeln('No classes to process.', 'INFO');
return;
}
$factory->generateProxyClasses($classes, isset($args['to-dir']) ? $args['to-dir'] : null);
} else {
$factory->generateProxyClasses(
$classes, isset($arguments['to-dir']) ? $arguments['to-dir'] : null
);
$printer->writeln(
'Proxy classes generated to: ' .
(isset($args['to-dir']) ? $args['to-dir'] : $em->getConfiguration()->getProxyDir())
);
$printer->writeln(
'Proxy classes generated to: ' . (isset($arguments['to-dir'])
? $arguments['to-dir'] : $em->getConfiguration()->getProxyDir())
);
}
}
}

View File

@ -21,7 +21,8 @@
namespace Doctrine\ORM\Tools\Cli\Tasks;
use Doctrine\Common\DoctrineException,
use Doctrine\Common\Cli\Tasks\AbstractTask,
Doctrine\Common\Cli\CliException,
Doctrine\Common\Util\Debug,
Doctrine\Common\Cli\Option,
Doctrine\Common\Cli\OptionGroup;
@ -65,12 +66,17 @@ class RunDqlTask extends AbstractTask
*/
public function validate()
{
$args = $this->getArguments();
$printer = $this->getPrinter();
$arguments = $this->getArguments();
$em = $this->getConfiguration()->getAttribute('em');
if ( ! isset($args['dql'])) {
$printer->writeln("Argument --dql must be defined.", 'ERROR');
return false;
if ($em === null) {
throw new CliException(
"Attribute 'em' of CLI Configuration is not defined or it is not a valid EntityManager."
);
}
if ( ! isset($arguments['dql'])) {
throw new CliException('Argument --dql must be defined.');
}
return true;
@ -78,21 +84,16 @@ class RunDqlTask extends AbstractTask
/**
* Executes the task.
* @inheritdoc
*/
public function run()
{
$args = $this->getArguments();
$arguments = $this->getArguments();
$em = $this->getConfiguration()->getAttribute('em');
$query = $em->createQuery($arguments['dql']);
$resultSet = $query->getResult();
$maxDepth = isset($arguments['depth']) ? $arguments['depth'] : 7;
try {
$query = $this->getEntityManager()->createQuery($args['dql']);
$resultSet = $query->getResult();
$maxDepth = isset($args['depth']) ? $args['depth'] : 7;
Debug::dump($resultSet, $maxDepth);
} catch (\Exception $ex) {
throw new DoctrineException($ex);
}
Debug::dump($resultSet, $maxDepth);
}
}

View File

@ -2,7 +2,8 @@
namespace Doctrine\ORM\Tools\Cli\Tasks;
use Doctrine\Common\DoctrineException,
use Doctrine\Common\Cli\Tasks\AbstractTask,
Doctrine\Common\Cli\CliException,
Doctrine\Common\Cli\Option,
Doctrine\Common\Cli\OptionGroup,
Doctrine\ORM\Tools\SchemaTool,
@ -100,44 +101,56 @@ class SchemaToolTask extends AbstractTask
*/
public function validate()
{
$args = $this->getArguments();
$printer = $this->getPrinter();
$arguments = $this->getArguments();
$em = $this->getConfiguration()->getAttribute('em');
if (array_key_exists('re-create', $args)) {
$args['drop'] = true;
$args['create'] = true;
$this->setArguments($args);
if ($em === null) {
throw new CliException(
"Attribute 'em' of CLI Configuration is not defined or it is not a valid EntityManager."
);
}
$isCreate = isset($args['create']);
$isDrop = isset($args['drop']);
$isUpdate = isset($args['update']);
$isCompleteUpdate = isset($args['complete-update']);
if (isset($arguments['re-create'])) {
$arguments['drop'] = true;
$arguments['create'] = true;
unset($arguments['re-create']);
$this->setArguments($arguments);
}
$isCreate = isset($arguments['create']) && $arguments['create'];
$isDrop = isset($arguments['drop']) && $arguments['drop'];
$isUpdate = isset($arguments['update']) && $arguments['update'];
$isCompleteUpdate = isset($arguments['complete-update']) && $arguments['complete-update'];
if ($isUpdate && ($isCreate || $isDrop || $isCompleteUpdate)) {
$printer->writeln("You can't use --update with --create, --drop or --complete-update", 'ERROR');
return false;
throw new CliException(
'You cannot use --update with --create, --drop or --complete-update.'
);
}
if ($isCompleteUpdate && ($isCreate || $isDrop || $isUpdate)) {
$printer->writeln("You can't use --update with --create, --drop or --update", 'ERROR');
return false;
throw new CliException('You cannot use --update with --create, --drop or --update.');
}
if ( ! ($isCreate || $isDrop || $isUpdate || $isCompleteUpdate)) {
$printer->writeln('You must specify at a minimum one of the options (--create, --drop, --update, --re-create, --complete-update).', 'ERROR');
return false;
throw new CliException(
'You must specify at a minimum one of the options ' .
'(--create, --drop, --update, --re-create or --complete-update).'
);
}
$metadataDriver = $this->getEntityManager()->getConfiguration()->getMetadataDriverImpl();
if ($metadataDriver instanceof \Doctrine\ORM\Mapping\Driver\AnnotationDriver) {
if ( ! isset($args['class-dir'])) {
$printer->writeln("The supplied configuration uses the annotation metadata driver."
. " The 'class-dir' argument is required for this driver.", 'ERROR');
return false;
} else {
if (isset($args['class-dir'])) {
$metadataDriver->setClassDirectory($args['class-dir']);
} else {
throw new CliException(
'The supplied configuration uses the annotation metadata driver. ' .
"The 'class-dir' argument is required for this driver."
);
}
}
@ -145,80 +158,66 @@ class SchemaToolTask extends AbstractTask
}
/**
* Executes the task.
* @inheritdoc
*/
public function run()
{
$args = $this->getArguments();
$isCreate = isset($args['create']);
$isDrop = isset($args['drop']);
$isUpdate = isset($args['update']);
$isCompleteUpdate = isset($args['complete-update']);
$em = $this->getEntityManager();
$cmf = $em->getMetadataFactory();
$classes = $cmf->getAllMetadata();
$arguments = $this->getArguments();
$printer = $this->getPrinter();
$isCreate = isset($arguments['create']) && $arguments['create'];
$isDrop = isset($arguments['drop']) && $arguments['drop'];
$isUpdate = isset($arguments['update']) && $arguments['update'];
$isCompleteUpdate = isset($arguments['complete-update']) && $arguments['complete-update'];
$em = $this->getConfiguration()->getAttribute('em');
$cmf = $em->getMetadataFactory();
$classes = $cmf->getAllMetadata();
if (empty($classes)) {
$printer->writeln('No classes to process.', 'INFO');
return;
}
$tool = new SchemaTool($em);
if ($isDrop) {
if (isset($args['dump-sql'])) {
if (isset($arguments['dump-sql'])) {
foreach ($tool->getDropSchemaSql($classes) as $sql) {
$printer->writeln($sql);
}
} else {
$printer->writeln('Dropping database schema...', 'INFO');
try {
$tool->dropSchema($classes);
$printer->writeln('Database schema dropped successfully.', 'INFO');
} catch (\Exception $ex) {
throw new DoctrineException($ex);
}
$tool->dropSchema($classes);
$printer->writeln('Database schema dropped successfully.', 'INFO');
}
}
if ($isCreate) {
if (isset($args['dump-sql'])) {
if (isset($arguments['dump-sql'])) {
foreach ($tool->getCreateSchemaSql($classes) as $sql) {
$printer->writeln($sql);
}
} else {
$printer->writeln('Creating database schema...', 'INFO');
try {
$tool->createSchema($classes);
$printer->writeln('Database schema created successfully.', 'INFO');
} catch (\Exception $ex) {
throw new DoctrineException($ex);
}
$tool->createSchema($classes);
$printer->writeln('Database schema created successfully.', 'INFO');
}
}
if ($isUpdate || $isCompleteUpdate) {
$saveMode = $isUpdate?true:false;
if (isset($args['dump-sql'])) {
$saveMode = $isUpdate ? true : false;
if (isset($arguments['dump-sql'])) {
foreach ($tool->getUpdateSchemaSql($classes, $saveMode) as $sql) {
$printer->writeln($sql);
}
} else {
$printer->writeln('Updating database schema...', 'INFO');
try {
$tool->updateSchema($classes, $saveMode);
$printer->writeln('Database schema updated successfully.', 'INFO');
} catch (\Exception $ex) {
throw new DoctrineException($ex);
}
$tool->updateSchema($classes, $saveMode);
$printer->writeln('Database schema updated successfully.', 'INFO');
}
}
}

View File

@ -21,6 +21,8 @@
namespace Doctrine\ORM\Tools\Cli\Tasks;
use Doctrine\Common\Cli\Tasks\AbstractTask;
/**
* CLI Task to display the doctrine version
*
@ -28,6 +30,7 @@ namespace Doctrine\ORM\Tools\Cli\Tasks;
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
@ -46,14 +49,6 @@ class VersionTask extends AbstractTask
$doc->setName('version')
->setDescription('Displays the current installed Doctrine version.');
}
/**
* @inheritdoc
*/
public function validate()
{
return true;
}
/**
* Displays the current version of Doctrine

View File

@ -32,9 +32,7 @@ $connectionOptions = array(
'path' => 'database.sqlite'
);
// These are required named variables (names can't change!)
$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
$globalArguments = array(
'class-dir' => './Entities'
);
$configuration = new \Doctrine\Common\Cli\Configuration();
$configuration->setAttribute('em', $em);

View File

@ -1,9 +1,13 @@
<?php
require __DIR__ . '/../../lib/Doctrine/Common/ClassLoader.php';
require_once __DIR__ . '/../../lib/Doctrine/Common/ClassLoader.php';
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine', __DIR__ . '/../../lib');
$classLoader = new \Doctrine\Common\ClassLoader();
$classLoader->setIncludePath(__DIR__ . '/../../lib');
$classLoader->register();
$cli = new \Doctrine\ORM\Tools\Cli\CliController();
// Variable $configuration is defined inside cli-config.php
require_once __DIR__ . '/cli-config.php';
$cli = new \Doctrine\Common\Cli\CliController($configuration);
$cli->run($_SERVER['argv']);