Browse Source

Merge branch 'master' of dev.yiisoft.com:yii2

tags/2.0.0-beta
Qiang Xue 13 years ago
parent
commit
59f57a820d
  1. 9
      docs/internals/errors_and_exceptions.md
  2. 12
      docs/internals/versions.md
  3. 7
      framework/YiiBase.php
  4. 58
      framework/base/Application.php
  5. 2
      framework/base/Event.php
  6. 14
      framework/base/Module.php
  7. 181
      framework/console/Application.php
  8. 339
      framework/console/Command.php
  9. 142
      framework/console/CommandRunner.php
  10. 77
      framework/console/HelpCommand.php
  11. 9
      framework/db/Migration.php
  12. 86
      framework/db/ar/ActiveRecord.php
  13. 5
      framework/db/ar/ActiveRecordBehavior.php
  14. 1
      framework/db/dao/Command.php
  15. 7
      framework/db/dao/Query.php
  16. 5
      framework/db/dao/QueryBuilder.php
  17. 2
      framework/db/dao/Schema.php
  18. 2
      framework/db/dao/mysql/QueryBuilder.php
  19. 5
      framework/logging/ProfileTarget.php
  20. 4
      framework/logging/WebTarget.php
  21. 141
      framework/util/File.php
  22. 43
      framework/util/Text.php
  23. 4
      framework/validators/DateValidator.php
  24. 5
      framework/validators/ExistValidator.php
  25. 4
      framework/validators/FileValidator.php
  26. 6
      framework/validators/UniqueValidator.php
  27. 40
      framework/web/HttpException.php
  28. 14
      framework/yiic
  29. 22
      framework/yiic.bat
  30. 30
      framework/yiic.php
  31. 2
      todo.md

9
docs/internals/errors_and_exceptions.md

@ -0,0 +1,9 @@
Errors and Exceptions
=====================
Errors i18n
-----------
A general rule is to tranlate only errors that are shown to end users only. If
it is a regular exception, debug screen etc. then message should not be translated.

12
docs/internals/versions.md

@ -0,0 +1,12 @@
Yii version numbering
=====================
A.B.C
A = For Yii2 it's always 2.
B = Major version. Non-BC changes with upgrade instructions.
C = BC changes and additions.
A.B.CrcD
This is when we want to release release candidate. D is the RC number. Starts with 1 and increments till we're getting a stable release with no critical bugs and BC incompatibility reports.

7
framework/YiiBase.php

@ -477,7 +477,7 @@ class YiiBase
/**
* Translates a message to the specified language.
* Starting from version 1.0.2, this method supports choice format (see {@link CChoiceFormat}),
* This method supports choice format (see {@link CChoiceFormat}),
* i.e., the message returned will be chosen from a few candidates according to the given
* number value. This feature is mainly used to solve plural format issue in case
* a message has different plural forms in some languages.
@ -486,16 +486,15 @@ class YiiBase
* more interpretation about message category.
* @param string $message the original message
* @param array $params parameters to be applied to the message using <code>strtr</code>.
* Starting from version 1.0.2, the first parameter can be a number without key.
* The first parameter can be a number without key.
* And in this case, the method will call {@link CChoiceFormat::format} to choose
* an appropriate message translation.
* Starting from version 1.1.6 you can pass parameter for {@link CChoiceFormat::format}
* You can pass parameter for {@link CChoiceFormat::format}
* or plural forms format without wrapping it with array.
* @param string $source which message source application component to use.
* Defaults to null, meaning using 'coreMessages' for messages belonging to
* the 'yii' category and using 'messages' for the rest messages.
* @param string $language the target language. If null (default), the {@link CApplication::getLanguage application language} will be used.
* This parameter has been available since version 1.0.3.
* @return string the translated message
* @see CMessageSource
*/

58
framework/base/Application.php

