Skip to content
This repository has been archived by the owner on Sep 30, 2024. It is now read-only.

[SDPAP-7716] Added managed file element type and related settings. #82

Open
wants to merge 17 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
"dpc-sdp/tide_core": "3.2.5",
"drupal/token_conditions": "dev-compatible-with-drupal-9",
"drupal/webform": "^6.1@beta",
"drupal/webform_rest": "^4.0",
"drupal/restui": "^1.21",
"choices/choices": "9.0.1",
"codemirror/codemirror": "5.53.2",
"jquery/inputmask": "5.0.5",
Expand All @@ -18,6 +20,9 @@
"drupal/webform": {
"Filtering by category doesn't work - https://www.drupal.org/project/webform/issues/3313766": "https://www.drupal.org/files/issues/2022-10-07/3313766-8.patch",
"Exporting webform submission as batch does not allowed for extended field due to static method - https://www.drupal.org/project/webform/issues/3348336#comment-14969352": "https://www.drupal.org/files/issues/2023-03-16/exporting-webform-submission-static-batch-process-3348336-3.patch"
},
"drupal/webform_rest": {
"Send/Upload files - https://www.drupal.org/project/webform_rest/issues/2899902": "https://www.drupal.org/files/issues/2023-05-10/webform_rest-add_file_upload_resource-2899902-56-v4.x.patch"
}
}
},
Expand Down
17 changes: 17 additions & 0 deletions config/optional/rest.resource.webform_rest_file_upload.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
langcode: en
status: true
dependencies:
module:
- serialization
- user
- webform_rest
id: webform_rest_file_upload
plugin_id: webform_rest_file_upload
granularity: resource
configuration:
methods:
- POST
formats:
- json
authentication:
- cookie
8 changes: 3 additions & 5 deletions config/optional/webform.settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ element:
fieldset: fieldset
item: item
language_select: language_select
managed_file: managed_file
range: range
search: search
tableselect: tableselect
Expand All @@ -140,7 +139,6 @@ element:
webform_contact: webform_contact
webform_custom_composite: webform_custom_composite
webform_document_file: webform_document_file
webform_element: webform_element
webform_email_confirm: webform_email_confirm
webform_email_multiple: webform_email_multiple
webform_entity_checkboxes: webform_entity_checkboxes
Expand Down Expand Up @@ -178,11 +176,11 @@ html_editor:
format: ''
tidy: true
file:
file_public: false
file_public: true
file_private_redirect: true
file_private_redirect_message: 'Please login to access the uploaded file.'
default_max_filesize: ''
default_managed_file_extensions: 'gif jpg png bmp eps tif pict psd txt rtf html odf pdf doc docx ppt pptx xls xlsx xml avi mov mp3 ogg wav bz2 dmg gz jar rar sit svg tar zip'
default_max_filesize: '10 MB'
default_managed_file_extensions: 'docx jpg png pdf csv zip xls mp3 mp4 wav avi'
default_audio_file_extensions: 'mp3 ogg wav'
default_document_file_extensions: 'txt rtf pdf doc docx odt ppt pptx odp xls xlsx ods'
default_image_file_extensions: 'gif jpg png svg'
Expand Down
47 changes: 47 additions & 0 deletions src/Routing/JsonapiLimitingRouteSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Drupal\tide_webform\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
* Class JsonapiLimitingRouteSubscriber.
*
* Remove all DELETE routes from jsonapi resources to protect content.
*
* Remove POST and PATCH routes from jsonapi resources except for those
* we want end users to create and update via the decoupled API.
*/
class JsonapiLimitingRouteSubscriber extends RouteSubscriberBase {

/**
* {@inheritdoc}
*/
protected function alterRoutes(RouteCollection $collection) {
$mutable_types = $this->mutableResourceTypes();
foreach ($collection as $name => $route) {
$defaults = $route->getDefaults();
if (!empty($defaults['_is_jsonapi']) && !empty($defaults['resource_type'])) {
$methods = $route->getMethods();
if (in_array('DELETE', $methods)) {
// We never want to delete data, only unpublish.
$collection->remove($name);
}
}
}
}

/**
* Get mutable resource types, exposed to user changes via API.
*
* @return array
* List of mutable jsonapi resource types as keys.
*/
public function mutableResourceTypes(): array {
return [
'file--file' => TRUE,
];
}

}
18 changes: 18 additions & 0 deletions src/TideWebformSubmissionListBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Drupal\tide_webform;

