Skip to content

Commit

Permalink
merge from 1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
qiang.xue committed Jan 21, 2009
1 parent 255d03a commit 8421cb2
Show file tree
Hide file tree
Showing 26 changed files with 1,213 additions and 66 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
Expand Up @@ -30,6 +30,10 @@ Version 1.0.2 to be released
- New: Upgraded jQuery to 1.3.0 (Qiang)
- New: Added CDbExpression so that AR can save DB expressions into database (Qiang)
- New: Added CDefaultValueValidator (Qiang)
- New: Implemented the behavior feature; added CBehavior, CModelBehavior and CActiveRecordBehavior (Qiang)
- New: Added a set of new events to CActiveRecord and CFormModel (Qiang)
- New: Added CModel::getValidatorsForAttribute (Qiang)
- New: Added CHtml::activeLabelEx and added 'required' option to CHtml::label (Qiang)

Version 1.0.1 January 4, 2009
-----------------------------
Expand Down
1 change: 1 addition & 0 deletions demos/blog/protected/models/Post.php
Expand Up @@ -36,6 +36,7 @@ public function rules()
array('title', 'length', 'max'=>128),
array('title, content, status', 'required'),
array('status', 'numerical', 'min'=>0, 'max'=>3),
array('tagInput', 'match', 'pattern'=>'/[\w\s,]+/', 'message'=>'Tags can only contain word characters.'),
);
}

Expand Down
2 changes: 1 addition & 1 deletion docs/guide/topics.auth.txt
Expand Up @@ -89,7 +89,7 @@ also be saved in cookie. Make sure you do not declare sensitive information
Login and Logout
----------------

Using the identity class and the user component user component, we can
Using the identity class and the user component, we can
implement login and logout actions easily.

~~~
Expand Down
3 changes: 3 additions & 0 deletions framework/YiiBase.php
Expand Up @@ -411,11 +411,13 @@ public static function t($category,$message,$params=array(),$source=null)
private static $_coreClasses=array(
'CApplication' => '/base/CApplication.php',
'CApplicationComponent' => '/base/CApplicationComponent.php',
'CBehavior' => '/base/CBehavior.php',
'CComponent' => '/base/CComponent.php',
'CErrorHandler' => '/base/CErrorHandler.php',
'CException' => '/base/CException.php',
'CHttpException' => '/base/CHttpException.php',
'CModel' => '/base/CModel.php',
'CModelBehavior' => '/base/CModelBehavior.php',
'CSecurityManager' => '/base/CSecurityManager.php',
'CStatePersister' => '/base/CStatePersister.php',
'CApcCache' => '/caching/CApcCache.php',
Expand Down Expand Up @@ -447,6 +449,7 @@ public static function t($category,$message,$params=array(),$source=null)
'CDbTransaction' => '/db/CDbTransaction.php',
'CActiveFinder' => '/db/ar/CActiveFinder.php',
'CActiveRecord' => '/db/ar/CActiveRecord.php',
'CActiveRecordBehavior' => '/db/ar/CActiveRecordBehavior.php',
'CDbColumnSchema' => '/db/schema/CDbColumnSchema.php',
'CDbCommandBuilder' => '/db/schema/CDbCommandBuilder.php',
'CDbCriteria' => '/db/schema/CDbCriteria.php',
Expand Down
9 changes: 9 additions & 0 deletions framework/base/CApplicationComponent.php
Expand Up @@ -24,6 +24,14 @@
*/
abstract class CApplicationComponent extends CComponent implements IApplicationComponent
{
/**
* @var array the behaviors that should be attached to this component.
* The behaviors will be attached to the component when {@link init} is called.
* Please refer to {@link CModel::behaviors} on how to specify the value of this property.
* @since 1.0.2
*/
public $behaviors=array();

private $_initialized=false;

/**
Expand All @@ -34,6 +42,7 @@ abstract class CApplicationComponent extends CComponent implements IApplicationC
*/
public function init()
{
$this->attachBehaviors($this->behaviors);
$this->_initialized=true;
}

Expand Down
87 changes: 87 additions & 0 deletions framework/base/CBehavior.php
@@ -0,0 +1,87 @@
<?php
/**
* CBehavior class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2009 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/

/**
* CBehavior is a convenient base class for behavior classes.
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id$
* @package system.base
* @since 1.0.2
*/
class CBehavior extends CComponent implements IBehavior
{
private $_enabled;
private $_owner;

/**
* Declares events and the corresponding event handler methods.
* The events are defined by the {@link owner} component, while the handler
* methods by the behavior class. The handlers will be attached to the corresponding
* events when the behavior is attached to the {@link owner} component; and they
* will be detached from the events when the behavior is detached from the component.
* @return array events (array keys) and the corresponding event handler methods (array values).
*/
public function events()
{
return array();
}

/**
* Attaches the behavior object to the component.
* The default implementation will set the {@link owner} property
* and attach event handlers as declared in {@link events}.
* Make sure you call the parent implementation if you override this method.
* @param CComponent the component that this behavior is to be attached to.
*/
public function attach($owner)
{
$this->_owner=$owner;
foreach($this->events() as $event=>$handler)
$owner->attachEventHandler($event,array($this,$handler));
}

/**
* Detaches the behavior object from the component.
* The default implementation will unset the {@link owner} property
* and detach event handlers declared in {@link events}.
* Make sure you call the parent implementation if you override this method.
* @param CComponent the component that this behavior is to be detached from.
*/
public function detach($owner)
{
foreach($this->events() as $event=>$handler)
$owner->detachEventHandler($event,array($this,$handler));
$this->_owner=null;
}

/**
* @return CComponent the owner component that this behavior is attached to.
*/
public function getOwner()
{
return $this->_owner;
}

/**
* @return boolean whether this behavior is enabled
*/
public function getEnabled()
{
return $this->_enabled;
}

/**
* @param boolean whether this behavior is enabled
*/
public function setEnabled($value)
{
$this->_enabled=$value;
}
}
173 changes: 162 additions & 11 deletions framework/base/CComponent.php
Expand Up @@ -66,6 +66,18 @@
*
* Both property names and event names are case-insensitive.
*
* Starting from version 1.0.2, CComponent supports behaviors. A behavior is an
* instance of {@link IBehavior} which is attached to a component. The methods of
* the behavior can be invoked as if they belong to the component. Multiple behaviors
* can be attached to the same component.
*
* To attach a behavior to a component, call {@link attachBehavior}; and to detach the behavior
* from the component, call {@link detachBehavior}.
*
* A behavior can be temporarily enabled or disabled by calling {@link enableBehavior}
* or {@link disableBehavior}, respectively. When disabled, the behavior methods cannot
* be invoked via the component.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id$
* @package system.base
Expand All @@ -74,6 +86,7 @@
class CComponent
{
private $_e;
private $_m;

/**
* Returns a property value or an event handler list by property or event name.
Expand Down Expand Up @@ -181,6 +194,152 @@ public function __unset($name)
array('{class}'=>get_class($this), '{property}'=>$name)));
}

/**
* Calls the named method which is not a class method.
* Do not call this method. This is a PHP magic method that we override
* @param string the method name
* @param array method parameters
* @return mixed the method return value
* @since 1.0.2
*/
public function __call($name,$parameters)
{
if($this->_m!==null)
{
foreach($this->_m as $object)
{
if($object->enabled && method_exists($object,$name))
return call_user_func_array(array($object,$name),$parameters);
}
}
throw new CException('yii','{class} does not have a method named {name}.',
array('{class}'=>get_class($this), '{name}'=>$name));
}


/**
* Attaches a list of behaviors to the component.
* Each behavior is indexed by its name and should be an instance of
* {@link IBehavior}, a string specifying the behavior class, or an
* array of the following structure:
* <pre>
* array(
* 'class'=>'path.to.BehaviorClass',
* 'property1'=>'value1',
* 'property2'=>'value2',
* )
* </pre>
* @param array list of behaviors to be attached to the component
* @since 1.0.2
*/
public function attachBehaviors($behaviors)
{
foreach($behaviors as $name=>$behavior)
$this->attachBehavior($name,$behavior);
}

/**
* Detaches all behaviors from the component.
* @since 1.0.2
*/
public function detachBehaviors()
{
if($this->_m!==null)
{
foreach($this->_m as $name=>$behavior)
$this->detachBehavior($name);
$this->_m=null;
}
}

/**
* Attaches a behavior to this component.
* This method will create the behavior object based on the given
* configuration. After that, the behavior object will be initialized
* by calling its {@link IBehavior::attach} method.
* @param string the behavior's name. It should uniquely identify this behavior.
* @param mixed the behavior configuration. This is passed as the first
* parameter to {@link YiiBase::createComponent} to create the behavior object.
* @return IBehavior the behavior object
* @since 1.0.2
*/
public function attachBehavior($name,$behavior)
{
if(!($behavior instanceof IBehavior))
$behavior=Yii::createComponent($behavior);
$behavior->setEnabled(true);
$behavior->attach($this);
return $this->_m[$name]=$behavior;
}

/**
* Detaches a behavior from the component.
* The behavior's {@link IBehavior::detach} method will be invoked.
* @param string the behavior's name. It uniquely identifies the behavior.
* @return IBehavior the detached behavior. Null if the behavior does not exist.
* @since 1.0.2
*/
public function detachBehavior($name)
{
if(isset($this->_m[$name]))
{
$this->_m[$name]->detach($this);
unset($this->_m[$name]);
return $this->_m[$name];
}
}

/**
* Enables all behaviors attached to this component.
* @since 1.0.2
*/
public function enableBehaviors()
{
if($this->_m!==null)
{
foreach($this->_m as $behavior)
$behavior->setEnabled(true);
}
}

/**
* Disables all behaviors attached to this component.
* @since 1.0.2
*/
public function disableBehaviors()
{
if($this->_m!==null)
{
foreach($this->_m as $behavior)
$behavior->setEnabled(false);
}
}

/**
* Enables an attached behavior.
* A behavior is only effective when it is enabled.
* A behavior is enabled when first attached.
* @param string the behavior's name. It uniquely identifies the behavior.
* @since 1.0.2
*/
public function enableBehavior($name)
{
if(isset($this->_m[$name]))
$this->_m[$name]->setEnabled(true);
}

/**
* Disables an attached behavior.
* A behavior is only effective when it is enabled.
* @param string the behavior's name. It uniquely identifies the behavior.
* @since 1.0.2
*/
public function disableBehavior($name)
{
if(isset($this->_m[$name]))
$this->_m[$name]->setEnabled(false);
}

/**
* Determines whether a property is defined.
* A property is defined if there is a getter or setter method
Expand Down Expand Up @@ -312,17 +471,9 @@ public function attachEventHandler($name,$handler)
public function detachEventHandler($name,$handler)
{
if($this->hasEventHandler($name))
{
try
{
$this->getEventHandlers($name)->remove($handler);
return true;
}
catch(Exception $e)
{
}
}
return false;
return $this->getEventHandlers($name)->remove($handler)!==false;
else
return false;
}

/**
Expand Down

0 comments on commit 8421cb2

Please sign in to comment.