From 7f35f9ada1330092a77d995f2c2c348ab44f1f2e Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sun, 25 Dec 2011 10:02:17 -0500 Subject: [PATCH] ... --- docs/internals/base.md | 2 +- framework/YiiBase.php | 140 ++++++++++------- framework/base/Application.php | 166 ++++++++++++-------- framework/base/Behavior.php | 4 +- framework/base/Component.php | 80 ++++++---- framework/base/Dictionary.php | 52 ++++--- framework/base/Event.php | 2 +- framework/base/Initable.php | 4 +- framework/base/Model.php | 75 ++++----- framework/base/Module.php | 99 ++++++------ framework/base/Object.php | 124 +++++++++------ framework/base/Vector.php | 47 +++--- framework/db/dao/ColumnSchema.php | 17 ++- framework/db/dao/Command.php | 226 +++++++++++++++------------- framework/db/dao/Connection.php | 70 +++++---- framework/db/dao/DataReader.php | 2 +- framework/db/dao/Query.php | 79 ++++++---- framework/db/dao/QueryBuilder.php | 65 ++++---- framework/db/dao/Schema.php | 5 + framework/db/dao/TableSchema.php | 6 +- framework/db/dao/Transaction.php | 16 +- framework/logging/Logger.php | 21 ++- framework/logging/Router.php | 4 +- framework/validators/Validator.php | 2 +- tests/unit/framework/base/BehaviorTest.php | 2 +- tests/unit/framework/base/ComponentTest.php | 2 +- tests/unit/framework/base/ObjectTest.php | 34 ++++- 27 files changed, 795 insertions(+), 551 deletions(-) diff --git a/docs/internals/base.md b/docs/internals/base.md index ede6ab2..252fafd 100644 --- a/docs/internals/base.md +++ b/docs/internals/base.md @@ -16,7 +16,7 @@ change API. Results in less repetitive code. Performance drop isn't significant. ### callbacks and expressions -### [[Object::create()]|create] method +### [[Object::newInstance|newInstance]] method This method is a powerful way to instantiate a class. Differences from `new`: diff --git a/framework/YiiBase.php b/framework/YiiBase.php index 35236ac..309d25b 100644 --- a/framework/YiiBase.php +++ b/framework/YiiBase.php @@ -49,12 +49,16 @@ class YiiBase * @var array class map used by the Yii autoloading mechanism. * The array keys are the class names, and the array values are the corresponding class file paths. * This property mainly affects how [[autoload]] works. + * @see import + * @see autoload */ public static $classMap = array(); /** * @var array list of directories where Yii will search for new classes to be included. * The first directory in the array will be searched first, and so on. * This property mainly affects how [[autoload]] works. + * @see import + * @see autoload */ public static $classPath = array(); /** @@ -63,10 +67,34 @@ class YiiBase public static $app; /** * @var array registered path aliases + * @see getAlias + * @see setAlias */ public static $aliases = array( '@yii' => __DIR__, ); + /** + * @var array initial property values that will be applied to objects newly created via [[createObject]]. + * The array keys are fully qualified namespaced class names, and the array values are the corresponding + * name-value pairs for initializing the created class instances. Make sure the class names do not have + * the leading backslashes. For example, + * + * ~~~ + * array( + * 'mycompany\foo\Bar' => array( + * 'prop1' => 'value1', + * 'prop2' => 'value2', + * ), + * 'mycompany\foo\Car' => array( + * 'prop1' => 'value1', + * 'prop2' => 'value2', + * ), + * ) + * ~~~ + * + * @see createObject + */ + public static $objectConfig = array(); private static $_imported = array(); // alias => class name or directory private static $_logger; @@ -140,13 +168,11 @@ class YiiBase if ($forceInclude) { require($path . "/$className.php"); self::$_imported[$alias] = $className; - } - else { + } else { self::$classMap[$className] = $path . "/$className.php"; } return $className; - } - else { // a directory + } else { // a directory array_unshift(self::$classPath, $path); return self::$_imported[$alias] = $path; } @@ -172,11 +198,9 @@ class YiiBase { if (isset(self::$aliases[$alias])) { return self::$aliases[$alias]; - } - elseif ($alias[0] !== '@') { // not an alias + } elseif ($alias[0] !== '@') { // not an alias return $alias; - } - elseif (($pos = strpos($alias, '/')) !== false) { + } elseif (($pos = strpos($alias, '/')) !== false) { $rootAlias = substr($alias, 0, $pos); if (isset(self::$aliases[$rootAlias])) { return self::$aliases[$alias] = self::$aliases[$rootAlias] . substr($alias, $pos); @@ -207,14 +231,11 @@ class YiiBase { if ($path === null) { unset(self::$aliases[$alias]); - } - elseif ($path[0] !== '@') { + } elseif ($path[0] !== '@') { self::$aliases[$alias] = rtrim($path, '\\/'); - } - elseif (($p = static::getAlias($path)) !== false) { + } elseif (($p = static::getAlias($path)) !== false) { self::$aliases[$alias] = $p; - } - else { + } else { throw new \yii\base\Exception('Invalid path: ' . $path); } } @@ -278,22 +299,34 @@ class YiiBase } /** - * Creates a new component instance using the given configuration. + * Creates a new object using the given configuration. * - * The specified configuration can be either a string or an array. - * If the former, the string is treated as the object type; if the latter, - * the array must contain a `class` element specifying the object type, and + * The configuration can be either a string or an array. + * If a string, it is treated as the *object type*; if an array, + * it must contain a `class` element specifying the *object type*, and * the rest of the name-value pairs in the array will be used to initialize * the corresponding object properties. * - * The object type can be either a class name or [[getAlias|path alias]] of + * The object type can be either a class name or the [[getAlias|alias]] of * the class. For example, * + * - `\app\components\GoogleMap`: namespaced class + * - `@app/components/GoogleMap`: an alias + * + * This method does the following steps to create an object: + * + * - create the object using the PHP `new` operator; + * - if [[objectConfig]] contains the configuration for the object class, + * initialize the object properties with that configuration; + * - initialize the object properties using the configuration passed to this method; + * - call the `init` method of the object if it implements the [[yii\base\Initable]] interface. + * + * Below are some usage examples: + * * ~~~ - * $component = Yii::create('@app/components/GoogleMap'); - * $component = Yii::create('\application\components\GoogleMap'); - * $component = Yii::create(array( - * 'class' => '@app/components/GoogleMap', + * $object = \Yii::createObject('@app/components/GoogleMap'); + * $object = \Yii::createObject(array( + * 'class' => '\app\components\GoogleMap', * 'apiKey' => 'xyz', * )); * ~~~ @@ -301,25 +334,19 @@ class YiiBase * Any additional parameters passed to this method will be * passed to the constructor of the object being created. * - * If a component class implements the [[\yii\base\Initable]] interface, - * its [[\yii\base\Initable::init|init]] method will be invoked AFTER - * the component properties are initialized. - * * @param mixed $config the configuration. It can be either a string or an array. * @return mixed the created object * @throws \yii\base\Exception if the configuration is invalid. */ - public static function create($config) + public static function createObject($config) { if (is_string($config)) { $class = $config; $config = array(); - } - elseif (isset($config['class'])) { + } elseif (isset($config['class'])) { $class = $config['class']; unset($config['class']); - } - else { + } else { throw new \yii\base\Exception('Object configuration must be an array containing a "class" element.'); } @@ -327,36 +354,38 @@ class YiiBase $class = static::import($class, true); } - if (($n = func_num_args()) > 1) { + if (($n = func_num_args()-1) > 0) { $args = func_get_args(); - if ($n === 2) { - $object = new $class($args[1]); - } - elseif ($n === 3) { - $object = new $class($args[1], $args[2]); - } - elseif ($n === 4) { - $object = new $class($args[1], $args[2], $args[3]); - } - else { - unset($args[0]); - $r = new ReflectionClass($class); - $object = $r->newInstanceArgs($args); - } + array_shift($args); // remove $config } - else { + + if ($n === 0) { $object = new $class; + } elseif ($n === 1) { + $object = new $class($args[0]); + } elseif ($n === 2) { + $object = new $class($args[0], $args[1]); + } elseif ($n === 3) { + $object = new $class($args[0], $args[1], $args[2]); + } else { + $r = new \ReflectionClass($class); + $object = $r->newInstanceArgs($args); + } + + $c = get_class($object); + if (isset(\Yii::$objectConfig[$c])) { + $config = isset($config) ? array_merge(\Yii::$objectConfig[$c], $config) : \Yii::$objectConfig[$c]; } - foreach ($config as $name => $value) { - $object->$name = $value; + if (!empty($config)) { + foreach ($config as $name => $value) { + $object->$name = $value; + } } if ($object instanceof \yii\base\Initable) { $object->init(); } - - return $object; } /** @@ -426,7 +455,7 @@ class YiiBase * @param string $category the category of this log message * @see endProfile */ - public static function beginProfile($token, $category) + public static function beginProfile($token, $category = 'application') { self::getLogger()->beginProfile($token, $category); } @@ -438,7 +467,7 @@ class YiiBase * @param string $category the category of this log message * @see beginProfile */ - public static function endProfile($token, $category) + public static function endProfile($token, $category = 'application') { self::getLogger()->endProfile($token, $category); } @@ -451,8 +480,7 @@ class YiiBase { if (self::$_logger !== null) { return self::$_logger; - } - else { + } else { return self::$_logger = new \yii\logging\Logger; } } diff --git a/framework/base/Application.php b/framework/base/Application.php index e12d095..f0f7eaa 100644 --- a/framework/base/Application.php +++ b/framework/base/Application.php @@ -119,15 +119,17 @@ abstract class Application extends Module \Yii::$app = $this; // set basePath at early as possible to avoid trouble - if (is_string($config)) + if (is_string($config)) { $config = require($config); - if (isset($config['basePath'])) - { + } + if (isset($config['basePath'])) { $this->setBasePath($config['basePath']); unset($config['basePath']); } else + { $this->setBasePath('protected'); + } \Yii::setAlias('application', $this->getBasePath()); \Yii::setAlias('webroot', dirname($_SERVER['SCRIPT_FILENAME'])); \Yii::setAlias('ext', $this->getBasePath() . DIRECTORY_SEPARATOR . 'extensions'); @@ -153,11 +155,13 @@ abstract class Application extends Module */ public function run() { - if ($this->hasEventHandlers('onBeginRequest')) + if ($this->hasEventHandlers('onBeginRequest')) { $this->onBeginRequest(new CEvent($this)); + } $this->processRequest(); - if ($this->hasEventHandlers('onEndRequest')) + if ($this->hasEventHandlers('onEndRequest')) { $this->onEndRequest(new CEvent($this)); + } } /** @@ -170,10 +174,12 @@ abstract class Application extends Module */ public function end($status = 0, $exit = true) { - if ($this->hasEventHandlers('onEndRequest')) + if ($this->hasEventHandlers('onEndRequest')) { $this->onEndRequest(new CEvent($this)); - if ($exit) + } + if ($exit) { exit($status); + } } /** @@ -191,8 +197,7 @@ abstract class Application extends Module */ public function onEndRequest($event) { - if (!$this->_ended) - { + if (!$this->_ended) { $this->_ended = true; $this->raiseEvent('onEndRequest', $event); } @@ -204,10 +209,13 @@ abstract class Application extends Module */ public function getId() { - if ($this->_id !== null) + if ($this->_id !== null) { return $this->_id; + } else + { return $this->_id = sprintf('%x', crc32($this->getBasePath() . $this->name)); + } } /** @@ -236,9 +244,10 @@ abstract class Application extends Module */ public function setBasePath($path) { - if (($this->_basePath = realpath($path)) === false || !is_dir($this->_basePath)) + if (($this->_basePath = realpath($path)) === false || !is_dir($this->_basePath)) { throw new \yii\base\Exception(\Yii::t('yii', 'Application base path "{path}" is not a valid directory.', array('{path}' => $path))); + } } /** @@ -247,8 +256,9 @@ abstract class Application extends Module */ public function getRuntimePath() { - if ($this->_runtimePath !== null) + if ($this->_runtimePath !== null) { return $this->_runtimePath; + } else { $this->setRuntimePath($this->getBasePath() . DIRECTORY_SEPARATOR . 'runtime'); @@ -263,9 +273,10 @@ abstract class Application extends Module */ public function setRuntimePath($path) { - if (($runtimePath = realpath($path)) === false || !is_dir($runtimePath) || !is_writable($runtimePath)) + if (($runtimePath = realpath($path)) === false || !is_dir($runtimePath) || !is_writable($runtimePath)) { throw new \yii\base\Exception(\Yii::t('yii', 'Application runtime path "{path}" is not valid. Please make sure it is a directory writable by the Web server process.', array('{path}' => $path))); + } $this->_runtimePath = $runtimePath; } @@ -284,9 +295,10 @@ abstract class Application extends Module */ public function setExtensionPath($path) { - if (($extensionPath = realpath($path)) === false || !is_dir($extensionPath)) + if (($extensionPath = realpath($path)) === false || !is_dir($extensionPath)) { throw new \yii\base\Exception(\Yii::t('yii', 'Extension path "{path}" does not exist.', array('{path}' => $path))); + } \Yii::setAlias('ext', $extensionPath); } @@ -359,12 +371,15 @@ abstract class Application extends Module */ public function findLocalizedFile($srcFile, $srcLanguage = null, $language = null) { - if ($srcLanguage === null) + if ($srcLanguage === null) { $srcLanguage = $this->sourceLanguage; - if ($language === null) + } + if ($language === null) { $language = $this->getLanguage(); - if ($language === $srcLanguage) + } + if ($language === $srcLanguage) { return $srcFile; + } $desiredFile = dirname($srcFile) . DIRECTORY_SEPARATOR . $language . DIRECTORY_SEPARATOR . basename($srcFile); return is_file($desiredFile) ? $desiredFile : $srcFile; } @@ -528,10 +543,13 @@ abstract class Application extends Module public function createAbsoluteUrl($route, $params = array(), $schema = '', $ampersand = '&') { $url = $this->createUrl($route, $params, $ampersand); - if (strpos($url, 'http') === 0) + if (strpos($url, 'http') === 0) { return $url; + } else + { return $this->getRequest()->getHostInfo($schema) . $url; + } } /** @@ -552,15 +570,19 @@ abstract class Application extends Module */ public function getHomeUrl() { - if ($this->_homeUrl === null) - { - if ($this->getUrlManager()->showScriptName) + if ($this->_homeUrl === null) { + if ($this->getUrlManager()->showScriptName) { return $this->getRequest()->getScriptUrl(); + } else + { return $this->getRequest()->getBaseUrl() . '/'; + } } else + { return $this->_homeUrl; + } } /** @@ -582,12 +604,16 @@ abstract class Application extends Module */ public function getGlobalState($key, $defaultValue = null) { - if ($this->_globalState === null) + if ($this->_globalState === null) { $this->loadGlobalState(); - if (isset($this->_globalState[$key])) + } + if (isset($this->_globalState[$key])) { return $this->_globalState[$key]; + } else + { return $defaultValue; + } } /** @@ -602,14 +628,13 @@ abstract class Application extends Module */ public function setGlobalState($key, $value, $defaultValue = null) { - if ($this->_globalState === null) + if ($this->_globalState === null) { $this->loadGlobalState(); + } $changed = $this->_stateChanged; - if ($value === $defaultValue) - { - if (isset($this->_globalState[$key])) - { + if ($value === $defaultValue) { + if (isset($this->_globalState[$key])) { unset($this->_globalState[$key]); $this->_stateChanged = true; } @@ -620,8 +645,9 @@ abstract class Application extends Module $this->_stateChanged = true; } - if ($this->_stateChanged !== $changed) + if ($this->_stateChanged !== $changed) { $this->attachEventHandler('onEndRequest', array($this, 'saveGlobalState')); + } } /** @@ -643,8 +669,9 @@ abstract class Application extends Module public function loadGlobalState() { $persister = $this->getStatePersister(); - if (($this->_globalState = $persister->load()) === null) + if (($this->_globalState = $persister->load()) === null) { $this->_globalState = array(); + } $this->_stateChanged = false; $this->detachEventHandler('onEndRequest', array($this, 'saveGlobalState')); } @@ -656,8 +683,7 @@ abstract class Application extends Module */ public function saveGlobalState() { - if ($this->_stateChanged) - { + if ($this->_stateChanged) { $this->_stateChanged = false; $this->detachEventHandler('onEndRequest', array($this, 'saveGlobalState')); $this->getStatePersister()->save($this->_globalState); @@ -685,12 +711,14 @@ abstract class Application extends Module restore_exception_handler(); $category = 'exception.' . get_class($exception); - if ($exception instanceof \yii\web\HttpException) + if ($exception instanceof \yii\web\HttpException) { $category .= '.' . $exception->statusCode; + } // php <5.2 doesn't support string conversion auto-magically $message = $exception->__toString(); - if (isset($_SERVER['REQUEST_URI'])) + if (isset($_SERVER['REQUEST_URI'])) { $message .= ' REQUEST_URI=' . $_SERVER['REQUEST_URI']; + } \Yii::error($message, $category); try @@ -699,11 +727,9 @@ abstract class Application extends Module //$event = new CExceptionEvent($this, $exception); $event = new Event($this, array('exception' => $exception)); $this->onException($event); - if (!$event->handled) - { + if (!$event->handled) { // try an error handler - if (($handler = $this->getErrorHandler()) !== null) - { + if (($handler = $this->getErrorHandler()) !== null) { $handler->handle($event); } else @@ -712,7 +738,7 @@ abstract class Application extends Module } } } - catch(Exception $e) + catch (Exception $e) { $this->displayException($e); } @@ -721,7 +747,7 @@ abstract class Application extends Module { $this->end(1); } - catch(Exception $e) + catch (Exception $e) { // use the most primitive way to log error $msg = get_class($e) . ': ' . $e->getMessage() . ' (' . $e->getFile() . ':' . $e->getLine() . ")\n"; @@ -754,8 +780,7 @@ abstract class Application extends Module */ public function handleError($code, $message, $file, $line) { - if ($code & error_reporting()) - { + if ($code & error_reporting()) { // disable error capturing to avoid recursive errors restore_error_handler(); restore_exception_handler(); @@ -763,23 +788,29 @@ abstract class Application extends Module $log = "$message ($file:$line)\nStack trace:\n"; $trace = debug_backtrace(); // skip the first 3 stacks as they do not tell the error position - if (count($trace) > 3) + if (count($trace) > 3) { $trace = array_slice($trace, 3); + } foreach ($trace as $i => $t) { - if (!isset($t['file'])) + if (!isset($t['file'])) { $t['file'] = 'unknown'; - if (!isset($t['line'])) + } + if (!isset($t['line'])) { $t['line'] = 0; - if (!isset($t['function'])) + } + if (!isset($t['function'])) { $t['function'] = 'unknown'; + } $log .= "#$i {$t['file']}( {$t['line']}): "; - if (isset($t['object']) && is_object($t['object'])) + if (isset($t['object']) && is_object($t['object'])) { $log .= get_class($t['object']) . '->'; + } $log .= " {$t['function']}()\n"; } - if (isset($_SERVER['REQUEST_URI'])) + if (isset($_SERVER['REQUEST_URI'])) { $log .= 'REQUEST_URI=' . $_SERVER['REQUEST_URI']; + } \Yii::error($log, 'php'); try @@ -787,16 +818,18 @@ abstract class Application extends Module \Yii::import('CErrorEvent', true); $event = new CErrorEvent($this, $code, $message, $file, $line); $this->onError($event); - if (!$event->handled) - { + if (!$event->handled) { // try an error handler - if (($handler = $this->getErrorHandler()) !== null) + if (($handler = $this->getErrorHandler()) !== null) { $handler->handle($event); + } else + { $this->displayError($code, $message, $file, $line); + } } } - catch(Exception $e) + catch (Exception $e) { $this->displayException($e); } @@ -805,7 +838,7 @@ abstract class Application extends Module { $this->end(1); } - catch(Exception $e) + catch (Exception $e) { // use the most primitive way to log error $msg = get_class($e) . ': ' . $e->getMessage() . ' (' . $e->getFile() . ':' . $e->getLine() . ")\n"; @@ -860,27 +893,31 @@ abstract class Application extends Module */ public function displayError($code, $message, $file, $line) { - if (YII_DEBUG) - { + if (YII_DEBUG) { echo "

