ajax_dashboard-8.x-2.x-dev/src/AJAXDashboard.php

src/AJAXDashboard.php
<?php

namespace Drupal\ajax_dashboard;

use Drupal\Component\Utility\Html;
use Symfony\Component\Yaml\Yaml;

/**
 * Class AJAXDashboard.
 *
 * @package Drupal\ajax_dashboard
 */
class AJAXDashboard {

  /**
   * @param $dashboard_id
   * @param $dashboard_params
   *
   * @return array
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public static function getDashboardConfig($dashboard_id, $dashboard_params = []) {

    $config_id = 'ajax_dashboard.ajax_dashboard.' . $dashboard_id;
    $config = \Drupal::config($config_id);
    $dashboard_config = $config->getRawData();


    // Create config from underlying YAML if it does not exist as config.
    if (empty($dashboard_config)) {
      $dashboard_manager = \Drupal::service('plugin.manager.ajax_dashboard');
      $dashboards = $dashboard_manager->getDefinitions();
      if (isset($dashboards[$dashboard_id])) {
        $dashboard_config = $dashboards[$dashboard_id];
        // AJAX Dashboard config can go up to 6 levels deep
        // e.g. Views button configs under controls.
        $config = \Drupal\ajax_dashboard\Entity\AJAXDashboard::create([
          'id' => $dashboard_id,
          'status' => TRUE,
          'data' => Yaml::dump($dashboard_config, 6, 2)
        ]);
        $config->save();
      }
    }

    // Override computed config with a module hook
    $dashboard_config['data'] = isset($dashboard_config['data']) && !empty($dashboard_config['data']) ? Yaml::parse($dashboard_config['data']) : [];
    \Drupal::moduleHandler()->alter('ajax_dashboard_config', $dashboard_config, $dashboard_params);

    if (isset($dashboard_config['status']) && !empty($dashboard_config['status'])) {
      return $dashboard_config['data'];
    }

    return [];
  }

  /**
   * Build the AJAX Dashboard.
   *
   * Builds the dashboard from the data specified in a YAML file, and
   * from parameters passed to the theme object.
   *
   * @param array $dashboard
   *   Dashboard data, loaded from a *.ajax_dashboard.yml file.
   * @param array $variables
   *   Theme variables to modify as a part of building the dashboard.
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public static function buildDashboard(array $dashboard, array &$variables) {
    $variables['dashboard']['id'] = $dashboard['id'];
    $variables['dashboard']['label'] = isset($dashboard['label']) ? $dashboard['label'] : '';

    $check_hash = function ($k) {
      return strpos($k, '#') !== FALSE;
    };
    $attributes = array_filter($dashboard, $check_hash, ARRAY_FILTER_USE_KEY);
    foreach ($attributes as $key => $value) {
      if ($key === '#attributes') {
        foreach ($value as $attr_key => $attr) {
          $variables['attributes'][$attr_key] = $attr;
        }
      }
      else {
        $variables[$key] = $value;
      }
    }
    // Add a generic placeholder if a custom one wasn't set.
    if (!isset($variables['attributes']['data-placeholder'])) {
      $variables['attributes']['data-placeholder'] = t('Loading...');
    }
    // For attributes, the dashboard also has the "ajax-dashboard" class.
    $variables['attributes']['class'][] = 'ajax-dashboard';
    // Do not let ID be set as an attribute. Set here.
    $variables['attributes']['id'] = 'ajax-dashboard--' . $dashboard['id'];

    // Build the controls.
    $variables['dashboard']['controls'] = [
      '#type' => 'html_tag',
      '#tag' => 'div',
    ];
    foreach ($dashboard['controls'] as $control_key => $control) {
      // Backwards compatibility: set the default control plugin.
      if (empty($control['plugin'])) {
        $control['plugin'] = 'button_list';
      }
      if (strpos($control_key, '#') === 0) {
        $variables['dashboard']['controls'][$control_key] = $control;
      }
      else {
        $variables['dashboard']['controls'][$control_key] = [
          '#theme' => 'ajax_dashboard_control',
          '#dashboard_id' => $dashboard['id'],
          '#control_id' => $control_key,
          '#control_data' => $control,
          '#params' => $variables['dashboard']['#params'],
          '#weight' => isset($control['weight']) ? $control['weight'] : 0,
        ];
      }
    }
    $variables['dashboard']['controls']['#attributes']['class'][] = 'ajax-dashboard-controls';
    $variables['dashboard']['controls']['#attributes']['id'] = 'ajax-dashboard-controls--' . $dashboard['id'];

    // Pick the active dashboard.
    $dashboard_params = [
      'dashboard' => $dashboard['id'],
      'params' => $variables['dashboard']['#params'],
    ];
    $active_button = self::getActiveButton($dashboard_params);
    if (!empty($active_button)) {
      $variables['dashboard']['display'] = self::displayDashboard($dashboard_params, $active_button);
    }

    $variables['#attached']['library'][] = 'ajax_dashboard/dashboard';
    $variables['#attached']['drupalSettings']['ajax_dashboard']['dashboard_id'] = $dashboard['id'];
  }

  /**
   * Utility function for sorting by weight.
   * @param $a
   * @param $b
   * @return int
   */
  public static function sortByWeight($a = [], $b = []) {
    $wa = isset($a['weight']) ? $a['weight'] : 0;
    $wb = isset($b['weight']) ? $b['weight'] : 0;
    if ($wa == $wb) {
      return 0;
    }
    return ($wa < $wb) ? -1 : 1;
  }

