Commit 7f35f9ad by Qiang Xue

...

parent 59f57a82
...@@ -16,7 +16,7 @@ change API. Results in less repetitive code. Performance drop isn't significant. ...@@ -16,7 +16,7 @@ change API. Results in less repetitive code. Performance drop isn't significant.
### callbacks and expressions ### callbacks and expressions
### [[Object::create()]|create] method ### [[Object::newInstance|newInstance]] method
This method is a powerful way to instantiate a class. Differences from `new`: This method is a powerful way to instantiate a class. Differences from `new`:
......
...@@ -49,12 +49,16 @@ class YiiBase ...@@ -49,12 +49,16 @@ class YiiBase
* @var array class map used by the Yii autoloading mechanism. * @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. * The array keys are the class names, and the array values are the corresponding class file paths.
* This property mainly affects how [[autoload]] works. * This property mainly affects how [[autoload]] works.
* @see import
* @see autoload
*/ */
public static $classMap = array(); public static $classMap = array();
/** /**
* @var array list of directories where Yii will search for new classes to be included. * @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. * The first directory in the array will be searched first, and so on.
* This property mainly affects how [[autoload]] works. * This property mainly affects how [[autoload]] works.
* @see import
* @see autoload
*/ */
public static $classPath = array(); public static $classPath = array();
/** /**
...@@ -63,10 +67,34 @@ class YiiBase ...@@ -63,10 +67,34 @@ class YiiBase
public static $app; public static $app;
/** /**
* @var array registered path aliases * @var array registered path aliases
* @see getAlias
* @see setAlias
*/ */
public static $aliases = array( public static $aliases = array(
'@yii' => __DIR__, '@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 $_imported = array(); // alias => class name or directory
private static $_logger; private static $_logger;
...@@ -140,13 +168,11 @@ class YiiBase ...@@ -140,13 +168,11 @@ class YiiBase
if ($forceInclude) { if ($forceInclude) {
require($path . "/$className.php"); require($path . "/$className.php");
self::$_imported[$alias] = $className; self::$_imported[$alias] = $className;
} } else {
else {
self::$classMap[$className] = $path . "/$className.php"; self::$classMap[$className] = $path . "/$className.php";
} }
return $className; return $className;
} } else { // a directory
else { // a directory
array_unshift(self::$classPath, $path); array_unshift(self::$classPath, $path);
return self::$_imported[$alias] = $path; return self::$_imported[$alias] = $path;
} }
...@@ -172,11 +198,9 @@ class YiiBase ...@@ -172,11 +198,9 @@ class YiiBase
{ {
if (isset(self::$aliases[$alias])) { if (isset(self::$aliases[$alias])) {
return self::$aliases[$alias]; return self::$aliases[$alias];
} } elseif ($alias[0] !== '@') { // not an alias
elseif ($alias[0] !== '@') { // not an alias
return $alias; return $alias;
} } elseif (($pos = strpos($alias, '/')) !== false) {
elseif (($pos = strpos($alias, '/')) !== false) {
$rootAlias = substr($alias, 0, $pos); $rootAlias = substr($alias, 0, $pos);
if (isset(self::$aliases[$rootAlias])) { if (isset(self::$aliases[$rootAlias])) {
return self::$aliases[$alias] = self::$aliases[$rootAlias] . substr($alias, $pos); return self::$aliases[$alias] = self::$aliases[$rootAlias] . substr($alias, $pos);
...@@ -207,14 +231,11 @@ class YiiBase ...@@ -207,14 +231,11 @@ class YiiBase
{ {
if ($path === null) { if ($path === null) {
unset(self::$aliases[$alias]); unset(self::$aliases[$alias]);
} } elseif ($path[0] !== '@') {
elseif ($path[0] !== '@') {
self::$aliases[$alias] = rtrim($path, '\\/'); self::$aliases[$alias] = rtrim($path, '\\/');
} } elseif (($p = static::getAlias($path)) !== false) {
elseif (($p = static::getAlias($path)) !== false) {
self::$aliases[$alias] = $p; self::$aliases[$alias] = $p;
} } else {
else {
throw new \yii\base\Exception('Invalid path: ' . $path); throw new \yii\base\Exception('Invalid path: ' . $path);
} }
} }
...@@ -278,22 +299,34 @@ class YiiBase ...@@ -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. * The configuration can be either a string or an array.
* If the former, the string is treated as the object type; if the latter, * If a string, it is treated as the *object type*; if an array,
* the array must contain a `class` element specifying the object type, and * 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 rest of the name-value pairs in the array will be used to initialize
* the corresponding object properties. * 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, * 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'); * $object = \Yii::createObject('@app/components/GoogleMap');
* $component = Yii::create('\application\components\GoogleMap'); * $object = \Yii::createObject(array(
* $component = Yii::create(array( * 'class' => '\app\components\GoogleMap',
* 'class' => '@app/components/GoogleMap',
* 'apiKey' => 'xyz', * 'apiKey' => 'xyz',
* )); * ));
* ~~~ * ~~~
...@@ -301,25 +334,19 @@ class YiiBase ...@@ -301,25 +334,19 @@ class YiiBase
* Any additional parameters passed to this method will be * Any additional parameters passed to this method will be
* passed to the constructor of the object being created. * 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. * @param mixed $config the configuration. It can be either a string or an array.
* @return mixed the created object * @return mixed the created object
* @throws \yii\base\Exception if the configuration is invalid. * @throws \yii\base\Exception if the configuration is invalid.
*/ */
public static function create($config) public static function createObject($config)
{ {
if (is_string($config)) { if (is_string($config)) {
$class = $config; $class = $config;
$config = array(); $config = array();
} } elseif (isset($config['class'])) {
elseif (isset($config['class'])) {
$class = $config['class']; $class = $config['class'];
unset($config['class']); unset($config['class']);
} } else {
else {
throw new \yii\base\Exception('Object configuration must be an array containing a "class" element.'); throw new \yii\base\Exception('Object configuration must be an array containing a "class" element.');
} }
...@@ -327,36 +354,38 @@ class YiiBase ...@@ -327,36 +354,38 @@ class YiiBase
$class = static::import($class, true); $class = static::import($class, true);
} }
if (($n = func_num_args()) > 1) { if (($n = func_num_args()-1) > 0) {
$args = func_get_args(); $args = func_get_args();
if ($n === 2) { array_shift($args); // remove $config
$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]); if ($n === 0) {
$r = new ReflectionClass($class); $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); $object = $r->newInstanceArgs($args);
} }
}
else { $c = get_class($object);
$object = new $class; 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) { foreach ($config as $name => $value) {
$object->$name = $value; $object->$name = $value;
} }
}
if ($object instanceof \yii\base\Initable) { if ($object instanceof \yii\base\Initable) {
$object->init(); $object->init();
} }
return $object;
} }
/** /**
...@@ -426,7 +455,7 @@ class YiiBase ...@@ -426,7 +455,7 @@ class YiiBase
* @param string $category the category of this log message * @param string $category the category of this log message
* @see endProfile * @see endProfile
*/ */
public static function beginProfile($token, $category) public static function beginProfile($token, $category = 'application')
{ {
self::getLogger()->beginProfile($token, $category); self::getLogger()->beginProfile($token, $category);
} }
...@@ -438,7 +467,7 @@ class YiiBase ...@@ -438,7 +467,7 @@ class YiiBase
* @param string $category the category of this log message * @param string $category the category of this log message
* @see beginProfile * @see beginProfile
*/ */
public static function endProfile($token, $category) public static function endProfile($token, $category = 'application')
{ {
self::getLogger()->endProfile($token, $category); self::getLogger()->endProfile($token, $category);
} }
...@@ -451,8 +480,7 @@ class YiiBase ...@@ -451,8 +480,7 @@ class YiiBase
{ {
if (self::$_logger !== null) { if (self::$_logger !== null) {
return self::$_logger; return self::$_logger;
} } else {
else {
return self::$_logger = new \yii\logging\Logger; return self::$_logger = new \yii\logging\Logger;
} }
} }
......
...@@ -98,15 +98,18 @@ class Component extends Object ...@@ -98,15 +98,18 @@ class Component extends Object
$getter = 'get' . $name; $getter = 'get' . $name;
if (method_exists($this, $getter)) { // read property, e.g. getName() if (method_exists($this, $getter)) { // read property, e.g. getName()
return $this->$getter(); 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); $name = strtolower($name);
if (!isset($this->_e[$name])) { if (!isset($this->_e[$name])) {
$this->_e[$name] = new Vector; $this->_e[$name] = new Vector;
} }
return $this->_e[$name]; return $this->_e[$name];
} elseif (isset($this->_b[$name])) { // behavior }
elseif (isset($this->_b[$name])) { // behavior
return $this->_b[$name]; 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) { foreach ($this->_b as $object) {
if ($object->canGetProperty($name)) { if ($object->canGetProperty($name)) {
return $object->$name; return $object->$name;
...@@ -137,13 +140,15 @@ class Component extends Object ...@@ -137,13 +140,15 @@ class Component extends Object
$setter = 'set' . $name; $setter = 'set' . $name;
if (method_exists($this, $setter)) { // write property if (method_exists($this, $setter)) { // write property
return $this->$setter($value); 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); $name = strtolower($name);
if (!isset($this->_e[$name])) { if (!isset($this->_e[$name])) {
$this->_e[$name] = new Vector; $this->_e[$name] = new Vector;
} }
return $this->_e[$name]->add($value); return $this->_e[$name]->add($value);
} elseif (is_array($this->_b)) { // behavior }
elseif (is_array($this->_b)) { // behavior
foreach ($this->_b as $object) { foreach ($this->_b as $object) {
if ($object->canSetProperty($name)) { if ($object->canSetProperty($name)) {
return $object->$name = $value; return $object->$name = $value;
...@@ -152,7 +157,8 @@ class Component extends Object ...@@ -152,7 +157,8 @@ class Component extends Object
} }
if (method_exists($this, 'get' . $name)) { if (method_exists($this, 'get' . $name)) {
throw new Exception('Setting read-only property: ' . get_class($this) . '.' . $name); throw new Exception('Setting read-only property: ' . get_class($this) . '.' . $name);
} else { }
else {
throw new Exception('Setting unknown property: ' . get_class($this) . '.' . $name); throw new Exception('Setting unknown property: ' . get_class($this) . '.' . $name);
} }
} }
...@@ -175,12 +181,15 @@ class Component extends Object ...@@ -175,12 +181,15 @@ class Component extends Object
$getter = 'get' . $name; $getter = 'get' . $name;
if (method_exists($this, $getter)) { // property is not null if (method_exists($this, $getter)) { // property is not null
return $this->$getter() !== 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); $name = strtolower($name);
return isset($this->_e[$name]) && $this->_e[$name]->getCount(); return isset($this->_e[$name]) && $this->_e[$name]->getCount();
} elseif (isset($this->_b[$name])) { // has behavior }
elseif (isset($this->_b[$name])) { // has behavior
return true; return true;
} elseif (is_array($this->_b)) { }
elseif (is_array($this->_b)) {
foreach ($this->_b as $object) { foreach ($this->_b as $object) {
if ($object->canGetProperty($name)) { if ($object->canGetProperty($name)) {
return $object->$name !== null; return $object->$name !== null;
...@@ -208,12 +217,15 @@ class Component extends Object ...@@ -208,12 +217,15 @@ class Component extends Object
$setter = 'set' . $name; $setter = 'set' . $name;
if (method_exists($this, $setter)) { // write property if (method_exists($this, $setter)) { // write property
return $this->$setter(null); 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)]); unset($this->_e[strtolower($name)]);
return; return;
} elseif (isset($this->_b[$name])) { // behavior }
elseif (isset($this->_b[$name])) { // behavior
return $this->detachBehavior($name); return $this->detachBehavior($name);
} elseif (is_array($this->_b)) { // behavior property }
elseif (is_array($this->_b)) { // behavior property
foreach ($this->_b as $object) { foreach ($this->_b as $object) {
if ($object->canSetProperty($name)) { if ($object->canSetProperty($name)) {
return $object->$name = null; return $object->$name = null;
...@@ -266,7 +278,7 @@ class Component extends Object ...@@ -266,7 +278,7 @@ class Component extends Object
*/ */
public function hasEvent($name) public function hasEvent($name)
{ {
return method_exists($this, $name) && strncasecmp($name, 'on', 2)===0; return method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0;
} }
/** /**
...@@ -374,17 +386,21 @@ class Component extends Object ...@@ -374,17 +386,21 @@ class Component extends Object
foreach ($this->_e[$name] as $handler) { foreach ($this->_e[$name] as $handler) {
if (is_string($handler) || $handler instanceof \Closure) { if (is_string($handler) || $handler instanceof \Closure) {
call_user_func($handler, $event); call_user_func($handler, $event);
} elseif (is_callable($handler, true)) { }
elseif (is_callable($handler, true)) {
// an array: 0 - object, 1 - method name // an array: 0 - object, 1 - method name
list($object, $method) = $handler; list($object, $method) = $handler;
if (is_string($object)) { // static method call if (is_string($object)) { // static method call
call_user_func($handler, $event); call_user_func($handler, $event);
} elseif (method_exists($object, $method)) { }
elseif (method_exists($object, $method)) {
$object->$method($event); $object->$method($event);
} else { }
else {
throw new Exception('Event "' . get_class($this) . '.' . $name . '" is attached with an invalid handler.'); 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.'); throw new Exception('Event "' . get_class($this) . '.' . $name . '" is attached with an invalid handler.');
} }
...@@ -393,7 +409,8 @@ class Component extends Object ...@@ -393,7 +409,8 @@ class Component extends Object
return; return;
} }
} }
} elseif (!$this->hasEvent($name)) { }
elseif (!$this->hasEvent($name)) {
throw new Exception('Raising unknown event: ' . get_class($this) . '.' . $name); throw new Exception('Raising unknown event: ' . get_class($this) . '.' . $name);
} }
} }
...@@ -419,16 +436,15 @@ class Component extends Object ...@@ -419,16 +436,15 @@ class Component extends Object
* *
* - a [[Behavior]] object * - a [[Behavior]] object
* - a string specifying the behavior class * - 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 * @return Behavior the behavior object
* @see detachBehavior * @see detachBehavior
*/ */
public function attachBehavior($name, $behavior) public function attachBehavior($name, $behavior)
{ {
if (!($behavior instanceof Behavior)) { if (!($behavior instanceof Behavior)) {
$behavior = \Yii::create($behavior); $behavior = \Yii::createObject($behavior);
} }
$behavior->attach($this); $behavior->attach($this);
return $this->_b[$name] = $behavior; return $this->_b[$name] = $behavior;
......
...@@ -114,7 +114,8 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co ...@@ -114,7 +114,8 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
{ {
if ($key === null) { if ($key === null) {
$this->_d[] = $value; $this->_d[] = $value;
} else { }
else {
$this->_d[$key] = $value; $this->_d[$key] = $value;
} }
} }
...@@ -131,7 +132,8 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co ...@@ -131,7 +132,8 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
$value = $this->_d[$key]; $value = $this->_d[$key];
unset($this->_d[$key]); unset($this->_d[$key]);
return $value; return $value;
} else { // the value is null }
else { // the value is null
unset($this->_d[$key]); unset($this->_d[$key]);
return null; return null;
} }
...@@ -149,7 +151,8 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co ...@@ -149,7 +151,8 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
foreach (array_keys($this->_d) as $key) { foreach (array_keys($this->_d) as $key) {
$this->remove($key); $this->remove($key);
} }
} else { }
else {
$this->_d = array(); $this->_d = array();
} }
} }
...@@ -181,8 +184,7 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co ...@@ -181,8 +184,7 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
*/ */
public function copyFrom($data) public function copyFrom($data)
{ {
if (is_array($data) || $data instanceof \Traversable) if (is_array($data) || $data instanceof \Traversable) {
{
if ($this->_d !== array()) { if ($this->_d !== array()) {
$this->clear(); $this->clear();
} }
...@@ -192,7 +194,8 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co ...@@ -192,7 +194,8 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
foreach ($data as $key => $value) { foreach ($data as $key => $value) {
$this->add($key, $value); $this->add($key, $value);
} }
} else { }
else {
throw new Exception('Data must be either an array or an object implementing Traversable.'); 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 ...@@ -214,7 +217,7 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
* *
* @throws CException If data is neither an array nor an iterator. * @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 (is_array($data) || $data instanceof \Traversable) {
if ($data instanceof self) { if ($data instanceof self) {
...@@ -222,20 +225,23 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co ...@@ -222,20 +225,23 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
} }
if ($recursive) { if ($recursive) {
if ($data instanceof \Traversable) { if ($data instanceof \Traversable) {
$d=array(); $d = array();
foreach($data as $key => $value) { foreach ($data as $key => $value) {
$d[$key] = $value; $d[$key] = $value;
} }
$this->_d = self::mergeArray($this->_d, $d); $this->_d = self::mergeArray($this->_d, $d);
} else { }
else {
$this->_d = self::mergeArray($this->_d, $data); $this->_d = self::mergeArray($this->_d, $data);
} }
} else { }
foreach($data as $key => $value) { else {
foreach ($data as $key => $value) {
$this->add($key, $value); $this->add($key, $value);
} }
} }
} else { }
else {
throw new Exception('Dictionary data must be an array or an object implementing Traversable.'); 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 ...@@ -278,7 +284,7 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
*/ */
public function offsetSet($offset, $item) 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 ...@@ -308,12 +314,14 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co
*/ */
public static function mergeArray($a, $b) public static function mergeArray($a, $b)
{ {
foreach($b as $k=>$v) { foreach ($b as $k => $v) {
if(is_integer($k)) { if (is_integer($k)) {
isset($a[$k]) ? $a[] = $v : $a[$k] = $v; 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); $a[$k] = self::mergeArray($a[$k], $v);
} else { }
else {
$a[$k] = $v; $a[$k] = $v;
} }
} }
......
...@@ -51,7 +51,7 @@ class Event extends Object ...@@ -51,7 +51,7 @@ class Event extends Object
* @param mixed $sender sender of the event * @param mixed $sender sender of the event
* @param mixed $params parameters 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->sender = $sender;
$this->params = $params; $this->params = $params;
......
...@@ -13,7 +13,7 @@ namespace yii\base; ...@@ -13,7 +13,7 @@ namespace yii\base;
* Initable is an interface indicating a class needs initialization to work properly. * Initable is an interface indicating a class needs initialization to work properly.
* *
* Initable requires a class to implement the [[init]] method. * 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 * Initable, it will call the [[init]] method after setting the initial values of the
* component properties. * component properties.
* *
...@@ -24,7 +24,7 @@ interface Initable ...@@ -24,7 +24,7 @@ interface Initable
{ {
/** /**
* Initializes this component. * 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, * component instance and initializes the component properties. In other words,
* at this stage, the component has been fully configured. * at this stage, the component has been fully configured.
*/ */
......
...@@ -43,7 +43,7 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc ...@@ -43,7 +43,7 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
* Constructor. * Constructor.
* @param string $scenario name of the [[scenario]] that this model is used in. * @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->_scenario = $scenario;
$this->afterConstruct(); $this->afterConstruct();
...@@ -52,7 +52,7 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc ...@@ -52,7 +52,7 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
/** /**
* Initializes this model. * 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. * after it creates the new model instance and initializes the model properties.
* *
* The default implementation calls [[behaviors]] and registers any available behaviors. * The default implementation calls [[behaviors]] and registers any available behaviors.
...@@ -367,7 +367,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc ...@@ -367,7 +367,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
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)); $validator = \yii\validators\Validator::createValidator($rule[1], $this, $rule[0], array_slice($rule, 2));
$validators->add($validator); $validators->add($validator);
} else { }
else {
throw new Exception('Invalid validation rule: a rule must specify both attribute names and validator type.'); throw new Exception('Invalid validation rule: a rule must specify both attribute names and validator type.');
} }
} }
...@@ -455,7 +456,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc ...@@ -455,7 +456,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
{ {
if ($attribute === null) { if ($attribute === null) {
return $this->_errors === null ? array() : $this->_errors; return $this->_errors === null ? array() : $this->_errors;
} else { }
else {
return isset($this->_errors[$attribute]) ? $this->_errors[$attribute] : array(); return isset($this->_errors[$attribute]) ? $this->_errors[$attribute] : array();
} }
} }
...@@ -494,7 +496,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc ...@@ -494,7 +496,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
foreach ($error as $e) { foreach ($error as $e) {
$this->_errors[$attribute][] = $e; $this->_errors[$attribute][] = $e;
} }
} else { }
else {
$this->_errors[$attribute][] = $error; $this->_errors[$attribute][] = $error;
} }
} }
...@@ -508,7 +511,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc ...@@ -508,7 +511,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
{ {
if ($attribute === null) { if ($attribute === null) {
$this->_errors = array(); $this->_errors = array();
} else { }
else {
unset($this->_errors[$attribute]); unset($this->_errors[$attribute]);
} }
} }
...@@ -543,7 +547,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc ...@@ -543,7 +547,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
$values[$name] = $this->$name; $values[$name] = $this->$name;
} }
} }
} else { }
else {
foreach ($this->attributeNames() as $name) { foreach ($this->attributeNames() as $name) {
$values[$name] = $this->$name; $values[$name] = $this->$name;
} }
...@@ -567,7 +572,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc ...@@ -567,7 +572,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
foreach ($values as $name => $value) { foreach ($values as $name => $value) {
if (isset($attributes[$name])) { if (isset($attributes[$name])) {
$this->$name = $value; $this->$name = $value;
} elseif ($safeOnly) { }
elseif ($safeOnly) {
$this->onUnsafeAttribute($name, $value); $this->onUnsafeAttribute($name, $value);
} }
} }
...@@ -633,7 +639,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc ...@@ -633,7 +639,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
foreach ($validator->attributes as $name) { foreach ($validator->attributes as $name) {
$unsafe[] = $name; $unsafe[] = $name;
} }
} else { }
else {
foreach ($validator->attributes as $name) { foreach ($validator->attributes as $name) {
$attributes[$name] = true; $attributes[$name] = true;
} }
......
...@@ -59,10 +59,10 @@ abstract class Module extends Component ...@@ -59,10 +59,10 @@ abstract class Module extends Component
$this->_parentModule = $parent; $this->_parentModule = $parent;
// set basePath at early as possible to avoid trouble // set basePath at early as possible to avoid trouble
if (is_string($config)) if (is_string($config)) {
$config = require($config); $config = require($config);
if (isset($config['basePath'])) }
{ if (isset($config['basePath'])) {
$this->setBasePath($config['basePath']); $this->setBasePath($config['basePath']);
unset($config['basePath']); unset($config['basePath']);
} }
...@@ -139,7 +139,7 @@ abstract class Module extends Component ...@@ -139,7 +139,7 @@ abstract class Module extends Component
*/ */
public function setId($id) public function setId($id)
{ {
$this->_id=$id; $this->_id = $id;
} }
/** /**
...@@ -246,23 +246,22 @@ abstract class Module extends Component ...@@ -246,23 +246,22 @@ abstract class Module extends Component
*/ */
public function getModule($id) 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]; return $this->_modules[$id];
}
elseif (isset($this->_moduleConfig[$id])) elseif (isset($this->_moduleConfig[$id]))
{ {
$config = $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'); \Yii::trace("Loading \"$id\" module", 'system.base.CModule');
$class = $config['class']; $class = $config['class'];
unset($config['class'], $config['enabled']); unset($config['class'], $config['enabled']);
if ($this === \Yii::$app) if ($this === \Yii::$app) {
{ $module = \Yii::createObject($class, $id, null, $config);
$module = Yii::create($class, $id, null, $config);
} }
else else
{ {
$module = Yii::create($class, $this->getId() . '/' . $id, $this, $config); $module = \Yii::createObject($class, $this->getId() . '/' . $id, $this, $config);
} }
return $this->_modules[$id] = $module; return $this->_modules[$id] = $module;
} }
...@@ -318,23 +317,24 @@ abstract class Module extends Component ...@@ -318,23 +317,24 @@ abstract class Module extends Component
{ {
foreach ($modules as $id => $module) foreach ($modules as $id => $module)
{ {
if (is_int($id)) if (is_int($id)) {
{
$id = $module; $id = $module;
$module = array(); $module = array();
} }
if (!isset($module['class'])) if (!isset($module['class'])) {
{
Yii::setPathOfAlias($id, $this->getModulePath() . DIRECTORY_SEPARATOR . $id); Yii::setPathOfAlias($id, $this->getModulePath() . DIRECTORY_SEPARATOR . $id);
$module['class'] = $id . '.' . ucfirst($id) . 'Module'; $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); $this->_moduleConfig[$id] = CMap::mergeArray($this->_moduleConfig[$id], $module);
}
else else
{
$this->_moduleConfig[$id] = $module; $this->_moduleConfig[$id] = $module;
} }
} }
}
/** /**
* Checks whether the named component exists. * Checks whether the named component exists.
...@@ -356,16 +356,16 @@ abstract class Module extends Component ...@@ -356,16 +356,16 @@ abstract class Module extends Component
*/ */
public function getComponent($id, $createIfNull = true) public function getComponent($id, $createIfNull = true)
{ {
if (isset($this->_components[$id])) if (isset($this->_components[$id])) {
return $this->_components[$id]; return $this->_components[$id];
}
elseif (isset($this->_componentConfig[$id]) && $createIfNull) elseif (isset($this->_componentConfig[$id]) && $createIfNull)
{ {
$config = $this->_componentConfig[$id]; $config = $this->_componentConfig[$id];
if (!isset($config['enabled']) || $config['enabled']) 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']); unset($config['enabled']);
$component = \Yii::create($config); $component = \Yii::createObject($config);
return $this->_components[$id] = $component; return $this->_components[$id] = $component;
} }
} }
...@@ -381,15 +381,16 @@ abstract class Module extends Component ...@@ -381,15 +381,16 @@ abstract class Module extends Component
*/ */
public function setComponent($id, $component) public function setComponent($id, $component)
{ {
if ($component === null) if ($component === null) {
unset($this->_components[$id]); unset($this->_components[$id]);
else }
{ else {
$this->_components[$id] = $component; $this->_components[$id] = $component;
if (!$component->getIsInitialized()) if (!$component->getIsInitialized()) {
$component->init(); $component->init();
} }
} }
}
/** /**
* Returns the application components. * Returns the application components.
...@@ -401,11 +402,13 @@ abstract class Module extends Component ...@@ -401,11 +402,13 @@ abstract class Module extends Component
*/ */
public function getComponents($loadedOnly = true) public function getComponents($loadedOnly = true)
{ {
if ($loadedOnly) if ($loadedOnly) {
return $this->_components; return $this->_components;
else }
else {
return array_merge($this->_componentConfig, $this->_components); return array_merge($this->_componentConfig, $this->_components);
} }
}
/** /**
* Sets the application components. * Sets the application components.
...@@ -442,14 +445,19 @@ abstract class Module extends Component ...@@ -442,14 +445,19 @@ abstract class Module extends Component
{ {
foreach ($components as $id => $component) foreach ($components as $id => $component)
{ {
if ($component instanceof IApplicationComponent) if ($component instanceof IApplicationComponent) {
$this->setComponent($id, $component); $this->setComponent($id, $component);
}
elseif (isset($this->_componentConfig[$id]) && $merge) elseif (isset($this->_componentConfig[$id]) && $merge)
{
$this->_componentConfig[$id] = CMap::mergeArray($this->_componentConfig[$id], $component); $this->_componentConfig[$id] = CMap::mergeArray($this->_componentConfig[$id], $component);
}
else else
{
$this->_componentConfig[$id] = $component; $this->_componentConfig[$id] = $component;
} }
} }
}
/** /**
* Configures the module with the specified configuration. * Configures the module with the specified configuration.
...@@ -457,12 +465,13 @@ abstract class Module extends Component ...@@ -457,12 +465,13 @@ abstract class Module extends Component
*/ */
public function configure($config) public function configure($config)
{ {
if (is_array($config)) if (is_array($config)) {
{
foreach ($config as $key => $value) foreach ($config as $key => $value)
{
$this->$key = $value; $this->$key = $value;
} }
} }
}
/** /**
* Loads static application components. * Loads static application components.
...@@ -470,8 +479,10 @@ abstract class Module extends Component ...@@ -470,8 +479,10 @@ abstract class Module extends Component
public function preloadComponents() public function preloadComponents()
{ {
foreach ($this->preload as $id) foreach ($this->preload as $id)
{
$this->getComponent($id); $this->getComponent($id);
} }
}
/** /**
* Preinitializes the module. * Preinitializes the module.
......
...@@ -85,7 +85,8 @@ class Object ...@@ -85,7 +85,8 @@ class Object
$getter = 'get' . $name; $getter = 'get' . $name;
if (method_exists($this, $getter)) { if (method_exists($this, $getter)) {
return $this->$getter(); return $this->$getter();
} else { }
else {
throw new Exception('Getting unknown property: ' . get_class($this) . '.' . $name); throw new Exception('Getting unknown property: ' . get_class($this) . '.' . $name);
} }
} }
...@@ -105,9 +106,11 @@ class Object ...@@ -105,9 +106,11 @@ class Object
$setter = 'set' . $name; $setter = 'set' . $name;
if (method_exists($this, $setter)) { if (method_exists($this, $setter)) {
$this->$setter($value); $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); throw new Exception('Setting read-only property: ' . get_class($this) . '.' . $name);
} else { }
else {
throw new Exception('Setting unknown property: ' . get_class($this) . '.' . $name); throw new Exception('Setting unknown property: ' . get_class($this) . '.' . $name);
} }
} }
...@@ -127,7 +130,8 @@ class Object ...@@ -127,7 +130,8 @@ class Object
$getter = 'get' . $name; $getter = 'get' . $name;
if (method_exists($this, $getter)) { // property is not null if (method_exists($this, $getter)) { // property is not null
return $this->$getter() !== null; return $this->$getter() !== null;
} else { }
else {
return false; return false;
} }
} }
...@@ -148,7 +152,8 @@ class Object ...@@ -148,7 +152,8 @@ class Object
$setter = 'set' . $name; $setter = 'set' . $name;
if (method_exists($this, $setter)) { // write property if (method_exists($this, $setter)) { // write property
$this->$setter(null); $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); throw new Exception('Unsetting read-only property: ' . get_class($this) . '.' . $name);
} }
} }
...@@ -244,74 +249,107 @@ class Object ...@@ -244,74 +249,107 @@ class Object
* @param array $_data_ additional parameters to be passed to the above expression/callback. * @param array $_data_ additional parameters to be passed to the above expression/callback.
* @return mixed the expression result * @return mixed the expression result
*/ */
public function evaluateExpression($_expression_, $_data_=array()) public function evaluateExpression($_expression_, $_data_ = array())
{ {
if (is_string($_expression_)) { if (is_string($_expression_)) {
extract($_data_); extract($_data_);
return eval('return ' . $_expression_ . ';'); return eval('return ' . $_expression_ . ';');
} else { }
else {
$_data_[] = $this; $_data_[] = $this;
return call_user_func_array($_expression_, $_data_); return call_user_func_array($_expression_, $_data_);
} }
} }
/** /**
* Creates a new object instance. * Creates a new instance of the calling class.
*
* 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]].
* *
* Parameters passed to this method will be used as the parameters to the object * Parameters passed to this method will be used as the parameters to the object
* constructor. * constructor.
* *
* Additionally, one can pass in an associative array as the last parameter to * This method does the following steps to create a object:
* this method. This method will treat the array as name-value pairs that initialize *
* the corresponding object properties. For example, * - 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 $c;
* public function __construct($a, $b) * 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: * // which is equivalent to the following lines:
* $model = new Foo(1, 2); * $model = new Foo(1, 2);
* $model->c = 3; * $model->c = 3;
* $model->init();
* ~~~ * ~~~
* *
* @return object the created object * @return object the created object
* @throws Exception if the configuration is invalid. * @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) { if (($n = func_num_args()) > 0) {
$args = func_get_args(); $args = func_get_args();
if (is_array($args[$n-1])) { if (is_array($args[$n - 1])) {
// the last parameter could be configuration array
$method = new \ReflectionMethod($class, '__construct'); $method = new \ReflectionMethod($class, '__construct');
if ($method->getNumberOfParameters()+1 == $n) { if ($method->getNumberOfParameters() < $n) {
$config = $args[$n-1]; // the last EXTRA parameter is a configuration array
array_pop($args); $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;
} }
} }
...@@ -103,9 +103,11 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta ...@@ -103,9 +103,11 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
{ {
if (isset($this->_d[$index])) { if (isset($this->_d[$index])) {
return $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]; return $this->_d[$index];
} else { }
else {
throw new Exception('Index out of range: ' . $index); throw new Exception('Index out of range: ' . $index);
} }
} }
...@@ -119,7 +121,7 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta ...@@ -119,7 +121,7 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
public function add($item) public function add($item)
{ {
$this->insertAt($this->_c, $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 ...@@ -134,10 +136,12 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
{ {
if ($index === $this->_c) { if ($index === $this->_c) {
$this->_d[$this->_c++] = $item; $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)); array_splice($this->_d, $index, 0, array($item));
$this->_c++; $this->_c++;
} else { }
else {
throw new Exception('Index out of range: ' . $index); throw new Exception('Index out of range: ' . $index);
} }
} }
...@@ -156,7 +160,8 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta ...@@ -156,7 +160,8 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
if (($index = $this->indexOf($item)) >= 0) { if (($index = $this->indexOf($item)) >= 0) {
$this->removeAt($index); $this->removeAt($index);
return $index; return $index;
} else { }
else {
return false; return false;
} }
} }
...@@ -173,12 +178,14 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta ...@@ -173,12 +178,14 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
$this->_c--; $this->_c--;
if ($index === $this->_c) { if ($index === $this->_c) {
return array_pop($this->_d); return array_pop($this->_d);
} else { }
else {
$item = $this->_d[$index]; $item = $this->_d[$index];
array_splice($this->_d, $index, 1); array_splice($this->_d, $index, 1);
return $item; return $item;
} }
} else { }
else {
throw new Exception('Index out of range: ' . $index); throw new Exception('Index out of range: ' . $index);
} }
} }
...@@ -192,10 +199,11 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta ...@@ -192,10 +199,11 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
public function clear($safeClear = false) public function clear($safeClear = false)
{ {
if ($safeClear) { if ($safeClear) {
for ($i = $this->_c-1;$i >= 0;--$i) { for ($i = $this->_c - 1; $i >= 0; --$i) {
$this->removeAt($i); $this->removeAt($i);
} }
} else { }
else {
$this->_d = array(); $this->_d = array();
$this->_c = 0; $this->_c = 0;
} }
...@@ -252,7 +260,8 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta ...@@ -252,7 +260,8 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
foreach ($data as $item) { foreach ($data as $item) {
$this->add($item); $this->add($item);
} }
} else { }
else {
throw new Exception('Data must be either an array or an object implementing Traversable.'); 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 ...@@ -272,7 +281,8 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
foreach ($data as $item) { foreach ($data as $item) {
$this->add($item); $this->add($item);
} }
} else { }
else {
throw new Exception('Data must be either an array or an object implementing Traversable.'); 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 ...@@ -318,7 +328,8 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta
{ {
if ($offset === null || $offset === $this->_c) { if ($offset === null || $offset === $this->_c) {
$this->insertAt($this->_c, $item); $this->insertAt($this->_c, $item);
} else { }
else {
$this->removeAt($offset); $this->removeAt($offset);
$this->insertAt($offset, $item); $this->insertAt($offset, $item);
} }
......
...@@ -114,9 +114,12 @@ class ColumnSchema extends \yii\base\Component ...@@ -114,9 +114,12 @@ class ColumnSchema extends \yii\base\Component
return $value; return $value;
} }
switch ($this->phpType) { switch ($this->phpType) {
case 'string': return (string)$value; case 'string':
case 'integer': return (integer)$value; return (string)$value;
case 'boolean': return (boolean)$value; case 'integer':
return (integer)$value;
case 'boolean':
return (boolean)$value;
} }
return $value; return $value;
} }
......
...@@ -26,7 +26,7 @@ use yii\db\Exception; ...@@ -26,7 +26,7 @@ use yii\db\Exception;
* the DB connection: * 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(); * $connection->active = true; // same as: $connection->open();
* ~~~ * ~~~
* *
...@@ -219,7 +219,7 @@ class Connection extends \yii\base\ApplicationComponent ...@@ -219,7 +219,7 @@ class Connection extends \yii\base\ApplicationComponent
/** /**
* @var array mapping between PDO driver names and [[Schema]] classes. * @var array mapping between PDO driver names and [[Schema]] classes.
* The keys of the array are PDO driver names while the values the corresponding * 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. * details on how to specify a configuration.
* *
* This property is mainly used by [[getSchema]] when fetching the database schema information. * This property is mainly used by [[getSchema]] when fetching the database schema information.
...@@ -428,7 +428,8 @@ class Connection extends \yii\base\ApplicationComponent ...@@ -428,7 +428,8 @@ class Connection extends \yii\base\ApplicationComponent
{ {
if ($this->_transaction !== null && $this->_transaction->active) { if ($this->_transaction !== null && $this->_transaction->active) {
return $this->_transaction; return $this->_transaction;
} else { }
else {
return null; return null;
} }
} }
...@@ -453,11 +454,13 @@ class Connection extends \yii\base\ApplicationComponent ...@@ -453,11 +454,13 @@ class Connection extends \yii\base\ApplicationComponent
{ {
if ($this->_schema !== null) { if ($this->_schema !== null) {
return $this->_schema; return $this->_schema;
} else { }
else {
$driver = $this->getDriverName(); $driver = $this->getDriverName();
if (isset($this->schemaMap[$driver])) { if (isset($this->schemaMap[$driver])) {
return $this->_schema = \Yii::create($this->schemaMap[$driver], $this); return $this->_schema = \Yii::createObject($this->schemaMap[$driver], $this);
} else { }
else {
throw new Exception("Connection does not support reading schema for '$driver' database."); throw new Exception("Connection does not support reading schema for '$driver' database.");
} }
} }
...@@ -500,7 +503,8 @@ class Connection extends \yii\base\ApplicationComponent ...@@ -500,7 +503,8 @@ class Connection extends \yii\base\ApplicationComponent
$this->open(); $this->open();
if (($value = $this->pdo->quote($str)) !== false) { if (($value = $this->pdo->quote($str)) !== false) {
return $value; 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") . "'"; return "'" . addcslashes(str_replace("'", "''", $str), "\000\n\r\\\032") . "'";
} }
} }
...@@ -542,7 +546,8 @@ class Connection extends \yii\base\ApplicationComponent ...@@ -542,7 +546,8 @@ class Connection extends \yii\base\ApplicationComponent
{ {
if ($this->tablePrefix !== null && strpos($sql, '{{') !== false) { if ($this->tablePrefix !== null && strpos($sql, '{{') !== false) {
return preg_replace('/{{(.*?)}}/', $this->tablePrefix . '\1', $sql); return preg_replace('/{{(.*?)}}/', $this->tablePrefix . '\1', $sql);
} else { }
else {
return $sql; return $sql;
} }
} }
...@@ -572,7 +577,8 @@ class Connection extends \yii\base\ApplicationComponent ...@@ -572,7 +577,8 @@ class Connection extends \yii\base\ApplicationComponent
{ {
if (($pos = strpos($this->dsn, ':')) !== false) { if (($pos = strpos($this->dsn, ':')) !== false) {
return strtolower(substr($this->dsn, 0, $pos)); return strtolower(substr($this->dsn, 0, $pos));
} else { }
else {
return strtolower($this->getAttribute(\PDO::ATTR_DRIVER_NAME)); return strtolower($this->getAttribute(\PDO::ATTR_DRIVER_NAME));
} }
} }
......
...@@ -102,10 +102,10 @@ class Query extends \yii\base\Object ...@@ -102,10 +102,10 @@ class Query extends \yii\base\Object
} }
if ($this->select !== $query->select) { if ($this->select !== $query->select) {
if($this->select === '*') { if ($this->select === '*') {
$this->select = $query->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; $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; $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)); $this->select = array_merge($select1, array_diff($select2, $select1));
...@@ -238,16 +238,19 @@ class Query extends \yii\base\Object ...@@ -238,16 +238,19 @@ class Query extends \yii\base\Object
*/ */
public function addCondition($condition, $operator = 'AND') public function addCondition($condition, $operator = 'AND')
{ {
if (is_array($condition)) if (is_array($condition)) {
{ if ($condition === array()) {
if ($condition === array())
return $this; return $this;
}
$condition = '(' . implode(') ' . $operator . ' (', $condition) . ')'; $condition = '(' . implode(') ' . $operator . ' (', $condition) . ')';
} }
if ($this->condition === '') if ($this->condition === '') {
$this->condition = $condition; $this->condition = $condition;
}
else else
{
$this->condition = '(' . $this->condition . ') ' . $operator . ' (' . $condition . ')'; $this->condition = '(' . $this->condition . ') ' . $operator . ' (' . $condition . ')';
}
return $this; return $this;
} }
...@@ -271,10 +274,12 @@ class Query extends \yii\base\Object ...@@ -271,10 +274,12 @@ class Query extends \yii\base\Object
*/ */
public function addSearchCondition($column, $keyword, $escape = true, $operator = 'AND', $like = 'LIKE') public function addSearchCondition($column, $keyword, $escape = true, $operator = 'AND', $like = 'LIKE')
{ {
if ($keyword == '') if ($keyword == '') {
return $this; return $this;
if ($escape) }
if ($escape) {
$keyword = '%' . strtr($keyword, array('%' => '\%', '_' => '\_', '\\' => '\\\\')) . '%'; $keyword = '%' . strtr($keyword, array('%' => '\%', '_' => '\_', '\\' => '\\\\')) . '%';
}
$condition = $column . " $like " . self::PARAM_PREFIX . self::$paramCount; $condition = $column . " $like " . self::PARAM_PREFIX . self::$paramCount;
$this->params[self::PARAM_PREFIX . self::$paramCount++] = $keyword; $this->params[self::PARAM_PREFIX . self::$paramCount++] = $keyword;
return $this->addCondition($condition, $operator); return $this->addCondition($condition, $operator);
...@@ -294,13 +299,14 @@ class Query extends \yii\base\Object ...@@ -294,13 +299,14 @@ class Query extends \yii\base\Object
*/ */
public function addInCondition($column, $values, $operator = 'AND') public function addInCondition($column, $values, $operator = 'AND')
{ {
if (($n = count($values)) < 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 return $this->addCondition('0=1', $operator);
if ($n === 1) } // 0=1 is used because in MSSQL value alone can't be used in WHERE
{ if ($n === 1) {
$value = reset($values); $value = reset($values);
if ($value === null) if ($value === null) {
return $this->addCondition($column . ' IS NULL'); return $this->addCondition($column . ' IS NULL');
}
$condition = $column . '=' . self::PARAM_PREFIX . self::$paramCount; $condition = $column . '=' . self::PARAM_PREFIX . self::$paramCount;
$this->params[self::PARAM_PREFIX . self::$paramCount++] = $value; $this->params[self::PARAM_PREFIX . self::$paramCount++] = $value;
} }
...@@ -331,13 +337,14 @@ class Query extends \yii\base\Object ...@@ -331,13 +337,14 @@ class Query extends \yii\base\Object
*/ */
public function addNotInCondition($column, $values, $operator = 'AND') public function addNotInCondition($column, $values, $operator = 'AND')
{ {
if (($n = count($values)) < 1) if (($n = count($values)) < 1) {
return $this; return $this;
if ($n === 1) }
{ if ($n === 1) {
$value = reset($values); $value = reset($values);
if ($value === null) if ($value === null) {
return $this->addCondition($column . ' IS NOT NULL'); return $this->addCondition($column . ' IS NOT NULL');
}
$condition = $column . '!=' . self::PARAM_PREFIX . self::$paramCount; $condition = $column . '!=' . self::PARAM_PREFIX . self::$paramCount;
$this->params[self::PARAM_PREFIX . self::$paramCount++] = $value; $this->params[self::PARAM_PREFIX . self::$paramCount++] = $value;
} }
...@@ -370,8 +377,9 @@ class Query extends \yii\base\Object ...@@ -370,8 +377,9 @@ class Query extends \yii\base\Object
$params = array(); $params = array();
foreach ($columns as $name => $value) foreach ($columns as $name => $value)
{ {
if ($value === null) if ($value === null) {
$params[] = $name . ' IS NULL'; $params[] = $name . ' IS NULL';
}
else else
{ {
$params[] = $name . '=' . self::PARAM_PREFIX . self::$paramCount; $params[] = $name . '=' . self::PARAM_PREFIX . self::$paramCount;
...@@ -426,35 +434,42 @@ class Query extends \yii\base\Object ...@@ -426,35 +434,42 @@ class Query extends \yii\base\Object
*/ */
public function compare($column, $value, $partialMatch = false, $operator = 'AND', $escape = true) public function compare($column, $value, $partialMatch = false, $operator = 'AND', $escape = true)
{ {
if (is_array($value)) if (is_array($value)) {
{ if ($value === array()) {
if ($value === array())
return $this; return $this;
}
return $this->addInCondition($column, $value, $operator); return $this->addInCondition($column, $value, $operator);
} }
else else
{
$value = "$value"; $value = "$value";
}
if (preg_match('/^(?:\s*(<>|<=|>=|<|>|=))?(.*)$/', $value, $matches)) if (preg_match('/^(?:\s*(<>|<=|>=|<|>|=))?(.*)$/', $value, $matches)) {
{
$value = $matches[2]; $value = $matches[2];
$op = $matches[1]; $op = $matches[1];
} }
else else
{
$op = ''; $op = '';
}
if ($value === '') if ($value === '') {
return $this; return $this;
}
if ($partialMatch) if ($partialMatch) {
{ if ($op === '') {
if ($op === '')
return $this->addSearchCondition($column, $value, $escape, $operator); return $this->addSearchCondition($column, $value, $escape, $operator);
if ($op === '<>') }
if ($op === '<>') {
return $this->addSearchCondition($column, $value, $escape, $operator, 'NOT LIKE'); return $this->addSearchCondition($column, $value, $escape, $operator, 'NOT LIKE');
} }
}
elseif ($op === '') elseif ($op === '')
{
$op = '='; $op = '=';
}
$this->addCondition($column . $op . self::PARAM_PREFIX . self::$paramCount, $operator); $this->addCondition($column . $op . self::PARAM_PREFIX . self::$paramCount, $operator);
$this->params[self::PARAM_PREFIX . self::$paramCount++] = $value; $this->params[self::PARAM_PREFIX . self::$paramCount++] = $value;
...@@ -479,8 +494,9 @@ class Query extends \yii\base\Object ...@@ -479,8 +494,9 @@ class Query extends \yii\base\Object
*/ */
public function addBetweenCondition($column, $valueStart, $valueEnd, $operator = 'AND') public function addBetweenCondition($column, $valueStart, $valueEnd, $operator = 'AND')
{ {
if ($valueStart === '' || $valueEnd === '') if ($valueStart === '' || $valueEnd === '') {
return $this; return $this;
}
$paramStart = self::PARAM_PREFIX . self::$paramCount++; $paramStart = self::PARAM_PREFIX . self::$paramCount++;
$paramEnd = self::PARAM_PREFIX . self::$paramCount++; $paramEnd = self::PARAM_PREFIX . self::$paramCount++;
...@@ -488,10 +504,13 @@ class Query extends \yii\base\Object ...@@ -488,10 +504,13 @@ class Query extends \yii\base\Object
$this->params[$paramEnd] = $valueEnd; $this->params[$paramEnd] = $valueEnd;
$condition = "$column BETWEEN $paramStart AND $paramEnd"; $condition = "$column BETWEEN $paramStart AND $paramEnd";
if ($this->condition === '') if ($this->condition === '') {
$this->condition = $condition; $this->condition = $condition;
}
else else
{
$this->condition = '(' . $this->condition . ') ' . $operator . ' (' . $condition . ')'; $this->condition = '(' . $this->condition . ') ' . $operator . ' (' . $condition . ')';
}
return $this; return $this;
} }
......
...@@ -177,8 +177,10 @@ class QueryBuilder extends \yii\base\Object ...@@ -177,8 +177,10 @@ class QueryBuilder extends \yii\base\Object
$cols[] = "\t" . $this->schema->quoteColumnName($name) . ' ' . $this->schema->getColumnType($type); $cols[] = "\t" . $this->schema->quoteColumnName($name) . ' ' . $this->schema->getColumnType($type);
} }
else else
{
$cols[] = "\t" . $type; $cols[] = "\t" . $type;
} }
}
$sql = "CREATE TABLE " . $this->schema->quoteTableName($table) . " (\n" . implode(",\n", $cols) . "\n)"; $sql = "CREATE TABLE " . $this->schema->quoteTableName($table) . " (\n" . implode(",\n", $cols) . "\n)";
return $options === null ? $sql : $sql . ' ' . $options; return $options === null ? $sql : $sql . ' ' . $options;
} }
...@@ -288,20 +290,24 @@ class QueryBuilder extends \yii\base\Object ...@@ -288,20 +290,24 @@ class QueryBuilder extends \yii\base\Object
public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete = null, $update = null) public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete = null, $update = null)
{ {
$columns = preg_split('/\s*,\s*/', $columns, -1, PREG_SPLIT_NO_EMPTY); $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); $columns[$i] = $this->schema->quoteColumnName($col);
}
$refColumns = preg_split('/\s*,\s*/', $refColumns, -1, PREG_SPLIT_NO_EMPTY); $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); $refColumns[$i] = $this->schema->quoteColumnName($col);
}
$sql = 'ALTER TABLE ' . $this->schema->quoteTableName($table) $sql = 'ALTER TABLE ' . $this->schema->quoteTableName($table)
. ' ADD CONSTRAINT ' . $this->schema->quoteColumnName($name) . ' ADD CONSTRAINT ' . $this->schema->quoteColumnName($name)
. ' FOREIGN KEY (' . implode(', ', $columns) . ')' . ' FOREIGN KEY (' . implode(', ', $columns) . ')'
. ' REFERENCES ' . $this->schema->quoteTableName($refTable) . ' REFERENCES ' . $this->schema->quoteTableName($refTable)
. ' (' . implode(', ', $refColumns) . ')'; . ' (' . implode(', ', $refColumns) . ')';
if ($delete !== null) if ($delete !== null) {
$sql .= ' ON DELETE ' . $delete; $sql .= ' ON DELETE ' . $delete;
if ($update !== null) }
if ($update !== null) {
$sql .= ' ON UPDATE ' . $update; $sql .= ' ON UPDATE ' . $update;
}
return $sql; return $sql;
} }
...@@ -332,11 +338,14 @@ class QueryBuilder extends \yii\base\Object ...@@ -332,11 +338,14 @@ class QueryBuilder extends \yii\base\Object
$columns = preg_split('/\s*,\s*/', $column, -1, PREG_SPLIT_NO_EMPTY); $columns = preg_split('/\s*,\s*/', $column, -1, PREG_SPLIT_NO_EMPTY);
foreach ($columns as $col) foreach ($columns as $col)
{ {
if (strpos($col, '(') !== false) if (strpos($col, '(') !== false) {
$cols[] = $col; $cols[] = $col;
}
else else
{
$cols[] = $this->schema->quoteColumnName($col); $cols[] = $this->schema->quoteColumnName($col);
} }
}
return ($unique ? 'CREATE UNIQUE INDEX ' : 'CREATE INDEX ') return ($unique ? 'CREATE UNIQUE INDEX ' : 'CREATE INDEX ')
. $this->schema->quoteTableName($name) . ' ON ' . $this->schema->quoteTableName($name) . ' ON '
. $this->schema->quoteTableName($table) . ' (' . implode(', ', $cols) . ')'; . $this->schema->quoteTableName($table) . ' (' . implode(', ', $cols) . ')';
...@@ -488,9 +497,9 @@ class QueryBuilder extends \yii\base\Object ...@@ -488,9 +497,9 @@ class QueryBuilder extends \yii\base\Object
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])) { if (isset($join[0], $join[1])) {
$table = $join[1]; $table = $join[1];
if (strpos($table,'(')===false) { if (strpos($table, '(') === false) {
if (preg_match('/^(.*?)(?i:\s+as\s+|\s+)(.*)$/', $table, $matches)) { // with alias if (preg_match('/^(.*?)(?i:\s+as\s+|\s+)(.*)$/', $table, $matches)) { // with alias
$table = $this->connection->quoteTableName($matches[1]).' '.$this->connection->quoteTableName($matches[2]); $table = $this->connection->quoteTableName($matches[1]) . ' ' . $this->connection->quoteTableName($matches[2]);
} }
else { else {
$table = $this->connection->quoteTableName($table); $table = $this->connection->quoteTableName($table);
...@@ -582,8 +591,8 @@ class QueryBuilder extends \yii\base\Object ...@@ -582,8 +591,8 @@ class QueryBuilder extends \yii\base\Object
if ($query->limit !== null && $query->limit >= 0) { if ($query->limit !== null && $query->limit >= 0) {
$sql = 'LIMIT ' . (int)$query->limit; $sql = 'LIMIT ' . (int)$query->limit;
} }
if ($query->offset>0) { if ($query->offset > 0) {
$sql .= ' OFFSET '.(int)$query->offset; $sql .= ' OFFSET ' . (int)$query->offset;
} }
return ltrim($sql); return ltrim($sql);
} }
......
...@@ -20,6 +20,9 @@ use yii\db\Exception; ...@@ -20,6 +20,9 @@ use yii\db\Exception;
*/ */
abstract class Schema extends \yii\base\Object abstract class Schema extends \yii\base\Object
{ {
/**
* @var \yii\db\dao\Connection the database connection
*/
public $connection; public $connection;
private $_tableNames = array(); private $_tableNames = array();
...@@ -194,7 +197,9 @@ abstract class Schema extends \yii\base\Object ...@@ -194,7 +197,9 @@ abstract class Schema extends \yii\base\Object
$name = substr($name, $pos + 1); $name = substr($name, $pos + 1);
} }
else else
{
$prefix = ''; $prefix = '';
}
return $prefix . $this->quoteSimpleColumnName($name); return $prefix . $this->quoteSimpleColumnName($name);
} }
......
...@@ -69,7 +69,8 @@ class Transaction extends \yii\base\Object ...@@ -69,7 +69,8 @@ class Transaction extends \yii\base\Object
\Yii::trace('Committing transaction', __CLASS__); \Yii::trace('Committing transaction', __CLASS__);
$this->connection->pdo->commit(); $this->connection->pdo->commit();
$this->active = false; $this->active = false;
} else { }
else {
throw new Exception('Failed to commit transaction: transaction was inactive.'); throw new Exception('Failed to commit transaction: transaction was inactive.');
} }
} }
...@@ -84,7 +85,8 @@ class Transaction extends \yii\base\Object ...@@ -84,7 +85,8 @@ class Transaction extends \yii\base\Object
\Yii::trace('Rolling back transaction', __CLASS__); \Yii::trace('Rolling back transaction', __CLASS__);
$this->connection->pdo->rollBack(); $this->connection->pdo->rollBack();
$this->active = false; $this->active = false;
} else { }
else {
throw new Exception('Failed to roll back transaction: transaction was inactive.'); throw new Exception('Failed to roll back transaction: transaction was inactive.');
} }
} }
......
...@@ -22,12 +22,12 @@ namespace yii\logging; ...@@ -22,12 +22,12 @@ namespace yii\logging;
*/ */
class Logger extends \yii\base\Component class Logger extends \yii\base\Component
{ {
const LEVEL_ERROR = 1; const LEVEL_ERROR = 'error';
const LEVEL_WARNING = 2; const LEVEL_WARNING = 'warning';
const LEVEL_INFO = 3; const LEVEL_INFO = 'info';
const LEVEL_TRACE = 4; const LEVEL_TRACE = 'trace';
const LEVEL_PROFILE_BEGIN = 5; const LEVEL_PROFILE_BEGIN = 'profile-begin';
const LEVEL_PROFILE_END = 6; const LEVEL_PROFILE_END = 'profile-end';
/** /**
* @var integer how many messages should be logged before they are flushed from memory and sent to targets. * @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 ...@@ -253,13 +253,10 @@ class Logger extends \yii\base\Component
$stack = array(); $stack = array();
foreach ($this->messages as $log) { foreach ($this->messages as $log) {
if ($log[1] < self::LEVEL_PROFILE_BEGIN) { if ($log[1] === self::LEVEL_PROFILE_BEGIN) {
continue;
}
list($token, $level, $category, $timestamp) = $log;
if ($level === self::LEVEL_PROFILE_BEGIN) {
$stack[] = $log; $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) { if (($last = array_pop($stack)) !== null && $last[0] === $token) {
$timings[] = array($token, $category, $timestamp - $last[3]); $timings[] = array($token, $category, $timestamp - $last[3]);
} else { } else {
......
...@@ -101,7 +101,7 @@ class Router extends \yii\base\ApplicationComponent ...@@ -101,7 +101,7 @@ class Router extends \yii\base\ApplicationComponent
* Sets the log targets. * Sets the log targets.
* @param array $config list of log target configurations. Each array element * @param array $config list of log target configurations. Each array element
* represents the configuration for creating a single log target. It will be * 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) public function setTargets($config)
{ {
...@@ -110,7 +110,7 @@ class Router extends \yii\base\ApplicationComponent ...@@ -110,7 +110,7 @@ class Router extends \yii\base\ApplicationComponent
$this->_targets[$name] = $target; $this->_targets[$name] = $target;
} }
else { else {
$this->_targets[$name] = \Yii::create($target); $this->_targets[$name] = \Yii::createObject($target);
} }
} }
} }
......
...@@ -166,7 +166,7 @@ abstract class Validator extends \yii\base\Component ...@@ -166,7 +166,7 @@ abstract class Validator extends \yii\base\Component
foreach ($params as $name => $value) { foreach ($params as $name => $value) {
$config[$name] = $value; $config[$name] = $value;
} }
$validator = \Yii::create($config); $validator = \Yii::createObject($config);
return $validator; return $validator;
} }
......
...@@ -21,7 +21,7 @@ class BehaviorTest extends \yiiunit\TestCase ...@@ -21,7 +21,7 @@ class BehaviorTest extends \yiiunit\TestCase
{ {
public function testAttachAndAccessing() public function testAttachAndAccessing()
{ {
$bar = BarClass::create(); $bar = BarClass::newInstance();
$behavior = new BarBehavior(); $behavior = new BarBehavior();
$bar->attachBehavior('bar', $behavior); $bar->attachBehavior('bar', $behavior);
$this->assertEquals('behavior property', $bar->behaviorProperty); $this->assertEquals('behavior property', $bar->behaviorProperty);
......
...@@ -206,7 +206,7 @@ class ComponentTest extends \yiiunit\TestCase ...@@ -206,7 +206,7 @@ class ComponentTest extends \yiiunit\TestCase
public function testCreate() 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(1, $component->b);
$this->assertEquals(2, $component->c); $this->assertEquals(2, $component->c);
$this->assertEquals(3, $component->a); $this->assertEquals(3, $component->a);
......
...@@ -7,6 +7,23 @@ class Foo extends \yii\base\Object ...@@ -7,6 +7,23 @@ class Foo extends \yii\base\Object
public $prop; 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 * ObjectTest
*/ */
...@@ -24,15 +41,28 @@ class ObjectTest extends \yiiunit\TestCase ...@@ -24,15 +41,28 @@ class ObjectTest extends \yiiunit\TestCase
$this->object = null; $this->object = null;
} }
public function testCreate() public function testNewInstance()
{ {
$foo = Foo::create(array( $foo = Foo::newInstance(array(
'prop' => array( 'prop' => array(
'test' => 'test', 'test' => 'test',
), ),
)); ));
$this->assertEquals('test', $foo->prop['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() 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