0 follower

CSort

Package system.web
Inheritance class CSort » CComponent
Since 1.0.1
Version $Id$
Source Code framework/web/CSort.php
CSort represents information relevant to sorting.

When data needs to be sorted according to one or several attributes, we can use CSort to represent the sorting information and generate appropriate hyperlinks that can lead to sort actions.

CSort is designed to be used together with CActiveRecord. When creating a CSort instance, you need to specify modelClass. You can use CSort to generate hyperlinks by calling link. You can also use CSort to modify a CDbCriteria instance so that it can cause the query results to be sorted according to the specified attributes.

CSort is primarily used for active record involving a single DB table. In order to use it with relational active record, special care needs to be taken. We use an example to illustrate this use case. Assume 'Post' is the main active record class, and 'author' is one of its related attributes. We would like to sort by post's title as well as its author's name. First, we need to define aliases for the two attributes by setting the attributes property:
array(
    'title',
    'author.name'=>'authorName',
)


We also need to modify the 'author' relation in 'Post' class and explicitly specify the 'alias' option with value 'author':
'author'=>array(self::BELONGS_TO, 'User', 'alias'=>'author')


Finally, we can use the following code to generate hyperlinks:
echo CSort::link('title');
echo CSort::link('author.name');

Public Properties

Hide inherited properties

PropertyTypeDescriptionDefined By
attributes array list of attributes that are allowed to be sorted. CSort
defaultOrder string the default order that should be applied to the query criteria when the current request does not specify any sort. CSort
directions array Returns the currently requested sort information. CSort
modelClass string the class name of data models that need to be sorted. CSort
multiSort boolean whether the sorting can be applied to multiple attributes simultaneously. CSort
params array the additional GET parameters (name=>value) that should be used when generating sort URLs. CSort
route string the route (controller ID and action ID) for generating the sorted contents. CSort
separators array separators used in the generated URL. CSort
sortVar string the name of the GET parameter that specifies which attributes to be sorted in which direction. CSort

Public Methods

Hide inherited methods

MethodDescriptionDefined By
__call() Calls the named method which is not a class method. CComponent
__construct() Constructor. CSort
__get() Returns a property value, an event handler list or a behavior based on its name. CComponent
__isset() Checks if a property value is null. CComponent
__set() Sets value of a component property. CComponent
__unset() Sets a component property to be null. CComponent
applyOrder() Modifies the query criteria by changing its CDbCriteria::order property. CSort
asa() Returns the named behavior object. CComponent
attachBehavior() Attaches a behavior to this component. CComponent
attachBehaviors() Attaches a list of behaviors to the component. CComponent
attachEventHandler() Attaches an event handler to an event. CComponent
canGetProperty() Determines whether a property can be read. CComponent
canSetProperty() Determines whether a property can be set. CComponent
createUrl() Creates a URL that can lead to generating sorted data. CSort
detachBehavior() Detaches a behavior from the component. CComponent
detachBehaviors() Detaches all behaviors from the component. CComponent
detachEventHandler() Detaches an existing event handler. CComponent
disableBehavior() Disables an attached behavior. CComponent
disableBehaviors() Disables all behaviors attached to this component. CComponent
enableBehavior() Enables an attached behavior. CComponent
enableBehaviors() Enables all behaviors attached to this component. CComponent
getDirections() Returns the currently requested sort information. CSort
getEventHandlers() Returns the list of attached event handlers for an event. CComponent
hasEvent() Determines whether an event is defined. CComponent
hasEventHandler() Checks whether the named event has attached handlers. CComponent
hasProperty() Determines whether a property is defined. CComponent
raiseEvent() Raises an event. CComponent
resolveLabel() Resolves the attribute label based on label definition in the AR class. CSort
validateAttribute() Validates an attribute that is requested to be sorted. CSort

Protected Methods

Hide inherited methods

MethodDescriptionDefined By

Property Details

attributes property
public array $attributes;

list of attributes that are allowed to be sorted. For example, array('user_id','create_time') would specify that only 'user_id' and 'create_time' can be sorted. Defaults to null, meaning all attributes of the modelClass can be sorted. This property can also be used to specify attribute aliases that should appear in the 'sort' GET parameter in place of the original attribute names. In this case, the aliases should be array values while the attribute names should be the corresponding array keys. Do not use '-' and '.' in the aliases as they are used as separators.

