You are here

public function WebformEntityHandler::postSave in Webform Entity Handler 2.x

Same name and namespace in other branches
  1. 8 src/Plugin/WebformHandler/WebformEntityHandler.php \Drupal\webform_entity_handler\Plugin\WebformHandler\WebformEntityHandler::postSave()

Acts on a saved webform submission before the insert or update hook is invoked.

Parameters

\Drupal\webform\WebformSubmissionInterface $webform_submission: A webform submission.

bool $update: TRUE if the entity has been updated, or FALSE if it has been inserted.

Overrides WebformHandlerBase::postSave

File

src/Plugin/WebformHandler/WebformEntityHandler.php, line 297

Class

WebformEntityHandler
Create or update an entity with a webform submission values.

Namespace

Drupal\webform_entity_handler\Plugin\WebformHandler

Code

public function postSave(WebformSubmissionInterface $webform_submission, $update = TRUE) {
  $state = $webform_submission
    ->getWebform()
    ->getSetting('results_disabled') ? WebformSubmissionInterface::STATE_COMPLETED : $webform_submission
    ->getState();
  if (in_array($state, $this->configuration['states'])) {

    // Get the handler configuration and replace the values of the mapped
    // elements.
    $data = $this->configuration['entity_values'];
    $submission_data = $webform_submission
      ->getData();
    array_walk_recursive($data, function (&$value) use ($webform_submission, $submission_data) {
      if (strpos($value, 'input:') !== FALSE) {
        [
          ,
          $element_key,
        ] = explode(':', $value);
        $element_key = explode('|', $element_key);
        $value = NestedArray::getValue($submission_data, $element_key);
      }
      elseif ($value === '_null_') {
        $value = NULL;
      }
      $value = $this->tokenManager
        ->replace($value, $webform_submission, [], [
        'clear' => TRUE,
      ]);
    });
    [
      $type,
      $bundle,
    ] = explode(':', $this->configuration['entity_type_id']);

    // Add the bundle value if the entity has one.
    if ($this->entityTypeManager
      ->getDefinition($type)
      ->hasKey('bundle')) {
      $data[$this->entityTypeManager
        ->getDefinition($type)
        ->getKey('bundle')] = $bundle;
    }
    try {
      $entity_id = FALSE;
      if ($this->configuration['operation'] != self::DEFAULT_VALUE) {
        if (strpos($this->configuration['operation'], 'input:') !== FALSE) {
          [
            ,
            $element_key,
          ] = explode(':', $this->configuration['operation']);
          $element_key = explode('|', $element_key);
          $entity_id = NestedArray::getValue($submission_data, $element_key);
        }
        else {
          $entity_id = $this->configuration['operation'];
        }
        $entity_id = $this->webformTokenManager
          ->replace($entity_id, $webform_submission);
      }
      if (!empty($entity_id)) {

        // Load the entity and update the values.
        if (($entity = $this->entityTypeManager
          ->getStorage($type)
          ->load($entity_id)) !== NULL) {

          // If the new values change the bundle we need to remove it first.
          if ($this->entityTypeManager
            ->getDefinition($type)
            ->hasKey('bundle') && $bundle != $entity
            ->bundle()) {

            /** @var \Drupal\Core\Entity\EntityInterface $previous_entity */
            $previous_entity = clone $entity;
            $entity
              ->delete();
            unset($entity);

            // If the previous entity has the field of the current one,
            // it has value, and in the submission there is no value,
            // we recover it.
            foreach (array_keys($data) as $field_name) {
              if (empty($data[$field_name]) && $previous_entity
                ->hasField($field_name) && !$previous_entity
                ->get($field_name)
                ->isEmpty()) {
                $data[$field_name] = $previous_entity
                  ->get($field_name)
                  ->getValue();
              }
            }

            // Ensure the entity preserve its ID.
            $data['id'] = $previous_entity
              ->id();
            $data['uuid'] = $previous_entity
              ->uuid();
          }
          else {
            foreach ($data as $field => $value) {
              $append = !empty($value['webform_entity_handler_append']);
              if (isset($value['webform_entity_handler_append'])) {
                unset($value['webform_entity_handler_append']);
              }
              if ($append && !$entity
                ->get($field)
                ->isEmpty()) {
                $entity
                  ->get($field)
                  ->appendItem($value);
              }
              else {
                $entity
                  ->set($field, $value);
              }
            }
          }
        }
      }
      if (empty($entity)) {

        // Create the entity with the values.
        $entity = $this->entityTypeManager
          ->getStorage($type)
          ->create($data);
      }
      if ($this->entityTypeManager
        ->getDefinition($type)
        ->isRevisionable()) {
        $entity
          ->setNewRevision($this->configuration['entity_revision']);
      }
      if ($entity
        ->save() == SAVED_NEW) {
        $message = '@type %title has been created.';
      }
      else {
        $message = '@type %title has been updated.';
      }
      $context = [
        '@type' => $entity
          ->getEntityType()
          ->getLabel(),
        '%title' => $entity
          ->label(),
      ];
      if ($entity
        ->hasLinkTemplate('canonical')) {
        $context += [
          'link' => $entity
            ->toLink($this
            ->t('View'))
            ->toString(),
        ];
      }
      if ($webform_submission
        ->getWebform()
        ->hasSubmissionLog()) {

        // Log detailed message to the 'webform_submission' log.
        $context += [
          'link' => $webform_submission
            ->id() ? $webform_submission
            ->toLink($this
            ->t('View'))
            ->toString() : NULL,
          'webform_submission' => $webform_submission,
          'handler_id' => $this
            ->getHandlerId(),
          'operation' => 'sent email',
        ];
        $this
          ->getLogger('webform_submission')
          ->notice($message, $context);
      }
      else {

        // Log general message to the 'webform_entity_handler' log.
        $context += [
          'link' => $this
            ->getWebform()
            ->toLink($this
            ->t('Edit'), 'handlers')
            ->toString(),
        ];
        $this
          ->getLogger('webform_entity_handler')
          ->notice($message, $context);
      }

      // Update the entity ID.
      if ($entity && $this->configuration['operation'] != self::DEFAULT_VALUE && strpos($this->configuration['operation'], 'input:') !== FALSE) {
        [
          ,
          $element_key,
        ] = explode(':', $this->configuration['operation']);
        $element_key = explode('|', $element_key);
        $webform_submission
          ->setElementData(end($element_key), $entity
          ->id());
        $webform_submission
          ->resave();
      }
    } catch (\Exception $exception) {
      watchdog_exception('webform_entity_handler', $exception);
      $this
        ->messenger()
        ->addError($this
        ->t('There was a problem processing your request. Please, try again.'));
    }
  }
}