use Drupal\Core\Database\Database;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\webform\WebformSubmissionListBuilder;
Expand All @@ -24,6 +25,11 @@ class TideWebformSubmissionListBuilder extends WebformSubmissionListBuilder {
*/
const STATE_UNPROCESSED = 'unprocessed';

/**
* Submission state with_attachments.
*/
const STATE_WITH_ATTACHMENTS = 'with_attachments';

/**
* {@inheritdoc}
*/
Expand All @@ -48,6 +54,18 @@ protected function getQuery($keys = '', $state = '', $source_entity = '') {
$query->condition('processed', 0);
break;

case static::STATE_WITH_ATTACHMENTS:
$sub_query = Database::getConnection()->select('webform_submission_data', 'sd');
$sub_query->join('file_usage', 'fu', 'fu.fid = CAST(sd.value as UNSIGNED)');
$sub_query
->fields('sd', ['sid'])
->condition('sd.value', '', '<>')
->groupBy('sd.sid');
$query->condition(
$query->orConditionGroup()
->condition('sid', $sub_query, 'IN')
);
break;
}
return $query;
}
Expand Down
2 changes: 2 additions & 0 deletions tide_webform.info.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ dependencies:
- token_conditions:token_conditions
- webform:webform
- webform:webform_ui
- webform_rest:webform_rest
- restui:restui
- dpc-sdp:tide_core
config_devel:
install:
Expand Down
38 changes: 38 additions & 0 deletions tide_webform.install
Original file line number Diff line number Diff line change
Expand Up @@ -325,3 +325,41 @@ function tide_webform_update_8013() {
$config->save();
}
}

