Skip to content

Commit

Permalink
Merge pull request #86 from esmero/ISSUE-85
Browse files Browse the repository at this point in the history
ISSUE-85 and ISSUE-84: Allow multivalued Webform elements to read single valued JSON data
  • Loading branch information
DiegoPino committed Jan 6, 2021
2 parents c05d121 + 54e5934 commit f9a3487
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 101 deletions.
16 changes: 15 additions & 1 deletion src/Controller/StrawberryRunnerModalController.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,20 @@ public function openModalForm(WebformInterface $webform = NULL, Request $request
}
else {
$data['data'] = $data_defaults + json_decode($stored_value,true);
// In case the saved data is "single valued" for a key
// But the corresponding webform element is not
// we cast to it multi valued so it can be read/updated
/* @var \Drupal\webform\WebformInterface $webform */
$webform_elements = $webform->getElementsInitializedFlattenedAndHasValue();
$elements_in_data = array_intersect_key($webform_elements, $data['data']);
if (is_array($elements_in_data) && count($elements_in_data)>0) {
foreach($elements_in_data as $key => $elements_in_datum) {
if (isset($elements_in_datum['#webform_multiple']) &&
$elements_in_datum['#webform_multiple']!== FALSE) {
$data['data'][$key] = (array) $data['data'][$key];
}
}
}
}

$confirmation_message = $webform->getSetting('confirmation_message', FALSE);
Expand Down Expand Up @@ -264,4 +278,4 @@ public function closeModalForm(Request $request)
}


}
}
Original file line number Diff line number Diff line change
Expand Up @@ -206,14 +206,13 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
if (empty($my_webform_machinename)) {
$my_webform_machinename = 'webform_strawberry_default';
}

/* @var \Drupal\webform\WebformInterface $my_webform */
$my_webform = \Drupal\webform\Entity\Webform::load($my_webform_machinename);
// Deals with any existing confirmation messages.
$confirmation_message = $my_webform->getSetting('confirmation_message', FALSE);
$confirmation_message = !empty($confirmation_message) && strlen(trim($confirmation_message)) > 0 ? $confirmation_message : $this->t(
'Thanks, you are all set! Please Save the content to persist the changes.');


if ($my_webform == null) {
// Well someone dropped the ball here
// and removed our super default
Expand Down Expand Up @@ -304,8 +303,25 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
}
else {
$data['data'] = $data_defaults + json_decode($stored_value,true);

// In case the saved data is "single valued" for a key
// But the corresponding webform element is not
// we cast to it multi valued so it can be read/updated
/* @var \Drupal\webform\WebformInterface $my_webform */
$webform_elements = $my_webform->getElementsInitializedFlattenedAndHasValue();
$elements_in_data = array_intersect_key($webform_elements, $data['data']);
if (is_array($elements_in_data) && count($elements_in_data)>0) {
foreach($elements_in_data as $key => $elements_in_datum) {
if (isset($elements_in_datum['#webform_multiple']) &&
$elements_in_datum['#webform_multiple']!== FALSE) {
//@TODO should we log this operation for admins?
$data['data'][$key] = (array) $data['data'][$key];
}
}
}
}


// @see \Drupal\webform_strawberryfield\Element\WebformCustom element.
// @TODO expose #override options in the widget config.
// @see \Drupal\webform\Entity\Webform::getDefaultSettings for all settings
Expand Down
103 changes: 5 additions & 98 deletions src/Plugin/WebformHandler/strawberryFieldharvester.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

namespace Drupal\webform_strawberryfield\Plugin\WebformHandler;

