stacks-8.x-1.x-dev/src/Widget/WidgetRequiredFields.php

src/Widget/WidgetRequiredFields.php
<?php

namespace Drupal\stacks\Widget;

use Drupal\Core;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\stacks\Entity\WidgetInstanceEntity;
use Drupal\stacks\Entity\WidgetEntity;
use Drupal\stacks\Widget;

/**
 * Class WidgetFieldHandlers.
 *
 * Used to attach required fields. See hook_node_presave() implementation.
 */
class WidgetRequiredFields {

  // The type of node this widget field is on.
  private $node_type = '';
  // The name of the widget field on this node.
  private $field_name = '';
  // These are the form settings for the widget field.
  private $settings_required = [];
  private $settings_required_loc_optional = [];

  // Did this get changed? If so we need to save the node.
  private $changed = FALSE;

  public function __construct(&$node) {
    $this->initiate($node);
  }

  /**
   * Send a $node object, it will determine if there are any widget fields on this
   * node and auto add any required stacks to the top.
   */
  private function initiate(&$node) {
    // Reverse the order of the fields, since our field will be towards the bottom.
    // if it is there.
    $fields = array_reverse($node->getFields());

    // Loop through all fields and see if there are any widget fields.
    foreach ($fields as $field) {
      if ($field->getFieldDefinition()->getType() == 'stacks_type') {
        // Add any necessary required fields.
        $this->defineSettings($node, $field);
        $this->handleRequiredFieldsOnNode($node);
      }
    }
  }

  /**
   * Grabs the settings for the required widget bundles for a certain field on
   * a certain content type.
   *
   * @param $node
   * @param $field Make sure to only send widget fields.
   */
  private function defineSettings($node, $field) {
    $this->node_type = $node->getType();
    $this->field_name = $field->getFieldDefinition()->getName();

    $bundle_settings = EntityFormDisplay::load('node.' . $this->node_type . '.default')
      ->getComponent($this->field_name)['settings'];
    $this->settings_required = (isset($bundle_settings['bundles_required_pos_locked']) ? $bundle_settings['bundles_required_pos_locked'] : []);
    $this->settings_required_loc_optional = (isset($bundle_settings['bundles_required_pos_optional']) ? $bundle_settings['bundles_required_pos_optional'] : []);
  }

  /**
   * Grabs the items for this widget field from the node.
   *
   * @param $node
   */
  private function handleRequiredFieldsOnNode(&$node) {

    if (empty($this->field_name)) {
      return;
    }

    // If the $_POST variable for this field exists, and if the node id doesn't
    // exist, we know this is a duplicate call for a new node and we use those
    // values.
    if (is_null($node->id()) && isset($_POST[$this->field_name])) {
      $node->get($this->field_name)->setValue($_POST[$this->field_name]);
      return;
    }

    $list = $node->get($this->field_name)->getValue();

    $required_on_node = [];
    foreach ($list as $item) {
      $widget_instance_id = isset($item['widget_instance_id']) ? $item['widget_instance_id'] : FALSE;
      if ($widget_instance_id) {

        // Widget instance exists.
        $widget_instance = WidgetInstanceEntity::load($widget_instance_id);
        if ($widget_instance->getIsRequired()) {

          // This is a required widget instance on this node.
          // Add it to the array.
          $required_type = $widget_instance->getRequiredType();
          $required_bundle = $widget_instance->getRequiredBundle();
          $required_on_node[$required_type][$required_bundle] = $widget_instance_id;

        }

      }
    }

    // Add any required stacks to the list. Handle both types of required
    // widgets.
    $this->addRequiredFields($node, 'open', $required_on_node);
    $this->addRequiredFields($node, 'locked', $required_on_node);
  }

  /**
   * This is where we add the required widgest on the node that are not there.
   *
   * @param $node
   * @param $required_on_node
   */
  private function addRequiredFields(&$node, $required_type, $required_on_node) {
    // Grab the latest items. We need to do this because this can change each
    // time this method is called!
    $list = $node->get($this->field_name)->getValue();

    $settings = $this->settings_required;
    if ($required_type == 'open') {
      $settings = $this->settings_required_loc_optional;
    }

    // Now compare the required stacks with the data they have on this node.
    // If a required widget needs to be added, add it to the beginning of
    // the list.
    $changed = FALSE;
    foreach ($settings as $required_bundle) {
      if (!empty($required_bundle) && !isset($required_on_node[$required_type][$required_bundle])) {
        // They do not have this required widget on the node. We need to add it.
        // Create Required Widget entity.
        $widget_entity = WidgetEntity::create([
          'type' => $required_bundle,
        ]);

        $widget_entity->save();

        // Create Required Widget Instance.
        $widget_instance_entity = WidgetInstanceEntity::create([
          'type' => 'widget_instance_entity',
          'title' => $required_bundle . ': ' . t('Required Type') . ' (' . $required_type . ')',
          'enable_sharing' => FALSE,
          'widget_entity' => $widget_entity->id(),
          'required' => TRUE,
          'required_type' => $required_type,
          'required_bundle' => $required_bundle,
        ]);

        $widget_instance_entity->save();

        // Add the item to the beginning of the list.
        $add_required_bundle = [
          'widget_instance_id' => $widget_instance_entity->id(),
          'required' => TRUE,
          'required_type' => $required_type,
          'required_bundle' => $required_bundle,
        ];

        array_unshift($list, $add_required_bundle);
        $changed = TRUE;
      }
    }

    // If the list has changed, make sure to update the value.
    if ($changed) {
      $node->get($this->field_name)->setValue($list);
    }
  }

}

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

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