Yvision.kz
kk
Разное
Разное
399 773 постов41 подписчиков
Всяко-разно
0
04:07, 16 февраля 2011

Zend Framework: создаем блог. Шаг 2

Продолжаем копипасту разработку блога на Zend Framework. В планах на этот раз у нас создание категорий, отображение постов в них и вывод комментариев к постам. Готовы? Поехали.

Начнем с моделей. Нам нужно вывести список категорий и при выборе определенной категории, вывести посты принадлежащие ей. Давайте добавим в нашу модель постов новый метод для выбора постов по ID'шнику категории. Вот полный код обновленной модели постов.

 

 

 

  1. <?php
  2.  
  3. /**
  4.  * Posts model
  5.  *
  6.  * @author Kanat Gailimov, http://gailimov.info
  7.  * @copyright Copyright (c) Kanat Gailimov (http://gailimov.info) 2011
  8.  */
  9.  
  10. class Application_Model_DbTable_Posts extends Zend_Db_Table_Abstract
  11. {
  12. /**
  13.   * Db table name
  14.   *
  15.   * @var string
  16.   */
  17. protected $_name = 'zf_posts';
  18.  
  19. /**
  20.   * Get post by ID
  21.   *
  22.   * @param int $id ID of post
  23.   * @return array
  24.   */
  25. public function getById($id)
  26. {
  27. $id = intval($id);
  28. $row = $this->fetchRow('id = ' . $id);
  29. if (!$row) {
  30. throw new Exception('Ахтунг! Выборка поста не удалась :(');
  31. }
  32. return $row;
  33. }
  34.  
  35. /**
  36.   * Get by category's ID
  37.   *
  38.   * @param int $categoryId ID of category
  39.   * @return array
  40.   */
  41. public function getByCategoryId($categoryId)
  42. {
  43. $categoryId = intval($categoryId);
  44. // Формируем условие запроса
  45. $select = $this->select()->where('category_id = ' . $categoryId)
  46. ->order('created_at DESC')
  47. ->order('id DESC');
  48. // Выполняем запрос
  49. $row = $this->fetchAll($select);
  50. if (!$row) {
  51. throw new Exception('Ахтунг! Выборка категорий не удалась :(');
  52. }
  53. return $row->toArray();
  54. }
  55. }

 

 

 

Как видите, мы добавили метод getByCategoryId($categoryId). Он принимает в качестве параметра ID'шник категории и возвращает посты соотвествующие ей в виде массива. Обратите внимание на условия запроса: они образуют как бы "паровозик" из методов. Также нам нужно получать данные по самой категории. А именно название (а если бы были мета-теги, то и их). Для этого нам нужно создать еще одну модель для категорий. Приведу ее код:

 

 

 

  1. <?php
  2.  
  3. /**
  4.  * Categories model
  5.  *
  6.  * @author Kanat Gailimov, http://gailimov.info
  7.  * @copyright Copyright (c) Kanat Gailimov (http://gailimov.info) 2011
  8.  */
  9.  
  10. class Application_Model_DbTable_Categories extends Zend_Db_Table_Abstract
  11. {
  12. /**
  13.   * DB table name
  14.   *
  15.   * @var string
  16.   */
  17. protected $_name = 'zf_categories';
  18.  
  19. /**
  20.   * Get by ID
  21.   *
  22.   * @param int $id ID
  23.   * @return array
  24.   */
  25. public function getById($id)
  26. {
  27. $id = intval($id);
  28. $row = $this->fetchRow('id = ' . $id);
  29. if (!$row) {
  30. throw new Exception('Ахтунг! Выборка данных по категории не прошла :(');
  31. }
  32. return $row;
  33. }
  34. }

 

 

 

