Baigudin Software avatar
Baigudin Software logo
home
ru region
en region

PHP DOM Builder API

PHP DOM Builder представлена во второй ревизии

В 2014 году, в рамках проекта Baigudin Software, был представлен первый программный продукт - библиотека PHP DOM Builder, и сегодня, спустя ровно два года, мы рады предложить её второе поколение - PHP DOM Builder Revision 2.

Многоязыковая поддержка

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

Давайте попробуем учесть все эти факторы и разработаем форму ввода с многоязыковой поддержкой, чтобы её вывод зависел только лишь от переданного значение настройки языка. Для примера возьмем два языка – русский и английский.

И так, давайте сразу приведём исходный код её реализации, а затем будем разбираться, что к чему. Вот она:

<?php
/**
 * Пример работы с формой.
 * 
 * @author    Sergey Baigudin, baigudin@mail.ru
 * @copyright 2014-2016 Sergey Baigudin
 * @license   http://baigudin.software/license/
 * @link      http://baigudin.software
 */ 

use DomBuilder\Element as Element;
class 
Form
{
  
/** 
   * Получение формы.
   * 
   * @return Element форма ввода.
   */  
  
static public function get()
  {
    
self::_listInit();
    
$form self::_form();
    if( 
self::_isChecked() ) self::_save($form);
    return 
$form
  }
  
/** 
   * Инициализация списка.
   */  
  
static private function _listInit()
  {
    
self::$_list Element::newList();
    
// Добавление поля «Как нас нашли?»
    
$node Element::create('select')->key('select')
      ->
data('Как нас нашли?: ','ru')
      ->
data('How did you find us?: ','en');
    
$node->insert('option')->value(0);
    
$node->insert('option')->value(1)
      ->
html('В поисковике','ru')
      ->
html('Search engine','en');
    
$node->insert('option')->value(2)
      ->
html('В соцсети','ru')
      ->
html('Social network','en');
    
$node->insert('option')->value(3)
      ->
html('На форуме','ru')
      ->
html('Forum','en');
    
$node->insert('option')->value(4)
      ->
html('Шёл, шёл и нашел','ru')
      ->
html('It was an accidental','en');
    
$node->insert('option')->value(5)
      ->
html('Другое','ru')
      ->
html('Other','en');
    
self::$_list->push($node);
    
// Добавление поля «Имя»
    
$node Element::create('input/text')->fill(true)->maxlength(30)->key('name')
      ->
data('* Имя: ','ru')
      ->
data('* Name: ','en');
    
self::$_list->push($node);
    
// Добавление поля «E-mail»
    
$node Element::create('input/text')->maxlength(30)->key('email')
      ->
reg('^[a-zA-Z0-9_\-\.]+@[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+$')
      ->
data('E-mail: ');
    
self::$_list->push($node);    
    
// Добавление поля «Файл»
    
$node Element::create('input/file')->fileSize(1024102400)->key('file')
      ->
data('Файл: ','ru')
      ->
data('Upload: ','en');
    
self::$_list->push($node);     
    
// Добавление поля «Комментарий»
    
$node Element::create('textarea')->key('comment')
      ->
data('Комментарий: ','ru')
      ->
data('Comment: ','en');
    
self::$_list->push($node);    
    
// Добавление поля «Передать разработчикам»
    
$node Element::create('input/checkbox')->key('send')
      ->
data('Передать разработчикам: ','ru')
      ->
data('Send to developers: ','en');
    
self::$_list->push($node);        
    
// Добавление кнопки «Отправить»
    
$node Element::create('input/submit')->key('submit')
      ->
value('Отправить','ru')
      ->
value('Send','en');
    
self::$_list->push($node);    
  }
  
/** 
   * Создание формы.
   * 
   * @return Element форма ввода.
   */  
  
static private function _form()
  {
    
// Получаем кнопку
    
$submit self::$_list->get('submit');
    
// Создаём форму
    
$form Element::create('form')->action('')->method('post')
      ->
enctype('multipart/form-data');
    
// Создаём сообщение
    
$form->insert('p')->addClass('message')
      ->
html('Ваш отзыв','ru')
      ->
html('Your opinion','en');
    
// Добавление полей
    
$list self::$_list->not($submit);
    
$length $list->length();
    for(
$i=0$i<$length$i++)
    {
      
$node $list->get($i);
      
$form->insert('p')->insert('ext/str')->html($node->data())->after($node);
    }
    
// Добавление кнопки «Отправить»
    
$form->insert($submit);
    
// Создаем сноски
    
$form->insert('p')->addClass('fill')
      ->
html('* - Поле, обязательное для заполнения','ru')
      ->
html('* - Field must be filled','en');     
    return 
$form;
  }
  
/** 
   * Проверка корректности полей формы.
   * 
   * @return bool результат проверки формы.
   */   
  
static private function _isChecked()
  {
    
// Получаем кнопку
    
$submit self::$_list->get('submit');
    if(
$submit === false) return false;
    
// Проверяем, что форма была отправлена
    
if($submit->value() === false) return false;
    
// Находим все поля, кроме кнопки submit
    
$list self::$_list->not($submit);
    
$error false;
    
// Проверка полей на ошибки
    
for($i=0$i<$list->length(); $i++) 
    {
      
$node $list->get($i);
      
$error |= $node->check()->error();  
      if( 
$node->error() == true self::_message($node);
    }
    return !
$error;
  }
  
/** 
   * Вывод сообщения об ошибке.
   * 
   * @param Element $node узел поля ввода.   
   */  
  
static private function _message($node)
  {
    
$nodeName $node->prev()->html();
    
$errorStr $node->errorStr();
    
// Находим тег P с class=message и добавляем строку ошибки
    
$node->parents('form')->find('p.message')
      ->
insert('span')->addClass('error')
      ->
html("Поле $nodeName $errorStr",'ru')
      ->
html("Error $nodeName $errorStr",'en')
      ->
after('br');
  }  
  
/** 
   * Сохранение результата формы
   * 
   * @param Element $form форма ввода.  
   */  
  
static private function _save($form)
  {
    
$text '';
    
// Получаем значение checkbox
    
$value self::$_list->get('send')->value();
    if(
$value === false
    {
      
$text = array(
        
'ru'=>'Отзыв заполнен, но нам не отправлен',
        
'en'=>'Your opinion is successfully filled, but does not sent to us'
      
);
    }
    else
    {
      
$text = array(
        
'ru'=>'Спасибо за Ваш отзыв!',
        
'en'=>'Thank you for your opinion!'
      
);      
    }
    
$form->find('p.message')->insert('span')->addClass('complete')->html($text);    
    
// Если checkbox не установлен, то выходим
    
if($value === false) return;
    
// ...
    // Тут мы сохраним Ваш отзыв
    // ...
  

  
/**
   * Список узлов
   * @var ElementList 
   */  
  
static private $_list;  
}

?>

Как и в предыдущем примере, мы создадим два файла: index.php и Form.php. Содержимое файла index.php вы можете посмотреть в статье «Работа с полями формы», а код Form.php мы представили выше.

Как и в предыдущий раз у нас есть метод get, но его реализация изменилась. Теперь у нас есть переменная $_list, объявленная, как объект класса ElementList, методом _listInit. Этот список хранит в себе все проинициализированные поля ввода нашей формы. Стоит отметить метод data, принимающий в качестве аргумента любой тип данных, которому передаются названия этих полей. В остальном, внутренняя реализация нашего класса осталась неизменной. Вызвав метод инициализации списка, метод get вызывает метод получения дерева элементов формы, проверяет эти элементы на ошибки и, если их нет, сохраняет результат, возвращая эту самую форму.

Как вы наверняка успели заметить, ряд методов нашей библиотеки, такие как: html, data и другие, принимают в качестве второго необязательного аргумента строку – ключ. Этот ключ ассоциируется, как язык вывода, с переданной строкой текста. Если библиотека, при выводе данных, устанавливает совпадение данного ключа и настройки языковой зоны, то она возвращает соответствующую этому ключу строку. В противном случаи, она выводит последнюю переданную ей текстовую строку для каждого конкретного элемента. Таким образом, изменив настройку языковой зоны в файле index.php, мы изменяем язык всей формы и HTML документа в целом.

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

Ну что же, мы оптимизировали нашу форму и представили её пользовательский интерфейс на двух языках. Задача выполнена.

К предыдущей статье

К списку статей