stacks-8.x-1.x-dev/src/WidgetAdmin/Form/WidgetFormAdmin.php

src/WidgetAdmin/Form/WidgetFormAdmin.php
<?php

namespace Drupal\stacks\WidgetAdmin\Form;


use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Ajax\AlertCommand;
use Drupal\Core\Ajax\RemoveCommand;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\stacks\WidgetAdmin\Manager\StepManager;
use Drupal\stacks\WidgetAdmin\Step\StepsEnum;
use Drupal\inline_entity_form\ElementSubmit;
use Drupal\inline_entity_form\WidgetSubmit;
use Drupal\stacks\Entity\WidgetInstanceEntity;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\stacks\WidgetAdmin\Button\StepCancelButton;
use Drupal\stacks\WidgetAdmin\Validator\ValidatorRequired;

/**
 * Class WidgetForm
 * @package Drupal\stacks\Form\widgetform
 */
class WidgetFormAdmin extends FormBase {

  protected $step_id;
  protected $step;
  protected $stepManager;

  public function __construct() {
    $this->step_id = StepsEnum::STEP_ONE;
    $this->stepManager = new StepManager();
  }

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

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {

    $form['#attached']['library'][] = 'stacks/admin_widget_forms';

    // Get step from step manager.
    $this->step = $this->stepManager->getStep($this->step_id);
    $this->step_id = $this->step->setStep();
    $form['step_id'] = ['#type' => 'hidden', '#value' => $this->step_id];

    $form['wrapper-messages'] = [
      '#type' => 'container',
      '#attributes' => [
        'id' => 'messages-wrapper',
      ],
    ];

    $delta = $_GET['delta'];
    $wrapper = "wrapper-{$delta}";

    $form[$wrapper] = [
      '#type' => 'container',
      '#attributes' => [
        'id' => "form-wrapper-{$delta}",
        'class' => ['form-wrapper'],
      ],
    ];

    if ($this->step_id == 2) {
      ElementSubmit::attach($form, $form_state);
    }

    // Attach step form elements.
    $form[$wrapper] += $this->step->buildStepFormElements();

    // Attach buttons.
    $form[$wrapper]['actions']['#type'] = 'actions';

    $cancelButton = new StepCancelButton();
    $form[$wrapper]['actions'][$cancelButton->getKey()] = $cancelButton->build();

    $buttons = $this->step->getButtons();
    foreach ($buttons as $button) {
      /** @var \Drupal\stacks\WidgetAdmin\Button\ButtonInterface $button */
      $form[$wrapper]['actions'][$button->getKey()] = $button->build();

      if ($button->ajaxify()) {
        // Add ajax to button.
        $form[$wrapper]['actions'][$button->getKey()]['#ajax'] = [
          'callback' => [get_class($this), 'loadStep'],
          'wrapper' => "form-wrapper-{$delta}",
          'effect' => 'fade',
        ];
      }

      $callable = [$this, $button->getSubmitHandler()];
      if ($button->getSubmitHandler() && is_callable($callable)) {
        // attach submit handler to button, so we can execute it later on..
        $form[$wrapper]['actions'][$button->getKey()]['#submit_handler'] = $button->getSubmitHandler();
      }

      if ($button->getKey() == 'finish') {
        // As we are doing our own submission handling, we
        // do what just what we need for IEF to work
        // on our button.
        // @see ElementSubmit::addCallback
        $element =& $form[$wrapper]['actions'][$button->getKey()];
        $element['#ief_submit_trigger']  = TRUE;
        $element['#ief_submit_trigger_all'] = TRUE;
      }
    }

    return $form;
  }

  /**
   * Ajax callback to load new step.
   *
   * @param array $form
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   * @return \Drupal\Core\Ajax\AjaxResponse
   */
  static public function loadStep(array &$form, FormStateInterface $form_state) {

    $response = new AjaxResponse();

    $messenger = \Drupal::messenger();
    $messages = $messenger->all();
    if (!empty($messages)) {
      $messenger->deleteAll();
      // Form did not validate, get messages and render them.
      $messages = [
        '#theme' => 'status_messages',
        '#message_list' => $messages,
        '#status_headings' => [
          'status' => t('Status message'),
          'error' => t('Error message'),
          'warning' => t('Warning message'),
        ],
      ];

      $response->addCommand(new HtmlCommand('#messages-wrapper', $messages));
    }
    else {
      // Remove messages.
      $response->addCommand(new HtmlCommand('#messages-wrapper', ''));
    }

    $delta = $_GET['delta'];

    // Update Form.
    $response->addCommand(new HtmlCommand("#form-wrapper-{$delta}", $form["wrapper-{$delta}"]));

    // Removing step 1 actions
    if ($form['step_id']['#value'] == 2) {
      $response->addCommand(new RemoveCommand('#form-wrapper-'.$delta.' + div[data-drupal-selector="edit-actions"]'));
    }

    return $response;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $triggering_element = $form_state->getTriggeringElement();

    // Only validate if validation doesn't have to be skipped.
    // For example on "previous" button.
    if (empty($triggering_element['#skip_validation']) && $fields_validators = $this->step->getFieldsValidators()) {

      // Validate fields.
      foreach ($fields_validators as $field => $validators) {

        // Validate all validators for this field.
        foreach ($validators as $validator) {

          // Trigger the validate() method on the validation class.
          $validator->setFormState($form_state);
          if (!$validator->validates($form_state->getValue($field))) {
            $form_state->setErrorByName($field, $validator->getErrorMessage());
          }

        } // End $validators foreach loop.

      } // End $fields_validators foreach loop.
    } // End #skip_validation if check.
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    // Set step to navigate to.
    $triggering_element = $form_state->getTriggeringElement();
    $go_to_step = $triggering_element['#goto_step'];
    $values = [];

    // Save the values. Do not save the values if the previous button was clicked.
    // We do this to prevent wiping out the stacks entity from step #2.
    if (!isset($triggering_element['#previous'])) {

      // Save filled out values to step. So we can use them as default_value later on.
      foreach ($this->step->getFieldNames() as $name) {
        $values[$name] = $form_state->getValue($name);
      }

      // If the widget_template value is here, let's process it so we can add the
      // bundle and template values.
      if ($form_state->getValue('widget_template')) {
        $template_info = $this->stepManager->extractBundleFromTemplate($form_state->getValue('widget_template'));
        $values['bundle'] = $template_info['bundle'];
        $values['template'] = $template_info['template'];
      }

      $this->step->setValues($values);
      $this->stepManager->addStep($this->step);
    }

    // If an extra submit handler is set, execute it.
    if (isset($triggering_element['#submit_handler'])){
      $this->{$triggering_element['#submit_handler']}($form, $form_state);
    }

    // Setting reusable field
    if ($form_state->getValue('reusable')) {
      $values['reusable'] = $form_state->getValue('reusable');
    }

    // Set the next step to load.
    $this->step_id = $go_to_step;

    // Rebuild the form with the correct step.
    $form_state->setRebuild(TRUE);
  }

