Last active
August 29, 2015 14:10
-
-
Save may-cat/2a2b3e024a65ae8e4f5c to your computer and use it in GitHub Desktop.
Beautiful forms / All forms are equal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Читаем данные об элементе, если это возможно | |
$arElement = getElement(); | |
/** | |
* С помощью статичного класса Generator мы создаём объект "Форма" класса MyForm, | |
* которому скармливаем всё, что нам сейчас известно. | |
* Можно обойтись и без него, но только до тех пор, пока у вас одни поля формы не зависят от других. | |
* Если от выбора, например, пола пользователя, зависят надписи, а то и вовсе - вопросы, которые будут заданы - | |
* лучше использовать данный паттерн. | |
*/ | |
$rsForm = Generator::generateForm($arElement, $_REQUEST); | |
if (isDataSubmitted()) | |
{ | |
// Если данные валидны - пробуем сохранить, если нет - зовём коллбэк и успокаиваемся | |
if ($arValidData = $rsForm->isValid()){ | |
if (save($arValidData)) | |
{ | |
on_success(); | |
} else { | |
on_fault(); | |
} | |
}else{ | |
on_invalid(); | |
} | |
}else{ | |
render_form(); // @notice: в шаблоне нужно сделать доступным объект $rsForm, чтобы вытаскивать информацию о | |
// структуре формы прямо из него. Ниже будет рассказано как это. | |
} | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
class Generator | |
{ | |
static function generateForm($arData, $USER_INPUT) | |
{ | |
// тут подготавливаем на основе пришедших данных некий массив $myFields, структура которого задаётся сугубо ожиданиями класса MyForm | |
$myFields = array(); | |
if ($arData['OK']) | |
$myFields = array( | |
'FIELD1'=>array( | |
'TYPE'=>'INTEGER' | |
) | |
); | |
else | |
$myFields = array( | |
'FIELD2'=>array( | |
'TYPE'=>'STRING' | |
) | |
); | |
// И потом конструктор объекта сделает всю магию | |
return new MyForm($myFields); | |
} | |
} | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
class MyForm | |
{ | |
/** | |
* Удобно в свойстве классе прописать сразу пример того, как заполняются поля | |
* @var array | |
*/ | |
var $exampleField = array( | |
'TYPE'=>'STRING' // STRING | INTEGER | ARRAY | |
); | |
/** | |
* @param $fields array of $exampleField | |
*/ | |
function __constructor($fields, $userInput) | |
{ | |
$this->fields = $fields; | |
$this->userInput = $userInput; | |
} | |
/** | |
* находит по $fieldName поле в $this->fields и echo'ает его в соответствии с типом | |
* @param $fieldName | |
*/ | |
function echoField($fieldName) | |
{} | |
/** | |
* Проверяет все данные в $userInput на валидность. | |
* Учитывая, что у нас есть список полей и их типы данных, а также любые другие данные, что мы только захотели | |
* прописать каждому полю в его описании - мы можем полностью автоматизировать процесс валидации. | |
*/ | |
function isValid() | |
{} | |
/** | |
* Возвращает список имеющихся полей. | |
* Если вы захотите хранить в $this->fields вложенную структуру данных (например, объединяя поля в группы), | |
* то тут придётся повозиться, но результат стоит труда | |
* @return array | |
*/ | |
function getFields() | |
{ | |
return array_keys($this->fields); | |
} | |
} | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// Пример шаблона | |
// | |
?> | |
<form method="post"> | |
<? foreach ($rsForm->getFields() as $fieldCode) { ?> | |
<div class="wrapper"> | |
<? $rsForm->echoField($fieldCode) ?> | |
</div> | |
<? } ?> | |
</form> | |
<? | |
/** | |
* Обратите внимание, что объект формы ничего не знает о: | |
* - хранении данных об элементе (чтении, сохранении) | |
* - логике отправки и получении данных (где эти данные - в $_REQUEST или где-то ещё - её не должно волновать) | |
* | |
* Генератор знает всё о: | |
* - том, какие поля, в каких ситуациях надо выводить, а какие не надо | |
* | |
* Форма всё знает о: | |
* - списке полей | |
* - свойствах каждого из полей | |
* - том, какие данные можно пользователю вводить, какие - нельзя | |
* - том, как выглядят отдельные поля, но не тем, что их обрамляет и/или как это всё обрабатывается | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment