diff --git a/framework/YiiBase.php b/framework/YiiBase.php index 9e8b8b3..90b9ddc 100644 --- a/framework/YiiBase.php +++ b/framework/YiiBase.php @@ -141,11 +141,11 @@ class YiiBase return self::$_imported[$alias]; } - if (class_exists($alias, false) || interface_exists($alias, false)) { - return self::$_imported[$alias] = $alias; - } - - if ($alias[0] !== '@') { // a simple class name + if ($alias[0] !== '@') { + // a simple class name + if (class_exists($alias, false) || interface_exists($alias, false)) { + return self::$_imported[$alias] = $alias; + } if ($forceInclude && static::autoload($alias)) { self::$_imported[$alias] = $alias; } @@ -171,7 +171,8 @@ class YiiBase self::$classMap[$className] = $path . "/$className.php"; } return $className; - } else { // a directory + } else { + // a directory array_unshift(self::$classPath, $path); return self::$_imported[$alias] = $path; } diff --git a/framework/base/Application.php b/framework/base/Application.php index 3ce1272..f9d65ea 100644 --- a/framework/base/Application.php +++ b/framework/base/Application.php @@ -2,7 +2,6 @@ /** * Application class file. * - * @author Qiang Xue * @link http://www.yiiframework.com/ * @copyright Copyright © 2008-2012 Yii Software LLC * @license http://www.yiiframework.com/license/ diff --git a/framework/base/Behavior.php b/framework/base/Behavior.php index db9388a..d65fe91 100644 --- a/framework/base/Behavior.php +++ b/framework/base/Behavior.php @@ -16,6 +16,8 @@ namespace yii\base; * In particular, it can "inject" its own methods and properties into the component * and make them directly accessible via the component. * + * @property Component $owner The owner component that this behavior is attached to. + * * @author Qiang Xue * @since 2.0 */ diff --git a/framework/base/Component.php b/framework/base/Component.php index f2c4835..301fd39 100644 --- a/framework/base/Component.php +++ b/framework/base/Component.php @@ -323,10 +323,10 @@ class Component extends \yii\base\Object if (isset($this->_e[$name])) { if ($event === null) { $event = new Event($this); - $event->name = $name; - } elseif ($event instanceof Event) { - $event->name = $name; + } + if ($event instanceof Event) { $event->handled = false; + $event->name = $name; } foreach ($this->_e[$name] as $handler) { call_user_func($handler, $event); diff --git a/framework/base/Dictionary.php b/framework/base/Dictionary.php index e526f5e..d94c3cf 100644 --- a/framework/base/Dictionary.php +++ b/framework/base/Dictionary.php @@ -31,6 +31,7 @@ use yii\util\ArrayHelper; * ~~~ * * @property integer $count the number of items in the dictionary + * @property array $keys The keys in the dictionary * * @author Qiang Xue * @since 2.0 diff --git a/framework/base/Model.php b/framework/base/Model.php index a92a2ec..e15125d 100644 --- a/framework/base/Model.php +++ b/framework/base/Model.php @@ -22,14 +22,25 @@ use yii\util\Text; * - massive attribute assignment * - scenario-based validation * - * Model also provides a set of events for further customization: + * Model also raises the following events when performing data validation: * - * - [[onBeforeValidate]]: an event raised at the beginning of [[validate()]] - * - [[onAfterValidate]]: an event raised at the end of [[validate()]] + * - [[beforeValidate]]: an event raised at the beginning of [[validate()]] + * - [[afterValidate]]: an event raised at the end of [[validate()]] * * You may directly use Model to store model data, or extend it with customization. * You may also customize Model by attaching [[ModelBehavior|model behaviors]]. * + * @property Vector $validators All the validators declared in the model. + * @property array $activeValidators The validators applicable to the current [[scenario]]. + * @property array $errors Errors for all attributes or the specified attribute. Empty array is returned if no error. + * @property array $attributes Attribute values (name=>value). + * @property string $scenario The scenario that this model is in. + * @property array $safeAttributeNames Safe attribute names in the current [[scenario]]. + * + * @event ModelEvent beforeValidate an event raised at the beginning of [[validate()]]. You may set + * [[ModelEvent::isValid]] to be false to stop the validation. + * @event Event afterValidate an event raised at the end of [[validate()]] + * * @author Qiang Xue * @since 2.0 */ @@ -42,9 +53,9 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess /** * Constructor. - * @param string $scenario name of the [[scenario]] that this model is used in. + * @param string|null $scenario name of the [[scenario]] that this model is used in. */ - public function __construct($scenario = '') + public function __construct($scenario = null) { $this->_scenario = $scenario; } @@ -178,8 +189,8 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess * validation rules should be validated. * @param boolean $clearErrors whether to call [[clearErrors()]] before performing validation * @return boolean whether the validation is successful without any error. - * @see beforeValidate - * @see afterValidate + * @see beforeValidate() + * @see afterValidate() */ public function validate($attributes = null, $clearErrors = true) { @@ -198,7 +209,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess /** * This method is invoked before validation starts. - * The default implementation raises the [[onBeforeValidate]] event. + * The default implementation raises a `beforeValidate` event. * You may override this method to do preliminary checks before validation. * Make sure the parent implementation is invoked so that the event can be raised. * @return boolean whether validation should be executed. Defaults to true. @@ -206,44 +217,20 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess */ public function beforeValidate() { - if ($this->hasEventHandlers('onBeforeValidate')) { - $event = new ModelEvent($this); - $this->onBeforeValidate($event); - return $event->isValid; - } - return true; + $event = new ModelEvent($this); + $this->trigger('beforeValidate', $event); + return $event->isValid; } /** * This method is invoked after validation ends. - * The default implementation raises the [[onAfterValidate]] event. + * The default implementation raises an `afterValidate` event. * You may override this method to do postprocessing after validation. * Make sure the parent implementation is invoked so that the event can be raised. */ public function afterValidate() { $this->trigger('afterValidate'); - if ($this->hasEventHandlers('onAfterValidate')) { - $this->onAfterValidate(new Event($this)); - } - } - - /** - * This event is raised before the validation is performed. - * @param ModelEvent $event the event parameter - */ - public function onBeforeValidate($event) - { - $this->raiseEvent(__FUNCTION__, $event); - } - - /** - * This event is raised after the validation is performed. - * @param Event $event the event parameter - */ - public function onAfterValidate($event) - { - $this->raiseEvent(__FUNCTION__, $event); } /** @@ -281,10 +268,8 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess $validators = array(); $scenario = $this->getScenario(); foreach ($this->getValidators() as $validator) { - if ($validator->applyTo($scenario)) { - if ($attribute === null || in_array($attribute, $validator->attributes, true)) { - $validators[] = $validator; - } + if ($validator->applyTo($scenario, $attribute)) { + $validators[] = $validator; } } return $validators; @@ -529,7 +514,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess * Scenario affects how validation is performed and which attributes can * be massively assigned. * - * A validation rule will be performed when calling [[validate]] + * A validation rule will be performed when calling [[validate()]] * if its 'on' option is not set or contains the current scenario value. * * And an attribute can be massively assigned if it is associated with diff --git a/framework/base/Module.php b/framework/base/Module.php index 12e9283..d099f09 100644 --- a/framework/base/Module.php +++ b/framework/base/Module.php @@ -14,6 +14,14 @@ namespace yii\base; * * Module mainly manages application components and sub-modules that belongs to a module. * + * @property string $id The module ID. + * @property string $basePath The root directory of the module. Defaults to the directory containing the module class. + * @property Module|null $parentModule The parent module. Null if this module does not have a parent. + * @property array $modules The configuration of the currently installed modules (module ID => configuration). + * @property array $components The application components (indexed by their IDs). + * @property array $import List of aliases to be imported. This property is write-only. + * @property array $aliases List of aliases to be defined. This property is write-only. + * * @author Qiang Xue * @since 2.0 */ @@ -108,7 +116,7 @@ abstract class Module extends Component implements Initable /** * Returns the root directory of the module. - * @return string the root directory of the module. Defaults to the directory containing the module class. + * @return string the root directory of the module. Defaults to the directory containing the module class file. */ public function getBasePath() { @@ -127,14 +135,17 @@ abstract class Module extends Component implements Initable */ public function setBasePath($path) { - if (($this->_basePath = realpath($path)) === false || !is_dir($this->_basePath)) { + if (($p = realpath($path)) === false || !is_dir($p)) { throw new Exception('Invalid base path: ' . $path); + } else { + $this->_basePath = $p; } } /** * Imports the specified path aliases. - * This method is provided so that you can import a set of path aliases by module configuration. + * This method is provided so that you can import a set of path aliases when configuring a module. + * The path aliases will be imported by calling [[\Yii::import()]]. * @param array $aliases list of path aliases to be imported */ public function setImport($aliases) @@ -146,15 +157,15 @@ abstract class Module extends Component implements Initable /** * Defines path aliases. - * This method calls [[\Yii::setPathOfAlias]] to register the path aliases. - * This method is provided so that you can define path aliases by module configuration. + * This method calls [[\Yii::setAlias()]] to register the path aliases. + * This method is provided so that you can define path aliases when configuring a module. * @param array $aliases list of path aliases to be defined. The array keys are alias names - * (must start with '@') while the array values are the corresponding paths or aliases. + * (must start with '@') and the array values are the corresponding paths or aliases. * For example, * * ~~~ * array( - * '@models' => '@app/models', // an existing alias + * '@models' => '@app/models', // an existing alias * '@backend' => __DIR__ . '/../backend', // a directory * ) * ~~~ diff --git a/framework/validators/Validator.php b/framework/validators/Validator.php index 7c6851e..aa0d8e6 100644 --- a/framework/validators/Validator.php +++ b/framework/validators/Validator.php @@ -219,11 +219,17 @@ abstract class Validator extends \yii\base\Component * - the validator's `on` property contains the specified scenario * * @param string $scenario scenario name + * @param string|null $attribute the attribute name to check. If this is not null, + * the method will also check if the attribute appears in [[attributes]]. * @return boolean whether the validator applies to the specified scenario. */ - public function applyTo($scenario) + public function applyTo($scenario, $attribute = null) { - return empty($this->on) || isset($this->on[$scenario]); + if ($attribute === null) { + return empty($this->on) || isset($this->on[$scenario]); + } else { + return (empty($this->on) || isset($this->on[$scenario])) && in_array($attribute, $this->attributes, true); + } } /**