Commit b947d688 by Qiang Xue

...

parent 03ea25b1
...@@ -108,7 +108,7 @@ class Component extends Object ...@@ -108,7 +108,7 @@ class Component extends Object
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 (property_exists($object, $name) || $object->canGetProperty($name)) { if ($object->canGetProperty($name)) {
return $object->$name; return $object->$name;
} }
} }
...@@ -145,7 +145,7 @@ class Component extends Object ...@@ -145,7 +145,7 @@ class Component extends Object
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 (property_exists($object, $name) || $object->canSetProperty($name)) { if ($object->canSetProperty($name)) {
return $object->$name = $value; return $object->$name = $value;
} }
} }
...@@ -182,7 +182,7 @@ class Component extends Object ...@@ -182,7 +182,7 @@ class Component extends Object
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 (property_exists($object, $name) || $object->canGetProperty($name)) { if ($object->canGetProperty($name)) {
return $object->$name !== null; return $object->$name !== null;
} }
} }
...@@ -201,27 +201,25 @@ class Component extends Object ...@@ -201,27 +201,25 @@ class Component extends Object
* Do not call this method directly as it is a PHP magic method that * Do not call this method directly as it is a PHP magic method that
* will be implicitly called when executing `unset($component->property)`. * will be implicitly called when executing `unset($component->property)`.
* @param string $name the property name * @param string $name the property name
* @return null
* @throws Exception if the property is read only. * @throws Exception if the property is read only.
*/ */
public function __unset($name) public function __unset($name)
{ {
$setter = 'set' . $name; $setter = 'set' . $name;
if (method_exists($this, $setter)) { // write property if (method_exists($this, $setter)) { // write property
$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)]); return unset($this->_e[strtolower($name)]);
} elseif (isset($this->_b[$name])) { // behavior } elseif (isset($this->_b[$name])) { // behavior
$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 (property_exists($object, $name)) { if ($object->canSetProperty($name)) {
return $object->$name = null; return $object->$name = null;
} elseif ($object->canSetProperty($name)) {
return $object->$setter(null);
} }
} }
} elseif (method_exists($this, 'get' . $name)) { }
if (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);
} }
} }
...@@ -236,24 +234,22 @@ class Component extends Object ...@@ -236,24 +234,22 @@ class Component extends Object
* Do not call this method directly as it is a PHP magic method that * Do not call this method directly as it is a PHP magic method that
* will be implicitly called when an unknown method is being invoked. * will be implicitly called when an unknown method is being invoked.
* @param string $name the method name * @param string $name the method name
* @param array $parameters method parameters * @param array $params method parameters
* @return mixed the method return value * @return mixed the method return value
*/ */
public function __call($name, $parameters) public function __call($name, $params)
{ {
if ($this->canGetProperty($name)) { if ($this->canGetProperty($name, false)) {
$func = $this->$name; $func = $this->$name;
if ($func instanceof \Closure) { if ($func instanceof \Closure) {
return call_user_func_array($func, $parameters); return call_user_func_array($func, $params);
} }
} }
if ($this->_b !== null) if ($this->_b !== null) {
{ foreach ($this->_b as $object) {
foreach ($this->_b as $object)
{
if (method_exists($object, $name)) { if (method_exists($object, $name)) {
return call_user_func_array(array($object, $name), $parameters); return call_user_func_array(array($object, $name), $params);
} }
} }
} }
......
...@@ -63,6 +63,13 @@ namespace yii\base; ...@@ -63,6 +63,13 @@ namespace yii\base;
class Object class Object
{ {
/** /**
* Constructor.
*/
public function __construct()
{
}
/**
* Returns the value of a object property. * Returns the value of a object property.
* *
* Do not call this method directly as it is a PHP magic method that * Do not call this method directly as it is a PHP magic method that
...@@ -78,9 +85,10 @@ class Object ...@@ -78,9 +85,10 @@ 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 {
throw new Exception('Getting unknown property: ' . get_class($this) . '.' . $name); throw new Exception('Getting unknown property: ' . get_class($this) . '.' . $name);
} }
}
/** /**
* Sets value of a object property. * Sets value of a object property.
...@@ -89,7 +97,6 @@ class Object ...@@ -89,7 +97,6 @@ class Object
* will be implicitly called when executing `$object->property = $value;`. * will be implicitly called when executing `$object->property = $value;`.
* @param string $name the property name or the event name * @param string $name the property name or the event name
* @param mixed $value the property value * @param mixed $value the property value
* @return mixed value that was set
* @throws Exception if the property is not defined or read-only. * @throws Exception if the property is not defined or read-only.
* @see __get * @see __get
*/ */
...@@ -97,9 +104,8 @@ class Object ...@@ -97,9 +104,8 @@ class Object
{ {
$setter = 'set' . $name; $setter = 'set' . $name;
if (method_exists($this, $setter)) { if (method_exists($this, $setter)) {
return $this->$setter($value); $this->$setter($value);
} } elseif (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);
...@@ -121,9 +127,10 @@ class Object ...@@ -121,9 +127,10 @@ 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 {
return false; return false;
} }
}
/** /**
* Sets a object property to be null. * Sets a object property to be null.
...@@ -147,17 +154,42 @@ class Object ...@@ -147,17 +154,42 @@ class Object
} }
/** /**
* Calls the named method which is not a class method.
* If the name refers to a component property whose value is
* an anonymous function, the method will execute the function.
*
* Do not call this method directly as it is a PHP magic method that
* will be implicitly called when an unknown method is being invoked.
* @param string $name the method name
* @param array $params method parameters
* @return mixed the method return value
*/
public function __call($name, $params)
{
if ($this->canGetProperty($name, false)) {
$getter = 'get' . $name;
$func = $this->$getter;
if ($func instanceof \Closure) {
return call_user_func_array($func, $params);
}
}
throw new Exception('Unknown method: ' . get_class($this) . "::$name()");
}
/**
* Returns a value indicating whether a property is defined. * Returns a value indicating whether a property is defined.
* A property is defined if there is a getter or setter method * A property is defined if there is a getter or setter method
* defined in the class. Note that property names are case-insensitive. * defined in the class. Note that property names are case-insensitive.
* @param string $name the property name * @param string $name the property name
* @param boolean $checkVar whether to treat member variables as properties
* @return boolean whether the property is defined * @return boolean whether the property is defined
* @see canGetProperty * @see canGetProperty
* @see canSetProperty * @see canSetProperty
*/ */
public function hasProperty($name) public function hasProperty($name, $checkVar = true)
{ {
return $this->canGetProperty($name) || $this->canSetProperty($name); return $this->canGetProperty($name, false) || $this->canSetProperty($name, false)
|| $checkVar && property_exists($this, $name);
} }
/** /**
...@@ -165,12 +197,13 @@ class Object ...@@ -165,12 +197,13 @@ class Object
* A property can be read if the class has a getter method * A property can be read if the class has a getter method
* for the property name. Note that property name is case-insensitive. * for the property name. Note that property name is case-insensitive.
* @param string $name the property name * @param string $name the property name
* @param boolean $checkVar whether to treat member variables as properties
* @return boolean whether the property can be read * @return boolean whether the property can be read
* @see canSetProperty * @see canSetProperty
*/ */
public function canGetProperty($name) public function canGetProperty($name, $checkVar = true)
{ {
return method_exists($this, 'get' . $name); return method_exists($this, 'get' . $name) || $checkVar && property_exists($this, $name);
} }
/** /**
...@@ -178,12 +211,13 @@ class Object ...@@ -178,12 +211,13 @@ class Object
* A property can be written if the class has a setter method * A property can be written if the class has a setter method
* for the property name. Note that property name is case-insensitive. * for the property name. Note that property name is case-insensitive.
* @param string $name the property name * @param string $name the property name
* @param boolean $checkVar whether to treat member variables as properties
* @return boolean whether the property can be written * @return boolean whether the property can be written
* @see canGetProperty * @see canGetProperty
*/ */
public function canSetProperty($name) public function canSetProperty($name, $checkVar = true)
{ {
return method_exists($this, 'set' . $name); return method_exists($this, 'set' . $name) || $checkVar && property_exists($this, $name);
} }
/** /**
......
...@@ -20,15 +20,20 @@ use yii\db\Exception; ...@@ -20,15 +20,20 @@ use yii\db\Exception;
* *
* To execute a non-query SQL (such as INSERT, DELETE, UPDATE), call [[execute]]. * To execute a non-query SQL (such as INSERT, DELETE, UPDATE), call [[execute]].
* To execute a SQL statement that returns result data set (such as SELECT), * To execute a SQL statement that returns result data set (such as SELECT),
* use [[query]], [[queryRow]], [[queryColumn]], or [[queryScalar]]. * use [[queryAll]], [[queryRow]], [[queryColumn]], [[queryScalar]], or [[query]].
* For example,
*
* ~~~
* $users = \Yii::app()->db->createCommand('SELECT * FROM tbl_user')->queryAll();
* ~~~
* *
* Command supports SQL statement preparation and parameter binding. * Command supports SQL statement preparation and parameter binding.
* Call [[bindValue]] to bind a value to a SQL parameter; * Call [[bindValue]] to bind a value to a SQL parameter;
* Call [[bindParam]] to bind a PHP variable to a SQL parameter. * Call [[bindParam]] to bind a PHP variable to a SQL parameter.
* When binding a parameter, the SQL statement is automatically prepared. * When binding a parameter, the SQL statement is automatically prepared.
* You may also call [[prepare]] to explicitly prepare a SQL statement. * You may also call [[prepare]] explicitly to prepare a SQL statement.
* *
* Command can also be used as a query builder that builds and executes a SQL statement * Command can be used as a query builder that builds and executes a SQL statement
* from code fragments. For example, * from code fragments. For example,
* *
* ~~~ * ~~~
......
...@@ -37,6 +37,9 @@ use yii\db\Exception; ...@@ -37,6 +37,9 @@ use yii\db\Exception;
*/ */
class DataReader extends \yii\base\Object implements \Iterator, \Countable class DataReader extends \yii\base\Object implements \Iterator, \Countable
{ {
/**
* @var \PDOStatement the PDOStatement associated with the command
*/
private $_statement; private $_statement;
private $_closed = false; private $_closed = false;
private $_row; private $_row;
...@@ -48,7 +51,7 @@ class DataReader extends \yii\base\Object implements \Iterator, \Countable ...@@ -48,7 +51,7 @@ class DataReader extends \yii\base\Object implements \Iterator, \Countable
*/ */
public function __construct(Command $command) public function __construct(Command $command)
{ {
$this->_statement = $command->getPdoStatement(); $this->_statement = $command->pdoStatement;
$this->_statement->setFetchMode(\PDO::FETCH_ASSOC); $this->_statement->setFetchMode(\PDO::FETCH_ASSOC);
} }
......
...@@ -45,7 +45,6 @@ class Transaction extends \yii\base\Object ...@@ -45,7 +45,6 @@ class Transaction extends \yii\base\Object
public $active; public $active;
/** /**
* @var Connection the database connection that this transaction is associated with. * @var Connection the database connection that this transaction is associated with.
* This property is set true when the transaction is started.
*/ */
public $connection; public $connection;
...@@ -70,9 +69,8 @@ class Transaction extends \yii\base\Object ...@@ -70,9 +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('Transaction is inactive and cannot perform commit operation.');
} }
} }
...@@ -86,9 +84,8 @@ class Transaction extends \yii\base\Object ...@@ -86,9 +84,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('Transaction is inactive and cannot perform roll back operation.');
} }
} }
} }
...@@ -7,6 +7,7 @@ All rights reserved. ...@@ -7,6 +7,7 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
are met: are met:
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright * Redistributions in binary form must reproduce the above copyright
......
...@@ -58,6 +58,4 @@ ...@@ -58,6 +58,4 @@
- assets - assets
* ability to manage scripts order (store these in a vector?) * ability to manage scripts order (store these in a vector?)
* http://ryanbigg.com/guides/asset_pipeline.html, http://guides.rubyonrails.org/asset_pipeline.html, use content hash instead of mtime + directory hash. * http://ryanbigg.com/guides/asset_pipeline.html, http://guides.rubyonrails.org/asset_pipeline.html, use content hash instead of mtime + directory hash.
- collections
* http://code.google.com/p/yii/source/detail?r=3428
- Requirement checker - Requirement checker
\ No newline at end of file
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