You are here

public function ParagraphsWidget::massageFormValues in Paragraphs 8

Massages the form values into the format expected for field values.

Parameters

array $values: The submitted form values produced by the widget.

  • If the widget does not manage multiple values itself, the array holds the values generated by the multiple copies of the $element generated by the formElement() method, keyed by delta.
  • If the widget manages multiple values, the array holds the values of the form element generated by the formElement() method.

array $form: The form structure where field elements are attached to. This might be a full form structure, or a sub-element of a larger form.

\Drupal\Core\Form\FormStateInterface $form_state: The form state.

Return value

array An array of field values, keyed by delta.

Overrides WidgetBase::massageFormValues

File

src/Plugin/Field/FieldWidget/ParagraphsWidget.php, line 2224

Class

ParagraphsWidget
Plugin implementation of the 'entity_reference_revisions paragraphs' widget.

Namespace

Drupal\paragraphs\Plugin\Field\FieldWidget

Code

public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
  $field_name = $this->fieldDefinition
    ->getName();
  $widget_state = static::getWidgetState($form['#parents'], $field_name, $form_state);
  $element = NestedArray::getValue($form_state
    ->getCompleteForm(), $widget_state['array_parents']);
  if (!empty($widget_state['dragdrop'])) {
    $path = array_merge($form['#parents'], array(
      $field_name,
    ));
    static::reorderParagraphs($form_state, $path);

    // After re-ordering, get the updated widget state.
    $widget_state = static::getWidgetState($form['#parents'], $field_name, $form_state);

    // Re-create values based on current widget state.
    $values = [];
    foreach ($widget_state['paragraphs'] as $delta => $paragraph_state) {
      $values[$delta]['entity'] = $paragraph_state['entity'];
    }
    return $values;
  }
  foreach ($values as $delta => &$item) {
    if (isset($widget_state['paragraphs'][$item['_original_delta']]['entity']) && $widget_state['paragraphs'][$item['_original_delta']]['mode'] != 'remove') {

      /** @var \Drupal\paragraphs\ParagraphInterface $paragraphs_entity */
      $paragraphs_entity = $widget_state['paragraphs'][$item['_original_delta']]['entity'];

      /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $display */
      $display = $widget_state['paragraphs'][$item['_original_delta']]['display'];
      if ($widget_state['paragraphs'][$item['_original_delta']]['mode'] == 'edit') {
        $display
          ->extractFormValues($paragraphs_entity, $element[$item['_original_delta']]['subform'], $form_state);
      }

      // A content entity form saves without any rebuild. It needs to set the
      // language to update it in case of language change.
      $langcode_key = $paragraphs_entity
        ->getEntityType()
        ->getKey('langcode');
      if ($paragraphs_entity
        ->get($langcode_key)->value != $form_state
        ->get('langcode')) {

        // If a translation in the given language already exists, switch to
        // that. If there is none yet, update the language.
        if ($paragraphs_entity
          ->hasTranslation($form_state
          ->get('langcode'))) {
          $paragraphs_entity = $paragraphs_entity
            ->getTranslation($form_state
            ->get('langcode'));
        }
        else {
          $paragraphs_entity
            ->set($langcode_key, $form_state
            ->get('langcode'));
        }
      }
      if (isset($item['behavior_plugins'])) {

        // Submit all enabled behavior plugins.
        $paragraphs_type = $paragraphs_entity
          ->getParagraphType();
        foreach ($paragraphs_type
          ->getEnabledBehaviorPlugins() as $plugin_id => $plugin_values) {
          if (!isset($item['behavior_plugins'][$plugin_id])) {
            $item['behavior_plugins'][$plugin_id] = [];
          }
          $original_delta = $item['_original_delta'];
          if (isset($element[$original_delta]) && isset($element[$original_delta]['behavior_plugins'][$plugin_id]) && $form_state
            ->getCompleteForm() && \Drupal::currentUser()
            ->hasPermission('edit behavior plugin settings')) {
            $subform_state = SubformState::createForSubform($element[$original_delta]['behavior_plugins'][$plugin_id], $form_state
              ->getCompleteForm(), $form_state);
            if (isset($item['behavior_plugins'][$plugin_id])) {
              $plugin_values
                ->submitBehaviorForm($paragraphs_entity, $item['behavior_plugins'][$plugin_id], $subform_state);
            }
          }
        }
      }

      // We can only use the entity form display to display validation errors
      // if it is in edit mode.
      if (!$form_state
        ->isValidationComplete() && $widget_state['paragraphs'][$item['_original_delta']]['mode'] === 'edit') {
        $display
          ->validateFormValues($paragraphs_entity, $element[$item['_original_delta']]['subform'], $form_state);
      }
      elseif (!$form_state
        ->isValidationComplete() && $form_state
        ->getLimitValidationErrors() === NULL) {
        $violations = $paragraphs_entity
          ->validate();
        $violations
          ->filterByFieldAccess();
        if (!empty($violations)) {

          /** @var \Symfony\Component\Validator\ConstraintViolationInterface $violation */
          foreach ($violations as $violation) {

            // Ignore text format related validation errors by ignoring
            // the .format property.
            if (substr($violation
              ->getPropertyPath(), -7) === '.format') {
              continue;
            }
            $form_state
              ->setError($element[$item['_original_delta']], $this
              ->t('Validation error on collapsed paragraph @path: @message', [
              '@path' => $violation
                ->getPropertyPath(),
              '@message' => $violation
                ->getMessage(),
            ]));
          }
        }
      }
      $paragraphs_entity
        ->setNeedsSave(TRUE);
      $item['entity'] = $paragraphs_entity;
      $item['target_id'] = $paragraphs_entity
        ->id();
      $item['target_revision_id'] = $paragraphs_entity
        ->getRevisionId();
    }
    elseif (isset($widget_state['paragraphs'][$item['_original_delta']]['mode']) && $widget_state['paragraphs'][$item['_original_delta']]['mode'] == 'remove') {
      $item['target_id'] = NULL;
      $item['target_revision_id'] = NULL;
    }
  }
  return $values;
}