Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
novicell/custom_forms / src / Form / CustomFormItemSettingsForm.php
Size: Mime:
<?php

namespace Drupal\custom_forms\Form;

use Drupal\Component\Datetime\Time;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CloseDialogCommand;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Entity\EntityStorageException;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element\StatusMessages;
use Drupal\custom_forms\CustomFormItem;
use Drupal\custom_forms\CustomFormItemFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * Class CustomFormItemSettingsForm
 *
 * The settings form for each custom form item (fields and groups).
 *
 * @package Drupal\custom_forms\Form
 */
class CustomFormItemSettingsForm extends CustomFormItemFormBase {

  /**
   * The factory in charge of CRUD operations for custom form items.
   *
   * @var \Drupal\custom_forms\CustomFormItemFactory
   */
  protected $itemFactory;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('custom_forms.factory.item')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function __construct(CustomFormItemFactory $item_factory) {
    $this->itemFactory = $item_factory;
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'custom_form_item_settings_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form         = parent::buildForm($form, $form_state);
    $request      = \Drupal::request();
    $attributes   = $request->attributes;
    $customForm   = $attributes->get('custom_form');
    $formItem     = $this->itemFactory->loadItem($attributes->get('item'));

    $form['custom_form'] = [
      '#type' => 'value',
      '#value' => $customForm,
    ];
    $form['item'] = [
      '#type' => 'value',
      '#value' => $formItem,
    ];

    /** @var \Drupal\custom_forms\Plugin\CustomForms\FieldType\CustomFormsFieldTypeInterface $plugin */
    $plugin = $formItem->getPlugin();
    $plugin->buildSettingsForm($formItem, $form, $form_state);

    if ($formItem->getType() === 'field') {
      $mapping_plugins = $this->itemFactory->getCompatibleMappings($customForm, $formItem->getPluginId());
      $mapping_options = [];

      // Generate the options array.
      foreach ($mapping_plugins as $mapping_id => $mapping_definition) {
        $mapping_options[$mapping_id] = $mapping_definition['label'];
      }
      $form['mapping'] = [
        '#type' => 'select',
        '#title' => $this->t('Mapping'),
        '#description' => $this->t('Select the mapping to use.'),
        '#required' => TRUE,
        '#empty_option' => '- ' . $this->t('Choose mapping') . ' -',
        '#default_value' => $formItem->getMappingId(),
        '#weight' => -99,
        '#options' => $mapping_options,
      ];
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $values = $form_state->cleanValues()->getValues();
    $trigger = $form_state->getTriggeringElement();
    $request = \Drupal::request();

    if ($trigger['#op'] === 'cancel' || $request->isXmlHttpRequest()) {
      return;
    }

    $attributes = $request->attributes;
    /** @var \Drupal\custom_forms\Entity\CustomForm $custom_form */
    $custom_form = $attributes->get('custom_form');
    /** @var \Drupal\custom_forms\CustomFormItem $item */
    $item = $this->itemFactory->loadItem($attributes->get('item'));

    /** @var \Drupal\custom_forms\Plugin\CustomForms\FieldType\CustomFormsFieldTypeInterface $plugin */
    $plugin = $item->getPlugin();
    $plugin->submitSettingsForm($item, $form, $form_state);
    $values = $form_state->cleanValues()->getValues();

    // Create a new custom form revision since we are modifying it by
    // removing a field.
    $revision_saved = FALSE;
    $custom_form->setNewRevision(TRUE);
    // For some reason required for log messages to show up.
    $custom_form->setRevisionTranslationAffected(TRUE);
    $custom_form->setRevisionLogMessage(
      $this->t('Updated settings for @field-label', [
        '@field-label' => $item->getSetting('label'),
      ]));
    $custom_form->setRevisionCreationTime(\Drupal::time()->getRequestTime());
    $custom_form->setRevisionUserId(\Drupal::currentUser()->id());
    try {
      $custom_form->save();
      $revision_saved = TRUE;
    }
    catch (EntityStorageException $e) {
      $error_message = $this->t('Failed during creation of new revision. Message = %message', [
        '%message' => $e->getMessage(),
      ]);
      \Drupal::logger('Custom Forms')->error($error_message);
      $this->messenger()->addError($this->t('Failed during creation of new revision, please try again. If it continues please contact an administrator.'));
    }

    if ($revision_saved) {
      $new_item = $this->itemFactory->loadItem($item->id(), NULL, $custom_form->getLoadedRevisionId());
      $this->setItemValues($new_item, $values);

      try {
        // We save it without creating a new revision, as that has already
        // been done at this point.
        $new_item->save(FALSE);

        $form_state->setRedirect('entity.custom_form.fields_form', ['custom_form' => $custom_form->id()]);
        $this->messenger()->addMessage($this->t('%item-label was successfully saved.', ['%item-label' => $item->getSetting('label')]));
      }
      catch (\Exception $e) {
        $error_message = $this->t('Field saving failed. Message = %message. Trace = @trace', [
          '%message' => $e->getMessage(),
          '@trace' => $e->getTraceAsString(),
        ]);
        \Drupal::logger('Custom Forms')->error($error_message);
        $this->messenger()->addError($this->t('Failed during saving of field, please try again. If it continues please contact an administrator.'));
      }
    }
  }

  /**
   * Submit the form through ajax.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request that is calling this function.
   *
   * @return \Drupal\Core\Ajax\AjaxResponse
   *   Returns an AjaxResponse for usage within Drupal's ajax system.
   * @throws \Drupal\Component\Plugin\Exception\PluginException
   */
  public function ajaxSubmitForm(array &$form, FormStateInterface $form_state, Request $request) {
    $response = new AjaxResponse();
    $values = $form_state->cleanValues()->getValues();
    $settings_config = \Drupal::config('custom_forms.settings');

    $attributes = $request->attributes;
    /** @var \Drupal\custom_forms\Entity\CustomForm $custom_form */
    $custom_form = $attributes->get('custom_form');
    /** @var \Drupal\custom_forms\CustomFormItem $item */
    $item = $this->itemFactory->loadItem($attributes->get('item'));

    /** @var \Drupal\custom_forms\Plugin\CustomForms\FieldType\CustomFormsFieldTypeInterface $plugin */
    $plugin = $item->getPlugin();
    $plugin->submitSettingsForm($item, $form, $form_state);
    $values = $form_state->cleanValues()->getValues();

    // Create a new custom form revision since we are modifying it by
    // removing a field.
    $revision_saved = FALSE;
    $custom_form->setNewRevision(TRUE);
    // For some reason required for log messages to show up.
    $custom_form->setRevisionTranslationAffected(TRUE);
    $custom_form->setRevisionLogMessage(
      $this->t('Updated settings for @field-label', [
        '@field-label' => $item->getSetting('label'),
      ]));
    $custom_form->setRevisionCreationTime(\Drupal::time()->getRequestTime());
    $custom_form->setRevisionUserId(\Drupal::currentUser()->id());
    try {
      $custom_form->save();
      $revision_saved = TRUE;
    }
    catch (EntityStorageException $e) {
      $error_message = $this->t('Failed during creation of new revision. Message = %message. Trace = @trace', [
        '%message' => $e->getMessage(),
        '@trace' => $e->getTraceAsString(),
      ]);
      \Drupal::logger('Custom Forms')->error($error_message);
      $this->messenger()->addError($this->t('Failed during creation of new revision, please try again. If it continues please contact an administrator.'));
    }

    if ($revision_saved) {
      $new_item = $this->itemFactory->loadItem($item->id(), NULL, $custom_form->getLoadedRevisionId(), $custom_form->language()->getId());
      $this->setItemValues($new_item, $values);

      try {
        // We save it without creating a new revision, as that has already
        // been done at this point.
        $new_item->save(FALSE);
        $response->addCommand(new CloseDialogCommand('#drupal-off-canvas'));
        $this->messenger()->addMessage($this->t('%item-label was successfully saved.', ['%item-label' => $item->getSetting('label')]));

        switch ($settings_config->get('off_screen_field_settings')) {
          case 'rebuild':
            $form = \Drupal::formBuilder()->getForm(CustomFormFieldListForm::class);
            $response->addCommand(new ReplaceCommand('#custom-form__field-list', $form));

            // Get the messages for display.
            $messages = StatusMessages::renderMessages();
            // Remove the current messages to avoid showing any sticky
            // messages double.
            $response->addCommand(new InvokeCommand('div.region.region-highlighted div.messages', 'remove'));
            // Append the new messages to the highlighted region.
            $response->addCommand(new InvokeCommand('div.region.region-highlighted', 'append', [render($messages)]));
            break;
          case 'reload':
          default:
            $response->addCommand(new InvokeCommand('form.custom-forms-fields input.form-submit[type="submit"][name="op"]', 'click', []));
            break;
        }

      }
      catch (\Exception $e) {
        $error_message = $this->t('Field saving failed. Message = %message. Trace = @trace', [
          '%message' => $e->getMessage(),
          '@trace' => $e->getTraceAsString(),
        ]);
        \Drupal::logger('Custom Forms')->error($error_message);
        $this->messenger()->addError($this->t('Failed during saving of field, please try again. If it continues please contact an administrator.'));
      }
    }

    return $response;
  }

  /**
   * Save values to the custom forms item.
   *
   * @param \Drupal\custom_forms\CustomFormItem $item
   *   The item to save the values to.
   * @param array $values
   *   The array of values to save.
   */
  private function setItemValues(CustomFormItem $item, &$values) {
    // Unset the form and field values as they should not get saved to settings.
    unset($values['custom_form'], $values['item']);

    // Add machine name to settings so it can be used by plugin.
    $values['machine_name'] = $item->getMachineName();
    $mapping_id = $values['mapping'];
    unset($values['mapping']);

    /** @var Time $time */
    $time = \Drupal::service('datetime.time');
    $timestamp = $time->getCurrentTime();

    $item->setChanged($timestamp);
    $item->setSettings($values);
    $item->setMappingId($mapping_id);
  }
}