<?php
// $Id: date.install,v 1.4.2.3 2006/10/31 14:00:00 karens Exp $

/**
 * Implementation of hook_install().
 */
function date_install() {
}

function date_update_1() {
  $ret = array();

  switch ($GLOBALS['db_type']) {
    case 'pgsql':
      db_add_column($ret, 'node_field_date_data', 'nid', 'integer', array('not null' => TRUE, 'default' => 0));
      break;

    case 'mysql':
    case 'mysqli':
      $ret[] = update_sql("ALTER TABLE {node_field_date_data} ADD COLUMN nid int(10) NOT NULL DEFAULT 0");
      break;
  }

  return $ret;
}

function date_update_2() {
  // Multi-part update
  if (!isset($_SESSION['date_update_2'])) {
    $_SESSION['date_update_2'] = 0;
    $_SESSION['date_update_2_max'] = db_result(db_query("SELECT COUNT(*) FROM {node_field_date_data}"));;
  }

  $limit = 20;
  $result = db_query_range("SELECT nr.nid, nfdd.vid, nfdd.field_name, nfdd.delta FROM {node_field_date_data} nfdd LEFT JOIN {node_revisions} nr ON nr.vid = nfdd.vid", $_SESSION['date_update_2'], $limit);
  if (db_num_rows($result) == 0) {
    unset($_SESSION['date_update_2']);
    unset($_SESSION['date_update_2_max']);
    return array();
  }
  while ($data = db_fetch_object($result)) {
    $_SESSION['date_update_2']++;
    db_query("UPDATE {node_field_date_data} SET nid = %d WHERE vid = %d AND field_name = '%s' AND delta = %d", $data->nid, $data->vid, $data->field_name, $data->delta);
  }

  return array('#finished' => $_SESSION['date_update_2'] / $_SESSION['date_update_2_max']);
}

/**
 * Data is now stored in per-field tables.
 */
function date_update_3() {
  $ret = array();

  include_once(drupal_get_path('module', 'content') .'/content.module');
  include_once(drupal_get_path('module', 'content') .'/content_admin.inc');

  $fields = content_fields();

  foreach ($fields as $field) {
    switch ($field['type']) {
      case 'date':
        $columns = array(
          'value' => array('type' => 'varchar', 'length' => 17, 'not null' => TRUE, 'default' => "'00010101T00:00:00'"),
        );
        content_alter_db_field(array(), array(), $field, $columns);
        if ($field['multiple']) {
          $ret[] = update_sql('INSERT INTO {node_data_'. $field['field_name'] .'} (vid, delta, nid, '. $field['field_name'] ."_value) SELECT vid, delta, nid, field_date FROM {node_field_date_data} WHERE field_name = '". $field['field_name'] ."'");
        }
        else {
          $ret[] = update_sql('INSERT INTO {node_data_'. $field['field_name'] .'} (vid, nid, '. $field['field_name'] ."_value) SELECT vid, nid, field_date FROM {node_field_date_data} WHERE field_name = '". $field['field_name'] ."'");
        }
        break;
    }
  }

  $ret[] = update_sql('DROP TABLE {node_field_date_data}');

  db_query('DELETE FROM {cache}');
  return $ret;
}

/**
 * Alter date field size and default value to comply with ISO standards, add timezone field.
 */

// a conditional update, can be rerun if changes didn't get made properly previously

function date_update_4() {
  $ret = array();

  include_once(drupal_get_path('module', 'content') .'/content.module');
  include_once(drupal_get_path('module', 'content') .'/content_admin.inc');

  $fields = content_fields();

  foreach ($fields as $field) {
    switch ($field['type']) {
      case 'date':
        $columns = array(
          'value' => array('type' => 'varchar', 'length' => 20, 'not null' => TRUE, 'default' => "'0001-01-01T00:00:00'"),
          'timezone' => array('type' => 'varchar', 'length' => 50, 'not null' => TRUE, 'default' => "'GMT'"),
        );
        $db_info = content_database_info($field);
        if ($db_info['columns']['value']['default'] != "'0001-01-01T00:00:00'") {
          content_alter_db_field(array(), array(), $field, $columns);
        }
        $id = $field['field_name']. '_value';
        $ret[] = update_sql("UPDATE {". $db_info['table'] ."} SET $id = CONCAT(SUBSTRING($id,1,4), '-', SUBSTRING($id,5,2), '-', SUBSTRING($id,7)) WHERE SUBSTRING($id, 5, 1) <> '-'");
    }
  }
  db_query('DELETE FROM {cache}');
  return $ret;
}

// adds in potential for empty dates by allowing date and timezone values to be null
// add column for timezone offset -- needed for views integration with dates that have date-specific zones