@ -8,6 +8,8 @@
* @license http://www.yiiframework.com/license/
*/
namespace yii\base;
/**
* Application is the base class for all application classes.
*
@ -114,7 +116,7 @@ abstract class Application extends Module
*/
public function __construct($config = null)
{
Yii::setApplication($this);
\Yii::$app = $this;
// set basePath at early as possible to avoid trouble
if (is_string($config))
@ -126,9 +128,9 @@ abstract class Application extends Module
}
else
$this->setBasePath('protected');
Yii::setPathOfAlias('application', $this->getBasePath());
Yii::setPathOfAlias('webroot', dirname($_SERVER['SCRIPT_FILENAME']));
Yii::setPathOfAlias('ext', $this->getBasePath() . DIRECTORY_SEPARATOR . 'extensions');
\Yii::setAlias('application', $this->getBasePath());
\Yii::setAlias('webroot', dirname($_SERVER['SCRIPT_FILENAME']));
\Yii::setAlias('ext', $this->getBasePath() . DIRECTORY_SEPARATOR . 'extensions');
$this->preinit();
@ -151,10 +153,10 @@ abstract class Application extends Module
*/
public function run()
{
if ($this->hasEventHandler('onBeginRequest'))
if ($this->hasEventHandlers('onBeginRequest'))
$this->onBeginRequest(new CEvent($this));
$this->processRequest();
if ($this->hasEventHandler('onEndRequest'))
if ($this->hasEventHandlers('onEndRequest'))
$this->onEndRequest(new CEvent($this));
}
@ -168,7 +170,7 @@ abstract class Application extends Module
*/
public function end($status = 0, $exit = true)
{
if ($this->hasEventHandler('onEndRequest'))
if ($this->hasEventHandlers('onEndRequest'))
$this->onEndRequest(new CEvent($this));
if ($exit)
exit($status);
@ -235,7 +237,7 @@ abstract class Application extends Module
public function setBasePath($path)
{
if (($this->_basePath = realpath($path)) === false || !is_dir($this->_basePath))
throw new CException(Yii::t('yii', 'Application base path "{path}" is not a valid directory.',
throw new \yii\base\Exception(\Yii::t('yii', 'Application base path "{path}" is not a valid directory.',
array('{path}' => $path)));
}
@ -262,7 +264,7 @@ abstract class Application extends Module
public function setRuntimePath($path)
{
if (($runtimePath = realpath($path)) === false || !is_dir($runtimePath) || !is_writable($runtimePath))
throw new CException(Yii::t('yii', 'Application runtime path "{path}" is not valid. Please make sure it is a directory writable by the Web server process.',
throw new \yii\base\Exception(\Yii::t('yii', 'Application runtime path "{path}" is not valid. Please make sure it is a directory writable by the Web server process.',
array('{path}' => $path)));
$this->_runtimePath = $runtimePath;
}
@ -273,7 +275,7 @@ abstract class Application extends Module
*/
public function getExtensionPath()
{
return Yii::getPathOfAlias('ext');
return \Yii::getPathOfAlias('ext');
}
/**
@ -283,9 +285,9 @@ abstract class Application extends Module
public function setExtensionPath($path)
{
if (($extensionPath = realpath($path)) === false || !is_dir($extensionPath))
throw new CException(Yii::t('yii', 'Extension path "{path}" does not exist.',
throw new \yii\base\Exception(\Yii::t('yii', 'Extension path "{path}" does not exist.',
array('{path}' => $path)));
Yii::setPathOfAlias('ext', $extensionPath);
\Yii::setAlias('ext', $extensionPath);
}
/**
@ -319,7 +321,6 @@ abstract class Application extends Module
* This is a simple wrapper of PHP function date_default_timezone_get().
* @return string the time zone used by this application.
* @see http://php.net/manual/en/function.date-default-timezone-get.php
* @since 1.0.9
*/
public function getTimeZone()
{
@ -331,7 +332,6 @@ abstract class Application extends Module
* This is a simple wrapper of PHP function date_default_timezone_set().
* @param string $value the time zone used by this application.
* @see http://php.net/manual/en/function.date-default-timezone-set.php
* @since 1.0.9
*/
public function setTimeZone($value)
{
@ -382,17 +382,15 @@ abstract class Application extends Module
/**
* Returns the directory that contains the locale data.
* @return string the directory that contains the locale data. It defaults to 'framework/i18n/data'.
* @since 1.1.0
*/
public function getLocaleDataPath()
{
return CLocale::$dataPath === null ? Yii::getPathOfAlias('system.i18n.data') : CLocale::$dataPath;
return CLocale::$dataPath === null ? \Yii::getPathOfAlias('system.i18n.data') : CLocale::$dataPath;
}
/**
* Sets the directory that contains the locale data.
* @param string $value the directory that contains the locale data.
* @since 1.1.0
*/
public function setLocaleDataPath($value)
{
@ -501,7 +499,6 @@ abstract class Application extends Module
/**
* @return CController the currently active controller. Null is returned in this base class.
* @since 1.1.8
*/
public function getController()
{
@ -641,7 +638,7 @@ abstract class Application extends Module
/**
* Loads the global state data from persistent storage.
* @see getStatePersister
* @throws CException if the state persister is not available
* @throws \yii\base\Exception if the state persister is not available
*/
public function loadGlobalState()
{
@ -688,25 +685,31 @@ abstract class Application extends Module
restore_exception_handler();
$category = 'exception.' . get_class($exception);
if ($exception instanceof CHttpException)
if ($exception instanceof \yii\web\HttpException)
$category .= '.' . $exception->statusCode;
// php <5.2 doesn't support string conversion auto-magically
$message = $exception->__toString();
if (isset($_SERVER['REQUEST_URI']))
$message .= ' REQUEST_URI=' . $_SERVER['REQUEST_URI'];
Yii::log($message, CLogger::LEVEL_ERROR, $category);
\Yii::error($message, $category);
try
{
$event = new CExceptionEvent($this, $exception);
// TODO: do we need separate exception class as it was in 1.1?
//$event = new CExceptionEvent($this, $exception);
$event = new Event($this, array('exception' => $exception));
$this->onException($event);
if (!$event->handled)
{
// try an error handler
if (($handler = $this->getErrorHandler()) !== null)
{
$handler->handle($event);
}
else
{
$this->displayException($exception);
}
}
}
catch(Exception $e)
@ -777,11 +780,11 @@ abstract class Application extends Module
}
if (isset($_SERVER['REQUEST_URI']))
$log .= 'REQUEST_URI=' . $_SERVER['REQUEST_URI'];
Yii::log($log, CLogger::LEVEL_ERROR, 'php');
\Yii::error($log, 'php');
try
{
Yii::import('CErrorEvent', true);
\Yii::import('CErrorEvent', true);
$event = new CErrorEvent($this, $code, $message, $file, $line);
$this->onError($event);
if (!$event->handled)
@ -940,9 +943,10 @@ abstract class Application extends Module
'messages' => array(
'class' => 'CPhpMessageSource',
),
'errorHandler' => array(
'class' => 'CErrorHandler',
),
// TODO: uncomment when error handler is properly implemented
// 'errorHandler' => array(
// 'class' => 'CErrorHandler',
// ),
'securityManager' => array(
'class' => 'CSecurityManager',
),

2
framework/base/Event.php

@ -47,7 +47,9 @@ class Event extends Object
/**
* Constructor.
*
* @param mixed $sender sender of the event
* @param mixed $params parameters of the event
*/
public function __construct($sender=null, $params=null)
{

14
framework/base/Module.php

@ -253,13 +253,17 @@ abstract class Module extends Component
$config = $this->_moduleConfig[$id];
if (!isset($config['enabled']) || $config['enabled'])
{
Yii::trace("Loading \"$id\" module", 'system.base.CModule');
\Yii::trace("Loading \"$id\" module", 'system.base.CModule');
$class = $config['class'];
unset($config['class'], $config['enabled']);
if ($this === Yii::app())
if ($this === \Yii::$app)
{
$module = Yii::create($class, $id, null, $config);
}
else
{
$module = Yii::create($class, $this->getId() . '/' . $id, $this, $config);
}
return $this->_modules[$id] = $module;
}
}
@ -269,7 +273,6 @@ abstract class Module extends Component
* Returns a value indicating whether the specified module is installed.
* @param string $id the module ID
* @return boolean whether the specified module is installed.
* @since 1.1.2
*/
public function hasModule($id)
{
@ -360,10 +363,9 @@ abstract class Module extends Component
$config = $this->_componentConfig[$id];
if (!isset($config['enabled']) || $config['enabled'])
{
Yii::trace("Loading \"$id\" application component", 'system.CModule');
\Yii::trace("Loading \"$id\" application component", 'system.CModule');
unset($config['enabled']);
$component = Yii::create($config);
$component->init();
$component = \Yii::create($config);
return $this->_components[$id] = $component;
}
}

181
framework/console/Application.php

@ -0,0 +1,181 @@
<?php
/**
* Console Application class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2012 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\console;
/**
* \yii\console\Application represents a console application.
*
* \yii\console\Application extends {@link \yii\base\Application} by providing functionalities
* specific to console requests. In particular, it deals with console requests
* through a command-based approach:
* <ul>
* <li>A console application consists of one or several possible user commands;</li>
* <li>Each user command is implemented as a class extending {@link \yii\console\Command};</li>
* <li>User specifies which command to run on the command line;</li>
* <li>The command processes the user request with the specified parameters.</li>
* </ul>
*
* The command classes reside in the directory {@link getCommandPath commandPath}.
* The name of the class follows the pattern: &lt;command-name&gt;Command, and its
* file name is the same the class name. For example, the 'ShellCommand' class defines
* a 'shell' command and the class file name is 'ShellCommand.php'.
*
* To run the console application, enter the following on the command line:
* <pre>
* php path/to/entry_script.php <command name> [param 1] [param 2] ...
* </pre>
*
* You may use the following to see help instructions about a command:
* <pre>
* php path/to/entry_script.php help <command name>
* </pre>
*
* @property string $commandPath The directory that contains the command classes. Defaults to 'protected/commands'.
* @property CommandRunner $commandRunner The command runner.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Application extends \yii\base\Application
{
/**
* @var array mapping from command name to command configurations.
* Each command configuration can be either a string or an array.
* If the former, the string should be the file path of the command class.
* If the latter, the array must contain a 'class' element which specifies
* the command's class name or {@link \YiiBase::getPathOfAlias class path alias}.
* The rest name-value pairs in the array are used to initialize
* the corresponding command properties. For example,
* <pre>
* array(
* 'email'=>array(
* 'class'=>'path.to.Mailer',
* 'interval'=>3600,
* ),
* 'log'=>'path/to/LoggerCommand.php',
* )
* </pre>
*/
public $commandMap=array();
private $_commandPath;
/**
* @var \yii\console\CommandRunner
*/
private $_runner;
/**
* Initializes the application by creating the command runner.
*/
public function init()
{
if(!isset($_SERVER['argv']))
{
die('This script must be run from the command line.');
}
$this->_runner=$this->createCommandRunner();
$this->_runner->commands=$this->commandMap;
$this->_runner->addCommands($this->getCommandPath());
}
/**
* Processes the user request.
* This method creates a console command runner to handle the particular user command.
*/
public function processRequest()
{
$this->_runner->run($_SERVER['argv']);
}
/**
* Creates the command runner instance.
* @return CommandRunner the command runner
*/
protected function createCommandRunner()
{
return new CommandRunner();
}
/**
* Displays the captured PHP error.
* This method displays the error in console mode when there is
* no active error handler.
* @param integer $code error code
* @param string $message error message
* @param string $file error file
* @param string $line error line
*/
public function displayError($code,$message,$file,$line)
{
echo "PHP Error[$code]: $message\n";
echo " in file $file at line $line\n";
$trace=debug_backtrace();
// skip the first 4 stacks as they do not tell the error position
if(count($trace)>4)
$trace=array_slice($trace,4);
foreach($trace as $i=>$t)
{
if(!isset($t['file']))
$t['file']='unknown';
if(!isset($t['line']))
$t['line']=0;
if(!isset($t['function']))
$t['function']='unknown';
echo "#$i {$t['file']}({$t['line']}): ";
if(isset($t['object']) && is_object($t['object']))
echo get_class($t['object']).'->';
echo "{$t['function']}()\n";
}
}
/**
* Displays the uncaught PHP exception.
* This method displays the exception in console mode when there is
* no active error handler.
* @param Exception $exception the uncaught exception
*/
public function displayException($exception)
{
echo $exception;
}
/**
* @return string the directory that contains the command classes. Defaults to 'protected/commands'.
*/
public function getCommandPath()
{
$applicationCommandPath = $this->getBasePath().DIRECTORY_SEPARATOR.'commands';
if($this->_commandPath===null && file_exists($applicationCommandPath))
$this->setCommandPath($applicationCommandPath);
return $this->_commandPath;
}
/**
* @param string $value the directory that contains the command classes.
* @throws CException if the directory is invalid
*/
public function setCommandPath($value)
{
if(($this->_commandPath=realpath($value))===false || !is_dir($this->_commandPath))
throw new \yii\base\Exception(Yii::t('yii','The command path "{path}" is not a valid directory.',
array('{path}'=>$value)));
}
/**
* Returns the command runner.
* @return CConsoleCommandRunner the command runner.
*/
public function getCommandRunner()
{
return $this->_runner;
}
}

339
framework/console/Command.php

@ -0,0 +1,339 @@
<?php
/**
* Command class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2011 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\console;
/**
* Command represents an executable console command.
*
* It works like {@link \yii\web\Controller} by parsing command line options and dispatching
* the request to a specific action with appropriate option values.
*
* Users call a console command via the following command format:
* <pre>
* yiic CommandName ActionName --Option1=Value1 --Option2=Value2 ...
* </pre>
*
* Child classes mainly needs to implement various action methods whose name must be
* prefixed with "action". The parameters to an action method are considered as options
* for that specific action. The action specified as {@link defaultAction} will be invoked
* when a user does not specify the action name in his command.
*
* Options are bound to action parameters via parameter names. For example, the following
* action method will allow us to run a command with <code>yiic sitemap --type=News</code>:
* <pre>
* class SitemapCommand {
* public function actionIndex($type) {
* ....
* }
* }
* </pre>
*
* @property string $name The command name.
* @property CommandRunner $commandRunner The command runner instance.
* @property string $help The command description. Defaults to 'Usage: php entry-script.php command-name'.
* @property array $optionHelp The command option help information. Each array element describes
* the help information for a single action.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
abstract class Command extends \yii\base\Component
{
/**
* @var string the name of the default action. Defaults to 'index'.
*/
public $defaultAction='index';
private $_name;
private $_runner;
/**
* Constructor.
* @param string $name name of the command
* @param CConsoleCommandRunner $runner the command runner
*/
public function __construct($name,$runner)
{
$this->_name=$name;
$this->_runner=$runner;
}
/**
* Initializes the command object.
* This method is invoked after a command object is created and initialized with configurations.
* You may override this method to further customize the command before it executes.
*/
public function init()
{
}
/**
* Executes the command.
* The default implementation will parse the input parameters and
* dispatch the command request to an appropriate action with the corresponding
* option values
* @param array $args command line parameters for this command.
*/
public function run($args)
{
list($action, $options, $args)=$this->resolveRequest($args);
$methodName='action'.$action;
if(!preg_match('/^\w+$/',$action) || !method_exists($this,$methodName))
$this->usageError("Unknown action: ".$action);
$method=new \ReflectionMethod($this,$methodName);
$params=array();
// named and unnamed options
foreach($method->getParameters() as $param)
{
$name=$param->getName();
if(isset($options[$name]))
{
if($param->isArray())
$params[]=is_array($options[$name]) ? $options[$name] : array($options[$name]);
else if(!is_array($options[$name]))
$params[]=$options[$name];
else
$this->usageError("Option --$name requires a scalar. Array is given.");
}
else if($name==='args')
$params[]=$args;
else if($param->isDefaultValueAvailable())
$params[]=$param->getDefaultValue();
else
$this->usageError("Missing required option --$name.");
unset($options[$name]);
}
// try global options
if(!empty($options))
{
$class=new \ReflectionClass(get_class($this));
foreach($options as $name=>$value)
{
if($class->hasProperty($name))
{
$property=$class->getProperty($name);
if($property->isPublic() && !$property->isStatic())
{
$this->$name=$value;
unset($options[$name]);
}
}
}
}
if(!empty($options))
$this->usageError("Unknown options: ".implode(', ',array_keys($options)));
if($this->beforeAction($action,$params))
{
$method->invokeArgs($this,$params);
$this->afterAction($action,$params);
}
}
/**
* This method is invoked right before an action is to be executed.
* You may override this method to do last-minute preparation for the action.
* @param string $action the action name
* @param array $params the parameters to be passed to the action method.
* @return boolean whether the action should be executed.
*/
protected function beforeAction($action,$params)
{
return true;
}
/**
* This method is invoked right after an action finishes execution.
* You may override this method to do some postprocessing for the action.
* @param string $action the action name
* @param array $params the parameters to be passed to the action method.
*/
protected function afterAction($action,$params)
{
}
/**
* Parses the command line arguments and determines which action to perform.
* @param array $args command line arguments
* @return array the action name, named options (name=>value), and unnamed options
*/
protected function resolveRequest($args)
{
$options=array(); // named parameters
$params=array(); // unnamed parameters
foreach($args as $arg)
{
if(preg_match('/^--(\w+)(=(.*))?$/',$arg,$matches)) // an option
{
$name=$matches[1];
$value=isset($matches[3]) ? $matches[3] : true;
if(isset($options[$name]))
{
if(!is_array($options[$name]))
$options[$name]=array($options[$name]);
$options[$name][]=$value;
}
else
$options[$name]=$value;
}
else if(isset($action))
$params[]=$arg;
else
$action=$arg;
}
if(!isset($action))
$action=$this->defaultAction;
return array($action,$options,$params);
}
/**
* @return string the command name.
*/
public function getName()
{
return $this->_name;
}
/**
* @return \yii\console\CommandRunner the command runner instance
*/
public function getCommandRunner()
{
return $this->_runner;
}
/**
* Provides the command description.
* This method may be overridden to return the actual command description.
* @return string the command description. Defaults to 'Usage: php entry-script.php command-name'.
*/
public function getHelp()
{
$help='Usage: '.$this->getCommandRunner()->getScriptName().' '.$this->getName();
$options=$this->getOptionHelp();
if(empty($options))
return $help;
if(count($options)===1)
return $help.' '.$options[0];
$help.=" <action>\nActions:\n";
foreach($options as $option)
$help.=' '.$option."\n";
return $help;
}
/**
* Provides the command option help information.
* The default implementation will return all available actions together with their
* corresponding option information.
* @return array the command option help information. Each array element describes
* the help information for a single action.
*/
public function getOptionHelp()
{
$options=array();
$class=new \ReflectionClass(get_class($this));
foreach($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method)
{
$name=$method->getName();
if(!strncasecmp($name,'action',6) && strlen($name)>6)
{
$name=substr($name,6);
$name[0]=strtolower($name[0]);
$help=$name;
foreach($method->getParameters() as $param)
{
$optional=$param->isDefaultValueAvailable();
$defaultValue=$optional ? $param->getDefaultValue() : null;
$name=$param->getName();
if($optional)
$help.=" [--$name=$defaultValue]";
else
$help.=" --$name=value";
}
$options[]=$help;
}
}
return $options;
}
/**
* Displays a usage error.
* This method will then terminate the execution of the current application.
* @param string $message the error message
*/
public function usageError($message)
{
echo "Error: $message\n\n".$this->getHelp()."\n";
exit(1);
}
/**
* Renders a view file.
* @param string $_viewFile_ view file path
* @param array $_data_ optional data to be extracted as local view variables
* @param boolean $_return_ whether to return the rendering result instead of displaying it
* @return mixed the rendering result if required. Null otherwise.
*/
public function renderFile($_viewFile_,$_data_=null,$_return_=false)
{
if(is_array($_data_))
extract($_data_,EXTR_PREFIX_SAME,'data');
else
$data=$_data_;
if($_return_)
{
ob_start();
ob_implicit_flush(false);
require($_viewFile_);
return ob_get_clean();
}
else
require($_viewFile_);
}
/**
* Reads input via the readline PHP extension if that's available, or fgets() if readline is not installed.
*
* @param string $message to echo out before waiting for user input
* @return mixed line read as a string, or false if input has been closed
*/
public function prompt($message)
{
if(extension_loaded('readline'))
{
$input = readline($message.' ');
readline_add_history($input);
return $input;
}
else
{
echo $message.' ';
return trim(fgets(STDIN));
}
}
/**
* Asks user to confirm by typing y or n.
*
* @param string $message to echo out before waiting for user input
* @return bool if user confirmed
*/
public function confirm($message)
{
echo $message.' [yes|no] ';
return !strncasecmp(trim(fgets(STDIN)),'y',1);
}
}

142
framework/console/CommandRunner.php

@ -0,0 +1,142 @@
<?php
/**
* CConsoleCommandRunner class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2011 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\console;
/**
* CConsoleCommandRunner manages commands and executes the requested command.
*
* @property string $scriptName The entry script name.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class CommandRunner extends \yii\base\Component
{
/**
* @var array list of all available commands (command name=>command configuration).
* Each command configuration can be either a string or an array.
* If the former, the string should be the class name or
* {@link YiiBase::getPathOfAlias class path alias} of the command.
* If the latter, the array must contain a 'class' element which specifies
* the command's class name or {@link YiiBase::getPathOfAlias class path alias}.
* The rest name-value pairs in the array are used to initialize
* the corresponding command properties. For example,
* <pre>
* array(
* 'email'=>array(
* 'class'=>'path.to.Mailer',
* 'interval'=>3600,
* ),
* 'log'=>'path.to.LoggerCommand',
* )
* </pre>
*/
public $commands=array();
private $_scriptName;
/**
* Executes the requested command.
* @param array $args list of user supplied parameters (including the entry script name and the command name).
*/
public function run($args)
{
$this->_scriptName=$args[0];
array_shift($args);
if(isset($args[0]))
{
$name=$args[0];
array_shift($args);
}
else
$name='help';
if(($command=$this->createCommand($name))===null)
$command=$this->createCommand('help');
$command->init();
$command->run($args);
}
/**
* @return string the entry script name
*/
public function getScriptName()
{
return $this->_scriptName;
}
/**
* Searches for commands under the specified directory.
* @param string $path the directory containing the command class files.
* @return array list of commands (command name=>command class file)
*/
public function findCommands($path)
{
if(($dir=@opendir($path))===false)
return array();
$commands=array();
while(($name=readdir($dir))!==false)
{
$file=$path.DIRECTORY_SEPARATOR.$name;
if(!strcasecmp(substr($name,-11),'Command.php') && is_file($file))
$commands[strtolower(substr($name,0,-11))]=$file;
}
closedir($dir);
return $commands;
}
/**
* Adds commands from the specified command path.
* If a command already exists, the new one will be ignored.
* @param string $path the alias of the directory containing the command class files.
*/
public function addCommands($path)
{
if(($commands=$this->findCommands($path))!==array())
{
foreach($commands as $name=>$file)
{
if(!isset($this->commands[$name]))
$this->commands[$name]=$file;
}
}
}
/**
* @param string $name command name (case-insensitive)
* @return \yii\console\Command the command object. Null if the name is invalid.
*/
public function createCommand($name)
{
$name=strtolower($name);
if(isset($this->commands[$name]))
{
if(is_string($this->commands[$name])) // class file path or alias
{
if(strpos($this->commands[$name],'/')!==false || strpos($this->commands[$name],'\\')!==false)
{
$className=substr(basename($this->commands[$name]),0,-4);
if(!class_exists($className,false))
require_once($this->commands[$name]);
}
else // an alias
$className=\Yii::import($this->commands[$name]);
return new $className($name,$this);
}
else // an array configuration
return \Yii::create($this->commands[$name],$name,$this);
}
else if($name==='help')
return new HelpCommand('help',$this);
else
return null;
}
}

77
framework/console/HelpCommand.php

@ -0,0 +1,77 @@
<?php
/**
* CHelpCommand class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2011 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\console;
/**
* CHelpCommand represents a console help command.
*
* CHelpCommand displays the available command list or the help instructions
* about a specific command.
*
* To use this command, enter the following on the command line:
* <pre>
* php path/to/entry_script.php help [command name]
* </pre>
* In the above, if the command name is not provided, it will display all
* available commands.
*
* @property string $help The command description.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class HelpCommand extends Command
{
/**
* Execute the action.
* @param array $args command line parameters specific for this command
*/
public function run($args)
{
$runner=$this->getCommandRunner();
$commands=$runner->commands;
if(isset($args[0]))
{
$name=strtolower($args[0]);
}
if(!isset($args[0]) || !isset($commands[$name]))
{
if(!empty($commands))
{
echo "Yii command runner (based on Yii v".\Yii::getVersion().")\n";
echo "Usage: ".$runner->getScriptName()." <command-name> [parameters...]\n";
echo "\nThe following commands are available:\n";
$commandNames=array_keys($commands);
sort($commandNames);
echo ' - '.implode("\n - ",$commandNames);
echo "\n\nTo see individual command help, use the following:\n";
echo " ".$runner->getScriptName()." help <command-name>\n";
}
else
{
echo "No available commands.\n";
echo "Please define them under the following directory:\n";
echo "\t".\Yii::$app->getCommandPath()."\n";
}
}
else
echo $runner->createCommand($name)->getHelp();
}
/**
* Provides the command description.
* @return string the command description.
*/
public function getHelp()
{
return parent::getHelp().' [command-name]';
}
}

9
framework/db/Migration.php

@ -28,11 +28,9 @@
* applying migrations.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CDbMigration.php 3218 2011-05-13 00:06:44Z alexander.makarow $
* @package system.db
* @since 1.1.6
* @since 2.0
*/
abstract class CDbMigration extends CComponent
abstract class CDbMigration extends yii\base\Component
{
private $_db;
@ -94,7 +92,6 @@ abstract class CDbMigration extends CComponent
* Child classes may implement this method instead of {@link up} if the DB logic
* needs to be within a transaction.
* @return boolean
* @since 1.1.7
*/
public function safeUp()
{
@ -107,7 +104,6 @@ abstract class CDbMigration extends CComponent
* Child classes may implement this method instead of {@link up} if the DB logic
* needs to be within a transaction.
* @return boolean
* @since 1.1.7
*/
public function safeDown()
{
@ -146,7 +142,6 @@ abstract class CDbMigration extends CComponent
* This method executes the specified SQL statement using {@link dbConnection}.
* @param string $sql the SQL statement to be executed
* @param array $params input parameters (name=>value) for the SQL execution. See {@link CDbCommand::execute} for more details.
* @since 1.1.7
*/
public function execute($sql, $params = array())
{

86
framework/db/ar/ActiveRecord.php

@ -51,9 +51,7 @@ $post->save();
* about this class.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: ActiveRecord.php 3344 2011-07-06 22:04:50Z alexander.makarow $
* @package system.db.ar
* @since 1.0
* @since 2.0
*
* @property array $attributes
*/
@ -111,7 +109,6 @@ abstract class ActiveRecord extends \yii\base\Model
* @param integer $queryCount number of SQL queries that need to be cached after calling this method. Defaults to 1,
* meaning that the next SQL query will be cached.
* @return ActiveRecord the active record instance itself.
* @since 1.1.7
*/
public function cache($duration, $dependency = null, $queryCount = 1)
{
@ -174,7 +171,6 @@ abstract class ActiveRecord extends \yii\base\Model
* if the named attribute is null or not.
* @param string $name the property name or the event name
* @return boolean whether the property value is null
* @since 1.0.1
*/
public function __isset($name)
{
@ -195,7 +191,6 @@ abstract class ActiveRecord extends \yii\base\Model
* This method overrides the parent implementation by clearing
* the specified attribute value.
* @param string $name the property name or the event name
* @since 1.0.1
*/
public function __unset($name)
{
@ -214,7 +209,6 @@ abstract class ActiveRecord extends \yii\base\Model
* @param string $name the method name
* @param array $parameters method parameters
* @return mixed the method return value
* @since 1.0.5
*/
public function __call($name, $parameters)
{
@ -249,7 +243,6 @@ abstract class ActiveRecord extends \yii\base\Model
* This parameter has been available since version 1.0.5.
* @return mixed the related object(s).
* @throws CDbException if the relation is not specified in {@link relations}.
* @since 1.0.2
*/
public function getRelated($name, $refresh = false, $params = array())
{
@ -307,7 +300,6 @@ abstract class ActiveRecord extends \yii\base\Model
* Returns a value indicating whether the named related object(s) has been loaded.
* @param string $name the relation name
* @return boolean a value indicating whether the named related object(s) has been loaded.
* @since 1.0.3
*/
public function hasRelated($name)
{
@ -320,7 +312,6 @@ abstract class ActiveRecord extends \yii\base\Model
* @return CDbCriteria the query criteria that is associated with this model.
* This criteria is mainly used by {@link scopes named scope} feature to accumulate
* different criteria specifications.
* @since 1.0.5
*/
public function getDbCriteria($createIfNull = true)
{
@ -335,7 +326,6 @@ abstract class ActiveRecord extends \yii\base\Model
/**
* Sets the query criteria for the current model.
* @param CDbCriteria $criteria the query criteria
* @since 1.1.3
*/
public function setDbCriteria($criteria)
{
@ -349,7 +339,6 @@ abstract class ActiveRecord extends \yii\base\Model
* if the model needs to be queried with some default criteria (e.g. only active records should be returned).
* @return array the query criteria. This will be used as the parameter to the constructor
* of {@link CDbCriteria}.
* @since 1.0.5
*/
public function defaultScope()
{
@ -360,7 +349,6 @@ abstract class ActiveRecord extends \yii\base\Model
* Resets all scopes and criterias applied including default scope.
*
* @return ActiveRecord
* @since 1.1.2
*/
public function resetScope()
{
@ -415,7 +403,6 @@ abstract class ActiveRecord extends \yii\base\Model
* This is useful if the table schema has been changed and you want to use the latest
* available table schema. Make sure you have called {@link CDbSchema::refresh}
* before you call this method. Otherwise, old table schema data will still be used.
* @since 1.0.8
*/
public function refreshMetaData()
{
@ -446,7 +433,6 @@ abstract class ActiveRecord extends \yii\base\Model
* If the key is a single column, it should return the column name;
* If the key is a composite one consisting of several columns, it should
* return the array of the key column names.
* @since 1.0.4
*/
public function primaryKey()
{
@ -566,7 +552,6 @@ abstract class ActiveRecord extends \yii\base\Model
* @return array the scope definition. The array keys are scope names; the array
* values are the corresponding scope definitions. Each scope definition is represented
* as an array whose keys must be properties of {@link CDbCriteria}.
* @since 1.0.5
*/
public function scopes()
{
@ -577,7 +562,6 @@ abstract class ActiveRecord extends \yii\base\Model
* Returns the list of all attribute names of the model.
* This would return all column names of the table associated with this AR class.
* @return array list of attribute names.
* @since 1.0.1
*/
public function attributeNames()
{
@ -593,7 +577,6 @@ abstract class ActiveRecord extends \yii\base\Model
* @param string $attribute the attribute name
* @return string the attribute label
* @see generateAttributeLabel
* @since 1.1.4
*/
public function getAttributeLabel($attribute)
{
@ -834,7 +817,6 @@ abstract class ActiveRecord extends \yii\base\Model
* This event is raised before the record is saved.
* By setting {@link CModelEvent::isValid} to be false, the normal {@link save()} process will be stopped.
* @param CModelEvent $event the event parameter
* @since 1.0.2
*/
public function onBeforeSave($event)
{
@ -844,7 +826,6 @@ abstract class ActiveRecord extends \yii\base\Model
/**
* This event is raised after the record is saved.
* @param CEvent $event the event parameter
* @since 1.0.2
*/
public function onAfterSave($event)
{
@ -855,7 +836,6 @@ abstract class ActiveRecord extends \yii\base\Model
* This event is raised before the record is deleted.
* By setting {@link CModelEvent::isValid} to be false, the normal {@link delete()} process will be stopped.
* @param CModelEvent $event the event parameter
* @since 1.0.2
*/
public function onBeforeDelete($event)
{
@ -865,7 +845,6 @@ abstract class ActiveRecord extends \yii\base\Model
/**
* This event is raised after the record is deleted.
* @param CEvent $event the event parameter
* @since 1.0.2
*/
public function onAfterDelete($event)
{
@ -880,7 +859,6 @@ abstract class ActiveRecord extends \yii\base\Model
* You can modify either criteria to customize them based on needs.
* @param CModelEvent $event the event parameter
* @see beforeFind
* @since 1.0.9
*/
public function onBeforeFind($event)
{
@ -890,7 +868,6 @@ abstract class ActiveRecord extends \yii\base\Model
/**
* This event is raised after the record is instantiated by a find method.
* @param CEvent $event the event parameter
* @since 1.0.2
*/
public function onAfterFind($event)
{
@ -971,8 +948,6 @@ abstract class ActiveRecord extends \yii\base\Model
*
* Starting from version 1.1.5, this method may be called with a hidden {@link CDbCriteria}
* parameter which represents the current query criteria as passed to a find method of AR.
*
* @since 1.0.9
*/
protected function beforeFind()
{
@ -1000,7 +975,6 @@ abstract class ActiveRecord extends \yii\base\Model
/**
* Calls {@link beforeFind}.
* This method is internally used.
* @since 1.0.11
*/
public function beforeFindInternal()
{
@ -1010,7 +984,6 @@ abstract class ActiveRecord extends \yii\base\Model
/**
* Calls {@link afterFind}.
* This method is internally used.
* @since 1.0.3
*/
public function afterFindInternal()
{
@ -1153,7 +1126,6 @@ abstract class ActiveRecord extends \yii\base\Model
* @param array $counters the counters to be updated (column name=>increment value)
* @return boolean whether the saving is successful
* @see updateCounters
* @since 1.1.8
*/
public function saveCounters($counters)
{
@ -1256,7 +1228,6 @@ abstract class ActiveRecord extends \yii\base\Model
* After calling this method, the old primary key value can be obtained from {@link oldPrimaryKey}.
* @param mixed $value the new primary key value. If the primary key is composite, the new value
* should be provided as an array (column name=>column value).
* @since 1.1.0
*/
public function setPrimaryKey($value)
{
@ -1278,7 +1249,6 @@ abstract class ActiveRecord extends \yii\base\Model
* The value remains unchanged even if the primary key attribute is manually assigned with a different value.
* @return mixed the old primary key value. An array (column name=>column value) is returned if the primary key is composite.
* If primary key is not defined, null will be returned.
* @since 1.1.0
*/
public function getOldPrimaryKey()
{
@ -1288,7 +1258,6 @@ abstract class ActiveRecord extends \yii\base\Model
/**
* Sets the old primary key value.
* @param mixed $value the old primary key value.
* @since 1.1.3
*/
public function setOldPrimaryKey($value)
{
@ -1301,7 +1270,6 @@ abstract class ActiveRecord extends \yii\base\Model
* @param CDbCriteria $criteria the query criteria
* @param boolean $all whether to return all data
* @return mixed the AR objects populated with the query result
* @since 1.1.7
*/
protected function query($criteria, $all = false)
{
@ -1326,7 +1294,6 @@ abstract class ActiveRecord extends \yii\base\Model
* This method merges {@link dbCriteria} with the given criteria parameter.
* It then resets {@link dbCriteria} to be null.
* @param CDbCriteria $criteria the query criteria. This parameter may be modified by merging {@link dbCriteria}.
* @since 1.0.12
*/
public function applyScopes(&$criteria)
{
@ -1382,7 +1349,6 @@ abstract class ActiveRecord extends \yii\base\Model
* This parameter must be set false when calling this method in {@link defaultScope}.
* An infinite loop would be formed otherwise.
* @return string the default table alias
* @since 1.1.1
*/
public function getTableAlias($quote = false, $checkScopes = true)
{
@ -1396,7 +1362,6 @@ abstract class ActiveRecord extends \yii\base\Model
/**
* Sets the table alias to be used in queries.
* @param string $alias the table alias to be used in queries. The alias should NOT be quoted.
* @since 1.1.3
*/
public function setTableAlias($alias)
{
@ -1578,7 +1543,6 @@ abstract class ActiveRecord extends \yii\base\Model
* @param mixed $condition query condition or criteria.
* @param array $params parameters to be bound to an SQL statement.
* @return string the number of rows satisfying the specified query condition. Note: type is string to keep max. precision.
* @since 1.1.4
*/
public function countByAttributes($attributes, $condition = '', $params = array())
{
@ -1686,7 +1650,6 @@ abstract class ActiveRecord extends \yii\base\Model
* This is only used in relational AR query. Please refer to {@link CDbCriteria::together}
* for more details.
* @return ActiveRecord the AR object itself
* @since 1.1.4
*/
public function together()
{
@ -1792,7 +1755,6 @@ abstract class ActiveRecord extends \yii\base\Model
* @param mixed $condition query condition or criteria.
* @param array $params parameters to be bound to an SQL statement.
* @return integer number of rows affected by the execution.
* @since 1.0.9
*/
public function deleteAllByAttributes($attributes, $condition = '', $params = array())
{
@ -1873,7 +1835,6 @@ abstract class ActiveRecord extends \yii\base\Model
* you may implement the so-called single-table inheritance mapping.
* @param array $attributes list of attribute values for the active records.
* @return ActiveRecord the active record
* @since 1.0.2
*/
protected function instantiate($attributes)
{
@ -1887,7 +1848,6 @@ abstract class ActiveRecord extends \yii\base\Model
* This method is required by the interface ArrayAccess.
* @param mixed $offset the offset to check on
* @return boolean
* @since 1.0.2
*/
public function offsetExists($offset)
{
@ -1899,9 +1859,6 @@ abstract class ActiveRecord extends \yii\base\Model
/**
* CBaseActiveRelation is the base class for all active relations.
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: ActiveRecord.php 3344 2011-07-06 22:04:50Z alexander.makarow $
* @package system.db.ar
* @since 1.0.4
*/
class CBaseActiveRelation extends CComponent
{
@ -1941,7 +1898,6 @@ class CBaseActiveRelation extends CComponent
/**
* @var string how to join with other tables. This refers to the JOIN clause in an SQL statement.
* For example, <code>'LEFT JOIN users ON users.id=authorID'</code>.
* @since 1.1.3
*/
public $join = '';
/**
@ -1975,7 +1931,6 @@ class CBaseActiveRelation extends CComponent
* Merges this relation with a criteria specified dynamically.
* @param array $criteria the dynamically specified criteria
* @param boolean $fromScope whether the criteria to be merged is from scopes
* @since 1.0.5
*/
public function mergeWith($criteria, $fromScope = false)
{
@ -2042,9 +1997,6 @@ class CBaseActiveRelation extends CComponent
/**
* CStatRelation represents a statistical relational query.
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: ActiveRecord.php 3344 2011-07-06 22:04:50Z alexander.makarow $
* @package system.db.ar
* @since 1.0.4
*/
class CStatRelation extends CBaseActiveRelation
{
@ -2063,7 +2015,6 @@ class CStatRelation extends CBaseActiveRelation
* Merges this relation with a criteria specified dynamically.
* @param array $criteria the dynamically specified criteria
* @param boolean $fromScope whether the criteria to be merged is from scopes
* @since 1.0.5
*/
public function mergeWith($criteria, $fromScope = false)
{
@ -2080,9 +2031,7 @@ class CStatRelation extends CBaseActiveRelation
/**
* CActiveRelation is the base class for representing active relations that bring back related objects.
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: ActiveRecord.php 3344 2011-07-06 22:04:50Z alexander.makarow $
* @package system.db.ar
* @since 1.0
* @since 2.0
*/
class CActiveRelation extends CBaseActiveRelation
{
@ -2092,13 +2041,11 @@ class CActiveRelation extends CBaseActiveRelation
public $joinType = 'LEFT OUTER JOIN';
/**
* @var string ON clause. The condition specified here will be appended to the joining condition using AND operator.
* @since 1.0.2
*/
public $on = '';
/**
* @var string the alias for the table that this relation refers to. Defaults to null, meaning
* the alias will be the same as the relation name.
* @since 1.0.1
*/
public $alias;
/**
@ -2123,7 +2070,6 @@ class CActiveRelation extends CBaseActiveRelation
* <li>Single scope: 'scopes'=>'scopeName'.</li>
* <li>Multiple scopes: 'scopes'=>array('scopeName1','scopeName2').</li>
* </ul>
* @since 1.1.9
*/
public $scopes;
@ -2131,7 +2077,6 @@ class CActiveRelation extends CBaseActiveRelation
* Merges this relation with a criteria specified dynamically.
* @param array $criteria the dynamically specified criteria
* @param boolean $fromScope whether the criteria to be merged is from scopes
* @since 1.0.5
*/
public function mergeWith($criteria, $fromScope = false)
{
@ -2177,9 +2122,7 @@ class CActiveRelation extends CBaseActiveRelation
/**
* CBelongsToRelation represents the parameters specifying a BELONGS_TO relation.
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: ActiveRecord.php 3344 2011-07-06 22:04:50Z alexander.makarow $
* @package system.db.ar
* @since 1.0
* @since 2.0
*/
class CBelongsToRelation extends CActiveRelation
{
@ -2189,16 +2132,13 @@ class CBelongsToRelation extends CActiveRelation
/**
* CHasOneRelation represents the parameters specifying a HAS_ONE relation.
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: ActiveRecord.php 3344 2011-07-06 22:04:50Z alexander.makarow $
* @package system.db.ar
* @since 1.0
* @since 2.0
*/
class CHasOneRelation extends CActiveRelation
{
/**
* @var string the name of the relation that should be used as the bridge to this relation.
* Defaults to null, meaning don't use any bridge.
* @since 1.1.7
*/
public $through;
}
@ -2207,9 +2147,7 @@ class CHasOneRelation extends CActiveRelation
/**
* CHasManyRelation represents the parameters specifying a HAS_MANY relation.
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: ActiveRecord.php 3344 2011-07-06 22:04:50Z alexander.makarow $
* @package system.db.ar
* @since 1.0
* @since 2.0
*/
class CHasManyRelation extends CActiveRelation
{
@ -2224,13 +2162,11 @@ class CHasManyRelation extends CActiveRelation
/**
* @var string the name of the column that should be used as the key for storing related objects.
* Defaults to null, meaning using zero-based integer IDs.
* @since 1.0.7
*/
public $index;
/**
* @var string the name of the relation that should be used as the bridge to this relation.
* Defaults to null, meaning don't use any bridge.
* @since 1.1.7
*/
public $through;
@ -2238,7 +2174,6 @@ class CHasManyRelation extends CActiveRelation
* Merges this relation with a criteria specified dynamically.
* @param array $criteria the dynamically specified criteria
* @param boolean $fromScope whether the criteria to be merged is from scopes
* @since 1.0.5
*/
public function mergeWith($criteria, $fromScope = false)
{
@ -2260,9 +2195,7 @@ class CHasManyRelation extends CActiveRelation
/**
* CManyManyRelation represents the parameters specifying a MANY_MANY relation.
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: ActiveRecord.php 3344 2011-07-06 22:04:50Z alexander.makarow $
* @package system.db.ar
* @since 1.0
* @since 2.0
*/
class CManyManyRelation extends CHasManyRelation
{
@ -2273,9 +2206,7 @@ class CManyManyRelation extends CHasManyRelation
* ActiveRecordMetaData represents the meta-data for an Active Record class.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: ActiveRecord.php 3344 2011-07-06 22:04:50Z alexander.makarow $
* @package system.db.ar
* @since 1.0
* @since 2.0
*/
class ActiveRecordMetaData
{
@ -2349,7 +2280,6 @@ class ActiveRecordMetaData
* @param string $name $name Name of the relation.
* @param array $config $config Relation parameters.
* @return void
* @since 1.1.2
*/
public function addRelation($name, $config)
{
@ -2364,7 +2294,6 @@ class ActiveRecordMetaData
*
* @param string $name $name Name of the relation.
* @return boolean
* @since 1.1.2
*/
public function hasRelation($name)
{
@ -2376,7 +2305,6 @@ class ActiveRecordMetaData
*
* @param string $name $name
* @return void
* @since 1.1.2
*/
public function removeRelation($name)
{

5
framework/db/ar/ActiveRecordBehavior.php

@ -14,9 +14,7 @@
* that are only defined by {@link CActiveRecord}.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CActiveRecordBehavior.php 2799 2011-01-01 19:31:13Z qiang.xue $
* @package system.db.ar
* @since 1.0.2
* @since 2.0
*/
class CActiveRecordBehavior extends CModelBehavior
{
@ -80,7 +78,6 @@ class CActiveRecordBehavior extends CModelBehavior
* Responds to {@link CActiveRecord::onBeforeFind} event.
* Overrides this method if you want to handle the corresponding event of the {@link CBehavior::owner owner}.
* @param CEvent $event event parameter
* @since 1.0.9
*/
public function beforeFind($event)
{

1
framework/db/dao/Command.php

@ -671,7 +671,6 @@ class Command extends \yii\base\Component
/**
* Sets the LIMIT part of the query.
* @param integer $limit the limit
* @param integer $offset the offset
* @return Command the command object itself
*/
public function limit($limit)

7
framework/db/dao/Query.php

@ -235,7 +235,6 @@ class Query extends \yii\base\Object
* @param mixed $condition the new condition. It can be either a string or an array of strings.
* @param string $operator the operator to join different conditions. Defaults to 'AND'.
* @return Query the criteria object itself
* @since 1.0.9
*/
public function addCondition($condition, $operator = 'AND')
{
@ -269,7 +268,6 @@ class Query extends \yii\base\Object
* Defaults to 'AND'.
* @param string $like the LIKE operator. Defaults to 'LIKE'. You may also set this to be 'NOT LIKE'.
* @return Query the criteria object itself
* @since 1.0.10
*/
public function addSearchCondition($column, $keyword, $escape = true, $operator = 'AND', $like = 'LIKE')
{
@ -293,7 +291,6 @@ class Query extends \yii\base\Object
* @param string $operator the operator used to concatenate the new condition with the existing one.
* Defaults to 'AND'.
* @return Query the criteria object itself
* @since 1.0.10
*/
public function addInCondition($column, $values, $operator = 'AND')
{
@ -331,7 +328,6 @@ class Query extends \yii\base\Object
* @param string $operator the operator used to concatenate the new condition with the existing one.
* Defaults to 'AND'.
* @return Query the criteria object itself
* @since 1.1.1
*/
public function addNotInCondition($column, $values, $operator = 'AND')
{
@ -368,7 +364,6 @@ class Query extends \yii\base\Object
* @param string $operator the operator used to concatenate the new condition with the existing one.
* Defaults to 'AND'.
* @return Query the criteria object itself
* @since 1.0.10
*/
public function addColumnCondition($columns, $columnOperator = 'AND', $operator = 'AND')
{
@ -428,7 +423,6 @@ class Query extends \yii\base\Object
* character on both ends. When this parameter is false, the value will be directly used for
* matching without any change.
* @return Query the criteria object itself
* @since 1.1.1
*/
public function compare($column, $value, $partialMatch = false, $operator = 'AND', $escape = true)
{
@ -482,7 +476,6 @@ class Query extends \yii\base\Object
* @param string $operator the operator used to concatenate the new condition with the existing one.
* Defaults to 'AND'.
* @return Query the criteria object itself
* @since 1.1.2
*/
public function addBetweenCondition($column, $valueStart, $valueEnd, $operator = 'AND')
{

5
framework/db/dao/QueryBuilder.php

@ -110,7 +110,6 @@ class QueryBuilder extends \yii\base\Object
* refer to {@link where} on how to specify conditions.
* @param array $params the parameters to be bound to the query.
* @return integer number of rows affected by the execution.
* @since 1.1.6
*/
public function update($table, $columns, $conditions = '', &$params = array())
{
@ -144,7 +143,6 @@ class QueryBuilder extends \yii\base\Object
* refer to {@link where} on how to specify conditions.
* @param array $params the parameters to be bound to the query.
* @return integer number of rows affected by the execution.
* @since 1.1.6
*/
public function delete($table, $conditions = '')
{
@ -224,7 +222,6 @@ class QueryBuilder extends \yii\base\Object
* into the physical one. Anything that is not recognized as abstract type will be kept in the generated SQL.
* For example, 'string' will be turned into 'varchar(255)', while 'string not null' will become 'varchar(255) not null'.
* @return string the SQL statement for adding a new column.
* @since 1.1.6
*/
public function addColumn($table, $column, $type)
{
@ -238,7 +235,6 @@ class QueryBuilder extends \yii\base\Object
* @param string $table the table whose column is to be dropped. The name will be properly quoted by the method.
* @param string $column the name of the column to be dropped. The name will be properly quoted by the method.
* @return string the SQL statement for dropping a DB column.
* @since 1.1.6
*/
public function dropColumn($table, $column)
{
@ -252,7 +248,6 @@ class QueryBuilder extends \yii\base\Object
* @param string $name the old name of the column. The name will be properly quoted by the method.
* @param string $newName the new name of the column. The name will be properly quoted by the method.
* @return string the SQL statement for renaming a DB column.
* @since 1.1.6
*/
public function renameColumn($table, $name, $newName)
{

2
framework/db/dao/Schema.php

@ -35,7 +35,7 @@ abstract class Schema extends \yii\base\Object
/**
* Constructor.
* @param CDbConnection $conn database connection.
* @param CDbConnection $connection database connection.
*/
public function __construct($connection)
{

2
framework/db/dao/mysql/QueryBuilder.php

@ -45,7 +45,6 @@ class QueryBuilder extends \yii\db\dao\QueryBuilder
* @param string $name the old name of the column. The name will be properly quoted by the method.
* @param string $newName the new name of the column. The name will be properly quoted by the method.
* @return string the SQL statement for renaming a DB column.
* @since 1.1.6
*/
public function renameColumn($table, $name, $newName)
{
@ -77,7 +76,6 @@ class QueryBuilder extends \yii\db\dao\QueryBuilder
* @param string $name the name of the foreign key constraint to be dropped. The name will be properly quoted by the method.
* @param string $table the table whose foreign is to be dropped. The name will be properly quoted by the method.
* @return string the SQL statement for dropping a foreign key constraint.
* @since 1.1.6
*/
public function dropForeignKey($name, $table)
{

5
framework/logging/ProfileTarget.php

@ -21,9 +21,7 @@
* </ul>
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CProfileLogRoute.php 3204 2011-05-05 21:36:32Z alexander.makarow $
* @package system.logging
* @since 1.0
* @since 2.0
*/
class CProfileLogRoute extends CWebLogRoute
{
@ -32,7 +30,6 @@ class CProfileLogRoute extends CWebLogRoute
* If false, the results will be aggregated by categories.
* Defaults to true. Note that this property only affects the summary report
* that is enabled when {@link report} is 'summary'.
* @since 1.0.6
*/
public $groupByToken = true;
/**

4
framework/logging/WebTarget.php

@ -15,9 +15,7 @@
* or in FireBug console window (if {@link showInFireBug} is set true).
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CWebLogRoute.php 3001 2011-02-24 16:42:44Z alexander.makarow $
* @package system.logging
* @since 1.0
* @since 2.0
*/
class CWebLogRoute extends CLogRoute
{

141
framework/util/File.php

@ -0,0 +1,141 @@
<?php
/**
* Filesystem helper class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Alex Makarov <sam@rmcreative.ru>
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2012 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\util;
/**
* Filesystem helper
*
* @since 2.0
*/
class File
{
/**
* Copies a list of files from one place to another.
* @param array $fileList the list of files to be copied (name=>spec).
* The array keys are names displayed during the copy process, and array values are specifications
* for files to be copied. Each array value must be an array of the following structure:
* <ul>
* <li>source: required, the full path of the file/directory to be copied from</li>
* <li>target: required, the full path of the file/directory to be copied to</li>
* <li>callback: optional, the callback to be invoked when copying a file. The callback function
* should be declared as follows:
* <pre>
* function foo($source,$params)
* </pre>
* where $source parameter is the source file path, and the content returned
* by the function will be saved into the target file.</li>
* <li>params: optional, the parameters to be passed to the callback</li>
* </ul>
* @see buildFileList
*/
public function copyFiles($fileList)
{
$overwriteAll=false;
foreach($fileList as $name=>$file)
{
$source=strtr($file['source'],'/\\',DIRECTORY_SEPARATOR);
$target=strtr($file['target'],'/\\',DIRECTORY_SEPARATOR);
$callback=isset($file['callback']) ? $file['callback'] : null;
$params=isset($file['params']) ? $file['params'] : null;
if(is_dir($source))
{
$this->ensureDirectory($target);
continue;
}
if($callback!==null)
$content=call_user_func($callback,$source,$params);
else
$content=file_get_contents($source);
if(is_file($target))
{
if($content===file_get_contents($target))
{
echo " unchanged $name\n";
continue;
}
if($overwriteAll)
echo " overwrite $name\n";
else
{
echo " exist $name\n";
echo " ...overwrite? [Yes|No|All|Quit] ";
$answer=trim(fgets(STDIN));
if(!strncasecmp($answer,'q',1))
return;
else if(!strncasecmp($answer,'y',1))
echo " overwrite $name\n";
else if(!strncasecmp($answer,'a',1))
{
echo " overwrite $name\n";
$overwriteAll=true;
}
else
{
echo " skip $name\n";
continue;
}
}
}
else
{
$this->ensureDirectory(dirname($target));
echo " generate $name\n";
}
file_put_contents($target,$content);
}
}
/**
* Builds the file list of a directory.
* This method traverses through the specified directory and builds
* a list of files and subdirectories that the directory contains.
* The result of this function can be passed to {@link copyFiles}.
* @param string $sourceDir the source directory
* @param string $targetDir the target directory
* @param string $baseDir base directory
* @return array the file list (see {@link copyFiles})
*/
public function buildFileList($sourceDir, $targetDir, $baseDir='')
{
$list=array();
$handle=opendir($sourceDir);
while(($file=readdir($handle))!==false)
{
if($file==='.' || $file==='..' || $file==='.svn' ||$file==='.yii')
continue;
$sourcePath=$sourceDir.DIRECTORY_SEPARATOR.$file;
$targetPath=$targetDir.DIRECTORY_SEPARATOR.$file;
$name=$baseDir===''?$file : $baseDir.'/'.$file;
$list[$name]=array('source'=>$sourcePath, 'target'=>$targetPath);
if(is_dir($sourcePath))
$list=array_merge($list,$this->buildFileList($sourcePath,$targetPath,$name));
}
closedir($handle);
return $list;
}
/**
* Creates all parent directories if they do not exist.
* @param string $directory the directory to be checked
*/
public function ensureDirectory($directory)
{
if(!is_dir($directory))
{
$this->ensureDirectory(dirname($directory));
echo " mkdir ".strtr($directory,'\\','/')."\n";
mkdir($directory);
}
}
}

43
framework/util/Text.php

@ -0,0 +1,43 @@
<?php
/**
* Text helper class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Alex Makarov <sam@rmcreative.ru>
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2012 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\util;
/**
* Text helper
*
* @since 2.0
*/
class Text
{
/**
* Converts a word to its plural form.
* @param string $name the word to be pluralized
* @return string the pluralized word
*/
public function pluralize($name)
{
$rules=array(
'/(x|ch|ss|sh|us|as|is|os)$/i' => '\1es',
'/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
'/(m)an$/i' => '\1en',
'/(child)$/i' => '\1ren',
'/(r)y$/i' => '\1ies',
'/s$/' => 's',
);
foreach($rules as $rule=>$replacement)
{
if(preg_match($rule,$name))
return preg_replace($rule,$replacement,$name);
}
return $name.'s';
}
}

4
framework/validators/DateValidator.php

@ -16,9 +16,7 @@ namespace yii\validators;
* must be in. If the given date value doesn't follow the format, the attribute is considered as invalid.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CDateValidator.php 2799 2011-01-01 19:31:13Z qiang.xue $
* @package system.validators
* @since 1.1.7
* @since 2.0
*/
class CDateValidator extends Validator
{

5
framework/validators/ExistValidator.php

@ -16,9 +16,7 @@ namespace yii\validators;
* that can be found in the foreign table.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CExistValidator.php 2799 2011-01-01 19:31:13Z qiang.xue $
* @package system.validators
* @since 1.0.4
* @since 2.0
*/
class CExistValidator extends Validator
{
@ -41,7 +39,6 @@ class CExistValidator extends Validator
* @var array additional query criteria. This will be combined with the condition
* that checks if the attribute value exists in the corresponding table column.
* This array will be used to instantiate a {@link CDbCriteria} object.
* @since 1.0.8
*/
public $criteria = array();
/**

4
framework/validators/FileValidator.php

@ -40,9 +40,7 @@ namespace yii\validators;
* You can use {@link CFileValidator} to validate the file attribute.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CFileValidator.php 2799 2011-01-01 19:31:13Z qiang.xue $
* @package system.validators
* @since 1.0
* @since 2.0
*/
class CFileValidator extends Validator
{

6
framework/validators/UniqueValidator.php

@ -13,8 +13,6 @@ namespace yii\validators;
* CUniqueValidator validates that the attribute value is unique in the corresponding database table.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CUniqueValidator.php 3260 2011-06-13 20:56:54Z alexander.makarow $
* @package system.validators
* @since 1.0
*/
class CUniqueValidator extends Validator
@ -35,7 +33,6 @@ class CUniqueValidator extends Validator
* the class of the object currently being validated.
* You may use path alias to reference a class name here.
* @see attributeName
* @since 1.0.8
*/
public $className;
/**
@ -43,14 +40,12 @@ class CUniqueValidator extends Validator
* used to look for the attribute value being validated. Defaults to null,
* meaning using the name of the attribute being validated.
* @see className
* @since 1.0.8
*/
public $attributeName;
/**
* @var array additional query criteria. This will be combined with the condition
* that checks if the attribute value exists in the corresponding table column.
* This array will be used to instantiate a {@link CDbCriteria} object.
* @since 1.0.8
*/
public $criteria = array();
/**
@ -61,7 +56,6 @@ class CUniqueValidator extends Validator
/**
* @var boolean whether this validation rule should be skipped if when there is already a validation
* error for the current attribute. Defaults to true.
* @since 1.1.1
*/
public $skipOnError = true;

40
framework/web/HttpException.php

@ -0,0 +1,40 @@
<?php
/**
* HttpException class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2012 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\web;
/**
* CHttpException represents an exception caused by invalid operations of end-users.
*
* The HTTP error code can be obtained via {@link statusCode}.
* Error handlers may use this status code to decide how to format the error page.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class HttpException extends \yii\base\Exception
{
/**
* @var integer HTTP status code, such as 403, 404, 500, etc.
*/
public $statusCode;
/**
* Constructor.
* @param integer $status HTTP status code, such as 404, 500, etc.
* @param string $message error message
* @param integer $code error code
*/
public function __construct($status,$message=null,$code=0)
{
$this->statusCode=$status;
parent::__construct($message,$code);
}
}

14
framework/yiic

@ -0,0 +1,14 @@
#!/usr/bin/env php
<?php
/**
* Yii command line script for Unix/Linux.
*
* This is the bootstrap script for running yiic on Unix/Linux.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2012 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
require_once(__DIR__.'/yiic.php');

22
framework/yiic.bat

@ -0,0 +1,22 @@
@echo off
rem -------------------------------------------------------------
rem Yii command line script for Windows.
rem
rem This is the bootstrap script for running yiic on Windows.
rem
rem @author Qiang Xue <qiang.xue@gmail.com>
rem @link http://www.yiiframework.com/
rem @copyright Copyright &copy; 2012 Yii Software LLC
rem @license http://www.yiiframework.com/license/
rem -------------------------------------------------------------
@setlocal
set YII_PATH=%~dp0
if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe
"%PHP_COMMAND%" "%YII_PATH%yiic" %*
@endlocal

30
framework/yiic.php

@ -0,0 +1,30 @@
<?php
/**
* Yii console bootstrap file.
*
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2012 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
// fcgi doesn't have STDIN defined by default
defined('STDIN') or define('STDIN', fopen('php://stdin', 'r'));
require(__DIR__.'/yii.php');
if(isset($config))
{
$app=new \yii\console\Application($config);
$app->commandRunner->addCommands(YII_PATH.'/cli/commands');
$env=@getenv('YII_CONSOLE_COMMANDS');
if(!empty($env))
$app->commandRunner->addCommands($env);
}
else
{
$app=new \yii\console\Application(array(
'basePath'=>__DIR__.'/cli',
));
}
$app->run();

2
todo.md

@ -59,3 +59,5 @@
* ability to manage scripts order (store these in a vector?)
* http://ryanbigg.com/guides/asset_pipeline.html, http://guides.rubyonrails.org/asset_pipeline.html, use content hash instead of mtime + directory hash.
- Requirement checker
- widgets
* if we're going to supply default ones, these should generate really unique IDs. This will solve a lot of AJAX-nesting problems.
Loading…
Cancel
Save