sessionless-1.x-dev/modules/sessionless_forms/src/SessionlessFormHiddenFieldHandler.php

modules/sessionless_forms/src/SessionlessFormHiddenFieldHandler.php
<?php

declare(strict_types=1);
namespace Drupal\sessionless_forms;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Security\TrustedCallbackInterface;
use Drupal\sessionless\SessionlessInterface;

final class SessionlessFormHiddenFieldHandler implements TrustedCallbackInterface {

  public function __construct(
    protected SessionlessInterface $webTokenService
  ) {}

  public function preRender(array $element): array {
    if ($serializedForm = $element['#sessionless_forms__serialized_form']) {
      $element['form'] = [
        '#type' => 'hidden',
        '#name' => 'sessionless_forms__form',
        '#value' => $this->webTokenService->encode($serializedForm),
      ];
    }
    if ($serializedFormState = $element['#sessionless_forms__serialized_form_state']) {
      $element['form_state'] = [
        '#type' => 'hidden',
        '#name' => 'sessionless_forms__form_state',
        '#value' => $this->webTokenService->encode($serializedFormState),
      ];
    }
    return $element;
  }

  public static function hookFormAlter(array &$form, FormStateInterface $form_state, $form_id) {
    // Add the lazy builder for our hidden fields.
    $form['sessionless_forms'] = [
      '#cache' => ['max-age' => 0],
      '#pre_render' => [
        'sessionless_forms.hidden_field_handler:preRender',
      ],
      '#sessionless_forms__serialized_form' => NULL,
      '#sessionless_forms__serialized_form_state' => NULL,
    ];
    // Store a ref to an alterable form.
    // Sorry kittens, this seems the only way to get that currently.
    $storage =& $form_state->getStorage();
    $storage['sessionless__alterable_form'] =& $form;
    $form_state->setStorage($storage);
  }

  public function resetValues(array &$form) {
    $form['sessionless_forms']['#sessionless_forms__serialized_form'] = NULL;
    $form['sessionless_forms']['#sessionless_forms__serialized_form_state'] = NULL;
  }

  public function setForm(FormStateInterface $formState, $form) {
    $alterableForm =& $formState->get('sessionless__alterable_form');
    if (!is_array($alterableForm)) {
      throw new \UnexpectedValueException('CompleteForm must be set here.');
    }

    $copiedForm = $form;
    $this->resetValues($copiedForm);
    $serialized = serialize($copiedForm);
    $alterableForm['sessionless_forms']['#sessionless_forms__serialized_form'] = $serialized;
  }

  public function setFormState(FormStateInterface $formState) {
    $alterableForm =& $formState->get('sessionless__alterable_form');
    if (!is_array($alterableForm)) {
      throw new \UnexpectedValueException('CompleteForm must be set here.');
    }

    $cacheableArray = $formState->getCacheableArray();
    unset($cacheableArray['storage']['sessionless__alterable_form']);
    $serialized = serialize($cacheableArray);
    $alterableForm['sessionless_forms']['#sessionless_forms__serialized_form_state'] = $serialized;
  }

  public function getForm(array $userInput): ?array {
    $webToken = $userInput['sessionless_forms__form'] ?? NULL;
    if ($webToken) {
      $serialized = $this->webTokenService->decode($webToken);
      // Unserializing is safe here, as the value is generated in a trusted way,
      // then signed and encrypted.
      return unserialize($serialized);
    }
    return NULL;
  }

  public function getFormStateArray(array $userInput): ?array {
    $webToken = $userInput['sessionless_forms__form_state'] ?? NULL;
    if ($webToken) {
      $serialized = $this->webTokenService->decode($webToken);
      // Unserializing is safe here, as the value is generated in a trusted way,
      // then signed and encrypted.
      return unserialize($serialized);
    }
    return NULL;
  }

  public static function trustedCallbacks() {
    return ['preRender'];
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc