Codeigniter

Создание движка на Codeigniter 3 + HMVC. Часть 6. Пишем модуль обратной связи - forms

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

Основную концепцию данного модуля написал мой хороший друг и отличный программист ЯRIK. За что я выражаю ему огромную благодарность и надеюсь он не против упоминания в данной статье ;-) Дружище, тебе привет!

Во первых в будущих статьях, разрабатывая систему мы будем все чаще и чаще прибегать к таблице с настройками в БД. В данный момент при рендере страницы мы уже два раза обращаемся к модулю настроек. Зачем использовать лишние ресурсы. Что бы например отправить письмо или вывести форму обратной связи - нам понадобится брать все данные из настроек: почтовый ящик отправителя, почтовый ящик получателя, имя сайта. А возможно мы захотим отправлять письма и придется парсить шаблон для письма подставляя значения - телефон, адрес, почтовый ящик.

Решено: будем делать автозагрузку всех настроек и использовать данные как конфиг codeigniter'а. Открываем наш проект и в корневой папке модуля common создаем папку config. В папке config создаем конфигурационный файл site_settings.php с следующим содержимым:


Знакомый скрипт не правда ли? ДА это практически полная копия метода get_all_settings нашего контроллера settings. Только в данном случае мы помещаем наш массив настроек в конфиг.

Далее в конструкторе общей библиотеки main_lib.php в конструктор добавляем следующую строку


Если вы еще не успели познакомится с конфигурационными файлами и работой класса Config - сейчас самое время перейти к мануалу.

Что нам дали эти действия? Проверим работоспособность следующим образом: открываем шаблон index.tpl или page_full.tpl и рядом с выводом content допишем строчку:

Открываем сайт и видим как наши настройки сайт из БД великолепно выводятся благодаря клаcсу Config. что бы вызвать одно значение - следует писать echo $this->config->item('sitename', 'site_settings');

Улучшения библиотеки main_lib

Во первых в функциях render_main_page заменим строку кода - в которой мы вызывали модуль settings и объединяли массив $data. Вместо вызова модуля settings мы добавим все наши элементы массива конфигурации движка.

То же самое в функции get_meta_data

Отлично, и раз уж мы правим main_lib, то давайте доработаем наш "укротитель текста" - short_content. Вместо самописной функции substrword, которая обрезала лишние символы и добавляла троеточие в конце текста мы будем использовать помощник кодигнайтера - text. Очень полезная вещь, уверен пригодится в разработке в будущем.

Новый измененный код функции:

Форма обратной связи на Codeigniter 3 + HMVC

Не так давно я уже писал отличный скрипт формы обратной связи на своем блоге. Но в этот раз мы сделаем во истину гениальный и простой модуль всплывающих окон!

image description

Все как обычно: создаем папку forms - в ней контроллер Forms.php и объявляем класс Forms. План работы модуля:

  • Метод get - позволит нам вызывать форму обратной связи на сайте - достаточно будет написать Modules::run('forms/forms/get', '1') и на нужной нам странице выведется сгенерированная форма учитывая все настройки сайта.
  • get_ajax - именно этот метод я использую для вызова всплывающего окна. Скрипт проверяет - был ли запрос асинхронным и если да - то загружается шаблон с формой для вывода.
  • send_form1 - обработчик данных введенных пользователем. Так же проверяем был ли запрос асинхронным или нет, берем все POST данные, чистим от вредоносного кода, сверяем капчу - если она включена на сайте. Создаем массив с данными: данные с полей для ввода, IP адрес пользователя, тип заявки(обратная связь или консультация или заказ сайта) - типы заявок можно создавать любые и хранить значения в бд. Статус заявки: новая одобрена, на обработке и так далее, значения хранятся в бд, можно создавать сколько угодно статусов. Далее помещаем все данные в таблицу с заявками и выводим финальное сообщение для пользователя функцией _final($id)
  • _form_mail($id) - отправляет данные на почтовый ящик администратора сайта, указанный в настройках сайта
  • _final($id) - функция выводит сообщение об успешной оформленной заявке, да бы пользователь не задумывался ушла ли заявка с сайта или система не работает ;) Мы напишем немного расширенную версию, позволяющую при наличии шаблона письма парсить и выводить именно данные из таблицы с настройками(ну позже разъясню в чем задумка)
  • _captcha_is_on и _send_mail - проверяет включены ли в настройках сайта капча и отправка писем - можно обойтись и без этих функций - задавая в условии данные из конфига, но такой способ мне кажется более правильный и незнакомый с вашим сайтом программист быстрее поймет в чем дело и что это за условие в функции.
  • функция captcha - генерирует рисунок с цифрами и записывает проверочный код в сессии. Для данной функции мы создадим папку plugins и поместим в нее шрифт генерирующий красивые цифры для вывода. Данный скрипт капчи - очень старый и не даст вам 100% защиты от ботов, но для наглядного примера работы самой системы, мы используем в нашем сайте именно этот вариант проверки.
  • _check_captcha($post) - проверяет совпал ли проверочный код хранимый в сессиях с тем, что ввел пользователь, если нет выводит сообщение об ошибке.
  • show_error($error) - функция рендерит и выводит шаблон с текстом ошибки, при неверно введенных данных. Хорошая практика - делать валидацию полей как на стороне сервера так и на стороне клиента. В данном уроке мы не будем писать мега полную валидацию полей с помощью codeigniter'а - таких статей в интернете пруд пруди, а вот валидация на стороне клиента в этой статье заставит вас удивиться современным технологиям яваскрипта и бутстрапа ;) Но это в конце.

