<?php

/**
 * @file
 * Database schema of
 * @see themekey.module
 *
 * @author Markus Kalkbrenner | bio.logis GmbH
 *   @see http://drupal.org/user/124705
 *
 * @author profix898
 *   @see http://drupal.org/user/35192
 */


/**
 * Implements hook_schema().
 */
function themekey_schema() {
  $schema = array();
  $schema['themekey_properties'] = array(
    'fields' => array(
      'id' => array(
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'property' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'operator' => array(
        'type' => 'varchar',
        'length' => 2,
        'not null' => TRUE,
        'default' => '=',
      ),
      'value' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'weight' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'theme' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'enabled' => array(
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'wildcards' => array(
        'type' => 'text',
        'not null' => TRUE,
        'size' => 'big',
        'serialize' => TRUE,
      ),
      'parent' => array(
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'module' => array(
        'description' => 'The name of the module that created this entry.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
    ),
    'primary key' => array('id'),
    'indexes' => array(
      'enabled_parent_weight' => array('enabled', 'parent', 'weight'),
      'parent_weight' => array('parent', 'weight'),
    ),
  );

  return $schema;
}


/**
 * Implements hook_install().
 */
function themekey_install() {
}


/**
 * Implements hook_uninstall().
 */
function themekey_uninstall() {
  // Remove variables
  db_delete('variable')
  ->condition('name', 'themekey_%%', 'LIKE')
  ->execute();
  cache_clear_all('variables', 'cache');
}

/**
 * Implements hook_requirements().
 */
function themekey_requirements($phase) {
  $requirements = array();
  $t = get_t();

  switch ($phase) {
    case 'update':
      if (module_exists('domain_theme') && !module_exists('domain_themekey')) {
        $requirements['domain_themekey_warning'] = array(
          'title' => $t('Domain ThemeKey'),
          'description' => $t('You enabled the Domain Theme module. To ensure the its compatibility to ThemeKey its required to additionally install and enable the !module_link sub-module before you proceed.', array('!module_link' => l('Domain ThemeKey', 'https://www.drupal.org/project/domain_themekey'))),
          'value' => $t('Not installed'),
          'severity' => REQUIREMENT_ERROR,
        );
      }
      break;

    case 'runtime':
      // If Domain ThemeKey is disabled or uninstalled but ThemeKey
      // holds Domain ThemeKey properties then error message needed.
      if (!module_exists('domain_themekey')) {
        $themekey_properties = db_select('themekey_properties', 'tp')->fields('tp')->condition('tp.enabled', 1)->condition('tp.property', db_like('domain:') . '%', 'LIKE')->execute()->fetchAll();

        if (count($themekey_properties) > 0) {
          $requirements['domain_themekey_error'] = array(
            'title' => $t('Domain ThemeKey'),
            'description' => $t('Your rule chain contains properties provided by the !module_link sub-module. You have to enable it to get your chain to work correctly.', array('!module_link' => l('Domain ThemeKey', 'https://www.drupal.org/project/domain_themekey'))),
            'value' => $t('Not installed'),
            'severity' => REQUIREMENT_WARNING,
          );
        }
      }
      break;
  }

  return $requirements;
}

/**
 * Implements hook_update_N().
 *
 * Update property 'nid' to 'node:nid'
 */
function themekey_update_6001() {

  $result = db_query('SELECT * FROM {themekey_properties} WHERE property = :property', array(':property' => 'nid'));

  foreach ($result as $item) {
    if (db_query('SELECT COUNT(id) FROM {themekey_properties} WHERE property = :property AND value = :value', array(':property' => 'node:nid', ':value' => $item->value))->fetchField() > 0) {
      db_delete('themekey_properties')
      ->condition('id', $item->id, '=')
      ->execute();
    }
    else {
      $num_updated = db_update('themekey_properties')
      ->fields(array(
        'property' => 'node:nid',
      ))
      ->condition('id', $item->id, '=')
      ->execute();
    }
  }

  return t('Updated property "nid" to "node:nid"');
}


/**
 * Implements hook_update_N().
 */
function themekey_update_6100() {

  $properties = variable_get('themekey_properties', array());

  foreach ($properties as $key => &$property) {
    if (array_key_exists('path', $property) && $key === $property['path']) {
      $property['path'] = FALSE;
    }
  }

  variable_set('themekey_properties', $properties);

  return t('Updated variable themekey_properties:path.');
}


/**
 * Implements hook_update_N().
 */
function themekey_update_6101() {
  $num_updated = db_update('system')
  ->fields(array(
    'weight' => 0,
  ))
  ->condition('name', 'themekey', '=')
  ->execute();

  return t('Updated system weight to 0 for ThemeKey.');
}


/**
 * Implements hook_update_N().
 */
function themekey_update_6102() {
  if (module_exists('forum')) {
    variable_set('themekey_module_forum_triggers_taxonomy_vid', 1);
  }

  if (module_exists('taxonomy_menu')) {
    variable_set('themekey_module_taxonomy_menu_triggers_taxonomy_tid', 1);
  }

  return t('Set variables "themekey_module_forum_triggers_taxonomy_vid" and "themekey_module_taxonomy_menu_triggers_taxonomy_tid" with value 1');
}


/**
 * Implements hook_update_N().
 */
function themekey_update_6103() {
  variable_del('themekey_nodediscover');
  return t('Deleted variable themekey_nodediscover.');
}


/**
 * Implements hook_update_N().
 */
function themekey_update_6104() {
  db_drop_field('themekey_properties', 'callbacks');
  return t('Dropped field callbacks.');
}


/**
 * Implements hook_update_N().
 */
function themekey_update_6105() {
  // Coder module complains "global variables should start with a single
  // underscore followed by the module and another underscore". But $db_type is
  // defined by drupal core.
  // @ignore style_global_vars
  global $db_type;

  $return = array();

  // we need to handle upgrade of module ThemeKey UI here because
  // it will fail when triggered at themekey_ui.install after
  // ThemeKey upgrade from 6.x-1.1 to 6.x.2.0
  if (module_exists('themekey_ui')) {
    $schema_version = drupal_get_installed_schema_version('themekey_ui');
    if (6100 > $schema_version) {
      drupal_install_schema('themekey_ui');

      if (!variable_get('themekey_nodeaspath', 0)) {
        $sql = '';
        if (0 === strpos($db_type, 'mysql')) {
          $sql = "SELECT id, value, theme, nid, vid FROM {themekey_properties} JOIN {node_revisions} ON (value = nid) WHERE property = :property AND conditions = :conditions";
        }
        elseif (0 === strpos($db_type, 'pqsql')) {
          $sql = "SELECT id, value, theme, nid, vid FROM {themekey_properties} JOIN {node_revisions} ON (value = nid::character varying) WHERE property = :property AND conditions = :conditions";
        }
        if ($result = db_query($sql, array(':property' => 'node:nid', ':conditions' => 'a:0:{}'))) {


        foreach ($result as $row) {

          $return['INSERT']['success'] = db_insert('themekey_ui_node_theme')
            ->fields(array(
              'nid' => $row->nid,
              'vid' => $row->vid,
              'theme' => $row->theme,
            ))
            ->execute();

            if ($return['INSERT']['success']) {
              $return['DELETE']['success'] = db_delete('themekey_properties')
              ->condition('id', $row->id)
              ->execute();
              if (!($return['DELETE']['success'])) {
                break;
              }
            }
            else {
              $return['INSERT']['success'] = FALSE;
              break;
            }
          }

          $return = t('Themekey UI was successfully updated');

        }
        else {
          $return = t('Update of Themekey UI failed.');
        }
      }

      variable_del('themekey_nodeaspath');
    }
  }

  return $return;
}


/**
 * Function _themekey_properties_explode_conditions()
 * converts conditions formatted as string into an array.
 * It was part of themekey_build.inc up to version 6.x-1.2.
 * Now it's only required one more time to perform
 * themekey_update_6200()
 *
 * @param $conditions
 *   ThemeKey conditions as string
 *
 * @return
 *   ThemeKey conditions as array
 */
function _themekey_properties_explode_conditions($conditions) {
  if (!is_array($conditions)) {
    $parts = array_filter(explode(';', $conditions));
    $conditions = array();
    foreach ($parts as $part) {
      $part = trim($part);
      if (preg_match('/(.*?)([<>=!~])(.*)/', $part, $matches)) {
        $conditions[] = array(
          'property' => trim($matches[1]),
          'operator' => trim($matches[2]),
          'value' => trim($matches[3]),
        );
      }
    }
  }

  return $conditions;
}


/**
 * Implements hook_update_N().
 */
function themekey_update_6200() {
  $field = array(
    'type' => 'int',
    'unsigned' => TRUE,
    'not null' => TRUE,
    'default' => '0',
    'initial' => '1',
  );
  db_add_field('themekey_properties', 'enabled', $field);

  db_drop_index('themekey_properties', 'property');
  db_add_index('themekey_properties', 'enabled', array('enabled'));

  $field = array(
    'type' => 'text',
    'not null' => TRUE,
  );
  db_add_field('themekey_properties', 'wildcards', $field);

  $weight = ((int) db_query("SELECT MIN(weight) FROM {themekey_properties}")->fetchField()) - 1;

  $result = db_query("SELECT * FROM {themekey_paths} WHERE custom = :custom", array(':custom' => 1));

  foreach ($result as $item) {

    $conditions = unserialize($item->conditions);
    if (is_array($conditions) && !empty($conditions)) {
      if (!is_array($conditions[0])) {
        // ThemeKey 6.x-1.1 stored conditions for paths as simple string within an array
        $conditions = _themekey_properties_explode_conditions($conditions[0]);
      }
    }

    $insert_success = db_insert('themekey_properties')
    ->fields(array(
      'property' => 'drupal:path',
      'value' => $item->path,
      'weight' => $weight,
      'conditions' => serialize($conditions),
      'theme' => $item->theme,
      'enabled' => 1,
      'wildcards' => $item->wildcards,
    ))
    ->execute();

    $num_deleted = db_delete('themekey_paths')
    ->condition('id', $item->id)
    ->execute();

  }

  db_drop_field('themekey_paths', 'conditions');
  db_drop_field('themekey_paths', 'custom');
  db_drop_field('themekey_paths', 'theme');

  return t('Updated ThemeKey properties.');
}


/**
 * Implements hook_update_N().
 */
function themekey_update_6201() {
  // Moved to themekey_update_6202().
  return '';
}


/**
 * Implements hook_update_N().
 */
function themekey_update_6202() {
  $ret = array();

  $field_operator = array(
    'type' => 'varchar',
    'length' => 2,
    'not null' => TRUE,
    'default' => '=',
    'initial' => '=',
  );
  db_add_field('themekey_properties', 'operator', $field_operator);

  $field_parent = array(
    'type' => 'int',
    'unsigned' => TRUE,
    'not null' => TRUE,
    'default' => 0,
    'initial' => 0,
  );
  db_add_field('themekey_properties', 'parent', $field_parent);

  if ($result = db_query("SELECT * FROM {themekey_properties} WHERE conditions <> :conditions", array(':conditions' => serialize(array())))) {
    foreach ($result as $row) {
      $conditions = unserialize($row->conditions);
      if (is_array($conditions)) {
        $parent = $row->id;
        foreach ($conditions as $condition) {
          $parent = db_insert('themekey_properties')
          ->fields(array(
            'property' =>  $condition['property'],
            'operator' => $condition['operator'],
            'value' => $condition['value'],
            'weight' => 0,
            'theme' => $row->theme,
            'enabled' => $row->enabled,
            'wildcards' => serialize(array()),
            'parent' => $parent,
          ))
          ->execute();
        }
      }
    }
  }

  db_drop_field('themekey_properties', 'conditions');
  db_drop_index('themekey_properties', 'enabled');
  db_drop_index('themekey_properties', 'weight');
  db_add_index('themekey_properties', 'enabled_parent_weight', array('enabled', 'parent', 'weight'));
  db_add_index('themekey_properties', 'parent_weight', array('parent', 'weight'));

  db_drop_index('themekey_paths', 'path');
  db_drop_index('themekey_paths', 'fit');
  db_drop_index('themekey_paths', 'weight');
  db_add_index('themekey_paths', 'path_fit_weight', array('path', 'fit', 'weight'));

  return t('Updated ThemeKey properties.');
}


/**
 * Implements hook_update_N().
 */
function themekey_update_6203() {
  // moved themekey_rebuild() to themekey_update_6300()
  return '';
}


/**
 * Implements hook_update_N().
 */
function themekey_update_6300() {
  // moved themekey_rebuild() to themekey_update_6301()

  db_drop_table('themekey_paths');
  return t('Update of ThemeKey ran successfully');
}


/**
 * Implements hook_update_N().
 */
function themekey_update_6301() {
  // moved themekey_rebuild() to themekey_update_7101()
  return '';
}

/**
 * Implements hook_update_N().
 */
function themekey_update_7100() {
  // cleanup for users of older versions of the obsolete module themekey_properties
  $attributes = array(
    'system:query_param',
    'system:query_string',
    'system:cookie',
    'system:server_ip',
    'system:server_port',
    'system:server_name',
    'system:https',
    'system:remote_ip',
    'system:referer',
    'system:user_agent',
    'system:user_browser',
    'system:user_browser_simplified',
    'system:user_os',
    'system:user_os_simplified',
    'system:date_time',
    'system:date',
    'system:time',
    'system:dummy',
    'drupal:base_path',
    'drupal:is_front_page',
    'user:role',
  );
  $properties = variable_get('themekey_properties', array());
  foreach ($attributes as $attribute) {
    if (array_key_exists($attribute, $properties)) {
      $properties[$attribute]['path'] = FALSE;
    }
  }
  variable_set('themekey_properties', $properties);

  // cleanup for users of older versions of the obsolete module themekey_properties
  variable_del('themekey_properties_debug_show_values');

  return t('Update of ThemeKey ran successfully');
}

/**
 * Implements hook_update_N().
 */
function themekey_update_7101() {
  // moved themekey_rebuild() to themekey_update_7104()

  return t('Update of ThemeKey ran successfully');
}

/**
 * Implements hook_update_N().
 */
function themekey_update_7102() {
  variable_del('themekey_override_custom_theme');

  return t('Update of ThemeKey ran successfully');
}


/**
 * Implements hook_update_N().
 */
function themekey_update_7103() {
  db_add_field('themekey_properties', 'module', array(
    'description' => 'The name of the module that created this entry.',
    'type' => 'varchar',
    'length' => 255,
    'not null' => TRUE,
    'default' => '',
    )
  );

  db_update('themekey_properties')
    ->fields(array('module' => 'themekey'))
    ->execute();

  return t('Update of ThemeKey ran successfully');
}

/**
 * Rebuild ThemeKey's internal property registry.
 */
function themekey_update_7104() {
  // moved themekey_rebuild() to themekey_update_7301()

  return t('Update of ThemeKey ran successfully');
}

// function themekey_update_7300() has been erroneously declared in
// themekey_redeirect.install before.

/**
 * Rebuild ThemeKey's internal property registry.
 */
function themekey_update_7301() {
  // moved themekey_rebuild() to themekey_update_7302()

  return t('Update of ThemeKey ran successfully');
}

/**
 * Rebuild ThemeKey's internal property registry.
 */
function themekey_update_7302() {
  module_load_include('inc', 'themekey', 'themekey_base');
  module_load_include('inc', 'themekey', 'themekey_build');
  themekey_rebuild();

  return t('Update of ThemeKey ran successfully');
}
