plus-8.x-4.x-dev/plus_enhancements/plus_enhancements.module

plus_enhancements/plus_enhancements.module
<?php

/**
 * @file
 * Drupal+ Enhancements module.
 */

// Define specific CSS and JS groups for aggregation purposes.
define('JS_ENHANCEMENT', JS_THEME + 100);
define('CSS_ENHANCEMENT', JS_THEME + 100);

/**
 * Retrieves user enhancement definitions.
 *
 * @param string $id
 *   The machine name identifier of a specific user enhancement to retrieve.
 * @param bool $rebuild
 *   Flag indicating whether to force rebuild the definitions.
 *
 * @return array|null
 *   An associative array of user enhancement definitions, keyed by machine
 *   name. If $id was provided, the user enhancement array definition or NULL
 *   if the user enhancement does not exist.
 */
function plus_enhancements_info($id = NULL, $rebuild = FALSE) {
  static $drupal_static_fast;
  if (!isset($drupal_static_fast)) {
    $drupal_static_fast['info'] = &drupal_static(__FUNCTION__);
  }
  $definitions = &$drupal_static_fast['info'];

  // Build the enhancement definitions from modules.
  if ($rebuild || !isset($definitions)) {
    $definitions = array();
    if (!$rebuild && ($cache = cache_get(__FUNCTION__)) && !empty($cache->data)) {
      $definitions = $cache->data;
    }
    else {
      foreach (module_implements('enhancements_info') as $module) {
        $module_path = drupal_get_path('module', $module);
        foreach (module_invoke($module, 'enhancements_info') as $key => $info) {
          // Ensure the following properties are always set with the correct info.
          $info['id'] = $key;
          $info['module'] = $module;

          // Fill in any defaults that weren't provided.
          $info += array(
            'conditions' => array(),
            'css' => array(),
            'dependencies' => array(),
            'description' => '',
            'enabled' => FALSE,
            'experimental' => FALSE,
            'group' => 'general',
            'js' => array(),
            'path' => "$module_path/enhancements",
            'settings' => array(),
            'title' => $key,
            'ui' => TRUE,
            'version' => NULL,
          );

          // If no assets were explicitly specified, attempt to automatically
          // discover them based on definition identifier, path and asset type.
          foreach (array('css', 'js') as $type) {
            if (empty($info[$type])) {
              $paths = array(
                $info['path'] . "/$key.min.$type",
                $info['path'] . "/$key.$type",
                // Look in specific enhancement directories.
                $info['path'] . "/$key/$key.min.$type",
                $info['path'] . "/$key/$key.$type",
              );
              if ($type === 'js') {
                $paths[] = $info['path'] . "/$key.es6.min.$type";
                $paths[] = $info['path'] . "/$key.es6.$type";
                $paths[] = $info['path'] . "/$key/$key.es6.min.$type";
                $paths[] = $info['path'] . "/$key/$key.es6.$type";
              }
              foreach ($paths as $path) {
                if (file_exists($path)) {
                  $info[$type][$path] = array();
                  break;
                }
              }
            }

            // Set sane defaults.
            foreach ($info[$type] as &$file) {
              if (!isset($file['group'])) {
                $file['group'] = $type === 'css' ? CSS_ENHANCEMENT : JS_ENHANCEMENT;
              }
            }
          }

          // Add the enhancement to the array.
          if (!isset($definitions[$key])) {
            $definitions[$key] = $info;
          }
          // Otherwise, merge in values.
          else {
            $definitions[$key] = drupal_array_merge_deep($definitions[$key], $info);
          }
        }
      }
      drupal_alter('enhancements_info', $definitions);

      // Post process definitions.
      foreach ($definitions as $key => &$info) {
        // Process dependencies and extrapolate shorthand syntax into proper
        // Drupal 7 style library dependencies, e.g. array(module, library).
        $dependencies = array('plus_enhancements/enhancements');
        foreach ($info['dependencies'] as $dependency) {
          // Convert to a sanitized D8 like dependency, e.g. module/library.
          $dependency = (string) (is_array($dependency) ? implode('/', $dependency) : $dependency);

          // Determine module and library identifiers.
          list($module, $name) = explode('/', $dependency . '/');

          // If no library name was given, assume that it is a user enhancement
          // dependency and add it as such.
          if (!empty($module) && empty($name)) {
            $dependencies[] = "plus_enhancements/$module";
          }
          // Handle normal module/library dependencies.
          else {
            if (!empty($module) && !empty($name)) {
              $dependencies[] = "$module/$name";
            }
          }
        }

        // Replace enhancement's dependencies with the sanitized array.
        $info['dependencies'] = array_map(function ($library) {
          list($module, $name) = explode('/', $library);
          return array($module, $name);
        }, array_unique($dependencies));
      }

      // Cache the definitions.
      cache_set(__FUNCTION__, $definitions);
    }
  }

  // Return a specific user enhancement definition.
  if (isset($id)) {
    return isset($definitions[$id]) ? $definitions[$id] : NULL;
  }

  return $definitions;
}

/** @noinspection PhpDocMissingThrowsInspection */

/**
 * Determines whether or not an enhancement has satisfied any conditions.
 *
 * @param array $enhancement
 *   The enhancement definition array.
 *
 * @return bool
 *   TRUE or FALSE
 */
function plus_enhancements_conditions_met(array $enhancement) {
  foreach ($enhancement['conditions'] as $condition) {
    // Entity condition.
    if (isset($condition['entity'])) {
      list($entity_type, $entity_bundle) = explode(':', $condition['entity'] . ':');
      $object = menu_get_object($entity_type);
      if (!$object) {
        return FALSE;
      }
      if (isset($entity_bundle)) {
        /** @noinspection PhpUnhandledExceptionInspection */
        list($id, $vid, $bundle) = entity_extract_ids($entity_type, $object);
        if ($entity_bundle !== $bundle) {
          return FALSE;
        }
      }
    }

    if (isset($condition['path'])) {
      $current_path_alias = drupal_strtolower(drupal_get_path_alias($_GET['q']));
      $paths = implode("\n", (array) $condition['path']);
      $match = drupal_match_path($current_path_alias, $paths);
      if (!$match && $current_path_alias != $_GET['q']) {
        $match = drupal_match_path($_GET['q'], $paths);
      }
      if (!$match) {
        return FALSE;
      }
    }
  }
  return TRUE;
}

/**
 * Implements hook_load().
 *
 * @param string $id
 *   The machine name identifier of a specific user enhancement to retrieve.
 * @param stdClass $account
 *   A user object to use. Defaults to the currently logged in user.
 *
 * @return array|null
 *   The user enhancement array definition or NULL if the user enhancement
 *   does not exist.
 */
function plus_enhancements_load($id, $account = NULL) {
  $user_enhancement = plus_enhancements_load_multiple(array($id), $account);
  return reset($user_enhancement);
}

/**
 * Retrieves the enabled enhancements (for a specific user).
 *
 * @param string[] $ids
 *   An indexed array of machine name identifiers of the specific user
 *   enhancements to retrieve. To return all, leave empty.
 * @param stdClass $account
 *   A user object to use. Defaults to the currently logged in user.
 * @param array $conditions
 *   An array of conditions that match the enhancements.
 *
 * @return array
 *   An array of enabled enhancement definitions, keyed by their machine name.
 *
 * @see plus_enhancements_info()
 */
function plus_enhancements_load_multiple(array $ids = array(), $account = NULL, array $conditions = array()) {
  global $user;

  // Default to current user.
  if (!isset($account)) {
    $account = $user;
  }

  // Get all user enhancements.
  $enhancements = plus_enhancements_info();

  // Merge user enhancements that are valid.
  $user_enhancements = isset($account->data['enhancements']) ? array_filter($account->data['enhancements']) : array();
  foreach ($user_enhancements as $id => $account_enhancement) {
    if (isset($enhancements[$id])) {
      $enhancements[$id] = drupal_array_merge_deep($enhancements[$id], $account_enhancement);
    }
  }

  $loaded = array_filter($enhancements, function ($info) use ($ids, $conditions) {
    // Check if identifiers match.
    if ($ids && !in_array($info['id'], $ids)) {
      return FALSE;
    }

    // Check if conditions match.
    $valid = TRUE;
    if ($conditions) {
      foreach ($conditions as $property => $value) {
        if (!$valid) {
          break;
        }

        // Handle conditions differently.
        if ($property === 'conditions' && ($value === TRUE || $value === FALSE)) {
          if ($value === TRUE) {
            $valid = plus_enhancements_conditions_met($info);
          }
          else {
            if ($value === FALSE) {
              $valid = !plus_enhancements_conditions_met($info);
            }
          }
        }
        // Otherwise, soft check if values match.
        elseif (isset($info[$property]) && $info[$property] != $value) {
          $valid = FALSE;
        }
      }
    }

    // All conditions have been met, keep the user enhancement.
    return $valid;
  });

  return $loaded;
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function plus_enhancements_form_user_profile_form_alter(&$form, &$form_state, $form_id) {
  // Immediately return if not the "enhancements" user profile category.
  if (!isset($form['#user_category']) || $form['#user_category'] !== 'enhancements') {
    return;
  }

  // Retrieve all available enhancements. merging in the user settings and
  // any submitted values from the form.
  $account = isset($form_state['user']) ? $form_state['user'] : NULL;
  $enhancements = drupal_array_merge_deep(plus_enhancements_info(), plus_enhancements_load_multiple(array(), $account), isset($form_state['values']['data']['enhancements']) ? $form_state['values']['data']['enhancements'] : array());

  $form['title'] = array(
    '#theme' => 'html_tag',
    '#tag' => 'h3',
    '#value' => t('User Enhancements'),
    '#weight' => -10,
  );
  $form['description'] = array(
    '#theme' => 'html_tag',
    '#tag' => 'p',
    '#value' => t('Below are a list of user enhancements that can be enabled through out this site.'),
    '#weight' => -9,
  );

  // Save any existing messages.
  $messages = drupal_get_messages();

  // Render the experimental message so the theme properly handles it.
  drupal_set_message('<strong>Experimental</strong> - This user enhancement may change or possibly be removed at a future date.', 'warning');
  $experimental_message = theme('status_messages');

  // Restore the saved messages.
  $_SESSION['messages'] = $messages;

  // Retrieve the user enhancement groups.
  $groups = user_enhancement_groups();

  // If there is more than one group, put them into vertical tabs.
  $vertical_tabs = count($groups) > 1;
  if ($vertical_tabs) {
    $form['vertical_tabs'] = array('#type' => 'vertical_tabs');
  }

  // Add each user enhancement to the form.
  foreach ($enhancements as $id => $enhancement) {
    // If enhancement has opted out of any UI, skip it.
    if (!$enhancement['ui']) {
      continue;
    }

    // Add the user enhancement group.
    $group_id = isset($enhancement['group']) && isset($groups[$enhancement['group']]) ? $enhancement['group'] : 'general';
    if (!isset($form['data']['enhancements'][$group_id])) {
      $form['data']['enhancements'][$group_id] = array(
        '#type' => 'fieldset',
        '#title' => $groups[$group_id]['title'],
        '#group' => 'vertical_tabs',
      );
      if ($vertical_tabs) {
        $form['data']['enhancements'][$group_id]['#group'] = 'vertical_tabs';
      }
      if (isset($groups[$group_id]['description'])) {
        $form['data']['enhancements'][$group_id]['#description'] = $groups[$group_id]['description'];
      }
    }

    // Add the user enhancement.
    $form['data']['enhancements'][$group_id][$id] = array(
      '#type' => 'fieldset',
      '#tree' => TRUE,
      // We need to specify the #parents to remove the group from also being
      // saved in the form state values; just using #tree here doesn't work.
      '#parents' => array('data', 'enhancements', $id),
    );
    $form['data']['enhancements'][$group_id][$id]['enabled'] = array(
      '#type' => 'checkbox',
      '#title' => $enhancement['title'],
      '#default_value' => !empty($enhancement['enabled']) ? 1 : 0,
    );
    if ($enhancement['experimental']) {
      if (!isset($enhancement['description'])) {
        $enhancement['description'] = '';
      }
      $enhancement['description'] .= $experimental_message;
    }
    if (isset($enhancement['description'])) {
      $form['data']['enhancements'][$group_id][$id]['enabled']['#description'] = $enhancement['description'];
    }

    // Provide additional settings for the user enhancement.
    $form['data']['enhancements'][$group_id][$id]['settings'] = array(
      '#type' => 'container',
      '#attributes' => array('class' => array('indented')),
      '#states' => [
        'visible' => array(
          ':input[name="data[enhancements][' . $id . '][enabled]"]' => array('checked' => TRUE),
        ),
      ],
    );

    // Allow module providers to expand the enhancement settings form.
    $settings = module_invoke_all('enhancements_settings_form', $enhancement);

    // Allow modules to alter the settings element.
    drupal_alter('enhancements_settings_form', $settings, $enhancement);

    // Merge in settings.
    if ($settings) {
      $form['data']['enhancements'][$group_id][$id]['settings'] = array_merge($form['data']['enhancements'][$group_id][$id]['settings'], $settings);
    }
    // Otherwise, hide the settings.
    else {
      $form['data']['enhancements'][$group_id][$id]['settings']['#access'] = FALSE;
    }
  }
}

/**
 * Retrieves a specific user enhancement group definition.
 *
 * @param string $id
 *   The machine name identifier of an enhancement.
 * @param bool $rebuild
 *   Toggle indicating whether or not the definitions should be rebuilt.
 *
 * @return array|NULL
 *   The enhancement array definition or NULL if the enhancement does not exist.
 */
function user_enhancement_group($id, $rebuild = FALSE) {
  $enhancements = user_enhancement_groups($rebuild);
  return isset($enhancements[$id]) ? $enhancements[$id] : NULL;
}

/**
 * Retrieves all user enhancement group definitions.
 *
 * @param bool $rebuild
 *   Toggle indicating whether or not the definitions should be rebuilt.
 *
 * @return array
 *   An associative array of enhancement definitions, keyed by machine name.
 */
function user_enhancement_groups($rebuild = FALSE) {
  static $drupal_static_fast;
  if (!isset($drupal_static_fast)) {
    $drupal_static_fast['groups'] = &drupal_static(__FUNCTION__);
  }
  $groups = &$drupal_static_fast['groups'];

  // Build the enhancement definitions from modules.
  if ($rebuild || !isset($groups)) {
    $groups = array('general' => array('title' => t('General')));
    if (!$rebuild && ($cache = cache_get(__FUNCTION__)) && !empty($cache->data)) {
      $groups = $cache->data;
    }
    else {
      foreach (module_implements('enhancements_group_info') as $module) {
        foreach (module_invoke($module, 'enhancements_group_info') as $id => $group) {
          // Ensure the following properties are always set with the correct info.
          $group['id'] = $id;
          $group['module'] = $module;

          // Fill in any defaults that weren't provided.
          $group += array(
            'description' => '',
            'title' => $id,
          );

          // Add the group to the array.
          if (!isset($groups[$id])) {
            $groups[$id] = $group;
          }
          // Otherwise, merge in values.
          else {
            $groups[$id] = drupal_array_merge_deep($groups[$id], $group);
          }
        }
      }
      drupal_alter('enhancements_group_info', $groups);
      cache_set(__FUNCTION__, $groups);
    }
  }

  return $groups;
}

/**
 * Implements hook_hook_info().
 */
function plus_enhancements_hook_info() {
  $info = array('group' => 'enhancements');
  $hooks['enhancements_info'] = $info;
  $hooks['enhancements_info_alter'] = $info;
  $hooks['enhancements_group_info'] = $info;
  $hooks['enhancements_group_info_alter'] = $info;
  $hooks['enhancements_js_settings_alter'] = $info;
  $hooks['enhancements_settings_form'] = $info;
  $hooks['enhancements_settings_form_alter'] = $info;
  return $hooks;
}

/**
 * Implements hook_library().
 */
function plus_enhancements_library() {
  $module_path = drupal_get_path('module', 'plus_enhancements');
  $version = '1.0.0';

  $libraries['enhancement'] = array(
    'title' => 'Drupal+ Enhancement',
    'version' => $version,
    'js' => array(
      "$module_path/js/Drupal.Enhancement.es6.js" => array(
        'es6' => TRUE,
        'group' => JS_ENHANCEMENT,
      ),
    ),
    'dependencies' => array(
      array('system', 'drupal'),
    ),
  );

  $libraries['enhancements'] = array(
    'title' => 'Drupal+ Enhancements',
    'version' => $version,
    'js' => array(
      "$module_path/js/Drupal.Enhancements.es6.js" => array(
        'es6' => TRUE,
        'group' => JS_ENHANCEMENT,
      ),
    ),
    'dependencies' => array(
      array('plus_enhancements', 'enhancement'),
    ),
  );

  // Add each enhancement as a separate library.
  $enhancements = plus_enhancements_info();
  foreach ($enhancements as $id => $enhancement) {
    $libraries[$id] = $enhancement;
  }

  return $libraries;
}

/**
 * Implements hook_page_build().
 */
function plus_enhancements_page_build(&$page) {
  $enhancements = plus_enhancements_load_multiple(array(), NULL, array(
    'conditions' => TRUE,
    'enabled' => TRUE,
    'ui' => TRUE,
  ));

  // Immediately return if there aren't any user enhancements on the page.
  if (!$enhancements) {
    return;
  }

  // Attach the user enhancements to the page.
  $settings = array();
  foreach ($enhancements as $id => $enhancement) {
    drupal_add_library('plus_enhancements', $id);
    $settings['Enhancements'][$id] = $enhancement['settings'];
  }

  // Add the necessary Drupal settings.
  if ($settings) {
    // Allow modules to alter the settings array.
    drupal_alter('enhancements_js_settings', $settings['Enhancements']);
    drupal_add_js($settings, 'setting');
  }
}

/**
 * Implements hook_user_categories().
 */
function plus_enhancements_user_categories() {
  return array(
    'enhancements' => array(
      'name' => 'enhancements',
      'title' => t('Enhancements'),
      'weight' => 30,
    ),
  );
}

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

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