defaultOrder property
public string $defaultOrder;

the default order that should be applied to the query criteria when the current request does not specify any sort.

directions property read-only
public array getDirections()

Returns the currently requested sort information.

modelClass property
public string $modelClass;

the class name of data models that need to be sorted. This should be a child class of CActiveRecord.

multiSort property
public boolean $multiSort;

whether the sorting can be applied to multiple attributes simultaneously. Defaults to true. If false, each time the data can only be sorted by one attribute.

params property (available since v1.0.9)
public array $params;

the additional GET parameters (name=>value) that should be used when generating sort URLs. Defaults to null, meaning using the currently available GET parameters.

route property
public string $route;

the route (controller ID and action ID) for generating the sorted contents. Defaults to empty string, meaning using the currently requested route.

separators property
public array $separators;

separators used in the generated URL. This must be an array consisting of two elements. The first element specifies the character separating different attributes, while the second element specifies the character separating attribute name and the corresponding sort direction. Defaults to array('-','.').

sortVar property
public string $sortVar;

the name of the GET parameter that specifies which attributes to be sorted in which direction. Defaults to 'sort'.

Method Details

__construct() method
public void __construct(string $modelClass)
$modelClass string the class name of data models that need to be sorted. This should be a child class of CActiveRecord.
Source Code: framework/web/CSort.php#115 (show)
public function __construct($modelClass)
{
    
$this->modelClass=$modelClass;
}

Constructor.

applyOrder() method
public void applyOrder(CDbCriteria $criteria)
$criteria CDbCriteria the query criteria
Source Code: framework/web/CSort.php#127 (show)
public function applyOrder($criteria)
{
    
$directions=$this->getDirections();
    if(empty(
$directions))
        
$order=$this->defaultOrder;
    else
    {
        
$schema=CActiveRecord::model($this->modelClass)->getDbConnection()->getSchema();
        
$orders=array();
        foreach(
$directions as $attribute=>$descending)
        {
            if((
$pos=strpos($attribute,'.'))!==false)
                
$attribute=$schema->quoteTableName(substr($attribute,0,$pos)).'.'.$schema->quoteColumnName(substr($attribute,$pos+1));
            else
                
$attribute=$schema->quoteColumnName($attribute);
            
$orders[]=$descending?$attribute.' DESC':$attribute;
        }
        
$order=implode(', ',$orders);
    }

    if(!empty(
$order))
    {
        if(!empty(
$criteria->order))
            
$criteria->order.=', ';
        
$criteria->order.=$order;
    }
}

Modifies the query criteria by changing its CDbCriteria::order property. This method will use directions to determine which columns need to be sorted. They will be put in the ORDER BY clause. If the criteria already has non-empty CDbCriteria::order value, the new value will be appended to it.

protected string createLink(string $attribute, string $label, string $url, array $htmlOptions)
$attribute string the name of the attribute that this link is for
$label string the label of the hyperlink
$url string the URL
$htmlOptions array additional HTML options
{return} string the generated hyperlink
Source Code: framework/web/CSort.php#298 (show)
protected function createLink($attribute,$label,$url,$htmlOptions)
{
    return 
CHtml::link($label,$url,$htmlOptions);
}

Creates a hyperlink based on the given label and URL. You may override this method to customize the link generation.

createUrl() method
public string createUrl(CController $controller, array $directions)
$controller CController the controller that will be used to create the URL.
$directions array the sort directions indexed by attribute names. The sort direction is true if the corresponding attribute should be sorted in descending order.
{return} string the URL for sorting
Source Code: framework/web/CSort.php#252 (show)
public function createUrl($controller,$directions)
{
    
$sorts=array();
    foreach(
$directions as $attribute=>$descending)
    {
        if(
is_array($this->attributes) && isset($this->attributes[$attribute]))
            
$attribute=$this->attributes[$attribute];
        
$sorts[]=$descending $attribute.$this->separators[1].'desc' $attribute;
    }
    
$params=$this->params===null $_GET $this->params;
    
$params[$this->sortVar]=implode($this->separators[0],$sorts);
    return 
$controller->createUrl($this->route,$params);
}