function date_update_5() {
  $ret = array();
  
  include_once(drupal_get_path('module', 'content') .'/content.module');
  include_once(drupal_get_path('module', 'content') .'/content_admin.inc');
  include_once(drupal_get_path('module', 'date') .'/date.module');

  $fields = content_fields();
  foreach ($fields as $field) {
    
    $db_info = content_database_info($field);
    $table = $db_info['table'];
    $columns_v4 = date_columns($field, 4);
    $columns_v5 = date_columns($field, 5);

    // update the table columns and their default values
    if (($field['type'] == 'date' || $field['type'] == 'datestamp') && variable_get('date_version', 4) < 5) {
      $db_info = content_database_info($field);
      content_alter_db_field($field, $columns_v4, $field, $columns_v5);
      $id     = $field['field_name']. '_value';
      $tz_id  = $field['field_name']. '_timezone';
      $offset = $field['field_name']. '_offset';
    }
    // reset not required values that were previously set to the default to null
    // using a range of values because timezone conversions might have altered the default by up to 24 hours
    switch ($field['type']) {
      case 'date':
        if (!$field['required'] && ($columns_v4['value']['default'] == "'0001-01-01T00:00:00'" || $columns_v4['value']['not null'])) {
          if ($field['tz_handling'] != 'date') {
            $ret[] = update_sql("UPDATE {$table} SET $id = NULL WHERE $id <= '0001-01-01T23:59:59'");
          }
          else {
            $ret[] = update_sql("UPDATE {$table} SET $id = NULL, $tz_id = NULL, $offset = NULL WHERE $id <= '0001-01-01T23:59:59'");
          }
        }
        break;
      case 'datestamp':
        if (!$field['required'] && ($columns_v4['value']['default'] == 0 || $columns_v4['value']['not null'])) {
          if ($field['tz_handling'] != 'date') {
            $ret[] = update_sql("UPDATE {$table} SET $id = NULL WHERE $id > -86399 AND $id <= 86399");
          }
          else {
            $ret[] = update_sql("UPDATE {$table} SET $id = NULL, $tz_id = NULL, $offset = NULL WHERE $id > -86399 AND $id <= 86399");
          }
        }
        break;
    }
  }
  drupal_set_message(t('Date module fields were updated to allow empty (NULL) values. Existing date fields with default values were reset to NULL.'));
  db_query('DELETE FROM {cache}');
  variable_set('date_version', 5);
  return $ret;
}

// update existing date-specific timezone fields with their offset values
// a conditional update, can be rerun if changes didn't get made properly previously

function date_update_6() {
  $ret = array();

  include_once(drupal_get_path('module', 'content') .'/content.module');
  include_once(drupal_get_path('module', 'content') .'/content_admin.inc');

  $fields = content_fields();
  
  // See if being called for the first time
  if (!isset($_SESSION['date_update_5'])) {
    // find all tables that have date-specific timezone handling
    $update = array();
    foreach ($fields as $field) {
      $db_info = content_database_info($field);
      if ($field['tz_handling'] && ($field['type'] == 'date' || $field['type'] == 'datestamp')) {
        $update[$db_info['table']] = $field;
      }
    }
    // keep track of progress
    $_SESSION['date_update_5']['tables'] = $update;
    $_SESSION['date_update_5']['counted'] = 0;
    foreach ($update as $table => $field) {
      $_SESSION['date_update_5'][$table]['nid']   = 0;
      $_SESSION['date_update_5'][$table]['to_count'] = db_result(db_query("SELECT COUNT(nid) FROM  {$table}"));
      $_SESSION['date_update_5']['count_total'] += $_SESSION['date_update_5'][$table]['to_count'];
    }
  }
  $update = $_SESSION['date_update_5']['tables'];
  foreach ($update as $table => $field) {
    // Fetch the next 20 nodes
    $results = db_query_range("SELECT * FROM {$table} WHERE nid > %d ORDER BY nid", $_SESSION['date_update_5'][$table]['nid'], 0, 20);
    while ($arr = db_fetch_array($results)) {
      $node = node_load($arr['nid']);
      foreach ((array) $node->$field['field_name'] as $delta => $field_part) {
        $date = date_make_date($field_part['value'], 'GMT', 'db', ($field['type'] == 'date' ? DATE_ISO : DATE_UNIX));
        date_convert_timezone($date, 'GMT', $field_part['timezone'], 'local');
        $add[$delta]['value']    = $field_part['value'];
        $add[$delta]['timezone'] = $field['required'] || $field_part['value'] ? $field_part['timezone'] : NULL;
        $add[$delta]['offset']   = $field['required'] || $field_part['value'] ? $date->local->offset : NULL;
      }
      $node->$field['field_name'] = $add;
      node_save($node);
      // reset nid
      $_SESSION['date_update_5'][$table]['nid'] = $node->nid;
      // add to count total
      $_SESSION['date_update_5']['counted']++;
      // reduce the number of items in this table left to count
      $_SESSION['date_update_5'][$table]['to_count']--;
    }

    // if everything in this table has been done, move to next table
    if ($_SESSION['date_update_5'][$table]['to_count'] < 1) {
      array_shift($_SESSION['date_update_5']['tables']);
    }

    // See if we are done
    if ($_SESSION['date_update_5']['count'] && $_SESSION['date_update_5']['counted'] < $_SESSION['date_update_5']['count_total']) {
      // Not done yet. Return the progress.
      return array('#finished' => $_SESSION['date_update_5']['counted'] / $_SESSION['date_update_5']['count']);
    }
    else {
      // Done. Clean up and indicate we're finished.
      unset($_SESSION['date_update_5']);

      drupal_set_message(t('Date module timezone-specific fields were updated to add offset values.'));
      db_query('DELETE FROM {cache}');
      variable_set('date_version', 6);

      return array('#finished' => 1);
    }
  }
}