/**
* Updating webform settings for managed_file types.
*/
function tide_webform_update_8014() {
/** @var \Drupal\Core\Extension\ModuleHandler $moduleHandler */
$moduleExists = \Drupal::service('module_handler')->moduleExists('webform_rest');
// Check if module is both installed and enabled.
if (!$moduleExists) {
// If not, install the queue_mail module.
\Drupal::service('module_installer')->install(['webform_rest', 'restui']);
}
if (\Drupal::moduleHandler()->moduleExists('webform')) {
$webform_elements = [
'managed_file',
'webform_element',
];
$config_factory = \Drupal::configFactory();
$config = $config_factory->getEditable('webform.settings');
$excluded_elements_values = $config->get('element.excluded_elements');
foreach ($webform_elements as $webform_element) {
if (array_key_exists($webform_element, $excluded_elements_values)) {
unset($excluded_elements_values[$webform_element]);
}
}
$config->set('element.excluded_elements', $excluded_elements_values);
$config->set('file.default_max_filesize', '10 MB');
$config->set('file.file_public', TRUE);
$config->set('file.default_managed_file_extensions', 'docx jpg png pdf csv zip xls mp3 mp4 wav avi');
$config->save();
}
module_load_include('inc', 'tide_core', 'includes/helpers');
$config_storage = \Drupal::service('config.storage');
$rest_resource_webform_file_upload = 'rest.resource.webform_rest_file_upload';
$config_location = [drupal_get_path('module', 'tide_webform') . '/config/optional'];
$config_read = _tide_read_config($rest_resource_webform_file_upload, $config_location, TRUE);
$config_storage->write($rest_resource_webform_file_upload, $config_read);
}
64 changes: 64 additions & 0 deletions tide_webform.module
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,15 @@ function tide_webform_form_alter(&$form, FormStateInterface $form_state, $form_i

if ($form_id == 'webform_ui_element_form') {
$form['#after_build'][] = 'tide_webform_webform_ui_element_form_after_build';
// Custom validation for the managed_file elemt type.
$form['#validate'][] = 'tide_webform_managed_file_type_element_validation';
}

if ($form_id == 'webform_submission_filter_form') {
$options = $form['filter']['state']['#options'];
$options['processed'] = 'Exported [' . tide_webform_submission_filter_query(1) . ']';
$options['unprocessed'] = 'New [' . tide_webform_submission_filter_query(0) . ']';
$options['with_attachments'] = 'With attachments [' . tide_webform_submission_data_filter() . ']';
$form['filter']['state']['#options'] = $options;
}

Expand Down Expand Up @@ -365,3 +368,64 @@ function tide_webform_form_webform_results_export_form_submit(array $form, FormS
$options = ['query' => $query];
$form_state->setRedirect('entity.webform.results_export', $route_parameters, $options);
}

/**
* Custom validation callback for managed file type element.
*
* @param array $element
* The form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* Form state.
*/
function tide_webform_managed_file_type_element_validation(array $element, FormStateInterface $form_state) {
$allowed_file_formats = [
'docx',
'jpg',
'png',
'pdf',
'csv',
'zip',
'xls',
'mp3',
'mp4',
'wav',
'avi',
];
$element_settings = $form_state->getValues();
if ($element_settings["properties"]["type"] !== "managed_file") {
return;
}
$given_file_formats = explode(" ", $element_settings["properties"]["file_extensions"]);
if ($element_settings["properties"]["multiple"] > 3 || $element_settings["properties"]["multiple"] === TRUE) {
$form_state->setError($element, t('Maximum allowed number of values are 3.'));
}
$matched_values = array_intersect($allowed_file_formats, $given_file_formats);
if (count($matched_values) > 0) {
$unmatched_values = array_diff($given_file_formats, $matched_values);
if (count($unmatched_values) > 0) {
$form_state->setError($element, t('Invalid file formats found: @format', ['@format' => implode(", ", $unmatched_values)]));
}
}
$unmatched_values = array_diff($allowed_file_formats, $matched_values);
if (count($matched_values) == 0 && count($unmatched_values) > 0) {
$form_state->setError($element, t('Invalid file formats found: @format', ['@format' => implode(", ", $given_file_formats)]));
}
}

/**
* Function to build query for filter on webform submissions data pages.
*
* @return total
* Returns total from the webform submission data count.
*/
function tide_webform_submission_data_filter() {
$database = \Drupal::service('database');
$select = $database->select('webform_submission_data', 'sd');
$select->join('file_usage', 'fu', 'fu.fid = sd.value');
$select
->fields('sd', ['sid'])
->condition('sd.value', '', '<>');
$select->groupBy('sid');
$total = $select->countQuery()->execute()->fetchField();
return $total;
}
6 changes: 5 additions & 1 deletion tide_webform.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ services:
public: false
decorates: webform_submission.exporter
decoration_priority: 4
arguments: ['@tide_webform.exporter.inner', '@config.factory', '@file_system', '@entity_type.manager', '@stream_wrapper_manager', '@plugin.manager.archiver', '@plugin.manager.webform.element', '@plugin.manager.webform.exporter']
arguments: ['@tide_webform.exporter.inner', '@config.factory', '@file_system', '@entity_type.manager', '@stream_wrapper_manager', '@plugin.manager.archiver', '@plugin.manager.webform.element', '@plugin.manager.webform.exporter']
tide_webform.route_subscriber:
class: Drupal\tide_webform\Routing\JsonapiLimitingRouteSubscriber
tags:
- { name: event_subscriber }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added this service to block deleting files using json api