Skip to content

Commit

Permalink
Merge branch 'release/2.9.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
rhukster committed Sep 8, 2017
2 parents c5f54ef + cfca5d4 commit e47ad77
Show file tree
Hide file tree
Showing 15 changed files with 230 additions and 55 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
# v2.9.0
## 09/07/2017

1. [](#new)
* Added **Refresh Prevention** capabilities (Not enabled by default) [#184](https://github.com/getgrav/grav-plugin-form/issues/184)
* Added support for field `attributes` [#176](https://github.com/getgrav/grav-plugin-form/pull/176)
* Added global variables for setting form classes
* Added support for new `select_optgroup` form field [#165](https://github.com/getgrav/grav-plugin-form/issues/165)
1. [](#improved)
* Moved messages output into partial to allow style overriding
* Logic cleanup
* Updated Italian and Russian translations
1. [](#bugfix)
* Fixed an issue with conditional field not always displaying properly
* Only add Twig form variable if not already set
* Fixed issue with multiple forms on a page failing on Captcha client-side validation [#182](https://github.com/getgrav/grav-plugin-form/issues/182)
* Fixed issue with Ajax forms return full form HTML on error [#163](https://github.com/getgrav/grav-plugin-form/issues/163)

# v2.8.2
## 08/18/2017

Expand Down
14 changes: 13 additions & 1 deletion blueprints.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: Form
version: 2.8.2
version: 2.9.0
description: Enables the forms handling
icon: check-square
author:
Expand Down Expand Up @@ -43,6 +43,18 @@ form:
validate:
type: bool

refresh_prevention:
type: toggle
label: PLUGIN_FORM.REFRESH_PREVENTION
help: PLUGIN_FORM.REFRESH_PREVENTION_HELP
highlight: 1
default: 0
options:
1: Enabled
0: Disabled
validate:
type: bool

files:
type: section
title: PLUGIN_FORM.FILES
Expand Down
2 changes: 0 additions & 2 deletions classes/form.php
Original file line number Diff line number Diff line change
Expand Up @@ -613,8 +613,6 @@ public function post()
$grav->fireEvent('onFormProcessed', $event);
}
}
} else {
// Default action.
}
}

Expand Down
85 changes: 59 additions & 26 deletions form.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,21 +173,15 @@ public function onPagesInitialized()
}

// Enable form events if there's a POST
if (isset($_POST) && isset($_POST['form-nonce'])) {
if ($this->shouldProcessForm()) {
$this->enable([
'onFormProcessed' => ['onFormProcessed', 0],
'onFormValidationError' => ['onFormValidationError', 0],
'onFormFieldTypes' => ['onFormFieldTypes', 0],
]);

// Retrieve the form if it's not already set
if (!isset($this->form)) {
$current_form_name = $this->getFormName($this->grav['page']);
$this->form = $this->getFormByName($current_form_name);
}

// Post the form
if ($this->form) {
if ($this->form()) {
if ($this->grav['uri']->extension() === 'json' && isset($_POST['__form-file-uploader__'])) {
$this->json_response = $this->form->uploadFiles();
} else {
Expand All @@ -196,7 +190,6 @@ public function onPagesInitialized()
}
}


// Clear flash objects for previously uploaded files
// whenever the user switches page / reloads
// ignoring any JSON / extension call
Expand Down Expand Up @@ -255,25 +248,28 @@ public function onTwigVariables(Event $event = null)
$current_page_route = $this->getCurrentPageRoute();
$found_forms = [];

if (isset($this->form)) {
$this->grav['twig']->twig_vars['form'] = $this->form;
} elseif (!isset($this->grav['twig']->twig_vars['form'])) {
if (isset($this->forms[$page_route])) {
$found_forms = $this->forms[$page_route];
} elseif (isset($this->forms[$current_page_route])) {
$found_forms = $this->forms[$current_page_route];
} elseif (isset($header->form)) {
$found_forms = [new Form($page)];
}
$twig = $this->grav['twig'];

$this->grav['twig']->twig_vars['form'] = array_shift($found_forms);
if (!isset($twig->twig_vars['form'])) {
if (isset($this->form)) {
$twig->twig_vars['form'] = $this->form;
} else {
if (isset($this->forms[$page_route])) {
$found_forms = $this->forms[$page_route];
} elseif (isset($this->forms[$current_page_route])) {
$found_forms = $this->forms[$current_page_route];
} elseif (isset($header->form)) {
$found_forms = [new Form($page)];
}
$twig->twig_vars['form'] = array_shift($found_forms);
}
}

if ($this->config->get('plugins.form.built_in_css')) {
$this->grav['assets']->addCss('plugin://form/assets/form-styles.css');
}

$this->grav['twig']->twig_vars['form_json_response'] = $this->json_response;
$twig->twig_vars['form_json_response'] = $this->json_response;
}

/**
Expand Down Expand Up @@ -534,11 +530,6 @@ protected function process($form)
}
}
}

// Set page template if passed by form
if (isset($form->template)) {
$this->grav['page']->template($form->template);
}
}

/**
Expand Down Expand Up @@ -656,4 +647,46 @@ protected function getFormByName($form_name)
return null;
}

protected function shouldProcessForm()
{
$status = isset($_POST) && isset($_POST['form-nonce']);
$refresh_prevention = null;

if ($status && $this->form()) {

// Set page template if passed by form
if (isset($this->form->template)) {
$this->grav['page']->template($this->form->template);
}

if (!is_null($this->form->refresh_prevention)) {
$refresh_prevention = (bool) $this->form->refresh_prevention;
} else {
$refresh_prevention = $this->config->get('plugins.form.refresh_prevention', false);
}

$unique_form_id = filter_input(INPUT_POST, '__unique_form_id__', FILTER_SANITIZE_STRING);

if ($refresh_prevention && $unique_form_id) {
if(($this->grav['session']->unique_form_id != $unique_form_id)) {
$this->grav['session']->unique_form_id = $unique_form_id;
} else {
$status = false;
$this->form->message = $this->grav['language']->translate('PLUGIN_FORM.FORM_ALREADY_SUBMITTED');
$this->form->message_color = 'red';
}
}
}

return $status;
}

protected function form()
{
if (!isset($this->form)) {
$current_form_name = $this->getFormName($this->grav['page']);
$this->form = $this->getFormByName($current_form_name);
}
return $this->form;
}
}
1 change: 1 addition & 0 deletions form.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
enabled: true
built_in_css: true
refresh_prevention: false
files:
multiple: false # To allow multiple files, default is single
limit: 10 # Number of allowed files per field (multiple required)
Expand Down
64 changes: 64 additions & 0 deletions languages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ en:
NOT_VALIDATED: "Form not validated. One or more required fields are missing."
NONCE_NOT_VALIDATED: "Oops there was a problem, please check your input and submit the form again."
FILES: "Files Upload"
FORM_ALREADY_SUBMITTED: "This form has already been submitted."
ALLOW_MULTIPLE: "Allow More than one file"
ALLOW_MULTIPLE_HELP: "Allows to select more than one file for upload."
DESTINATION: "Destination"
Expand Down Expand Up @@ -35,6 +36,8 @@ en:
DROPZONE_RESPONSE_ERROR: "Server responded with {{statusCode}} code."
YES: "Yes"
NO: "No"
REFRESH_PREVENTION: "Refresh prevention"
REFRESH_PREVENTION_HELP: "Use the form's unique ID to ensure the same form is not reprocessed when refreshing the browser"

de:
PLUGIN_FORM:
Expand Down Expand Up @@ -103,6 +106,44 @@ fr:
DROPZONE_REMOVE_FILE_CONFIRMATION: "Êtes-vous sûr de vouloir supprimer ce fichier ?"
DROPZONE_RESPONSE_ERROR: "Le serveur a répondu avec le code {{statusCode}}."

ru:
PLUGIN_FORM:
NOT_VALIDATED: "Форма не подтверждена. Отсутствует одно или несколько обязательных полей."
NONCE_NOT_VALIDATED: "Упс, у вас возникла проблема, проверьте свои данные и отправьте форму еще раз."
FILES: "Загрузка файлов"
ALLOW_MULTIPLE: "Разрешить несколько файлов"
ALLOW_MULTIPLE_HELP: "Позволяет выбрать более одного файла для загрузки."
DESTINATION: "Место назначения"
DESTINATION_HELP: "Место, куда файлы должны быть загружены в"
ACCEPT: "Разрешенные MIME типы"
ACCEPT_HELP: "Список MIME типов, разрешенных для загрузки"
ERROR_VALIDATING_CAPTCHA: "Ошибка проверки Captcha"
DATA_SUMMARY: "Вот краткое изложение того, что вы нам написали:"
NO_FORM_DATA: "Данные формы отсутствуют"
RECAPTCHA: "ReCaptcha"
RECAPTCHA_SITE_KEY: "Site key"
RECAPTCHA_SITE_KEY_HELP: "Для получения дополнительной информации посетите https://developers.google.com/recaptcha"
RECAPTCHA_SECRET_KEY: "Secret key"
RECAPTCHA_SECRET_KEY_HELP: "Для получения дополнительной информации посетите https://developers.google.com/recaptcha"
GENERAL: "Общие"
USE_BUILT_IN_CSS: "Использовать встроенный CSS"
FILEUPLOAD_PREVENT_SELF: 'Нельзя использовать "%s" за пределами страниц.'
FILEUPLOAD_UNABLE_TO_UPLOAD: 'Не удалось загрузить файл %s: %s'
FILEUPLOAD_UNABLE_TO_MOVE: 'Не удалось переместить файл %s в "%s"'
DROPZONE_CANCEL_UPLOAD: 'Отменить загрузку'
DROPZONE_CANCEL_UPLOAD_CONFIRMATION: 'Вы действительно хотите отменить эту загрузку?'
DROPZONE_DEFAULT_MESSAGE: 'Бросьте свои файлы сюда или <strong>щелкните в этой области</strong>'
DROPZONE_FALLBACK_MESSAGE: 'Ваш браузер не поддерживает загрузку файлов с перетаскиванием.'
DROPZONE_FALLBACK_TEXT: 'Пожалуйста, используйте приведенную ниже форму для загрузки ваших файлов, как в старые времена.'
DROPZONE_FILE_TOO_BIG: 'Файл слишком большой ({{filesize}}мб). Максимальный размер файла: {{maxFilesize}}мб.'
DROPZONE_INVALID_FILE_TYPE: "Вы не можете загружать файлы этого типа."
DROPZONE_MAX_FILES_EXCEEDED: "Вы не можете загружать больше файлов."
DROPZONE_REMOVE_FILE: "Удалить файл"
DROPZONE_REMOVE_FILE_CONFIRMATION: 'Вы действительно хотите удалить этот файл?'
DROPZONE_RESPONSE_ERROR: "Сервер ответил кодом {{statusCode}}."
YES: "Да"
NO: "Нет"

hr:
PLUGIN_FORM:
NOT_VALIDATED: "Formular nije validiran. Jedan ili više traženih polja nedostaju."
Expand Down Expand Up @@ -140,6 +181,29 @@ it:
ACCEPT: "Tipi di MIME Concessi"
ACCEPT_HELP: "Una lista di tipi di MIME che sono permessi per l'upload"
ERROR_VALIDATING_CAPTCHA: "Errore durante la validazione del Captcha"
DATA_SUMMARY: "Ecco il riassunto di ciò che ci hai scritto:"
NO_FORM_DATA: "Nessuna informazione disponibile"
RECAPTCHA: "ReCaptcha"
RECAPTCHA_SITE_KEY: "Site key"
RECAPTCHA_SITE_KEY_HELP: "Per maggiori informazioni visita https://developers.google.com/recaptcha"
RECAPTCHA_SECRET_KEY: "Chiave segreta"
RECAPTCHA_SECRET_KEY_HELP: "Per maggiori informazioni visita https://developers.google.com/recaptcha"
GENERAL: "Generale"
USE_BUILT_IN_CSS: "Usa CSS incorporato"
FILEUPLOAD_PREVENT_SELF: 'Non si può usare "%s" fuori dalle pagine.'
FILEUPLOAD_UNABLE_TO_UPLOAD: 'Impossibile caricare il file %s: %s'
FILEUPLOAD_UNABLE_TO_MOVE: 'Impossibile muovere il file %s to "%s"'
DROPZONE_CANCEL_UPLOAD: 'Trasferimento annullato'
DROPZONE_CANCEL_UPLOAD_CONFIRMATION: 'Sei sicuro di voler cancellare questo trasferimento?'
DROPZONE_DEFAULT_MESSAGE: "Trascina qui i tuoi file o <strong>clicca su quest'area</strong>"
DROPZONE_FALLBACK_MESSAGE: 'Il tuo browser non supporta il trascinamento dei file per il trasferimento.'
DROPZONE_FALLBACK_TEXT: 'Utilizza il modulo di riserva qui sotto per caricare i tuoi file come ai vecchi tempi.'
DROPZONE_FILE_TOO_BIG: 'Il file è troppo grande ({{filesize}}MiB). Dimensione massima consentita: {{maxFilesize}}MiB.'
DROPZONE_INVALID_FILE_TYPE: "Non puoi caricare questo tipo di file"
DROPZONE_MAX_FILES_EXCEEDED: "Non puoi caricare ulteriori file, hai raggiunto il limite consentito."
DROPZONE_REMOVE_FILE: "Rimuovi il file"
DROPZONE_REMOVE_FILE_CONFIRMATION: 'Sei sicuro di voler eliminare questo file??'
DROPZONE_RESPONSE_ERROR: "Il Server ha risposto con il codice {{statusCode}}."
YES: "Si"
NO: "No"

Expand Down
8 changes: 1 addition & 7 deletions templates/form-messages.html.twig
Original file line number Diff line number Diff line change
@@ -1,7 +1 @@
{% if form.message %}
{% if form.inline_errors and form.messages %}
<div class="alert notices {{ form.message_color ?: 'green' }}"><p>{{ "FORM.VALIDATION_FAIL"|t|raw }}</p></div>
{% else %}
<div class="alert notices {{ form.message_color ?: 'green' }}"><p>{{ form.message|raw }}</p></div>
{% endif %}
{% endif %}
{% include 'partials/form-messages.html.twig' %}
2 changes: 2 additions & 0 deletions templates/form-messages.json.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{% set message = form.inline_errors and form.messages ? "FORM.VALIDATION_FAIL"|t : form.message %}
{{ {'message':message, 'color':form.message_color}|json_encode|raw }}
17 changes: 11 additions & 6 deletions templates/forms/default/field.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
{% set errors = attribute(form.messages, field.name) %}

{% block field %}
<div class="form-field {{ field.outerclasses }} {% if errors %} has-errors{% endif %} {% block outer_field_classes %}{% endblock %}">
<div class="{{ form_field_outer_classes ?: 'form-field' }} {{ field.outerclasses }} {% if errors %} has-errors{% endif %} {% block outer_field_classes %}{% endblock %}">
{% block contents %}
{% if field.label is not same as(false) %}
<div class="form-label {{ field.labelclasses }}">
<label class="inline" {% if field.id is defined %}for="{{ field.id|e }}" {% endif %} >
<div class="{{ form_field_outer_label_classes ?: 'form-label' }} {{ field.labelclasses }}">
<label class="{{ form_field_label_classes ?: 'inline' }}" {% if field.id is defined %}for="{{ field.id|e }}" {% endif %} >
{% block label %}
{% if field.help %}
<span class="tooltip" data-asTooltip-position="w" title="{{ field.help|t|e }}">{{ field.label|default(field.name|capitalize)|t }}</span>
Expand All @@ -21,7 +21,7 @@
</label>
</div>
{% endif %}
<div class="form-data {{ field.dataclasses }}"
<div class="{{ form_field_outer_data_classes ?: 'form-data' }} {{ field.dataclasses }}"
{% block global_attributes %}
data-grav-field="{{ field.type }}"
data-grav-disabled="{{ originalValue is null ? 'true' : 'false' }}"
Expand All @@ -30,7 +30,7 @@
>
{% block group %}
{% block input %}
<div class="form-input-wrapper {{ field.size }} {{ field.wrapper_classes }}">
<div class="{{ form_field_wrapper_classes ?: 'form-input-wrapper' }} {{ field.size }} {{ field.wrapper_classes }}">
{% block prepend %}{% endblock prepend %}
<input
{# required attribute structures #}
Expand All @@ -47,6 +47,11 @@
{% if field.novalidate in ['on', 'true', 1] %}novalidate="novalidate"{% endif %}
{% if field.readonly in ['on', 'true', 1] %}readonly="readonly"{% endif %}
{% if field.autocomplete in ['on', 'off'] %}autocomplete="{{ field.autocomplete }}"{% endif %}
{% if field.attributes is defined %}
{% for attribute in field.attributes %}
{{ attribute.name }}="{{ attribute.value|e }}"
{% endfor %}
{% endif %}
{% if field.validate.required in ['on', 'true', 1] %}required="required"{% endif %}
{% if field.validate.pattern %}pattern="{{ field.validate.pattern|e }}"{% endif %}
{% if field.validate.message %}title="{{ field.validate.message|t|e }}"
Expand All @@ -55,7 +60,7 @@
/>
{% block append %}{% endblock append %}
{% if form.inline_errors and errors %}
<div class="form-errors">
<div class="{{ form_errors_classes ?: 'form-errors' }}">
{% for error in errors %}
<p class="form-message"><i class="fa fa-exclamation-circle"></i> {{ error }}</p>
{% endfor %}
Expand Down
Loading

0 comments on commit e47ad77

Please sign in to comment.