Yii1.1 AR Behavior - how to get alias?

Hello! I’m trying to write a SortableBehavior extends CActiveRecordBehavior.

It should automatically sort AR result

In simplified form it looks like:




<?php

class SortableBehavior extends CActiveRecordBehavior

{

    public $fieldName = "sort";

    public $sortDirection = "ASC";

    protected $_sortEnabled = true;


    public function beforeFind($event)

    {

        if ($this->_sortEnabled)

        {

            $this->owner->dbCriteria->order = "t." . $this->fieldName . " " . $this->sortDirection;

        }

        return parent::beforeFind($event);

    }

}



The problem is following:

I cannot get future table alias inside of beforeFind.

So, when I’m using “t” alias (like in the example above), and accessing a relation, i get a error “Unknown column ‘t.sort’ in ‘order clause’”, because of FROM part of query is: FROM tbl_category children_categories

When I’m don’t specify any alias, it works fine, until I request some Category::model()->with(“children_categories”)->findAll(), when I get error about “sort field is ambiguous” (it exists in different tables).

I’d like to know, what alias would be used in SQL query, but $this->owner->dbCriteria->alias is null at the time, when beforeFind is called.

Are there any workaround for this?

I found some bad variants:

  1. Rename field "sort" in every table, so where would be no ambiguity.

  2. Subclass CActiveRecord class, so it whould sort by itself.

  3. SubClass yii queryBuilder, and add some pattern replacement to it, for example, string like "{alias}" whould be automatically replaced to current table alias, while contructing SQL query.

Thanks, everyone, who tried to think about my problem

Made a workaround, now behavior doesn’t automatically sort table, but sorting could be applied with ->sorted(“tableAlias”) chain call.

The code:




<?php

class SortableBehavior extends CActiveRecordBehavior

{

    public $fieldName = "sort";

    public $sortDirection = "ASC";

    protected $_sortEnabled = false;

    protected $_tableAlias = "";

 

    public function sorted($tableAlias = null)

    {

        if (!is_null($tableAlias))

        {

            $this->_tableAlias = $tableAlias;

        }

        $this->_sortEnabled = true;

        return $this->owner;

    }


    public function beforeFind($event)

    {

        if ($this->_sortEnabled)

        {

            $field = ($this->tableAlias ? ("`" . $this->tableAlias . "`.") : "") . "`" . $this->fieldName . "`";

            $this->owner->dbCriteria->order = $field . " " . $this->sortDirection;

        }

        return parent::beforeFind($event);

    }

}



Usage:




$categroies = Category::model()->with('children_categories')->sorted("t")->findAll();

$items = Item::model()->sorted()->findAll($criteria);



Of course, there are some getters and setters to access _sortEnabled and _tableAlias, but I didn’t include it here, for briefness.