Много кода и функций, и по началу все выглядит немного запутанно, но не переживайте - модуль достаточно функциональный и принесет очень много пользы в любом вашем проекте. Начнем с базы данных:

--
-- Структура таблицы `forms`
--

CREATE TABLE IF NOT EXISTS `forms` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `form_id` int(11) NOT NULL,
  `status` int(2) DEFAULT NULL,
  `product` varchar(255) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `tel` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `message` text,
  `date` datetime DEFAULT NULL,
  `ip` varchar(30) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

-- --------------------------------------------------------

--
-- Структура таблицы `forms_id`
--

CREATE TABLE IF NOT EXISTS `forms_id` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT '',
  `fields` text,
  `validation` text,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;

--
-- Дамп данных таблицы `forms_id`
--

INSERT INTO `forms_id` (`id`, `name`, `fields`, `validation`) VALUES
(1, 'Обратная связь', '', ''),
(2, 'Консультация', '', '');

-- --------------------------------------------------------

--
-- Структура таблицы `forms_status`
--

CREATE TABLE IF NOT EXISTS `forms_status` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;

--
-- Дамп данных таблицы `forms_status`
--

INSERT INTO `forms_status` (`id`, `name`) VALUES
(1, 'Новая'),
(2, 'Одобрена'),
(3, 'На обработке'),
(4, 'Обработана'),
(5, 'Отклонена');

Для реализации капчи, сразу же скачаем исходники шрифта с моего облака и поместим файл в папку plugins в корне сайта.

Теперь необходимо создать папку с шаблонами для наших всплывающих окошечек. /themes/site/forms - создаем три файла:




Вы наверное заметили, что мы установили действие для формы - существующий метод /forms/forms/send_form1 - для каждой формы можно указывать и создавать собственный обработчик. Таким образом мы можем создавать сколько угодно шаблонов для формы обратной связи или просто формы-опросника, всплывающего блока с кратким описанием товара на лендинге например, да все на что хватит фантазии вашего клиента ;)
Так же в шаблоне мы условным оператором if проверяем включена ли капча, если включена - то генерируем картинку с кодом и сохраняем данные в сесиях.


Прежде чем перейти к коду контроллера, давайте создадим модель для модуля - forms_model.php

Ну вот и пришло время для контроллера. Напишем его, предварительно протестируем без AJAX и после напишем javaScript и стили всплывающей формы и проверим полностью работоспособный модуль.


Тестируем вывод формы обратной связи без AJAX

Ну что попробуем вывести не стилизованную форму в шаблон сайта?! Откроем таблицу с настройками сайта и включим капчу и отправку email на почтовый ящик администратора(ячейки captcha и send_mail в поле value ставим значение = 1) В шаблоне page_full.tpl под выводом $content напишем строку:

И открываем наш сайт. Барабанная дробь.... Великолепно! Форма обратной связи стилизованная bootstrap так и просить что бы мы ее заполнили;-)

image description

Заполняем отправляем. Если форма заполнена правильно - видим уведомление об успешной отправки. Если не ввели имя - то видим ошибку с нашим текстом из контроллера. Если не ввели проверочный код - так же видим ошибку. Все великолепно работает, но это сырой продукт, с таким функционалом далеко не уедешь ) Вот дальше возложим на плечи jQuery всю мощь нашего скрипта. Для начала уберем вывод формы с шаблона page_full.tpl и напишем стили выпадающего окошка в style.css:


Думаю с этим проблем не возникнет. Теперь javascript:


Данный код практически идентичный тому, что я описывал в предыдущей статье - создание модального окна с формой обратной связи.По порядку снизу вверх повторим уроки:

  • При клике на обьект с классом "open_popup" - запускаем функцию show_popup, в качестве параметра передаем путь(адрес) нашего метода запуска формы обратной связи.
  • При клике на затемненную область или на иконку закрытия формы - уничтожаем добавленные функцией блоки по уникальным идентификаторам popup и fade.
  • Функция show_popup - посылает нашему контроллеру forms запрос на сервер методом ajax.
  • Метод get_ajax или get принимает числовой параметр, который мы передали через URI и по нему выбирает какой именно файл нам рендерить. Если укажем в ссылке кнопки, вызывающей форму атрибут href="/forms/get_ajax/23" - то наш метод get_ajax($id) будет искать и выводить шаблон forms_get_23.tpl Пока мы создали только один шаблон (forms_get_1.tpl) и один обработчик send_form1() - с ними и будем работать.
  • Сервер отдает нам сгенерированный html код мы добавляем в конец документа между тегами
  • Затемняем всю рабочую область сайта блоком #fade создаем тем самым красивый эффект для работы с модальным окном

Что бы запустить весь данный функционал давайте добавим в правый сайдбар кнопку "Задать вопрос" и присвоим ей класс "open_popup"

Пробуем! Работает? Отлично...

Валидация формы на лету + асинхронная отправка данных на сервер.

Для валидации форм на лету, без перезагрузки страницы я уже более года использую отличную вещь - http://formvalidation.io/

image description

Просто изумительный скрипт. Посмотреть примеры и демо работы скрипта и приступить к работе с этим скриптом можно вот здесь. Безумно радует то, что скрипт уже переведен на 38 языков, есть Русский и даже Украинский!!! В архиве с исходниками будет лежать мой подключенный файл со скриптом + подключенный русский перевод, что бы не подключать лишний файл с переводом. Правда для работы этого помощника необходим bootstrap - это существенный минус для верстальщиков, которые по своим существенным убеждениям не используют данный фреймворк, но мы создавая наш движок уже подключили бутстрап, так что вперед.
Все что нужно это подключить js файл в нижней части документа, перед закрытием тега body.


 //вот и наш файл валидатора

Теперь в наш файл с скриптами добавим следующий код. Пояснения ниже

Рекомендую тщательно изучить документацию плагина, если желаете в полной мере использовать данные технологии на своем сайте. Возможности скрипта впечатляют. Что же мы делаем сейчас:

  • Вешаем событие на кнопку подтверждение отправки формы
  • При клике на кнопку с классом .form_submit мы запускаем наш валидатор
  • Указываем какую форму будем проверять на ошибки - #popup - родитель формы .form-callback - класс формы
  • fields - поля, которым мы задаем условия валидации.
  • Значению name мы укажем, что поле не может быть пустым и должно состоять минимум из 3х символов и максимум из 40. Пробелы не учитываются, что тоже важно
  • Поле email так же не может быть пустым и должно быть настоящим e-mail адресом, за это отвечает строка emailAddress:{} - проверяя веденные значения pregreplace на наличие всех допустимых и недопустимых в адресе почтового ящика символов.
  • Далее при удачной валидации - если пользователь правильно заполнил все поля - мы запускаем свой обработчик:
  • Предотвращаем стандартную отправку данных и на страницу указанную в action формы - посылаем AJAX запрос
  • При успешном ответе с помощью jQuery скрываем нашу форму с попап-окна и выводим полученные сервером данные на ее месте. Так же добавляем крестик затертый при замене содержимого блока, хотя можно использовать другие методы и избавиться от данной строки.
  • Пробуем не ввести имя или почтовый ящик. Пробуем не вводить проверочный код.
  • Наслаждаемся полученным результатом.