  /**
   * @param array $dashboard_params
   * @return mixed|null
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public static function getActiveButton(array $dashboard_params = []) {
    $active_button = NULL;
    /*
     * Build the list of available buttons.
     */
    if (isset($dashboard_params['dashboard'])) {
      $params = !empty($dashboard_params['params']) ? $dashboard_params['params'] : [];
      $dashboard = self::getDashboardConfig($dashboard_params['dashboard'], $params);
      $control_manager = \Drupal::service('plugin.manager.ajax_dashboard_control');
      $control_definitions = $control_manager->getDefinitions();

      $buttons = [];
      // Get dashboard buttons.
      if (isset($dashboard['controls'])) {
        // Sort the dashboard items.
        $sort_func = AJAXDashboard::class . '::sortByWeight';
        uasort($dashboard['controls'], $sort_func);
        foreach ($dashboard['controls'] as $control_id => $control) {
          $control['id'] = $control_id;
          // If the control plugin isn't specified, use button_list as the assumed default.
          if (empty($control['plugin'])) {
            $control['plugin'] = 'button_list';
          }
          // If the plugin points to a valid control class, get its button data.
          // Then, add the data to the $buttons array.
          if (isset($control_definitions[$control['plugin']]['class'])) {
            $control_buttons = $control_definitions[$control['plugin']]['class']::getButtonData($dashboard_params, $control, $dashboard);
            $buttons = array_merge($buttons, $control_buttons);
          }
        }
      }
      /*
       * If this was called with a query, the exact item will be selected.
       * Otherwise, use the cookie logic.
       * Finally, first valid item.
       */

      // First check if we have at least one button with access enabled.
      if (!empty($buttons)) {
        $active_button = NULL;
        // See if we have params for a clicked button.
        // $dashboard_params['dashboard'] was verified earlier.
        if (isset($dashboard_params['control']) && isset($dashboard_params['button'])) {
          $button_id_array = [
            $dashboard_params['dashboard'],
            $dashboard_params['control'],
            $dashboard_params['button'],
          ];
          $button_id = implode('_', $button_id_array);
          if (isset($buttons[$button_id])) {
            $active_button = $buttons[$button_id];
          }
        }
        // If we hadn't clicked something, check the url for a query parameter.
        if (!$active_button) {
          $query = \Drupal::request()->query;
          if ($query->has('dashboard')) {
            $button_id = $query->get('dashboard');
            if (isset($buttons[$button_id])) {
              $active_button = $buttons[$button_id];
            }
          }
        }
        // Next, see if we have a cookie.
        if (!$active_button) {
          $cookies = \Drupal::request()->cookies;
          if ($cookies->has('ajax_dashboard__' . $dashboard_params['dashboard'])) {
            $button_id = $cookies->get('ajax_dashboard__' . $dashboard_params['dashboard']);
            if (isset($buttons[$button_id])) {
              $active_button = $buttons[$button_id];
            }
          }
        }
        // Finally, just get the first item in the list.
        if (!$active_button) {
          $keys = array_keys($buttons);
          $key = array_shift($keys);
          $active_button = $buttons[$key];
        }
      }
    }
    return $active_button;
  }

  /**
   * Create the dashboard display's render array.
   *
   * This may be called during the AJAX reload, or on initial page load.
   * This function looks for the active button, and runs that button's
   * display logic to create the dashboard.
   *
   * @param array $dashboard_params
   *   Dashboard parameters and data.
   * @param array $active_button
   *   The active dashboard button.
   *
   * @return array
   *   A render array.
   */
  public static function displayDashboard(array $dashboard_params = [], array $active_button = []) {
    $dashboard_params['params'] = isset($dashboard_params['params']) ? $dashboard_params['params'] : [];
    $output = ['#markup' => ''];
    if ($active_button && isset($active_button['class'])) {
      // Build the display.
      $output = $active_button['class']::getButtonDashboardContent($dashboard_params['params'], $active_button['button_data']);
      $dashboard_display_id = Html::escape('ajax-dashboard-display--' . $dashboard_params['dashboard']);
      return [
        '#prefix' => '<div id="' . $dashboard_display_id . '" class="ajax-dashboard-display">',
        'dashboard' => $output,
        '#suffix' => '</div>',
        '#cache' => [
          'max-age' => 0,
        ],
      ];
    }

    return $output;
  }

}

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

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