Browse Source

w

tags/2.0.0-beta
Qiang Xue 13 years ago
parent
commit
d2159b128b
  1. 40
      framework/base/Behavior.php
  2. 65
      framework/base/Component.php
  3. 9
      framework/base/Event.php
  4. 34
      tests/unit/framework/base/ComponentTest.php
  5. 35
      todo.txt

40
framework/base/Behavior.php

@ -21,7 +21,6 @@ namespace yii\base;
*/ */
class Behavior extends Component class Behavior extends Component
{ {
private $_enabled;
private $_owner; private $_owner;
/** /**
@ -34,7 +33,14 @@ class Behavior extends Component
* the behavior is detached from the component. * the behavior is detached from the component.
* *
* The method should return an array whose keys are the names of the owner's events * The method should return an array whose keys are the names of the owner's events
* and values are the names of the behavior methods. * and values are the names of the behavior methods. For example,
*
* ~~~
* array(
* 'onBeforeValidate' => 'myBeforeValidate',
* 'onAfterValidate' => 'myAfterValidate',
* )
* ~~~
* *
* @return array events (keys) and the corresponding behavior method names (values). * @return array events (keys) and the corresponding behavior method names (values).
*/ */
@ -81,34 +87,4 @@ class Behavior extends Component
{ {
return $this->_owner; return $this->_owner;
} }
/**
* Returns a value indicating whether this behavior is enabled.
* @return boolean whether this behavior is enabled
*/
public function getEnabled()
{
return $this->_enabled;
}
/**
* Enables or disables the behavior.
* @param boolean $value whether this behavior should be enabled.
*/
public function setEnabled($value)
{
if($this->_enabled!=$value && $this->_owner) {
if($value) {
foreach($this->events() as $event=>$handler) {
$this->_owner->attachEventHandler($event, array($this, $handler));
}
}
else {
foreach($this->events() as $event=>$handler) {
$this->_owner->detachEventHandler($event, array($this, $handler));
}
}
}
$this->_enabled = $value;
}
} }

65
framework/base/Component.php

