- Подписка на печатную версию:
- Подписка на электронную версию:
- Подшивки старых номеров журнала (печатные версии)
LXF141:CackePHP3
Материал из Linuxformat.
- Учебник CakePHP
CakePHP |
---|
Содержание |
CakePHP: Сайт для закладок
- Часть III Cерию уроков по CakePHP Грэм Уэлдон заканчивает чуточкой магии Web 2.0, создавая сервис закладок.
Если вы прочли предыдущие уроки, то стали экспертами в CakePHP: вы знаете, как находить контроллеры, углубляться в модели и создавать представления, впечатляющие публику. Но, войдя во вкус быстрой разработки приложений с CakePHP, вы хотите сделать еще, причем больше за меньшее время. Что ж, имеете право; и мы посмотрим, как расширить функционал нашего приложения с помощью модулей CakePHP. Это следствие принципа DRY (Don’t repeat yourself – Не повторяй себя).
Найдя решение проблемы однажды, разумным образом оформите его и поделитесь им со всем миром, чтобы каждый смог что-то вложить и что-то получить от этого решения. А для этого прихватите немного кода, уже написанного другими, и воспользуйтесь модулями расширения, чтобы сэкономить массу времени.
На последнем уроке мы рискнем создать сайт для хранения закладок, где будут храниться не только адреса с их описанием, но и симпатичные миниатюры. Так как мы живем в эпоху социальных сетей, добавим возможность быстрого и удобного размещения закладок в социальных сетях, чтобы друзья и знакомые узнали о них.
Как всегда, потратим немного времени на то, чтобы убедиться, что наша база данных соответствует соглашениям и стандартам CakePHP, чтобы каркас сделал за нас всю трудную работу. Впрочем, если вы захотите отклониться от предложенных здесь стандартов или структуры, это очень просто. Ознакомьтесь со списком соглашений на странице http://book.cakephp.org/view/901/CakePHP-Conventions – там же можно получить всю информацию о том, как уйти в свободное плавание собственным путем.
Немного поразмыслим о данных, которые нам нужно хранить. Нам понадобятся URL-адреса, пользователи и рейтинги, чтобы при размещении адресов закладок в Twitter, Facebook или любой другой социальной сети пользователи смогли оценить содержимое, если оно им нравится.
CREATE DATABASE `bookmark`; USE `bookmark`; CREATE TABLE `urls` ( ` id` CHAR(36) NOT NULL PRIMARY KEY, `user_id` CHAR(36) NOT NULL, `name` VARCHAR(128) NOT NULL, `url` TEXT, `created` DATETIME, `modified` DATETIME ); CREATE TABLE `users` ( `id` CHAR(36) NOT NULL PRIMARY KEY, `username` VARCHAR(45) NOT NULL, `password` VARCHAR(255) NOT NULL, `email` VARCHAR(255) NOT NULL, `created` DATETIME, `modified` DATETIME );
Минуточку… но ведь это, конечно, не все таблицы, которые нам нужны? Список параметров, которые мы хотели хранить для каждой вкладки, был довольно длинным. И непохоже, что в этой таблице хватает полей на все данные – если не считать того момента, что каждый модуль расширения может хранить необходимую информацию из базы данных самостоятельно, чтобы гарантировать, что в пакете модуля содержится весь предоставляемый им функционал, включая требования базы по хранению данных.
Ну и как это работает? Для этого необходимо воспользоваться либо оболочкой “Schema”, поставляемой с CakePHP, либо модулем расширения “Migrations”, разработанным Cake Development Corporation. Мы воспользуемся модулем миграции, так как он предоставляет гораздо большие возможности, оставаясь простым в использовании.
Запалим духовку — время печь!
Bake – консольная команда CakePHP, с помощью которой можно генерировать код, выполнять миграции, запускать тесты и многое другое. Повторимся, что для удобства работы с ней из консоли, путь cake/console внутри пакета CakePHP нужно включить в переменную окружения PATH. Сделать это можно следующей командой:
$ export PATH=”$PATH:/path/to/cakephp/cake/console”
Единственное оставшееся требование – PHP должен быть доступен в командной строке. Во многих дистрибутивах есть пакет php-cli или подобный ему, в котором есть исполняемый файл PHP для командной строки.
Испечем новый проект и создадим базовую структуру, от которой будем отталкиваться. Выполните следующие команды в терминале:
$ cake bake project bookmark $ cd bookmark
CakePHP создал базовую структуру приложения. Она содержит каталоги и ряд исходных файлов для обслуживания статических страниц. Покопайтесь в этой структуре и посмотрите, чем именно вас снабдили. Стоит познакомиться со структурой файла, которую перенимает CakePHP.
Прежде чем заняться выпечкой, нужно объяснить CakePHP, как подключиться к нашей базе данных. Скопируйте файл /config/database.php.default в /config/database.php. Введите туда настройки своей базы данных, имя пользователя и пароль для вашей базы данных, установленной локально. Вот моя конфигурация:
<?php class DATABASE_CONFIG { var $default = array( ‘driver’ => ‘mysql’, ‘persistent’ => false, ‘host’ => ‘localhost’, ‘login’ => ‘dev’, ‘password’ => ‘dev’, ‘database’ => ‘bookmark’, ‘prefix’ => ‘’, ); }
Заметьте, что я удалил из этого файла настройки базы данных test. Тестовая конфигурация используется при модульном тестировании, а в рамках нашего урока мы этим заниматься не будем.
Давайте приступим к выпеканию моделей, представлений и контроллеров для таблиц базы данных, которые мы создали ранее. В процессе выпечки создастся весь код, необходимый для работы приложения в целом, а нам останется только его модифицировать, что сэкономит массу времени.
$ cake bake all user $ cake bake all url
Пусть вас не пугает объем вывода команды bake; чем больше данных она выводит, тем больше мы сэкономим на написании кода. Взглянув на ее вывод, вы увидите все пути и имена файлов, которые были созданы для нас. Теперь у вас есть пользователь и система управления ссылками, и вы можете заходить на сайт, чтобы добавлять и изменять какую-либо информацию. Попробуйте открыть ссылку /users. Я выпекал каталог в корне своего web-сервера, и мой адрес будет таким: http://localhost/bookmark/users. Откроется страница со списком пользователей, где вы сможете найти ссылки для добавления пользователей и изменения информации о них.
Добавим аутентификацию
Быстренько пробежимся по тому, как закрыть сайт от доступа посторонних, чтобы мы могли создавать пользователей и входить в систему, но без входа в систему доступ ко всему был бы закрыт. Это прекрасный способ защитить ваш сайт, а сделать это проще простого!
Откройте файл app_controller.php в корне проекта. Это пустой контроллер, от которого наследуют свой функционал все остальные контроллеры приложения. Все сделанное здесь будет доступно во всех контроллерах, так что это прекрасное место для аутентификации, которая заставит пользователей входить на сайт и помешает незваным гостям изменять данные. Добавьте компоненты “Auth” и “Session”. Теперь ваш контроллер AppController должен выглядеть так:
Thumboo! – прекрасный сервис миниатюр, на который можно отправить URL и получить миниатюру для него. С помощью этого сервиса мы будем создавать миниатюры. Регистрация на сервисе бесплатная, поэтому зайдите на http://www.thumboo.com и создайте учетную запись.
<?php class AppController extends Controller { var $components = array(‘Auth’, ‘Session’); function beforeFilter() { $this->set(‘authUser’, $this->Auth->user()); return parent::beforeFilter(); } }
Как видите, мы изменили вызов set в функции beforeFilter. Это гарантирует нам доступ к информации о текущем пользователе во всех представлениях сайта. Если текущего пользователя нет, this установится в null.
Затем откройте /controllers/users_controller.php и добавьте действие login. Оно может быть пустым: о его содержании позаботится CakePHP. Пока мы тут, добавьте и действие logout, чтобы пользователи могли выходить из системы:
function login() { } function logout() { return $this->redirect($this->Auth->logout()); }
Наконец, в контроллере нужно гарантировать, что для создания пользователя не придется входить в систему, иначе система заблокируется, так как в ней не будет ни одного пользователя, и создать нового пользователя тоже будет нельзя! Добавьте следующий метод в контроллер users:
function beforeFilter() { $this->Auth->allow(‘add’); return parent::beforeFilter(); }
Последний фрагмент этой мозаики – файл представления view, который не был создан CakePHP утилитой bake. Он примет имя пользователя и пароль и позволит пользователям войти в систему. Создайте представление login в новом файле: /views/users/login.ctp:
<div class=”users form”> <?php echo $this->Form->create(‘User’, array(‘url’ => array(‘action’ => ‘login’)));?> <fieldset> <legend><?php __(‘Login’); ?></legend> <?php echo $this->Form->input(‘username’); echo $this->Form->input(‘password’); ?> </fieldset> <?php echo $this->Form->end(__(‘Login’, true));?> </div>
Снова откройте список пользователей users (http://localhost/bookmark/users), и вы незамедлительно будете перенаправлены на форму авторизации. Теперь попробуйте зайти на страницу добавления пользователя (http://localhost/bookmark/users/add), и вы увидите, что ее можно просматривать без ввода логина и пароля. Прекрасно! Проще не бывает!
Пора выпить чашечку кофе и похлопать себя по плечу: данные защищены, а сайт работает. Пробегитесь по приложению и создайте нового пользователя. Зайдите на сайт под этим пользователем и проверьте, что все работает правильно, затем добавьте ссылку-другую. Теперь, когда сайт вам знаком и вы довольны его работой, перейдем к подключению модулей и заставим работать разные примочки!
Из школы вас бы за это выгнали, но здесь вы можете спокойно брать код, написанный другими людьми, и использовать его в своем приложении, чтобы расширить его функционал или просто сэкономить время. Не забывайте только проверять лицензии на использование выбранных модулей, они могут быть несовместимы с вашим проектом.
Как схитрить
Итак, давайте отыщем необходимые модули, загрузим их и настроим каталоги в /app/plugins. Для загрузки модулей воспользуемся Git. Возможно, он у вас уже установлен. С помощью Git модули загружаются быстрее, и работать с ними удобнее. Вдобавок это прекрасная возможность научиться работать с Git как со средством управления версиями, если он вам еще не знаком.
Выполните следующие команды Git в консоли:
git clone https://github.com/CakeDC/migrations.git plugins/migrations git clone https://github.com/CakeDC/ratings.git plugins/ratings git clone https://github.com/CakeDC/search.git plugins/search git clone https://github.com/predominant/cake_social.git plugins/cake_social git clone https://github.com/predominant/goodies.git plugins/goodies
Только что вы сэкономили несколько месяцев на разработке. Я не шучу. Мы воспользовались набором модулей с открытым исходным кодом, которые доступны любому разработчику CakePHP, желающему с их помощью реализовать общий функционал в своем приложении. Это экономит время и деньги и позволяет быстрее по сравнению с остальными разработчиками перейти от работы к отдыху. Бонус!
Раньше освоить Git было непросто. Сейчас есть множество ресурсов, которые помогут вам научиться с ним работать или улучшить свои навыки. Познакомьтесь с книгой сообщества на сайте http://book.git-scm.com.
Применяем модули
Если у вас централизованный вариант установки CakePHP, и информация о ней есть в директиве include_path в файле php.ini (для более подробной информации по развертыванию, вариантам установки и лучшим подходам см. http://book.cakephp.org/view/1645/Deployment), можете добавить свои модули в каталог /cake/plugins, и каждый из модулей тут же станет доступным любому приложению CakePHP, использующему эту установку. Это лучший способ гарантировать свежесть модулей и избежать их множественных копий, и самим не копировать файлы повсюду.
Выполнение миграций
Ранее я говорил, что нам не хватает таблиц в базе данных, и мы позаботимся об этом с помощью миграции базы данных. Это время пришло, и сейчас вы увидите, как просто создать таблицу базы данных для модулей и повторного использования кода в проектах. Не всем модулям нужна миграция, и не все ее предусматривают. У тех, у кого она есть, в каталоге config есть подкаталог migrations. Например, вы можете найти каталог /plugins/ratings/config/migrations. Вы можете пройтись по модулям и посмотреть, каким из них нужна миграция, или просто запустить ее для всех: тогда для модулей, которым она не нужна, появится сообщение об ошибке – тут мы их и накроем.
Выполните следующую, чтобы завершить настройку таблиц для добавленных нами модулей:
$ cake migration -plugin ratings all
Теперь у вас должны быть все необходимые таблицы! Для начала обеспечим способ выставления рейтинга. Рейтинг должен быть только у URL-адресов. Добавить компонент очень просто. Откройте UrlsController в файле /controllers/urls_controller.php и добавьте компонент Ratings. В результате получится код
class UrlsController extends AppController { var $components = array(‘Ratings.Ratings’); // ... existing code ... }
Здесь прекрасно то, что свежедобавленный компонент сам подключает вспомогательный класс, необходимый для отображения формы с рейтингами, а также обрабатывает сохранение и загрузку информации о рейтингах. Поэтому все, что нам нужно – задать представление для отображения формы с рейтингами с помощью вспомогательного класса рейтингов и самого рейтинга. Модуль не является по-настоящему портируемым и гибким, поэтому информация о рейтинге при загрузке не усредняется и не вычисляется, так как это предполагало бы, что методы вычислений для каждой конкретной ситуации известны заранее. Поэтому нужно позаботиться, чтобы отображалось верное значение, а форма показывалась только тогда, когда пользователь еще не оценил сайт.
Следующий фрагмент кода довольно велик, поэтому мы поместили его в файл http://www.linuxformat.com/files/cakephp_04.txt, но довольно и прост, если его разобрать. Он состоит из двух частей: первая выводит форму, если вы еще не оценили закладку, вторая – показывает наш рейтинг. Обе части используют класс Set, что упрощает работу с большими списками данных и позволяет выполнять фильтрацию. Добавьте этот код сразу после тэга <dl> в начале представления ваших адресов в файле /views/urls/view.ctp.
Если теперь щелкнуть по ссылке, мы увидим набор радиокнопок и кнопку «Отправить оценку». Мило! Попробуйте это сделать, оцените ссылку – и вас перенаправят на ту самую страницу, и будет показан результирующий рейтинг. Сделайте то же самое под другим пользователем, и вы увидите, как рейтинг изменился на среднее значение всех отправленных оценок. Чертовски мило!
Используем аватары gravatar
Страница просмотра адреса смотрится довольно пресно. Да, пресно! Нужно как минимум добавить немного графики и элементов управления, чтобы посетители быстрее воспринимали информацию. Оставим сложности CSS и стилизации страницы до совершенства web-дизайнерам, но упростим их задачу с помощью граватаров, показав иконки пользователя из информации о пользователе для каждого адреса. Граватар – глобальный аватар, который бесплатно предоставляется сервисом http://gravatar.com. Когда мы клонировали все плагины, то подключили и плагин Goodies, и вспомогательный класс gravatar – только одна из его удивительных возможностей.
Но хватит хвалебных речей – давайте покажем эти аватары. Если вы еще этого не сделали, зайдите на сайт gravatar, зарегистрируйте бесплатную учетную запись и выберите свой аватар (gravatar). Затем откройте представление для адресов (/views/urls/view.ctp). Прокрутите немного вниз, туда, где выводится информация о пользователе. Мы заменим строку
<?php echo $this->Html->link($url[‘User’][‘id’], array(‘controller’ => ‘users’, ‘action’ => ‘view’, $url[‘User’] [‘id’])); ?>
на похожую, но на сей раз включающую вывод аватара с помощью вспомогательного класса:
<?php echo $this->Html->link( $this->Gravatar->image($url[‘User’][‘email’]), array(‘controller’ => ‘users’, ‘action’ => ‘view’, $url[‘User’][‘id’]), array(‘escape’ => false)); ?> <?php echo $url[‘User’][‘username’]; ?>
Наконец, подключите вспомогательный класс в контроллере AppController в файле /app_controller.php:
class AppController extends Controller { var $helpers = array(‘Html’, ‘Form’, ‘Session’, ‘Goodies.Gravatar’); // ... existing code ... }
Теперь будет отображаться граватар пользователя, полученный по его e-mail, указанному во время регистрации, а вместо уродливого идентификатора UUID будет показано имя пользователя. Идем дальше. Обновите страницу или просмотрите информацию о другом адресе, и граватар будет отображаться на месте информации о пользователе.
Добавление виджета социальных сетей
Давайте еще немного украсим дополнительную информацию, добавив возможность поделиться ссылкой в социальных сетях, чтобы привлечь больше посетителей на сайт и чтобы пользователи могли поделиться закладками, которые им в самом деле нравятся. Этот функционал предоставляет модуль CakeSocial, который мы добавили в начале. В модуле есть вспомогательный класс для сервиса “ShareThis”, который очень сильно упрощает обмен контентом в социальных сетях. Простой модуль для простого сервиса должен быть вдвойне простым, правильно? Судите сами. Добавьте вспомогательный класс в контроллер AppController в файле /app_controller.php:
class AppController extends Controller { var $helpers = array(‘Html’, ‘Form’, ‘Session’, ‘Goodies.Gravatar’, ‘CakeSocial.ShareThis’); // ... existing code ... }
И сразу перед закрывающим тэгом </dl> в представлении для адресов /views/urls/view.ctp вставьте следующий код:
<dt<?php if ($i % 2 == 0) echo $class;?>><?php __(‘Share’); ?></dt> <dd<?php if ($i++ % 2 == 0) echo $class;?>> <?php echo $this->ShareThis->display(); ?> </dd>
Ух ты! В этом представлении пять строк, но только одна выводит ссылки на социальные сети. Остальное – метка и стили для обертки вывода. Обновите страницу и увидите, что ссылки на социальные сети ShareThis появились, и можно поделиться ссылкой в списке сервисов по умолчанию. А на http://www.linuxformat.com/files/cakephp_04.txt вы узнаете, как добавить миниатюры.
Что дальше? Приложение, которое у нас получилось, показывает, как быстро можно создавать приложения с CakePHP, и иллюстрирует качество свободных модулей, созданных сообществом. У приложения есть большой потенциал для расширения – предоставление дополнительной информации, например, частных URL-адресов, интеграция в сервис REST, Ajax-скриплет для работы с закладками, который можно встроить в браузер, небольшое приукрашивание и удаление некоторых данных и страниц, установленных по умолчанию. Возможности безграничны!
Повторно об исходниках
Коды для нашего тройного урока доступны на GitHub под моей учетной записью http://github.com/predominant/cakephp_linux_format. Можете взять код оттуда, если не получается сгенерировать его утилитой bake или вы просто хотите собрать и запустить приложение побыстрее – код можно скопировать, опустив все этапы данного урока.
О любых вопросах или предложениях по этой статье дайте мне знать через мой сайт http://grahamweldon.com или по электронной почте [mailot:graham@grahamweldon.com graham@grahamweldon.com].