Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [Doctrine] Po aktualizacji do wer. 1.1.3 nie działa createRoot() itp.., Po prostu nie można nic zrobić przy pomocy Nested Set
Sajrox
post 17.08.2009, 20:31:25
Post #1





Grupa: Zarejestrowani
Postów: 254
Pomógł: 7
Dołączył: 9.10.2007
Skąd: Poznań

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


Witam,

Czy ktoś także zauwazył problemy z Nested Set a mianowicie z funkcją  createRoot() itp ?

Po aktualizacji z wersji 1.1.2 do 1.1.3 są problemy z tą klasą. Kod który działał już nie działa.

  1.  
  2. $category = new Kategorie();
  3. $category->name = 'Root Category 1';
  4. $category->save();
  5.  
  6. $categoryTable = Doctrine::getTable('Kategorie');
  7.  
  8. $treeObject = $categoryTable->getTree();
  9. $treeObject->createRoot($category);
  10.  
  11.  





Go to the top of the page
+Quote Post
murwazy
post 17.08.2009, 21:41:42
Post #2





Grupa: Zarejestrowani
Postów: 53
Pomógł: 5
Dołączył: 13.04.2007
Skąd: Szczecin

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


nie zauwazylem zadnych problemow. co konkretnie jest nie tak?

sprawdzilem u siebie i mam tak
  1. $category = new Kategorie();
  2. $category->name = 'Root Category 1';
  3. //$category->save();
  4.  
  5. $categoryTable = Doctrine::getTable('Kategorie');
  6.  
  7. $treeObject = $categoryTable->getTree();
  8. $treeObject->createRoot($category);


Ten post edytował murwazy 17.08.2009, 21:45:39
Go to the top of the page
+Quote Post
Sajrox
post 18.08.2009, 11:37:44
Post #3





Grupa: Zarejestrowani
Postów: 254
Pomógł: 7
Dołączył: 9.10.2007
Skąd: Poznań

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


A więć. Dzisiaj usiadłem sobie i zrobiłem to samo co wczoraj i co ? Działa !

Może miałem jakiś zastój w Apache, cholera wie. Ale działa i to jest najważniejsze.


Ale mam kilka pytań do tego modułu w Doctrine.
1) Czy jest on bardzo wydajny przy budowie dynamicznie rozwijanego drzewa kategorii w ajaxie.
2) Po co są te pola w bazie "lft" i "rgt" czy mogą mi się jakoś przydać questionmark.gif


Dołączam także przykłąd mojej klasy do dodawania do bazy kategorii przy pomocy tego mechanizmu.
  1. /**
  2.   * Dodanie krotki do bazy
  3.   * @param $_POST['nazwa'] - nazwa kategorii
  4.   * @param $this->tblKategorie - nazwa tabeli
  5.   * @param $this->id - identyfikator otwartej kategorii (z $_GET)
  6.   * @return int
  7.   */
  8. public function dodaj()
  9. {
  10. $this->conn->beginTransaction();
  11.  
  12. $return = 0;
  13. try
  14. {
  15. if ($this->id == 0)
  16. {
  17. // Dodanie kategorii głównej
  18. $q = new $this->tblKategorie;
  19. $q->name = parent::POST('nazwa');
  20. }
  21. else {
  22. // Dodanie podkategorii do danej kategorii
  23. $q = Doctrine::getTable($this->tblKategorie)->findOneById($this->id);
  24.  
  25. // Tworzenie podkategorii
  26. $child = new $this->tblKategorie;
  27. $child->name = parent::POST('nazwa');
  28. $child->kategorie_id = $this->id;
  29. }
  30.  
  31. if ($q->isValid())
  32. {
  33. if ($this->id == 0) {
  34. // Dodanie kategorii i utworzenie z niej kategorii głównej
  35. $q->save();
  36. $treeObject = Doctrine::getTable($this->tblKategorie)->getTree();
  37. $treeObject->createRoot($q);
  38. }
  39. else {
  40. // Dodanie podkategorii do kategorii głównej
  41. $child->getNode()->insertAsLastChildOf($q);
  42. }
  43.  
  44. if ($this->conn->commit())
  45. $return = 1;
  46. }
  47. else
  48. $return = -1;
  49. }
  50. catch(Doctrine_Exception $e) {
  51. Lib_MyException::get($e);
  52. $this->conn->rollback();
  53. }
  54.  
  55. return $return;
  56. }
Go to the top of the page
+Quote Post
murwazy
post 18.08.2009, 12:37:49
Post #4





Grupa: Zarejestrowani
Postów: 53
Pomógł: 5
Dołączył: 13.04.2007
Skąd: Szczecin

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


widze ze moda na nieczytanie dokumentacji ciagle obecna ;-)

dodatkowo zerknij tu:
http://www.dbf.pl/faq/tresc.html?rozdzial=1#o1_9
metoda 3

mechanizm jest bardzo wydajny, ale od dynamicznego wyciagania dzieci ajaxem lepsze jest wyciagniecie calego drzewa i keszowanie go za pomoca dokryny albo frameworka.

"lft" i "rgt" cie nie interesuja, napisali nawet w dokumentacji, za to "level" jest uzyteczny.

twoja metoda do dodania wydaje mi sie malo uniwersalna. co bedzie, jesli model danych zaklada tlumaczenia? ja zrezygnowalem z pisania takiego kodu, tam gdzie potrzebuje dodaje po prostu te 3 linie (i ew modyfikuje je wg potrzeb):
  1. $record = new CategoryTree();
  2. $record->name = 'nowa kategoria podrzedna';
  3. //$record->Translation[$this->lang_s]->name = 'nowa kategoria podrzedna';
  4. //$record->Translation[$this->lang_s]->lang = $this->lang_s;
  5. $record->getNode()->insertAsLastChildOf(Doctrine::getTable('CategoryTree')->find($this->params['id']));
dodalem za to sprawdzenie czy drzewo istnieje i w razie potrzeb tworze je (oczywiscie dzieje sie to zanim mam mozliwosc wykonac cokolwiek na drzewie).
  1. if (!Doctrine::getTable('CategoryTree')->rootExist($this->lang_s_id)) Doctrine::getTable('CategoryTree')->addTree($this->lang_s_id);
jak widzisz tworze drzewa, ktore maja id jezyka jako roota, to mi zapewnia zroznicowana strukture dla kazdego z jezykow w systemie - ale to tak na marginesie.

warto za to "opakowac" sobie "przesuwanie" lisci/galezi w klasie bazowej dla klas *Table doktryny:
  1. public function nodeDown($id) {
  2. $record = $this->find($id);
  3. if ($record->getNode()->hasNextSibling()) {
  4. $sibling = $record->getNode()->getNextSibling();
  5. $record->getNode()->moveAsNextSiblingOf($sibling);
  6. }
  7. }
uzywam tego tak:
  1. $record = Doctrine::getTable('Cms_CategoryTree')->nodeDown($this->params['id']);
i sprawdza sie swietnie.

pozdrawiam

Ten post edytował murwazy 18.08.2009, 12:39:09
Go to the top of the page
+Quote Post
Sajrox
post 18.08.2009, 15:32:15
Post #5





Grupa: Zarejestrowani
Postów: 254
Pomógł: 7
Dołączył: 9.10.2007
Skąd: Poznań

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


Ciekawe smile.gif Co do wersji językowych to z tym nie miałem do czynienia jeszcze w Dictrine ale na pewno się z tym zapoznam.

Mam tylko pytanie co do Cachowania drzewa.

Kod który stosuję nie działa:
  1. $treeObject = Doctrine::getTable('Kategorie')
  2. ->useResultCache(true)
  3. ->getTree();



A co do komentowania to aż tak tragicznie ? winksmiley.jpg Hehe.

Jeszcze gdyby to nie był problem to napisz proszę jak np. wyciagasz dzieci kategorii na levelu 1. Chciałbm pobrać tylko dzieci danej kategorii (root) o levelu np. 1
W dokumentacji jest tylko wyciąganie całego drzewa bez mozliwości pobrania kategorii na danym poziomie sad.gif


Edit:
I jeszcze chciałbym zaproponować pewien sposób na sortowanie pozycji kategorii.

  1. public function move($idFor=0, $idTo=0)
  2. {
  3. $recordFor = Doctrine::getTable($this->tblKategorie)->find($idFor);
  4. $recordTo = Doctrine::getTable($this->tblKategorie)->find($idTo);
  5.  
  6. if ($recordFor['lft'] < $recordTo['lft'])
  7. $recordFor->getNode()->moveAsNextSiblingOf($recordTo);
  8. if ($recordFor['lft'] > $recordTo['lft'])
  9. $recordFor->getNode()->moveAsPrevSiblingOf($recordTo);
  10. }


metoda move() przesuwa nam kategorie na dowolne miejsce na liście. Możemy tutaj przesunąć kategorie z 2 na 20 miejsce na liście smile.gif



Ten post edytował Sajrox 18.08.2009, 16:55:57
Go to the top of the page
+Quote Post
murwazy
post 18.08.2009, 16:49:48
Post #6





Grupa: Zarejestrowani
Postów: 53
Pomógł: 5
Dołączył: 13.04.2007
Skąd: Szczecin

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


Cytat(Sajrox @ 18.08.2009, 16:32:15 ) *
Mam tylko pytanie co do Cachowania drzewa.

Kod który stosuję nie działa:

sprawdz to
  1. $q = Doctrine_Query::create();
  2. ->select('c.name, p.name, m.name')
  3. ->from('Category c')
  4. ->leftJoin('c.HottestProduct p')
  5. ->leftJoin('p.Manufacturer m')
  6. ->setHydrationMode(Doctrine::HYDRATE_ARRAY);
  7. ->useResultCache(true);
  8.  
  9. $treeObject = Doctrine::getTable('Category')->getTree();
  10. $treeObject->setBaseQuery($q);
  11. $tree = $treeObject->fetchTree();
  12. $treeObject->resetBaseQuery();
mozesz rownie dobrze "opakowac" ten kawalek kodu w zend_cache - wtedy wywalasz ->useResultCache(true);

Cytat(Sajrox @ 18.08.2009, 16:32:15 ) *
A co do komentowania to aż tak tragicznie ? winksmiley.jpg Hehe.

obawiam sie ze nie rozumiem:)

----- kurcze nie da sie opublikowac 2 postow po sobie? wystepuje jakis blad ale tresci nie ma...

Cytat(Sajrox @ 18.08.2009, 16:32:15 ) *
Jeszcze gdyby to nie był problem to napisz proszę jak np. wyciagasz dzieci kategorii na levelu 1. Chciałbm pobrać tylko dzieci danej kategorii (root) o levelu np. 1
W dokumentacji jest tylko wyciąganie całego drzewa bez mozliwości pobrania kategorii na danym poziomie sad.gif
tak jak juz pisalem keszuje cale drzewo i ew w szablonie daje if ($level == 1) {}.
potestuj uzycie czegos takiego:
  1. $q = Doctrine_Query::create();
  2. ->select('c.name, p.name, m.name')
  3. ->from('Category c')
  4. ->where('c.level<?', 2)
  5. ->setHydrationMode(Doctrine::HYDRATE_ARRAY)
  6. ->useResultCache(true);
  7.  
  8. $treeObject = Doctrine::getTable('Category')->getTree();
  9. $treeObject->setBaseQuery($q);
  10. $tree = $treeObject->fetchTree();
  11. $treeObject->resetBaseQuery();
ale zauwazylem ze czasem wychodza cuda jak sie zamiesza z zapytaniem.
inna sprawa ze masz metody getAncestors(), getDescendants(), getChildren().

no i obok fetchTree() masz do dyspozycji fetchBranch() - nie ma jej w manualu - polecam zerkac do api
http://www.doctrine-project.org/Doctrine_Tree_NestedSet/1_1

Cytat(Sajrox @ 18.08.2009, 16:32:15 ) *
I jeszcze chciałbym zaproponować pewien sposób na sortowanie pozycji kategorii.

  1. public function move($idFor=0, $idTo=0)
  2. {
  3. $recordFor = Doctrine::getTable($this->tblKategorie)->find($idFor);
  4. $recordTo = Doctrine::getTable($this->tblKategorie)->find($idTo);
  5. if ($recordFor['lft'] < $recordTo['lft'])
  6. $recordFor->getNode()->moveAsNextSiblingOf($recordTo);
  7. if ($recordFor['lft'] > $recordTo['lft'])
  8. $recordFor->getNode()->moveAsPrevSiblingOf($recordTo);
  9. }


metoda move() przesuwa nam kategorie na dowolne miejsce na liście. Możemy tutaj przesunąć kategorie z 2 na 20 miejsce na liście smile.gif

nie analizowalem tego algorytmu ale skoro mowisz ze dziala to pewnie dziala:)
uzywam wyzej/nizej/pierwszy/ostatni i dodatkowo mam przenoszenie lisci/galezi za pomoca ajaxa - drag&drop, nie mialem potrzeby takiego przesuniecia jak opisales.

pozdrawiam


Ten post edytował murwazy 18.08.2009, 20:34:13
Go to the top of the page
+Quote Post
Sajrox
post 19.08.2009, 10:59:39
Post #7





Grupa: Zarejestrowani
Postów: 254
Pomógł: 7
Dołączył: 9.10.2007
Skąd: Poznań

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


Dzieki wielkie za wyjaśnienie smile.gif

Generalnie co do wyciagania samych dzieci użyłem funkcji getChildren()

Jeszcze męczy mnie jeden problem:


Mam kod

  1.  
  2. $q = Doctrine::getTable('FirmyOpisy')->findOneByFirmyId(1);
  3.  
  4. $q->opis = $opis;
  5.  
  6. $q->save();
  7.  


Otóż gdy w tabeli FirmyOpisy jest krotka o firmy_id = 1 to wszystko jest ok jednak gdy jej nie ma wywala błąd:

  1.  
  2. Fatal error: Call to undefined method stdClass::save() in ...
  3.  


Jakby nie mogło po prostu nic nie wyświetlić albo zwrócić false a tutaj taki błąd. Można jakoś przed wywołaniem save() sprawdzić czy krotka istnieje w tabeli ?




Go to the top of the page
+Quote Post
murwazy
post 19.08.2009, 11:38:18
Post #8





Grupa: Zarejestrowani
Postów: 53
Pomógł: 5
Dołączył: 13.04.2007
Skąd: Szczecin

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


Cytat(Sajrox @ 19.08.2009, 11:59:39 ) *
Jakby nie mogło po prostu nic nie wyświetlić albo zwrócić false a tutaj taki błąd. Można jakoś przed wywołaniem save() sprawdzić czy krotka istnieje w tabeli ?

zwraca false, tylko ze pozniej na tym false wywolujesz metode save()
  1. if ($q !== false) $g->save();
  2. // albo
  3. if ($q['id']) $g->save();

pozdrawiam

Ten post edytował murwazy 19.08.2009, 11:39:10
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 - 20:25