<?php

/**
 * @file
 * Installation file.
 */

/**
 * Implements hook_schema().
 */
function eu_cookie_compliance_schema() {
  $schema['eu_cookie_compliance_basic_consent'] = array(
    'description' => 'Basic consent storage for EU Cookie Compliance / GDPR.',
    'fields' => array(
      'cid' => array(
        'type' => 'serial',
        'not null' => TRUE,
        'description' => 'Primary Key: Unique consent storage ID.',
      ),
      'uid' => array(
        'description' => '{users}.uid for user.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'timestamp' => array(
        'description' => 'Time of consent.',
        'type' => 'int',
        'unsigned' => FALSE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'ip_address' => array(
        'description' => 'The IP address.',
        'type' => 'varchar',
        // Maximum length of an ipv6 IP address.
        'length' => 45,
        'not null' => TRUE,
        'default' => '',
      ),
      'consent_type' => array(
        'description' => 'The type of consent, such as "banner" for the banner and form_id for forms.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'revision_id' => array(
        'description' => 'Revision of the privacy policy at the time of consent.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'primary key' => array('cid'),
    'indexes' => array(
      'uid' => array('uid'),
    ),
    'foreign keys' => array(
      'uid' => array('users' => 'uid'),
    ),
  );

  return $schema;
}

/**
 * Implements hook_install().
 */
function eu_cookie_compliance_install() {
  $popup_settings = _eu_cookie_compliance_get_popup_default_setting();
  variable_set('eu_cookie_compliance', $popup_settings);

  // Enable banner for all roles.
  $roles = user_roles();
  $permission = 'display EU Cookie Compliance popup';
  foreach ($roles as $rid => $value) {
    user_role_grant_permissions($rid, array($permission));
  }
}

/**
 * Implements hook_uninstall().
 */
function eu_cookie_compliance_uninstall() {
  variable_del('eu_cookie_compliance');
  cache_clear_all('variables', 'cache');
}

/**
 * Implements hook_requirements().
 */
function eu_cookie_compliance_requirements($phase) {
  $requirements = array();

  if ($phase == 'runtime') {
    module_load_include('module', 'eu_cookie_compliance', 'eu_cookie_compliance');
    $settings = eu_cookie_compliance_get_settings();

    if (!empty($settings['popup_link']) && $settings['popup_link'] == '<front>' && !empty($settings['show_disagree_button']) && $settings['show_disagree_button']) {
      $requirements['eu_cookie_compliance'] = array(
        'title' => t('EU Cookie Compliance'),
        'severity' => REQUIREMENT_ERROR,
        'description' => t('Your privacy policy link is pointing at the front page. This is the default value after installation, and unless your privacy policy is actually posted at the front page, you will need to create a separate page for the privacy policy and link to that page.'),
        'value' => t('Privacy Policy link not provided'),
      );
    }
  }

  return $requirements;
}

/**
 * Gets the default settings for the 'eu_cookie_compliance' variables.
 *
 * @return array
 *   Associative array containing the default value for each
 *   'eu_cookie_compliance' parameter.
 */
function _eu_cookie_compliance_get_popup_default_setting() {
  $default_filter_format = filter_default_format();
  if ($default_filter_format == 'filtered_html' && filter_format_load('full_html')) {
    $default_filter_format = 'full_html';
  }

  $cookie_policy = _eu_cookie_compliance_find_privacy_policy();
  if (!$cookie_policy) {
    $cookie_policy = '<front>';
  }

  return array(
    'info_template' => 'new',
    'popup_info' => array(
      'value' => '<h2>We use cookies on this site to enhance your user experience</h2><p>By clicking any link on this page you are giving your consent for us to set cookies.</p>',
      'format' => $default_filter_format,
    ),
    'popup_agreed' => array(
      'value' => '<h2>Thank you for accepting cookies</h2><p>You can now hide this message or find out more about cookies.</p>',
      'format' => $default_filter_format,
    ),
    'popup_enabled' => TRUE,
    'popup_position' => FALSE,
    'popup_bg_hex' => '0779bf',
    'popup_text_hex' => 'fff',
    'popup_agreed_enabled' => FALSE,
    'popup_height' => '',
    'popup_width' => '100%',
    'popup_delay' => 1000,
    'popup_link' => $cookie_policy,
    'fixed_top_position' => TRUE,
    'consent_storage_method' => 'do_not_store',
    'disabled_javascripts' => '',
    'cookie_session' => 0,
    'disable_google_analytics' => 0,
    'withdraw_message' => array(
      'value' => '<h2>We use cookies on this site to enhance your user experience</h2><p>You have given your consent for us to set cookies.</p>',
      'format' => $default_filter_format,
    ),
    'withdraw_action_button_label' => 'Withdraw consent',
    'withdraw_tab_button_label' => 'Privacy settings',
    'withdraw_enabled' => 0,
  );
}

/**
 * Change the banner sliding animation time from seconds to milliseconds.
 */
function eu_cookie_compliance_update_7000(&$sandbox = NULL) {
  global $language;
  if (module_exists('locale')) {
    $languages = locale_language_list();
    foreach ($languages as $key => $current_language) {
      $eu_cookie_settings = variable_get('eu_cookie_compliance_' . $key, array());
      if (!empty($eu_cookie_settings['popup_delay'])) {
        $eu_cookie_settings['popup_delay'] *= 1000;
        variable_set('eu_cookie_compliance_' . $key, $eu_cookie_settings);
      }
    }
  }
  else {
    $current_language = ($language->language) ? $language->language : 'en';
    $eu_cookie_settings = variable_get('eu_cookie_compliance_' . $current_language, array());
    if (!empty($eu_cookie_settings['popup_delay'])) {
      $eu_cookie_settings['popup_delay'] *= 1000;
      variable_set('eu_cookie_compliance_' . $current_language, $eu_cookie_settings);
    }
  }
}

/**
 * Migrate translation handling to Variable API.
 *
 * NOTE: Make sure the variable_realm and i18n_variable modules are either
 * enabled or in the filesystem if you are using multiple languages.
 */
function eu_cookie_compliance_update_7001(&$sandbox) {
  $languages = language_list();
  $variable_names = db_query("SELECT name FROM {variable} WHERE name LIKE '%eu_cookie_compliance_%' AND name NOT IN('eu_cookie_compliance_domain', 'eu_cookie_compliance_cookie_lifetime')")->fetchCol();
  $default_value = array();
  if (count($variable_names) === 1) {
    // We only have one language.
    $name = reset($variable_names);
    $default_value = variable_get($name);
    variable_del($name);
  }
  else {
    // Multiple languages, need to install variable_realm module.
    $variable_exists = TRUE;
    if (!module_exists('i18n_variable')) {
      $variable_exists = module_enable(array('i18n_variable'));
    }
    if ($variable_exists) {
      $default_language = language_default('language');
      foreach ($variable_names as $name) {
        $langcode = str_replace('eu_cookie_compliance_', '', $name);
        if (isset($languages[$langcode])) {
          $value = variable_get($name);
          if ($langcode == $default_language) {
            $default_value = $value;
          }
          i18n_variable_set('eu_cookie_compliance', $value, $langcode);
          variable_del($name);
        }
      }

      // Enable translation variables for EU Cookie Compliance.
      $controller = variable_realm_controller('language');
      $old_variables = $controller->getEnabledVariables();
      $old_list = variable_children($old_variables);
      $variables = array_merge($old_list, array('eu_cookie_compliance'));
      $controller->setRealmVariable('list', $variables);
    }
    else {
      throw new DrupalUpdateException('EU Cookie Compliance now requires the modules variable ( https://www.drupal.org/project/variable ) and i18n ( https://www.drupal.org/project/i18n ) for multilingual sites. Please add these modules to your site.');
    }
  }
  // Even with i18n_variable, aan entry in the variable table is required.
  variable_set('eu_cookie_compliance', $default_value);
  cache_clear_all('variables', 'cache');
}

/**
 * Delete the menu item that was added due to a missing menu item type in 1.15.
 */
function eu_cookie_compliance_update_7002() {
  db_query('delete from {menu_links} where link_path = \'eu-cookie-compliance-check\'');
}

/**
 * Clear cache for only the settings of this module, to initialize new module settings.
 */
function eu_cookie_compliance_update_7003() {
  module_load_include('module', 'eu_cookie_compliance', 'eu_cookie_compliance');
  eu_cookie_compliance_clear_caches();
}

/**
 * Version 1.21. Clear cache for only the settings of this module.
 */
function eu_cookie_compliance_update_7004() {
  module_load_include('module', 'eu_cookie_compliance', 'eu_cookie_compliance');
  eu_cookie_compliance_clear_caches();
}

/**
 * Version 1.24. Add new settings.
 */
function eu_cookie_compliance_update_7005() {
  $eu_cookie_settings = variable_get('eu_cookie_compliance', array());
  $eu_cookie_settings['method'] = 'default';
  $eu_cookie_settings['disagree_button_label'] = 'No, thanks';
  $eu_cookie_settings['disabled_javascripts'] = '';
  $eu_cookie_settings['whitelisted_cookies'] = '';
  variable_set('eu_cookie_compliance', $eu_cookie_settings);
}

/**
 * Version 1.24. Create table for storing consent, and update settings.
 */
function eu_cookie_compliance_update_7006() {
  // NEVER load the schema with hook schema as the schema may has changed!
  $schema['eu_cookie_compliance_basic_consent'] = array(
    'description' => 'Basic consent storage for EU Cookie Compliance / GDPR.',
    'fields' => array(
      'cid' => array(
        'type' => 'serial',
        'not null' => TRUE,
        'description' => 'Primary Key: Unique consent storage ID.',
      ),
      'uid' => array(
        'description' => '{users}.uid for user.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'timestamp' => array(
        'description' => 'Time of consent.',
        'type' => 'int',
        'unsigned' => FALSE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'ip_address' => array(
        'description' => 'The IP address.',
        'type' => 'varchar',
        // Maximum length of an ipv6 IP address.
        'length' => 45,
        'not null' => TRUE,
        'default' => '',
      ),
      'consent_type' => array(
        'description' => 'The type of consent, such as "banner" for the banner and form_id for forms.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'revision_id' => array(
        'description' => 'Revision of the privacy policy at the time of consent.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'primary key' => array('cid'),
    'indexes' => array(
      'uid' => array('uid'),
    ),
    'foreign keys' => array(
      'uid' => array('users' => 'uid'),
    ),
  );

  if (!db_table_exists('eu_cookie_compliance_basic_consent')) {
    db_create_table('eu_cookie_compliance_basic_consent', $schema['eu_cookie_compliance_basic_consent']);
  }
  $eu_cookie_settings = variable_get('eu_cookie_compliance', array());
  $eu_cookie_settings['consent_storage_method'] = 'do_not_store';
  variable_set('eu_cookie_compliance', $eu_cookie_settings);

  module_load_include('module', 'eu_cookie_compliance', 'eu_cookie_compliance');
  eu_cookie_compliance_clear_caches();
}

/**
 * Version 1.24. Be sure weight of the module is higher than jQuery Update.
 */
function eu_cookie_compliance_update_7007() {
  if (module_exists('jquery_update')) {
    // @TODO: Document why this weight change is needed. Add a test.
    // Get the weight of the jquery update module.
    $result = db_select('system', 's')
      ->fields('s', array('weight'))
      ->condition('name', 'jquery_update', '=')
      ->execute();
    $weight = !empty($result) ? $result->fetchField() : 0;

    // Set the weight of this module to 1 heavier.
    db_update('system')
      ->fields(array('weight' => $weight + 1))
      ->condition('name', 'eu_cookie_compliance', '=')
      ->execute();
  }
}

/**
 * Add config variables for the withdraw banner.
 */
function eu_cookie_compliance_update_7008() {
  $default_filter_format = filter_default_format();
  if ($default_filter_format == 'filtered_html' && filter_format_load('full_html')) {
    $default_filter_format = 'full_html';
  }
  $eu_cookie_settings = variable_get('eu_cookie_compliance', array());
  $eu_cookie_settings['withdraw_message'] = array(
    'value' => '<h2>We use cookies on this site to enhance your user experience</h2><p>You have given your consent for us to set cookies.</p>',
    'format' => $default_filter_format,
  );
  $eu_cookie_settings['withdraw_action_button_label'] = 'Withdraw consent';
  $eu_cookie_settings['withdraw_tab_button_label'] = 'Privacy settings';
  $eu_cookie_settings['withdraw_enabled'] = 1;
  // Set default info template to 'legacy' for 'consent by default' config
  // option.
  if (!array_key_exists('info_template', $eu_cookie_settings)) {
    $eu_cookie_settings['info_template'] = 'legacy';
  }
  variable_set('eu_cookie_compliance', $eu_cookie_settings);
}

/**
 * Disable withdraw tab and banner in the consent method "Consent by default".
 */
function eu_cookie_compliance_update_7009() {
  $eu_cookie_settings = variable_get('eu_cookie_compliance', array());

  if (!empty($eu_cookie_settings['method']) && $eu_cookie_settings['method'] == 'default' && !empty($eu_cookie_settings['withdraw_enabled']) && $eu_cookie_settings['withdraw_enabled'] == 1) {
    $eu_cookie_settings['withdraw_enabled'] = 0;
  }
  variable_set('eu_cookie_compliance', $eu_cookie_settings);
}

/**
 * Ensure that all "eu_cookie_compliance" parameters have a default value.
 */
function eu_cookie_compliance_update_7010() {
  $settings = variable_get('eu_cookie_compliance', array());
  $updated_setting = $settings + _eu_cookie_compliance_get_popup_default_setting();
  variable_set('eu_cookie_compliance', $updated_setting);

  if (module_exists('i18n_variable')) {
    $languages = language_list();
    foreach (array_keys($languages) as $langcode) {
      $settings = i18n_variable_get('eu_cookie_compliance', $langcode);
      if (!empty($settings)) {
        $updated_setting = $settings + _eu_cookie_compliance_get_popup_default_setting();
        i18n_variable_set('eu_cookie_compliance', $updated_setting, $langcode);
      }
    }
  }
}