  /**
   * Submit handler for last step of form.
   * @param array $form
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   */
  public function submitValues(array &$form, FormStateInterface $form_state) {
    // Handle Inline Entity Form...create Widget Entity
    ElementSubmit::trigger($form, $form_state);

    $delta = $_GET['delta'];
    $wrapper = "wrapper-{$delta}";
    $widget_entity = $form[$wrapper]['inline_entity_form']['#entity'];

    $widget_id = $widget_entity->id();

    // Get values and extract the template value.
    $steps = $this->stepManager->getAllSteps();
    $step1 = $steps[1];
    $step1_values = $steps[1]->getValues();
    $step2_values = $steps[2]->getValues();
    $template_info = $this->stepManager->extractBundleFromTemplate($step1_values['widget_template']);

    // Mark widget sharing depending on Stacks' configuration
    if ($form_state->getValue('reusable') == 1) {
      $step1_values['reusable'] = 1;
    } else {
      $step1_values['reusable'] = 0;
    }

    if (empty($step1_values['widget_instance_id'])) {
      // Create Widget Instance
      $widget_instance_entity = WidgetInstanceEntity::create([
        'type' => 'widget_instance_entity',
        'title' => $step1_values['widget_name'],
        'template' => $template_info['template'],
        'theme' => $step1_values['widget_theme'],
        'status' => $step1_values['status'],
        'enable_sharing' => $step1_values['reusable'],
        'widget_entity' => $widget_id,
        'wrapper_id' => $step2_values['wrapper_id'],
        'wrapper_classes' => $step2_values['wrapper_classes'],
      ]);
    }
    else {
      // Update Widget Instance
      $widget_instance_entity = WidgetInstanceEntity::load($step1_values['widget_instance_id']);

      // $widget_instance_entity->setTitle($step1_values['widget_name']);
      $widget_instance_entity->setTitle($form_state->getValue('widget_name'));

      $widget_instance_entity->setTemplate($template_info['template']);
      $widget_instance_entity->setTheme($step1_values['widget_theme']);
      $widget_instance_entity->setStatus($step1_values['status']);
      $widget_instance_entity->setWidgetEntityID($widget_id);
      $widget_instance_entity->setWrapperID($step2_values['wrapper_id']);
      $widget_instance_entity->setWrapperClasses($step2_values['wrapper_classes']);

      $widget_instance_entity->setEnableSharing($step1_values['reusable']);
    }

    // Enabling widget instance title replacement in step 2.
    if ($this->step_id != 1) {
      $widget_instance_entity->setTitle($form_state->getValue('widget_name'));
    }

    $widget_instance_entity->save();
    $widget_instance_id = $widget_instance_entity->id();

    // Add widget instance id to the values in step #1.
    $step1_values['widget_instance_id'] = $widget_instance_id;
    $step1->setValues($step1_values);

    // Success message is display in StepFinalize
  }

  /**
   * Submit handler for last step of form with existing widgets
   * @param array $form
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   */
  public function submitValuesExisting(array &$form, FormStateInterface $form_state) {

    $selected_value = $form_state->getValue('existing_stacks_table');
    if($selected_value) {
/*
      $widget_instance_entity = WidgetInstanceEntity::load($selected_value);
      $widget_id = $widget_instance_entity->getWidgetEntityID();
*/
      // Get values and extract the template value.
      $steps = $this->stepManager->getAllSteps();
      $step1 = $steps[1];
      $step1_values = $steps[1]->getValues();
  //    $step2_values = $steps[2]->getValues();
/*
      $step1_values['widget_name'] = $widget_instance_entity->getTitle() . " (Copy)";
      $template_info['template'] = $widget_instance_entity->getTemplate();
      $step1_values['widget_theme'] = $widget_instance_entity->getTheme();
      $step2_values['wrapper_id'] = $widget_instance_entity->getWrapperID();
      $step2_values['wrapper_classes'] = $widget_instance_entity->getWrapperClasses();
*/
      // Add widget instance id to the values in step #1.
      $step1_values['widget_instance_id'] = $selected_value;
      $step1->setValues($step1_values);
    }

  }

}

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

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