Commit 7f35f9ad by Qiang Xue

...

parent 59f57a82
......@@ -16,7 +16,7 @@ change API. Results in less repetitive code. Performance drop isn't significant.
### callbacks and expressions
### [[Object::create()]|create] method
### [[Object::newInstance|newInstance]] method
This method is a powerful way to instantiate a class. Differences from `new`:
......
......@@ -49,12 +49,16 @@ class YiiBase
* @var array class map used by the Yii autoloading mechanism.
* The array keys are the class names, and the array values are the corresponding class file paths.
* This property mainly affects how [[autoload]] works.
* @see import
* @see autoload
*/
public static $classMap = array();
/**
* @var array list of directories where Yii will search for new classes to be included.
* The first directory in the array will be searched first, and so on.
* This property mainly affects how [[autoload]] works.
* @see import
* @see autoload
*/
public static $classPath = array();
/**
......@@ -63,10 +67,34 @@ class YiiBase
public static $app;
/**
* @var array registered path aliases
* @see getAlias
* @see setAlias
*/
public static $aliases = array(
'@yii' => __DIR__,
);
/**
* @var array initial property values that will be applied to objects newly created via [[createObject]].
* The array keys are fully qualified namespaced class names, and the array values are the corresponding
* name-value pairs for initializing the created class instances. Make sure the class names do not have
* the leading backslashes. For example,
*
* ~~~
* array(
* 'mycompany\foo\Bar' => array(
* 'prop1' => 'value1',
* 'prop2' => 'value2',
* ),
* 'mycompany\foo\Car' => array(
* 'prop1' => 'value1',
* 'prop2' => 'value2',
* ),
* )
* ~~~
*
* @see createObject
*/
public static $objectConfig = array();
private static $_imported = array(); // alias => class name or directory
private static $_logger;
......@@ -140,13 +168,11 @@ class YiiBase
if ($forceInclude) {
require($path . "/$className.php");
self::$_imported[$alias] = $className;
}
else {
} else {
self::$classMap[$className] = $path . "/$className.php";
}
return $className;
}
else { // a directory
} else { // a directory
array_unshift(self::$classPath, $path);
return self::$_imported[$alias] = $path;
}
......@@ -172,11 +198,9 @@ class YiiBase
{
if (isset(self::$aliases[$alias])) {
return self::$aliases[$alias];
}
elseif ($alias[0] !== '@') { // not an alias
} elseif ($alias[0] !== '@') { // not an alias
return $alias;
}
elseif (($pos = strpos($alias, '/')) !== false) {
} elseif (($pos = strpos($alias, '/')) !== false) {
$rootAlias = substr($alias, 0, $pos);
if (isset(self::$aliases[$rootAlias])) {
return self::$aliases[$alias] = self::$aliases[$rootAlias] . substr($alias, $pos);
......@@ -207,14 +231,11 @@ class YiiBase
{
if ($path === null) {
unset(self::$aliases[$alias]);
}
elseif ($path[0] !== '@') {
} elseif ($path[0] !== '@') {
self::$aliases[$alias] = rtrim($path, '\\/');
}
elseif (($p = static::getAlias($path)) !== false) {
} elseif (($p = static::getAlias($path)) !== false) {
self::$aliases[$alias] = $p;
}
else {
} else {
throw new \yii\base\Exception('Invalid path: ' . $path);
}
}
......@@ -278,22 +299,34 @@ class YiiBase
}
/**
* Creates a new component instance using the given configuration.
* Creates a new object using the given configuration.
*
* The specified configuration can be either a string or an array.
* If the former, the string is treated as the object type; if the latter,
* the array must contain a `class` element specifying the object type, and
* The configuration can be either a string or an array.
* If a string, it is treated as the *object type*; if an array,
* it must contain a `class` element specifying the *object type*, and
* the rest of the name-value pairs in the array will be used to initialize
* the corresponding object properties.
*
* The object type can be either a class name or [[getAlias|path alias]] of
* The object type can be either a class name or the [[getAlias|alias]] of
* the class. For example,
*
* - `\app\components\GoogleMap`: namespaced class
* - `@app/components/GoogleMap`: an alias
*
* This method does the following steps to create an object:
*
* - create the object using the PHP `new` operator;
* - if [[objectConfig]] contains the configuration for the object class,
* initialize the object properties with that configuration;
* - initialize the object properties using the configuration passed to this method;
* - call the `init` method of the object if it implements the [[yii\base\Initable]] interface.
*
* Below are some usage examples:
*
* ~~~
* $component = Yii::create('@app/components/GoogleMap');
* $component = Yii::create('\application\components\GoogleMap');
* $component = Yii::create(array(
* 'class' => '@app/components/GoogleMap',
* $object = \Yii::createObject('@app/components/GoogleMap');
* $object = \Yii::createObject(array(
* 'class' => '\app\components\GoogleMap',
* 'apiKey' => 'xyz',
* ));
* ~~~
......@@ -301,25 +334,19 @@ class YiiBase
* Any additional parameters passed to this method will be
* passed to the constructor of the object being created.
*
* If a component class implements the [[\yii\base\Initable]] interface,
* its [[\yii\base\Initable::init|init]] method will be invoked AFTER
* the component properties are initialized.
*
* @param mixed $config the configuration. It can be either a string or an array.
* @return mixed the created object
* @throws \yii\base\Exception if the configuration is invalid.
*/
public static function create($config)
public static function createObject($config)
{
if (is_string($config)) {
$class = $config;
$config = array();
}
elseif (isset($config['class'])) {
} elseif (isset($config['class'])) {
$class = $config['class'];
unset($config['class']);
}
else {
} else {
throw new \yii\base\Exception('Object configuration must be an array containing a "class" element.');
}
......@@ -327,36 +354,38 @@ class YiiBase
$class = static::import($class, true);
}
if (($n = func_num_args()) > 1) {
if (($n = func_num_args()-1) > 0) {
$args = func_get_args();
if ($n === 2) {
$object = new $class($args[1]);
}
elseif ($n === 3) {
$object = new $class($args[1], $args[2]);
}
elseif ($n === 4) {
$object = new $class($args[1], $args[2], $args[3]);
}
else {
unset($args[0]);
$r = new ReflectionClass($class);
$object = $r->newInstanceArgs($args);
}
array_shift($args); // remove $config
}
else {
if ($n === 0) {
$object = new $class;
} elseif ($n === 1) {
$object = new $class($args[0]);
} elseif ($n === 2) {
$object = new $class($args[0], $args[1]);
} elseif ($n === 3) {
$object = new $class($args[0], $args[1], $args[2]);
} else {
$r = new \ReflectionClass($class);
$object = $r->newInstanceArgs($args);
}
$c = get_class($object);
if (isset(\Yii::$objectConfig[$c])) {
$config = isset($config) ? array_merge(\Yii::$objectConfig[$c], $config) : \Yii::$objectConfig[$c];
}
foreach ($config as $name => $value) {
$object->$name = $value;
if (!empty($config)) {
foreach ($config as $name => $value) {
$object->$name = $value;
}
}
if ($object instanceof \yii\base\Initable) {
$object->init();
}
return $object;
}
/**
......@@ -426,7 +455,7 @@ class YiiBase
* @param string $category the category of this log message
* @see endProfile
*/
public static function beginProfile($token, $category)
public static function beginProfile($token, $category = 'application')
{
self::getLogger()->beginProfile($token, $category);
}
......@@ -438,7 +467,7 @@ class YiiBase
* @param string $category the category of this log message
* @see beginProfile
*/
public static function endProfile($token, $category)
public static function endProfile($token, $category = 'application')
{
self::getLogger()->endProfile($token, $category);
}
......@@ -451,8 +480,7 @@ class YiiBase
{
if (self::$_logger !== null) {
return self::$_logger;
}
else {
} else {
return self::$_logger = new \yii\logging\Logger;
}
}
......
......@@ -47,8 +47,8 @@ class Behavior extends Object
*
* ~~~
* array(
* 'onBeforeValidate' => 'myBeforeValidate',
* 'onAfterValidate' => 'myAfterValidate',
* 'onBeforeValidate' => 'myBeforeValidate',
* 'onAfterValidate' => 'myAfterValidate',
* )
* ~~~
*
......
......@@ -22,7 +22,7 @@ namespace yii\base;
* ~~~
* public function onClick($event)
* {
* $this->raiseEvent('onClick', $event);
* $this->raiseEvent('onClick', $event);
* }
* ~~~
*
......@@ -54,8 +54,8 @@ namespace yii\base;
*
* ~~~
* $component->onClick->insertAt(0, $callback); // attach a handler as the first one
* $component->onClick[] = $callback; // attach a handler as the last one
* unset($component->onClick[0]); // detach the first handler
* $component->onClick[] = $callback; // attach a handler as the last one
* unset($component->onClick[0]); // detach the first handler
* ~~~
*
*
......@@ -98,15 +98,18 @@ class Component extends Object
$getter = 'get' . $name;
if (method_exists($this, $getter)) { // read property, e.g. getName()
return $this->$getter();
} elseif (method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0) { // event, e.g. onClick()
}
elseif (method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0) { // event, e.g. onClick()
$name = strtolower($name);
if (!isset($this->_e[$name])) {
$this->_e[$name] = new Vector;
}
return $this->_e[$name];
} elseif (isset($this->_b[$name])) { // behavior
}
elseif (isset($this->_b[$name])) { // behavior
return $this->_b[$name];
} elseif (is_array($this->_b)) { // a behavior property
}
elseif (is_array($this->_b)) { // a behavior property
foreach ($this->_b as $object) {
if ($object->canGetProperty($name)) {
return $object->$name;
......@@ -135,15 +138,17 @@ class Component extends Object
public function __set($name, $value)
{
$setter = 'set' . $name;
if (method_exists($this, $setter)) { // write property
if (method_exists($this, $setter)) { // write property
return $this->$setter($value);
} elseif (method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0) { // event
}
elseif (method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0) { // event
$name = strtolower($name);
if (!isset($this->_e[$name])) {
$this->_e[$name] = new Vector;
}
return $this->_e[$name]->add($value);
} elseif (is_array($this->_b)) { // behavior
}
elseif (is_array($this->_b)) { // behavior
foreach ($this->_b as $object) {
if ($object->canSetProperty($name)) {
return $object->$name = $value;
......@@ -152,7 +157,8 @@ class Component extends Object
}
if (method_exists($this, 'get' . $name)) {
throw new Exception('Setting read-only property: ' . get_class($this) . '.' . $name);
} else {
}
else {
throw new Exception('Setting unknown property: ' . get_class($this) . '.' . $name);
}
}
......@@ -175,12 +181,15 @@ class Component extends Object
$getter = 'get' . $name;
if (method_exists($this, $getter)) { // property is not null
return $this->$getter() !== null;
} elseif (method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0) { // has event handler
}
elseif (method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0) { // has event handler
$name = strtolower($name);
return isset($this->_e[$name]) && $this->_e[$name]->getCount();
} elseif (isset($this->_b[$name])) { // has behavior
return true;
} elseif (is_array($this->_b)) {
}
elseif (isset($this->_b[$name])) { // has behavior
return true;
}
elseif (is_array($this->_b)) {
foreach ($this->_b as $object) {
if ($object->canGetProperty($name)) {
return $object->$name !== null;
......@@ -206,14 +215,17 @@ class Component extends Object
public function __unset($name)
{
$setter = 'set' . $name;
if (method_exists($this, $setter)) { // write property
if (method_exists($this, $setter)) { // write property
return $this->$setter(null);
} elseif (method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0) { // event
}
elseif (method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0) { // event
unset($this->_e[strtolower($name)]);
return;
} elseif (isset($this->_b[$name])) { // behavior
}
elseif (isset($this->_b[$name])) { // behavior
return $this->detachBehavior($name);
} elseif (is_array($this->_b)) { // behavior property
}
elseif (is_array($this->_b)) { // behavior property
foreach ($this->_b as $object) {
if ($object->canSetProperty($name)) {
return $object->$name = null;
......@@ -266,7 +278,7 @@ class Component extends Object
*/
public function hasEvent($name)
{
return method_exists($this, $name) && strncasecmp($name, 'on', 2)===0;
return method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0;
}
/**
......@@ -318,10 +330,10 @@ class Component extends Object
* some examples:
*
* ~~~
* 'handleOnClick' // handleOnClick() is a global function
* array($object, 'handleOnClick') // $object->handleOnClick()
* array('Page', 'handleOnClick') // Page::handleOnClick()
* function($event) { ... } // anonymous function
* 'handleOnClick' // handleOnClick() is a global function
* array($object, 'handleOnClick') // $object->handleOnClick()
* array('Page', 'handleOnClick') // Page::handleOnClick()
* function($event) { ... } // anonymous function
* ~~~
*
* An event handler must be defined with the following signature,
......@@ -374,17 +386,21 @@ class Component extends Object
foreach ($this->_e[$name] as $handler) {
if (is_string($handler) || $handler instanceof \Closure) {
call_user_func($handler, $event);
} elseif (is_callable($handler, true)) {
}
elseif (is_callable($handler, true)) {
// an array: 0 - object, 1 - method name
list($object, $method) = $handler;
if (is_string($object)) { // static method call
if (is_string($object)) { // static method call
call_user_func($handler, $event);
} elseif (method_exists($object, $method)) {
}
elseif (method_exists($object, $method)) {
$object->$method($event);
} else {
}
else {
throw new Exception('Event "' . get_class($this) . '.' . $name . '" is attached with an invalid handler.');
}
} else {
}
else {
throw new Exception('Event "' . get_class($this) . '.' . $name . '" is attached with an invalid handler.');
}
......@@ -393,7 +409,8 @@ class Component extends Object
return;
}
}
} elseif (!$this->hasEvent($name)) {
}
elseif (!$this->hasEvent($name)) {
throw new Exception('Raising unknown event: ' . get_class($this) . '.' . $name);
}
}
......@@ -419,16 +436,15 @@ class Component extends Object
*
* - a [[Behavior]] object
* - a string specifying the behavior class
* - an object configuration array
* - an object configuration array that will be passed to [[\Yii::createObject]] to create the behavior object.
*
* parameter to [[\Yii::create]] to create the behavior object.
* @return Behavior the behavior object
* @see detachBehavior
*/
public function attachBehavior($name, $behavior)
{
if (!($behavior instanceof Behavior)) {
$behavior = \Yii::create($behavior);
$behavior = \Yii::createObject($behavior);
}
$behavior->attach($this);
return $this->_b[$name] = $behavior;
......
......@@ -21,11 +21,11 @@ namespace yii\base;
* like a regular PHP array as follows,
*
* ~~~
* $dictionary[$key] = $value; // add a key-value pair
* unset($dictionary[$key]); // remove the value with the specified key
* if (isset($dictionary[$key])) // if the dictionary contains the key
* $dictionary[$key] = $value; // add a key-value pair
* unset($dictionary[$key]); // remove the value with the specified key
* if (isset($dictionary[$key])) // if the dictionary contains the key
* foreach ($dictionary as $key=>$value) // traverse the items in the dictionary
* $n = count($dictionary); // returns the number of items in the dictionary
* $n = count($dictionary); // returns the number of items in the dictionary
* ~~~
*
* @author Qiang Xue <qiang.xue@gmail.com>
......@@ -114,7 +114,8 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
{
if ($key === null) {
$this->_d[] = $value;
} else {
}
else {
$this->_d[$key] = $value;
}
}
......@@ -131,7 +132,8 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
$value = $this->_d[$key];
unset($this->_d[$key]);
return $value;
} else { // the value is null
}
else { // the value is null
unset($this->_d[$key]);
return null;
}
......@@ -149,7 +151,8 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
foreach (array_keys($this->_d) as $key) {
$this->remove($key);
}
} else {
}
else {
$this->_d = array();
}
}
......@@ -181,8 +184,7 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
*/
public function copyFrom($data)
{
if (is_array($data) || $data instanceof \Traversable)
{
if (is_array($data) || $data instanceof \Traversable) {
if ($this->_d !== array()) {
$this->clear();
}
......@@ -192,7 +194,8 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
foreach ($data as $key => $value) {
$this->add($key, $value);
}
} else {
}
else {
throw new Exception('Data must be either an array or an object implementing Traversable.');
}
}
......@@ -214,7 +217,7 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
*
* @throws CException If data is neither an array nor an iterator.
*/
public function mergeWith($data, $recursive=true)
public function mergeWith($data, $recursive = true)
{
if (is_array($data) || $data instanceof \Traversable) {
if ($data instanceof self) {
......@@ -222,20 +225,23 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
}
if ($recursive) {
if ($data instanceof \Traversable) {
$d=array();
foreach($data as $key => $value) {
$d = array();
foreach ($data as $key => $value) {
$d[$key] = $value;
}
$this->_d = self::mergeArray($this->_d, $d);
} else {
}
else {
$this->_d = self::mergeArray($this->_d, $data);
}
} else {
foreach($data as $key => $value) {
}
else {
foreach ($data as $key => $value) {
$this->add($key, $value);
}
}
} else {
}
else {
throw new Exception('Dictionary data must be an array or an object implementing Traversable.');
}
}
......@@ -278,7 +284,7 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
*/
public function offsetSet($offset, $item)
{
$this->add($offset,$item);
$this->add($offset, $item);
}
/**
......@@ -308,12 +314,14 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
*/
public static function mergeArray($a, $b)
{
foreach($b as $k=>$v) {
if(is_integer($k)) {
foreach ($b as $k => $v) {
if (is_integer($k)) {
isset($a[$k]) ? $a[] = $v : $a[$k] = $v;
} elseif(is_array($v) && isset($a[$k]) && is_array($a[$k])) {
}
elseif (is_array($v) && isset($a[$k]) && is_array($a[$k])) {
$a[$k] = self::mergeArray($a[$k], $v);
} else {
}
else {
$a[$k] = $v;
}
}
......
......@@ -51,7 +51,7 @@ class Event extends Object
* @param mixed $sender sender of the event
* @param mixed $params parameters of the event
*/
public function __construct($sender=null, $params=null)
public function __construct($sender = null, $params = null)
{
$this->sender = $sender;
$this->params = $params;
......
......@@ -13,7 +13,7 @@ namespace yii\base;
* Initable is an interface indicating a class needs initialization to work properly.
*
* Initable requires a class to implement the [[init]] method.
* When [[\Yii::create]] is being used to create a new component which implements
* When [[\Yii::createObject]] is being used to create a new component which implements
* Initable, it will call the [[init]] method after setting the initial values of the
* component properties.
*
......@@ -24,7 +24,7 @@ interface Initable
{
/**
* Initializes this component.
* This method is invoked by [[\Yii::create]] after its creates the new
* This method is invoked by [[\Yii::createObject]] after its creates the new
* component instance and initializes the component properties. In other words,
* at this stage, the component has been fully configured.
*/
......
......@@ -35,15 +35,15 @@ namespace yii\base;
class Model extends Component implements Initable, \IteratorAggregate, \ArrayAccess
{
private static $_attributes = array(); // class name => array of attribute names
private $_errors; // attribute name => array of errors
private $_validators; // validators
private $_scenario; // scenario
private $_errors; // attribute name => array of errors
private $_validators; // validators
private $_scenario; // scenario
/**
* Constructor.
* @param string $scenario name of the [[scenario]] that this model is used in.
*/
public function __construct($scenario='')
public function __construct($scenario = '')
{
$this->_scenario = $scenario;
$this->afterConstruct();
......@@ -52,7 +52,7 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
/**
* Initializes this model.
*
* This method is required by the [[Initable]] interface. It is invoked by [[\Yii::create]]
* This method is required by the [[Initable]] interface. It is invoked by [[\Yii::createObject]]
* after it creates the new model instance and initializes the model properties.
*
* The default implementation calls [[behaviors]] and registers any available behaviors.
......@@ -72,9 +72,9 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
*
* ~~~
* 'behaviorName' => array(
* 'class' => 'BehaviorClass',
* 'property1' => 'value1',
* 'property2' => 'value2',
* 'class' => 'BehaviorClass',
* 'property1' => 'value1',
* 'property2' => 'value2',
* )
* ~~~
*
......@@ -123,10 +123,10 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
*
* ~~~
* array(
* 'attribute list',
* 'validator type',
* 'on'=>'scenario name',
* ...other parameters...
* 'attribute list',
* 'validator type',
* 'on'=>'scenario name',
* ...other parameters...
* )
* ~~~
*
......@@ -134,11 +134,11 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
*
* - attribute list: required, specifies the attributes (separated by commas) to be validated;
* - validator type: required, specifies the validator to be used. It can be the name of a model
* class method, the name of a built-in validator, or a validator class (or its path alias).
* class method, the name of a built-in validator, or a validator class (or its path alias).
* - on: optional, specifies the [[scenario|scenarios]] (separated by commas) when the validation
* rule can be applied. If this option is not set, the rule will apply to any scenario.
* rule can be applied. If this option is not set, the rule will apply to any scenario.
* - additional name-value pairs can be specified to initialize the corresponding validator properties.
* Please refer to individual validator class API for possible properties.
* Please refer to individual validator class API for possible properties.
*
* A validator can be either a model class method or an object.
* If the former, the method must have the following signature:
......@@ -156,10 +156,10 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
*
* ~~~
* array(
* array('username', 'required'),
* array('username', 'length', 'min'=>3, 'max'=>12),
* array('password', 'compare', 'compareAttribute'=>'password2', 'on'=>'register'),
* array('password', 'authenticate', 'on'=>'login'),
* array('username', 'required'),
* array('username', 'length', 'min'=>3, 'max'=>12),
* array('password', 'compare', 'compareAttribute'=>'password2', 'on'=>'register'),
* array('password', 'authenticate', 'on'=>'login'),
* );
* ~~~
*
......@@ -364,10 +364,11 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
{
$validators = new Vector;
foreach ($this->rules() as $rule) {
if (isset($rule[0], $rule[1])) { // attributes, validator type
if (isset($rule[0], $rule[1])) { // attributes, validator type
$validator = \yii\validators\Validator::createValidator($rule[1], $this, $rule[0], array_slice($rule, 2));
$validators->add($validator);
} else {
}
else {
throw new Exception('Invalid validation rule: a rule must specify both attribute names and validator type.');
}
}
......@@ -439,13 +440,13 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
*
* ~~~
* array(
* 'username' => array(
* 'Username is required.',
* 'Username must contain only word characters.',
* ),
* 'email' => array(
* 'Email address is invalid.',
* )
* 'username' => array(
* 'Username is required.',
* 'Username must contain only word characters.',
* ),
* 'email' => array(
* 'Email address is invalid.',
* )
* )
* ~~~
*
......@@ -455,7 +456,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
{
if ($attribute === null) {
return $this->_errors === null ? array() : $this->_errors;
} else {
}
else {
return isset($this->_errors[$attribute]) ? $this->_errors[$attribute] : array();
}
}
......@@ -494,7 +496,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
foreach ($error as $e) {
$this->_errors[$attribute][] = $e;
}
} else {
}
else {
$this->_errors[$attribute][] = $error;
}
}
......@@ -508,7 +511,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
{
if ($attribute === null) {
$this->_errors = array();
} else {
}
else {
unset($this->_errors[$attribute]);
}
}
......@@ -543,7 +547,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
$values[$name] = $this->$name;
}
}
} else {
}
else {
foreach ($this->attributeNames() as $name) {
$values[$name] = $this->$name;
}
......@@ -567,7 +572,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
foreach ($values as $name => $value) {
if (isset($attributes[$name])) {
$this->$name = $value;
} elseif ($safeOnly) {
}
elseif ($safeOnly) {
$this->onUnsafeAttribute($name, $value);
}
}
......@@ -633,7 +639,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
foreach ($validator->attributes as $name) {
$unsafe[] = $name;
}
} else {
}
else {
foreach ($validator->attributes as $name) {
$attributes[$name] = true;
}
......
......@@ -59,10 +59,10 @@ abstract class Module extends Component
$this->_parentModule = $parent;
// set basePath at early as possible to avoid trouble
if (is_string($config))
if (is_string($config)) {
$config = require($config);
if (isset($config['basePath']))
{
}
if (isset($config['basePath'])) {
$this->setBasePath($config['basePath']);
unset($config['basePath']);
}
......@@ -139,7 +139,7 @@ abstract class Module extends Component
*/
public function setId($id)
{
$this->_id=$id;
$this->_id = $id;
}
/**
......@@ -216,8 +216,8 @@ abstract class Module extends Component
*
* ~~~
* array(
* '@models' => '@app/models', // an existing alias
* '@backend' => __DIR__ . '/../backend', // a directory
* '@models' => '@app/models', // an existing alias
* '@backend' => __DIR__ . '/../backend', // a directory
* )
* ~~~
*/
......@@ -246,23 +246,22 @@ abstract class Module extends Component
*/
public function getModule($id)
{
if (isset($this->_modules[$id]) || array_key_exists($id, $this->_modules))
if (isset($this->_modules[$id]) || array_key_exists($id, $this->_modules)) {
return $this->_modules[$id];
}
elseif (isset($this->_moduleConfig[$id]))
{
$config = $this->_moduleConfig[$id];
if (!isset($config['enabled']) || $config['enabled'])
{
if (!isset($config['enabled']) || $config['enabled']) {
\Yii::trace("Loading \"$id\" module", 'system.base.CModule');
$class = $config['class'];
unset($config['class'], $config['enabled']);
if ($this === \Yii::$app)
{
$module = Yii::create($class, $id, null, $config);
if ($this === \Yii::$app) {
$module = \Yii::createObject($class, $id, null, $config);
}
else
{
$module = Yii::create($class, $this->getId() . '/' . $id, $this, $config);
$module = \Yii::createObject($class, $this->getId() . '/' . $id, $this, $config);
}
return $this->_modules[$id] = $module;
}
......@@ -299,10 +298,10 @@ abstract class Module extends Component
* For example, the following array declares two modules:
* <pre>
* array(
* 'admin', // a single module ID
* 'payment'=>array( // ID-configuration pair
* 'server'=>'paymentserver.com',
* ),
* 'admin', // a single module ID
* 'payment'=>array( // ID-configuration pair
* 'server'=>'paymentserver.com',
* ),
* )
* </pre>
*
......@@ -318,21 +317,22 @@ abstract class Module extends Component
{
foreach ($modules as $id => $module)
{
if (is_int($id))
{
if (is_int($id)) {
$id = $module;
$module = array();
}
if (!isset($module['class']))
{
if (!isset($module['class'])) {
Yii::setPathOfAlias($id, $this->getModulePath() . DIRECTORY_SEPARATOR . $id);
$module['class'] = $id . '.' . ucfirst($id) . 'Module';
}
if (isset($this->_moduleConfig[$id]))
if (isset($this->_moduleConfig[$id])) {
$this->_moduleConfig[$id] = CMap::mergeArray($this->_moduleConfig[$id], $module);
}
else
{
$this->_moduleConfig[$id] = $module;
}
}
}
......@@ -356,16 +356,16 @@ abstract class Module extends Component
*/
public function getComponent($id, $createIfNull = true)
{
if (isset($this->_components[$id]))
if (isset($this->_components[$id])) {
return $this->_components[$id];
}
elseif (isset($this->_componentConfig[$id]) && $createIfNull)
{
$config = $this->_componentConfig[$id];
if (!isset($config['enabled']) || $config['enabled'])
{
if (!isset($config['enabled']) || $config['enabled']) {
\Yii::trace("Loading \"$id\" application component", 'system.CModule');
unset($config['enabled']);
$component = \Yii::create($config);
$component = \Yii::createObject($config);
return $this->_components[$id] = $component;
}
}
......@@ -381,13 +381,14 @@ abstract class Module extends Component
*/
public function setComponent($id, $component)
{
if ($component === null)
if ($component === null) {
unset($this->_components[$id]);
else
{
}
else {
$this->_components[$id] = $component;
if (!$component->getIsInitialized())
if (!$component->getIsInitialized()) {
$component->init();
}
}
}
......@@ -401,10 +402,12 @@ abstract class Module extends Component
*/
public function getComponents($loadedOnly = true)
{
if ($loadedOnly)
if ($loadedOnly) {
return $this->_components;
else
}
else {
return array_merge($this->_componentConfig, $this->_components);
}
}
/**
......@@ -421,15 +424,15 @@ abstract class Module extends Component
* The following is the configuration for two components:
* <pre>
* array(
* 'db'=>array(
* 'class'=>'CDbConnection',
* 'connectionString'=>'sqlite:path/to/file.db',
* ),
* 'cache'=>array(
* 'class'=>'CDbCache',
* 'connectionID'=>'db',
* 'enabled'=>!YII_DEBUG, // enable caching in non-debug mode
* ),
* 'db'=>array(
* 'class'=>'CDbConnection',
* 'connectionString'=>'sqlite:path/to/file.db',
* ),
* 'cache'=>array(
* 'class'=>'CDbCache',
* 'connectionID'=>'db',
* 'enabled'=>!YII_DEBUG, // enable caching in non-debug mode
* ),
* )
* </pre>
*
......@@ -442,12 +445,17 @@ abstract class Module extends Component
{
foreach ($components as $id => $component)
{
if ($component instanceof IApplicationComponent)
if ($component instanceof IApplicationComponent) {
$this->setComponent($id, $component);
}
elseif (isset($this->_componentConfig[$id]) && $merge)
{
$this->_componentConfig[$id] = CMap::mergeArray($this->_componentConfig[$id], $component);
}
else
{
$this->_componentConfig[$id] = $component;
}
}
}
......@@ -457,10 +465,11 @@ abstract class Module extends Component
*/
public function configure($config)
{
if (is_array($config))
{
if (is_array($config)) {
foreach ($config as $key => $value)
{
$this->$key = $value;
}
}
}
......@@ -470,7 +479,9 @@ abstract class Module extends Component
public function preloadComponents()
{
foreach ($this->preload as $id)
{
$this->getComponent($id);
}
}
/**
......
......@@ -21,12 +21,12 @@ namespace yii\base;
*
* public function getLabel()
* {
* return $this->_label;
* return $this->_label;
* }
*
* public function setLabel($value)
* {
* $this->_label = $value;
* $this->_label = $value;
* }
* ~~~
*
......@@ -85,7 +85,8 @@ class Object
$getter = 'get' . $name;
if (method_exists($this, $getter)) {
return $this->$getter();
} else {
}
else {
throw new Exception('Getting unknown property: ' . get_class($this) . '.' . $name);
}
}
......@@ -105,9 +106,11 @@ class Object
$setter = 'set' . $name;
if (method_exists($this, $setter)) {
$this->$setter($value);
} elseif (method_exists($this, 'get' . $name)) {
}
elseif (method_exists($this, 'get' . $name)) {
throw new Exception('Setting read-only property: ' . get_class($this) . '.' . $name);
} else {
}
else {
throw new Exception('Setting unknown property: ' . get_class($this) . '.' . $name);
}
}
......@@ -127,7 +130,8 @@ class Object
$getter = 'get' . $name;
if (method_exists($this, $getter)) { // property is not null
return $this->$getter() !== null;
} else {
}
else {
return false;
}
}
......@@ -146,9 +150,10 @@ class Object
public function __unset($name)
{
$setter = 'set' . $name;
if (method_exists($this, $setter)) { // write property
if (method_exists($this, $setter)) { // write property
$this->$setter(null);
} elseif (method_exists($this, 'get' . $name)) {
}
elseif (method_exists($this, 'get' . $name)) {
throw new Exception('Unsetting read-only property: ' . get_class($this) . '.' . $name);
}
}
......@@ -244,74 +249,107 @@ class Object
* @param array $_data_ additional parameters to be passed to the above expression/callback.
* @return mixed the expression result
*/
public function evaluateExpression($_expression_, $_data_=array())
public function evaluateExpression($_expression_, $_data_ = array())
{
if (is_string($_expression_)) {
extract($_data_);
return eval('return ' . $_expression_ . ';');
} else {
}
else {
$_data_[] = $this;
return call_user_func_array($_expression_, $_data_);
}
}
/**
* Creates a new object instance.
*
* This method calls [[\Yii::create]] to create the new object instance.
*
* This method differs from the PHP `new` operator in that it does the following
* steps to create a new object instance:
*
* - Call class constructor (same as the `new` operator);
* - Initialize the object properties using the name-value pairs given as the
* last parameter to this method;
* - Call [[Initable::init|init]] if the class implements [[Initable]].
* Creates a new instance of the calling class.
*
* Parameters passed to this method will be used as the parameters to the object
* constructor.
*
* Additionally, one can pass in an associative array as the last parameter to
* this method. This method will treat the array as name-value pairs that initialize
* the corresponding object properties. For example,
* This method does the following steps to create a object:
*
* - create the object using the PHP `new` operator;
* - if [[Yii::objectConfig]] contains the configuration for the object class,
* initialize the object properties with that configuration;
* - if the number of the given parameters is more than the number of the parameters
* listed in the object constructor and the last given parameter is an array,
* initialize the object properties using that array;
* - call the `init` method of the object if it implements the [[yii\base\Initable]] interface.
*
* For example,
*
* ~~~
* class Foo extends \yii\base\Object
* class Foo extends \yii\base\Object implements \yii\base\Initable
* {
* public $c;
* public function __construct($a, $b)
* {
* ...
* }
* public $c;
* public function __construct($a, $b)
* {
* ...
* }
* public function init()
* {
* ...
* }
* }
*
* $model = Foo::create(1, 2, array('c' => 3));
* $model = Foo::newInstance(1, 2, array('c' => 3));
* // which is equivalent to the following lines:
* $model = new Foo(1, 2);
* $model->c = 3;
* $model->init();
* ~~~
*
* @return object the created object
* @throws Exception if the configuration is invalid.
*/
public static function create()
public static function newInstance()
{
$class = '\\' . get_called_class();
$c = get_called_class();
$class = '\\' . $c;
if (($n = func_num_args()) > 0) {
$args = func_get_args();
if (is_array($args[$n-1])) {
// the last parameter could be configuration array
if (is_array($args[$n - 1])) {
$method = new \ReflectionMethod($class, '__construct');
if ($method->getNumberOfParameters()+1 == $n) {
$config = $args[$n-1];
array_pop($args);
if ($method->getNumberOfParameters() < $n) {
// the last EXTRA parameter is a configuration array
$config = $args[--$n];
unset($args[$n]);
}
}
$config['class'] = $class;
array_unshift($args, $config);
return call_user_func_array('\Yii::create', $args);
} else {
return \Yii::create($class);
}
if ($n === 0) {
$object = new $class;
}
elseif ($n === 1) {
$object = new $class($args[0]);
}
elseif ($n === 2) {
$object = new $class($args[0], $args[1]);
}
elseif ($n === 3) {
$object = new $class($args[0], $args[1], $args[2]);
}
else {
$r = new \ReflectionClass($class);
$object = $r->newInstanceArgs($args);
}
if (isset(\Yii::$objectConfig[$c])) {
$config = isset($config) ? array_merge(\Yii::$objectConfig[$c], $config) : \Yii::$objectConfig[$c];
}
if (!empty($config)) {
foreach ($config as $name => $value) {
$object->$name = $value;
}
}
if ($object instanceof \yii\base\Initable) {
$object->init();
}
return $object;
}
}
......@@ -22,12 +22,12 @@ namespace yii\base;
* like a regular PHP array as follows,
*
* ~~~
* $vector[] = $item; // append new item at the end
* $vector[$index] = $item; // set new item at $index
* unset($vector[$index]); // remove the item at $index
* if (isset($vector[$index])) // if the vector has an item at $index
* $vector[] = $item; // append new item at the end
* $vector[$index] = $item; // set new item at $index
* unset($vector[$index]); // remove the item at $index
* if (isset($vector[$index])) // if the vector has an item at $index
* foreach ($vector as $index=>$item) // traverse each item in the vector
* $n = count($vector); // count the number of items
* $n = count($vector); // count the number of items
* ~~~
*
* Note that if you plan to extend Vector by performing additional operations
......@@ -103,9 +103,11 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
{
if (isset($this->_d[$index])) {
return $this->_d[$index];
} elseif ($index >= 0 && $index < $this->_c) { // in case the value is null
}
elseif ($index >= 0 && $index < $this->_c) { // in case the value is null
return $this->_d[$index];
} else {
}
else {
throw new Exception('Index out of range: ' . $index);
}
}
......@@ -119,7 +121,7 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
public function add($item)
{
$this->insertAt($this->_c, $item);
return $this->_c-1;
return $this->_c - 1;
}
/**
......@@ -134,10 +136,12 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
{
if ($index === $this->_c) {
$this->_d[$this->_c++] = $item;
} elseif ($index >= 0 && $index < $this->_c) {
}
elseif ($index >= 0 && $index < $this->_c) {
array_splice($this->_d, $index, 0, array($item));
$this->_c++;
} else {
}
else {
throw new Exception('Index out of range: ' . $index);
}
}
......@@ -156,7 +160,8 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
if (($index = $this->indexOf($item)) >= 0) {
$this->removeAt($index);
return $index;
} else {
}
else {
return false;
}
}
......@@ -173,12 +178,14 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
$this->_c--;
if ($index === $this->_c) {
return array_pop($this->_d);
} else {
}
else {
$item = $this->_d[$index];
array_splice($this->_d, $index, 1);
return $item;
}
} else {
}
else {
throw new Exception('Index out of range: ' . $index);
}
}
......@@ -192,10 +199,11 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
public function clear($safeClear = false)
{
if ($safeClear) {
for ($i = $this->_c-1;$i >= 0;--$i) {
for ($i = $this->_c - 1; $i >= 0; --$i) {
$this->removeAt($i);
}
} else {
}
else {
$this->_d = array();
$this->_c = 0;
}
......@@ -252,7 +260,8 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
foreach ($data as $item) {
$this->add($item);
}
} else {
}
else {
throw new Exception('Data must be either an array or an object implementing Traversable.');
}
}
......@@ -272,7 +281,8 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
foreach ($data as $item) {
$this->add($item);
}
} else {
}
else {
throw new Exception('Data must be either an array or an object implementing Traversable.');
}
}
......@@ -318,7 +328,8 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
{
if ($offset === null || $offset === $this->_c) {
$this->insertAt($this->_c, $item);
} else {
}
else {
$this->removeAt($offset);
$this->insertAt($offset, $item);
}
......
......@@ -86,10 +86,10 @@ class ColumnSchema extends \yii\base\Component
{
static $typeMap = array( // logical type => php type
'smallint' => 'integer',
'integer' => 'integer',
'bigint' => 'integer',
'boolean' => 'boolean',
'float' => 'double',
'integer' => 'integer',
'bigint' => 'integer',
'boolean' => 'boolean',
'float' => 'double',
);
if (isset($typeMap[$this->type])) {
if ($this->type === 'bigint') {
......@@ -114,9 +114,12 @@ class ColumnSchema extends \yii\base\Component
return $value;
}
switch ($this->phpType) {
case 'string': return (string)$value;
case 'integer': return (integer)$value;
case 'boolean': return (boolean)$value;
case 'string':
return (string)$value;
case 'integer':
return (integer)$value;
case 'boolean':
return (boolean)$value;
}
return $value;
}
......
......@@ -26,7 +26,7 @@ use yii\db\Exception;
* the DB connection:
*
* ~~~
* $connection = \yii\db\dao\Connection::create($dsn, $username, $password);
* $connection = \yii\db\dao\Connection::newInstance($dsn, $username, $password);
* $connection->active = true; // same as: $connection->open();
* ~~~
*
......@@ -57,13 +57,13 @@ use yii\db\Exception;
* ~~~
* $transaction = $connection->beginTransaction();
* try {
* $connection->createCommand($sql1)->execute();
* $connection->createCommand($sql2)->execute();
* // ... executing other SQL statements ...
* $transaction->commit();
* $connection->createCommand($sql1)->execute();
* $connection->createCommand($sql2)->execute();
* // ... executing other SQL statements ...
* $transaction->commit();
* }
* catch(Exception $e) {
* $transaction->rollBack();
* $transaction->rollBack();
* }
* ~~~
*
......@@ -72,15 +72,15 @@ use yii\db\Exception;
*
* ~~~
* array(
* 'components' => array(
* 'db' => array(
* 'class' => '\yii\db\dao\Connection',
* 'dsn' => 'mysql:host=127.0.0.1;dbname=demo',
* 'username' => 'root',
* 'password' => '',
* 'charset' => 'utf8',
* ),
* ),
* 'components' => array(
* 'db' => array(
* 'class' => '\yii\db\dao\Connection',
* 'dsn' => 'mysql:host=127.0.0.1;dbname=demo',
* 'username' => 'root',
* 'password' => '',
* 'charset' => 'utf8',
* ),
* ),
* )
* ~~~
*
......@@ -219,7 +219,7 @@ class Connection extends \yii\base\ApplicationComponent
/**
* @var array mapping between PDO driver names and [[Schema]] classes.
* The keys of the array are PDO driver names while the values the corresponding
* schema class name or configuration. Please refer to [[\Yii::create]] for
* schema class name or configuration. Please refer to [[\Yii::createObject]] for
* details on how to specify a configuration.
*
* This property is mainly used by [[getSchema]] when fetching the database schema information.
......@@ -227,15 +227,15 @@ class Connection extends \yii\base\ApplicationComponent
* [[Schema]] class to support DBMS that is not supported by Yii.
*/
public $schemaMap = array(
'pgsql' => '\yii\db\dao\pgsql\Schema', // PostgreSQL
'mysqli' => '\yii\db\dao\mysql\Schema', // MySQL
'mysql' => '\yii\db\dao\mysql\Schema', // MySQL
'sqlite' => '\yii\db\dao\sqlite\Schema', // sqlite 3
'sqlite2' => '\yii\db\dao\sqlite\Schema', // sqlite 2
'mssql' => '\yii\db\dao\mssql\Schema', // Mssql driver on windows hosts
'dblib' => '\yii\db\dao\mssql\Schema', // dblib drivers on linux (and maybe others os) hosts
'sqlsrv' => '\yii\db\dao\mssql\Schema', // Mssql
'oci' => '\yii\db\dao\oci\Schema', // Oracle driver
'pgsql' => '\yii\db\dao\pgsql\Schema', // PostgreSQL
'mysqli' => '\yii\db\dao\mysql\Schema', // MySQL
'mysql' => '\yii\db\dao\mysql\Schema', // MySQL
'sqlite' => '\yii\db\dao\sqlite\Schema', // sqlite 3
'sqlite2' => '\yii\db\dao\sqlite\Schema', // sqlite 2
'mssql' => '\yii\db\dao\mssql\Schema', // Mssql driver on windows hosts
'dblib' => '\yii\db\dao\mssql\Schema', // dblib drivers on linux (and maybe others os) hosts
'sqlsrv' => '\yii\db\dao\mssql\Schema', // Mssql
'oci' => '\yii\db\dao\oci\Schema', // Oracle driver
);
/**
......@@ -428,7 +428,8 @@ class Connection extends \yii\base\ApplicationComponent
{
if ($this->_transaction !== null && $this->_transaction->active) {
return $this->_transaction;
} else {
}
else {
return null;
}
}
......@@ -453,11 +454,13 @@ class Connection extends \yii\base\ApplicationComponent
{
if ($this->_schema !== null) {
return $this->_schema;
} else {
}
else {
$driver = $this->getDriverName();
if (isset($this->schemaMap[$driver])) {
return $this->_schema = \Yii::create($this->schemaMap[$driver], $this);
} else {
return $this->_schema = \Yii::createObject($this->schemaMap[$driver], $this);
}
else {
throw new Exception("Connection does not support reading schema for '$driver' database.");
}
}
......@@ -500,7 +503,8 @@ class Connection extends \yii\base\ApplicationComponent
$this->open();
if (($value = $this->pdo->quote($str)) !== false) {
return $value;
} else { // the driver doesn't support quote (e.g. oci)
}
else { // the driver doesn't support quote (e.g. oci)
return "'" . addcslashes(str_replace("'", "''", $str), "\000\n\r\\\032") . "'";
}
}
......@@ -542,7 +546,8 @@ class Connection extends \yii\base\ApplicationComponent
{
if ($this->tablePrefix !== null && strpos($sql, '{{') !== false) {
return preg_replace('/{{(.*?)}}/', $this->tablePrefix . '\1', $sql);
} else {
}
else {
return $sql;
}
}
......@@ -572,7 +577,8 @@ class Connection extends \yii\base\ApplicationComponent
{
if (($pos = strpos($this->dsn, ':')) !== false) {
return strtolower(substr($this->dsn, 0, $pos));
} else {
}
else {
return strtolower($this->getAttribute(\PDO::ATTR_DRIVER_NAME));
}
}
......
......@@ -22,7 +22,7 @@ use yii\db\Exception;
*
* ~~~
* foreach($reader as $row) {
* // $row represents a row of data
* // $row represents a row of data
* }
* ~~~
*
......
......@@ -102,10 +102,10 @@ class Query extends \yii\base\Object
}
if ($this->select !== $query->select) {
if($this->select === '*') {
if ($this->select === '*') {
$this->select = $query->select;
}
elseif($query->select!=='*') {
elseif ($query->select !== '*') {
$select1 = is_string($this->select) ? preg_split('/\s*,\s*/', trim($this->select), -1, PREG_SPLIT_NO_EMPTY) : $this->select;
$select2 = is_string($query->select) ? preg_split('/\s*,\s*/', trim($query->select), -1, PREG_SPLIT_NO_EMPTY) : $query->select;
$this->select = array_merge($select1, array_diff($select2, $select1));
......@@ -238,16 +238,19 @@ class Query extends \yii\base\Object
*/
public function addCondition($condition, $operator = 'AND')
{
if (is_array($condition))
{
if ($condition === array())
if (is_array($condition)) {
if ($condition === array()) {
return $this;
}
$condition = '(' . implode(') ' . $operator . ' (', $condition) . ')';
}
if ($this->condition === '')
if ($this->condition === '') {
$this->condition = $condition;
}
else
{
$this->condition = '(' . $this->condition . ') ' . $operator . ' (' . $condition . ')';
}
return $this;
}
......@@ -271,10 +274,12 @@ class Query extends \yii\base\Object
*/
public function addSearchCondition($column, $keyword, $escape = true, $operator = 'AND', $like = 'LIKE')
{
if ($keyword == '')
if ($keyword == '') {
return $this;
if ($escape)
}
if ($escape) {
$keyword = '%' . strtr($keyword, array('%' => '\%', '_' => '\_', '\\' => '\\\\')) . '%';
}
$condition = $column . " $like " . self::PARAM_PREFIX . self::$paramCount;
$this->params[self::PARAM_PREFIX . self::$paramCount++] = $keyword;
return $this->addCondition($condition, $operator);
......@@ -294,13 +299,14 @@ class Query extends \yii\base\Object
*/
public function addInCondition($column, $values, $operator = 'AND')
{
if (($n = count($values)) < 1)
return $this->addCondition('0=1', $operator); // 0=1 is used because in MSSQL value alone can't be used in WHERE
if ($n === 1)
{
if (($n = count($values)) < 1) {
return $this->addCondition('0=1', $operator);
} // 0=1 is used because in MSSQL value alone can't be used in WHERE
if ($n === 1) {
$value = reset($values);
if ($value === null)
if ($value === null) {
return $this->addCondition($column . ' IS NULL');
}
$condition = $column . '=' . self::PARAM_PREFIX . self::$paramCount;
$this->params[self::PARAM_PREFIX . self::$paramCount++] = $value;
}
......@@ -331,13 +337,14 @@ class Query extends \yii\base\Object
*/
public function addNotInCondition($column, $values, $operator = 'AND')
{
if (($n = count($values)) < 1)
if (($n = count($values)) < 1) {
return $this;
if ($n === 1)
{
}
if ($n === 1) {
$value = reset($values);
if ($value === null)
if ($value === null) {
return $this->addCondition($column . ' IS NOT NULL');
}
$condition = $column . '!=' . self::PARAM_PREFIX . self::$paramCount;
$this->params[self::PARAM_PREFIX . self::$paramCount++] = $value;
}
......@@ -370,8 +377,9 @@ class Query extends \yii\base\Object
$params = array();
foreach ($columns as $name => $value)
{
if ($value === null)
if ($value === null) {
$params[] = $name . ' IS NULL';
}
else
{
$params[] = $name . '=' . self::PARAM_PREFIX . self::$paramCount;
......@@ -426,35 +434,42 @@ class Query extends \yii\base\Object
*/
public function compare($column, $value, $partialMatch = false, $operator = 'AND', $escape = true)
{
if (is_array($value))
{
if ($value === array())
if (is_array($value)) {
if ($value === array()) {
return $this;
}
return $this->addInCondition($column, $value, $operator);
}
else
{
$value = "$value";
}
if (preg_match('/^(?:\s*(<>|<=|>=|<|>|=))?(.*)$/', $value, $matches))
{
if (preg_match('/^(?:\s*(<>|<=|>=|<|>|=))?(.*)$/', $value, $matches)) {
$value = $matches[2];
$op = $matches[1];
}
else
{
$op = '';
}
if ($value === '')
if ($value === '') {
return $this;
}
if ($partialMatch)
{
if ($op === '')
if ($partialMatch) {
if ($op === '') {
return $this->addSearchCondition($column, $value, $escape, $operator);
if ($op === '<>')
}
if ($op === '<>') {
return $this->addSearchCondition($column, $value, $escape, $operator, 'NOT LIKE');
}
}
elseif ($op === '')
{
$op = '=';
}
$this->addCondition($column . $op . self::PARAM_PREFIX . self::$paramCount, $operator);
$this->params[self::PARAM_PREFIX . self::$paramCount++] = $value;
......@@ -479,8 +494,9 @@ class Query extends \yii\base\Object
*/
public function addBetweenCondition($column, $valueStart, $valueEnd, $operator = 'AND')
{
if ($valueStart === '' || $valueEnd === '')
if ($valueStart === '' || $valueEnd === '') {
return $this;
}
$paramStart = self::PARAM_PREFIX . self::$paramCount++;
$paramEnd = self::PARAM_PREFIX . self::$paramCount++;
......@@ -488,10 +504,13 @@ class Query extends \yii\base\Object
$this->params[$paramEnd] = $valueEnd;
$condition = "$column BETWEEN $paramStart AND $paramEnd";
if ($this->condition === '')
if ($this->condition === '') {
$this->condition = $condition;
}
else
{
$this->condition = '(' . $this->condition . ') ' . $operator . ' (' . $condition . ')';
}
return $this;
}
......
......@@ -23,21 +23,21 @@ class QueryBuilder extends \yii\base\Object
/**
* @var array the abstract column types mapped to physical column types.
*/
public $typeMap = array(
'pk' => 'int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY',
'string' => 'varchar(255)',
'text' => 'text',
'integer' => 'int(11)',
'float' => 'float',
'decimal' => 'decimal',
'datetime' => 'datetime',
'timestamp' => 'timestamp',
'time' => 'time',
'date' => 'date',
'binary' => 'blob',
'boolean' => 'tinyint(1)',
public $typeMap = array(
'pk' => 'int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY',
'string' => 'varchar(255)',
'text' => 'text',
'integer' => 'int(11)',
'float' => 'float',
'decimal' => 'decimal',
'datetime' => 'datetime',
'timestamp' => 'timestamp',
'time' => 'time',
'date' => 'date',
'binary' => 'blob',
'boolean' => 'tinyint(1)',
'money' => 'decimal(19,4)',
);
);
/**
* @var Connection the database connection.
*/
......@@ -177,7 +177,9 @@ class QueryBuilder extends \yii\base\Object
$cols[] = "\t" . $this->schema->quoteColumnName($name) . ' ' . $this->schema->getColumnType($type);
}
else
{
$cols[] = "\t" . $type;
}
}
$sql = "CREATE TABLE " . $this->schema->quoteTableName($table) . " (\n" . implode(",\n", $cols) . "\n)";
return $options === null ? $sql : $sql . ' ' . $options;
......@@ -288,20 +290,24 @@ class QueryBuilder extends \yii\base\Object
public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete = null, $update = null)
{
$columns = preg_split('/\s*,\s*/', $columns, -1, PREG_SPLIT_NO_EMPTY);
foreach ($columns as $i => $col)
foreach ($columns as $i => $col) {
$columns[$i] = $this->schema->quoteColumnName($col);
}
$refColumns = preg_split('/\s*,\s*/', $refColumns, -1, PREG_SPLIT_NO_EMPTY);
foreach ($refColumns as $i => $col)
foreach ($refColumns as $i => $col) {
$refColumns[$i] = $this->schema->quoteColumnName($col);
}
$sql = 'ALTER TABLE ' . $this->schema->quoteTableName($table)
. ' ADD CONSTRAINT ' . $this->schema->quoteColumnName($name)
. ' FOREIGN KEY (' . implode(', ', $columns) . ')'
. ' REFERENCES ' . $this->schema->quoteTableName($refTable)
. ' (' . implode(', ', $refColumns) . ')';
if ($delete !== null)
if ($delete !== null) {
$sql .= ' ON DELETE ' . $delete;
if ($update !== null)
}
if ($update !== null) {
$sql .= ' ON UPDATE ' . $update;
}
return $sql;
}
......@@ -332,10 +338,13 @@ class QueryBuilder extends \yii\base\Object
$columns = preg_split('/\s*,\s*/', $column, -1, PREG_SPLIT_NO_EMPTY);
foreach ($columns as $col)
{
if (strpos($col, '(') !== false)
if (strpos($col, '(') !== false) {
$cols[] = $col;
}
else
{
$cols[] = $this->schema->quoteColumnName($col);
}
}
return ($unique ? 'CREATE UNIQUE INDEX ' : 'CREATE INDEX ')
. $this->schema->quoteTableName($name) . ' ON '
......@@ -400,8 +409,8 @@ class QueryBuilder extends \yii\base\Object
* @param string $type abstract column type
* @return string physical column type.
*/
public function getColumnType($type)
{
public function getColumnType($type)
{
if (isset($this->typeMap[$type])) {
return $this->typeMap[$type];
}
......@@ -485,19 +494,19 @@ class QueryBuilder extends \yii\base\Object
}
foreach ($joins as $i => $join) {
if (is_array($join)) { // join type, table name, on-condition
if (is_array($join)) { // join type, table name, on-condition
if (isset($join[0], $join[1])) {
$table = $join[1];
if (strpos($table,'(')===false) {
if (preg_match('/^(.*?)(?i:\s+as\s+|\s+)(.*)$/', $table, $matches)) { // with alias
$table = $this->connection->quoteTableName($matches[1]).' '.$this->connection->quoteTableName($matches[2]);
if (strpos($table, '(') === false) {
if (preg_match('/^(.*?)(?i:\s+as\s+|\s+)(.*)$/', $table, $matches)) { // with alias
$table = $this->connection->quoteTableName($matches[1]) . ' ' . $this->connection->quoteTableName($matches[2]);
}
else {
$table = $this->connection->quoteTableName($table);
}
}
$joins[$i] = strtoupper($join[0]) . ' ' . $table;
if (isset($join[2])) { // join condition
if (isset($join[2])) { // join condition
$condition = $this->buildCondition($join[2]);
$joins[$i] .= ' ON ' . $condition;
}
......@@ -582,8 +591,8 @@ class QueryBuilder extends \yii\base\Object
if ($query->limit !== null && $query->limit >= 0) {
$sql = 'LIMIT ' . (int)$query->limit;
}
if ($query->offset>0) {
$sql .= ' OFFSET '.(int)$query->offset;
if ($query->offset > 0) {
$sql .= ' OFFSET ' . (int)$query->offset;
}
return ltrim($sql);
}
......
......@@ -20,6 +20,9 @@ use yii\db\Exception;
*/
abstract class Schema extends \yii\base\Object
{
/**
* @var \yii\db\dao\Connection the database connection
*/
public $connection;
private $_tableNames = array();
......@@ -194,7 +197,9 @@ abstract class Schema extends \yii\base\Object
$name = substr($name, $pos + 1);
}
else
{
$prefix = '';
}
return $prefix . $this->quoteSimpleColumnName($name);
}
......
......@@ -55,9 +55,9 @@ class TableSchema extends \yii\base\Object
*
* ~~~
* array(
* 'ForeignTableName',
* 'fk1' => 'pk1', // pk1 is in foreign table
* 'fk2' => 'pk2', // if composite foreign key
* 'ForeignTableName',
* 'fk1' => 'pk1', // pk1 is in foreign table
* 'fk2' => 'pk2', // if composite foreign key
* )
* ~~~
*/
......
......@@ -23,13 +23,13 @@ use yii\db\Exception;
* ~~~
* $transaction = $connection->beginTransaction();
* try {
* $connection->createCommand($sql1)->execute();
* $connection->createCommand($sql2)->execute();
* //.... other SQL executions
* $transaction->commit();
* $connection->createCommand($sql1)->execute();
* $connection->createCommand($sql2)->execute();
* //.... other SQL executions
* $transaction->commit();
* }
* catch(Exception $e) {
* $transaction->rollBack();
* $transaction->rollBack();
* }
* ~~~
*
......@@ -69,7 +69,8 @@ class Transaction extends \yii\base\Object
\Yii::trace('Committing transaction', __CLASS__);
$this->connection->pdo->commit();
$this->active = false;
} else {
}
else {
throw new Exception('Failed to commit transaction: transaction was inactive.');
}
}
......@@ -84,7 +85,8 @@ class Transaction extends \yii\base\Object
\Yii::trace('Rolling back transaction', __CLASS__);
$this->connection->pdo->rollBack();
$this->active = false;
} else {
}
else {
throw new Exception('Failed to roll back transaction: transaction was inactive.');
}
}
......
......@@ -22,12 +22,12 @@ namespace yii\logging;
*/
class Logger extends \yii\base\Component
{
const LEVEL_ERROR = 1;
const LEVEL_WARNING = 2;
const LEVEL_INFO = 3;
const LEVEL_TRACE = 4;
const LEVEL_PROFILE_BEGIN = 5;
const LEVEL_PROFILE_END = 6;
const LEVEL_ERROR = 'error';
const LEVEL_WARNING = 'warning';
const LEVEL_INFO = 'info';
const LEVEL_TRACE = 'trace';
const LEVEL_PROFILE_BEGIN = 'profile-begin';
const LEVEL_PROFILE_END = 'profile-end';
/**
* @var integer how many messages should be logged before they are flushed from memory and sent to targets.
......@@ -253,13 +253,10 @@ class Logger extends \yii\base\Component
$stack = array();
foreach ($this->messages as $log) {
if ($log[1] < self::LEVEL_PROFILE_BEGIN) {
continue;
}
list($token, $level, $category, $timestamp) = $log;
if ($level === self::LEVEL_PROFILE_BEGIN) {
if ($log[1] === self::LEVEL_PROFILE_BEGIN) {
$stack[] = $log;
} else {
} elseif ($log[1] === self::LEVEL_PROFILE_END) {
list($token, $level, $category, $timestamp) = $log;
if (($last = array_pop($stack)) !== null && $last[0] === $token) {
$timings[] = array($token, $category, $timestamp - $last[3]);
} else {
......
......@@ -101,7 +101,7 @@ class Router extends \yii\base\ApplicationComponent
* Sets the log targets.
* @param array $config list of log target configurations. Each array element
* represents the configuration for creating a single log target. It will be
* passed to [[\Yii::create]] to create the target instance.
* passed to [[\Yii::createObject]] to create the target instance.
*/
public function setTargets($config)
{
......@@ -110,7 +110,7 @@ class Router extends \yii\base\ApplicationComponent
$this->_targets[$name] = $target;
}
else {
$this->_targets[$name] = \Yii::create($target);
$this->_targets[$name] = \Yii::createObject($target);
}
}
}
......
......@@ -166,7 +166,7 @@ abstract class Validator extends \yii\base\Component
foreach ($params as $name => $value) {
$config[$name] = $value;
}
$validator = \Yii::create($config);
$validator = \Yii::createObject($config);
return $validator;
}
......
......@@ -21,7 +21,7 @@ class BehaviorTest extends \yiiunit\TestCase
{
public function testAttachAndAccessing()
{
$bar = BarClass::create();
$bar = BarClass::newInstance();
$behavior = new BarBehavior();
$bar->attachBehavior('bar', $behavior);
$this->assertEquals('behavior property', $bar->behaviorProperty);
......
......@@ -206,7 +206,7 @@ class ComponentTest extends \yiiunit\TestCase
public function testCreate()
{
$component = NewComponent2::create(1, 2, array('a'=>3));
$component = NewComponent2::newInstance(1, 2, array('a'=>3));
$this->assertEquals(1, $component->b);
$this->assertEquals(2, $component->c);
$this->assertEquals(3, $component->a);
......
......@@ -7,6 +7,23 @@ class Foo extends \yii\base\Object
public $prop;
}
class Bar extends \yii\base\Component implements \yii\base\Initable
{
public $prop1;
public $prop2;
public $prop3;
public function __construct($a, $b)
{
$this->prop1 = $a + $b;
}
public function init()
{
$this->prop3 = 3;
}
}
/**
* ObjectTest
*/
......@@ -24,15 +41,28 @@ class ObjectTest extends \yiiunit\TestCase
$this->object = null;
}
public function testCreate()
public function testNewInstance()
{
$foo = Foo::create(array(
$foo = Foo::newInstance(array(
'prop' => array(
'test' => 'test',
),
));
$this->assertEquals('test', $foo->prop['test']);
$bar = Bar::newInstance(10, 20);
$this->assertEquals(30, $bar->prop1);
$this->assertEquals(null, $bar->prop2);
$this->assertEquals(3, $bar->prop3);
$bar = Bar::newInstance(100, 200, array(
'prop2' => 'x',
'prop3' => 400,
));
$this->assertEquals(300, $bar->prop1);
$this->assertEquals('x', $bar->prop2);
$this->assertEquals(3, $bar->prop3);
}
public function testHasProperty()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment