В этой статье как вы уже догадались по названию, мы будем писать один из самых востребованных модулей любого web-приложения. Кроме этого придется еще и доработать код главной библиотеки нашего движка. Напишем несколько полезных функций, под корректируем модули, тем самым сделаем наш движок еще прогрессивней.
Основную концепцию данного модуля написал мой хороший друг и отличный программист ЯRIK. За что я выражаю ему огромную благодарность и надеюсь он не против упоминания в данной статье ;-) Дружище, тебе привет!
Во первых в будущих статьях, разрабатывая систему мы будем все чаще и чаще прибегать к таблице с настройками в БД. В данный момент при рендере страницы мы уже два раза обращаемся к модулю настроек. Зачем использовать лишние ресурсы. Что бы например отправить письмо или вывести форму обратной связи - нам понадобится брать все данные из настроек: почтовый ящик отправителя, почтовый ящик получателя, имя сайта. А возможно мы захотим отправлять письма и придется парсить шаблон для письма подставляя значения - телефон, адрес, почтовый ящик.
Решено: будем делать автозагрузку всех настроек и использовать данные как конфиг codeigniter'а. Открываем наш проект и в корневой папке модуля common создаем папку config. В папке config создаем конфигурационный файл site_settings.php с следующим содержимым:
Знакомый скрипт не правда ли? ДА это практически полная копия метода get_all_settings нашего контроллера settings. Только в данном случае мы помещаем наш массив настроек в конфиг.
Далее в конструкторе общей библиотеки main_lib.php в конструктор добавляем следующую строку
Если вы еще не успели познакомится с конфигурационными файлами и работой
Что нам дали эти действия? Проверим работоспособность следующим образом: открываем шаблон 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, которая обрезала лишние символы и добавляла троеточие в конце текста мы будем использовать
Новый измененный код функции:
Форма обратной связи на Codeigniter 3 + HMVC
Не так давно я уже писал отличный скрипт формы обратной связи на своем блоге. Но в этот раз мы сделаем во истину гениальный и простой модуль всплывающих окон!
Все как обычно: создаем папку 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 так и просить что бы мы ее заполнили;-)
Заполняем отправляем. Если форма заполнена правильно - видим уведомление об успешной отправки. Если не ввели имя - то видим ошибку с нашим текстом из контроллера. Если не ввели проверочный код - так же видим ошибку. Все великолепно работает, но это сырой продукт, с таким функционалом далеко не уедешь ) Вот дальше возложим на плечи 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"
Пробуем! Работает? Отлично...
Валидация формы на лету + асинхронная отправка данных на сервер.
Для валидации форм на лету, без перезагрузки страницы я уже более года использую отличную вещь -
Просто изумительный скрипт. Посмотреть примеры и демо работы скрипта и приступить к работе с этим скриптом можно
Все что нужно это подключить js файл в нижней части документа, перед закрытием тега body.
//вот и наш файл валидатора
Теперь в наш файл с скриптами добавим следующий код. Пояснения ниже
Рекомендую тщательно изучить документацию плагина, если желаете в полной мере использовать данные технологии на своем сайте. Возможности скрипта впечатляют. Что же мы делаем сейчас:
- Вешаем событие на кнопку подтверждение отправки формы
- При клике на кнопку с классом .form_submit мы запускаем наш валидатор
- Указываем какую форму будем проверять на ошибки - #popup - родитель формы .form-callback - класс формы
- fields - поля, которым мы задаем условия валидации.
- Значению name мы укажем, что поле не может быть пустым и должно состоять минимум из 3х символов и максимум из 40. Пробелы не учитываются, что тоже важно
- Поле email так же не может быть пустым и должно быть настоящим e-mail адресом, за это отвечает строка emailAddress:{} - проверяя веденные значения pregreplace на наличие всех допустимых и недопустимых в адресе почтового ящика символов.
- Далее при удачной валидации - если пользователь правильно заполнил все поля - мы запускаем свой обработчик:
- Предотвращаем стандартную отправку данных и на страницу указанную в action формы - посылаем AJAX запрос
- При успешном ответе с помощью jQuery скрываем нашу форму с попап-окна и выводим полученные сервером данные на ее месте. Так же добавляем крестик затертый при замене содержимого блока, хотя можно использовать другие методы и избавиться от данной строки.
- Пробуем не ввести имя или почтовый ящик. Пробуем не вводить проверочный код.
- Наслаждаемся полученным результатом.
Если проверка данных валидатором пропустила не заполненный проверочный код, то сервер такой ошибки не сделает и отправит созданный нами шаблон с ошибкой и наоборот.
Ну вот и все на сегодня. Урок получился очень жирным, достаточно сложным. Не старайтесь сразу скачивать и пользоваться исходниками урока, попробуйте поэкспериментировать, изменить функции, чуть переписать валидацию на PHP, подробнее рассмотреть метод отправки письма на почтовый ящик администратора. Что бы разобраться с валидатором тоже уйдет достаточно времени, он мне не сразу поддался, но после изучения даже основных его возможностей - ваш сайт станет куда современнее и удобнее для пользователя!
У кого возникли сложности или ошибки - как всегда исходные материалы урока с бд
Живую версию работы модуля можно посмотреть на тестовом домене для данного движка
Всем успехов в программировании и жду комментариев!
Євген
Дуже чекав на продовження :) Вирішив все розбирати на робочому сайті, зараз на локалці, але планую перенести на хостинг. Чи не буде проблем з розміщенням файлів в папці, а не в кореневій директорії і як до цього підготуватись? Дякую.
Поляков Е.
Для домена создавайте поддомен и в эту папку заливайте полностью сайт. То есть сам сайт может быть в папке - но в конфиге апача нужно указать эту папку как домен. Если пользуютесь ISPManager или любой другой веб-мордой то просто нужно создать новый сайт.
На подобном движке уже много сайтов запустил все пока работает на разно настроенных серверах и хостингах все отлично. Так что запускайте смело, проблем не будет. Если что пишите.