1: <?php
  2: /**
  3:  * CBehavior class file.
  4:  *
  5:  * @author Qiang Xue <qiang.xue@gmail.com>
  6:  * @link http://www.yiiframework.com/
  7:  * @copyright 2008-2013 Yii Software LLC
  8:  * @license http://www.yiiframework.com/license/
  9:  */
 10: 
 11: /**
 12:  * CBehavior is a convenient base class for behavior classes.
 13:  *
 14:  * @property CComponent $owner The owner component that this behavior is attached to.
 15:  * @property boolean $enabled Whether this behavior is enabled.
 16:  *
 17:  * @author Qiang Xue <qiang.xue@gmail.com>
 18:  * @package system.base
 19:  */
 20: class CBehavior extends CComponent implements IBehavior
 21: {
 22:     private $_enabled=false;
 23:     private $_owner;
 24: 
 25:     /**
 26:      * Declares events and the corresponding event handler methods.
 27:      * The events are defined by the {@link owner} component, while the handler
 28:      * methods by the behavior class. The handlers will be attached to the corresponding
 29:      * events when the behavior is attached to the {@link owner} component; and they
 30:      * will be detached from the events when the behavior is detached from the component.
 31:      * Make sure you've declared handler method as public.
 32:      * @return array events (array keys) and the corresponding event handler methods (array values).
 33:      */
 34:     public function events()
 35:     {
 36:         return array();
 37:     }
 38: 
 39:     /**
 40:      * Attaches the behavior object to the component.
 41:      * The default implementation will set the {@link owner} property
 42:      * and attach event handlers as declared in {@link events}.
 43:      * This method will also set {@link enabled} to true.
 44:      * Make sure you've declared handler as public and call the parent implementation if you override this method.
 45:      * @param CComponent $owner the component that this behavior is to be attached to.
 46:      */
 47:     public function attach($owner)
 48:     {
 49:         $this->_enabled=true;
 50:         $this->_owner=$owner;
 51:         $this->_attachEventHandlers();
 52:     }
 53: 
 54:     /**
 55:      * Detaches the behavior object from the component.
 56:      * The default implementation will unset the {@link owner} property
 57:      * and detach event handlers declared in {@link events}.
 58:      * This method will also set {@link enabled} to false.
 59:      * Make sure you call the parent implementation if you override this method.
 60:      * @param CComponent $owner the component that this behavior is to be detached from.
 61:      */
 62:     public function detach($owner)
 63:     {
 64:         foreach($this->events() as $event=>$handler)
 65:             $owner->detachEventHandler($event,array($this,$handler));
 66:         $this->_owner=null;
 67:         $this->_enabled=false;
 68:     }
 69: 
 70:     /**
 71:      * @return CComponent the owner component that this behavior is attached to.
 72:      */
 73:     public function getOwner()
 74:     {
 75:         return $this->_owner;
 76:     }
 77: 
 78:     /**
 79:      * @return boolean whether this behavior is enabled
 80:      */
 81:     public function getEnabled()
 82:     {
 83:         return $this->_enabled;
 84:     }
 85: 
 86:     /**
 87:      * @param boolean $value whether this behavior is enabled
 88:      */
 89:     public function setEnabled($value)
 90:     {
 91:         $value=(bool)$value;
 92:         if($this->_enabled!=$value && $this->_owner)
 93:         {
 94:             if($value)
 95:                 $this->_attachEventHandlers();
 96:             else
 97:             {
 98:                 foreach($this->events() as $event=>$handler)
 99:                     $this->_owner->detachEventHandler($event,array($this,$handler));
100:             }
101:         }
102:         $this->_enabled=$value;
103:     }
104: 
105:     private function _attachEventHandlers()
106:     {
107:         $class=new ReflectionClass($this);
108:         foreach($this->events() as $event=>$handler)
109:         {
110:             if($class->getMethod($handler)->isPublic())
111:                 $this->_owner->attachEventHandler($event,array($this,$handler));
112:         }
113:     }
114: }
115: