Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [ZendFramework] Tagi
Forum PHP.pl > Forum > PHP > Frameworki
CzarnyGsm
Witam,

Prosiłbym o sprawdzenie czy dobrze rozwiązałem problem z tagami w ZF. Przy okazji zoptymalizowany kod przyda się dla forumowiczów bo w sieci jest dość mało literatury odnośnie tagów. Zaznaczam, że kod działa, ale nie wiem czy jest on zgodny z zasadą MVC itp. konwencjami tworzenia we frameworku.

Utworzyłem 3 tabele w tym jedną z widokiem.
  1. --pcms_tag
  2. CREATE TABLE IF NOT EXISTS `pcms_tag` (
  3. `id` int(11) NOT NULL AUTO_INCREMENT,
  4. `title` varchar(40) CHARACTER SET utf8 DEFAULT NULL,
  5. PRIMARY KEY (`id`)
  6. ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
  7.  
  8.  
  9. --pcms_tag_articles
  10. CREATE TABLE IF NOT EXISTS `pcms_tag_articles` (
  11. `tag_id` int(11) NOT NULL,
  12. `article_id` int(11) NOT NULL,
  13. PRIMARY KEY (`tag_id`,`article_id`)
  14. ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
  15.  
  16. --pcms_tag_weights
  17. CREATE VIEW `pcms_tag_weights` AS SELECT
  18. `pcms_tag`.`id` AS `id`
  19. ,`pcms_tag`.`title` AS `title`
  20. ,count(0) AS `weight`
  21. FROM (`pcms_tag` JOIN `pcms_tag_articles`)
  22. WHERE (`pcms_tag`.`id` = `pcms_tag_articles`.`tag_id`)
  23. GROUP BY `pcms_tag`.`id` ORDER BY `pcms_tag`.`title`;


Niżej kod dwóch modeli:
  1. <?php
  2. class Application_Model_TagArticles extends Zend_Db_Table_Abstract
  3. {
  4. protected $_name = 'pcms_tag_articles';
  5.  
  6. public function addRelationship($articleId,$tagId){
  7. $row = $this->createRow();
  8. if ($row) {
  9. $row->tag_id = $tagId;
  10. $row->article_id = $articleId;
  11. $row->save();
  12. return TRUE;
  13. } else {
  14. throw new Zend_Exception('Nie można utworzyć użytkownika. Błąd bazy danych!');
  15. }
  16. }
  17.  
  18. }

  1. <?php
  2.  
  3. class Application_Model_Tag extends Zend_Db_Table_Abstract {
  4.  
  5. protected $_name = 'pcms_tag';
  6.  
  7. public function saveTags($articleId, $tags)
  8. {
  9. $validator = new Zend_Validate_Db_NoRecordExists(
  10. 'table' => $this->_name,
  11. 'field' => 'title'
  12. )
  13. );
  14. $tagsTab = explode(",", $tags);
  15. $modelTagArticles = new Application_Model_TagArticles();
  16. foreach ($tagsTab as $tag) {
  17. if ($validator->isValid($tag)){ // dodajemy tag do bazy danych
  18. $row = $this->createRow();
  19. if ($row) {
  20. $row->title = $tag;
  21. $row->save();
  22. $tagId = $this->getId($tag);
  23. $modelTagArticles->addRelationship($articleId, $tagId);
  24. } else {
  25. throw new Zend_Exception('Nie można dodać tagu. Błąd bazy danych!');
  26. }
  27. }else{
  28. $tagId = $this->getId($tag);
  29. $modelTagArticles->addRelationship($articleId, $tagId);
  30. }
  31.  
  32. }
  33. }
  34. public function getId($title){
  35. $select = $this->select();
  36. $select->from($this->_name, $this->_name.".id")
  37. ->where('title = ?', $title);
  38. $row = $this->fetchRow($select);
  39. return $row->id;
  40. }
  41.  
  42. }


W akcji kontrolera dodawania artykułu dodałem:
  1. ...
  2. $modelTag = new Application_Model_Tag();
  3. $modelTag->saveTags($articleId, $tags);
  4. ...

Po zaprojektowaniu powyższych struktur w widoku na stronie bez problemów można zaimplementować chmurkę tagów wykorzystując Zend_Tag.

Wiem, że kod nie jest rewelacyjny i dlatego proszę o jakieś uwagi, co należałoby zmienić w kodzie.
Z góry dziękuję za pomoc.
snapshot
Zmieniłbym tylko w Application_Model_Tag::saveTags() przekazywanie tagów. Zamiast stringu oddzielonego przecinkami wymusić przekazywanie gotowej tablicy. Odpuść sobie także walidację (Zend_Validate_Db_NoRecordExists). Ustaw sobie index unique na kolumnie title. Zaoszczędzisz sporą ilość zapytań do bazy wink.gif
I jeszcze zamiast $this->getId($tag); daj $this->id; Po zapisaniu rekordu automatycznie klucz główny wypełnia się wygenerowaną wartością.

Aha, no i zmień sobie silnik mysql na innodb aby wdrożyć transakcje.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.