use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\TempStore\TempStoreException;
Expand Down Expand Up @@ -483,9 +481,10 @@ public function preSave(WebformSubmissionInterface $webform_submission) {

$values = $webform_submission->getData();
$cleanvalues = $values;
$processedcleanvalues = [];

// Helper structure to keep elements that map to entities around
$entity_mapping_structure = isset($cleanvalues['ap:entitymapping']) ? $cleanvalues['ap:entitymapping'] : [];

// Check which elements carry files around
$allelements = $webform_submission->getWebform()->getElementsManagedFiles();
foreach ($allelements as $element) {
Expand All @@ -495,17 +494,8 @@ public function preSave(WebformSubmissionInterface $webform_submission) {
// Track what fields map to file entities.
$entity_mapping_structure['entity:file'][] = $originalelement['#webform_key'];
// Process each managed files field.
$processedcleanvaluesforfield = $this->processFileField(
$originalelement,
$webform_submission,
$cleanvalues
);
// Merge since different fields can contribute to same as:filetype structure.
$processedcleanvalues = array_merge_recursive(
$processedcleanvalues,
$processedcleanvaluesforfield
);
}

// This is more expensive. Entity References?
$anyelement = $webform_submission->getWebform()->getElementsInitializedAndFlattened();
foreach ($anyelement as $elementkey => $element) {
Expand Down Expand Up @@ -534,14 +524,6 @@ public function preSave(WebformSubmissionInterface $webform_submission) {
SORT_STRING
));
}
// Distribute all processed AS values for each field into its final JSON
// Structure, e.g as:image, as:application, as:documents, etc.
foreach ($processedcleanvalues as $askey => $info) {
//@TODO ensure non managed files inside structure are preserved.
//Could come from another URL only field or added manually by some
// Advanced user.
$cleanvalues[$askey] = $info;
}
$cleanvalues['ap:entitymapping'] = $entity_mapping_structure;

if (isset($values["strawberry_field_widget_state_id"])) {
Expand Down Expand Up @@ -663,61 +645,6 @@ public function submitForm(
//$post_url = $this->configuration['submission_url'];
}

/**
* Process temp files and give them SBF structure
*
* @param array $element
* An associative array containing the file webform element.
* @param \Drupal\webform\webformSubmissionInterface $webform_submission
* @param $cleanvalues
*
* @return array
* Associative array keyed by AS type with binary info.
*/
public function processFileField(
array $element,
WebformSubmissionInterface $webform_submission,
$cleanvalues
) {

$key = $element['#webform_key'];
$type = $element['#type'];
// Equivalent of getting original data from an node entity
$original_data = $webform_submission->getOriginalData();
$processedAsValues = [];

$value = isset($cleanvalues[$key]) ? $cleanvalues[$key] : [];
$fids = (is_array($value)) ? $value : [$value];

$original_value = isset($original_data[$key]) ? $original_data[$key] : [];
$original_fids = (is_array(
$original_value
)) ? $original_value : [$original_value];

// Delete the old file uploads?
// @TODO build some cleanup logic here. Could be moved to attached field hook.
// Issue with this approach is that it is 100% webform dependant
// Won't apply in the same way if using direct JSON input and node save.

$delete_fids = array_diff($original_fids, $fids);

// @TODO what do we do with removed files?
// Idea. Check the fileUsage. If there is still some other than this one
// don't remove.
// @see \Drupal\webform\Plugin\WebformElement\WebformManagedFileBase::deleteFiles

// Exit if there is no fids.
if (empty($fids)) {
return $processedAsValues;
}

/* @see \Drupal\strawberryfield\StrawberryfieldFilePersisterService */
$processedAsValues = \Drupal::service('strawberryfield.file_persister')
->generateAsFileStructure($fids, $key, $cleanvalues);
return $processedAsValues;

}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -797,7 +724,7 @@ protected function getUriSchemeForManagedFile(array $element) {
if (isset($element['#uri_scheme'])) {
return $element['#uri_scheme'];
}
$scheme_options = \Drupal\webform\Plugin\WebformElement\WebformManagedFileBase::getVisibleStreamWrappers(
$scheme_options = WebformManagedFileBase::getVisibleStreamWrappers(
);
if (isset($scheme_options['private'])) {
return 'private';
Expand Down Expand Up @@ -963,7 +890,6 @@ protected function getFieldsForBundle($bundle) {
$field_properties = array_intersect_key($field_properties, $field_schema['columns']);
}


if (!empty($field_properties)) {
$form[$field_name] = [
'#type' => 'details',
Expand Down Expand Up @@ -1177,7 +1103,6 @@ public function postSave(WebformSubmissionInterface $webform_submission, $update
public function calculateSbfJson(array $values, WebformSubmissionInterface $webform_submission) {

$cleanvalues = $values;
$processedcleanvalues = [];
// Helper structure to keep elements that map to entities around
$entity_mapping_structure = isset($cleanvalues['ap:entitymapping']) ? $cleanvalues['ap:entitymapping'] : [];
// Check which elements carry files around
Expand All @@ -1199,17 +1124,6 @@ public function calculateSbfJson(array $values, WebformSubmissionInterface $webf
);
// Track what fields map to file entities.
$entity_mapping_structure['entity:file'][] = $originalelement['#webform_key'];
// Process each managed files field.
$processedcleanvaluesforfield = $this->processFileField(
$originalelement,
$webform_submission,
$cleanvalues
);
// Merge since different fields can contribute to same as:filetype structure.
$processedcleanvalues = array_merge_recursive(
$processedcleanvalues,
$processedcleanvaluesforfield
);
}
// Check also which elements carry entity references around
// @see https://www.drupal.org/project/webform/issues/3067958
Expand All @@ -1227,14 +1141,7 @@ public function calculateSbfJson(array $values, WebformSubmissionInterface $webf
SORT_STRING
));
}
// Distribute all processed AS values for each field into its final JSON
// Structure, e.g as:image, as:application, as:documents, etc.
foreach ($processedcleanvalues as $askey => $info) {
//@TODO ensure non managed files inside structure are preserved.
//Could come from another URL only field or added manually by some
// Advanced user.
$cleanvalues[$askey] = $info;
}

$cleanvalues["ap:entitymapping"] = $entity_mapping_structure;
$cleanvalues["strawberry_field_widget_id"] = $this->getWebform()->id();
return $cleanvalues;
Expand Down

0 comments on commit f9a3487

Please sign in to comment.