visualn-8.x-1.x-dev/src/Plugin/VisualN/ResourceProvider/DrawerPreviewResourceProvider.php

src/Plugin/VisualN/ResourceProvider/DrawerPreviewResourceProvider.php
<?php

// @todo: mostly it is the same as Generated Data standard resource provider
//    but also has a drawer context that allows to autodetect corresponding data generator
//    and additional controls, e.g. to reset to default or show/hide relevant
//    data generators

// @todo: rename to "Compatible generator data (for drawer preview)"

namespace Drupal\visualn\Plugin\VisualN\ResourceProvider;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Component\Utility\NestedArray;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\Render\Element;

/**
 * Provides a 'Drawer Preview Resource Provider' VisualN resource provider.
 *
 * @VisualNResourceProvider(
 *  id = "visualn_drawer_preview",
 *  label = @Translation("Drawer Preview Resource Provider"),
 *  context = {
 *    "visualn_drawer_id" = @ContextDefinition("string", label = @Translation("VisualN Drawer Id"), required = TRUE)
 *  }
 * )
 */
class DrawerPreviewResourceProvider extends GeneratedResourceProvider {

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);


    // @todo: get from context
    $base_drawer_id = $this->getContextValue('visualn_drawer_id');
    $compatible_dgs = [];
    $dg_definitions = $this->visualNDataGeneratorManager->getDefinitions();
    foreach ($dg_definitions as $id => $dg_definition) {
      if (!empty($dg_definition['compatible_drawers'])) {
        // @todo: is it any drawer or just base drawers?
        foreach ($dg_definition['compatible_drawers'] as $drawer_id) {
          $compatible_dgs[$drawer_id][] = $id;
        }
      }
    }

    // @todo: or other drawers could also provide info (using some hook)
    //   about "compatible drawers" which can share generator providers
    //   with them

    $default_data_generator_id = '';

    // keep compatible generators for ::preRenderShowCompatible() callback
    $form['#compatible_dgs'] = [];
    if (!empty($compatible_dgs[$base_drawer_id])) {
      $default_data_generator_id = reset($compatible_dgs[$base_drawer_id]);
      $form['data_generator_id']['#default_value'] = $default_data_generator_id;
      $form['#compatible_dgs'] = $compatible_dgs[$base_drawer_id];
    }
    else {
      // @todo: add message 'No compatible Data generators found'
    }


    // @todo: may context be also used with subdrawers but not only base drawers?

    // @todo: add context of the current drawer used


    // limit list to only compatible data generators, add ajax action to the checkbox
    $ajax_wrapper_id = implode('-', array_merge($form['#array_parents'], ['show_compatible'])) .'-ajax-wrapper';

    // avoid overriding prefix and suffix if already set somewhere else
    $form['#prefix'] = isset($form['#prefix']) ? $form['#prefix'] : '';
    $form['#suffix'] = isset($form['#suffix']) ? $form['#suffix'] : '';
    $form['#prefix'] = '<div id="' . $ajax_wrapper_id . '">' . $form['#prefix'];
    $form['#suffix'] = $form['#suffix'] . '</div>';
    $form['show_compatible'] = [
      '#type' => 'checkbox',
      '#title' => t('Show only compatible generators'),
      '#default_value' => !empty($default_data_generator_id),
      '#ajax' =>  [
        'callback' => [get_called_class(), 'ajaxCallbackShowCompatible'],
        'wrapper' => $ajax_wrapper_id,
      ],
      '#weight' => -50,
    ];
    $form['#pre_render'][] = static::class . '::preRenderShowCompatible';

/*
    $form['reset'] = [
      '#type' => 'submit',
      '#value' => t('Reset'),
      //'#weight' => -50,
    ];
*/

    return $form;
  }

  /**
   * Return data generator configuration form via ajax request at "show compatible" option change.
   */
  public static function ajaxCallbackShowCompatible(array $form, FormStateInterface $form_state, Request $request) {
    $triggering_element = $form_state->getTriggeringElement();
    $visualn_style_id = $form_state->getValue($form_state->getTriggeringElement()['#parents']);
    $triggering_element_parents = array_slice($triggering_element['#array_parents'], 0, -1);
    $element = NestedArray::getValue($form, $triggering_element_parents);

    return $element;
  }

  /**
   * Hide incompatible drawer generators.
   */
  public static function preRenderShowCompatible($build) {

    $selected_generator_id = $build['data_generator_id']['#value'];
    if ($build['show_compatible']['#value']) {
      $visible_dgs = $build['#compatible_dgs'];
      if (!empty($selected_generator_id) && !in_array($selected_generator_id, $visible_dgs)) {
        $visible_dgs[] = $selected_generator_id;
      }

      foreach ($build['data_generator_id']['#options'] as $k => $options) {
        if ($k != '' && !in_array($k, $visible_dgs)) {
          unset($build['data_generator_id']['#options'][$k]);
        }
      }
    }

    // @todo: or should be done in ajaxCallbackShowCompatible() ?
    // open generator config by default when changin "show compatible" option
    if (!empty($selected_generator_id)) {
      $build['generator_container'][$selected_generator_id]['#open'] = TRUE;
    }

    return $build;
  }

}

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

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