Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [OPT 1.1.5] Jakie interfejsy dla obiektu aby mógł być iterowany w section jak array?
tornax
post 25.02.2011, 13:15:49
Post #1





Grupa: Zarejestrowani
Postów: 25
Pomógł: 0
Dołączył: 11.10.2006

Ostrzeżenie: (0%)
-----


Mam problem z iterowaniem w OPT 1.1.5 obiektów które mają się zachowywać jak tablice (array).

(Narazie nie zamiejszczam wszystkich definicji klas ponieważ to zazwyczaj odstrasza od dalszego czytania)

Mam klasę która ma taki oto nagłówek
  1. class ormcollection implements SeekableIterator, ArrayAccess, Countable

oraz kawałek kodu który zwraca obiekt tej klasy (linijka 1.) oraz ładuje do odpowiedniej sekcji w templatce (linijka 2.)
  1. $data = configurator::finder()->getAll();
  2. $this->view->assign('configurator', $data);

obiekt $data (klasa ormcollection) przechowywuje w prywatnej tablicy obiekty klasy configurator, które odzwierciedlają poszczególne rekordy w bazie danych
  1. class configurator extends orm {
  2.  
  3. public $name;
  4. public $active = 0;
  5.  
  6. public function __construct(){
  7. parent::__construct('configurator');
  8. }
  9.  
  10. public static function finder($className=__CLASS__){
  11. return parent::finder($className);
  12. }
  13. }

Teraz templatka wygląda do tego banalnie
  1. {section=configurator}
  2. {$configurator.name}
  3. {/section}

... ale nic nie generuje ... więc dla sprawdzenia czy działa iteracja i są pobierane dane wrzuciłem pare linijek do testu
  1. $data = configurator::finder()->getAll();
  2.  
  3. var_dump('foreach');
  4. foreach($data as $r){
  5. var_dump($r['name'], $r->name);
  6. }
  7.  
  8. var_dump('for');
  9. for($i=0; $i < count($data); $i++){
  10. var_dump($data[$i]['name'], $data[$i]->name);
  11. }
  12.  
  13. $this->view->assign('configurator', $data);

z wynikiem
  1. string(7) "foreach"
  2. string(10) "Deskorolki"
  3. string(10) "Deskorolki"
  4. string(12) "Poduszkowiec"
  5. string(12) "Poduszkowiec"
  6. string(3) "for"
  7. string(10) "Deskorolki"
  8. string(10) "Deskorolki"
  9. string(12) "Poduszkowiec"
  10. string(12) "Poduszkowiec"

Iteracja działa i zwraca wyniki ale nie w OPT, aby upewnić się, że samo OPT działa wykonałem taki test
  1. $this->view->assign('configurator', array(array('name'=>'pies'), array('name'=>'kot')));

rezultat
  1. pieskot

Test co prawda na tablicach ale przynjmniej wiem, że przekazuje zmienne. Moje podejżenie jest takie, że w ormcollection brakuje jakiegoś dodatkowego interfejsu ale nie potrafię powiedzieć jakiego bo ze wszystkimi obecnymi pętle for i foreach działąją bez problemu.

Czy ktoś ma może jakiś pomysł ?
Go to the top of the page
+Quote Post
Zyx
post 25.02.2011, 13:59:01
Post #2





Grupa: Zarejestrowani
Postów: 952
Pomógł: 154
Dołączył: 20.01.2007
Skąd: /dev/oracle

Ostrzeżenie: (0%)
-----


Z tego, co pamiętam jeszcze z OPT 1.x, sekcje tam mogły iterować tylko po tablicach. Że tak się Ciebie zapytam... dlaczego męczysz się z tą wersją, kiedy ona jest już od dobrych 3 lat nierozwijana? W OPT 2.x sekcje mogą iterować po wszystkim.


--------------------
Specjalista ds. głupich i beznadziejnych, Zyx
Nowości wydawnicze: Open Power Collector 3.0.1.0 | Open Power Autoloader 3.0.3.0
Go to the top of the page
+Quote Post
tornax
post 25.02.2011, 14:40:22
Post #3





Grupa: Zarejestrowani
Postów: 25
Pomógł: 0
Dołączył: 11.10.2006

Ostrzeżenie: (0%)
-----


@Zyx, Bóg mi świadkiem, że gdybym nie musiał to bym się nie męczył.

W ramach projektu który został mi przydzielony muszę wykonać poważne zmiany w funkcjonalności pewnego sklepu internetowego, takiego który jeszcze był pisany z użyciem OPT 1.1.2 (aktualizacje w między czasie zrobiłem).

Ponieważ dotychczasowy sposób obsługi modelu lekko mówiąc ssie potrzebowałem napisać sobie coś sensowniejsego - wiec mam taki prosty ORM (pisany tak w myśl pomysłu TActiveRecord z Prado Framework) wykorzystujący dotychczasowy kod aby na wszelki wypadek nic się nie rozkraczyło, nie było konieczności podpisanania jakiegoś zewnętrznego ORM (kupa roboty sklep juz jest bardzo rozbudowany).

Long story short: sodoma i gomora i ciskanie gromami


Może mógłbyś mnie pokierować gdzie przychodzące do sekcji zmienne są obsługiwane? Podejżewam, że sprawdzane jest czy zmienna jest obiektem a nie sprawdzane jest czy implemntuje jakieś iteratory w konsekwencji obiekt nie jest obsługiwany jako tablica. Modyfikacja zapewne góra kilku linijek (mam nadzieje), a jak kojarze to gałąź 2.x nie jest kompatybilna wstecznie z 1.x

Ten post edytował tornax 25.02.2011, 14:42:29
Go to the top of the page
+Quote Post
Zyx
post 25.02.2011, 22:06:02
Post #4





Grupa: Zarejestrowani
Postów: 952
Pomógł: 154
Dołączył: 20.01.2007
Skąd: /dev/oracle

Ostrzeżenie: (0%)
-----


Tak, gałąź 2.x została przepisana całkowicie od nowa (m.in. po to, by wyeliminować tego typu idiotyzmy, z którymi teraz się męczysz) i nie jest kompatybilna ani pod kątem API, ani pod kątem języka szablonów.

Ogólnie kody instrukcji możesz znaleźć w pliku opt.instruction.php. Każda instrukcja ma własną klasę, gdzie obsługiwana jest kompilacja poszczególnych znaczników do kodu PHP. Klasa optSection jest gdzieś na początku tego pliku. To, co Ci jest najbardziej potrzebne, znajduje się w metodzie showAction(). Najważniejszy kod to te linijki:

  1. if(is_null($state))
  2. {
  3. $output .= ' if(is_array('.$link.') && ($__'.$name.'_cnt = sizeof('.$link.')) > 0){ ';
  4. }
  5. else
  6. {
  7. if($this -> tpl -> statePriority == OPT_PRIORITY_NORMAL)
  8. {
  9. $output .= ' if('.$state.' && is_array('.$link.') && ($__'.$name.'_cnt = sizeof('.$link.')) > 0){ ';
  10. }
  11. else
  12. {
  13. $output .= ' if('.$state.'){ if(is_array('.$link.') && ($__'.$name.'_cnt = sizeof('.$link.')) > 0){ ';
  14. }
  15. }


Jak widzisz, odpowiadają one za wygenerowanie kodu PHP sprawdzającego typ i zliczającego elementy tablicy. Musisz je zastąpić tak, aby akceptowały też obiekty implementujące odpowiednie interfejsy. Na wszelki wypadek radzę Ci też poprawić trochę linijek powyżej - nie wiem, czy korzystasz z sekcji dynamicznych, ale na wszelki wypadek popraw i je, gdyby ktoś miał to jeszcze rozwijać, by w Ciebie gromami nie rzucał smile.gif.

Po tym zabiegu musisz jeszcze skoczyć do sectionBegin() i poprawić tam jedną drobną rzecz:

  1. if($this->sections[$this->nesting]['order'] == 'reversed')
  2. {
  3. $this -> compiler -> out(' for($__'.$name.'_id = $__'.$name.'_cnt - 1; $__'.$name.'_id >= 0; $__'.$name.'_id--){ $__'.$name.'_val = &'.$this->sections[$this->nesting]['link'].'[$__'.$name.'_id]; ');
  4. }
  5. else
  6. {
  7. $this -> compiler -> out(' foreach('.$this->sections[$this->nesting]['link'].' as $__'.$name.'_id => &$__'.$name.'_val){ ');
  8. }


Jak widzisz, do wyświetlania sekcji w odwróconej kolejności wykorzystywana jest pętla for, zatem jeśli korzystasz z tego, dobrze by było implementować ArrayAccess. Z kolei dla porządku normalnego jest foreach, tylko tam przy generowaniu zmiennej wartości OPT wstawia brzydki znaczek referencji, który nie bardzo będzie chciał współpracować z Twoimi obiektami. Usuwasz go i problem załatwiony. Identyczny symbol masz też przy pętli for.

Generalnie jak chcesz sekcje odwrócone, możesz zastosować myk, który zaimplementowałem w formacie Objective do OPT 2.0. Tam najpierw jedziemy pętlą foreach po iteratorze i budujemy tablicę wartości. Następnie ją odwracamy i wprowadzamy do właściwej pętli. Może zbyt efektywne to nie jest, ale dla ogólnego przypadku jest to jedyna metoda. Ewentualnie, skoro już robisz konkretne obiekty, możesz tu zaimplementować to, co Ci najbardziej pasuje.

Ten post edytował Zyx 25.02.2011, 22:06:42


--------------------
Specjalista ds. głupich i beznadziejnych, Zyx
Nowości wydawnicze: Open Power Collector 3.0.1.0 | Open Power Autoloader 3.0.3.0
Go to the top of the page
+Quote Post
tornax
post 28.02.2011, 10:05:38
Post #5





Grupa: Zarejestrowani
Postów: 25
Pomógł: 0
Dołączył: 11.10.2006

Ostrzeżenie: (0%)
-----


Dzięki wielkie za pomoc i wskazanie odpowiednich linii kodu, przyszedłem dziś, przeczytałem odpowiedź i w tej chwili podstawowe sekcje działają, co do dynamicznych i odwróconych to nigdzie w dotychczasowym kodzie ich nie widziałem, sam za mało jeszcze robiłem przy OPT aby myśleć o tym co ciekawego można by zrobić, terminy gonią i są narazie bardziej priorytetowe sprawy. Kudos
Go to the top of the page
+Quote Post
Marek Rynarzewsk...
post 2.09.2012, 18:59:42
Post #6





Grupa: Zarejestrowani
Postów: 3
Pomógł: 0
Dołączył: 7.11.2011

Ostrzeżenie: (0%)
-----


Jakie obiekt udoskonalający tablicę musi implementować interfejsy by móc być użyty w pętli foreach?
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 19.04.2024 - 08:27