CakePHP: Добавляем «каменты» в блог.

    <p />Итак, мы решили начать программировать «по понятиям» и наконец разобраться с каким-нибудь фреймворком.
    <p />Перед нами встаёт мучительный выбор, какой же фреймворк для этого использовать. Для этого можно найти кучу статей, обзоров, сравнительных анализов скорости, производительности, удобства использования и установки, а можно просто набрать в гугле «php framework» и кликнуть «Мне повезёт».
    <p />Ура, мы только что выбрали для разработки фрэймворк под названием CakePHP!
    Конечно же читать про его достоинства и недостатки у нас нет времени, нам нужно как можно быстрее реализовать наш проект. Поэтому мы пишем в поиске tutorial и попадаем на статью о том, как за 5 минут наляпать маленький блог.
    <p />Статья эта начинается с описания того, как установить CakePHP в свой проект. Рассказывает о том, чего нужно хранить в каждой папочке и для чего они нужны.
    Потом переходит сразу к делу, предлагает вам создать таблицу, настроить доступ к MySQL (почему-то именно в таком порядке, а не наоборот), проверить, правильно ли настроен mod_rewrite в апаче. И тут же предлагает приступить к созданию блога.
    Блог этот представляет собой таблицу, в которой содержатся посты. Мы можем добавлять, редактировать и удалять посты. Надо заметить, что всё это действительно очень просто. Почти так же просто, как и на рельсах.
    <p />Статья эта написана на простом и понятном английском языке и содержит весь необходимый для создания блога код. Знай себе копируй, да вставляй.
    <p />Но создав этот блог по этому туториалу, мы вдруг понимаем, что самого главного, ради чего ведутся все блоги, у нас нет. Это каменты (или «комментарии» для любителей чистоты языка). В панике мы начинаем гуглить, ища расширенный туториал, но убеждаемся, что кроме компонент заоблачной сложности нам ничего не найти. И тогда мы решаемся на отчаянный шаг: добавим функционал каментов сами.
    <p />Для этого сначала создадим таблицу, в которой будут хранится каменты
    CREATE TABLE `comments` (
    `id` int(11) NOT NULL auto_increment,
    `post` int(11) default NULL,
    `comment` text NOT NULL,
    `created` datetime NOT NULL,
    `modified` datetime NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
    INSERT INTO `comments` VALUES (1, 1, 'This is a comment to the first post.', NOW( ), '0000-00-00 00:00:00');
    INSERT INTO `comments` VALUES (2, 2, 'The comment to second post.', NOW( ), '0000-00-00 00:00:00');

    <p />Этот запрос создал нам таблицу `comments` и добавил в неё два камента. К первой и второй записи соответственно.
    <p />Теперь надо сделать так, чтобы эти каменты были видны. Мы слыхали про MVC, поэтому сразу идём в контроллер постов (posts_controller.php). И добавляем там следующую строчку:
    var $uses = array('Post', 'Comment');

    <p />Переменная $uses контроллера отвечает за те модели, которые будет использовать контроллер. Если эта переменная не задана, то по умолчанию он будет использовать только ту модель, чьим контроллером он собственно и является. То есть PostsController будет использовать только Post.
    <p />Тут, как видно, мы указываем контроллеру, что тот будет использовать модели Post и Comment.
    <p />Теперь отредактируем функцию контроллера, которая отвечает за отображение собственно поста.
    function view($id)
    {
    $this->Post->id = $id;
    $this->set('post',$this->Post->read());
    // добавляем следующую строчку:
    $this->set('comments' , $this->Comment->findAllByPost($id));
    }

    <p />Этой новой строчкой, мы добавляем во вью новую переменную comment и устанавливаем её значение результату $this->Comment->findAllByPost($id).
    <p />Тут надо сказать пару слов о замечательном методе findAllByPost.
    <p />Умный CakePHP предоставляет классам, унаследованным от AppModel использовать методы типа findAllBy<имя поля>(<значение>). Которые найдут все записи из таблицы, соответствующей модели, где <имя поля> = <значение>. Здорово, правда?
    <p />Поэтому $this->Comment->findAllByPost($id) вернёт все каменты, принадлежащие отображаемому посту.
    <p />Теперь в файле view.thtml, который находится в папке app/views/posts добавим отображение этих каментов. Для этого в самый конец этого файла добавим:
    <?php
    foreach($comments as $comment):
    echo ''.$comment['Comment']['comment'].'<br/>';
    endforeach;
    ?>

    <p />Тут вью пробежит по всем каментам, что мы передали во вью в предыдущем кусочке кода и выведит их на экран. Круто? Круто!
    <p />Но в каментах самое главное, чтобы их могли оставлять. Поэтому нам нужна форма добавления каментов внизу страницы поста. В этом нам поможет помощник форм.
    var $helpers = array('Html', 'Form');
    <p />Эта строчка в файле posts_controller.php указывает контроллеру, какие помощники он будет использовать в своей работе. Нашему контроллеру постов помогают соответственно Html и Form.
    <p />Во всё тот же файл view.thtml добавляем следующее:
    <?php
    echo $form->create('Comment');
    echo $form->hidden('post', array('value' => $post['Post']['id'])); echo $form->input('comment', array('type'=>'textarea'));
    echo $form->submit('Submit');

    echo $form->end();
    ?>

    <p />Это наш маленький помощник создал форму добавления камента. В нём скрытым полем (hidden) указан айдишник поста, а в textarea предлагается ввести камент.
    <p />Теперь нам нужно что-то, что сможет контролировать добавление этого камента. Это будет контроллер комментариев:
    <?php
    class CommentsController extends AppController
    {
    var $name = 'Comments';
    function add()
    {
    if (!empty($this->data))
    {
    if ($this->Comment->save($this->data))
    {
    $this->Session->setFlash('Redirecting');
    $this->redirect('/posts/view/'.$this->data['Comment']['post']);
    }
    else
    $this->Session->setFlash('You fail');
    }
    }
    }

    <p />У контроллера каментов всего один обработчик одного события «add». Он идентичен такому же обработчику добавления контроллера постов, только редиректит в другое место.
    <p />Ура! У нас теперь есть настоящий блог с каментами. Да не простой, а написанный на настоящем фреймворке, по взаправдашней архитектуре MVC. Своими собственными руками.

    Комментарии 20

      +1
      хм. а почему вы не использовали самую "вкусную" часть cakephp - ассоциации?
      можно было для модели Post сделать ассоциацию hasMany Comment. А потом при выводе самого поста все комментарии вытащатся из базы. Единственное, надо будет отключать ассоциацию (unBind) при выводе всех постов. Нужно только кол-во комментариев. Хотя может есть какой-то вариант с получением кол-ва через ассоциации который я не знаю.
        –1
        Может быть потому, что я с cakephp знаком только несколько часов? Я глубоко не разбирался, сделал первое, что пришло в голову, чтобы побаловаться с фреймворком.
        А где там в модели делать эти ассоциации?
          0
          class Post extends AppModel
          {
          var hasMany = array("Comment");
          };

          ну и там нада прописать ещё настройки типа поле по которому будет связаны таблицы. А вообще в мануале все хорошо написано =) Считаю что в cakephp самые удобные модели, легко используются, всего в пару строчек =)
            0
            может сначала надо самому научится а потом уже друих учить? а не учить делать так как не надо
              0
              вероятно это экспериментальное постописательство :)
              0
            –1
            >> Ура, мы только что выбрали для разработки фрэймворк под названием CakePHP!

            Нашли что выбирать. Уж симфони бы посмотрели.
              –2
              Почему не Zend? :)
                0
                Ой-ой. Можно подумать cakephp даже рядом не стоит с symfony по функциональности.
                  –2
                  Уж точно.
                  ZF - это хороший выбор.
                    0
                    Минуснувшим - привет пламенный, дурачки анонимные =)
                    0
                    Может CakePHP и не лучший выбор из PHP фрэймворков, но говорить что он хуже и не достоин внимания тоже нельзя. В каждом фрэймворке есть свои плюсы и минусы. Хотябы можно взять во внимание как реализован MVC патерн. Даже из выше написанного примера видно что его реализация в symfony и CakePHP отличаетса.
                    0
                    А какой ORM использует CakePHP? Уж не Doctrine?
                      0
                      На сколько я успел разобраться, то у него свой. Но есть возможность привязать doctrine.
                      0
                      Немного озодачивает скорость развития cakephp, на bakery.cakephp.org обновлений не было больше месяца, последняя бета пирожка вышла 1 января, с тех пор тишина, никаких новостей. Документация тоже не обновляется. Если посмотреть, например, на symfony, развитие идет очень активно. Пирожок умирает?
                        +1
                        Кстате да сегодня вышла первая офицальная бэта symfony 1.1 Я как с утра посморел так на работу и не пошёл. Играюсь целый день =)
                          0
                          все печется как и раньше
                          вот я под Кейком ежедневно пишу.
                          0
                          а кэйк снова начали поддерживать? а то они там перессорились все было дело....
                            0
                            в посте код старый, писан под CakePHP 1.1
                            текущая версия 1.2 намного более качественная и сексуальная.

                            я пишу на СakePHP fulltime, знаю о чем говорю.
                              0
                              В 1.2 ошибок много пока) stable его не назвать)

                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                            Самое читаемое