You are here

google_tag.install in GoogleTagManager 7.2

Same filename and directory in other branches
  1. 8 google_tag.install
  2. 7 google_tag.install

Provides install, update, and uninstall functions.

@author Jim Berry ("solotandem", http://drupal.org/user/240748)

File

google_tag.install
View source
<?php

/**
 * @file
 * Provides install, update, and uninstall functions.
 *
 * @author Jim Berry ("solotandem", http://drupal.org/user/240748)
 */

/**
 * Implements hook_enable().
 */
function google_tag_enable() {
  global $_google_tag_display_message;
  $_google_tag_display_message = TRUE;
  google_tag_settings_create();
  google_tag_assets_create();
}

/**
 * Implements hook_uninstall().
 */
function google_tag_uninstall() {

  /*
    // Does not apply to 2.x branch; move to hook_update_N.
    db_delete('variable')
      ->condition('name', db_like('google_tag_') . '%', 'LIKE')
      ->execute();

    if (module_exists('variable_realm') && module_exists('variable_store')) {
      db_delete('variable_store')
        ->condition('name', db_like('google_tag_') . '%', 'LIKE')
        ->execute();

      // Remove variables from realm variable list.
      $realms = variable_realm_list();
      foreach ($realms as $realm => $label) {
        $variables = variable_get('variable_realm_list_' . $realm, array());
        if ($variables) {
          foreach ($variables as $key => $variable) {
            if (substr($variable, 0, 10) == 'google_tag') {
              unset($variables[$key]);
            }
          }
          variable_set('variable_realm_list_' . $realm, $variables);
        }
      }
    }
  */
  $row = db_query('SELECT * FROM {gtag_config} WHERE name = \'google_tag.settings\'')
    ->fetchAllKeyed();
  $settings = unserialize(array_shift($row));
  if (!empty($settings['flush_snippets'])) {
    $directory = $settings['uri'];
    if (!empty($directory)) {

      // Remove snippet file directory.
      file_unmanaged_delete_recursive($directory . '/google_tag');
    }
  }

  // @todo Is this relevant here or in _google_tag_snippets_save()?
  drupal_clear_js_cache();
}

/**
 * Implements hook_requirements().
 */
function google_tag_requirements($phase) {
  $t = get_t();
  $requirements = array();
  if ($phase == 'runtime') {
    $manager = \GTMContainerManager::getInstance();
    $containers = $manager
      ->loadContainers();
    if (empty($containers)) {

      // Google Tag Manager container ID has not been set.
      $args = array(
        '@url1' => '/admin/config/system/google_tag/settings',
        '@url2' => '/admin/config/system/google_tag',
      );
      $description = $t('Configure default settings on the <a href="@url1">module settings page</a>. Afterwards, add a container on the <a href="@url2">container management page</a>.', $args);
      $requirements['google_tag'] = array(
        'title' => $t('Google Tag Manager'),
        'description' => $description,
        'severity' => REQUIREMENT_WARNING,
        'value' => $t('Not configured'),
      );
    }
  }
  if ($phase == 'runtime' || $phase == 'update' || $phase == 'install') {
    $phase == 'install' ? require_once __DIR__ . '/google_tag.module' : '';

    // Adapted from system_requirements().
    $directory = $phase == 'install' ? 'public:/' : \GTMSettings::getInstance()
      ->get('uri');
    if (empty($directory)) {
      $requirements['google_tag_snippet_parent_directory'] = array(
        'title' => t('Google Tag Manager'),
        'description' => $t('The snippet parent directory is not set. Configure default settings on the <a href="@url1">module settings page</a>.', array(
          '@url1' => '/admin/config/system/google_tag/settings',
        )),
        'severity' => REQUIREMENT_ERROR,
        'value' => t('Not configured'),
      );
      return $requirements;
    }
    $directory .= '/google_tag';
    if (!is_dir($directory) || !_google_tag_is_writable($directory) || !_google_tag_is_executable($directory)) {
      _file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
    }
    $is_executable = _google_tag_is_executable($directory);
    $is_writable = _google_tag_is_writable($directory);
    $is_directory = is_dir($directory);
    if (!$is_executable || !$is_writable || !$is_directory) {

      // The snippet directory does not exist or is not writable or searchable.
      // If applicable, get the directory path of stream wrapper.
      $wrapper = file_stream_wrapper_get_instance_by_uri($directory);
      if (method_exists($wrapper, 'getDirectoryPath') && ($path = $wrapper
        ->getDirectoryPath())) {

        // getDirectoryPath() is not defined in StreamWrapperInterface; it
        // exists in LocalStream and the local storage replacement classes in
        // google_appengine; s3fs returns an empty string.
        $path .= '/google_tag';
      }
      elseif (!($path = $wrapper
        ->getExternalUrl())) {
        $path = $directory;
      }
      if (!$is_directory) {
        $error = $t('The directory %directory does not exist.', array(
          '%directory' => $path,
        ));
        $description = $t('An automated attempt to create the directory failed, possibly due to a permissions problem. Create the directory and make it writable.');
        $value = $t('Does not exist');
      }
      elseif (!$is_writable) {
        $error = $t('The directory %directory is not writable.', array(
          '%directory' => $path,
        ));
        $description = $t('An automated attempt to make the directory writable failed, possibly due to a permissions problem. Make the directory writable.');
        $value = $t('Not writable');
      }
      else {
        $error = $t('The directory %directory is not searchable.', array(
          '%directory' => $path,
        ));
        $description = $t('An automated attempt to make the directory searchable failed, possibly due to a permissions problem. Make the directory searchable.');
        $value = $t('Not searchable');
      }
      if ($phase == 'install') {
        $description .= $t(' For more information, see INSTALL.txt or the <a href="!handbook_url">online handbook</a>.', array(
          '!handbook_url' => 'https://www.drupal.org/server-permissions',
        ));
        $value = '';
      }
      $requirements['google_tag_snippet_directory'] = array(
        'title' => $t('Google Tag Manager snippet directory'),
        'description' => "{$error} {$description}",
        'severity' => REQUIREMENT_ERROR,
        'value' => $value,
      );
    }
  }
  return $requirements;
}

/**
 * Implements hook_schema().
 */
function google_tag_schema() {
  $schema = array();

  // Configuration table.
  $schema['gtag_config'] = array(
    'description' => 'The base table for configuration data.',
    'export' => array(
      'admin_title' => 'label',
      'key' => 'name',
      'key name' => 'Machine-readable name',
      'primary key' => 'name',
      'identifier' => 'gtag',
      'object factory' => 'google_tag_object_factory',
      'load all callback' => 'google_tag_export_load',
      'cache defaults' => TRUE,
    ),
    'fields' => array(
      'name' => array(
        'description' => 'The configuration object name (primary identifier).',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'data' => array(
        'description' => 'The serialized configuration data.',
        'type' => 'text',
        'serialize' => TRUE,
      ),
    ),
    'primary key' => array(
      'name',
    ),
    'unique keys' => array(
      'machine_name' => array(
        'name',
      ),
    ),
  );
  return $schema;
}

/**
 * Convert values in role_list variable from rid to role name.
 */
function google_tag_update_7101(&$sandbox) {
  $roles = user_roles();
  $old_values = variable_get('google_tag_role_list', array());
  $new_values = array();
  foreach ($old_values as $rid => $old_value) {
    $role_name = $roles[$rid];
    $new_values[$role_name] = $old_value ? $role_name : $old_value;
  }
  variable_set('google_tag_role_list', $new_values);
  return t('Converted @count role IDs to role names in google_tag_role_list variable', array(
    '@count' => count($old_values),
  ));
}

/**
 * Create directory for snippet files, if not present.
 */
function google_tag_update_7102(&$sandbox) {
  $result = _google_tag_snippet_directory_prepare();
  return t('The directory exists (or was created) and is writable: @result', array(
    '@result' => $result ? 1 : 0,
  ));
}

/**
 * Creates directory for snippet files, if not present.
 *
 * @return bool
 *   Whether the directory exists (or was created) and is writable.
 */
function _google_tag_snippet_directory_prepare() {

  // Create directory if not present.
  $directory = 'public://google_tag';
  $result = file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
  if (!$result) {
    drupal_set_message(t('An error occurred creating a directory for snippet files. Please try again or contact the site administrator if it persists.'));
  }
  return $result;
}

/**
 * Convert toggle settings from integer to string.
 */
function google_tag_update_7103(&$sandbox) {
  $types = array(
    'path',
    'role',
    'status',
  );
  $count = 0;
  if (module_exists('variable_realm') && module_exists('variable_store')) {

    // i18n_variable module depends on variable_realm, variable_store
    // In the course of variable_realm_set() calls will be made to:
    // - cache_clear_all('variables', 'cache_bootstrap');
    // - cache_clear_all('variable:' . $realm . ':' . $key, 'cache_bootstrap');
    // which will clear all relevant cache tables except for cache_variable.
    // Clear the latter at end.
    $realms = variable_realm_list();
    foreach ($realms as $realm_name => $realm_title) {
      $keys = variable_realm_keys($realm_name);
      foreach ($keys as $key_name => $key_title) {
        foreach ($types as $type) {
          $name = "google_tag_{$type}_toggle";
          $value = variable_realm_get($realm_name, $key_name, $name);

          // Safer to set status toggle to 'all except' regardless of prior value.
          $value = $type == 'status' ? 0 : $value;
          if (!is_null($value)) {
            $new_value = $value ? GOOGLE_TAG_INCLUDE_LISTED : GOOGLE_TAG_EXCLUDE_LISTED;
            variable_realm_set($realm_name, $key_name, $name, $new_value, FALSE);
            $count++;
          }
        }
      }
    }
    variable_cache_clear();
  }
  else {
    global $conf;
    foreach ($types as $type) {
      $name = "google_tag_{$type}_toggle";
      if (isset($conf[$name])) {
        $new_value = $conf[$name] ? GOOGLE_TAG_INCLUDE_LISTED : GOOGLE_TAG_EXCLUDE_LISTED;
        variable_set($name, $new_value);
        $count++;
      }
    }
  }
  return t('Converted @count toggle settings', array(
    '@count' => $count,
  ));
}

/**
 * Rename 'compact_tag' setting to 'compact_snippet'.
 */
function google_tag_update_7104(&$sandbox) {
  $count = 0;
  $tables = array(
    'variable',
  );
  if (module_exists('variable_realm') && module_exists('variable_store')) {
    global $conf;
    $tables[] = 'variable_store';
    $realms = variable_realm_list();
    foreach ($realms as $realm_name => $realm_title) {
      if (!empty($conf["variable_realm_list_{$realm_name}"])) {
        $items = $conf["variable_realm_list_{$realm_name}"];
        if ($key = array_search('google_tag_compact_tag', $items, TRUE)) {
          $items[$key] = 'google_tag_compact_snippet';
          variable_set("variable_realm_list_{$realm_name}", $items);
          $count++;
        }
      }
    }
  }
  foreach ($tables as $table) {
    $count += db_update($table)
      ->fields(array(
      'name' => 'google_tag_compact_snippet',
    ))
      ->condition('name', 'google_tag_compact_tag')
      ->execute();
  }
  cache_clear_all('variables', 'cache_bootstrap');
  cache_clear_all('variable:', 'cache_bootstrap', TRUE);
  if (module_exists('variable')) {
    variable_cache_clear();
  }
  return t('Converted @count occurrences of setting', array(
    '@count' => $count,
  ));
}

/**
 * Deprecated update hook; no changes will be made.
 */
function google_tag_update_7105(&$sandbox) {

  // This update used to [re]create the snippet files, but this is no longer
  // necessary here as hook_enable() and hook_cron() were implemented.
}

/**
 * Deprecated update hook; no changes will be made.
 */
function google_tag_update_7106(&$sandbox) {

  // This update used to [re]create the snippet files, but this is no longer
  // necessary here as hook_enable() and hook_cron() were implemented.
}

/**
 * Migrate variables to settings and container config items.
 */
function google_tag_update_7200(&$sandbox) {

  // @todo Retain variables until next hook_update_N to avoid migration issues.
  // Extract the delete variables code from hook_uninstall().
  // google_tag_uninstall();
  $chema = drupal_get_schema_unprocessed('google_tag', 'gtag_config');
  db_create_table('gtag_config', $chema);

  // Do first while the realm keys are hopefully on defaults.
  _google_tag_settings_migrate();
  if (module_exists('variable_realm') && module_exists('variable_store')) {

    // Backup global config as switching realm overwrites this array.
    $backup = $GLOBALS['conf'];

    // i18n_variable module depends on variable_realm, variable_store
    $realms = variable_realm_list();

    // @todo If realm enabled but only realm is global, then do that.
    foreach ($realms as $realm_name => $realm_title) {
      $keys = variable_realm_keys($realm_name);
      foreach ($keys as $key_name => $key_title) {
        variable_realm_switch($realm_name, $key_name);
        _google_tag_container_migrate($realm_name, $key_name);
      }
    }
    $GLOBALS['conf'] = $backup;
  }
  else {
    _google_tag_container_migrate();
  }
  return t('Migrate variables to settings and container config items');
}

/**
 * Migrates module settings to settings configuration entity.
 */
function _google_tag_settings_migrate() {
  google_tag_settings_create(FALSE);
}

/**
 * Migrates container variables to container configuration entities.
 *
 * @param string $realm_name
 *   The realm name.
 * @param string $key_name
 *   The realm key name.
 */
function _google_tag_container_migrate($realm_name = '', $key_name = '') {
  ctools_include('export');
  module_load_include('inc', 'google_tag', 'includes/variable');
  $machine_name = $key_name ? str_replace(':', '_', $key_name) : 'primary';
  $result = gtag_export_crud_load('gtag_config', "google_tag.container.{$machine_name}");
  if ($result) {
    return;
  }

  // Gather data.
  $groups = array(
    'general',
    'advanced',
    'path',
    'role',
    'status',
  );
  $data['name'] = $machine_name;
  $data['label'] = $key_name ? $key_name : 'Primary';
  $data['status'] = TRUE;

  // Build variables.
  $variables = _google_tag_variable_list($groups);
  foreach ($variables as $name => $variable) {

    // Stodo Restore the 'google_tag_' prefix to the variable name.
    $key = $name;
    $name = 'google_tag_' . $name;
    $data[$key] = variable_get($name, '');
  }
  $data['weight'] = 1;

  // Ensure default values for new settings.
  $data['realm_toggle'] = $variables['realm_toggle']['default'];
  $data['realm_list'] = $variables['realm_list']['default'];
  if ($realm_name && $key_name) {
    $data['realm_toggle'] = GOOGLE_TAG_INCLUDE_LISTED;
    $data['realm_list']["{$realm_name}:{$key_name}"] = "{$realm_name}:{$key_name}";
  }

  // Prune the list.
  $data['role_list'] = array_filter($data['role_list']);
  $object['name'] = "google_tag.container.{$machine_name}";
  $object['data'] = $data;
  $object['export_type'] = NULL;
  $object = (object) $object;
  $result = ctools_export_crud_save('gtag_config', $object);
}

/**
 * Installs module settings as a settings configuration entity.
 *
 * @param bool $use_install_config
 *   (optional) Whether to populate settings from existing variable values or
 *   default configuration values.
 */
function google_tag_settings_create($use_install_config = TRUE) {
  ctools_include('export');
  module_load_include('inc', 'google_tag', 'includes/variable');
  $result = gtag_export_crud_load('gtag_config', 'google_tag.settings');
  if ($result) {
    return;
  }

  // Gather data.
  $data['name'] = 'settings';
  $data['label'] = 'Module settings';
  $data['status'] = TRUE;

  // Build module settings.
  $groups = array(
    'settings',
  );
  $variables = _google_tag_variable_list($groups);
  foreach ($variables as $name => $variable) {

    // Stodo Restore the 'google_tag_' prefix to the variable name.
    $key = $name;
    $name = 'google_tag_' . $name;
    $data[$key] = $use_install_config ? $variable['default'] : variable_get($name, '');
  }

  // Ensure default values for new settings.
  $data['uri'] = 'public:/';
  $data['rebuild_snippets'] = $variables['rebuild_snippets']['default'];
  $data['flush_snippets'] = $variables['flush_snippets']['default'];

  // Build default container settings.
  $groups = array(
    'advanced',
    'path',
    'role',
    'status',
    'realm',
  );
  $variables = _google_tag_variable_list($groups);
  foreach ($variables as $name => $variable) {

    // Stodo Restore the 'google_tag_' prefix to the variable name.
    $key = $name;
    $name = 'google_tag_' . $name;
    $data[$key] = $use_install_config ? $variable['default'] : variable_get($name, '');
  }

  // Prune the list.
  $data['role_list'] = array_filter($data['role_list']);
  $object['name'] = 'google_tag.settings';
  $object['data'] = $data;
  $object['export_type'] = NULL;
  $object = (object) $object;
  $result = ctools_export_crud_save('gtag_config', $object);
}

/**
 * Returns a list of variables in the groups.
 *
 * @param array $groups
 *   The variable groups.
 *
 * @return array
 *   Associative array of variables keyed by variable name.
 */
function _google_tag_variable_list(array $groups = array()) {
  static $variables;
  $key = implode(':', $groups);
  if (!isset($variables[$key])) {

    // Build variables.
    $variables[$key] = array();
    foreach ($groups as $group) {
      $function = "_google_tag_variable_info_{$group}";
      $variables[$key] += $function($options = array());
    }
  }
  return $variables[$key];
}

Functions

Namesort descending Description
google_tag_enable Implements hook_enable().
google_tag_requirements Implements hook_requirements().
google_tag_schema Implements hook_schema().
google_tag_settings_create Installs module settings as a settings configuration entity.
google_tag_uninstall Implements hook_uninstall().
google_tag_update_7101 Convert values in role_list variable from rid to role name.
google_tag_update_7102 Create directory for snippet files, if not present.
google_tag_update_7103 Convert toggle settings from integer to string.
google_tag_update_7104 Rename 'compact_tag' setting to 'compact_snippet'.
google_tag_update_7105 Deprecated update hook; no changes will be made.
google_tag_update_7106 Deprecated update hook; no changes will be made.
google_tag_update_7200 Migrate variables to settings and container config items.
_google_tag_container_migrate Migrates container variables to container configuration entities.
_google_tag_settings_migrate Migrates module settings to settings configuration entity.
_google_tag_snippet_directory_prepare Creates directory for snippet files, if not present.
_google_tag_variable_list Returns a list of variables in the groups.