Здесь у нас метод, принимающий в качестве параметра ID'шник и возращающий данные по категории соответствующей ему. Теперь нам нужно создать модель для комментариев. В нем будет метод, выбирающий комментарии по ID'шнику поста. Давайте напишем его:

 

 

 

  1. <?php
  2.  
  3. /**
  4.  * Comments model
  5.  *
  6.  * @author Kanat Gailimov, http://gailimov.info
  7.  * @copyright Copyright (c) Kanat Gailimov (http://gailimov.info) 2011
  8.  */
  9.  
  10. class Application_Model_DbTable_Comments extends Zend_Db_Table_Abstract
  11. {
  12. /**
  13.   * DB table name
  14.   *
  15.   * @var string
  16.   */
  17. protected $_name = 'zf_comments';
  18.  
  19. /**
  20.   * Get comments by post's ID
  21.   *
  22.   * @param int $postId ID of post
  23.   * @return array
  24.   */
  25. public function getByPostId($postId)
  26. {
  27. $postId = intval($postId);
  28. $row = $this->fetchAll('post_id = ' . $postId);
  29. if (!$row) {
  30. throw new Exception('Ахтунг! Попытка получить комменты не удалась :(');
  31. }
  32. return $row->toArray();
  33. }
  34. }

 

 

 

Давайте теперь изменим наш контроллер. Я сразу приведу готовый код и ниже поясню:

 

 

 

  1. <?php
  2.  
  3. class IndexController extends Zend_Controller_Action
  4. {
  5.  
  6. public function init()
  7. {
  8. // Уставливаем название блога
  9. $this->view->title = 'Тестовый блог на Zend Framework';
  10. // Устанавливаем разделитель для тега title с помощью хелперов
  11. // headTitle() и setSeparator()
  12. $this->view->headTitle()->setSeparator(' | ');
  13. // Передаем заголовок в тег title, с помошью хелпера headTitle()
  14. $this->view->headTitle($this->view->title);
  15.  
  16. // Создаем экземпляр модели категорий
  17. $categories = new Application_Model_DbTable_Categories();
  18. // Выбираем все категории
  19. $this->view->categories = $categories->fetchAll();
  20. }
  21.  
  22. public function indexAction()
  23. {
  24. // Создаем экземпляр модели постов
  25. $posts = new Application_Model_DbTable_Posts();
  26. // Выбираем все посты
  27. // Формируем условие
  28. $select = $posts->select()->order('created_at DESC')
  29. ->order('id DESC');
  30. // Выполняем запрос
  31. $this->view->posts = $posts->fetchAll($select);
  32. }
  33.  
  34. /**
  35.   * View post
  36.   *
  37.   * @return void
  38.   */
  39. public function postAction()
  40. {
  41. // Берем ID'шник из параметра
  42. $id = intval($this->_getParam('id', 0));
  43. if ($id > 0) {
  44. // Создаем экземпляр модели постов и выбираем посты по ID
  45. $post = new Application_Model_DbTable_Posts();
  46. $this->view->post = $post->getById($id);
  47. // Устанавливаем заголовок для поста в тег title
  48. $this->view->postTitle = $this->view->post['title'];
  49. $this->view->headTitle($this->view->postTitle);
  50. // Получаем комменты к посту
  51. $comments = new Application_Model_DbTable_Comments();
  52. $this->view->comments = $comments->getByPostId($id);
  53. }
  54. }
  55.  
  56. /**
  57.   * View category
  58.   *
  59.   * @return void
  60.   */
  61. public function categoryAction()
  62. {
  63. $id = intval($this->_getParam('id', 0));
  64. if ($id > 0) {
  65. $posts = new Application_Model_DbTable_Posts();
  66. $this->view->posts = $posts->getByCategoryId($id);
  67. // Получаем данные по категории
  68. $category = new Application_Model_DbTable_Categories();
  69. $this->view->category = $category->getById($id);
  70. // Устанавливаем заголовок для категории в тег title
  71. $this->view->categoryTitle = $this->view->category['title'];
  72. $this->view->headTitle($this->view->categoryTitle);
  73. }
  74. }
  75.  
  76. }

 

 

 