Creates a URL that can lead to generating sorted data.

getDirections() method
public array getDirections()
{return} array sort directions indexed by attribute names. The sort direction is true if the corresponding attribute should be sorted in descending order.
Source Code: framework/web/CSort.php#213 (show)
public function getDirections()
{
    if(
$this->_directions===null)
    {
        
$this->_directions=array();
        if(isset(
$_GET[$this->sortVar]))
        {
            
$attributes=explode($this->separators[0],$_GET[$this->sortVar]);
            foreach(
$attributes as $attribute)
            {
                if((
$pos=strpos($attribute,$this->separators[1]))!==false)
                {
                    
$descending=substr($attribute,$pos+1)==='desc';
                    
$attribute=substr($attribute,0,$pos);
                }
                else
                    
$descending=false;

                if((
$attribute=$this->validateAttribute($attribute))!==false)
                    
$this->_directions[$attribute]=$descending;
            }
            if(!
$this->multiSort)
            {
                foreach(
$this->_directions as $attribute=>$descending)
                    return 
$this->_directions=array($attribute=>$descending);
            }
        }
    }
    return 
$this->_directions;
}

Returns the currently requested sort information.

public string link(string $attribute, string $label=NULL, array $htmlOptions=array ( ))
$attribute string the attribute name. This must be the actual attribute name, not alias. If it is an attribute of a related AR object, the name should be prefixed with the relation name (e.g. 'author.name', where 'author' is the relation name).
$label string the link label. If null, the label will be determined according to the attribute (see resolveLabel).
$htmlOptions array additional HTML attributes for the hyperlink tag
{return} string the generated hyperlink
Source Code: framework/web/CSort.php#165 (show)
public function link($attribute,$label=null,$htmlOptions=array())
{
    
$directions=$this->getDirections();
    if(isset(
$directions[$attribute]))
    {
        
$descending=!$directions[$attribute];
        unset(
$directions[$attribute]);
    }
    else
        
$descending=false;
    if(
$this->multiSort)
        
$directions=array_merge(array($attribute=>$descending),$directions);
    else
        
$directions=array($attribute=>$descending);

    if(
$label===null)
        
$label=$this->resolveLabel($attribute);
    
$url=$this->createUrl(Yii::app()->getController(),$directions);

    return 
$this->createLink($attribute,$label,$url,$htmlOptions);
}

Generates a hyperlink that can be clicked to cause sorting.

resolveLabel() method (available since v1.0.2)
public string resolveLabel(string $attribute)
$attribute string the attribute name.
{return} string the attribute label
Source Code: framework/web/CSort.php#194 (show)
public function resolveLabel($attribute)
{
    if((
$pos=strpos($attribute,'.'))!==false)
    {
        
$baseModel=CActiveRecord::model($this->modelClass);
        if((
$relation=$baseModel->getActiveRelation(substr($attribute,0,$pos)))!==null)
            return 
CActiveRecord::model($relation->className)->getAttributeLabel(substr($attribute,$pos+1));
        else
            return 
$baseModel->getAttributeLabel(substr($attribute,$pos+1));
    }
    return 
CActiveRecord::model($this->modelClass)->getAttributeLabel($attribute);
}

Resolves the attribute label based on label definition in the AR class. This will invoke CActiveRecord::getAttributeLabel to determine what label to use.

validateAttribute() method
public string validateAttribute(string $attribute)
$attribute string the attribute name (could be an alias) that the user requests to sort on
{return} string the real attribute name. False if the attribute cannot be sorted
Source Code: framework/web/CSort.php#275 (show)
public function validateAttribute($attribute)
{
    if(empty(
$this->attributes))
        
$attributes=CActiveRecord::model($this->modelClass)->attributeNames();
    else
        
$attributes=$this->attributes;
    foreach(
$attributes as $name=>$alias)
    {
        if(
$alias===$attribute)
            return 
is_string($name) ? $name $alias;
    }
    return 
false;
}

Validates an attribute that is requested to be sorted. The validation is based on attributes and CActiveRecord::attributeNames. False will be returned if the attribute is not allowed to be sorted. If the attribute is aliased via attributes, the original attribute name will be returned.