место в рейтинге
  • 70458
  • 223
  • 37
Нравится блог?
Подписывайтесь!

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, самое время исправиться. На этом у меня все, до следующего поста. Исходники лежат тут.

Канат Гайлимов KanatGailimov
Мальчик-красавчик
16 февраля 2011, 16:07
1451

Загрузка...
Loading...

Комментарии

Levak2
0
0
Мне этого не понять((
Levak2
0
0
Наверное полезно)
megido
0
0
потом ещё cache добавь)
до кэша пока не дошел (в мане) :)
Пеши исчо :)
плюсанул в карму
пара ошибок:
application/views/scripts/category.phtml нужно заменить на application/views/scripts/index/category.phtml
application/views/scripts/index.post.phtml в место точки слэш нужен application/views/scripts/index/post.phtml
спасибо) ты мой самый внимательный читатель :)
Прост я делаю все что описано:)
Пробовал осваивать zf, но дальше установки не пошло. Сейчас с приходом твоих записей вторая попытка:)
приятно слышать, что твои посты кому-то полезны :)
я тут поразмышлял по поводу urlов. сейчас они такого вида: testblog/index/category/id/2 , testblog/index/post/id/3 индекс явно лишний... быть может стоит перебрать, чтобы получалось testblog/post/id/3, testblog/category/id/2 ?
до URL'ов и роутинга еще дойдем :) Хочется полное ЧПУ, т.е. вместо ID, осмысленные названия
а еще у меня не работал baseUrl(). заменил на serverUrl()
странно, а код из моего архива не проверял?
у тебя там baseUrl()
в браузере смотрю исходный код - ничего не выводит
Ну попробуй убрать baseUrl() и посмотри.
baseUrl() выводит путь к твоему приложению, т.е. /zftest/public/ У меня все именно так

Оставьте свой комментарий

Спасибо за открытие блога в Yvision.kz! Чтобы убедиться в отсутствии спама, все комментарии новых пользователей проходят премодерацию. Соблюдение правил нашей блог-платформы ускорит ваш переход в категорию надежных пользователей, не нуждающихся в премодерации. Обязательно прочтите наши правила по указанной ссылке: Правила

Также можно нажать Ctrl+Enter

Популярные посты

Мой дом – не гостиница. Я не останавливаюсь у своей родни, потому что знаю, что это такое

Мой дом – не гостиница. Я не останавливаюсь у своей родни, потому что знаю, что это такое

Наступил долгожданный момент и мы смогли заселиться в собственную квартиру. А потом началось... Все знакомые, родственники, даже коллеги и соседи родителей вспомнили о нашем существовании.
Idealovnet
14 окт. 2017 / 20:38
  • 7934
  • 78
Работа на EXPO. «Улыбайтесь, вы – лица Казахстана»

Работа на EXPO. «Улыбайтесь, вы – лица Казахстана»

Продление перерывов, втыки от менеджеров, борьба за стенды, кучкования, как мы друг-друга прикрывали, защищали от гостей. Все эти события доставляли радость, и каждый день на работу я приходила...
madiNAtty
14 окт. 2017 / 22:34
  • 5327
  • 22
Молчание Бозумбаева. Как «бензиновые короли» диктуют государству свои правила игры

Молчание Бозумбаева. Как «бензиновые короли» диктуют государству свои правила игры

Произошедшая в сентябре одновременная остановка двух казахстанских НПЗ из трёх и последовавший за этим топливный кризис – это для Казахстана уже не ново. История повторяется каждый год.
openqazaqstan
11 окт. 2017 / 16:32
  • 4256
  • 44
«Что дали задом?» Родительский чат в WhatsApp покорил Интернет

«Что дали задом?» Родительский чат в WhatsApp покорил Интернет

Чат дагестанских родителей в WhatsApp стал популярным в Интернете. Кто-то записал общение родителей в мессенджере и после опубликовал в Твиттере.
tala03
12 окт. 2017 / 15:10
  • 2894
  • 11
Актогайский горно-обогатительный комплекс – брат-близнец Бозшаколя

Актогайский горно-обогатительный комплекс – брат-близнец Бозшаколя

Рядом с посёлком Актогай в ВКО расположено одно из крупнейших в мире неосвоенных медных месторождений. В октябре Актогайская обогатительная фабрика вышла на проектную мощность.
theYakov
12 окт. 2017 / 10:47
  • 2943
  • 19
«Bank RBK» банкрот? Почему мы не можем распоряжаться собственными же деньгами?!

«Bank RBK» банкрот? Почему мы не можем распоряжаться собственными же деньгами?!

Мы не можем выдать зарплату, оплатить по счетам или как-то иначе распорядиться нашими же деньгами! У физ.лиц, насколько мне известно, ситуация не лучше - при нас люди не могли снять свои деньги с депозитов.
daniyar4422017
13 окт. 2017 / 15:46
  • 2727
  • 12
Я четко помню тот день, когда мне позвонили друзья и сообщили: «Она выходит замуж»

Я четко помню тот день, когда мне позвонили друзья и сообщили: «Она выходит замуж»

У нас была особенная атмосфера, мы постоянно были вместе, читали треки, летом часто поднимались в горы. Гуляли пешком по ночному городу, иногда до утра. Снимали хату и представляли совместную жизнь...
Dominator-kz
14 окт. 2017 / 22:29
Отчего в Казахстане предвзятое отношение к отечественному продукту?

Отчего в Казахстане предвзятое отношение к отечественному продукту?

Вы когда-нибудь пользовались казахстанской косметикой? Я тоже нет, поэтому сразу же откликнулась на приглашение своего фейсбук-френда протестировать отечественные крема… из Степногорска.
Shimanskaya
вчера / 11:32
  • 1966
  • 15
Когда почти все уехали в «А-города», стоит ли жить в Шымкенте?

Когда почти все уехали в «А-города», стоит ли жить в Шымкенте?

Город имеет особую ауру - очень густая энергетика, думаю, это от того, что он со всех сторон окружен "местами силы". Шымкент напоминает мне старенького доброго мудрого дедушку-аксакала.
Bonittta
13 окт. 2017 / 15:15