Первое изменение произошло в методе init(). В него мы добавили вывод всех категорий для отображения в сайдбаре. Изменение номер два - в методе postAction() добавлен вывод комментариев к посту. И наконец последнее измение - добавление нового метода categoryAction(). Он будет срабатывать при выборе определенной категории. Его можно добавить как ручками, так и с помощью Zend_Tool - командой "zf create action category index". При втором варианте также создастся соответствующий вид (application/views/scripts/category.phtml), иначе его надо будет добавить самому. Итак в методе categoryAction() мы получаем из параметров ID. Далее если ID больше нуля, то получаем посты, данные по категории и устанавливаем заголовок для категории.

И наконец осталось набросать вьюшку. Для начала подредактируем layout (application/layouts/scripts/layout.phtml). В месте где у нас в сайдбаре выводился список категорий, добавим реальный список из БД:

 

 

 

  1. <aside>
  2. <section>
  3. <header>
  4. <h4>Категории</h4>
  5. </header>
  6. <ul>
  7. <?php foreach ($this->categories as $category) : ?>
  8. <li><a href="<?php echo $this->url(array('controller' => 'index', 'action' => 'category', 'id' => $category->id)) ?>"><?php echo $category->title ?></a></li>
  9. <?php endforeach ?>
  10. </ul>
  11. </section>
  12. </aside>

 

 

 

Я не стал снова приводить код всего макета, а показал сам сайдбар. Здесь просто цикл foreach, в котором выводятся категории. Все должно быть знакомо и понятно. А вот и сама вьюшка категорий (application/views/scripts/index/category.phtml):

 

 

 

  1. <section id="content">
  2. <section id="posts">
  3. <?php if (count($this->posts) < 1) : ?>
  4. <article>
  5. <p>Посты закончились</p>
  6. </article>
  7. <?php else : foreach ($this->posts as $post) : ?>
  8. <article>
  9. <header>
  10. <h2><a href="<?php echo $this->url(array('controller' => 'index', 'action' => 'post', 'id' => $post['id'])) ?>"><?php echo $this->escape($post['title']) ?></a></h2>
  11. </header>
  12. <?php echo $post['blog_post'] ?>
  13. <p><?php echo $this->escape($post['created_at']) ?></p>
  14. </article>
  15. <?php endforeach; endif ?>
  16. </section> <!-- posts -->
  17. </section> <!-- content -->

 

 

 

Тут все как на главной. Ну а теперь добавим вывод комментариев в наш вид для отдельного поста (application/views/scripts/index/post.phtml):

 

 

 

  1. <section id="content">
  2. <section id="posts">
  3. <article>
  4. <header>
  5. <h2><?php echo $this->post['title'] ?></h2>
  6. </header>
  7. <?php echo $this->post['blog_post'] ?>
  8. <p class="date"><?php echo $this->post['created_at'] ?></p>
  9. </article>
  10. </section> <!-- posts -->
  11. <section id="comments">
  12. <header>
  13. <h3>Комменты:</h3>
  14. </header>
  15. <?php if (empty($this->comments)) : ?>
  16. <article>
  17. <p>Комментов нет</p>
  18. </article>
  19. <?php else : foreach ($this->comments as $comment) : ?>
  20. <article>
  21. <?php if (!empty($comment['url'])) : ?>
  22. <header>
  23. <h5><a href="<?php echo $comment['url'] ?>"><?php echo $this->escape($comment['name']) ?></a></h5>
  24. </header>
  25. <?php else : ?>
  26. <header>
  27. <h5><?php echo $this->escape($comment['name']) ?></h5>
  28. </header>
  29. <?php endif ?>
  30. <p><?php echo $comment['blog_comment'] ?></p>
  31. <p class="date"><?php echo $comment['created_at'] ?></p>
  32. </article>
  33. <?php endforeach; endif ?>
  34. </section> <!-- comments -->
  35. </section> <!-- content -->

 

 

 

Теперь можете запустить браузер, набрать URL вашего проекта и лицезреть результат. Поклацайте по ссылкам, все должно работать. В следующий раз займемся добавлением комментариев. Так что если вы до сих пор не подписались на RSS, самое время исправиться. На этом у меня все, до следующего поста. Исходники лежат тут.

0