@ -97,10 +97,6 @@ namespace yii\base;
* To attach a behavior to a component, call [[attachBehavior]]; and to detach the behavior * To attach a behavior to a component, call [[attachBehavior]]; and to detach the behavior
* from the component, call [[detachBehavior]]. * from the component, call [[detachBehavior]].
* *
* A behavior can be temporarily enabled or disabled by calling [[enableBehavior]] or
* [[disableBehavior]], respectively. When disabled, the behavior's public properties and methods
* cannot be accessed via the component.
*
* Components created via [[\Yii::createComponent]] have life cycles. In particular, * Components created via [[\Yii::createComponent]] have life cycles. In particular,
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
@ -146,7 +142,7 @@ class Component
} }
elseif (is_array($this->_b)) { // a behavior property elseif (is_array($this->_b)) { // a behavior property
foreach ($this->_b as $object) { foreach ($this->_b as $object) {
if ($object->getEnabled() && (property_exists($object, $name) || $object->canGetProperty($name))) { if (property_exists($object, $name) || $object->canGetProperty($name)) {
return $object->$name; return $object->$name;
} }
} }
@ -184,7 +180,7 @@ class Component
} }
elseif (is_array($this->_b)) { // behavior elseif (is_array($this->_b)) { // behavior
foreach ($this->_b as $object) { foreach ($this->_b as $object) {
if ($object->getEnabled() && (property_exists($object, $name) || $object->canSetProperty($name))) { if (property_exists($object, $name) || $object->canSetProperty($name)) {
return $object->$name = $value; return $object->$name = $value;
} }
} }
@ -225,7 +221,7 @@ class Component
} }
elseif (is_array($this->_b)) { elseif (is_array($this->_b)) {
foreach ($this->_b as $object) { foreach ($this->_b as $object) {
if ($object->getEnabled() && (property_exists($object, $name) || $object->canGetProperty($name))) { if (property_exists($object, $name) || $object->canGetProperty($name)) {
return $object->$name !== null; return $object->$name !== null;
} }
} }
@ -260,7 +256,6 @@ class Component
} }
elseif (is_array($this->_b)) { // behavior property elseif (is_array($this->_b)) { // behavior property
foreach ($this->_b as $object) { foreach ($this->_b as $object) {
if ($object->getEnabled()) {
if (property_exists($object, $name)) { if (property_exists($object, $name)) {
return $object->$name = null; return $object->$name = null;
} }
@ -269,7 +264,6 @@ class Component
} }
} }
} }
}
elseif (method_exists($this, 'get' . $name)) { elseif (method_exists($this, 'get' . $name)) {
throw new Exception('Unsetting read-only property: ' . get_class($this) . '.' . $name); throw new Exception('Unsetting read-only property: ' . get_class($this) . '.' . $name);
} }
@ -301,7 +295,7 @@ class Component
{ {
foreach ($this->_b as $object) foreach ($this->_b as $object)
{ {
if ($object->getEnabled() && method_exists($object, $name)) { if (method_exists($object, $name)) {
return call_user_func_array(array($object, $name), $parameters); return call_user_func_array(array($object, $name), $parameters);
} }
} }
@ -498,6 +492,9 @@ class Component
public function raiseEvent($name, $event) public function raiseEvent($name, $event)
{ {
$name = strtolower($name); $name = strtolower($name);
if ($event instanceof Event) {
$event->name = $name;
}
if (isset($this->_e[$name])) { if (isset($this->_e[$name])) {
foreach ($this->_e[$name] as $handler) { foreach ($this->_e[$name] as $handler) {
if (is_string($handler) || $handler instanceof \Closure) { if (is_string($handler) || $handler instanceof \Closure) {
@ -612,54 +609,6 @@ class Component
} }
/** /**
* Enables all behaviors attached to this component.
*/
public function enableBehaviors()
{
if ($this->_b !== null) {
foreach ($this->_b as $behavior) {
$behavior->setEnabled(true);
}
}
}
/**
* Disables all behaviors attached to this component.
*/
public function disableBehaviors()
{
if ($this->_b !== null) {
foreach ($this->_b as $behavior) {
$behavior->setEnabled(false);
}
}
}
/**
* Enables an attached behavior.
* A behavior is only effective when it is enabled.
* @param string $name the behavior's name. It uniquely identifies the behavior.
*/
public function enableBehavior($name)
{
if (isset($this->_b[$name])) {
$this->_b[$name]->setEnabled(true);
}
}
/**
* Disables an attached behavior.
* A behavior is only effective when it is enabled.
* @param string $name the behavior's name. It uniquely identifies the behavior.
*/
public function disableBehavior($name)
{
if (isset($this->_b[$name])) {
$this->_b[$name]->setEnabled(false);
}
}
/**
* Evaluates a PHP expression or callback under the context of this component. * Evaluates a PHP expression or callback under the context of this component.
* *
* Valid PHP callback can be class method name in the form of * Valid PHP callback can be class method name in the form of

9
framework/base/Event.php

@ -25,12 +25,19 @@ namespace yii\base;
class Event extends Component class Event extends Component
{ {
/** /**
* @var string the event name. This property is set by [[Component::raiseEvent]].
* Event handlers may use this property to check what event it is handling.
* The event name is in lower case.
*/
public $name;
/**
* @var object the sender of this event * @var object the sender of this event
*/ */
public $sender; public $sender;
/** /**
* @var boolean whether the event is handled. Defaults to false. * @var boolean whether the event is handled. Defaults to false.
* When a handler sets this to be true, the rest of the uninvoked event handlers will be canceled. * When a handler sets this to be true, the event processing will stop and
* ignore the rest of the uninvoked event handlers.
*/ */
public $handled = false; public $handled = false;
/** /**

34
tests/unit/framework/base/ComponentTest.php

@ -175,13 +175,17 @@ class ComponentTest extends \yii\test\TestCase
$this->setExpectedException('yii\base\Exception'); $this->setExpectedException('yii\base\Exception');
$this->component->onMyEvent(); $this->component->onMyEvent();
} }
public function testDetachBehavior() {
public function testDetachBehavior()
{
$component=new NewComponent; $component=new NewComponent;
$behavior = new NewBehavior; $behavior = new NewBehavior;
$component->attachBehavior('a',$behavior); $component->attachBehavior('a',$behavior);
$this->assertSame($behavior,$component->detachBehavior('a')); $this->assertSame($behavior,$component->detachBehavior('a'));
} }
public function testDetachingBehaviors() {
public function testDetachingBehaviors()
{
$component=new NewComponent; $component=new NewComponent;
$behavior = new NewBehavior; $behavior = new NewBehavior;
$component->attachBehavior('a',$behavior); $component->attachBehavior('a',$behavior);
@ -189,31 +193,17 @@ class ComponentTest extends \yii\test\TestCase
$this->setExpectedException('yii\base\Exception'); $this->setExpectedException('yii\base\Exception');
$component->test(); $component->test();
} }
public function testEnablingBehavior() {
$component=new NewComponent; public function testAsa()
$behavior = new NewBehavior; {
$component->attachBehavior('a',$behavior);
$component->disableBehavior('a');
$this->assertFalse($behavior->getEnabled());
$component->enableBehavior('a');
$this->assertTrue($behavior->getEnabled());
}
public function testEnablingBehaviors() {
$component=new NewComponent;
$behavior = new NewBehavior;
$component->attachBehavior('a',$behavior);
$component->disableBehaviors();
$this->assertFalse($behavior->getEnabled());
$component->enableBehaviors();
$this->assertTrue($behavior->getEnabled());
}
public function testAsa() {
$component=new NewComponent; $component=new NewComponent;
$behavior = new NewBehavior; $behavior = new NewBehavior;
$component->attachBehavior('a',$behavior); $component->attachBehavior('a',$behavior);
$this->assertSame($behavior,$component->asa('a')); $this->assertSame($behavior,$component->asa('a'));
} }
public function testEvaluateExpression() {
public function testEvaluateExpression()
{
$component = new NewComponent; $component = new NewComponent;
$this->assertEquals('Hello world',$component->evaluateExpression('"Hello $who"',array('who' => 'world'))); $this->assertEquals('Hello world',$component->evaluateExpression('"Hello $who"',array('who' => 'world')));
$this->assertEquals('Hello world',$component->evaluateExpression(array($component,'exprEvaluator'),array('who' => 'world'))); $this->assertEquals('Hello world',$component->evaluateExpression(array($component,'exprEvaluator'),array('who' => 'world')));

35
todo.txt

@ -1,40 +1,37 @@
- add more doc to Model - base
- CompareValidator::clientValidateAttribute(): search for "CHtml::activeId" * add more doc to Model
- FileValidator, UniqueValidator, ExistValidator, DateValidator: TBD * error/exception handling
- Can consider merging UniqueValidator and ExistValidator and using a NOT property. - validators
- design of component life cycles: init() and afterConstruct() * CompareValidator::clientValidateAttribute(): search for "CHtml::activeId"
* construct object * FileValidator, UniqueValidator, ExistValidator, DateValidator: TBD
* preinit * consider merging UniqueValidator and ExistValidator and using a NOT property.
* attachBehaviors - console command support
* initialize properties - built-in console commands
* init + api doc builder
* ...
* destruct
- get/setFlash() should be moved to session component
- support optional parameter in URL patterns
- api doc builder
* support for markdown syntax * support for markdown syntax
* support for [[name]] * support for [[name]]
* consider to be released as a separate tool for user app docs * consider to be released as a separate tool for user app docs
- cache components - caching
* a way to invalidate/clear cached data * a way to invalidate/clear cached data
* a command to clear cached data * a command to clear cached data
- console command support
- db - db
* DAO * DAO
* schema
* AR * AR
* document-based * document-based
* key-value-based * key-value-based
- gii
- logging - logging
- i18n - i18n
* consider using PHP built-in support and data * consider using PHP built-in support and data
* message translations, choice format * message translations, choice format
* formatting: number and date * formatting: number and date
* parsing?? * parsing??
- error/exception handling
- helpers - helpers
* array * array
* image * image
* string * string
* file
- web: TBD - web: TBD
* get/setFlash() should be moved to session component
* support optional parameter in URL patterns
- gii

Loading…
Cancel
Save