Если проверка данных валидатором пропустила не заполненный проверочный код, то сервер такой ошибки не сделает и отправит созданный нами шаблон с ошибкой и наоборот.

Ну вот и все на сегодня. Урок получился очень жирным, достаточно сложным. Не старайтесь сразу скачивать и пользоваться исходниками урока, попробуйте поэкспериментировать, изменить функции, чуть переписать валидацию на PHP, подробнее рассмотреть метод отправки письма на почтовый ящик администратора. Что бы разобраться с валидатором тоже уйдет достаточно времени, он мне не сразу поддался, но после изучения даже основных его возможностей - ваш сайт станет куда современнее и удобнее для пользователя!

У кого возникли сложности или ошибки - как всегда исходные материалы урока с бд
Живую версию работы модуля можно посмотреть на тестовом домене для данного движка

Всем успехов в программировании и жду комментариев!

3187 Просмотров Комментариев: 17

Євген

Ответить

Дуже чекав на продовження :) Вирішив все розбирати на робочому сайті, зараз на локалці, але планую перенести на хостинг. Чи не буде проблем з розміщенням файлів в папці, а не в кореневій директорії і як до цього підготуватись? Дякую.

Поляков Е.

Ответить

Для домена создавайте поддомен и в эту папку заливайте полностью сайт. То есть сам сайт может быть в папке - но в конфиге апача нужно указать эту папку как домен. Если пользуютесь ISPManager или любой другой веб-мордой то просто нужно создать новый сайт.

На подобном движке уже много сайтов запустил все пока работает на разно настроенных серверах и хостингах все отлично. Так что запускайте смело, проблем не будет. Если что пишите.

Євген

Ответить

Дякую за підказку все вийшло. Почав застосовувати зміни в коді і помітив, що назва файлу вказана неправильно. "В папке config создаем конфигурационный файл site_config.php" а потрібно site_settings.php, оскільки саме така назва підключається в конструкторі $this->CI->config->load('common/site_settings', TRUE); і сайт починає сваритися:)

Поляков Е.

Ответить

Спасибо, исправил ошибку названия файла в статье.

Александр

Ответить

Создал сайт по вашему прототипуно столкнулся с проблемой при валидации форм не вызываються callback функции к примеру правило CODE: function index() { $this->form_validation->set_rules('login', 'Логин', 'callback_login_check'); } public function login_check($string) { // Здесь пробую вставить echo для теста в ответ тишина, элементарные условия типа if(1 == 1): return TRUE; endif; // Ник чему не приводят поле не проходит валидацию, ощущение что функция совсем не вызываеться } В чем может быть загвоздка?

Поляков Е.

Ответить

Добрый день, Александр. По правде ни чего не понятно - что вы хотите сделать этим методом. Во первых что использовать валидацию codeigniter нужно подключить помощник form. Задавать теги открытия, закрытия и теги для полей и указывать в контроллере правила для валидации.

Если хотите сами с нуля использовать проверку и выводить ошибку - в статье есть код функции show_error() - она рендерит вьюху с содержанием ошибки и отдает скрипту, написанному на jquery - ответ при асинхронном обращении к серверу. И ответ в виде куска html кода уже выводите в сплывающей форме или любом месте на сайте.

А если хотите стандартную валидацию codeigniter то там совсем другая логика;)

Александр

Ответить

Может я не совсем удачный зделал пример, весь код не выложешь. Я хочу зделать вызов callback функции а она не вызываеться, стандартные правила валидации прекрасно обрабатываються а вот когда вставляю своё правило обработки $this->form_validation->set_rules('pass2', 'Повтор пароля', 'callback_pass_check'); ругаеться что не установлена ошибка, устанавливаю ошибку для этой функции $this->form_validation->set_message('pass_check', 'Пароли не совпадают'); ругаться перестаёт, в этом же контролере создаю функцию pass_check и тупо в ней возвращаю TRUE правило не проходит валидацию, как уже писал ощущение что функция совсем не вызываеться. Курю мануал английский на среднем уровне! https://ellislab.com/codeigniter/user-guide/libraries/form_validation.html или и этот https://www.codeigniter.com/userguide3/libraries/form_validation.html повторяю примеры из них но результат тот же, здесь кажись разницы нету между версиями больших правок не произойшло. Я хочу для начала сверить пароли, по вашему прототипу зделал структуру движка и уже пару раз стал на грабли из за того что сменилась структура папок не смог с лёту интегрировать дополнения пока отложил это, вот эта парочка HybridIgniter-master и xajax, по этому возник вопрос не может ли быть причиной смена структуры движка?

Александр

Ответить

Спасибо за подробный ответ! Кажись нашол если отталкиваться от CI а не от MX то всё начинает работать тоесть в контролере обявляеться class Record extends CI_Controller{ а не class Record extends MX_Controller{. П.С. Кофе буду пить пока сам, благодаррю за внимание

Поляков Е.

Ответить

Ну дык, Александр) В первых статьях я же писал - что бы внимательно создавали новые модули и наследовали класс от MX_Controller - так как мы используем расширение модульное.

Сори что ен смог полностью помочь, но без кода подсказать что не работает - сами понимаете, без телепатии не возможно)))

В общем хорошо что разобрались, скоро продолжим еще модули писать;-)

Поляков Е.

Ответить

За кофе я понял))))
Ну ни чего, в следующий раз угостите ;-)

Николай

Ответить

Ну и времечко, добро наказуемо (

Александр

Ответить

Это моё первое знакомство с codeigniter раньше пользовался готовыми cms и для подгонки под нужный функционал приходилось крамсать код и шаблон что занимало много времени и было много не поняток с названиями переменных, классов, методов и т.п. Сейчас я решил что будет проще и понятнее для дальнейших разработок иметь свою платформу где всё будет названо и разложено по моим порядкам а реализовать какой либо функционал по известному алгоритму это пустяк, благо в сети полным полно готовых решений. В ваших премерах мне понравилось что дериктория modules вынесена на уровень application и сразу видно где мои файлы а где родные codeigniter а в остальном мне было просто интересно посмотреть концепцию разработки проэктов на этом фреймворке.

Виталий

Ответить

Несколько лет писал различной сложности движки, порой даже очень сложные, на обычном PHP, также использовал PDO, JS, jQuery, Ajax и шаблонизатор Smarty. Вчера вот решил начать изучение CodeIgniter и как-то застрял на его изучении. Шаблонизатор Smarty подключить удалось, создать Hello, world! тоже. А дальше просто затык: никак не соображу как реализовать настройки сайта из БД, подключить шапку, футер и т.д. Чувствую себя полным нубом. P.S. жаль, что у тебя нет примера работы CodeIgniter и Smarty.

СЕРГЕЙ

Ответить

Статья отличная. Codigniter - штука эндорфинная. Одна проблема - настроить пути в локалке. Сайт лежит к примеру http://localhost/ci/. В .htacceses: "RewriteBase /ci/; в /application/config/config.php: " $config['base_url']='http://localhost/ci'. CI в упор не видит этих настроек - он узнает только голый http://locahost. В *.tpl попробовал перед путями к *.css *.js *.jpg вставить <?php echo base_url();?> (его выдает читает корректно) - помогает не везде и это не выход. Куда копать?

Сергей

Ответить

Я тоже присоединился к Вашим читателям)) Надеюсь статьи будут часто выходить и не за бросится на пол пути

Валерий

Ответить

Хотел бы описать найденную ошибку в скрипте query сохранения письма, та же проблема и в комментариях. При сохранения письма и выводе ошибок - заполняем все правильно и отправляем - то будет сохранено дважды - чтобы это избежать почитав официальную документацию - нужно перед .on('success.form.bv', function(e) { добавить .off('success.form.bv') и все будет ок Ну как то так. Всем удачи

Алена

Ответить

Застряла на вот этом месте : "Тестируем вывод формы обратной связи без AJAX". Ввожу все данные и барабанная дробь....404 Page Not Found The page you requested was not found. Помогите разобраться

« Предыдущая статьяСоздание движка на Codeigniter 3 + HMVC. Часть 5. Создание модуля menu Следующая статья »Создание движка на Codeigniter 3 + HMVC. Часть 7. Пишем модуль комментарии - comments