Створення гнучких анкет у Drupal 7

У статті запропоновано патч для модуляWebform, який часто використовується в CMF Drupal для створення опитувальників та анкет. Патч дозволяє через адміністративний інтерфейс вказувати декілька умов для компонентів форми, а також керувати логікою їхньої спільної роботи.

Я вважаю, що будь-який веб-розробник рано чи пізно стикається із завданням створення опитувальника чи анкети. Звичайно, в наш час не так вже й важко підшукати якесь готове рішення, і благо, що варіантів тут у нас достатньо:

  • Можна знайти і використовувати якийсь потужний і самостійний продукт, де, по суті, сайт інтегрується готова система.
  • Другим варіантом є використання якого-небудь одного з багатьох тематичних сервісів, наприкладSurveyMonkeyабоWufoo.

У кожного з наведених вище варіантів є свої переваги і недоліки, на яких я загострювати увагу не буду, а запропоную розглянути рішення, на мій погляд, корисне всім розробникам, які використовують у своїй праці Drupal.

Динамічний анкетування.

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

  1. Необхідний механізм створення та редагування опитувальників через адміністративний інтерфейс;
  2. Необхідна можливість виводити питання поступово на кількох сторінках;
  3. Необхідна можливість виводити питання лише за виконання деяких умов;
  4. Умови можуть бути наступних типів: «вибранодеяке з перелічених значень», «не вибрано деяке із перелічених значень»;
  5. Умов може бути відразу кілька;
  6. При комбінуванні умов можуть використовувати оператори І/АБО.

Наведемо приклад такого опитувальника:

створення

Є три сторінки з питаннями та одна – з результатами. Сторінка 2 може бути зовсім не показана користувачеві, якщо на перші два питання він відповів«ТАК». Кількість питань на третій сторінці, куди користувач потрапляє завжди, варіюється в залежності від відповідей на перші два питання, тільки умови вже комбінується черезАБО. На сторінці результатів завжди виводиться текстове повідомлення з вдячністю. Також, якщо користувачеві було відображено сторінку 2, і він відповів на третє запитання позитивно, виводиться деякий додатковий текст.

Створення гнучкої анкети в Drupal.

ВстановлюємоDrupalта модульWebform. Після цього переходимо на сторінку додавання матеріалів [Add content -> Webform/node/add/webform), де вказуємо назву нашого опитувальника та вводимо його опис. Після збереження нової ноди повертаємось на сторінку її редагування та вибираємо вкладкуWebform. На цій вкладці приєднаємо до форми всі необхідні компоненти, які відповідають за запитання та сторінки опитувальника.

drupal

Для позначення питань використовуватимемо кодування за шаблоном «question_X», де X – порядковий номер питання. Варіанти відповідей (Options) для простоти використовуємо скрізь однакові, і закодуємо згідно з вимогами компонента типуSelect(ключ_значення).

створення

Зауважимо, що для ряду компонентів, починаючи з другої сторінки, можна вказати умову (condtional rules), але тільки одну.

Розширюємо можливості Webform

Вирішимо поставлене завдання модифікації поведінки модуляWebformдещо грубо і нетипово для Drupal, внісши ряд змін безпосередньо з метою економії часу. У майбутньому їх можна буде виділити окремо і створити окремий модуль. Спершу модифікуємо інтерфейс. Збільшимо кількість можливих умов, що виводяться на сторінці налаштування компонента, з 1 до 10. За самі елементи Drupal завжди відповідає деяка функція, яка повертає структуру Forms API. Щоб знайти її точну назву, достатньо в клієнтському HTML, наприклад, за допомогою Firebug'а, визначити значення елементаinput[name=”form_id”], який розташований усередині форми.

анкет

В даному випадку значення дорівнюєwebform_component_edit_form. Ця функція міститься у файлі"/webform/includes/webform.components.inc".

На 529 рядку починається код, який відповідає за умови. Тепер нам необхідно виконати його модифікацію, при цьому, не зламавши працездатність функцій, що виконують обробку введення у форму при самбміті (напр.webform_component_edit_form_validate,webform_component_edit_form_submit). При налагодженні коду можна помітити вся додаткова конфігурація компонента зберігається у полі Extra у таблиці компонентів.