PHP Error [$code]

\n"; echo "

$message ($file:$line)

\n"; echo '
';
 
 			$trace = debug_backtrace();
 			// skip the first 3 stacks as they do not tell the error position
-			if (count($trace) > 3)
+			if (count($trace) > 3) {
 				$trace = array_slice($trace, 3);
+			}
 			foreach ($trace as $i => $t)
 			{
-				if (!isset($t['file']))
+				if (!isset($t['file'])) {
 					$t['file'] = 'unknown';
-				if (!isset($t['line']))
+				}
+				if (!isset($t['line'])) {
 					$t['line'] = 0;
-				if (!isset($t['function']))
+				}
+				if (!isset($t['function'])) {
 					$t['function'] = 'unknown';
+				}
 				echo "#$i  {$t['file']}( {$t['line']}): ";
-				if (isset($t['object']) && is_object($t['object']))
+				if (isset($t['object']) && is_object($t['object'])) {
 					echo get_class($t['object']) . '->';
+				}
 				echo " {$t['function']}()\n";
 			}
 
@@ -901,8 +938,7 @@ abstract class Application extends Module
 	 */
 	public function displayException($exception)
 	{
-		if (YII_DEBUG)
-		{
+		if (YII_DEBUG) {
 			echo '

' . get_class($exception) . "

\n"; echo '

' . $exception->getMessage() . ' (' . $exception->getFile() . ':' . $exception->getLine() . ')

'; echo '
' . $exception->getTraceAsString() . '
'; @@ -919,10 +955,12 @@ abstract class Application extends Module */ protected function initSystemHandlers() { - if (YII_ENABLE_EXCEPTION_HANDLER) + if (YII_ENABLE_EXCEPTION_HANDLER) { set_exception_handler(array($this, 'handleException')); - if (YII_ENABLE_ERROR_HANDLER) + } + if (YII_ENABLE_ERROR_HANDLER) { set_error_handler(array($this, 'handleError'), error_reporting()); + } } /** diff --git a/framework/base/Behavior.php b/framework/base/Behavior.php index 40c4a00..fc0a462 100644 --- a/framework/base/Behavior.php +++ b/framework/base/Behavior.php @@ -47,8 +47,8 @@ class Behavior extends Object * * ~~~ * array( - * 'onBeforeValidate' => 'myBeforeValidate', - * 'onAfterValidate' => 'myAfterValidate', + * 'onBeforeValidate' => 'myBeforeValidate', + * 'onAfterValidate' => 'myAfterValidate', * ) * ~~~ * diff --git a/framework/base/Component.php b/framework/base/Component.php index 2ed8d64..a4d77eb 100644 --- a/framework/base/Component.php +++ b/framework/base/Component.php @@ -22,7 +22,7 @@ namespace yii\base; * ~~~ * public function onClick($event) * { - * $this->raiseEvent('onClick', $event); + * $this->raiseEvent('onClick', $event); * } * ~~~ * @@ -54,8 +54,8 @@ namespace yii\base; * * ~~~ * $component->onClick->insertAt(0, $callback); // attach a handler as the first one - * $component->onClick[] = $callback; // attach a handler as the last one - * unset($component->onClick[0]); // detach the first handler + * $component->onClick[] = $callback; // attach a handler as the last one + * unset($component->onClick[0]); // detach the first handler * ~~~ * * @@ -98,15 +98,18 @@ class Component extends Object $getter = 'get' . $name; if (method_exists($this, $getter)) { // read property, e.g. getName() return $this->$getter(); - } elseif (method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0) { // event, e.g. onClick() + } + elseif (method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0) { // event, e.g. onClick() $name = strtolower($name); if (!isset($this->_e[$name])) { $this->_e[$name] = new Vector; } return $this->_e[$name]; - } elseif (isset($this->_b[$name])) { // behavior + } + elseif (isset($this->_b[$name])) { // behavior return $this->_b[$name]; - } elseif (is_array($this->_b)) { // a behavior property + } + elseif (is_array($this->_b)) { // a behavior property foreach ($this->_b as $object) { if ($object->canGetProperty($name)) { return $object->$name; @@ -135,15 +138,17 @@ class Component extends Object public function __set($name, $value) { $setter = 'set' . $name; - if (method_exists($this, $setter)) { // write property + if (method_exists($this, $setter)) { // write property return $this->$setter($value); - } elseif (method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0) { // event + } + elseif (method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0) { // event $name = strtolower($name); if (!isset($this->_e[$name])) { $this->_e[$name] = new Vector; } return $this->_e[$name]->add($value); - } elseif (is_array($this->_b)) { // behavior + } + elseif (is_array($this->_b)) { // behavior foreach ($this->_b as $object) { if ($object->canSetProperty($name)) { return $object->$name = $value; @@ -152,7 +157,8 @@ class Component extends Object } if (method_exists($this, 'get' . $name)) { throw new Exception('Setting read-only property: ' . get_class($this) . '.' . $name); - } else { + } + else { throw new Exception('Setting unknown property: ' . get_class($this) . '.' . $name); } } @@ -175,12 +181,15 @@ class Component extends Object $getter = 'get' . $name; if (method_exists($this, $getter)) { // property is not null return $this->$getter() !== null; - } elseif (method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0) { // has event handler + } + elseif (method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0) { // has event handler $name = strtolower($name); return isset($this->_e[$name]) && $this->_e[$name]->getCount(); - } elseif (isset($this->_b[$name])) { // has behavior - return true; - } elseif (is_array($this->_b)) { + } + elseif (isset($this->_b[$name])) { // has behavior + return true; + } + elseif (is_array($this->_b)) { foreach ($this->_b as $object) { if ($object->canGetProperty($name)) { return $object->$name !== null; @@ -206,14 +215,17 @@ class Component extends Object public function __unset($name) { $setter = 'set' . $name; - if (method_exists($this, $setter)) { // write property + if (method_exists($this, $setter)) { // write property return $this->$setter(null); - } elseif (method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0) { // event + } + elseif (method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0) { // event unset($this->_e[strtolower($name)]); return; - } elseif (isset($this->_b[$name])) { // behavior + } + elseif (isset($this->_b[$name])) { // behavior return $this->detachBehavior($name); - } elseif (is_array($this->_b)) { // behavior property + } + elseif (is_array($this->_b)) { // behavior property foreach ($this->_b as $object) { if ($object->canSetProperty($name)) { return $object->$name = null; @@ -266,7 +278,7 @@ class Component extends Object */ public function hasEvent($name) { - return method_exists($this, $name) && strncasecmp($name, 'on', 2)===0; + return method_exists($this, $name) && strncasecmp($name, 'on', 2) === 0; } /** @@ -318,10 +330,10 @@ class Component extends Object * some examples: * * ~~~ - * 'handleOnClick' // handleOnClick() is a global function - * array($object, 'handleOnClick') // $object->handleOnClick() - * array('Page', 'handleOnClick') // Page::handleOnClick() - * function($event) { ... } // anonymous function + * 'handleOnClick' // handleOnClick() is a global function + * array($object, 'handleOnClick') // $object->handleOnClick() + * array('Page', 'handleOnClick') // Page::handleOnClick() + * function($event) { ... } // anonymous function * ~~~ * * An event handler must be defined with the following signature, @@ -374,17 +386,21 @@ class Component extends Object foreach ($this->_e[$name] as $handler) { if (is_string($handler) || $handler instanceof \Closure) { call_user_func($handler, $event); - } elseif (is_callable($handler, true)) { + } + elseif (is_callable($handler, true)) { // an array: 0 - object, 1 - method name list($object, $method) = $handler; - if (is_string($object)) { // static method call + if (is_string($object)) { // static method call call_user_func($handler, $event); - } elseif (method_exists($object, $method)) { + } + elseif (method_exists($object, $method)) { $object->$method($event); - } else { + } + else { throw new Exception('Event "' . get_class($this) . '.' . $name . '" is attached with an invalid handler.'); } - } else { + } + else { throw new Exception('Event "' . get_class($this) . '.' . $name . '" is attached with an invalid handler.'); } @@ -393,7 +409,8 @@ class Component extends Object return; } } - } elseif (!$this->hasEvent($name)) { + } + elseif (!$this->hasEvent($name)) { throw new Exception('Raising unknown event: ' . get_class($this) . '.' . $name); } } @@ -419,16 +436,15 @@ class Component extends Object * * - a [[Behavior]] object * - a string specifying the behavior class - * - an object configuration array + * - an object configuration array that will be passed to [[\Yii::createObject]] to create the behavior object. * - * parameter to [[\Yii::create]] to create the behavior object. * @return Behavior the behavior object * @see detachBehavior */ public function attachBehavior($name, $behavior) { if (!($behavior instanceof Behavior)) { - $behavior = \Yii::create($behavior); + $behavior = \Yii::createObject($behavior); } $behavior->attach($this); return $this->_b[$name] = $behavior; diff --git a/framework/base/Dictionary.php b/framework/base/Dictionary.php index 4c413d6..86be283 100644 --- a/framework/base/Dictionary.php +++ b/framework/base/Dictionary.php @@ -21,11 +21,11 @@ namespace yii\base; * like a regular PHP array as follows, * * ~~~ - * $dictionary[$key] = $value; // add a key-value pair - * unset($dictionary[$key]); // remove the value with the specified key - * if (isset($dictionary[$key])) // if the dictionary contains the key + * $dictionary[$key] = $value; // add a key-value pair + * unset($dictionary[$key]); // remove the value with the specified key + * if (isset($dictionary[$key])) // if the dictionary contains the key * foreach ($dictionary as $key=>$value) // traverse the items in the dictionary - * $n = count($dictionary); // returns the number of items in the dictionary + * $n = count($dictionary); // returns the number of items in the dictionary * ~~~ * * @author Qiang Xue @@ -114,7 +114,8 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co { if ($key === null) { $this->_d[] = $value; - } else { + } + else { $this->_d[$key] = $value; } } @@ -131,7 +132,8 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co $value = $this->_d[$key]; unset($this->_d[$key]); return $value; - } else { // the value is null + } + else { // the value is null unset($this->_d[$key]); return null; } @@ -149,7 +151,8 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co foreach (array_keys($this->_d) as $key) { $this->remove($key); } - } else { + } + else { $this->_d = array(); } } @@ -181,8 +184,7 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co */ public function copyFrom($data) { - if (is_array($data) || $data instanceof \Traversable) - { + if (is_array($data) || $data instanceof \Traversable) { if ($this->_d !== array()) { $this->clear(); } @@ -192,7 +194,8 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co foreach ($data as $key => $value) { $this->add($key, $value); } - } else { + } + else { throw new Exception('Data must be either an array or an object implementing Traversable.'); } } @@ -214,7 +217,7 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co * * @throws CException If data is neither an array nor an iterator. */ - public function mergeWith($data, $recursive=true) + public function mergeWith($data, $recursive = true) { if (is_array($data) || $data instanceof \Traversable) { if ($data instanceof self) { @@ -222,20 +225,23 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co } if ($recursive) { if ($data instanceof \Traversable) { - $d=array(); - foreach($data as $key => $value) { + $d = array(); + foreach ($data as $key => $value) { $d[$key] = $value; } $this->_d = self::mergeArray($this->_d, $d); - } else { + } + else { $this->_d = self::mergeArray($this->_d, $data); } - } else { - foreach($data as $key => $value) { + } + else { + foreach ($data as $key => $value) { $this->add($key, $value); } } - } else { + } + else { throw new Exception('Dictionary data must be an array or an object implementing Traversable.'); } } @@ -278,7 +284,7 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co */ public function offsetSet($offset, $item) { - $this->add($offset,$item); + $this->add($offset, $item); } /** @@ -308,12 +314,14 @@ class Dictionary extends Object implements \IteratorAggregate, \ArrayAccess, \Co */ public static function mergeArray($a, $b) { - foreach($b as $k=>$v) { - if(is_integer($k)) { + foreach ($b as $k => $v) { + if (is_integer($k)) { isset($a[$k]) ? $a[] = $v : $a[$k] = $v; - } elseif(is_array($v) && isset($a[$k]) && is_array($a[$k])) { + } + elseif (is_array($v) && isset($a[$k]) && is_array($a[$k])) { $a[$k] = self::mergeArray($a[$k], $v); - } else { + } + else { $a[$k] = $v; } } diff --git a/framework/base/Event.php b/framework/base/Event.php index f508f47..737f9b7 100644 --- a/framework/base/Event.php +++ b/framework/base/Event.php @@ -51,7 +51,7 @@ class Event extends Object * @param mixed $sender sender of the event * @param mixed $params parameters of the event */ - public function __construct($sender=null, $params=null) + public function __construct($sender = null, $params = null) { $this->sender = $sender; $this->params = $params; diff --git a/framework/base/Initable.php b/framework/base/Initable.php index fcbdd92..298f6ca 100644 --- a/framework/base/Initable.php +++ b/framework/base/Initable.php @@ -13,7 +13,7 @@ namespace yii\base; * Initable is an interface indicating a class needs initialization to work properly. * * Initable requires a class to implement the [[init]] method. - * When [[\Yii::create]] is being used to create a new component which implements + * When [[\Yii::createObject]] is being used to create a new component which implements * Initable, it will call the [[init]] method after setting the initial values of the * component properties. * @@ -24,7 +24,7 @@ interface Initable { /** * Initializes this component. - * This method is invoked by [[\Yii::create]] after its creates the new + * This method is invoked by [[\Yii::createObject]] after its creates the new * component instance and initializes the component properties. In other words, * at this stage, the component has been fully configured. */ diff --git a/framework/base/Model.php b/framework/base/Model.php index f90b044..d12a1a8 100644 --- a/framework/base/Model.php +++ b/framework/base/Model.php @@ -35,15 +35,15 @@ namespace yii\base; class Model extends Component implements Initable, \IteratorAggregate, \ArrayAccess { private static $_attributes = array(); // class name => array of attribute names - private $_errors; // attribute name => array of errors - private $_validators; // validators - private $_scenario; // scenario + private $_errors; // attribute name => array of errors + private $_validators; // validators + private $_scenario; // scenario /** * Constructor. * @param string $scenario name of the [[scenario]] that this model is used in. */ - public function __construct($scenario='') + public function __construct($scenario = '') { $this->_scenario = $scenario; $this->afterConstruct(); @@ -52,7 +52,7 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc /** * Initializes this model. * - * This method is required by the [[Initable]] interface. It is invoked by [[\Yii::create]] + * This method is required by the [[Initable]] interface. It is invoked by [[\Yii::createObject]] * after it creates the new model instance and initializes the model properties. * * The default implementation calls [[behaviors]] and registers any available behaviors. @@ -72,9 +72,9 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc * * ~~~ * 'behaviorName' => array( - * 'class' => 'BehaviorClass', - * 'property1' => 'value1', - * 'property2' => 'value2', + * 'class' => 'BehaviorClass', + * 'property1' => 'value1', + * 'property2' => 'value2', * ) * ~~~ * @@ -123,10 +123,10 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc * * ~~~ * array( - * 'attribute list', - * 'validator type', - * 'on'=>'scenario name', - * ...other parameters... + * 'attribute list', + * 'validator type', + * 'on'=>'scenario name', + * ...other parameters... * ) * ~~~ * @@ -134,11 +134,11 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc * * - attribute list: required, specifies the attributes (separated by commas) to be validated; * - validator type: required, specifies the validator to be used. It can be the name of a model - * class method, the name of a built-in validator, or a validator class (or its path alias). + * class method, the name of a built-in validator, or a validator class (or its path alias). * - on: optional, specifies the [[scenario|scenarios]] (separated by commas) when the validation - * rule can be applied. If this option is not set, the rule will apply to any scenario. + * rule can be applied. If this option is not set, the rule will apply to any scenario. * - additional name-value pairs can be specified to initialize the corresponding validator properties. - * Please refer to individual validator class API for possible properties. + * Please refer to individual validator class API for possible properties. * * A validator can be either a model class method or an object. * If the former, the method must have the following signature: @@ -156,10 +156,10 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc * * ~~~ * array( - * array('username', 'required'), - * array('username', 'length', 'min'=>3, 'max'=>12), - * array('password', 'compare', 'compareAttribute'=>'password2', 'on'=>'register'), - * array('password', 'authenticate', 'on'=>'login'), + * array('username', 'required'), + * array('username', 'length', 'min'=>3, 'max'=>12), + * array('password', 'compare', 'compareAttribute'=>'password2', 'on'=>'register'), + * array('password', 'authenticate', 'on'=>'login'), * ); * ~~~ * @@ -364,10 +364,11 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc { $validators = new Vector; foreach ($this->rules() as $rule) { - if (isset($rule[0], $rule[1])) { // attributes, validator type + if (isset($rule[0], $rule[1])) { // attributes, validator type $validator = \yii\validators\Validator::createValidator($rule[1], $this, $rule[0], array_slice($rule, 2)); $validators->add($validator); - } else { + } + else { throw new Exception('Invalid validation rule: a rule must specify both attribute names and validator type.'); } } @@ -439,13 +440,13 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc * * ~~~ * array( - * 'username' => array( - * 'Username is required.', - * 'Username must contain only word characters.', - * ), - * 'email' => array( - * 'Email address is invalid.', - * ) + * 'username' => array( + * 'Username is required.', + * 'Username must contain only word characters.', + * ), + * 'email' => array( + * 'Email address is invalid.', + * ) * ) * ~~~ * @@ -455,7 +456,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc { if ($attribute === null) { return $this->_errors === null ? array() : $this->_errors; - } else { + } + else { return isset($this->_errors[$attribute]) ? $this->_errors[$attribute] : array(); } } @@ -494,7 +496,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc foreach ($error as $e) { $this->_errors[$attribute][] = $e; } - } else { + } + else { $this->_errors[$attribute][] = $error; } } @@ -508,7 +511,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc { if ($attribute === null) { $this->_errors = array(); - } else { + } + else { unset($this->_errors[$attribute]); } } @@ -543,7 +547,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc $values[$name] = $this->$name; } } - } else { + } + else { foreach ($this->attributeNames() as $name) { $values[$name] = $this->$name; } @@ -567,7 +572,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc foreach ($values as $name => $value) { if (isset($attributes[$name])) { $this->$name = $value; - } elseif ($safeOnly) { + } + elseif ($safeOnly) { $this->onUnsafeAttribute($name, $value); } } @@ -633,7 +639,8 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc foreach ($validator->attributes as $name) { $unsafe[] = $name; } - } else { + } + else { foreach ($validator->attributes as $name) { $attributes[$name] = true; } diff --git a/framework/base/Module.php b/framework/base/Module.php index e28d81a..2843fdf 100644 --- a/framework/base/Module.php +++ b/framework/base/Module.php @@ -59,10 +59,10 @@ abstract class Module extends Component $this->_parentModule = $parent; // set basePath at early as possible to avoid trouble - if (is_string($config)) + if (is_string($config)) { $config = require($config); - if (isset($config['basePath'])) - { + } + if (isset($config['basePath'])) { $this->setBasePath($config['basePath']); unset($config['basePath']); } @@ -139,7 +139,7 @@ abstract class Module extends Component */ public function setId($id) { - $this->_id=$id; + $this->_id = $id; } /** @@ -216,8 +216,8 @@ abstract class Module extends Component * * ~~~ * array( - * '@models' => '@app/models', // an existing alias - * '@backend' => __DIR__ . '/../backend', // a directory + * '@models' => '@app/models', // an existing alias + * '@backend' => __DIR__ . '/../backend', // a directory * ) * ~~~ */ @@ -246,23 +246,22 @@ abstract class Module extends Component */ public function getModule($id) { - if (isset($this->_modules[$id]) || array_key_exists($id, $this->_modules)) + if (isset($this->_modules[$id]) || array_key_exists($id, $this->_modules)) { return $this->_modules[$id]; + } elseif (isset($this->_moduleConfig[$id])) { $config = $this->_moduleConfig[$id]; - if (!isset($config['enabled']) || $config['enabled']) - { + if (!isset($config['enabled']) || $config['enabled']) { \Yii::trace("Loading \"$id\" module", 'system.base.CModule'); $class = $config['class']; unset($config['class'], $config['enabled']); - if ($this === \Yii::$app) - { - $module = Yii::create($class, $id, null, $config); + if ($this === \Yii::$app) { + $module = \Yii::createObject($class, $id, null, $config); } else { - $module = Yii::create($class, $this->getId() . '/' . $id, $this, $config); + $module = \Yii::createObject($class, $this->getId() . '/' . $id, $this, $config); } return $this->_modules[$id] = $module; } @@ -299,10 +298,10 @@ abstract class Module extends Component * For example, the following array declares two modules: *
 	 * array(
-	 *     'admin',                // a single module ID
-	 *     'payment'=>array(       // ID-configuration pair
-	 *         'server'=>'paymentserver.com',
-	 *     ),
+	 *	 'admin',				// a single module ID
+	 *	 'payment'=>array(	   // ID-configuration pair
+	 *		 'server'=>'paymentserver.com',
+	 *	 ),
 	 * )
 	 * 
* @@ -318,21 +317,22 @@ abstract class Module extends Component { foreach ($modules as $id => $module) { - if (is_int($id)) - { + if (is_int($id)) { $id = $module; $module = array(); } - if (!isset($module['class'])) - { + if (!isset($module['class'])) { Yii::setPathOfAlias($id, $this->getModulePath() . DIRECTORY_SEPARATOR . $id); $module['class'] = $id . '.' . ucfirst($id) . 'Module'; } - if (isset($this->_moduleConfig[$id])) + if (isset($this->_moduleConfig[$id])) { $this->_moduleConfig[$id] = CMap::mergeArray($this->_moduleConfig[$id], $module); + } else + { $this->_moduleConfig[$id] = $module; + } } } @@ -356,16 +356,16 @@ abstract class Module extends Component */ public function getComponent($id, $createIfNull = true) { - if (isset($this->_components[$id])) + if (isset($this->_components[$id])) { return $this->_components[$id]; + } elseif (isset($this->_componentConfig[$id]) && $createIfNull) { $config = $this->_componentConfig[$id]; - if (!isset($config['enabled']) || $config['enabled']) - { + if (!isset($config['enabled']) || $config['enabled']) { \Yii::trace("Loading \"$id\" application component", 'system.CModule'); unset($config['enabled']); - $component = \Yii::create($config); + $component = \Yii::createObject($config); return $this->_components[$id] = $component; } } @@ -381,13 +381,14 @@ abstract class Module extends Component */ public function setComponent($id, $component) { - if ($component === null) + if ($component === null) { unset($this->_components[$id]); - else - { + } + else { $this->_components[$id] = $component; - if (!$component->getIsInitialized()) + if (!$component->getIsInitialized()) { $component->init(); + } } } @@ -401,10 +402,12 @@ abstract class Module extends Component */ public function getComponents($loadedOnly = true) { - if ($loadedOnly) + if ($loadedOnly) { return $this->_components; - else + } + else { return array_merge($this->_componentConfig, $this->_components); + } } /** @@ -421,15 +424,15 @@ abstract class Module extends Component * The following is the configuration for two components: *
 	 * array(
-	 *     'db'=>array(
-	 *         'class'=>'CDbConnection',
-	 *         'connectionString'=>'sqlite:path/to/file.db',
-	 *     ),
-	 *     'cache'=>array(
-	 *         'class'=>'CDbCache',
-	 *         'connectionID'=>'db',
-	 *         'enabled'=>!YII_DEBUG,  // enable caching in non-debug mode
-	 *     ),
+	 *	 'db'=>array(
+	 *		 'class'=>'CDbConnection',
+	 *		 'connectionString'=>'sqlite:path/to/file.db',
+	 *	 ),
+	 *	 'cache'=>array(
+	 *		 'class'=>'CDbCache',
+	 *		 'connectionID'=>'db',
+	 *		 'enabled'=>!YII_DEBUG,  // enable caching in non-debug mode
+	 *	 ),
 	 * )
 	 * 
* @@ -442,12 +445,17 @@ abstract class Module extends Component { foreach ($components as $id => $component) { - if ($component instanceof IApplicationComponent) + if ($component instanceof IApplicationComponent) { $this->setComponent($id, $component); + } elseif (isset($this->_componentConfig[$id]) && $merge) + { $this->_componentConfig[$id] = CMap::mergeArray($this->_componentConfig[$id], $component); + } else + { $this->_componentConfig[$id] = $component; + } } } @@ -457,10 +465,11 @@ abstract class Module extends Component */ public function configure($config) { - if (is_array($config)) - { + if (is_array($config)) { foreach ($config as $key => $value) + { $this->$key = $value; + } } } @@ -470,7 +479,9 @@ abstract class Module extends Component public function preloadComponents() { foreach ($this->preload as $id) + { $this->getComponent($id); + } } /** diff --git a/framework/base/Object.php b/framework/base/Object.php index 5b5ac34..60b2510 100644 --- a/framework/base/Object.php +++ b/framework/base/Object.php @@ -21,12 +21,12 @@ namespace yii\base; * * public function getLabel() * { - * return $this->_label; + * return $this->_label; * } * * public function setLabel($value) * { - * $this->_label = $value; + * $this->_label = $value; * } * ~~~ * @@ -85,7 +85,8 @@ class Object $getter = 'get' . $name; if (method_exists($this, $getter)) { return $this->$getter(); - } else { + } + else { throw new Exception('Getting unknown property: ' . get_class($this) . '.' . $name); } } @@ -105,9 +106,11 @@ class Object $setter = 'set' . $name; if (method_exists($this, $setter)) { $this->$setter($value); - } elseif (method_exists($this, 'get' . $name)) { + } + elseif (method_exists($this, 'get' . $name)) { throw new Exception('Setting read-only property: ' . get_class($this) . '.' . $name); - } else { + } + else { throw new Exception('Setting unknown property: ' . get_class($this) . '.' . $name); } } @@ -127,7 +130,8 @@ class Object $getter = 'get' . $name; if (method_exists($this, $getter)) { // property is not null return $this->$getter() !== null; - } else { + } + else { return false; } } @@ -146,9 +150,10 @@ class Object public function __unset($name) { $setter = 'set' . $name; - if (method_exists($this, $setter)) { // write property + if (method_exists($this, $setter)) { // write property $this->$setter(null); - } elseif (method_exists($this, 'get' . $name)) { + } + elseif (method_exists($this, 'get' . $name)) { throw new Exception('Unsetting read-only property: ' . get_class($this) . '.' . $name); } } @@ -244,74 +249,107 @@ class Object * @param array $_data_ additional parameters to be passed to the above expression/callback. * @return mixed the expression result */ - public function evaluateExpression($_expression_, $_data_=array()) + public function evaluateExpression($_expression_, $_data_ = array()) { if (is_string($_expression_)) { extract($_data_); return eval('return ' . $_expression_ . ';'); - } else { + } + else { $_data_[] = $this; return call_user_func_array($_expression_, $_data_); } } /** - * Creates a new object instance. - * - * This method calls [[\Yii::create]] to create the new object instance. - * - * This method differs from the PHP `new` operator in that it does the following - * steps to create a new object instance: - * - * - Call class constructor (same as the `new` operator); - * - Initialize the object properties using the name-value pairs given as the - * last parameter to this method; - * - Call [[Initable::init|init]] if the class implements [[Initable]]. + * Creates a new instance of the calling class. * * Parameters passed to this method will be used as the parameters to the object * constructor. * - * Additionally, one can pass in an associative array as the last parameter to - * this method. This method will treat the array as name-value pairs that initialize - * the corresponding object properties. For example, + * This method does the following steps to create a object: + * + * - create the object using the PHP `new` operator; + * - if [[Yii::objectConfig]] contains the configuration for the object class, + * initialize the object properties with that configuration; + * - if the number of the given parameters is more than the number of the parameters + * listed in the object constructor and the last given parameter is an array, + * initialize the object properties using that array; + * - call the `init` method of the object if it implements the [[yii\base\Initable]] interface. + * + * For example, * * ~~~ - * class Foo extends \yii\base\Object + * class Foo extends \yii\base\Object implements \yii\base\Initable * { - * public $c; - * public function __construct($a, $b) - * { - * ... - * } + * public $c; + * public function __construct($a, $b) + * { + * ... + * } + * public function init() + * { + * ... + * } * } * - * $model = Foo::create(1, 2, array('c' => 3)); + * $model = Foo::newInstance(1, 2, array('c' => 3)); * // which is equivalent to the following lines: * $model = new Foo(1, 2); * $model->c = 3; + * $model->init(); * ~~~ * * @return object the created object * @throws Exception if the configuration is invalid. */ - public static function create() + public static function newInstance() { - $class = '\\' . get_called_class(); + $c = get_called_class(); + $class = '\\' . $c; if (($n = func_num_args()) > 0) { $args = func_get_args(); - if (is_array($args[$n-1])) { - // the last parameter could be configuration array + if (is_array($args[$n - 1])) { $method = new \ReflectionMethod($class, '__construct'); - if ($method->getNumberOfParameters()+1 == $n) { - $config = $args[$n-1]; - array_pop($args); + if ($method->getNumberOfParameters() < $n) { + // the last EXTRA parameter is a configuration array + $config = $args[--$n]; + unset($args[$n]); } } - $config['class'] = $class; - array_unshift($args, $config); - return call_user_func_array('\Yii::create', $args); - } else { - return \Yii::create($class); } + + if ($n === 0) { + $object = new $class; + } + elseif ($n === 1) { + $object = new $class($args[0]); + } + elseif ($n === 2) { + $object = new $class($args[0], $args[1]); + } + elseif ($n === 3) { + $object = new $class($args[0], $args[1], $args[2]); + } + else { + $r = new \ReflectionClass($class); + $object = $r->newInstanceArgs($args); + } + + if (isset(\Yii::$objectConfig[$c])) { + $config = isset($config) ? array_merge(\Yii::$objectConfig[$c], $config) : \Yii::$objectConfig[$c]; + } + + if (!empty($config)) { + foreach ($config as $name => $value) { + $object->$name = $value; + } + } + + if ($object instanceof \yii\base\Initable) { + $object->init(); + } + + return $object; } } diff --git a/framework/base/Vector.php b/framework/base/Vector.php index bf010bb..b9e7c93 100644 --- a/framework/base/Vector.php +++ b/framework/base/Vector.php @@ -22,12 +22,12 @@ namespace yii\base; * like a regular PHP array as follows, * * ~~~ - * $vector[] = $item; // append new item at the end - * $vector[$index] = $item; // set new item at $index - * unset($vector[$index]); // remove the item at $index - * if (isset($vector[$index])) // if the vector has an item at $index + * $vector[] = $item; // append new item at the end + * $vector[$index] = $item; // set new item at $index + * unset($vector[$index]); // remove the item at $index + * if (isset($vector[$index])) // if the vector has an item at $index * foreach ($vector as $index=>$item) // traverse each item in the vector - * $n = count($vector); // count the number of items + * $n = count($vector); // count the number of items * ~~~ * * Note that if you plan to extend Vector by performing additional operations @@ -103,9 +103,11 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta { if (isset($this->_d[$index])) { return $this->_d[$index]; - } elseif ($index >= 0 && $index < $this->_c) { // in case the value is null + } + elseif ($index >= 0 && $index < $this->_c) { // in case the value is null return $this->_d[$index]; - } else { + } + else { throw new Exception('Index out of range: ' . $index); } } @@ -119,7 +121,7 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta public function add($item) { $this->insertAt($this->_c, $item); - return $this->_c-1; + return $this->_c - 1; } /** @@ -134,10 +136,12 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta { if ($index === $this->_c) { $this->_d[$this->_c++] = $item; - } elseif ($index >= 0 && $index < $this->_c) { + } + elseif ($index >= 0 && $index < $this->_c) { array_splice($this->_d, $index, 0, array($item)); $this->_c++; - } else { + } + else { throw new Exception('Index out of range: ' . $index); } } @@ -156,7 +160,8 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta if (($index = $this->indexOf($item)) >= 0) { $this->removeAt($index); return $index; - } else { + } + else { return false; } } @@ -173,12 +178,14 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta $this->_c--; if ($index === $this->_c) { return array_pop($this->_d); - } else { + } + else { $item = $this->_d[$index]; array_splice($this->_d, $index, 1); return $item; } - } else { + } + else { throw new Exception('Index out of range: ' . $index); } } @@ -192,10 +199,11 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta public function clear($safeClear = false) { if ($safeClear) { - for ($i = $this->_c-1;$i >= 0;--$i) { + for ($i = $this->_c - 1; $i >= 0; --$i) { $this->removeAt($i); } - } else { + } + else { $this->_d = array(); $this->_c = 0; } @@ -252,7 +260,8 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta foreach ($data as $item) { $this->add($item); } - } else { + } + else { throw new Exception('Data must be either an array or an object implementing Traversable.'); } } @@ -272,7 +281,8 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta foreach ($data as $item) { $this->add($item); } - } else { + } + else { throw new Exception('Data must be either an array or an object implementing Traversable.'); } } @@ -318,7 +328,8 @@ class Vector extends Object implements \IteratorAggregate, \ArrayAccess, \Counta { if ($offset === null || $offset === $this->_c) { $this->insertAt($this->_c, $item); - } else { + } + else { $this->removeAt($offset); $this->insertAt($offset, $item); } diff --git a/framework/db/dao/ColumnSchema.php b/framework/db/dao/ColumnSchema.php index 5e2c145..d6b457a 100644 --- a/framework/db/dao/ColumnSchema.php +++ b/framework/db/dao/ColumnSchema.php @@ -86,10 +86,10 @@ class ColumnSchema extends \yii\base\Component { static $typeMap = array( // logical type => php type 'smallint' => 'integer', - 'integer' => 'integer', - 'bigint' => 'integer', - 'boolean' => 'boolean', - 'float' => 'double', + 'integer' => 'integer', + 'bigint' => 'integer', + 'boolean' => 'boolean', + 'float' => 'double', ); if (isset($typeMap[$this->type])) { if ($this->type === 'bigint') { @@ -114,9 +114,12 @@ class ColumnSchema extends \yii\base\Component return $value; } switch ($this->phpType) { - case 'string': return (string)$value; - case 'integer': return (integer)$value; - case 'boolean': return (boolean)$value; + case 'string': + return (string)$value; + case 'integer': + return (integer)$value; + case 'boolean': + return (boolean)$value; } return $value; } diff --git a/framework/db/dao/Command.php b/framework/db/dao/Command.php index 7c44eb9..68ee314 100644 --- a/framework/db/dao/Command.php +++ b/framework/db/dao/Command.php @@ -38,10 +38,10 @@ use yii\db\Exception; * * ~~~ * $user = \Yii::app()->db->createCommand() - * ->select('username, password') - * ->from('tbl_user') - * ->where('id=:id', array(':id'=>1)) - * ->queryRow(); + * ->select('username, password') + * ->from('tbl_user') + * ->where('id=:id', array(':id'=>1)) + * ->queryRow(); * ~~~ * * @author Qiang Xue @@ -93,11 +93,13 @@ class Command extends \yii\base\Component $this->connection = $connection; if (is_object($query)) { $this->query = $query; - } else { + } + else { $this->query = new Query; if (is_array($query)) { $this->query->fromArray($query); - } else { + } + else { $this->_sql = $query; } } @@ -161,9 +163,10 @@ class Command extends \yii\base\Component $sql = $this->getSql(); try { $this->pdoStatement = $this->connection->pdo->prepare($sql); - } catch(\Exception $e) { + } + catch (\Exception $e) { \Yii::error($e->getMessage() . "\nFailed to prepare SQL: $sql", __CLASS__); - $errorInfo = $e instanceof \PDOException ? $e->errorInfo : null; + $errorInfo = $e instanceof \PDOException ? $e->errorInfo : null; throw new Exception($e->getMessage(), (int)$e->getCode(), $errorInfo); } } @@ -197,11 +200,14 @@ class Command extends \yii\base\Component $this->prepare(); if ($dataType === null) { $this->pdoStatement->bindParam($name, $value, $this->connection->getPdoType(gettype($value))); - } elseif ($length === null) { + } + elseif ($length === null) { $this->pdoStatement->bindParam($name, $value, $dataType); - } elseif ($driverOptions === null) { + } + elseif ($driverOptions === null) { $this->pdoStatement->bindParam($name, $value, $dataType, $length); - } else { + } + else { $this->pdoStatement->bindParam($name, $value, $dataType, $length, $driverOptions); } $this->_params[$name] =& $value; @@ -224,7 +230,8 @@ class Command extends \yii\base\Component $this->prepare(); if ($dataType === null) { $this->pdoStatement->bindValue($name, $value, $this->connection->getPdoType(gettype($value))); - } else { + } + else { $this->pdoStatement->bindValue($name, $value, $dataType); } $this->_params[$name] = $value; @@ -248,7 +255,7 @@ class Command extends \yii\base\Component /** * Executes the SQL statement. - * This method is meant only for executing non-query SQL statement, such as `INSERT`, `DELETE`, `UPDATE` SQLs. + * This method should only be used for executing non-query SQL statement, such as `INSERT`, `DELETE`, `UPDATE` SQLs. * No result set will be returned. * @param array $params input parameters (name=>value) for the SQL execution. This is an alternative * to [[bindValues]]. Note that if you pass parameters in this way, any previous call to [[bindParam]] @@ -263,8 +270,9 @@ class Command extends \yii\base\Component $this->_params = array_merge($this->_params, $params); if ($this->_params === array()) { $paramLog = ''; - } else { - $paramLog = "Parameters: " . var_export($this->_params, true); + } + else { + $paramLog = "\nParameters: " . var_export($this->_params, true); } \Yii::trace("Executing SQL: {$sql}{$paramLog}", __CLASS__); @@ -277,7 +285,8 @@ class Command extends \yii\base\Component $this->prepare(); if ($params === array()) { $this->pdoStatement->execute(); - } else { + } + else { $this->pdoStatement->execute($params); } $n = $this->pdoStatement->rowCount(); @@ -286,7 +295,8 @@ class Command extends \yii\base\Component \Yii::endProfile(__METHOD__ . "($sql)", __CLASS__); } return $n; - } catch (Exception $e) { + } + catch (Exception $e) { if ($this->connection->enableProfiling) { \Yii::endProfile(__METHOD__ . "($sql)", __CLASS__); } @@ -312,13 +322,13 @@ class Command extends \yii\base\Component } /** - * Executes the SQL statement and returns all rows. + * Executes the SQL statement and returns ALL rows at once. * @param array $params input parameters (name=>value) for the SQL execution. This is an alternative * to [[bindValues]]. Note that if you pass parameters in this way, any previous call to [[bindParam]] * or [[bindValue]] will be ignored. - * @param boolean $fetchAssociative whether each row should be returned as an associated array with - * column names as the keys or the array keys are column indexes (0-based). - * @return array all rows of the query result. Each array element is an array representing a row. + * @param mixed $fetchMode the result fetch mode. Please refer to [PHP manual](http://www.php.net/manual/en/function.PDOStatement-setFetchMode.php) + * for valid fetch modes. If this parameter is null, the value set in [[fetchMode]] will be used. + * @return array all rows of the query result. Each array element is an array representing a row of data. * An empty array is returned if the query results in nothing. * @throws Exception execution failed */ @@ -329,13 +339,14 @@ class Command extends \yii\base\Component /** * Executes the SQL statement and returns the first row of the result. - * This is a convenient method of {@link query} when only the first row of data is needed. + * This method is best used when only the first row of result is needed for a query. * @param array $params input parameters (name=>value) for the SQL execution. This is an alternative * to [[bindValues]]. Note that if you pass parameters in this way, any previous call to [[bindParam]] * or [[bindValue]] will be ignored. - * @param boolean $fetchAssociative whether the row should be returned as an associated array with - * column names as the keys or the array keys are column indexes (0-based). - * @return mixed the first row (in terms of an array) of the query result, false if no result. + * @param mixed $fetchMode the result fetch mode. Please refer to [PHP manual](http://www.php.net/manual/en/function.PDOStatement-setFetchMode.php) + * for valid fetch modes. If this parameter is null, the value set in [[fetchMode]] will be used. + * @return array|boolean the first row (in terms of an array) of the query result. False is returned if the query + * results in nothing. * @throws Exception execution failed */ public function queryRow($params = array(), $fetchMode = null) @@ -345,12 +356,12 @@ class Command extends \yii\base\Component /** * Executes the SQL statement and returns the value of the first column in the first row of data. - * This is a convenient method of {@link query} when only a single scalar - * value is needed (e.g. obtaining the count of the records). + * This method is best used when only a single value is needed for a query. * @param array $params input parameters (name=>value) for the SQL execution. This is an alternative * to [[bindValues]]. Note that if you pass parameters in this way, any previous call to [[bindParam]] * or [[bindValue]] will be ignored. - * @return mixed the value of the first column in the first row of the query result. False is returned if there is no value. + * @return mixed the value of the first column in the first row of the query result. + * False is returned if there is no value. * @throws Exception execution failed */ public function queryScalar($params = array()) @@ -366,12 +377,12 @@ class Command extends \yii\base\Component /** * Executes the SQL statement and returns the first column of the result. - * This is a convenient method of {@link query} when only the first column of data is needed. - * Note, the column returned will contain the first element in each row of result. + * This method is best used when only the first column of result (i.e. the first element in each row) + * is needed for a query. * @param array $params input parameters (name=>value) for the SQL execution. This is an alternative * to [[bindValues]]. Note that if you pass parameters in this way, any previous call to [[bindParam]] * or [[bindValue]] will be ignored. - * @return array the first column of the query result. Empty array if no result. + * @return array the first column of the query result. Empty array is returned if the query results in nothing. * @throws Exception execution failed */ public function queryColumn($params = array()) @@ -380,11 +391,13 @@ class Command extends \yii\base\Component } /** + * Performs the actual DB query of a SQL statement. * @param string $method method of PDOStatement to be called - * @param mixed $mode parameters to be passed to the method * @param array $params input parameters (name=>value) for the SQL execution. This is an alternative * to [[bindValues]]. Note that if you pass parameters in this way, any previous call to [[bindParam]] * or [[bindValue]] will be ignored. + * @param mixed $fetchMode the result fetch mode. Please refer to [PHP manual](http://www.php.net/manual/en/function.PDOStatement-setFetchMode.php) + * for valid fetch modes. If this parameter is null, the value set in [[fetchMode]] will be used. * @return mixed the method execution result */ private function queryInternal($method, $params, $fetchMode = null) @@ -395,21 +408,22 @@ class Command extends \yii\base\Component $this->_params = array_merge($this->_params, $params); if ($this->_params === array()) { $paramLog = ''; - } else { - $paramLog = "Parameters: " . var_export($this->_params, true); + } + else { + $paramLog = "\nParameters: " . var_export($this->_params, true); } \Yii::trace("Querying SQL: {$sql}{$paramLog}", __CLASS__); - $cachingEnabled = $db->queryCachingCount > 0 && $method !== '' - && $db->queryCachingDuration >= 0 - && ($cache = \Yii::app()->getComponent($db->queryCacheID)) !== null; - if ($cachingEnabled) { + if ($db->queryCachingCount > 0 && $db->queryCachingDuration >= 0 && $method !== '') { + $cache = \Yii::app()->getComponent($db->queryCacheID); + } + + if (isset($cache)) { $db->queryCachingCount--; - $cacheKey = 'yii:dbquery' . $db->connectionString . ':' . $db->username; - $cacheKey .= ':' . $sql . ':' . $paramLog; + $cacheKey = __CLASS__ . "/{$db->dsn}/{$db->username}/$sql/$paramLog"; if (($result = $cache->get($cacheKey)) !== false) { - \Yii::trace('Query result found in cache', 'system.db.Command'); + \Yii::trace('Query result found in cache', __CLASS__); return $result; } } @@ -422,13 +436,15 @@ class Command extends \yii\base\Component $this->prepare(); if ($params === array()) { $this->pdoStatement->execute(); - } else { + } + else { $this->pdoStatement->execute($params); } if ($method === '') { $result = new DataReader($this); - } else { + } + else { if ($fetchMode === null) { $fetchMode = $this->fetchMode; } @@ -440,58 +456,46 @@ class Command extends \yii\base\Component \Yii::endProfile(__METHOD__ . "($sql)", __CLASS__); } - if ($cachingEnabled) { + if (isset($cache)) { $cache->set($cacheKey, $result, $db->queryCachingDuration, $db->queryCachingDependency); + \Yii::trace('Saved query result in cache', __CLASS__); } return $result; - } catch (Exception $e) { + } + catch (Exception $e) { if ($db->enableProfiling) { \Yii::endProfile(__METHOD__ . "($sql)", __CLASS__); } - $errorInfo = $e instanceof \PDOException ? $e->errorInfo : null; $message = $e->getMessage(); - \Yii::log(\Yii::t('yii', 'Command::{method}() failed: {error}. The SQL statement executed was: {sql}.', - array('{method}' => $method, '{error}' => $message, '{sql}' => $this->getSql() . $par)), CLogger::LEVEL_ERROR, 'system.db.Command'); - if (YII_DEBUG) { - $message .= '. The SQL statement executed was: ' . $this->getSql() . $par; - } - throw new Exception(\Yii::t('yii', 'Command failed to execute the SQL statement: {error}', - array('{error}' => $message)), (int)$e->getCode(), $errorInfo); + \Yii::error("$message\nCommand::$method() failed: {$sql}{$paramLog}", __CLASS__); + $errorInfo = $e instanceof \PDOException ? $e->errorInfo : null; + throw new Exception($message, (int)$e->getCode(), $errorInfo); } } /** + /** * Sets the SELECT part of the query. * @param mixed $columns the columns to be selected. Defaults to '*', meaning all columns. * Columns can be specified in either a string (e.g. "id, name") or an array (e.g. array('id', 'name')). * Columns can contain table prefixes (e.g. "tbl_user.id") and/or column aliases (e.g. "tbl_user.id AS user_id"). * The method will automatically quote the column names unless a column contains some parenthesis * (which means the column contains a DB expression). + * @param boolean $distinct whether to use 'SELECT DISTINCT'. * @param string $option additional option that should be appended to the 'SELECT' keyword. For example, - * in MySQL, the option 'SQL_CALC_FOUND_ROWS' can be used. This parameter is supported since version 1.1.8. + * in MySQL, the option 'SQL_CALC_FOUND_ROWS' can be used. * @return Command the command object itself */ - public function select($columns = '*', $option = '') + public function select($columns = '*', $distinct = false, $option = '') { $this->query->select = $columns; + $this->query->distinct = $distinct; $this->query->selectOption = $option; return $this; } /** - * Sets the SELECT part of the query with the DISTINCT flag turned on. - * This is the same as {@link select} except that the DISTINCT flag is turned on. - * @param mixed $columns the columns to be selected. See {@link select} for more details. - * @return Command the command object itself - */ - public function selectDistinct($columns = '*', $option = '') - { - $this->query->distinct = true; - return $this->select($columns, $option); - } - - /** * Sets the FROM part of the query. * @param mixed $tables the table(s) to be selected from. This can be either a string (e.g. 'tbl_user') * or an array (e.g. array('tbl_user', 'tbl_profile')) specifying one or several table names. @@ -513,32 +517,42 @@ class Command extends \yii\base\Component * specifying the values to be bound to the query. * * The $conditions parameter should be either a string (e.g. 'id=1') or an array. - * If the latter, it must be of the format array(operator, operand1, operand2, ...), + * If the latter, it must be in the format `array(operator, operand1, operand2, ...)`, * where the operator can be one of the followings, and the possible operands depend on the corresponding * operator: - *
    - *
  • and: the operands should be concatenated together using AND. For example, - * array('and', 'id=1', 'id=2') will generate 'id=1 AND id=2'. If an operand is an array, - * it will be converted into a string using the same rules described here. For example, - * array('and', 'type=1', array('or', 'id=1', 'id=2')) will generate 'type=1 AND (id=1 OR id=2)'. - * The method will NOT do any quoting or escaping.
  • - *
  • or: similar as the and operator except that the operands are concatenated using OR.
  • - *
  • in: operand 1 should be a column or DB expression, and operand 2 be an array representing + * + * - `and`: the operands should be concatenated together using `AND`. For example, + * `array('and', 'id=1', 'id=2')` will generate `id=1 AND id=2`. If an operand is an array, + * it will be converted into a string using the rules described here. For example, + * `array('and', 'type=1', array('or', 'id=1', 'id=2'))` will generate `type=1 AND (id=1 OR id=2)`. + * The method will NOT do any quoting or escaping. + * + * - `or`: similar to the `and` operator except that the operands are concatenated using `OR`. + * + * - `in`: operand 1 should be a column or DB expression, and operand 2 be an array representing * the range of the values that the column or DB expression should be in. For example, - * array('in', 'id', array(1,2,3)) will generate 'id IN (1,2,3)'. - * The method will properly quote the column name and escape values in the range.
  • - *
  • not in: similar as the in operator except that IN is replaced with NOT IN in the generated condition.
  • - *
  • like: operand 1 should be a column or DB expression, and operand 2 be a string or an array representing + * `array('in', 'id', array(1,2,3))` will generate `id IN (1,2,3)`. + * The method will properly quote the column name and escape values in the range. + * + * - `not in`: similar to the `in` operator except that `IN` is replaced with `NOT IN` in the generated condition. + * + * - `like`: operand 1 should be a column or DB expression, and operand 2 be a string or an array representing * the values that the column or DB expression should be like. - * For example, array('like', 'name', '%tester%') will generate "name LIKE '%tester%'". - * When the value range is given as an array, multiple LIKE predicates will be generated and concatenated using AND. - * For example, array('like', 'name', array('%test%', '%sample%')) will generate - * "name LIKE '%test%' AND name LIKE '%sample%'". - * The method will properly quote the column name and escape values in the range.
  • - *
  • not like: similar as the like operator except that LIKE is replaced with NOT LIKE in the generated condition.
  • - *
  • or like: similar as the like operator except that OR is used to concatenated the LIKE predicates.
  • - *
  • or not like: similar as the not like operator except that OR is used to concatenated the NOT LIKE predicates.
  • - *
+ * For example, `array('like', 'name', '%tester%')` will generate `name LIKE '%tester%'`. + * When the value range is given as an array, multiple `LIKE` predicates will be generated and concatenated + * using `AND`. For example, `array('like', 'name', array('%test%', '%sample%'))` will generate + * `name LIKE '%test%' AND name LIKE '%sample%'`. + * The method will properly quote the column name and escape values in the range. + * + * - `or like`: similar to the `like` operator except that `OR` is used to concatenate the `LIKE` + * predicates when operand 2 is an array. + * + * - `not like`: similar to the `like` operator except that `LIKE` is replaced with `NOT LIKE` + * in the generated condition. + * + * - `or not like`: similar to the `not like` operator except that `OR` is used to concatenate + * the `NOT LIKE` predicates. + * * @param mixed $conditions the conditions that should be put in the WHERE part. * @param array $params the parameters (name=>value) to be bound to the query * @return Command the command object itself @@ -557,7 +571,7 @@ class Command extends \yii\base\Component * The method will automatically quote the table name unless it contains some parenthesis * (which means the table is given as a sub-query or DB expression). * @param mixed $conditions the join condition that should appear in the ON part. - * Please refer to {@link where} on how to specify conditions. + * Please refer to [[where]] on how to specify this parameter. * @param array $params the parameters (name=>value) to be bound to the query * @return Command the command object itself */ @@ -573,7 +587,7 @@ class Command extends \yii\base\Component * The method will automatically quote the table name unless it contains some parenthesis * (which means the table is given as a sub-query or DB expression). * @param mixed $conditions the join condition that should appear in the ON part. - * Please refer to {@link where} on how to specify conditions. + * Please refer to [[where]] on how to specify this parameter. * @param array $params the parameters (name=>value) to be bound to the query * @return Command the command object itself */ @@ -589,7 +603,7 @@ class Command extends \yii\base\Component * The method will automatically quote the table name unless it contains some parenthesis * (which means the table is given as a sub-query or DB expression). * @param mixed $conditions the join condition that should appear in the ON part. - * Please refer to {@link where} on how to specify conditions. + * Please refer to [[where]] on how to specify this parameter. * @param array $params the parameters (name=>value) to be bound to the query * @return Command the command object itself */ @@ -643,7 +657,7 @@ class Command extends \yii\base\Component /** * Sets the HAVING part of the query. * @param mixed $conditions the conditions to be put after HAVING. - * Please refer to {@link where} on how to specify conditions. + * Please refer to [[where]] on how to specify this parameter. * @param array $params the parameters (name=>value) to be bound to the query * @return Command the command object itself */ @@ -719,8 +733,8 @@ class Command extends \yii\base\Component * The method will properly escape the column names and bind the values to be updated. * @param string $table the table to be updated. * @param array $columns the column data (name=>value) to be updated. - * @param mixed $conditions the conditions that will be put in the WHERE part. Please - * refer to {@link where} on how to specify conditions. + * @param mixed $conditions the conditions that will be put in the WHERE part. + * Please refer to [[where]] on how to specify this parameter. * @param array $params the parameters to be bound to the query. * @return integer number of rows affected by the execution. */ @@ -733,8 +747,8 @@ class Command extends \yii\base\Component /** * Creates and executes a DELETE SQL statement. * @param string $table the table where the data will be deleted from. - * @param mixed $conditions the conditions that will be put in the WHERE part. Please - * refer to {@link where} on how to specify conditions. + * @param mixed $conditions the conditions that will be put in the WHERE part. + * Please refer to [[where]] on how to specify this parameter. * @param array $params the parameters to be bound to the query. * @return integer number of rows affected by the execution. */ @@ -750,7 +764,9 @@ class Command extends \yii\base\Component * The columns in the new table should be specified as name-definition pairs (e.g. 'name'=>'string'), * where name stands for a column name which will be properly quoted by the method, and definition * stands for the column type which can contain an abstract DB type. - * The {@link getColumnType} method will be invoked to convert any abstract type into a physical one. + * The method [[\yii\db\dao\QueryBuilder::getColumnType()]] will be called + * to convert the abstract column types to physical ones. For example, `string` will be converted + * as `varchar(255)`, and `string not null` becomes `varchar(255) not null`. * * If a column is specified with definition only (e.g. 'PRIMARY KEY (name, type)'), it will be directly * inserted into the generated SQL. @@ -804,9 +820,9 @@ class Command extends \yii\base\Component * Builds and executes a SQL statement for adding a new DB column. * @param string $table the table that the new column will be added to. The table name will be properly quoted by the method. * @param string $column the name of the new column. The name will be properly quoted by the method. - * @param string $type the column type. The {@link getColumnType} method will be invoked to convert abstract column type (if any) - * into the physical one. Anything that is not recognized as abstract type will be kept in the generated SQL. - * For example, 'string' will be turned into 'varchar(255)', while 'string not null' will become 'varchar(255) not null'. + * @param string $type the column type. [[\yii\db\dao\QueryBuilder::getColumnType()]] will be called + * to convert the give column type to the physical one. For example, `string` will be converted + * as `varchar(255)`, and `string not null` becomes `varchar(255) not null`. * @return integer number of rows affected by the execution. */ public function addColumn($table, $column, $type) @@ -844,9 +860,9 @@ class Command extends \yii\base\Component * Builds and executes a SQL statement for changing the definition of a column. * @param string $table the table whose column is to be changed. The table name will be properly quoted by the method. * @param string $column the name of the column to be changed. The name will be properly quoted by the method. - * @param string $type the new column type. The {@link getColumnType} method will be invoked to convert abstract column type (if any) - * into the physical one. Anything that is not recognized as abstract type will be kept in the generated SQL. - * For example, 'string' will be turned into 'varchar(255)', while 'string not null' will become 'varchar(255) not null'. + * @param string $type the column type. [[\yii\db\dao\QueryBuilder::getColumnType()]] will be called + * to convert the give column type to the physical one. For example, `string` will be converted + * as `varchar(255)`, and `string not null` becomes `varchar(255) not null`. * @return integer number of rows affected by the execution. */ public function alterColumn($table, $column, $type) @@ -920,7 +936,7 @@ class Command extends \yii\base\Component * The method will automatically quote the table name unless it contains some parenthesis * (which means the table is given as a sub-query or DB expression). * @param mixed $conditions the join condition that should appear in the ON part. - * Please refer to {@link where} on how to specify conditions. + * Please refer to [[where]] on how to specify this parameter. * @param array $params the parameters (name=>value) to be bound to the query * @return Command the command object itself */ diff --git a/framework/db/dao/Connection.php b/framework/db/dao/Connection.php index 9b74d37..fc7a535 100644 --- a/framework/db/dao/Connection.php +++ b/framework/db/dao/Connection.php @@ -26,7 +26,7 @@ use yii\db\Exception; * the DB connection: * * ~~~ - * $connection = \yii\db\dao\Connection::create($dsn, $username, $password); + * $connection = \yii\db\dao\Connection::newInstance($dsn, $username, $password); * $connection->active = true; // same as: $connection->open(); * ~~~ * @@ -57,13 +57,13 @@ use yii\db\Exception; * ~~~ * $transaction = $connection->beginTransaction(); * try { - * $connection->createCommand($sql1)->execute(); - * $connection->createCommand($sql2)->execute(); - * // ... executing other SQL statements ... - * $transaction->commit(); + * $connection->createCommand($sql1)->execute(); + * $connection->createCommand($sql2)->execute(); + * // ... executing other SQL statements ... + * $transaction->commit(); * } * catch(Exception $e) { - * $transaction->rollBack(); + * $transaction->rollBack(); * } * ~~~ * @@ -72,15 +72,15 @@ use yii\db\Exception; * * ~~~ * array( - * 'components' => array( - * 'db' => array( - * 'class' => '\yii\db\dao\Connection', - * 'dsn' => 'mysql:host=127.0.0.1;dbname=demo', - * 'username' => 'root', - * 'password' => '', - * 'charset' => 'utf8', - * ), - * ), + * 'components' => array( + * 'db' => array( + * 'class' => '\yii\db\dao\Connection', + * 'dsn' => 'mysql:host=127.0.0.1;dbname=demo', + * 'username' => 'root', + * 'password' => '', + * 'charset' => 'utf8', + * ), + * ), * ) * ~~~ * @@ -219,7 +219,7 @@ class Connection extends \yii\base\ApplicationComponent /** * @var array mapping between PDO driver names and [[Schema]] classes. * The keys of the array are PDO driver names while the values the corresponding - * schema class name or configuration. Please refer to [[\Yii::create]] for + * schema class name or configuration. Please refer to [[\Yii::createObject]] for * details on how to specify a configuration. * * This property is mainly used by [[getSchema]] when fetching the database schema information. @@ -227,15 +227,15 @@ class Connection extends \yii\base\ApplicationComponent * [[Schema]] class to support DBMS that is not supported by Yii. */ public $schemaMap = array( - 'pgsql' => '\yii\db\dao\pgsql\Schema', // PostgreSQL - 'mysqli' => '\yii\db\dao\mysql\Schema', // MySQL - 'mysql' => '\yii\db\dao\mysql\Schema', // MySQL - 'sqlite' => '\yii\db\dao\sqlite\Schema', // sqlite 3 - 'sqlite2' => '\yii\db\dao\sqlite\Schema', // sqlite 2 - 'mssql' => '\yii\db\dao\mssql\Schema', // Mssql driver on windows hosts - 'dblib' => '\yii\db\dao\mssql\Schema', // dblib drivers on linux (and maybe others os) hosts - 'sqlsrv' => '\yii\db\dao\mssql\Schema', // Mssql - 'oci' => '\yii\db\dao\oci\Schema', // Oracle driver + 'pgsql' => '\yii\db\dao\pgsql\Schema', // PostgreSQL + 'mysqli' => '\yii\db\dao\mysql\Schema', // MySQL + 'mysql' => '\yii\db\dao\mysql\Schema', // MySQL + 'sqlite' => '\yii\db\dao\sqlite\Schema', // sqlite 3 + 'sqlite2' => '\yii\db\dao\sqlite\Schema', // sqlite 2 + 'mssql' => '\yii\db\dao\mssql\Schema', // Mssql driver on windows hosts + 'dblib' => '\yii\db\dao\mssql\Schema', // dblib drivers on linux (and maybe others os) hosts + 'sqlsrv' => '\yii\db\dao\mssql\Schema', // Mssql + 'oci' => '\yii\db\dao\oci\Schema', // Oracle driver ); /** @@ -428,7 +428,8 @@ class Connection extends \yii\base\ApplicationComponent { if ($this->_transaction !== null && $this->_transaction->active) { return $this->_transaction; - } else { + } + else { return null; } } @@ -453,11 +454,13 @@ class Connection extends \yii\base\ApplicationComponent { if ($this->_schema !== null) { return $this->_schema; - } else { + } + else { $driver = $this->getDriverName(); if (isset($this->schemaMap[$driver])) { - return $this->_schema = \Yii::create($this->schemaMap[$driver], $this); - } else { + return $this->_schema = \Yii::createObject($this->schemaMap[$driver], $this); + } + else { throw new Exception("Connection does not support reading schema for '$driver' database."); } } @@ -500,7 +503,8 @@ class Connection extends \yii\base\ApplicationComponent $this->open(); if (($value = $this->pdo->quote($str)) !== false) { return $value; - } else { // the driver doesn't support quote (e.g. oci) + } + else { // the driver doesn't support quote (e.g. oci) return "'" . addcslashes(str_replace("'", "''", $str), "\000\n\r\\\032") . "'"; } } @@ -542,7 +546,8 @@ class Connection extends \yii\base\ApplicationComponent { if ($this->tablePrefix !== null && strpos($sql, '{{') !== false) { return preg_replace('/{{(.*?)}}/', $this->tablePrefix . '\1', $sql); - } else { + } + else { return $sql; } } @@ -572,7 +577,8 @@ class Connection extends \yii\base\ApplicationComponent { if (($pos = strpos($this->dsn, ':')) !== false) { return strtolower(substr($this->dsn, 0, $pos)); - } else { + } + else { return strtolower($this->getAttribute(\PDO::ATTR_DRIVER_NAME)); } } diff --git a/framework/db/dao/DataReader.php b/framework/db/dao/DataReader.php index ccb437e..0333397 100644 --- a/framework/db/dao/DataReader.php +++ b/framework/db/dao/DataReader.php @@ -22,7 +22,7 @@ use yii\db\Exception; * * ~~~ * foreach($reader as $row) { - * // $row represents a row of data + * // $row represents a row of data * } * ~~~ * diff --git a/framework/db/dao/Query.php b/framework/db/dao/Query.php index b65d2c7..73e3653 100644 --- a/framework/db/dao/Query.php +++ b/framework/db/dao/Query.php @@ -102,10 +102,10 @@ class Query extends \yii\base\Object } if ($this->select !== $query->select) { - if($this->select === '*') { + if ($this->select === '*') { $this->select = $query->select; } - elseif($query->select!=='*') { + elseif ($query->select !== '*') { $select1 = is_string($this->select) ? preg_split('/\s*,\s*/', trim($this->select), -1, PREG_SPLIT_NO_EMPTY) : $this->select; $select2 = is_string($query->select) ? preg_split('/\s*,\s*/', trim($query->select), -1, PREG_SPLIT_NO_EMPTY) : $query->select; $this->select = array_merge($select1, array_diff($select2, $select1)); @@ -238,16 +238,19 @@ class Query extends \yii\base\Object */ public function addCondition($condition, $operator = 'AND') { - if (is_array($condition)) - { - if ($condition === array()) + if (is_array($condition)) { + if ($condition === array()) { return $this; + } $condition = '(' . implode(') ' . $operator . ' (', $condition) . ')'; } - if ($this->condition === '') + if ($this->condition === '') { $this->condition = $condition; + } else + { $this->condition = '(' . $this->condition . ') ' . $operator . ' (' . $condition . ')'; + } return $this; } @@ -271,10 +274,12 @@ class Query extends \yii\base\Object */ public function addSearchCondition($column, $keyword, $escape = true, $operator = 'AND', $like = 'LIKE') { - if ($keyword == '') + if ($keyword == '') { return $this; - if ($escape) + } + if ($escape) { $keyword = '%' . strtr($keyword, array('%' => '\%', '_' => '\_', '\\' => '\\\\')) . '%'; + } $condition = $column . " $like " . self::PARAM_PREFIX . self::$paramCount; $this->params[self::PARAM_PREFIX . self::$paramCount++] = $keyword; return $this->addCondition($condition, $operator); @@ -294,13 +299,14 @@ class Query extends \yii\base\Object */ public function addInCondition($column, $values, $operator = 'AND') { - if (($n = count($values)) < 1) - return $this->addCondition('0=1', $operator); // 0=1 is used because in MSSQL value alone can't be used in WHERE - if ($n === 1) - { + if (($n = count($values)) < 1) { + return $this->addCondition('0=1', $operator); + } // 0=1 is used because in MSSQL value alone can't be used in WHERE + if ($n === 1) { $value = reset($values); - if ($value === null) + if ($value === null) { return $this->addCondition($column . ' IS NULL'); + } $condition = $column . '=' . self::PARAM_PREFIX . self::$paramCount; $this->params[self::PARAM_PREFIX . self::$paramCount++] = $value; } @@ -331,13 +337,14 @@ class Query extends \yii\base\Object */ public function addNotInCondition($column, $values, $operator = 'AND') { - if (($n = count($values)) < 1) + if (($n = count($values)) < 1) { return $this; - if ($n === 1) - { + } + if ($n === 1) { $value = reset($values); - if ($value === null) + if ($value === null) { return $this->addCondition($column . ' IS NOT NULL'); + } $condition = $column . '!=' . self::PARAM_PREFIX . self::$paramCount; $this->params[self::PARAM_PREFIX . self::$paramCount++] = $value; } @@ -370,8 +377,9 @@ class Query extends \yii\base\Object $params = array(); foreach ($columns as $name => $value) { - if ($value === null) + if ($value === null) { $params[] = $name . ' IS NULL'; + } else { $params[] = $name . '=' . self::PARAM_PREFIX . self::$paramCount; @@ -426,35 +434,42 @@ class Query extends \yii\base\Object */ public function compare($column, $value, $partialMatch = false, $operator = 'AND', $escape = true) { - if (is_array($value)) - { - if ($value === array()) + if (is_array($value)) { + if ($value === array()) { return $this; + } return $this->addInCondition($column, $value, $operator); } else + { $value = "$value"; + } - if (preg_match('/^(?:\s*(<>|<=|>=|<|>|=))?(.*)$/', $value, $matches)) - { + if (preg_match('/^(?:\s*(<>|<=|>=|<|>|=))?(.*)$/', $value, $matches)) { $value = $matches[2]; $op = $matches[1]; } else + { $op = ''; + } - if ($value === '') + if ($value === '') { return $this; + } - if ($partialMatch) - { - if ($op === '') + if ($partialMatch) { + if ($op === '') { return $this->addSearchCondition($column, $value, $escape, $operator); - if ($op === '<>') + } + if ($op === '<>') { return $this->addSearchCondition($column, $value, $escape, $operator, 'NOT LIKE'); + } } elseif ($op === '') + { $op = '='; + } $this->addCondition($column . $op . self::PARAM_PREFIX . self::$paramCount, $operator); $this->params[self::PARAM_PREFIX . self::$paramCount++] = $value; @@ -479,8 +494,9 @@ class Query extends \yii\base\Object */ public function addBetweenCondition($column, $valueStart, $valueEnd, $operator = 'AND') { - if ($valueStart === '' || $valueEnd === '') + if ($valueStart === '' || $valueEnd === '') { return $this; + } $paramStart = self::PARAM_PREFIX . self::$paramCount++; $paramEnd = self::PARAM_PREFIX . self::$paramCount++; @@ -488,10 +504,13 @@ class Query extends \yii\base\Object $this->params[$paramEnd] = $valueEnd; $condition = "$column BETWEEN $paramStart AND $paramEnd"; - if ($this->condition === '') + if ($this->condition === '') { $this->condition = $condition; + } else + { $this->condition = '(' . $this->condition . ') ' . $operator . ' (' . $condition . ')'; + } return $this; } diff --git a/framework/db/dao/QueryBuilder.php b/framework/db/dao/QueryBuilder.php index 0fc53bf..71badca 100644 --- a/framework/db/dao/QueryBuilder.php +++ b/framework/db/dao/QueryBuilder.php @@ -23,21 +23,21 @@ class QueryBuilder extends \yii\base\Object /** * @var array the abstract column types mapped to physical column types. */ - public $typeMap = array( - 'pk' => 'int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY', - 'string' => 'varchar(255)', - 'text' => 'text', - 'integer' => 'int(11)', - 'float' => 'float', - 'decimal' => 'decimal', - 'datetime' => 'datetime', - 'timestamp' => 'timestamp', - 'time' => 'time', - 'date' => 'date', - 'binary' => 'blob', - 'boolean' => 'tinyint(1)', + public $typeMap = array( + 'pk' => 'int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY', + 'string' => 'varchar(255)', + 'text' => 'text', + 'integer' => 'int(11)', + 'float' => 'float', + 'decimal' => 'decimal', + 'datetime' => 'datetime', + 'timestamp' => 'timestamp', + 'time' => 'time', + 'date' => 'date', + 'binary' => 'blob', + 'boolean' => 'tinyint(1)', 'money' => 'decimal(19,4)', - ); + ); /** * @var Connection the database connection. */ @@ -177,7 +177,9 @@ class QueryBuilder extends \yii\base\Object $cols[] = "\t" . $this->schema->quoteColumnName($name) . ' ' . $this->schema->getColumnType($type); } else + { $cols[] = "\t" . $type; + } } $sql = "CREATE TABLE " . $this->schema->quoteTableName($table) . " (\n" . implode(",\n", $cols) . "\n)"; return $options === null ? $sql : $sql . ' ' . $options; @@ -288,20 +290,24 @@ class QueryBuilder extends \yii\base\Object public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete = null, $update = null) { $columns = preg_split('/\s*,\s*/', $columns, -1, PREG_SPLIT_NO_EMPTY); - foreach ($columns as $i => $col) + foreach ($columns as $i => $col) { $columns[$i] = $this->schema->quoteColumnName($col); + } $refColumns = preg_split('/\s*,\s*/', $refColumns, -1, PREG_SPLIT_NO_EMPTY); - foreach ($refColumns as $i => $col) + foreach ($refColumns as $i => $col) { $refColumns[$i] = $this->schema->quoteColumnName($col); + } $sql = 'ALTER TABLE ' . $this->schema->quoteTableName($table) . ' ADD CONSTRAINT ' . $this->schema->quoteColumnName($name) . ' FOREIGN KEY (' . implode(', ', $columns) . ')' . ' REFERENCES ' . $this->schema->quoteTableName($refTable) . ' (' . implode(', ', $refColumns) . ')'; - if ($delete !== null) + if ($delete !== null) { $sql .= ' ON DELETE ' . $delete; - if ($update !== null) + } + if ($update !== null) { $sql .= ' ON UPDATE ' . $update; + } return $sql; } @@ -332,10 +338,13 @@ class QueryBuilder extends \yii\base\Object $columns = preg_split('/\s*,\s*/', $column, -1, PREG_SPLIT_NO_EMPTY); foreach ($columns as $col) { - if (strpos($col, '(') !== false) + if (strpos($col, '(') !== false) { $cols[] = $col; + } else + { $cols[] = $this->schema->quoteColumnName($col); + } } return ($unique ? 'CREATE UNIQUE INDEX ' : 'CREATE INDEX ') . $this->schema->quoteTableName($name) . ' ON ' @@ -400,8 +409,8 @@ class QueryBuilder extends \yii\base\Object * @param string $type abstract column type * @return string physical column type. */ - public function getColumnType($type) - { + public function getColumnType($type) + { if (isset($this->typeMap[$type])) { return $this->typeMap[$type]; } @@ -485,19 +494,19 @@ class QueryBuilder extends \yii\base\Object } foreach ($joins as $i => $join) { - if (is_array($join)) { // join type, table name, on-condition + if (is_array($join)) { // join type, table name, on-condition if (isset($join[0], $join[1])) { $table = $join[1]; - if (strpos($table,'(')===false) { - if (preg_match('/^(.*?)(?i:\s+as\s+|\s+)(.*)$/', $table, $matches)) { // with alias - $table = $this->connection->quoteTableName($matches[1]).' '.$this->connection->quoteTableName($matches[2]); + if (strpos($table, '(') === false) { + if (preg_match('/^(.*?)(?i:\s+as\s+|\s+)(.*)$/', $table, $matches)) { // with alias + $table = $this->connection->quoteTableName($matches[1]) . ' ' . $this->connection->quoteTableName($matches[2]); } else { $table = $this->connection->quoteTableName($table); } } $joins[$i] = strtoupper($join[0]) . ' ' . $table; - if (isset($join[2])) { // join condition + if (isset($join[2])) { // join condition $condition = $this->buildCondition($join[2]); $joins[$i] .= ' ON ' . $condition; } @@ -582,8 +591,8 @@ class QueryBuilder extends \yii\base\Object if ($query->limit !== null && $query->limit >= 0) { $sql = 'LIMIT ' . (int)$query->limit; } - if ($query->offset>0) { - $sql .= ' OFFSET '.(int)$query->offset; + if ($query->offset > 0) { + $sql .= ' OFFSET ' . (int)$query->offset; } return ltrim($sql); } diff --git a/framework/db/dao/Schema.php b/framework/db/dao/Schema.php index f5fdd6d..d96bd6c 100644 --- a/framework/db/dao/Schema.php +++ b/framework/db/dao/Schema.php @@ -20,6 +20,9 @@ use yii\db\Exception; */ abstract class Schema extends \yii\base\Object { + /** + * @var \yii\db\dao\Connection the database connection + */ public $connection; private $_tableNames = array(); @@ -194,7 +197,9 @@ abstract class Schema extends \yii\base\Object $name = substr($name, $pos + 1); } else + { $prefix = ''; + } return $prefix . $this->quoteSimpleColumnName($name); } diff --git a/framework/db/dao/TableSchema.php b/framework/db/dao/TableSchema.php index 5904000..6ad64db 100644 --- a/framework/db/dao/TableSchema.php +++ b/framework/db/dao/TableSchema.php @@ -55,9 +55,9 @@ class TableSchema extends \yii\base\Object * * ~~~ * array( - * 'ForeignTableName', - * 'fk1' => 'pk1', // pk1 is in foreign table - * 'fk2' => 'pk2', // if composite foreign key + * 'ForeignTableName', + * 'fk1' => 'pk1', // pk1 is in foreign table + * 'fk2' => 'pk2', // if composite foreign key * ) * ~~~ */ diff --git a/framework/db/dao/Transaction.php b/framework/db/dao/Transaction.php index eaba4af..c4df4dc 100644 --- a/framework/db/dao/Transaction.php +++ b/framework/db/dao/Transaction.php @@ -23,13 +23,13 @@ use yii\db\Exception; * ~~~ * $transaction = $connection->beginTransaction(); * try { - * $connection->createCommand($sql1)->execute(); - * $connection->createCommand($sql2)->execute(); - * //.... other SQL executions - * $transaction->commit(); + * $connection->createCommand($sql1)->execute(); + * $connection->createCommand($sql2)->execute(); + * //.... other SQL executions + * $transaction->commit(); * } * catch(Exception $e) { - * $transaction->rollBack(); + * $transaction->rollBack(); * } * ~~~ * @@ -69,7 +69,8 @@ class Transaction extends \yii\base\Object \Yii::trace('Committing transaction', __CLASS__); $this->connection->pdo->commit(); $this->active = false; - } else { + } + else { throw new Exception('Failed to commit transaction: transaction was inactive.'); } } @@ -84,7 +85,8 @@ class Transaction extends \yii\base\Object \Yii::trace('Rolling back transaction', __CLASS__); $this->connection->pdo->rollBack(); $this->active = false; - } else { + } + else { throw new Exception('Failed to roll back transaction: transaction was inactive.'); } } diff --git a/framework/logging/Logger.php b/framework/logging/Logger.php index 1c64e61..5fd11a2 100644 --- a/framework/logging/Logger.php +++ b/framework/logging/Logger.php @@ -22,12 +22,12 @@ namespace yii\logging; */ class Logger extends \yii\base\Component { - const LEVEL_ERROR = 1; - const LEVEL_WARNING = 2; - const LEVEL_INFO = 3; - const LEVEL_TRACE = 4; - const LEVEL_PROFILE_BEGIN = 5; - const LEVEL_PROFILE_END = 6; + const LEVEL_ERROR = 'error'; + const LEVEL_WARNING = 'warning'; + const LEVEL_INFO = 'info'; + const LEVEL_TRACE = 'trace'; + const LEVEL_PROFILE_BEGIN = 'profile-begin'; + const LEVEL_PROFILE_END = 'profile-end'; /** * @var integer how many messages should be logged before they are flushed from memory and sent to targets. @@ -253,13 +253,10 @@ class Logger extends \yii\base\Component $stack = array(); foreach ($this->messages as $log) { - if ($log[1] < self::LEVEL_PROFILE_BEGIN) { - continue; - } - list($token, $level, $category, $timestamp) = $log; - if ($level === self::LEVEL_PROFILE_BEGIN) { + if ($log[1] === self::LEVEL_PROFILE_BEGIN) { $stack[] = $log; - } else { + } elseif ($log[1] === self::LEVEL_PROFILE_END) { + list($token, $level, $category, $timestamp) = $log; if (($last = array_pop($stack)) !== null && $last[0] === $token) { $timings[] = array($token, $category, $timestamp - $last[3]); } else { diff --git a/framework/logging/Router.php b/framework/logging/Router.php index 8825efc..5676643 100644 --- a/framework/logging/Router.php +++ b/framework/logging/Router.php @@ -101,7 +101,7 @@ class Router extends \yii\base\ApplicationComponent * Sets the log targets. * @param array $config list of log target configurations. Each array element * represents the configuration for creating a single log target. It will be - * passed to [[\Yii::create]] to create the target instance. + * passed to [[\Yii::createObject]] to create the target instance. */ public function setTargets($config) { @@ -110,7 +110,7 @@ class Router extends \yii\base\ApplicationComponent $this->_targets[$name] = $target; } else { - $this->_targets[$name] = \Yii::create($target); + $this->_targets[$name] = \Yii::createObject($target); } } } diff --git a/framework/validators/Validator.php b/framework/validators/Validator.php index bba109a..e695b5d 100644 --- a/framework/validators/Validator.php +++ b/framework/validators/Validator.php @@ -166,7 +166,7 @@ abstract class Validator extends \yii\base\Component foreach ($params as $name => $value) { $config[$name] = $value; } - $validator = \Yii::create($config); + $validator = \Yii::createObject($config); return $validator; } diff --git a/tests/unit/framework/base/BehaviorTest.php b/tests/unit/framework/base/BehaviorTest.php index b34a94e..4d66bdc 100644 --- a/tests/unit/framework/base/BehaviorTest.php +++ b/tests/unit/framework/base/BehaviorTest.php @@ -21,7 +21,7 @@ class BehaviorTest extends \yiiunit\TestCase { public function testAttachAndAccessing() { - $bar = BarClass::create(); + $bar = BarClass::newInstance(); $behavior = new BarBehavior(); $bar->attachBehavior('bar', $behavior); $this->assertEquals('behavior property', $bar->behaviorProperty); diff --git a/tests/unit/framework/base/ComponentTest.php b/tests/unit/framework/base/ComponentTest.php index 686c097..5b42f43 100644 --- a/tests/unit/framework/base/ComponentTest.php +++ b/tests/unit/framework/base/ComponentTest.php @@ -206,7 +206,7 @@ class ComponentTest extends \yiiunit\TestCase public function testCreate() { - $component = NewComponent2::create(1, 2, array('a'=>3)); + $component = NewComponent2::newInstance(1, 2, array('a'=>3)); $this->assertEquals(1, $component->b); $this->assertEquals(2, $component->c); $this->assertEquals(3, $component->a); diff --git a/tests/unit/framework/base/ObjectTest.php b/tests/unit/framework/base/ObjectTest.php index 7c820a3..9321c98 100644 --- a/tests/unit/framework/base/ObjectTest.php +++ b/tests/unit/framework/base/ObjectTest.php @@ -7,6 +7,23 @@ class Foo extends \yii\base\Object public $prop; } +class Bar extends \yii\base\Component implements \yii\base\Initable +{ + public $prop1; + public $prop2; + public $prop3; + + public function __construct($a, $b) + { + $this->prop1 = $a + $b; + } + + public function init() + { + $this->prop3 = 3; + } +} + /** * ObjectTest */ @@ -24,15 +41,28 @@ class ObjectTest extends \yiiunit\TestCase $this->object = null; } - public function testCreate() + public function testNewInstance() { - $foo = Foo::create(array( + $foo = Foo::newInstance(array( 'prop' => array( 'test' => 'test', ), )); $this->assertEquals('test', $foo->prop['test']); + + $bar = Bar::newInstance(10, 20); + $this->assertEquals(30, $bar->prop1); + $this->assertEquals(null, $bar->prop2); + $this->assertEquals(3, $bar->prop3); + + $bar = Bar::newInstance(100, 200, array( + 'prop2' => 'x', + 'prop3' => 400, + )); + $this->assertEquals(300, $bar->prop1); + $this->assertEquals('x', $bar->prop2); + $this->assertEquals(3, $bar->prop3); } public function testHasProperty()