3.4 Гостевая книга.
Поработаем над гостевой. В базе данных, во второй таблице, kh_gb, уже имеется 2 отзыва о программе. Сделаем сначала их вывод, а затем и добавление.
Сперва создайте пустую модель Gb_Model с конструктором, в котором создаётся объект класса Database (как в модели новостей)
PHP код:
class Gb_Model extends Model {
public function __construct() {
parent::__construct();
$this->db = new Database();
}
}
Затем создайте контроллер с пустым методом index и конструктором создающим объект модели.
PHP код:
class Gb_Controller extends Controller {
public function __construct() {
parent::__construct();
$this->gb = new Gb_Model;
}
public function index() {
}
}
Далее, в модели создадим метод answersList, который будет возвращать массив отзывов гостевой книги.
PHP код:
public function answersList() {
return $this->db->from("gb")->orderby("id","DESC")->get();
}
В контроллере мы вызовем отображение шаблона /application/views/gb/index.php и передадим в него список отзывов в параметре answersList.
PHP код:
public function index() {
$view = new View('gb/index');
$view->header = new View('header');
$view->menu = new View('menu');
$view->footer = new View('footer');
$view->answersList = $this->gb->answersList();
$view->render(true);
}
И сам код шаблона гостевой.
Код:
<?=$header?>
<body>
<?=$menu?>
<!-- start page -->
<div id="page">
<!-- start content -->
<div id="content">
<div class="post">
<?foreach ($answersList as $answer):?>
<h2 class="title">
<b>
<?=$answer->author?>(<?=date('d-m-Y',$answer->pub_date)?>)
</b>
</h2>
<?=$answer->text?>
<?endforeach;?>
</div>
</div>
<!-- end content -->
<!-- start sidebar two -->
<!-- end sidebar two -->
<div style="clear: both;"> </div>
</div>
<!-- end page -->
<?=$footer?>
Сейчас обратитесь к главной странице гостевой книги. Должно отобразиться 2 записи.
Теперь разберёмся с формой добавления отзыва. Она будет содержать всего 2 поля - имя и текст сообщения.
Код:
<br />
<br />
<form action="/gb/send/" method="POST" >
<table width="100%" cellspacing="10" cellpadding="5">
<tr>
<td width="15%">Ваше имя:</td>
<td width="85%"><input type="text" name="name" /></td>
</tr>
<tr>
<td colspan="2"><textarea name="text" rows="7"></textarea></td>
</tr>
<tr>
<td colspan="2" width="30%"><input type="submit" value="Отправить отзыв"/></td>
</tr>
</table>
</form>
Добавьте его сразу после окончания цикла вывода отзывов. В модель добавим метод add, который будет вставлять в таблицу новую запись принимая 2 параметра соответствующих полям формы.
PHP код:
public function add($name,$text) {
$this->db->insert("gb",Array("author"=>$name,"text"=>$text,"pub_date"=>time()));
}
В контроллере мы позаботимся о безопасности с помощью хэлпера security (http://docs.kohanaphp.com/helpers/security). Воспользуемся его методом xss_clean(). А после добавления записи перенесём пользователя на главную страницу с помощью метода redirect, хэлпера url (http://docs.kohanaphp.com/helpers/url).
PHP код:
public function send() {
$name = security::xss_clean($_POST['name']);
$text = security::xss_clean($_POST['text']);
$this->gb->add($name,$text);
url::redirect("/gb/");
}
Обратите внимание на то что если в файле /application/config/config.php параметр "global_xss_filtering" установлен в значение "true" то входящие данные автоматически проходят XSS-фильтрацию.
Дальше введём валидацию. Нам нужно будет лишь проверять поля формы на пустоту.
PHP код:
$post = new Validation($_POST);
$post->add_rules("*","required");
Откроем языковой файл с ошибками и добавьте туда ещё 2 поля из этой формы.
PHP код:
'name' => Array(
'required' => 'Вы должны указать своё имя'
),
'text' => Array(
'required' => 'Заполните поле сообщения'
),
Добавим ещё фразу для поля captcha. Ниже мы соорудим проверку на робота.
PHP код:
'captcha' => Array(
'required' => 'Введите текст с картинки'
)
Для вывода ошибок создадим отдельный шаблон аналогичный шаблону ошибок заказа. Назовём его error.php.
Код:
<?=$header?>
<body>
<?=$menu?>
<!-- start page -->
<div id="page">
<!-- start content -->
<div id="content">
<div class="post">
<div class="entry">
<p>
Внимание! Обнаружены следующие ошибки:
<ul>
<?foreach($validation_errors as $error):?>
<li><?=$error?></li>
<?endforeach;?>
</ul><br />
Вернитесь пожалуйста <a href="/gb/">назад</a> и заполните форму правильно.
</p>
</div>
</div>
</div>
<!-- end content -->
<div style="clear: both;"> </div>
</div>
<!-- end page -->
<?=$footer?>
Ну и соответствующим образом поменяем код функции добавления.
PHP код:
public function send() {
// Валидация
$post = new Validation($_POST);
// Все поля должны быть заполнены
$post->add_rules("*","required");
// Если всё правильно то добавляем запись
if($post->validate()) {
// Чистим данные
$name = security::xss_clean($_POST['name']);
$text = security::xss_clean($_POST['text']);
// Добавляем их в базу
$this->gb->add($name,$text);
// Переносим пользователя
url::redirect("/gb/");
}
// Если же валидация не прошла то показываем ошибки
$view = new View("gb/error");
$view->header = new View('header');
$view->menu = new View('menu');
$view->footer = new View('footer');
$view->validation_errors = $post->errors("form_errors");
$view->render(true);
}
Теперь стоит позаботится о спам-защите и воспользовать Captcha. Благо в Kohana уже есть встроенная библиотека для решения таких задач (http://docs.kohanaphp.com/libraries/captcha). Создадим объект этой библиотеки в методе index и передадим в отображение результат работы функции render - она выводит html-код показывающий защитную картинку.
PHP код:
public function index() {
$captcha = new Captcha;
$view = new View('gb/index');
$view->header = new View('header');
$view->menu = new View('menu');
$view->footer = new View('footer');
$view->answersList = $this->gb->ansersList();
// Передаём код <img src...
$view->captcha = $captcha->render();
$view->render(true);
}
И в шаблон формы сразу после поля сообщения добавим код отображения картинки и поля ввода.
Код:
<tr>
<td colspan="2"><?=$captcha?></td>
</tr>
<tr>
<td width="15%">Текст с изображения</td>
<td width="85%"><input type="text" name="captcha" /></td>
</tr>
Далее, в контроллер, в функцию добавления встроим проверку введённого с картинки текста. Для этого строку
поменяем на
PHP код:
if($post->validate() AND Captcha::valid($_POST)) {
И в конце функции передадим в отображение (сразу после объявления свойства validation_errors) информацию о том что текст введён не правильно.
PHP код:
if(!Captcha::valid($_POST['captcha']))
$view->captcha_error = true;
А в отображении, прямо перед выводом ошибок валидации, мы встроим проверку на истинность параметра captcha_error.
Код:
<?if($captcha_error):?>
<li>Неправильно введён текст с картинки</li>
<?endif;?>