Третий урок по созданию MVC компонента

В этом уроке мы создадим форму для отправки сообщений, а так же отправим его на указанный E-mail указанный в настройках, сохраним запись в базу данных и выведем пользователю сообщение об успешной отправке сообщения!

Для начала отредактируем XML файл с нашей формой. Файл у нас находится по адресу: components/com_form/models/forms/form.xml
Сейчас этот файл содержит следующий код:

<?xml version="1.0"?>
<form>
    <fieldset>
        <field name="test" type="text" label="test field" class="span3" />
    </fieldset>
</form>

В нашей форме только одно поле с именем test. Нам нужно его удалить(или изменить) и сделать что бы у нас было 3 поля: Имя, E-mail и Сообщение

После добавления этих полей форма у нас будет выглядеть так:

<?xml version="1.0"?>
<form>
    <fieldset>
        <field name="name" type="text" label="Имя:" class="span3" required="true" />
        <field name="email" type="text" label="E-mail:" class="span3" required="true" validate="email"/>
        <field name="text" type="textarea" label="Сообщение:" class="span3" required="true" />
    </fieldset>
</form>

Если обратить внимание у нас появилось несколько дополнительных атрибутов в полях field:

  • required="true" - означает что поле будет обязательное, если его не заполнить будет ошибка!
  • validate="email" - означает что выполнится проверка или в это поле введен E-mail адрес (проверка будет выполняться только на стороне сервера)

Теперь нам нужно вывести эти поля в форме!
Для этого откроем файл components/com_form/views/form/tmpl/default.php

Для вывода полей формы, которые мы перед этим создали в XML файле, используются строки:

//для вывода метки поля из атрибута "label"
echo $this->form->getLabel( 'name' );
//для вывода самого поля, название поля содержится в атрибуте "name"
echo $this->form->getInput( 'name' );

Теперь нам нужно вывести три наших поля в форме, и код шаблона нашей формы изменится на такой:

<?php
// No direct access
defined( '_JEXEC' ) or die;
?>

<div class="item-page">
	<h1>Форма обратной связи</h1>

	<form action="<?php echo JRoute::_( 'index.php?view=form' ) ?>" method="post" class="form-validate">

		<div class="control-group form-inline">
			<div class="control-label"><?php echo $this->form->getLabel( 'name' ); ?></div>
			<div class="controls"><?php echo $this->form->getInput( 'name' ); ?></div>
		</div>
		<div class="control-group form-inline">
			<div class="control-label"><?php echo $this->form->getLabel( 'email' ); ?></div>
			<div class="controls"><?php echo $this->form->getInput( 'email' ); ?></div>
		</div>
		<div class="control-group form-inline">
			<div class="control-label"><?php echo $this->form->getLabel( 'text' ); ?></div>
			<div class="controls"><?php echo $this->form->getInput( 'text' ); ?></div>
		</div>

		<input type="hidden" name="task" value="form.save" />
		<input type="submit" value="Отправить" />
		<?php echo JHtml::_( 'form.token' ); ?>
	</form>
</div>
После проделанных манипуляций наша форма будет выглядеть как на картинке справа: Форма обратной связи после создания и вывода полей
Если мы не корректно заполним какое то поле и попробуем отправить форму нажав на кнопку отправить, то получим сообщение об ошибке: Сообщение о ошибке при некорректной форме
Если мы хотим добавить валидацию на стороне клиента то нам нужно в php код вставить такую строку:
JHtml::_( 'behavior.formvalidation' );
У тега form должен быть класс class="form-validate"
Форма с валидацией на стороне клиента

В форме у нас есть одно скрытое поле:
<input type="hidden" name="task" value="form.save" /> это поле означает что наш скрипт запустит задачу save в контроллере form

И еще одна непонятная конструкция в форме это: <?php echo JHtml::_( 'form.token' ); ?>.
Эта конструкция на самом деле всего лишь вставляет скрытое поле с уникальным значением! Служит это поле для защиты отправки формы вне сайта, то есть не выйдет создать на каком то чужом сайте форму с такими полями и отправлять на адрес этой формы какой либо спам!
Приблизительная его работа - в сессии генерируется случайное значение, и выводится в этом поле, после отправки формы проверяется или это значение пришло и совпадает ли оно с тем что установлено в форме!

На этом вывод формы завершен!

