Frage zu Yiis CActiveDataProvider Code

Hallo zusammen,

ich schaue mir gerade die Funktion fetchData() in CActiveDataProvider.php (Yii 1.1.4) an und frage mich, ob ich einfach nur Tomaten auf den Augen habe oder wofür $baseCriteria dort gebraucht wird?! Die DbCriteria des Models wird zuerst ausgelesen und dann 1-2 mal unverändert wieder gesetzt.

Kann mir bitte einer erklären welchen Sinn und Zweck das haben soll?

Hier der Code (CActiveDataProvider.php; Line 104-124):


	/**

     * Fetches the data from the persistent data storage.

     * @return array list of data items

     */

	protected function fetchData()

	{

		$criteria=clone $this->getCriteria();

		$baseCriteria=$this->model->getDbCriteria(false);

		if(($pagination=$this->getPagination())!==false)

		{

			if($baseCriteria!==null)

				$this->model->setDbCriteria(clone $baseCriteria);

			$pagination->setItemCount($this->getTotalItemCount());

			$pagination->applyLimit($criteria);

		}

		if(($sort=$this->getSort())!==false)

			$sort->applyOrder($criteria);


		$this->model->setDbCriteria($baseCriteria);

		return $this->model->findAll($criteria);

	}

Vielen Dank und schönen Gruß

Soweit ich das sehe, ist das nötig, damit das "Standard"-DBCriteria (das z.B. Kritierien aus einem Defaultscope liefert) des aktuellen Models nicht überschrieben wird. Achte auf die clone-Anweisungen! Würde man das nicht so machen, liefe man Gefahr, dass z.B. die Pagerkriterien (limit) im Defaultkriterium des Models gesetzt werden. Wird das Model dann während des Requests nochmal verwendet, würden plötzlich die Pagersettings vom ActiveDataProvider übernommen.

Hauptursache ist, dass Objekte in PHP 5 immer als Referenz übergeben werden.

Hoffe, ich konnte das jetzt überhaupt verständlich rüberbringen :)

Hallo Mike,

vielen Dank für deine Antwort.

Alles was du schreibst leuchtet mir ein und ich habe es auch genau so verstanden, allerdings trifft das zwar exakt auf $criteria zu nicht jedoch auf $baseCriteria, weil es nicht verändert wird.

Ausgehend von der Annahme, dass all das nur Sinn ergibt, wenn die DbCriteria des Models irgendwo verändert wird, habe ich mich mal durch den Code gehangelt und bin am Ende auch fündig geworden.

Für den (unwahrscheinlichen) Fall, dass das sonst noch jemanden interessiert:

  1. fetchData (CActiveDataProvider): Z.116 -> getTotalItemCount (CDataProvider): Z.176 -> calculateTotalItemCount (CActiveDataProvider): Z. 152 -> count (CActiveRecord): Z. 1444 -> applyScopes (CActiveRecord): Z. 1253 -> Das DbCriteria des Models wird am Ende von applyScopes auf NULL gesetzt.

An dieser Stelle kommt also das zum Tragen was du auch geschrieben hast. Würde man die DbCriteria nicht ‘sichern’ und später wiederherstellen, dann wäre die DbCriteria des Models (hauptsächlich der DefaultScope) nach dem Aufruf von getTotalItemCount() leer und würde bei einer weiteren Verwendung im Request nicht mehr angewandt.

Meine Frage ist somit geklärt und vermutlich hilft dieser Beitrag auch sonst keinem, aber ich hasse diese unvollständigen Topics, die sich irgendwann im Sand verlaufen ;)

Danke und schönen Gruß

Schön, dass du’s rausgefunden hast.

Weiß nicht, obs dir auch so geht, aber ich find, es macht immer wieder Spaß, sich ab und an in die "Innerereien" des Frameworks reinzuknien (schönes Bild… ). Das hilft fürs Verständnis des Ganzen ungemein.

Absolut! Ich schaue oft direkt in den Code um die Funktionsweisen und die Zusammenhänge besser zu verstehen bzw. au détail zu sehen. Dashalb finde ich es auch hervorragend, dass in der Doku nun die Codeauszüge der entsprechenden Funktionen direkt mit drin stehen.

Knietief durch ein Meer aus Bytes waten :lol: