You are here

function optimizely_page_attachments in Optimizely 8.3

Same name and namespace in other branches
  1. 8 optimizely.module \optimizely_page_attachments()
  2. 8.0 optimizely.module \optimizely_page_attachments()

Implements hook_page_attachments().

Checks each page that is about to be rendered as to whether to insert a snippet of Optimizely code or not.

File

./optimizely.module, line 110
Optimizely module.

Code

function optimizely_page_attachments(array &$page) {
  $url = Url::fromRoute('<current>');
  $current_path = $url
    ->getInternalPath();
  $current_path = _check_path($current_path);
  $current_path_alias = _lookup_path_alias($current_path);
  $add_snippet = FALSE;

  // Load all entries in the optimizely table.
  $query = \Drupal::database()
    ->select('optimizely', 'o', [
    'target' => 'slave',
  ])
    ->fields('o')
    ->condition('o.enabled', 1, '=')
    ->orderBy('oid');

  // Fetch the result set.
  $result = $query
    ->execute();
  if (!$result) {
    return;
  }

  // Query results found.
  $cache_tag = NULL;

  // Loop through each row of the found results.
  while ($project = $result
    ->fetchAssoc()) {

    // Only process the entries that are enabled.
    if (!$project['enabled']) {
      continue;
    }

    // Target paths from database for project.
    $project_paths = unserialize($project['path']);

    // Remember to check all paths for alias or sytem URL values.
    foreach ($project_paths as $proj_path) {

      // If the Optimizely snippet is added, use the project's path as one
      // of the cache tags for this page. Cache invalidation is triggered
      // via cache tags when project paths are modified or deleted. Spaces
      // are not allowed in cache_tags, but all other characters seem to be
      // allowed, including *. See class CacheRefresher which does the
      // qinvalidating.
      $cache_tag = 'optimizely:' . $proj_path;

      // Remove parameters, if any.
      if (strpos($proj_path, '?') !== FALSE) {
        $proj_path = substr($proj_path, 0, strpos($proj_path, '?'));
      }

      // Look for sitewide wild card.
      if ($proj_path == '*') {
        $add_snippet = TRUE;
        break 2;
      }

      // Look for wildcard match that is not sitewide.
      if (strpos($proj_path, '*') !== FALSE) {

        // Remove wildcard, get base path(s)
        $proj_path = substr($proj_path, 0, -2);

        // Look for wildcard match.
        if (stripos($current_path, $proj_path) === 0 || stripos(_lookup_path_alias($current_path), $proj_path) === 0 || stripos(_lookup_system_path($current_path), $proj_path) === 0) {
          $add_snippet = TRUE;
          break 2;
        }
      }

      // Build a string containing as many as three possible variants
      // of $proj_path.
      $paths_to_check = $proj_path;
      $proj_path_source = _lookup_system_path($proj_path);
      if ($proj_path_source) {
        $paths_to_check .= "\n" . $proj_path_source;
      }
      $proj_path_alias = _lookup_path_alias($proj_path);
      if ($proj_path_alias) {
        $paths_to_check .= "\n" . $proj_path_alias;
      }

      // See if there is a match against any variant of $proj_path.
      if (\Drupal::service('path.matcher')
        ->matchPath($current_path, $paths_to_check) || \Drupal::service('path.matcher')
        ->matchPath($current_path_alias, $paths_to_check)) {
        $add_snippet = TRUE;
        break 2;
      }
    }

    // foreach
  }
  if ($add_snippet) {

    // Add javascript call to page markup.
    $snippet_url = '//cdn.optimizely.com/js/' . $project['project_code'] . '.js';
    $page['#attached']['html_head'][] = [
      [
        '#tag' => 'script',
        '#attributes' => [
          'type' => 'text/javascript',
          'src' => $snippet_url,
        ],
        '#value' => '',
      ],
      'optimizely-snippet',
    ];
    $page['#cache']['tags'][] = $cache_tag;
  }

  // For every page, add all other cache tags that might possibly cause it
  // to be invalidated.
  // Site-wide wildcard.
  $page['#cache']['tags'][] = 'optimizely:*';

  // Non site-wide wildcards. Repeat for every directory level.
  $dirname = pathinfo($current_path, PATHINFO_DIRNAME);
  while ($dirname && $dirname != '/' && $dirname != '\\') {
    $page['#cache']['tags'][] = 'optimizely:' . $dirname . '/*';
    $dirname = pathinfo($dirname, PATHINFO_DIRNAME);
  }

  // The specific page url.
  $page['#cache']['tags'][] = 'optimizely:' . $current_path;

  // Finally, if there is an alias for the page, tag it.
  if ($current_path_alias) {
    $page['#cache']['tags'][] = 'optimizely:' . $current_path_alias;
  }
}