Mam taki oto problem. Chciałbym zmodyfikować {summary} w template CGridView - domyślnie {summary} wyświetla dane w takich sposób: {start} - {end} z {count}. Mam przykładową bazę danych bloga z postami, gdzie posty są przypisane do ich autora. Ja chciałbym w {summary} wyświetlić wyniki, które wskazywałyby ile jest łącznie postów danego użytkownika oraz ile jest łącznie postów wszystkich użytkowników w całej bazie danych. Coś na zasadzie {zlicz wszystkie posty przypisane do aktualnie zalogowanego użytkownika} - {zlicz wszystkie posty w bazie danych}. Ewentualnie jeśli byłoby to bardzo trudne aby zrobić to w CGridView to mógłbym to zrobić niezależnie od CGridView. Aczkolwiek chciałbym, aby to było związane z CGridView, a to dlatego, że: Tworzę na przykład kilka kategorii postów dla wszystkich użytkowników: np. samochody, książki itp. czyli zwyczajne działy. I później np. użytkownik filtrując swoje posty wyswietla wszystkie swoje posty z działu "samochody", to chciałbym, żeby to podsuomwanie o którym pisałem powyżej w sytuacji, gdy ktoś wyswietla posty z danego działu - wyświetlało takie zestawienie: {zlicz posty użytkownika z działu samochody} - {zlicz wszystkie posty w bazie z działu samochody}.
Czy ktoś mógłby mnie jakoś naprowadzić na rozwiązanie tego problemu?
Thommee dzięki za naprowadzanie. Twoja metoda działa, ale nie we wszystkich przypadkach. Nie uwzglednia sytuacji, gdy np. filtruje posty, tj. gdy chce aby cgridview wyświetlił mi posty z działu samochody- czyli. ilość Twoich postów z działu samochody / ilosć wszystkich postów w bazie z działu samochody. Jak dostosować summaryText, aby "widział" filtrowanie? Bo przykład podany przez Ciebie poniżej zawsze wyswietla to samo, czyli ilość postów z bazy gdzie id wprowadzajacego = id zalogowanego (bez uwzglednienia filtrowania) / ilość wszystkich postów (bez uwzględnienia filtrowania).
Thommee dzięki wielkie, już prawie wszystko działa z jedynym problemem:) Ja w dataProvider używaniem metody search z modelu, ale z uwzględnieniem zakresu przy wyszukiwaniu tj. w modelu mam zakres “owner”
public function scopes()
{
return array(
'owner'=>array(
'condition'=>"userid = ".Yii::app()->user->getId(),
),
}
Thommee, zauważyłem, że kod działa poprawnie pod warunkiem, że ‘dataProvider’=>$model->owner()->search(), znajduje się pod summaryText. Zaś gdy ‘dataProvider’=>$model->owner()->search(), znajduje się nad summaryText, to działanie jest błędne. Czy to normalne zachowanie? Czy kolejność wpisu ‘dataProvider’ w cgridview powinna mieć znaczenie ?
Tak, to normalne. Celowo przeniosłem fragment " ‘dataProvider’=>$model->owner()->search(), " niżej.
Zwróć uwagę na to, że $model zawsze wskazuje na ten sam obiekt (to samo miejsce w pamięci). Dlatego: gdy " ‘dataProvider’=>$model->owner()->search(), " uruchomisz jako pierwsze (wraz ze scopem “owner()”), to w kolejnych wywołaniach masz już ten scope zaaplikowany. Nawet gdy niżej robisz $model->search() to scope owner nadal jest aktywny, co powoduje niechciane zachowanie.
Thommee, masz u mnie browara:) Dzięki za pomoc. A tak przy okazji, mogę gdzieś w dokumentacji yii przeczytać o tym konkretnym zachowaniu? tj. kolejności wywołania obiektu $model w widoku, czy może to zachowanie niezależne od yii tylko specyfika php?
Jest to specyfika php. Pracujesz na tym samym obiekcie więc jeśli zrobisz w nim zmiany w 1. wywołaniu, to drugie będzie pracować na zmienionym obiekcie.
Thomee, mam jeszcze pytanko, w kodzie poniżej dodałem do metody search dodatkowe externalCriteria - jak mogę sprawdzić w widoku, czy metoda search jest wywołana z dodatkowymi externalCriteria, czy też externalCriteria jest puste?. Np chcę w widoku co innego wyswietlić gdy externalCriteria jest puste, i też co innego gdy externalCriteria zawiera jakieś elementy?
/**
* @param array $externalCriteria kryteria
* @return CActiveDataProvider
*/
public function search(array $externalCriteria = array()) // <= dodatkowe kryteria
{
$criteria=new CDbCriteria;
$criteria->mergeWith($externalCriteria); // <= merge kryteriów z filtrami
w kontrolerze sprawdzać czy są externalCriteria i w zależności od tego czy są - do widoku przekazać $dataProvider1 lub $dataProvider2. W samym widoku sprawdzasz czy istnieje $dataProvider1 - jeśli tak to pokazujesz dane w pierwszy sposób, analegicznie dla $dataProvider2.