Replacement Model Search Function

Ok so this is one of the last things I need to know before I can reprogram everything in Yii2.

We always had this function in models:




	public function search()

	{

		// Warning: Please modify the following code to remove attributes that

		// should not be searched.


		$criteria=new CDbCriteria;


		$criteria->compare('title_id',$this->title_id);

		$criteria->compare('subjects_id',$this->subjects_id);

		$criteria->compare('main',$this->main);


		return new CActiveDataProvider(get_class($this), array(

			'criteria'=>$criteria,

		));

	}



Unfortunately I have not yet found a good way of replacing this, namely because compare no longer exists.

The only way I have found was to create middle tier models to replicate the behaviour.

There is a thread on this: https://github.com/yiisoft/yii2/issues/2002#issuecomment-33351669 but there doesn’t seem to be any decision on how to progress on this.

What is the best way to progress?

Gii?

I think with Yii2 you will have 2 separate model classes as you generate your CRUD - one for create/update/delete and the other for search. So if you had a model named Post in Yii 1.x… you will have something like Post and PostSearch generated in Yii2.

So now, depending on your application design, you may want to check, how you can use Gii to generate all of your SearchModels, and then alter your code to point to the Search model. Not sure how challenging this is for you. You may want to see if you can have a BaseController Class and extend that through parameters.

It is a bit challenging, hence the reason why I haven’t used Gii.

I actually have a full application with 10,000’s of lines of code in it already. I am not start afresh hence why Gii hasn’t been used up until now.

I have over 60 models which brings my new total to 120 using a new search model…hmmm

I actually found a good way of doing this now without having to add search models.

Below I give a real world working example, I simply convert my single search function to:




	/**

	 * Retrieves a list of models based on the current search/filter conditions.

	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.

	 */

	public function search($type = 'books')

	{

		$query = static::find();

		$dataProvider = new ActiveDataProvider([

			'query' => $query

		]);

		$this->addCondition($query, 'id');

		$this->addCondition($query, 'series_id');

		$this->addCondition($query, 'grade');

		$this->addCondition($query, 'title', true);

		$this->addCondition($query, 'subtitle', true);

		$this->addCondition($query, 'description', true);

		$query->andWhere([ 'deleted' => 0 ]);

		if($type == 'books'){

			$query->andWhere(['not in', 'type', [5, 6]]);

		}else{

			$query->andWhere(['in', 'type', [5, 6]]);

		}

		$query->orderBy(['id' => SORT_DESC]);

		return $dataProvider;

	}

	

	protected function addCondition($query, $attribute, $partialMatch = false)

	{

		$valid = null;

		if(isset($this->$attribute)){

			$value = $this->$attribute;

		}

		if(trim($value) === ''){

			return;

		}

		if($partialMatch){

			$query->andWhere(['like', $attribute, $value]);

		} else {

			$query->andWhere([$attribute => $value]);

		}

	}



And now you have a template by which to rewrite all your models search functions easily from Yii1 to Yii2.

Good to note though that this still does not solve using operators like < > >= etc in the search string within widgets like gridview.