Commit a705fb4e by Qiang Xue

...

parent 409c508f
...@@ -141,11 +141,11 @@ class YiiBase ...@@ -141,11 +141,11 @@ class YiiBase
return self::$_imported[$alias]; return self::$_imported[$alias];
} }
if (class_exists($alias, false) || interface_exists($alias, false)) { if ($alias[0] !== '@') {
return self::$_imported[$alias] = $alias; // a simple class name
} if (class_exists($alias, false) || interface_exists($alias, false)) {
return self::$_imported[$alias] = $alias;
if ($alias[0] !== '@') { // a simple class name }
if ($forceInclude && static::autoload($alias)) { if ($forceInclude && static::autoload($alias)) {
self::$_imported[$alias] = $alias; self::$_imported[$alias] = $alias;
} }
...@@ -171,7 +171,8 @@ class YiiBase ...@@ -171,7 +171,8 @@ class YiiBase
self::$classMap[$className] = $path . "/$className.php"; self::$classMap[$className] = $path . "/$className.php";
} }
return $className; return $className;
} else { // a directory } else {
// a directory
array_unshift(self::$classPath, $path); array_unshift(self::$classPath, $path);
return self::$_imported[$alias] = $path; return self::$_imported[$alias] = $path;
} }
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
/** /**
* Application class file. * Application class file.
* *
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/ * @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2012 Yii Software LLC * @copyright Copyright &copy; 2008-2012 Yii Software LLC
* @license http://www.yiiframework.com/license/ * @license http://www.yiiframework.com/license/
......
...@@ -16,6 +16,8 @@ namespace yii\base; ...@@ -16,6 +16,8 @@ namespace yii\base;
* In particular, it can "inject" its own methods and properties into the component * In particular, it can "inject" its own methods and properties into the component
* and make them directly accessible via 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 <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
......
...@@ -323,10 +323,10 @@ class Component extends \yii\base\Object ...@@ -323,10 +323,10 @@ class Component extends \yii\base\Object
if (isset($this->_e[$name])) { if (isset($this->_e[$name])) {
if ($event === null) { if ($event === null) {
$event = new Event($this); $event = new Event($this);
$event->name = $name; }
} elseif ($event instanceof Event) { if ($event instanceof Event) {
$event->name = $name;
$event->handled = false; $event->handled = false;
$event->name = $name;
} }
foreach ($this->_e[$name] as $handler) { foreach ($this->_e[$name] as $handler) {
call_user_func($handler, $event); call_user_func($handler, $event);
......
...@@ -31,6 +31,7 @@ use yii\util\ArrayHelper; ...@@ -31,6 +31,7 @@ use yii\util\ArrayHelper;
* ~~~ * ~~~
* *
* @property integer $count the number of items in the dictionary * @property integer $count the number of items in the dictionary
* @property array $keys The keys in the dictionary
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
......
...@@ -22,14 +22,25 @@ use yii\util\Text; ...@@ -22,14 +22,25 @@ use yii\util\Text;
* - massive attribute assignment * - massive attribute assignment
* - scenario-based validation * - 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()]] * - [[beforeValidate]]: an event raised at the beginning of [[validate()]]
* - [[onAfterValidate]]: an event raised at the end 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 directly use Model to store model data, or extend it with customization.
* You may also customize Model by attaching [[ModelBehavior|model behaviors]]. * 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 <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
...@@ -42,9 +53,9 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess ...@@ -42,9 +53,9 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
/** /**
* Constructor. * 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; $this->_scenario = $scenario;
} }
...@@ -178,8 +189,8 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess ...@@ -178,8 +189,8 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
* validation rules should be validated. * validation rules should be validated.
* @param boolean $clearErrors whether to call [[clearErrors()]] before performing validation * @param boolean $clearErrors whether to call [[clearErrors()]] before performing validation
* @return boolean whether the validation is successful without any error. * @return boolean whether the validation is successful without any error.
* @see beforeValidate * @see beforeValidate()
* @see afterValidate * @see afterValidate()
*/ */
public function validate($attributes = null, $clearErrors = true) public function validate($attributes = null, $clearErrors = true)
{ {
...@@ -198,7 +209,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess ...@@ -198,7 +209,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
/** /**
* This method is invoked before validation starts. * 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. * 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. * Make sure the parent implementation is invoked so that the event can be raised.
* @return boolean whether validation should be executed. Defaults to true. * @return boolean whether validation should be executed. Defaults to true.
...@@ -206,44 +217,20 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess ...@@ -206,44 +217,20 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
*/ */
public function beforeValidate() public function beforeValidate()
{ {
if ($this->hasEventHandlers('onBeforeValidate')) { $event = new ModelEvent($this);
$event = new ModelEvent($this); $this->trigger('beforeValidate', $event);
$this->onBeforeValidate($event); return $event->isValid;
return $event->isValid;
}
return true;
} }
/** /**
* This method is invoked after validation ends. * 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. * You may override this method to do postprocessing after validation.
* Make sure the parent implementation is invoked so that the event can be raised. * Make sure the parent implementation is invoked so that the event can be raised.
*/ */
public function afterValidate() public function afterValidate()
{ {
$this->trigger('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 ...@@ -281,10 +268,8 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
$validators = array(); $validators = array();
$scenario = $this->getScenario(); $scenario = $this->getScenario();
foreach ($this->getValidators() as $validator) { foreach ($this->getValidators() as $validator) {
if ($validator->applyTo($scenario)) { if ($validator->applyTo($scenario, $attribute)) {
if ($attribute === null || in_array($attribute, $validator->attributes, true)) { $validators[] = $validator;
$validators[] = $validator;
}
} }
} }
return $validators; return $validators;
...@@ -529,7 +514,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess ...@@ -529,7 +514,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
* Scenario affects how validation is performed and which attributes can * Scenario affects how validation is performed and which attributes can
* be massively assigned. * 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. * 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 * And an attribute can be massively assigned if it is associated with
......
...@@ -14,6 +14,14 @@ namespace yii\base; ...@@ -14,6 +14,14 @@ namespace yii\base;
* *
* Module mainly manages application components and sub-modules that belongs to a module. * 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 <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
...@@ -108,7 +116,7 @@ abstract class Module extends Component implements Initable ...@@ -108,7 +116,7 @@ abstract class Module extends Component implements Initable
/** /**
* Returns the root directory of the module. * 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() public function getBasePath()
{ {
...@@ -127,14 +135,17 @@ abstract class Module extends Component implements Initable ...@@ -127,14 +135,17 @@ abstract class Module extends Component implements Initable
*/ */
public function setBasePath($path) 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); throw new Exception('Invalid base path: ' . $path);
} else {
$this->_basePath = $p;
} }
} }
/** /**
* Imports the specified path aliases. * 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 * @param array $aliases list of path aliases to be imported
*/ */
public function setImport($aliases) public function setImport($aliases)
...@@ -146,15 +157,15 @@ abstract class Module extends Component implements Initable ...@@ -146,15 +157,15 @@ abstract class Module extends Component implements Initable
/** /**
* Defines path aliases. * Defines path aliases.
* This method calls [[\Yii::setPathOfAlias]] to register the path aliases. * This method calls [[\Yii::setAlias()]] to register the path aliases.
* This method is provided so that you can define path aliases by module configuration. * 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 * @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, * For example,
* *
* ~~~ * ~~~
* array( * array(
* '@models' => '@app/models', // an existing alias * '@models' => '@app/models', // an existing alias
* '@backend' => __DIR__ . '/../backend', // a directory * '@backend' => __DIR__ . '/../backend', // a directory
* ) * )
* ~~~ * ~~~
......
...@@ -219,11 +219,17 @@ abstract class Validator extends \yii\base\Component ...@@ -219,11 +219,17 @@ abstract class Validator extends \yii\base\Component
* - the validator's `on` property contains the specified scenario * - the validator's `on` property contains the specified scenario
* *
* @param string $scenario scenario name * @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. * @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);
}
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment