You are here

simplemeta.module in Simple Meta 8.2

Contains simplemeta.module.

File

simplemeta.module
View source
<?php

/**
 * @file
 * Contains simplemeta.module.
 */
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Component\Utility\Html;
use Drupal\simplemeta\Entity\SimplemetaEntity;

/**
 * Implements hook_help().
 */
function simplemeta_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {

    // Main module help for the simplemeta module.
    case 'help.page.simplemeta':
      $output = '';
      $output .= '<h3>' . t('About') . '</h3>';
      $output .= '<p>' . t('SimpleMeta') . '</p>';
      return $output;
    default:
  }
}

/**
 * Implements hook_preprocess_HOOK().
 *
 * Preprocess html.
 */
function simplemeta_preprocess_html(&$vars) {
  if (simplemeta_need_to_inject() && ($entity = simplemeta_get_page_meta()) && ($title = $entity->data->title)) {
    $vars['head_title'] = [
      'title' => Html::escape($title),
    ];
  }
}

/**
 * Implements hook_page_bottom().
 */
function simplemeta_page_bottom(array &$page_bottom) {
  $user = \Drupal::currentUser();
  if (simplemeta_need_to_inject() && $user
    ->hasPermission('administer simplemeta')) {
    if (!($entity = simplemeta_get_page_meta())) {
      $entity = SimplemetaEntity::create();
    }
    $form = \Drupal::service('entity.form_builder')
      ->getForm($entity, 'default');
    if (!empty($form['actions']['delete'])) {
      $current_path = \Drupal::service('path.current')
        ->getPath();
      $query = $form['actions']['delete']['#url']
        ->getOption('query');
      $query['destination'] = $current_path;
      $form['actions']['delete']['#url']
        ->setOption('query', $query);
    }
    $form['#attached']['library'][] = 'simplemeta/simplemeta';
    $page_bottom['simplemeta'] = $form;
  }
}

/**
 * Implements hook_page_attachments().
 */
function simplemeta_page_attachments(array &$attachments) {
  if (simplemeta_need_to_inject() && ($entity = simplemeta_get_page_meta())) {
    foreach ([
      'title',
      'description',
      'keywords',
    ] as $element) {
      if ($entity->data->{$element}) {
        $tag = [
          '#tag' => 'meta',
          '#attributes' => [
            'name' => $element,
            'content' => $entity->data->{$element},
          ],
        ];
        $attachments['#attached']['html_head'][] = [
          $tag,
          $element,
        ];
      }
    }
  }
}

/**
 * Load SimpleMeta entity by path.
 *
 * @param string|array $path
 *   Single path or list of paths.
 * @param string $langcode
 *   Language code.
 *
 * @return \Drupal\Core\Entity\EntityInterface|false
 *   SimpleMeta metadata object or FALSE on failure.
 */
function simplemeta_meta_load_by_path($path, $langcode = NULL) {
  if (!isset($langcode)) {
    $langcode = \Drupal::languageManager()
      ->getCurrentLanguage()
      ->getId();
  }
  $condition = is_array($path) ? 'IN' : '=';
  $query = \Drupal::entityQuery('simplemeta');
  $query
    ->condition('url', $path, $condition);
  $query
    ->condition('langcode', $langcode);
  $query
    ->range(0, 1);
  if ($condition == 'IN') {
    $query
      ->sort('fit', 'DESC');
  }
  $result = $query
    ->execute();
  if (!empty($result)) {
    return SimplemetaEntity::load(reset($result));
  }
  return FALSE;
}

/**
 * Get SimpleMeta entity for a page, by path.
 *
 * @param string $path
 *   Path of the page to get metadata for.
 * @param string $langcode
 *   Language code to get metadata for.
 * @param bool $reset
 *   TRUE to reset static cache.
 *
 * @return \Drupal\simplemeta\Entity\SimplemetaEntity|false
 *   SimpleMeta entity if appropriate found, FALSE otherwise.
 */
function simplemeta_get_page_meta($path = NULL, $langcode = NULL, $reset = FALSE) {
  static $cache = [];
  if (!isset($path)) {
    $path = \Drupal::service('path.current')
      ->getPath();
  }
  if (!isset($cache[$path]) || $reset) {
    $parts = explode('/', $path);
    $ancestors = simplemeta_path_get_ancestors($parts);
    $cache[$path] = simplemeta_meta_load_by_path($ancestors, $langcode);
  }
  return $cache[$path];
}

/**
 * Get path ancestors.
 *
 * Get path ancestors (represented as parts) to find appropriate SimpleMeta
 * entity for the page.
 *
 * @param string[] $parts
 *   An array of path parts; for example,
 *   array('node', '12345', 'edit').
 *
 * @return string[]
 *   List of path ancestors.
 */
function simplemeta_path_get_ancestors(array $parts) {
  $number_parts = count($parts);
  $ancestors = [];
  $length = $number_parts - 1;
  $end = (1 << $number_parts) - 1;

  // Menu_masks actually takes defined menu paths (via hook_menu()
  // implementation) into account.
  $masks = [];

  // If the optimized menu_masks array is not available use brute force to get
  // the correct $ancestors and $placeholders returned. Do not use this as the
  // default value of the menu_masks variable to avoid building such a big
  // array.
  if (!$masks) {
    $masks = range(511, 1);
  }

  // Only examine patterns that actually exist as router items (the masks).
  foreach ($masks as $i) {
    if ($i > $end) {

      // Only look at masks that are not longer than the path of interest.
      continue;
    }
    elseif ($i < 1 << $length) {

      // We have exhausted the masks of a given length, so decrease the length.
      --$length;
    }

    // Path patterns which have less parts than original path must end with %
    // this also includes shorter paths without %.
    if ($length < $number_parts - 1 && $i & 1) {
      continue;
    }
    $current = '';
    for ($j = $length; $j >= 0; $j--) {

      // Check the bit on the $j offset.
      if ($i & 1 << $j) {

        // Bit one means the original value.
        $current .= $parts[$length - $j];
      }
      else {

        // Bit zero means means wildcard.
        $current .= '*';
      }

      // Unless we are at offset 0, add a slash.
      if ($j) {
        $current .= '/';
      }
    }
    $ancestors[] = $current;
  }
  return $ancestors;
}

/**
 * Check if simplemeta needed to inject into current page.
 *
 * @return bool
 *   Needed or not to inject simple meta into the current page.
 */
function simplemeta_need_to_inject() {
  $route = \Drupal::routeMatch()
    ->getRouteObject();
  $isAdmin = \Drupal::service('router.admin_context')
    ->isAdminRoute($route);
  return !$isAdmin;
}

Functions

Namesort descending Description
simplemeta_get_page_meta Get SimpleMeta entity for a page, by path.
simplemeta_help Implements hook_help().
simplemeta_meta_load_by_path Load SimpleMeta entity by path.
simplemeta_need_to_inject Check if simplemeta needed to inject into current page.
simplemeta_page_attachments Implements hook_page_attachments().
simplemeta_page_bottom Implements hook_page_bottom().
simplemeta_path_get_ancestors Get path ancestors.
simplemeta_preprocess_html Implements hook_preprocess_HOOK().