Теперь нам нужно зайти в контроллер нашей формы который находится по адресу: components/com_form/controllers/form.php. В нем есть такая строка:

$this->view_list = 'Form';

В этой строке мы указываем на какой вид мы попадем в случае успешной отправки нашей формы. Так как мы хотим выводить отдельный вид result на котором будет сообщение которое мы заполняем в конфигурационном файле, то смело меняем значение в этой строке на result:

$this->view_list = 'result';

 

Теперь приступим непосредственно к отправке письма и сохранения в архив записи!
Открываем нашу модель: components/com_form/models/form.php.

В модели у нас есть метод:

public function save( $data ){	return parent::save( $data ); }

Который выполняет сохранение данных и в случае успешного сохранения возвращает true. В этом методе есть одно значение $data которое представляет из себя асоциированный массив, в котором будут значения из отправленных в форме полей!
То есть например в $data['name'] - будет значение из поля "Имя"

Теперь нам нужно сформировать тело письма, отправить письмо и сохранить его в базе данных! Эту часть у нас выполнит следующий код:

public function save( $data ){
	//Формируем тело сообщения
   	$body = '<table class="table table-bordered table-striped table-hover">';
    $body .= '<tr><td>Имя:</td><td>' . $data['name'] . '</td></tr>';
    $body .= '<tr><td>E-mail:</td><td>' . $data['email'] . '</td></tr>';
    $body .= '<tr><td>Текст сообщения:</td><td>' . $data['text'] . '</td></tr>';
    $body .= '</table>';
	//Получаем данные из конфиг файла
	$params = JComponentHelper::getParams( 'com_form' );
	//Адрес получателя письма
	$recipient = $params->get( 'recipient' );
	//Тема письма
	$subject = $params->get( 'subject' );
	//Получаем экземпляр таблицы form_messages
	$table = $this->getTable( 'form_messages' );
	//Данные которые запишем в базу данных
	$archiveData = array(
		'title' => 'Сообщение от ' . $data['name'],
		'text' => $body
	);
	//Заносим данные в таблицу
	$table->bind( $archiveData );
	//если удалось сохранить запись в базу данных то отправляем E-mail
	if ( $table->store() ) {
		//Отправляем почту
		//Получаем данные о конфигурации сайта
		$config = JFactory::getConfig();
		//Получаем экземпляр класса JMail
		$mailer = JFactory::getMailer();
		//Указываем что письмо будет в формате HTML
		$mailer->IsHTML( true );
		//Указываем отправителя в качестве отправителя письма адрес и название которые у нас хранятся в конфиге сайта
		$mailer->setSender( array( $config->get( 'mailfrom' ), $config->get( 'fromname' ) ) );
		//Указываем тему письма
		$mailer->setSubject( $subject );
		//указываем получателя письма
		$mailer->addRecipient( $recipient );
		//Добавляем текст письма
		$mailer->setBody( $body );
		//Отправляем письмо
		$mailer->send();
		//возвращаем true тем самым говоря что сообщение успешно отправлено
		return true;
	}
	//Не удалось по какой то причине отправить сообщение
	return false;
}

Теперь наша форма сохраняет данные в базу данных, и отправляет данные на E-mail который вы указали в настройках нашего компонента в административной части!

После отправки формы мы перейдем на вид result и получим сообщения о сохранении данных: Сообщение после отправки формы
Если зайдем в административную часть и выберем "Компоненты" -> "Форма обратной связи", то увидим что у нас появилась новая запись Запись в административной части

Теперь нам нужно немного доработать наш вид result что бы он выводил сообщение которое мы сохранили в конфигурационном файле.
Открываем файл components/com_form/views/result/tmpl/default.php

<?php
// No direct access
defined( '_JEXEC' ) or die;
?>
<div class="item-page">
	<h1>Форма контактов</h1>
	<?php
	$params = JComponentHelper::getParams( 'com_form' );
	echo $params->get( 'message' );
	?>
</div>

 

На этом урок окончен!

В этом уроке мы использовали класс для работы с таблицами подробнее почитать о нем вы можете тут
А так же класс для отправки электронной почты о котором вы можете прочесть тут

В следующем уроке мы немного модифицируем административную часть, уберем лишнее для нашего компонента!

Все что мы делали в этом уроке вы можете скачать в архиве!