Access query criteria from beforeFind()

In the class documentation for CActiveRecord::onBeforeFind it says:

This event is triggered from inside CActiveRecords with the beforeFind() method. But the criteria object is never passed along (see for example the implementation of query()). So $event->criteria is always null.

I wonder, how this is supposed to be used. I can hardly think of a situation where you would call beforeFind($criteria) manually.

A little more background:

From a behavior i want to alter the query critieria on beforeFind() for the next query only. So i don’t want to change the scope criteria with $this->owner->dbCriteria or something. I tried to modify $event->criteria (or set a new criteria if it’s null) but found out that it does not work as expected (see above).

Any idea for a workaround?

This is fixed in the current github version.

However, up to today this does not work if the beforeFind() is applied to any relation.

Regards,

Just updated the documentation for CModelEvent::$criteria : https://github.com/yiisoft/yii/pull/1103

This property is not used anymore since yii 1.1.7.

Modifying $this->owner->dbCriteria is the right way since after a find the criteria will be reset to default scope. Changes are only valid for next query.

This currently does not work for relational queries:

Bug: https://github.com/yiisoft/yii/issues/93

Solution: https://github.com/yiisoft/yii/pull/1102

There are still these wrong comments in CActiveRecord:




    /**                                                                                                                      

     * This event is raised before an AR finder performs a find call.                                                        

     * In this event, the {@link CModelEvent::criteria} property contains the query criteria                                 

     * passed as parameters to those find methods. If you want to access                                                     

     * the query criteria specified in scopes, please use {@link getDbCriteria()}.                                           

     * You can modify either criteria to customize them based on needs.                                                      

     * @param CModelEvent $event the event parameter                                                                         

     * @see beforeFind                                                                                                       

     */                                                                                                                      

    public function onBeforeFind($event)                                                                                     

    {                                                                                                                        

        $this->raiseEvent('onBeforeFind',$event);                                                                            

    }

Only the first sentence is still valid.

And here, findBySql and findAllBySql is missing:





    /**                                                                                                                      

     * This method is invoked before an AR finder executes a find call.                                                      

     * The find calls include {@link find}, {@link findAll}, {@link findByPk},                                               

     * {@link findAllByPk}, {@link findByAttributes} and {@link findAllByAttributes}.                                        

     * The default implementation raises the {@link onBeforeFind} event.                                                     

     * If you override this method, make sure you call the parent implementation                                             

     * so that the event is raised properly.                                                                                 

     */                                                                                                                      

    protected function beforeFind()                                                                                          

    {                                                                                                                        

        if($this->hasEventHandler('onBeforeFind'))                                                                           

        {                                                                                                                    

            $event=new CModelEvent($this);                                                                                   

            $this->onBeforeFind($event);                                                                                     

        }                                                                                                                    

    }



Thanks for reporting, just fixed the documentation.

https://github.com/yiisoft/yii/commit/f6a351cf5b177f35c6dcb5f5274dbcb7ba0d7cb8

If you have anything to add, please add a comment on github.