Webform module and config export
This commit is contained in:
parent
3e6a5cbed2
commit
0e15467384
1040 changed files with 117682 additions and 0 deletions
|
|
@ -0,0 +1,833 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Component\Utility\Xss;
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Form\ConfigFormBase;
|
||||
use Drupal\Core\Form\FormState;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\file\Plugin\Field\FieldType\FileItem;
|
||||
use Drupal\webform\Entity\Webform;
|
||||
use Drupal\webform\Utility\WebformArrayHelper;
|
||||
use Drupal\webform\WebformElementManagerInterface;
|
||||
use Drupal\webform\WebformSubmissionExporterInterface;
|
||||
use Drupal\webform\WebformTokenManagerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Configure webform admin settings for this site.
|
||||
*/
|
||||
class WebformAdminSettingsForm extends ConfigFormBase {
|
||||
|
||||
/**
|
||||
* The module handler.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* The webform element manager.
|
||||
*
|
||||
* @var \Drupal\webform\WebformElementManagerInterface
|
||||
*/
|
||||
protected $elementManager;
|
||||
|
||||
/**
|
||||
* The webform submission exporter.
|
||||
*
|
||||
* @var \Drupal\webform\WebformSubmissionExporterInterface
|
||||
*/
|
||||
protected $submissionExporter;
|
||||
|
||||
/**
|
||||
* The token manager.
|
||||
*
|
||||
* @var \Drupal\webform\WebformTranslationManagerInterface
|
||||
*/
|
||||
protected $tokenManager;
|
||||
|
||||
/**
|
||||
* An array of element types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $elementTypes;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'webform_admin_settings_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getEditableConfigNames() {
|
||||
return ['webform.settings'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a WebformAdminSettingsForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
|
||||
* The factory for configuration objects.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $third_party_settings_manager
|
||||
* The module handler.
|
||||
* @param \Drupal\webform\WebformElementManagerInterface $element_manager
|
||||
* The webform element manager.
|
||||
* @param \Drupal\webform\WebformSubmissionExporterInterface $submission_exporter
|
||||
* The webform submission exporter.
|
||||
* @param \Drupal\webform\WebformTokenManagerInterface $token_manager
|
||||
* The token manager.
|
||||
*/
|
||||
public function __construct(ConfigFactoryInterface $config_factory, ModuleHandlerInterface $third_party_settings_manager, WebformElementManagerInterface $element_manager, WebformSubmissionExporterInterface $submission_exporter, WebformTokenManagerInterface $token_manager) {
|
||||
parent::__construct($config_factory);
|
||||
$this->moduleHandler = $third_party_settings_manager;
|
||||
$this->elementManager = $element_manager;
|
||||
$this->submissionExporter = $submission_exporter;
|
||||
$this->tokenManager = $token_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('config.factory'),
|
||||
$container->get('module_handler'),
|
||||
$container->get('plugin.manager.webform.element'),
|
||||
$container->get('webform_submission.exporter'),
|
||||
$container->get('webform.token_manager')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$config = $this->config('webform.settings');
|
||||
$settings = $config->get('settings');
|
||||
$element_plugins = $this->elementManager->getInstances();
|
||||
|
||||
// Page.
|
||||
$form['page'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Page default settings'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
$form['page']['default_page_base_path'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Default base path for webform URLs'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('settings.default_page_base_path'),
|
||||
];
|
||||
|
||||
// Form.
|
||||
$form['form'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Form default settings'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
$form['form']['default_form_closed_message'] = [
|
||||
'#type' => 'webform_html_editor',
|
||||
'#title' => $this->t('Default closed message'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('settings.default_form_closed_message'),
|
||||
];
|
||||
$form['form']['default_form_exception_message'] = [
|
||||
'#type' => 'webform_html_editor',
|
||||
'#title' => $this->t('Default closed exception message'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('settings.default_form_exception_message'),
|
||||
];
|
||||
$form['form']['default_form_confidential_message'] = [
|
||||
'#type' => 'webform_html_editor',
|
||||
'#title' => $this->t('Default confidential message'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('settings.default_form_confidential_message'),
|
||||
];
|
||||
$form['form']['default_form_submit_label'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Default submit button label'),
|
||||
'#required' => TRUE,
|
||||
'#size' => 20,
|
||||
'#default_value' => $settings['default_form_submit_label'],
|
||||
];
|
||||
$form['form']['default_form_submit_once'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Prevent duplicate submissions'),
|
||||
'#description' => $this->t('If checked, the submit button will be disabled immediately after is is clicked.'),
|
||||
'#default_value' => $settings['default_form_submit_once'],
|
||||
];
|
||||
$form['form']['default_form_disable_back'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Disable back button for all webforms'),
|
||||
'#description' => $this->t('If checked, users will not be allowed to navigate back to the webform using the browsers back button.'),
|
||||
'#return_value' => TRUE,
|
||||
'#default_value' => $config->get('settings.default_form_disable_back'),
|
||||
];
|
||||
$form['form']['default_form_unsaved'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Warn users about unsaved changes'),
|
||||
'#description' => $this->t('If checked, users will be displayed a warning message when they navigate away from a webform with unsaved changes.'),
|
||||
'#return_value' => TRUE,
|
||||
'#default_value' => $config->get('settings.default_form_unsaved'),
|
||||
];
|
||||
$form['form']['default_form_novalidate'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Disable client-side validation for all webforms'),
|
||||
'#description' => $this->t('If checked, the <a href=":href">novalidate</a> attribute, which disables client-side validation, will be added to all webforms.', [':href' => 'http://www.w3schools.com/tags/att_form_novalidate.asp']),
|
||||
'#return_value' => TRUE,
|
||||
'#default_value' => $config->get('settings.default_form_novalidate'),
|
||||
];
|
||||
$form['form']['default_form_details_toggle'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Display collapse/expand all details link'),
|
||||
'#description' => $this->t('If checked, an expand/collapse all (details) link will be added to all webforms with two or more details elements.'),
|
||||
'#return_value' => TRUE,
|
||||
'#default_value' => $config->get('settings.default_form_details_toggle'),
|
||||
];
|
||||
$form['form']['form_classes'] = [
|
||||
'#type' => 'webform_codemirror',
|
||||
'#title' => $this->t('Webform CSS classes'),
|
||||
'#description' => $this->t('A list of classes that will be provided in the "Webform CSS classes" dropdown. Enter one or more classes on each line. These styles should be available in your theme\'s CSS file.'),
|
||||
'#default_value' => $config->get('settings.form_classes'),
|
||||
];
|
||||
$form['form']['button_classes'] = [
|
||||
'#type' => 'webform_codemirror',
|
||||
'#title' => $this->t('Button CSS classes'),
|
||||
'#description' => $this->t('A list of classes that will be provided in "Button CSS classes" dropdown. Enter one or more classes on each line. These styles should be available in your theme\'s CSS file.'),
|
||||
'#default_value' => $config->get('settings.button_classes'),
|
||||
];
|
||||
|
||||
// Wizard.
|
||||
$form['wizard'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Wizard default settings'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
$form['wizard']['default_wizard_prev_button_label'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Default wizard previous page button label'),
|
||||
'#required' => TRUE,
|
||||
'#size' => 20,
|
||||
'#default_value' => $settings['default_wizard_prev_button_label'],
|
||||
];
|
||||
$form['wizard']['default_wizard_next_button_label'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Default wizard next page button label'),
|
||||
'#required' => TRUE,
|
||||
'#size' => 20,
|
||||
'#default_value' => $settings['default_wizard_next_button_label'],
|
||||
];
|
||||
$form['wizard']['default_wizard_start_label'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Default wizard start label'),
|
||||
'#required' => TRUE,
|
||||
'#size' => 20,
|
||||
'#default_value' => $settings['default_wizard_start_label'],
|
||||
];
|
||||
$form['wizard']['default_wizard_complete_label'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Default wizard end label'),
|
||||
'#required' => TRUE,
|
||||
'#size' => 20,
|
||||
'#default_value' => $settings['default_wizard_complete_label'],
|
||||
];
|
||||
|
||||
// Preview.
|
||||
$form['preview'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Preview default settings'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
$form['preview']['default_preview_next_button_label'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Default preview button label'),
|
||||
'#required' => TRUE,
|
||||
'#size' => 20,
|
||||
'#default_value' => $settings['default_preview_next_button_label'],
|
||||
];
|
||||
$form['preview']['default_preview_prev_button_label'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Default preview previous page button label'),
|
||||
'#required' => TRUE,
|
||||
'#size' => 20,
|
||||
'#default_value' => $settings['default_preview_prev_button_label'],
|
||||
];
|
||||
$form['preview']['default_preview_message'] = [
|
||||
'#type' => 'webform_html_editor',
|
||||
'#title' => $this->t('Default preview message'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $settings['default_preview_message'],
|
||||
];
|
||||
|
||||
// Draft.
|
||||
$form['draft'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Draft default settings'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
$form['draft']['default_draft_button_label'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Default draft button label'),
|
||||
'#required' => TRUE,
|
||||
'#size' => 20,
|
||||
'#default_value' => $settings['default_draft_button_label'],
|
||||
];
|
||||
$form['draft']['default_draft_saved_message'] = [
|
||||
'#type' => 'webform_html_editor',
|
||||
'#title' => $this->t('Default draft save message'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $settings['default_draft_saved_message'],
|
||||
];
|
||||
$form['draft']['default_draft_loaded_message'] = [
|
||||
'#type' => 'webform_html_editor',
|
||||
'#title' => $this->t('Default draft load message'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $settings['default_draft_loaded_message'],
|
||||
];
|
||||
|
||||
$form['confirmation'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Confirmation default settings'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
$form['confirmation']['default_confirmation_message'] = [
|
||||
'#type' => 'webform_html_editor',
|
||||
'#title' => $this->t('Default confirmation message'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('settings.default_confirmation_message'),
|
||||
];
|
||||
$form['confirmation']['default_confirmation_back_label'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Default confirmation back label'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('settings.default_confirmation_back_label'),
|
||||
];
|
||||
$form['confirmation']['confirmation_classes'] = [
|
||||
'#type' => 'webform_codemirror',
|
||||
'#title' => $this->t('Confirmation CSS classes'),
|
||||
'#description' => $this->t('A list of classes that will be provided in the "Confirmation CSS classes" dropdown. Enter one or more classes on each line. These styles should be available in your theme\'s CSS file.'),
|
||||
'#default_value' => $config->get('settings.confirmation_classes'),
|
||||
];
|
||||
$form['confirmation']['confirmation_back_classes'] = [
|
||||
'#type' => 'webform_codemirror',
|
||||
'#title' => $this->t('Confirmation back link CSS classes'),
|
||||
'#description' => $this->t('A list of classes that will be provided in the "Confirmation back link CSS classes" dropdown. Enter one or more classes on each line. These styles should be available in your theme\'s CSS file.'),
|
||||
'#default_value' => $config->get('settings.confirmation_back_classes'),
|
||||
];
|
||||
|
||||
// Limit.
|
||||
$form['limit'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Limit default settings'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
$form['limit']['default_limit_total_message'] = [
|
||||
'#type' => 'webform_html_editor',
|
||||
'#title' => $this->t('Default total submissions limit message'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('settings.default_limit_total_message'),
|
||||
];
|
||||
$form['limit']['default_limit_user_message'] = [
|
||||
'#type' => 'webform_html_editor',
|
||||
'#title' => $this->t('Default per user submission limit message'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('settings.default_limit_user_message'),
|
||||
];
|
||||
|
||||
// Assets.
|
||||
$form['assets'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Global Assets (CSS/JavaScript)'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
$form['assets']['css'] = [
|
||||
'#type' => 'webform_codemirror',
|
||||
'#mode' => 'css',
|
||||
'#title' => $this->t('CSS'),
|
||||
'#description' => $this->t('Enter custom CSS to be attached to all webforms.'),
|
||||
'#default_value' => $config->get('assets.css'),
|
||||
];
|
||||
$form['assets']['javascript'] = [
|
||||
'#type' => 'webform_codemirror',
|
||||
'#mode' => 'javascript',
|
||||
'#title' => $this->t('JavaScript'),
|
||||
'#description' => $this->t('Enter custom JavaScript to be attached to all webforms.'),
|
||||
'#default_value' => $config->get('assets.javascript'),
|
||||
];
|
||||
|
||||
// Elements.
|
||||
$form['elements'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Element default settings'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
$form['elements']['allowed_tags'] = [
|
||||
'#type' => 'webform_radios_other',
|
||||
'#title' => $this->t('Allowed tags'),
|
||||
'#options' => [
|
||||
'admin' => $this->t('Admin tags Excludes: script, iframe, etc...'),
|
||||
'html' => $this->t('HTML tags: Includes only @html_tags.', ['@html_tags' => WebformArrayHelper::toString(Xss::getHtmlTagList())]),
|
||||
],
|
||||
'#other__option_label' => $this->t('Custom tags'),
|
||||
'#other__placeholder' => $this->t('Enter multiple tags delimited using spaces'),
|
||||
'#other__default_value' => implode(' ', Xss::getAdminTagList()),
|
||||
'#other__maxlength' => 1000,
|
||||
'#required' => TRUE,
|
||||
'#description' => $this->t('Allowed tags are applied to any element property that may contain HTML markup. This properties include #title, #description, #field_prefix, and #field_suffix'),
|
||||
'#default_value' => $config->get('elements.allowed_tags'),
|
||||
];
|
||||
$form['elements']['wrapper_classes'] = [
|
||||
'#type' => 'webform_codemirror',
|
||||
'#title' => $this->t('Wrapper CSS classes'),
|
||||
'#description' => $this->t('A list of classes that will be provided in the "Wrapper CSS classes" dropdown. Enter one or more classes on each line. These styles should be available in your theme\'s CSS file.'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('elements.wrapper_classes'),
|
||||
];
|
||||
$form['elements']['classes'] = [
|
||||
'#type' => 'webform_codemirror',
|
||||
'#title' => $this->t('Element CSS classes'),
|
||||
'#description' => $this->t('A list of classes that will be provided in the "Element CSS classes" dropdown. Enter one or more classes on each line. These styles should be available in your theme\'s CSS file.'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('elements.classes'),
|
||||
];
|
||||
$form['elements']['default_description_display'] = [
|
||||
'#type' => 'select',
|
||||
'#title' => $this->t('Default description display'),
|
||||
'#options' => [
|
||||
'' => '',
|
||||
'before' => $this->t('Before'),
|
||||
'after' => $this->t('After'),
|
||||
'invisible' => $this->t('Invisible'),
|
||||
'tooltip' => $this->t('Tooltip'),
|
||||
],
|
||||
'#description' => $this->t('Determines the default placement of the description for all webform elements.'),
|
||||
'#default_value' => $config->get('elements.default_description_display'),
|
||||
];
|
||||
$form['elements']['default_google_maps_api_key'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Google Maps API key'),
|
||||
'#description' => $this->t('Google requires users to use a valid API key. Using the <a href="https://console.developers.google.com/apis">Google API Manager</a>, you can enable the <em>Google Maps JavaScript API</em>. That will create (or reuse) a <em>Browser key</em> which you can paste here.'),
|
||||
'#default_value' => $config->get('elements.default_google_maps_api_key'),
|
||||
];
|
||||
|
||||
// (Excluded) Types.
|
||||
$types_header = [
|
||||
'title' => ['data' => $this->t('Title')],
|
||||
'type' => ['data' => $this->t('Type')],
|
||||
];
|
||||
$this->elementTypes = [];
|
||||
$types_options = [];
|
||||
foreach ($element_plugins as $element_id => $element_plugin) {
|
||||
$this->elementTypes[$element_id] = $element_id;
|
||||
$types_options[$element_id] = [
|
||||
'title' => $element_plugin->getPluginLabel(),
|
||||
'type' => $element_plugin->getTypeName(),
|
||||
];
|
||||
}
|
||||
$form['types'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Element types'),
|
||||
'#description' => $this->t('Select available element types'),
|
||||
];
|
||||
$form['types']['excluded_types'] = [
|
||||
'#type' => 'tableselect',
|
||||
'#header' => $types_header,
|
||||
'#options' => $types_options,
|
||||
'#required' => TRUE,
|
||||
'#default_value' => array_diff($this->elementTypes, $config->get('elements.excluded_types')),
|
||||
];
|
||||
|
||||
// File.
|
||||
$form['file'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('File upload default settings'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
$form['file']['file_public'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Allow files to be uploaded to public file system.'),
|
||||
'#description' => $this->t('Public files upload destination is dangerous for webforms that are available to anonymous and/or untrusted users.') . ' ' .
|
||||
$this->t('For more information see: <a href="@href">DRUPAL-PSA-2016-003</a>', ['@href' => 'https://www.drupal.org/psa-2016-003']),
|
||||
'#return_value' => TRUE,
|
||||
'#default_value' => $config->get('file.file_public'),
|
||||
];
|
||||
$form['file']['default_max_filesize'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Default maximum upload size'),
|
||||
'#description' => $this->t('Enter a value like "512" (bytes), "80 KB" (kilobytes) or "50 MB" (megabytes) in order to restrict the allowed file size. If left empty the file sizes will be limited only by PHP\'s maximum post and file upload sizes (current limit <strong>%limit</strong>).', ['%limit' => function_exists('file_upload_max_size') ? format_size(file_upload_max_size()) : $this->t('N/A')]),
|
||||
'#element_validate' => [[get_class($this), 'validateMaxFilesize']],
|
||||
'#size' => 10,
|
||||
'#default_value' => $config->get('file.default_max_filesize'),
|
||||
];
|
||||
$file_types = [
|
||||
'managed_file' => 'file',
|
||||
'audio_file' => 'audio file',
|
||||
'document_file' => 'document file',
|
||||
'image_file' => 'image file',
|
||||
'video_file' => 'video file',
|
||||
];
|
||||
foreach ($file_types as $file_type_name => $file_type_title) {
|
||||
$form['file']["default_{$file_type_name}_extensions"] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Default allowed @title extensions', ['@title' => $file_type_title]),
|
||||
'#description' => $this->t('Separate extensions with a space and do not include the leading dot.'),
|
||||
'#element_validate' => [[get_class($this), 'validateExtensions']],
|
||||
'#required' => TRUE,
|
||||
'#maxlength' => 256,
|
||||
'#default_value' => $config->get("file.default_{$file_type_name}_extensions"),
|
||||
];
|
||||
}
|
||||
|
||||
// Format.
|
||||
$form['format'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Format default settings'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
foreach ($element_plugins as $element_id => $element_plugin) {
|
||||
// Element.
|
||||
$element_plugin_definition = $element_plugin->getPluginDefinition();
|
||||
$element_plugin_label = $element_plugin_definition['label'];
|
||||
$form['format'][$element_id] = [
|
||||
'#type' => 'details',
|
||||
'#title' => new FormattableMarkup('@label (@id)', ['@label' => $element_plugin_label, '@id' => $element_plugin->getTypeName()]),
|
||||
];
|
||||
// Element item format.
|
||||
$item_formats = $element_plugin->getItemFormats();
|
||||
foreach ($item_formats as $format_name => $format_label) {
|
||||
$item_formats[$format_name] = new FormattableMarkup('@label (@name)', ['@label' => $format_label, '@name' => $format_name]);
|
||||
}
|
||||
$item_formats = ['' => '<' . $this->t('Default') . '>'] + $item_formats;
|
||||
$item_default_format = $element_plugin->getItemDefaultFormat();
|
||||
$item_default_format_label = (isset($item_formats[$item_default_format])) ? $item_formats[$item_default_format] : $item_default_format;
|
||||
$form['format'][$element_id]['item'] = [
|
||||
'#type' => 'select',
|
||||
'#title' => $this->t('Item format'),
|
||||
'#description' => $this->t("Select how a @label element's single value is displayed.", ['@label' => $element_plugin_label]) . '<br/>' .
|
||||
$this->t('Defaults to: %value', ['%value' => $item_default_format_label]),
|
||||
'#options' => $item_formats,
|
||||
'#default_value' => $config->get("format.$element_id"),
|
||||
];
|
||||
// Element items format.
|
||||
if ($element_plugin->supportsMultipleValues()) {
|
||||
$items_formats = $element_plugin->getItemsFormats();
|
||||
foreach ($items_formats as $format_name => $format_label) {
|
||||
$items_formats[$format_name] = new FormattableMarkup('@label (@name)', ['@label' => $format_label, '@name' => $format_name]);
|
||||
}
|
||||
$items_formats = ['' => '<' . $this->t('Default') . '>'] + $items_formats;
|
||||
$items_default_format = $element_plugin->getItemsDefaultFormat();
|
||||
$items_default_format_label = (isset($item_formats[$items_default_format])) ? $items_formats[$items_default_format] : $items_default_format;
|
||||
$form['format'][$element_id]['items'] = [
|
||||
'#type' => 'select',
|
||||
'#title' => $this->t('Items format'),
|
||||
'#description' => $this->t("Select how a @label element's multiple values are displayed.", ['@label' => $element_plugin_label]) . '<br/>' .
|
||||
$this->t('Defaults to: %value', ['%value' => $items_default_format_label]),
|
||||
'#options' => $items_formats,
|
||||
'#default_value' => $config->get("format.$element_id"),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Mail.
|
||||
$form['mail'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Email default settings'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
$form['mail']['default_from_mail'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Default email from address'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('mail.default_from_mail'),
|
||||
];
|
||||
$form['mail']['default_from_name'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Default email from name'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('mail.default_from_name'),
|
||||
];
|
||||
$form['mail']['default_subject'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Default email subject'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('mail.default_subject'),
|
||||
];
|
||||
$form['mail']['default_body_text'] = [
|
||||
'#type' => 'webform_codemirror',
|
||||
'#mode' => 'text',
|
||||
'#title' => $this->t('Default email body (Plain text)'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('mail.default_body_text'),
|
||||
];
|
||||
$form['mail']['default_body_html'] = [
|
||||
'#type' => 'webform_codemirror',
|
||||
'#mode' => 'html',
|
||||
'#title' => $this->t('Default email body (HTML)'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('mail.default_body_html'),
|
||||
];
|
||||
$form['mail']['token_tree_link'] = $this->tokenManager->buildTreeLink();
|
||||
|
||||
// Export.
|
||||
$form['export'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Export default settings'),
|
||||
];
|
||||
$export_options = NestedArray::mergeDeep($config->get('export') ?: [],
|
||||
$this->submissionExporter->getValuesFromInput($form_state->getUserInput())
|
||||
);
|
||||
$export_form_state = new FormState();
|
||||
$this->submissionExporter->buildExportOptionsForm($form, $export_form_state, $export_options);
|
||||
|
||||
// Batch.
|
||||
$form['batch'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Batch settings'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
$form['batch']['default_batch_export_size'] = [
|
||||
'#type' => 'number',
|
||||
'#title' => $this->t('Batch export size'),
|
||||
'#min' => 1,
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('batch.default_batch_export_size'),
|
||||
];
|
||||
$form['batch']['default_batch_update_size'] = [
|
||||
'#type' => 'number',
|
||||
'#title' => $this->t('Batch update size'),
|
||||
'#min' => 1,
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('batch.default_batch_update_size'),
|
||||
];
|
||||
$form['batch']['default_batch_delete_size'] = [
|
||||
'#type' => 'number',
|
||||
'#title' => $this->t('Batch delete size'),
|
||||
'#min' => 1,
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $config->get('batch.default_batch_delete_size'),
|
||||
];
|
||||
|
||||
$form['purge_settings'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Automated purging settings'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
$form['purge_settings']['cron_size'] = [
|
||||
'#type' => 'number',
|
||||
'#title' => $this->t('Amount of submissions to process'),
|
||||
'#min' => 1,
|
||||
'#default_value' => $config->get('purge_settings.cron_size'),
|
||||
'#description' => $this->t('Amount of submissions to purge during single cron run. You may want to lower this number if you are facing memory or timeout issues when purging via cron.'),
|
||||
];
|
||||
|
||||
// Test.
|
||||
$form['test'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Test settings'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
$form['test']['types'] = [
|
||||
'#type' => 'webform_codemirror',
|
||||
'#mode' => 'yaml',
|
||||
'#title' => $this->t('Test data by element type'),
|
||||
'#description' => $this->t("Above test data is keyed by FAPI element #type."),
|
||||
'#default_value' => $config->get('test.types'),
|
||||
];
|
||||
$form['test']['names'] = [
|
||||
'#type' => 'webform_codemirror',
|
||||
'#mode' => 'yaml',
|
||||
'#title' => $this->t('Test data by element name'),
|
||||
'#description' => $this->t("Above test data is keyed by full or partial element names. For example, Using 'zip' will populate fields that are named 'zip' and 'zip_code' but not 'zipcode' or 'zipline'."),
|
||||
'#default_value' => $config->get('test.names'),
|
||||
];
|
||||
|
||||
// UI.
|
||||
$form['ui'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('User interface settings'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
$form['ui']['video_display'] = [
|
||||
'#type' => 'select',
|
||||
'#title' => $this->t('Video display'),
|
||||
'#description' => $this->t('Controls how videos are displayed in inline help and within the global help section.'),
|
||||
'#options' => [
|
||||
'dialog' => $this->t('Dialog'),
|
||||
'link' => $this->t('External link'),
|
||||
'hidden' => $this->t('Hidden'),
|
||||
],
|
||||
'#default_value' => $config->get('ui.video_display'),
|
||||
];
|
||||
$form['ui']['details_save'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Save details open/close state'),
|
||||
'#description' => $this->t('If checked, all <a href=":details_href">Details</a> element\'s open/close state will be saved using <a href=":local_storage_href">Local Storage</a>.', [
|
||||
':details_href' => 'http://www.w3schools.com/tags/tag_details.asp',
|
||||
':local_storage_href' => 'http://www.w3schools.com/html/html5_webstorage.asp',
|
||||
]),
|
||||
'#return_value' => TRUE,
|
||||
'#default_value' => $config->get('ui.details_save'),
|
||||
];
|
||||
$form['ui']['dialog_disabled'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Disable dialogs'),
|
||||
'#description' => $this->t('If checked, all modal dialogs (ie popups) will be disabled.'),
|
||||
'#return_value' => TRUE,
|
||||
'#default_value' => $config->get('ui.dialog_disabled'),
|
||||
];
|
||||
$form['ui']['offcanvas_disabled'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Disable off-canvas system tray'),
|
||||
'#description' => $this->t('If checked, off-canvas system tray will be disabled.'),
|
||||
'#return_value' => TRUE,
|
||||
'#default_value' => $config->get('ui.offcanvas_disabled'),
|
||||
'#access' => $this->moduleHandler->moduleExists('outside_in') && (floatval(\Drupal::VERSION) >= 8.3),
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
':input[name="ui[dialog_disabled]"]' => [
|
||||
'checked' => FALSE,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
if (!$this->moduleHandler->moduleExists('outside_in') && (floatval(\Drupal::VERSION) >= 8.3)) {
|
||||
$form['ui']['offcanvas_message'] = [
|
||||
'#type' => 'webform_message',
|
||||
'#message_type' => 'info',
|
||||
'#message_message' => $this->t('Enable the experimental <a href=":href">System tray module</a> to improve the Webform module\'s user experience.', [':href' => 'https://www.drupal.org/blog/drupal-82-now-with-more-outside-in']),
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
':input[name="ui[dialog_disabled]"]' => [
|
||||
'checked' => FALSE,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
$form['ui']['html_editor_disabled'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Disable HTML editor'),
|
||||
'#description' => $this->t('If checked, all HTML editor will be disabled.'),
|
||||
'#return_value' => TRUE,
|
||||
'#default_value' => $config->get('ui.html_editor_disabled'),
|
||||
];
|
||||
|
||||
// Library.
|
||||
$form['library'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Library settings'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
$form['library']['cdn'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Use CDN'),
|
||||
'#description' => $this->t('If checked, all warnings about missing libraries will be disabled.'),
|
||||
'#return_value' => TRUE,
|
||||
'#default_value' => $config->get('library.cdn'),
|
||||
];
|
||||
$form['library']['cdn_message'] = [
|
||||
'#type' => 'webform_message',
|
||||
'#message_type' => 'warning',
|
||||
'#message_message' => $this->t('Note that it is in general not a good idea to load libraries from a CDN; avoid this if possible. It introduces more points of failure both performance- and security-wise, requires more TCP/IP connections to be set up and these external assets are usually not in the browser cache anyway.'),
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
':input[name="library[cdn]"]' => [
|
||||
'checked' => TRUE,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
return parent::buildForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
/* Settings */
|
||||
|
||||
$settings = $form_state->getValue('page')
|
||||
+ $form_state->getValue('form')
|
||||
+ $form_state->getValue('wizard')
|
||||
+ $form_state->getValue('preview')
|
||||
+ $form_state->getValue('draft')
|
||||
+ $form_state->getValue('confirmation')
|
||||
+ $form_state->getValue('limit');
|
||||
|
||||
// Track if we need to trigger an update of all webform paths
|
||||
// because the 'default_page_base_path' changed.
|
||||
$update_paths = ($settings['default_page_base_path'] != $this->config('webform.settings')->get('settings.default_page_base_path')) ? TRUE : FALSE;
|
||||
|
||||
/* Excluded types */
|
||||
|
||||
// Convert list of included types to excluded types.
|
||||
$excluded_types = array_diff($this->elementTypes, array_filter($form_state->getValue('excluded_types')));
|
||||
ksort($excluded_types);
|
||||
|
||||
/* Format */
|
||||
|
||||
$format = $form_state->getValue('format');
|
||||
foreach ($format as $element_id => $element_format) {
|
||||
$format[$element_id] = array_filter($element_format);
|
||||
}
|
||||
$format = array_filter($format);
|
||||
|
||||
/* Config save */
|
||||
|
||||
$config = $this->config('webform.settings');
|
||||
$config->set('settings', $settings);
|
||||
$config->set('assets', $form_state->getValue('assets'));
|
||||
$config->set('elements', $form_state->getValue('elements') + ['excluded_types' => $excluded_types]);
|
||||
$config->set('file', $form_state->getValue('file'));
|
||||
$config->set('format', $format);
|
||||
$config->set('mail', $form_state->getValue('mail'));
|
||||
$config->set('export', $this->submissionExporter->getValuesFromInput($form_state->getValues()));
|
||||
$config->set('batch', $form_state->getValue('batch'));
|
||||
$config->set('purge_settings', $form_state->getValue('purge_settings'));
|
||||
$config->set('test', $form_state->getValue('test'));
|
||||
$config->set('ui', $form_state->getValue('ui'));
|
||||
$config->set('library', $form_state->getValue('library'));
|
||||
$config->save();
|
||||
|
||||
/* Update paths */
|
||||
|
||||
if ($update_paths) {
|
||||
/** @var \Drupal\webform\WebformInterface[] $webforms */
|
||||
$webforms = Webform::loadMultiple();
|
||||
foreach ($webforms as $webform) {
|
||||
$webform->updatePaths();
|
||||
}
|
||||
}
|
||||
|
||||
parent::submitForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for FileItem::validateExtensions.
|
||||
*/
|
||||
public static function validateExtensions($element, FormStateInterface $form_state) {
|
||||
if (class_exists('\Drupal\file\Plugin\Field\FieldType\FileItem')) {
|
||||
FileItem::validateExtensions($element, $form_state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for FileItem::validateMaxFilesize.
|
||||
*/
|
||||
public static function validateMaxFilesize($element, FormStateInterface $form_state) {
|
||||
if (class_exists('\Drupal\file\Plugin\Field\FieldType\FileItem')) {
|
||||
FileItem::validateMaxFilesize($element, $form_state);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use Drupal\Core\Form\ConfigFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\webform\WebformThirdPartySettingsManagerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Configure webform third party settings for this site.
|
||||
*/
|
||||
class WebformAdminThirdPartySettingsForm extends ConfigFormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'webform_admin_third_party_settings_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* The webform third party settings manager.
|
||||
*
|
||||
* @var \Drupal\webform\WebformThirdPartySettingsManagerInterface
|
||||
*/
|
||||
protected $thirdPartySettingsManager;
|
||||
|
||||
/**
|
||||
* Constructs a WebformAdminThirdPartySettingsForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
|
||||
* The factory for configuration objects.
|
||||
* @param \Drupal\webform\WebformThirdPartySettingsManagerInterface $third_party_settings_manager
|
||||
* The webform third party settings manager.
|
||||
*/
|
||||
public function __construct(ConfigFactoryInterface $config_factory, WebformThirdPartySettingsManagerInterface $third_party_settings_manager) {
|
||||
parent::__construct($config_factory);
|
||||
$this->thirdPartySettingsManager = $third_party_settings_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('config.factory'),
|
||||
$container->get('webform.third_party_settings_manager')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getEditableConfigNames() {
|
||||
return ['webform.settings'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$form = $this->thirdPartySettingsManager->buildForm($form, $form_state);
|
||||
return parent::buildForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
$config = $this->config('webform.settings');
|
||||
$third_party_settings = $form_state->getValue('third_party_settings') + ($config->get('third_party_settings') ?: []);
|
||||
$config->set('third_party_settings', $third_party_settings);
|
||||
$config->save();
|
||||
parent::submitForm($form, $form_state);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Provides the webform filter webform.
|
||||
*/
|
||||
class WebformEntityFilterForm extends WebformFilterFormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'webform_filter_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state, $search = NULL, $state = NULL, $state_options = []) {
|
||||
$form = parent::buildForm($form, $form_state, $search, $state, $state_options);
|
||||
$form['filter']['#title'] = $this->t('Filter webforms');
|
||||
$form['filter']['search']['#title'] = $this->t('Filter by title, description, or elements');
|
||||
$form['filter']['search']['#autocomplete_route_name'] = 'entity.webform.autocomplete';
|
||||
$form['filter']['search']['#placeholder'] = $this->t('Filter by title, description, or elements');
|
||||
return $form;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Provides base class for webform filter webforms.
|
||||
*/
|
||||
abstract class WebformFilterFormBase extends FormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state, $search = NULL, $state = NULL, array $state_options = []) {
|
||||
$form['#attributes'] = ['class' => ['webform-filter-form']];
|
||||
$form['filter'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Filter submissions'),
|
||||
'#open' => TRUE,
|
||||
'#attributes' => ['class' => ['container-inline']],
|
||||
];
|
||||
$form['filter']['search'] = [
|
||||
'#type' => 'search',
|
||||
'#title' => $this->t('Filter by submitted data and/or notes'),
|
||||
'#title_display' => 'invisible',
|
||||
'#placeholder' => $this->t('Filter by submitted data and/or notes'),
|
||||
'#maxlength' => 128,
|
||||
'#size' => 40,
|
||||
'#default_value' => $search,
|
||||
];
|
||||
$form['filter']['state'] = [
|
||||
'#type' => 'select',
|
||||
'#title' => $this->t('State'),
|
||||
'#title_display' => 'invisible',
|
||||
'#options' => $state_options,
|
||||
'#default_value' => $state,
|
||||
];
|
||||
$form['filter']['submit'] = [
|
||||
'#type' => 'submit',
|
||||
'#button_type' => 'primary',
|
||||
'#value' => $this->t('Filter'),
|
||||
];
|
||||
if (!empty($search) || !empty($state)) {
|
||||
$form['filter']['reset'] = [
|
||||
'#type' => 'submit',
|
||||
'#submit' => ['::resetForm'],
|
||||
'#value' => $this->t('Reset'),
|
||||
];
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
$query = [
|
||||
'search' => trim($form_state->getValue('search')),
|
||||
'state' => trim($form_state->getValue('state')),
|
||||
];
|
||||
$form_state->setRedirect($this->getRouteMatch()->getRouteName(), $this->getRouteMatch()->getRawParameters()->all(), [
|
||||
'query' => $query ,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the filter selection.
|
||||
*
|
||||
* @param array $form
|
||||
* An associative array containing the structure of the form.
|
||||
* @param \Drupal\Core\Form\FormStateInterface $form_state
|
||||
* The current state of the form.
|
||||
*/
|
||||
public function resetForm(array &$form, FormStateInterface $form_state) {
|
||||
$form_state->setRedirect($this->getRouteMatch()->getRouteName(), $this->getRouteMatch()->getRawParameters()->all());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\webform\WebformHandlerManagerInterface;
|
||||
use Drupal\webform\WebformInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides an add form for webform handler.
|
||||
*/
|
||||
class WebformHandlerAddForm extends WebformHandlerFormBase {
|
||||
|
||||
/**
|
||||
* The webform handler manager.
|
||||
*
|
||||
* @var \Drupal\webform\WebformHandlerManagerInterface
|
||||
*/
|
||||
protected $webformHandlerManager;
|
||||
|
||||
/**
|
||||
* Constructs a WebformHandlerAddForm.
|
||||
*
|
||||
* @param \Drupal\webform\WebformHandlerManagerInterface $webform_handler
|
||||
* The webform handler manager.
|
||||
*/
|
||||
public function __construct(WebformHandlerManagerInterface $webform_handler) {
|
||||
$this->webformHandlerManager = $webform_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('plugin.manager.webform.handler')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state, WebformInterface $webform = NULL, $webform_handler = NULL) {
|
||||
$form = parent::buildForm($form, $form_state, $webform, $webform_handler);
|
||||
$form['#title'] = $this->t('Add @label handler', ['@label' => $this->webformHandler->label()]);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareWebformHandler($webform_handler) {
|
||||
$webform_handler = $this->webformHandlerManager->createInstance($webform_handler);
|
||||
// Initialize the handler an pass in the webform.
|
||||
$webform_handler->init($this->webform);
|
||||
// Set the initial weight so this handler comes last.
|
||||
$webform_handler->setWeight(count($this->webform->getHandlers()));
|
||||
return $webform_handler;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Core\Form\ConfirmFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\webform\WebformDialogTrait;
|
||||
use Drupal\webform\WebformInterface;
|
||||
|
||||
/**
|
||||
* Form for deleting a webform handler.
|
||||
*/
|
||||
class WebformHandlerDeleteForm extends ConfirmFormBase {
|
||||
|
||||
use WebformDialogTrait;
|
||||
|
||||
/**
|
||||
* The webform containing the webform handler to be deleted.
|
||||
*
|
||||
* @var \Drupal\webform\WebformInterface
|
||||
*/
|
||||
protected $webform;
|
||||
|
||||
/**
|
||||
* The webform handler to be deleted.
|
||||
*
|
||||
* @var \Drupal\webform\WebformHandlerInterface
|
||||
*/
|
||||
protected $webformHandler;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getQuestion() {
|
||||
return $this->t('Are you sure you want to delete the @handler handler from the %webform webform?', ['%webform' => $this->webform->label(), '@handler' => $this->webformHandler->label()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfirmText() {
|
||||
return $this->t('Delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCancelUrl() {
|
||||
return $this->webform->toUrl('handlers-form');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'webform_handler_delete_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state, WebformInterface $webform = NULL, $webform_handler = NULL) {
|
||||
$this->webform = $webform;
|
||||
$this->webformHandler = $this->webform->getHandler($webform_handler);
|
||||
|
||||
$form = parent::buildForm($form, $form_state);
|
||||
$this->buildConfirmFormDialog($form, $form_state);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
$this->webform->deleteWebformHandler($this->webformHandler);
|
||||
drupal_set_message($this->t('The webform handler %name has been deleted.', ['%name' => $this->webformHandler->label()]));
|
||||
$form_state->setRedirectUrl($this->webform->toUrl('handlers-form'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\webform\WebformInterface;
|
||||
|
||||
/**
|
||||
* Provides a duplicate form for webform handler.
|
||||
*/
|
||||
class WebformHandlerDuplicateForm extends WebformHandlerAddForm {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state, WebformInterface $webform = NULL, $webform_handler = NULL) {
|
||||
$form = parent::buildForm($form, $form_state, $webform, $webform_handler);
|
||||
$form['#title'] = $this->t('Duplicate @label handler', ['@label' => $this->webformHandler->label()]);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareWebformHandler($webform_handler) {
|
||||
$webform_handler = clone $this->webform->getHandler($webform_handler);
|
||||
$webform_handler->setHandlerId(NULL);
|
||||
// Initialize the handler an pass in the webform.
|
||||
$webform_handler->init($this->webform);
|
||||
// Set the initial weight so this handler comes last.
|
||||
$webform_handler->setWeight(count($this->webform->getHandlers()));
|
||||
return $webform_handler;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\webform\WebformInterface;
|
||||
|
||||
/**
|
||||
* Provides an edit form for webform handlers.
|
||||
*/
|
||||
class WebformHandlerEditForm extends WebformHandlerFormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state, WebformInterface $webform = NULL, $webform_handler = NULL) {
|
||||
$form = parent::buildForm($form, $form_state, $webform, $webform_handler);
|
||||
$form['#title'] = $this->t('Edit @label handler', ['@label' => $this->webformHandler->label()]);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareWebformHandler($webform_handler) {
|
||||
return $this->webform->getHandler($webform_handler);
|
||||
}
|
||||
|
||||
}
|
||||
255
web/modules/contrib/webform/src/Form/WebformHandlerFormBase.php
Normal file
255
web/modules/contrib/webform/src/Form/WebformHandlerFormBase.php
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormState;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
|
||||
use Drupal\webform\WebformDialogTrait;
|
||||
use Drupal\webform\WebformHandlerInterface;
|
||||
use Drupal\webform\WebformInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* Provides a base webform for webform handlers.
|
||||
*/
|
||||
abstract class WebformHandlerFormBase extends FormBase {
|
||||
|
||||
use WebformDialogTrait;
|
||||
|
||||
/**
|
||||
* The webform.
|
||||
*
|
||||
* @var \Drupal\webform\WebformInterface
|
||||
*/
|
||||
protected $webform;
|
||||
|
||||
/**
|
||||
* The webform handler.
|
||||
*
|
||||
* @var \Drupal\webform\WebformHandlerInterface
|
||||
*/
|
||||
protected $webformHandler;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'webform_handler_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* Form constructor.
|
||||
*
|
||||
* @param array $form
|
||||
* An associative array containing the structure of the form.
|
||||
* @param \Drupal\Core\Form\FormStateInterface $form_state
|
||||
* The current state of the form.
|
||||
* @param \Drupal\webform\WebformInterface $webform
|
||||
* The webform.
|
||||
* @param string $webform_handler
|
||||
* The webform handler ID.
|
||||
*
|
||||
* @return array
|
||||
* The webform structure.
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
|
||||
* Throws not found exception if the number of handler instances for this
|
||||
* webform exceeds the handler's cardinality.
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state, WebformInterface $webform = NULL, $webform_handler = NULL) {
|
||||
$this->webform = $webform;
|
||||
try {
|
||||
$this->webformHandler = $this->prepareWebformHandler($webform_handler);
|
||||
}
|
||||
catch (PluginNotFoundException $e) {
|
||||
throw new NotFoundHttpException("Invalid handler id: '$webform_handler'.");
|
||||
}
|
||||
|
||||
// Limit the number of plugin instanced allowed.
|
||||
if (!$this->webformHandler->getHandlerId()) {
|
||||
$plugin_id = $this->webformHandler->getPluginId();
|
||||
$cardinality = $this->webformHandler->cardinality();
|
||||
$number_of_instances = $webform->getHandlers($plugin_id)->count();
|
||||
if ($cardinality !== WebformHandlerInterface::CARDINALITY_UNLIMITED && $cardinality <= $number_of_instances) {
|
||||
$t_args = ['@number' => $cardinality, '@instances' => $this->formatPlural($cardinality, $this->t('instance is'), $this->t('instances are'))];
|
||||
throw new NotFoundHttpException($this->t('Only @number @instance permitted', $t_args));
|
||||
}
|
||||
}
|
||||
|
||||
$request = $this->getRequest();
|
||||
|
||||
$form['description'] = [
|
||||
'#markup' => $this->webformHandler->description(),
|
||||
'#prefix' => '<p>',
|
||||
'#suffix' => '</p>',
|
||||
];
|
||||
|
||||
$form['id'] = [
|
||||
'#type' => 'value',
|
||||
'#value' => $this->webformHandler->getPluginId(),
|
||||
];
|
||||
|
||||
$form['status'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Enable the %name handler.', ['%name' => $this->webformHandler->label()]),
|
||||
'#default_value' => $this->webformHandler->isEnabled(),
|
||||
// Disable broken plugins.
|
||||
'#disabled' => ($this->webformHandler->getPluginId() == 'broken'),
|
||||
];
|
||||
|
||||
$form['label'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Title'),
|
||||
'#maxlength' => 255,
|
||||
'#default_value' => $this->webformHandler->label(),
|
||||
'#required' => TRUE,
|
||||
'#attributes' => ['autofocus' => 'autofocus'],
|
||||
];
|
||||
|
||||
$form['handler_id'] = [
|
||||
'#type' => 'machine_name',
|
||||
'#maxlength' => 64,
|
||||
'#description' => $this->t('A unique name for this handler instance. Must be alpha-numeric and underscore separated.'),
|
||||
'#default_value' => $this->webformHandler->getHandlerId() ?: $this->getUniqueMachineName($this->webformHandler),
|
||||
'#required' => TRUE,
|
||||
'#disabled' => $this->webformHandler->getHandlerId() ? TRUE : FALSE,
|
||||
'#machine_name' => [
|
||||
'exists' => [$this, 'exists'],
|
||||
],
|
||||
];
|
||||
|
||||
$form['settings'] = $this->webformHandler->buildConfigurationForm([], $form_state);
|
||||
// Get $form['settings']['#attributes']['novalidate'] and apply it to the
|
||||
// $form.
|
||||
// This allows handlers with hide/show logic to skip HTML5 validation.
|
||||
// @see http://stackoverflow.com/questions/22148080/an-invalid-form-control-with-name-is-not-focusable
|
||||
if (isset($form['settings']['#attributes']['novalidate'])) {
|
||||
$form['#attributes']['novalidate'] = 'novalidate';
|
||||
}
|
||||
$form['settings']['#tree'] = TRUE;
|
||||
|
||||
// Check the URL for a weight, then the webform handler,
|
||||
// otherwise use default.
|
||||
$form['weight'] = [
|
||||
'#type' => 'hidden',
|
||||
'#value' => $request->query->has('weight') ? (int) $request->query->get('weight') : $this->webformHandler->getWeight(),
|
||||
];
|
||||
|
||||
$form['actions'] = ['#type' => 'actions'];
|
||||
$form['actions']['submit'] = [
|
||||
'#type' => 'submit',
|
||||
'#value' => $this->t('Save'),
|
||||
'#button_type' => 'primary',
|
||||
];
|
||||
|
||||
$form = $this->buildFormDialog($form, $form_state);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateForm(array &$form, FormStateInterface $form_state) {
|
||||
// The webform handler configuration is stored in the 'settings' key in
|
||||
// the webform, pass that through for validation.
|
||||
$settings = $form_state->getValue('settings') ?: [];
|
||||
$handler_state = (new FormState())->setValues($settings);
|
||||
$this->webformHandler->validateConfigurationForm($form, $handler_state);
|
||||
|
||||
// Process handler state webform errors.
|
||||
$this->processHandlerFormErrors($handler_state, $form_state);
|
||||
|
||||
// Update the original webform values.
|
||||
$form_state->setValue('settings', $handler_state->getValues());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
if ($response = $this->validateDialog($form, $form_state)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$form_state->cleanValues();
|
||||
|
||||
// The webform handler configuration is stored in the 'settings' key in
|
||||
// the webform, pass that through for submission.
|
||||
$handler_data = (new FormState())->setValues($form_state->getValue('settings'));
|
||||
|
||||
$this->webformHandler->submitConfigurationForm($form, $handler_data);
|
||||
// Update the original webform values.
|
||||
$form_state->setValue('settings', $handler_data->getValues());
|
||||
|
||||
$is_new = ($this->webformHandler->getHandlerId()) ? FALSE : TRUE;
|
||||
|
||||
$this->webformHandler->setHandlerId($form_state->getValue('handler_id'));
|
||||
$this->webformHandler->setLabel($form_state->getValue('label'));
|
||||
$this->webformHandler->setStatus($form_state->getValue('status'));
|
||||
$this->webformHandler->setWeight($form_state->getValue('weight'));
|
||||
if ($is_new) {
|
||||
$this->webform->addWebformHandler($this->webformHandler->getConfiguration());
|
||||
}
|
||||
$this->webform->save();
|
||||
|
||||
// Display status message.
|
||||
drupal_set_message($this->t('The webform handler was successfully applied.'));
|
||||
|
||||
// Redirect.
|
||||
return $this->redirectForm($form, $form_state, $this->webform->toUrl('handlers-form'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a unique machine name for a webform handler instance.
|
||||
*
|
||||
* @param \Drupal\webform\WebformHandlerInterface $handler
|
||||
* The webform handler.
|
||||
*
|
||||
* @return string
|
||||
* Returns the unique name.
|
||||
*/
|
||||
public function getUniqueMachineName(WebformHandlerInterface $handler) {
|
||||
$suggestion = $handler->getPluginId();
|
||||
$count = 1;
|
||||
$machine_default = $suggestion;
|
||||
$instance_ids = $this->webform->getHandlers()->getInstanceIds();
|
||||
while (isset($instance_ids[$machine_default])) {
|
||||
$machine_default = $suggestion . '_' . $count++;
|
||||
}
|
||||
// Only return a suggestion if it is not the default plugin id.
|
||||
return ($machine_default != $handler->getPluginId()) ? $machine_default : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the webform handler ID already exists.
|
||||
*
|
||||
* @param string $handler_id
|
||||
* The webform handler ID.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the webform handler ID exists, FALSE otherwise.
|
||||
*/
|
||||
public function exists($handler_id) {
|
||||
$instance_ids = $this->webform->getHandlers()->getInstanceIds();
|
||||
|
||||
return (isset($instance_ids[$handler_id])) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process handler webform errors in webform.
|
||||
*
|
||||
* @param \Drupal\Core\Form\FormStateInterface $handler_state
|
||||
* The webform handler webform state.
|
||||
* @param \Drupal\Core\Form\FormStateInterface &$form_state
|
||||
* The webform state.
|
||||
*/
|
||||
protected function processHandlerFormErrors(FormStateInterface $handler_state, FormStateInterface &$form_state) {
|
||||
foreach ($handler_state->getErrors() as $name => $message) {
|
||||
$form_state->setErrorByName($name, $message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Webform for webform results clear webform.
|
||||
*/
|
||||
class WebformResultsClearForm extends WebformSubmissionsDeleteFormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'webform_results_clear';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getQuestion() {
|
||||
if ($this->sourceEntity) {
|
||||
$t_args = ['%title' => $this->sourceEntity->label()];
|
||||
}
|
||||
else {
|
||||
$t_args = ['%title' => $this->webform->label()];
|
||||
}
|
||||
return $this->t('Are you sure you want to delete all submissions to the %title webform?', $t_args);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCancelUrl() {
|
||||
$route_name = $this->requestHandler->getRouteName($this->webform, $this->sourceEntity, 'webform.results_submissions');
|
||||
$route_parameters = $this->requestHandler->getRouteParameters($this->webform, $this->sourceEntity);
|
||||
return new Url($route_name, $route_parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMessage() {
|
||||
if ($this->sourceEntity) {
|
||||
$t_args = ['%title' => $this->sourceEntity->label()];
|
||||
}
|
||||
else {
|
||||
$t_args = ['%title' => $this->webform->label()];
|
||||
}
|
||||
$this->t('Webform %title submissions cleared.', $t_args);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,334 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\webform\WebformRequestInterface;
|
||||
use Drupal\webform\WebformSubmissionStorageInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Webform for webform results custom(ize) webform.
|
||||
*/
|
||||
class WebformResultsCustomForm extends FormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'webform_results_custom';
|
||||
}
|
||||
|
||||
/**
|
||||
* The webform entity.
|
||||
*
|
||||
* @var \Drupal\webform\WebformInterface
|
||||
*/
|
||||
protected $webform;
|
||||
|
||||
/**
|
||||
* The webform source entity.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityInterface
|
||||
*/
|
||||
protected $sourceEntity;
|
||||
|
||||
/**
|
||||
* The webform submission storage.
|
||||
*
|
||||
* @var \Drupal\webform\WebformSubmissionStorageInterface
|
||||
*/
|
||||
protected $submissionStorage;
|
||||
|
||||
/**
|
||||
* Webform request handler.
|
||||
*
|
||||
* @var \Drupal\webform\WebformRequestInterface
|
||||
*/
|
||||
protected $requestHandler;
|
||||
|
||||
/**
|
||||
* Constructs a WebformResultsCustomForm object.
|
||||
*
|
||||
* @param \Drupal\webform\WebformSubmissionStorageInterface $webform_submission_storage
|
||||
* The webform submission storage.
|
||||
* @param \Drupal\webform\WebformRequestInterface $request_handler
|
||||
* The webform request handler.
|
||||
*/
|
||||
public function __construct(WebformSubmissionStorageInterface $webform_submission_storage, WebformRequestInterface $request_handler) {
|
||||
$this->submissionStorage = $webform_submission_storage;
|
||||
$this->requestHandler = $request_handler;
|
||||
list($this->webform, $this->sourceEntity) = $this->requestHandler->getWebformEntities();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager')->getStorage('webform_submission'),
|
||||
$container->get('webform.request')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$available_columns = $this->submissionStorage->getColumns($this->webform, $this->sourceEntity, NULL, TRUE);
|
||||
$custom_columns = $this->submissionStorage->getCustomColumns($this->webform, $this->sourceEntity, NULL, TRUE);
|
||||
// Change sid's # to an actual label.
|
||||
$available_columns['sid']['title'] = $this->t('Submission ID');
|
||||
if (isset($custom_columns['sid'])) {
|
||||
$custom_columns['sid']['title'] = $this->t('Submission ID');
|
||||
}
|
||||
|
||||
// Columns.
|
||||
$columns_options = [];
|
||||
foreach ($available_columns as $column_name => $column) {
|
||||
$title = (strpos($column_name, 'element__') === 0) ? ['data' => ['#markup' => '<b>' . $column['title'] . '</b>']] : $column['title'];
|
||||
$key = (isset($column['key'])) ? str_replace('webform_', '', $column['key']) : $column['name'];
|
||||
$columns_options[$column_name] = ['title' => $title, 'key' => $key];
|
||||
}
|
||||
$columns_keys = array_keys($custom_columns);
|
||||
$columns_default_value = array_combine($columns_keys, $columns_keys);
|
||||
$form['columns'] = [
|
||||
'#type' => 'webform_tableselect_sort',
|
||||
'#header' => [
|
||||
'title' => $this->t('Title'),
|
||||
'key' => $this->t('Key'),
|
||||
],
|
||||
'#options' => $columns_options,
|
||||
'#default_value' => $columns_default_value,
|
||||
];
|
||||
|
||||
// Get available sort options.
|
||||
$sort_options = [];
|
||||
$sort_columns = $available_columns;
|
||||
ksort($sort_columns);
|
||||
foreach ($sort_columns as $column_name => $column) {
|
||||
if (!isset($column['sort']) || $column['sort'] === TRUE) {
|
||||
$sort_options[$column_name] = (string) $column['title'];
|
||||
};
|
||||
}
|
||||
asort($sort_options);
|
||||
|
||||
// Sort and direction.
|
||||
// Display available columns sorted alphabetically.
|
||||
$sort = $this->webform->getState($this->getStateKey('sort'), 'serial');
|
||||
$direction = $this->webform->getState($this->getStateKey('direction'), 'desc');
|
||||
$form['sort'] = [
|
||||
'#prefix' => '<div class="container-inline">',
|
||||
'#type' => 'select',
|
||||
'#field_prefix' => $this->t('Sort by'),
|
||||
'#options' => $sort_options,
|
||||
'#default_value' => $sort,
|
||||
];
|
||||
$form['direction'] = [
|
||||
'#type' => 'select',
|
||||
'#field_prefix' => ' ' . $this->t('in', [], ['context' => 'Sort by {sort} in {direction} order.']) . ' ',
|
||||
'#field_suffix' => ' ' . $this->t('order', [], ['context' => 'Sort by {sort} in {direction} order.']) . '.',
|
||||
'#options' => [
|
||||
'asc' => $this->t('Ascending (ASC)'),
|
||||
'desc' => $this->t('Descending (DESC)'),
|
||||
],
|
||||
'#default_value' => $direction,
|
||||
'#suffix' => '</div>',
|
||||
];
|
||||
|
||||
// Limit.
|
||||
$limit = $this->webform->getState($this->getStateKey('limit'), NULL);
|
||||
$form['limit'] = [
|
||||
'#type' => 'select',
|
||||
'#field_prefix' => $this->t('Show', [], ['context' => 'Show {limit} results per page.']),
|
||||
'#field_suffix' => $this->t('results per page') . '.',
|
||||
'#options' => [
|
||||
'20' => '20',
|
||||
'50' => '50',
|
||||
'100' => '100',
|
||||
'200' => '200',
|
||||
'500' => '500',
|
||||
'1000' => '1000',
|
||||
'0' => $this->t('All'),
|
||||
],
|
||||
'#default_value' => ($limit != NULL) ? $limit : 50,
|
||||
];
|
||||
|
||||
// Default configuration.
|
||||
if (empty($this->sourceEntity)) {
|
||||
$form['config'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Configuration settings'),
|
||||
];
|
||||
$form['config']['default'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Use as default configuration'),
|
||||
'#description' => $this->t('If checked, the above settings will be used as the default configuration for all associated Webform nodes.'),
|
||||
'#return_value' => TRUE,
|
||||
'#default_value' => $this->webform->getState($this->getStateKey('default'), TRUE),
|
||||
];
|
||||
}
|
||||
|
||||
// Format settings.
|
||||
$format = $this->webform->getState($this->getStateKey('format'), [
|
||||
'header_format' => 'label',
|
||||
'element_format' => 'value',
|
||||
]);
|
||||
$form['format'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Format settings'),
|
||||
'#tree' => TRUE,
|
||||
];
|
||||
$form['format']['header_format'] = [
|
||||
'#type' => 'radios',
|
||||
'#title' => $this->t('Column header format'),
|
||||
'#description' => $this->t('Choose whether to show the element label or element key in each column header.'),
|
||||
'#options' => [
|
||||
'label' => $this->t('Element titles (label)'),
|
||||
'key' => $this->t('Element keys (key)'),
|
||||
],
|
||||
'#default_value' => $format['header_format'],
|
||||
];
|
||||
$form['format']['element_format'] = [
|
||||
'#type' => 'radios',
|
||||
'#title' => $this->t('Element format'),
|
||||
'#options' => [
|
||||
'value' => $this->t('Labels/values, the human-readable value (value)'),
|
||||
'raw' => $this->t('Raw values, the raw value stored in the database (raw)'),
|
||||
],
|
||||
'#default_value' => $format['element_format'],
|
||||
];
|
||||
|
||||
// Build actions.
|
||||
$form['actions']['#type'] = 'actions';
|
||||
$form['actions']['save'] = [
|
||||
'#type' => 'submit',
|
||||
'#value' => $this->t('Save'),
|
||||
];
|
||||
$form['actions']['delete'] = [
|
||||
'#type' => 'submit',
|
||||
'#value' => $this->t('Reset'),
|
||||
'#attributes' => [
|
||||
'class' => ['button', 'button--danger'],
|
||||
],
|
||||
'#access' => $this->webform->hasState($this->getStateKey('columns')),
|
||||
'#submit' => ['::delete'],
|
||||
];
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build table row for a results columns.
|
||||
*
|
||||
* @param string $column_name
|
||||
* The column name.
|
||||
* @param array $column
|
||||
* The column.
|
||||
* @param bool $default_value
|
||||
* Whether the column should be checked.
|
||||
* @param int $weight
|
||||
* The columns weights.
|
||||
* @param int $delta
|
||||
* The max delta for the weight element.
|
||||
*
|
||||
* @return array
|
||||
* A renderable containing a table row for a results column.
|
||||
*/
|
||||
protected function buildRow($column_name, array $column, $default_value, $weight, $delta) {
|
||||
return [
|
||||
'#attributes' => ['class' => ['draggable']],
|
||||
'name' => [
|
||||
'#type' => 'checkbox',
|
||||
'#default_value' => $default_value,
|
||||
],
|
||||
'title' => [
|
||||
'#markup' => $column['title'],
|
||||
],
|
||||
'key' => [
|
||||
'#markup' => (isset($column['key'])) ? $column['key'] : $column['name'],
|
||||
],
|
||||
'weight' => [
|
||||
'#type' => 'weight',
|
||||
'#title' => $this->t('Weight for @label', ['@label' => $column['title']]),
|
||||
'#title_display' => 'invisible',
|
||||
'#attributes' => [
|
||||
'class' => ['table-sort-weight'],
|
||||
],
|
||||
'#delta' => $delta,
|
||||
'#default_value' => $weight,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateForm(array &$form, FormStateInterface $form_state) {
|
||||
$columns = $form_state->getValue('columns');
|
||||
if (empty($columns)) {
|
||||
$form_state->setErrorByName('columns', $this->t('At least once column is required'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
// Set columns.
|
||||
$this->webform->setState($this->getStateKey('columns'), $form_state->getValue('columns'));
|
||||
|
||||
// Set sort, direction, limit.
|
||||
$this->webform->setState($this->getStateKey('sort'), $form_state->getValue('sort'));
|
||||
$this->webform->setState($this->getStateKey('direction'), $form_state->getValue('direction'));
|
||||
$this->webform->setState($this->getStateKey('limit'), (int) $form_state->getValue('limit'));
|
||||
$this->webform->setState($this->getStateKey('format'), $form_state->getValue('format'));
|
||||
|
||||
// Set default.
|
||||
if (empty($this->sourceEntity)) {
|
||||
$this->webform->setState($this->getStateKey('default'), $form_state->getValue('default'));
|
||||
}
|
||||
|
||||
// Display message.
|
||||
drupal_set_message($this->t('The customized table has been saved.'));
|
||||
|
||||
// Set redirect.
|
||||
$route_name = $this->requestHandler->getRouteName($this->webform, $this->sourceEntity, 'webform.results_table');
|
||||
$route_parameters = $this->requestHandler->getRouteParameters($this->webform, $this->sourceEntity);
|
||||
$form_state->setRedirect($route_name, $route_parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Webform delete customized columns handler.
|
||||
*
|
||||
* @param array $form
|
||||
* An associative array containing the structure of the form.
|
||||
* @param \Drupal\Core\Form\FormStateInterface $form_state
|
||||
* The current state of the form.
|
||||
*/
|
||||
public function delete(array &$form, FormStateInterface $form_state) {
|
||||
$this->webform->deleteState($this->getStateKey('columns'));
|
||||
$this->webform->deleteState($this->getStateKey('sort'));
|
||||
$this->webform->deleteState($this->getStateKey('direction'));
|
||||
$this->webform->deleteState($this->getStateKey('limit'));
|
||||
$this->webform->deleteState($this->getStateKey('default'));
|
||||
$this->webform->deleteState($this->getStateKey('format'));
|
||||
drupal_set_message($this->t('The customized table has been reset.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the state key for the custom data.
|
||||
*
|
||||
* @return string
|
||||
* The state key for the custom data.
|
||||
*/
|
||||
protected function getStateKey($name) {
|
||||
if ($source_entity = $this->sourceEntity) {
|
||||
return "results.custom.$name." . $source_entity->getEntityTypeId() . '.' . $source_entity->id();
|
||||
}
|
||||
else {
|
||||
return "results.custom.$name";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\webform\WebformSubmissionExporterInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Webform for webform results export webform.
|
||||
*/
|
||||
class WebformResultsExportForm extends FormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'webform_results_export';
|
||||
}
|
||||
|
||||
/**
|
||||
* The webform submission exporter.
|
||||
*
|
||||
* @var \Drupal\webform\WebformSubmissionExporterInterface
|
||||
*/
|
||||
protected $submissionExporter;
|
||||
|
||||
/**
|
||||
* Constructs a WebformResultsExportForm object.
|
||||
*
|
||||
* @param \Drupal\webform\WebformSubmissionExporterInterface $webform_submission_exporter
|
||||
* The webform submission exported.
|
||||
*/
|
||||
public function __construct(WebformSubmissionExporterInterface $webform_submission_exporter) {
|
||||
$this->submissionExporter = $webform_submission_exporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('webform_submission.exporter')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
// Set the merged default (global setting), saved, and user export options
|
||||
// into the webform's state.
|
||||
$settings_options = $this->config('webform.settings')->get('export');
|
||||
$saved_options = $this->submissionExporter->getWebformOptions();
|
||||
$user_options = $this->submissionExporter->getValuesFromInput($form_state->getUserInput());
|
||||
$export_options = NestedArray::mergeDeep($settings_options, $saved_options, $user_options);
|
||||
|
||||
// Build the webform.
|
||||
$this->submissionExporter->buildExportOptionsForm($form, $form_state, $export_options);
|
||||
|
||||
// Build actions.
|
||||
$form['actions']['#type'] = 'actions';
|
||||
$form['actions']['submit'] = [
|
||||
'#type' => 'submit',
|
||||
'#value' => $this->t('Download'),
|
||||
'#button_type' => 'primary',
|
||||
];
|
||||
$form['actions']['save'] = [
|
||||
'#type' => 'submit',
|
||||
'#value' => $this->t('Save settings'),
|
||||
'#submit' => ['::save'],
|
||||
];
|
||||
$form['actions']['delete'] = [
|
||||
'#type' => 'submit',
|
||||
'#value' => $this->t('Reset settings'),
|
||||
'#attributes' => [
|
||||
'class' => ['button', 'button--danger'],
|
||||
],
|
||||
'#access' => ($saved_options) ? TRUE : FALSE,
|
||||
'#submit' => ['::delete'],
|
||||
];
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
$export_options = $this->submissionExporter->getValuesFromInput($form_state->getValues());
|
||||
|
||||
// Implode exclude columns.
|
||||
$export_options['excluded_columns'] = implode(',', $export_options['excluded_columns']);
|
||||
|
||||
if ($source_entity = $this->submissionExporter->getSourceEntity()) {
|
||||
$entity_type = $source_entity->getEntityTypeId();
|
||||
$entity_id = $source_entity->id();
|
||||
$route_parameters = [$entity_type => $entity_id];
|
||||
$route_options = ['query' => $export_options];
|
||||
$form_state->setRedirect('entity.' . $entity_type . '.webform.results_export', $route_parameters, $route_options);
|
||||
}
|
||||
elseif ($webform = $this->submissionExporter->getWebform()) {
|
||||
$route_parameters = ['webform' => $webform->id()];
|
||||
$route_options = ['query' => $export_options];
|
||||
$form_state->setRedirect('entity.webform.results_export', $route_parameters, $route_options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Webform save configuration handler.
|
||||
*
|
||||
* @param array $form
|
||||
* An associative array containing the structure of the form.
|
||||
* @param \Drupal\Core\Form\FormStateInterface $form_state
|
||||
* The current state of the form.
|
||||
*/
|
||||
public function save(array &$form, FormStateInterface $form_state) {
|
||||
// Save the export options to the webform's state.
|
||||
$export_options = $this->submissionExporter->getValuesFromInput($form_state->getValues());
|
||||
$this->submissionExporter->setWebformOptions($export_options);
|
||||
drupal_set_message($this->t('The download settings have been saved.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Webform delete configuration handler.
|
||||
*
|
||||
* @param array $form
|
||||
* An associative array containing the structure of the form.
|
||||
* @param \Drupal\Core\Form\FormStateInterface $form_state
|
||||
* The current state of the form.
|
||||
*/
|
||||
public function delete(array &$form, FormStateInterface $form_state) {
|
||||
$this->submissionExporter->deleteWebformOptions();
|
||||
drupal_set_message($this->t('The download settings have been reset.'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Core\Entity\ContentEntityDeleteForm;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\webform\WebformRequestInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a confirmation webform for deleting a webform submission.
|
||||
*/
|
||||
class WebformSubmissionDeleteForm extends ContentEntityDeleteForm {
|
||||
|
||||
/**
|
||||
* The webform entity.
|
||||
*
|
||||
* @var \Drupal\webform\WebformInterface
|
||||
*/
|
||||
protected $webform;
|
||||
|
||||
|
||||
/**
|
||||
* The webform submission entity.
|
||||
*
|
||||
* @var \Drupal\webform\WebformSubmissionInterface
|
||||
*/
|
||||
protected $webformSubmission;
|
||||
|
||||
/**
|
||||
* The webform source entity.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityInterface
|
||||
*/
|
||||
protected $sourceEntity;
|
||||
|
||||
/**
|
||||
* Webform request handler.
|
||||
*
|
||||
* @var \Drupal\webform\WebformRequestInterface
|
||||
*/
|
||||
protected $requestHandler;
|
||||
|
||||
/**
|
||||
* Constructs a WebformSubmissionDeleteForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\webform\WebformRequestInterface $request_handler
|
||||
* The webform request handler.
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $entity_manager, WebformRequestInterface $request_handler) {
|
||||
parent::__construct($entity_manager);
|
||||
$this->requestHandler = $request_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager'),
|
||||
$container->get('webform.request')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
list($this->webformSubmission, $this->sourceEntity) = $this->requestHandler->getWebformSubmissionEntities();
|
||||
$this->webform = $this->webformSubmission->getWebform();
|
||||
return parent::buildForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getQuestion() {
|
||||
return $this->t('Are you sure you want to delete @title?', ['@title' => $this->webformSubmission->label()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getDeletionMessage() {
|
||||
return $this->t('@title has been deleted.', ['@title' => $this->webformSubmission->label()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCancelUrl() {
|
||||
$route_name = $this->requestHandler->getRouteName($this->webform, $this->sourceEntity, 'webform.results_submissions');
|
||||
$route_parameters = $this->requestHandler->getRouteParameters($this->webform, $this->sourceEntity);
|
||||
return new Url($route_name, $route_parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getRedirectUrl() {
|
||||
return $this->getCancelUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function logDeletionMessage() {
|
||||
// Deletion logging is handled via WebformSubmissionStorage.
|
||||
// @see \Drupal\webform\WebformSubmissionStorage::delete
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Form\ConfirmFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\user\PrivateTempStoreFactory;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
|
||||
/**
|
||||
* Provides a webform submission deletion confirmation form.
|
||||
*/
|
||||
class WebformSubmissionDeleteMultiple extends ConfirmFormBase {
|
||||
|
||||
/**
|
||||
* The array of webform_submissions to delete.
|
||||
*
|
||||
* @var string[][]
|
||||
*/
|
||||
protected $webformSubmissionInfo = [];
|
||||
|
||||
/**
|
||||
* The tempstore factory.
|
||||
*
|
||||
* @var \Drupal\user\PrivateTempStoreFactory
|
||||
*/
|
||||
protected $tempStoreFactory;
|
||||
|
||||
/**
|
||||
* The webform submission storage.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityStorageInterface
|
||||
*/
|
||||
protected $manager;
|
||||
|
||||
/**
|
||||
* Constructs a DeleteMultiple form object.
|
||||
*
|
||||
* @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
|
||||
* The tempstore factory.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $manager
|
||||
* The entity manager.
|
||||
*/
|
||||
public function __construct(PrivateTempStoreFactory $temp_store_factory, EntityManagerInterface $manager) {
|
||||
$this->tempStoreFactory = $temp_store_factory;
|
||||
$this->storage = $manager->getStorage('webform_submission');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('user.private_tempstore'),
|
||||
$container->get('entity.manager')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'webform_submission_multiple_delete_confirm';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getQuestion() {
|
||||
return $this->formatPlural(count($this->webformSubmissionInfo), 'Are you sure you want to delete this submission?', 'Are you sure you want to delete these submissions?');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCancelUrl() {
|
||||
return new Url('entity.webform_submission.collection');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfirmText() {
|
||||
return t('Delete');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
/** @var \Drupal\webform\WebformSubmissionInterface[] $webform_submissions */
|
||||
$webform_submissions = $this->tempStoreFactory->get('webform_submission_multiple_delete_confirm')->get(\Drupal::currentUser()->id());
|
||||
if (empty($webform_submissions)) {
|
||||
return new RedirectResponse($this->getCancelUrl()->setAbsolute()->toString());
|
||||
}
|
||||
|
||||
$form['webform_submissions'] = [
|
||||
'#theme' => 'item_list',
|
||||
'#items' => array_map(function ($webform_submission) {
|
||||
return $webform_submission->label();
|
||||
}, $webform_submissions),
|
||||
];
|
||||
$form = parent::buildForm($form, $form_state);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
/** @var \Drupal\webform\WebformSubmissionInterface[] $webform_submissions */
|
||||
$webform_submissions = $this->tempStoreFactory->get('webform_submission_multiple_delete_confirm')->get(\Drupal::currentUser()->id());
|
||||
if ($form_state->getValue('confirm') && !empty($webform_submissions)) {
|
||||
$this->storage->delete($webform_submissions);
|
||||
$this->logger('content')->notice('Deleted @count submission.', ['@count' => count($webform_submissions)]);
|
||||
$this->tempStoreFactory->get('webform_submission_multiple_delete_confirm')->delete(\Drupal::currentUser()->id());
|
||||
}
|
||||
|
||||
$form_state->setRedirect('entity.webform_submission.collection');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Provides the webform submission filter webform.
|
||||
*/
|
||||
class WebformSubmissionFilterForm extends WebformFilterFormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'webform_submission_filter_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state, $search = NULL, $state = NULL, array $state_options = []) {
|
||||
$form = parent::buildForm($form, $form_state, $search, $state, $state_options);
|
||||
$form['filter']['#title'] = $this->t('Filter submissions');
|
||||
$form['filter']['search']['#title'] = $this->t('Filter by submitted data and/or notes');
|
||||
$form['filter']['search']['#placeholder'] = $this->t('Filter by submitted data and/or notes');
|
||||
return $form;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,231 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\webform\Plugin\WebformHandler\EmailWebformHandler;
|
||||
use Drupal\webform\WebformRequestInterface;
|
||||
use Drupal\webform\WebformSubmissionInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines a webform that resends webform submission.
|
||||
*/
|
||||
class WebformSubmissionResendForm extends FormBase {
|
||||
|
||||
/**
|
||||
* A webform submission.
|
||||
*
|
||||
* @var \Drupal\webform\WebformSubmissionInterface
|
||||
*/
|
||||
protected $webformSubmission;
|
||||
|
||||
/**
|
||||
* The source entity.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityInterface
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'webform_submission_resend';
|
||||
}
|
||||
|
||||
/**
|
||||
* Webform request handler.
|
||||
*
|
||||
* @var \Drupal\webform\WebformRequestInterface
|
||||
*/
|
||||
protected $requestHandler;
|
||||
|
||||
/**
|
||||
* Constructs a WebformResultsResendForm object.
|
||||
*
|
||||
* @param \Drupal\webform\WebformRequestInterface $request_handler
|
||||
* The webform request handler.
|
||||
*/
|
||||
public function __construct(WebformRequestInterface $request_handler) {
|
||||
$this->requestHandler = $request_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('webform.request')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state, WebformSubmissionInterface $webform_submission = NULL) {
|
||||
$this->webformSubmission = $webform_submission;
|
||||
|
||||
$handlers = $webform_submission->getWebform()->getHandlers();
|
||||
|
||||
/** @var \Drupal\webform\WebformHandlerMessageInterface[] $message_handlers */
|
||||
$message_handlers = [];
|
||||
foreach ($handlers as $handler_id => $handler) {
|
||||
if ($handler instanceof EmailWebformHandler) {
|
||||
$message_handlers[$handler_id] = $handler;
|
||||
}
|
||||
}
|
||||
|
||||
// Get header.
|
||||
$header = [];
|
||||
$header['title'] = [
|
||||
'data' => $this->t('Title / Description'),
|
||||
];
|
||||
$header['id'] = [
|
||||
'data' => $this->t('ID'),
|
||||
'class' => [RESPONSIVE_PRIORITY_LOW],
|
||||
];
|
||||
$header['summary'] = [
|
||||
'data' => $this->t('summary'),
|
||||
'class' => [RESPONSIVE_PRIORITY_LOW],
|
||||
];
|
||||
$header['status'] = [
|
||||
'data' => $this->t('Status'),
|
||||
'class' => [RESPONSIVE_PRIORITY_LOW],
|
||||
];
|
||||
|
||||
// Get options.
|
||||
$options = [];
|
||||
foreach ($message_handlers as $index => $message_handler) {
|
||||
$message = $message_handler->getMessage($this->webformSubmission);
|
||||
|
||||
$options[$index]['title'] = [
|
||||
'data' => [
|
||||
'label' => [
|
||||
'#type' => 'label',
|
||||
'#title' => $message_handler->label() . ': ' . $message_handler->description(),
|
||||
'#title_display' => NULL,
|
||||
'#for' => 'edit-message-handler-id-' . str_replace('_', '-', $message_handler->getHandlerId()),
|
||||
],
|
||||
],
|
||||
];
|
||||
$options[$index]['id'] = [
|
||||
'data' => $message_handler->getHandlerId(),
|
||||
];
|
||||
$options[$index]['summary'] = [
|
||||
'data' => $message_handler->getMessageSummary($message),
|
||||
];
|
||||
$options[$index]['status'] = ($message_handler->isEnabled()) ? $this->t('Enabled') : $this->t('Disabled');
|
||||
}
|
||||
|
||||
// Get message handler id.
|
||||
if (empty($form_state->getValue('message_handler_id'))) {
|
||||
reset($options);
|
||||
$message_handler_id = key($options);
|
||||
$form_state->setValue('message_handler_id', $message_handler_id);
|
||||
}
|
||||
else {
|
||||
$message_handler_id = $form_state->getValue('message_handler_id');
|
||||
}
|
||||
|
||||
$message_handler = $this->getMessageHandler($form_state);
|
||||
$form['message_handler_id'] = [
|
||||
'#type' => 'tableselect',
|
||||
'#header' => $header,
|
||||
'#options' => $options,
|
||||
'#js_select' => TRUE,
|
||||
'#empty' => $this->t('No messages are available.'),
|
||||
'#multiple' => FALSE,
|
||||
'#default_value' => $message_handler_id,
|
||||
'#ajax' => [
|
||||
'callback' => '::updateMessage',
|
||||
'wrapper' => 'edit-webform-message-wrapper',
|
||||
],
|
||||
];
|
||||
|
||||
// Message.
|
||||
$form['message'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Message'),
|
||||
'#open' => TRUE,
|
||||
'#tree' => TRUE,
|
||||
'#prefix' => '<div id="edit-webform-message-wrapper">',
|
||||
'#suffix' => '</div>',
|
||||
];
|
||||
$message = $message_handler->getMessage($webform_submission);
|
||||
$form['message'] += $message_handler->resendMessageForm($message);
|
||||
|
||||
// Add resend button.
|
||||
$form['submit'] = [
|
||||
'#type' => 'submit',
|
||||
'#value' => $this->t('Resend message'),
|
||||
];
|
||||
|
||||
// Add submission navigation.
|
||||
$source_entity = $this->requestHandler->getCurrentSourceEntity('webform_submission');
|
||||
$form['navigation'] = [
|
||||
'#theme' => 'webform_submission_navigation',
|
||||
'#webform_submission' => $webform_submission,
|
||||
'#weight' => -20,
|
||||
];
|
||||
$form['information'] = [
|
||||
'#theme' => 'webform_submission_information',
|
||||
'#webform_submission' => $webform_submission,
|
||||
'#source_entity' => $source_entity,
|
||||
'#weight' => -19,
|
||||
];
|
||||
$form['#attached']['library'][] = 'webform/webform.admin';
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles switching between messages.
|
||||
*
|
||||
* @param array $form
|
||||
* An associative array containing the structure of the form.
|
||||
* @param \Drupal\Core\Form\FormStateInterface $form_state
|
||||
* The current state of the form.
|
||||
*
|
||||
* @return array
|
||||
* An associative array containing an email message.
|
||||
*/
|
||||
public function updateMessage(array $form, FormStateInterface $form_state) {
|
||||
$message_handler = $this->getMessageHandler($form_state);
|
||||
$message = $message_handler->getMessage($this->webformSubmission);
|
||||
foreach ($message as $key => $value) {
|
||||
$form['message'][$key]['#value'] = $value;
|
||||
}
|
||||
return $form['message'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
$params = $form_state->getValue('message');
|
||||
$message_handler = $this->getMessageHandler($form_state);
|
||||
$message_handler->sendMessage($params);
|
||||
|
||||
$t_args = [
|
||||
'%label' => $message_handler->label(),
|
||||
];
|
||||
drupal_set_message($this->t('Successfully re-sent %label.', $t_args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message handler from webform state.
|
||||
*
|
||||
* @param \Drupal\Core\Form\FormStateInterface $form_state
|
||||
* The current state of the form.
|
||||
*
|
||||
* @return \Drupal\webform\WebformHandlerMessageInterface
|
||||
* The current message handler.
|
||||
*/
|
||||
protected function getMessageHandler(FormStateInterface $form_state) {
|
||||
$message_handler_id = $form_state->getValue('message_handler_id');
|
||||
return $this->webformSubmission->getWebform()->getHandler($message_handler_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,210 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Form\ConfirmFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\webform\WebformInterface;
|
||||
use Drupal\webform\WebformRequestInterface;
|
||||
use Drupal\webform\WebformSubmissionStorageInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Base webform for deleting webform submission.
|
||||
*/
|
||||
abstract class WebformSubmissionsDeleteFormBase extends ConfirmFormBase {
|
||||
|
||||
/**
|
||||
* Default number of submission to be deleted during batch processing.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $batchLimit = 1000;
|
||||
|
||||
/**
|
||||
* The webform entity.
|
||||
*
|
||||
* @var \Drupal\webform\WebformInterface
|
||||
*/
|
||||
protected $webform;
|
||||
|
||||
/**
|
||||
* The webform source entity.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityInterface
|
||||
*/
|
||||
protected $sourceEntity;
|
||||
|
||||
/**
|
||||
* The webform submission storage.
|
||||
*
|
||||
* @var \Drupal\webform\WebformSubmissionStorageInterface
|
||||
*/
|
||||
protected $submissionStorage;
|
||||
|
||||
/**
|
||||
* Webform request handler.
|
||||
*
|
||||
* @var \Drupal\webform\WebformRequestInterface
|
||||
*/
|
||||
protected $requestHandler;
|
||||
|
||||
/**
|
||||
* Constructs a WebformResultsDeleteFormBase object.
|
||||
*
|
||||
* @param \Drupal\webform\WebformSubmissionStorageInterface $webform_submission_storage
|
||||
* The webform submission storage.
|
||||
* @param \Drupal\webform\WebformRequestInterface $request_handler
|
||||
* The webform request handler.
|
||||
*/
|
||||
public function __construct(WebformSubmissionStorageInterface $webform_submission_storage, WebformRequestInterface $request_handler) {
|
||||
$this->submissionStorage = $webform_submission_storage;
|
||||
$this->requestHandler = $request_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager')->getStorage('webform_submission'),
|
||||
$container->get('webform.request')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfirmText() {
|
||||
return $this->t('Clear');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
list($this->webform, $this->sourceEntity) = $this->requestHandler->getWebformEntities();
|
||||
return parent::buildForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
$form_state->setRedirectUrl($this->getCancelUrl());
|
||||
if ($this->submissionStorage->getTotal($this->webform, $this->sourceEntity) < $this->getBatchLimit()) {
|
||||
$this->submissionStorage->deleteAll($this->webform, $this->sourceEntity);
|
||||
drupal_set_message($this->getFinishedMessage());
|
||||
}
|
||||
else {
|
||||
$this->batchSet($this->webform, $this->sourceEntity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Message to displayed after submissions are deleted.
|
||||
*
|
||||
* @return \Drupal\Core\StringTranslation\TranslatableMarkup
|
||||
* Message to be displayed after delete has finished.
|
||||
*/
|
||||
public function getFinishedMessage() {
|
||||
return $this->t('Webform submissions cleared.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch API; Initialize batch operations.
|
||||
*
|
||||
* @param \Drupal\webform\WebformInterface|null $webform
|
||||
* The webform.
|
||||
* @param \Drupal\Core\Entity\EntityInterface|null $entity
|
||||
* The webform's source entity.
|
||||
*/
|
||||
public function batchSet(WebformInterface $webform = NULL, EntityInterface $entity = NULL) {
|
||||
$parameters = [
|
||||
$webform,
|
||||
$entity,
|
||||
$this->submissionStorage->getMaxSubmissionId($webform, $entity),
|
||||
];
|
||||
$batch = [
|
||||
'title' => $this->t('Clear submissions'),
|
||||
'init_message' => $this->t('Clearing submission data'),
|
||||
'error_message' => $this->t('The submissions could not be cleared because an error occurred.'),
|
||||
'operations' => [
|
||||
[[$this, 'batchProcess'], $parameters],
|
||||
],
|
||||
'finished' => [$this, 'batchFinish'],
|
||||
];
|
||||
|
||||
batch_set($batch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of submissions to be deleted with each batch.
|
||||
*
|
||||
* @return int
|
||||
* Number of submissions to be deleted with each batch.
|
||||
*/
|
||||
public function getBatchLimit() {
|
||||
return $this->config('webform.settings')->get('batch.default_batch_delete_size') ?: $this->batchLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch API callback; Delete submissions.
|
||||
*
|
||||
* @param \Drupal\webform\WebformInterface|null $webform
|
||||
* The webform.
|
||||
* @param \Drupal\Core\Entity\EntityInterface|null $entity
|
||||
* The webform's source entity.
|
||||
* @param int $max_sid
|
||||
* The max submission ID to be delete.
|
||||
* @param mixed|array $context
|
||||
* The batch current context.
|
||||
*/
|
||||
public function batchProcess(WebformInterface $webform = NULL, EntityInterface $entity = NULL, $max_sid, &$context) {
|
||||
// ISSUE:
|
||||
// $this->submissionStorage is not being setup via
|
||||
// WebformSubmissionsDeleteFormBase::__construct.
|
||||
//
|
||||
// WORKAROUND:
|
||||
// Reset it for each batch process.
|
||||
$this->submissionStorage = \Drupal::entityTypeManager()->getStorage('webform_submission');
|
||||
|
||||
if (empty($context['sandbox'])) {
|
||||
$context['sandbox']['progress'] = 0;
|
||||
$context['sandbox']['max'] = $this->submissionStorage->getTotal($webform, $entity);
|
||||
$context['results']['webform'] = $webform;
|
||||
$context['results']['entity'] = $entity;
|
||||
}
|
||||
|
||||
// Track progress.
|
||||
$context['sandbox']['progress'] += $this->submissionStorage->deleteAll($webform, $entity, $this->getBatchLimit(), $max_sid);
|
||||
|
||||
$context['message'] = $this->t('Deleting @count of @total submissions...', ['@count' => $context['sandbox']['progress'], '@total' => $context['sandbox']['max']]);
|
||||
|
||||
// Track finished.
|
||||
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
|
||||
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch API callback; Completed deletion.
|
||||
*
|
||||
* @param bool $success
|
||||
* TRUE if batch successfully completed.
|
||||
* @param array $results
|
||||
* Batch results.
|
||||
* @param array $operations
|
||||
* An array of function calls (not used in this function).
|
||||
*/
|
||||
public function batchFinish($success = FALSE, array $results, array $operations) {
|
||||
if (!$success) {
|
||||
drupal_set_message($this->t('Finished with an error.'));
|
||||
}
|
||||
else {
|
||||
drupal_set_message($this->getFinishedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\webform\Form;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Webform for webform submission purge webform.
|
||||
*/
|
||||
class WebformSubmissionsPurgeForm extends WebformSubmissionsDeleteFormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'webform_submissions_purge';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getQuestion() {
|
||||
return $this->t('Are you sure you want to delete all submissions?');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfirmText() {
|
||||
return $this->t('Purge');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCancelUrl() {
|
||||
return new Url('entity.webform_submission.collection');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFinishedMessage() {
|
||||
return $this->t('Webform submissions purged.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$form = parent::buildForm($form, $form_state);
|
||||
|
||||
$submission_total = \Drupal::entityQuery('webform_submission')->count()->execute();
|
||||
$form_total = \Drupal::entityQuery('webform')->count()->execute();
|
||||
$t_args = [
|
||||
'@submission_total' => $submission_total,
|
||||
'@submissions' => $this->formatPlural($submission_total, $this->t('submission'), $this->t('submissions')),
|
||||
'@form_total' => $form_total,
|
||||
'@forms' => $this->formatPlural($form_total, $this->t('webform'), $this->t('webforms')),
|
||||
];
|
||||
|
||||
$form['confirm'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Are you sure you want to delete @submission_total @submissions in @form_total @forms?', $t_args),
|
||||
'#required' => TRUE,
|
||||
'#weight' => -10,
|
||||
];
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in a new issue