анкет

Тому нічого страшного, якщо ми її розширимо, просто виконавши клонування елементів 10 раз. Магічне число 10 зробимо слабкою константою, тобто визначимо через функцію Drupal для того, щоб була гіпотетична можливість зробити адміністративний інтерфейс для модифікації цього значення. Замінимо весь код, що представляє умовні компоненти, таким:

Виконаємо перевірку. Перейдемо на сторінку налаштування довільного компонента,розташованого на будь-якій сторінці, крім першої. Можна помітити, що кількість умовних компонентів збільшилася. Додамо в цю форму ще одну додаткову настройку – вибір алгоритму, яким обчислюється кінцевий результат виконання умов, якщо їх відразу кілька. Нехай у нас буде два алгоритми:ANDтаOR. Для цього після попереднього коду одразу додамо наступний:

Тепер у нас є відразу кілька умов та налаштування алгоритму їх комбінування, що вже добре, але лише з боку адміністративного інтерфейсу. При обробці кінцевої клієнтської вебфоми, коли користувач заповнюватиме поля, залишається старий код, який вміє працювати з максимум однією умовою і нічого не знає про алгоритми комбінування. Залишилося знайти цей код. Перейдемо сторінку форми з боку клієнта (просто натиснувши View) і знайдемо відповіднийinput[name=«form_id»].

Його значення дорівнюєwebform_client_form_1і при пошуку рівно цієї функції результат виходить плачевним. Але, як відомо, Drupal має спосіб завдання правил відповідностіform_idкінцевої функції черезhook_forms(), і якщо знайти відповідний хук, то в ньому є вказівка ​​на callbackwebform_client_form, а ця функція має бути:

У цій функції (і в стандартному callback'і, що виконується при самбміті –webform_client_form_submit) немає нічого, що обробляє умови, але якщо проаналізувати її код, то можна помітити перевизначення submit callback'ів через:

Перейдемо до функціїwebform_client_form_pagesі знайдемо в ній виклик_webform_client_form_rule_check, який повертає TRUE або FALSE, і управляє відображенням або пропуском компонента. А це якраз те, що нам потрібне. В_webform_client_form_rule_checkфункціюпередається аргумент$component, який є конфігурацією будь-якого компонента веб-форми. Отримаємо з неї відомості про алгоритм і всі належні умови:

Також встановимо на початку прапор, який, зрештою, визначить (залежно від обраного алгоритму) показувати компонент чи ні:

Наступним завданням є розширення безпосереднього коду перевірки, який починається відразу за:

Вчинимо так: виконаємо по черзі кожну умову, результат перевірки зафіксуємо в масиві, який потім проаналізуємо згідно з алгоритмом. Якщо використовується алгоритм«OR», то наявність хоча б одного позитивного результату робить вираз позитивним, якщо ж алгоритм«AND», то навпаки, один негативний результат робить все вираз негативним. Для цього замінимо код перевірки на наступний:

І визначимо відразу ж обчислення результату алгоритму:

Виклик «drupal_alter» дозволить іншим модулям перевизначати результат у міру необхідності, про що необхідно завжди пам'ятати, розробляючи модулі для Drupal.

Тепер у нас є все, що необхідно для реалізації опитувальника, який наведено вище у статті. Для цього, повернувшись на сторінку зі списком компонентів веб-форми в адміністративному інтерфейсі, у компонентаpage_2поставимо правила:

  • Question 1 is one of [yes]
  • Question 2 is one of [yes]
  • Вкажемо алгоритм AND.

створення

На сторінці 3 правила відображення (відповідно до схеми) є тільки у питання 4. Налаштуємо їх:

  1. Question 1 is one of [yes]
  2. Question 2 is not one of [no]
  3. Вкажемо алгоритм "OR".

На сторінці результатів 4 додаткова інформація відображається тількитоді, коли на третє питання дано позитивну відповідь. Визначимо правило для останнього компонента:

  1. Question 3 is one of [yes].

Після всіх описаних у статті дій можна сміливо перейти на сторінку форми з клієнтської сторони та переконатися, що все працює так, як потрібно.