You are here

date.install in Date 5.2

Same filename and directory in other branches
  1. 6.2 date/date.install
  2. 6 date/date.install

File

date/date.install
View source
<?php

function date_install_clear() {
  cache_clear_all('date_', 'cache', '*');
  if (db_table_exists('cache_views')) {
    cache_clear_all('date_browser_views', 'cache_views');
  }
  drupal_load('module', 'content');
  content_clear_type_cache();
}

/**
 * Implementation of hook_install().
 */

/**
 * Implementation of hook_install().
 * Reset the date caches.
 */
function date_install() {
  date_install_clear();
}

/**
 * Implementation of hook_uninstall().
 *
 */
function date_uninstall() {
  date_install_clear();
}

/**
 * Implementation of hook_enable().
 * Reset the calendar caches.
 */
function date_enable() {
  date_install_clear();
}

/**
 * Implementation of hook_disable().
 * Empty the date caches.
 */
function date_disable() {
  date_install_clear();
}
function date_update_1() {
  $ret = array();
  if (!db_table_exists('node_field_date_data')) {
    return $ret;
  }
  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() {
  $ret = array();
  if (!db_table_exists('node_field_date_data')) {
    return $ret;
  }

  // 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();
  if (!db_table_exists('node_field_date_data')) {
    return $ret;
  }
  drupal_load('module', 'content');
  content_clear_type_cache();
  $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'",
          ),
        );

        // the following line will trigger (negligible) warnings if content_update_3 was run before
        // (column already exists)
        @content_alter_db_field(array(), array(), $field, $columns);
        $db_info = content_database_info($field);
        $table = $db_info['table'];
        if ($field['multiple']) {
          $ret[] = update_sql('INSERT INTO {' . $table . '} (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 {' . $table . '} (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();
  drupal_load('module', 'content');
  content_clear_type_cache();
  $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
// Superceded by update 5102, so skip this step and do it then.
function date_update_5() {
  $ret = array();
  return $ret;
}

/**
 * Update existing date-specific timezone fields with their offset values
 * Superceded by update 5103, so just skip this step and do it then.
 */
function date_update_6() {
  $ret = array();
  return $ret;
}

/**
 *  Update 7
 *
 *  Force all columns to allow NULL values to simplify the module.
 *  Previously only non-required fields allowed NULL values.
 *  Superceded by update 5102, so skipt this step and do it them.
 */
function date_update_7() {
  $ret = array();
  return $ret;
}

/**
 * Prepare for Version 5.2 updates, make changes to field and widget settings.
 */
function date_update_5100() {
  $ret = array();
  drupal_load('module', 'content');
  $fields = content_fields();
  foreach ($fields as $field) {
    if (strstr($field['type'], 'date')) {
      $field_settings = unserialize(db_result(db_query("SELECT global_settings from {node_field} where field_name = '%s'", $field['field_name'])));
      $widget_settings = unserialize(db_result(db_query("SELECT widget_settings from {node_field_instance} where field_name = '%s'", $field['field_name'])));

      // Move input format from field settings to widget settings, where it should have been all along.
      $input_format = $field_settings['input_format'];
      $input_format_custom = $field_settings['input_format_custom'];
      $widget_settings['input_format'] = $input_format;
      $widget_settings['input_format_custom'] = $input_format_custom;

      // New PHP 5 date handling will handle timezone formats correctly, so
      // add timezone formats to format string and drop old setting for tracking zones.
      $replace = array(
        '0000' => 'O',
        '00:00' => 'P',
        'name' => 'e',
        '' => '',
      );
      if (!empty($field_settings['output_format_zone'])) {
        $field_settings['output_format_date'] .= ' ' . $replace[$field_settings['output_format_zone']];
        if (!empty($field_settings['output_format_custom'])) {
          $field_settings['output_format_custom'] .= ' ' . $replace[$field_settings['output_format_zone']];
        }
      }
      if (!empty($field_settings['output_format_zone_short'])) {
        $field_settings['output_format_date_short'] .= ' ' . $replace[$field_settings['output_format_zone_short']];
        if (!empty($field_settings['output_format_custom_short'])) {
          $field_settings['output_format_custom_short'] .= ' ' . $replace[$field_settings['output_format_zone_short']];
        }
      }
      if (!empty($field_settings['output_format_zone_medium'])) {
        $field_settings['output_format_date_medium'] .= ' ' . $replace[$field_settings['output_format_zone_medium']];
        if (!empty($field_settings['output_format_custom_medium'])) {
          $field_settings['output_format_custom_medium'] .= ' ' . $replace[$field_settings['output_format_zone_medium']];
        }
      }
      if (!empty($field_settings['output_format_zone_long'])) {
        $field_settings['output_format_date_long'] .= ' ' . $replace[$field_settings['output_format_zone_long']];
        if (!empty($field_settings['output_format_custom_long'])) {
          $field_settings['output_format_custom_long'] .= ' ' . $replace[$field_settings['output_format_zone_long']];
        }
      }

      // Add new timezone_db setting.
      // For now this is fixed at 'UTC', but it provides a method to store a different timezone in the future.
      $field_settings['timezone_db'] = 'UTC';

      // Change select_year, select_month, select_day to array of text_parts and add to widget settings.
      $text_parts = array();
      if (isset($widget_settings['select_year']) && empty($widget_settings['select_year'])) {
        $text_parts[] = 'year';
      }
      if (isset($widget_settings['select_month']) && empty($widget_settings['select_month'])) {
        $text_parts[] = 'mon';
      }
      if (isset($widget_settings['select_day']) && empty($widget_settings['select_day'])) {
        $text_parts[] = 'mday';
      }
      $widget_settings['text_parts'] = $text_parts;

      // Combine years_back and years_forward into single year_range
      $widget_settings['year_range'] = '-' . intval(isset($widget_settings['years_back']) ? $widget_settings['years_back'] : 3) . ':+' . intval(isset($widget_settings['years_forward']) ? $widget_settings['years_forward'] : 3);

      // Clean up settings by removing all that are not valid.
      $fields = array(
        'granularity',
        'field_timezone',
        'timezone_db',
        'tz_handling',
        'todate',
        'output_format_date',
        'output_format_date_short',
        'output_format_date_medium',
        'output_format_date_long',
        'output_format_custom',
        'output_format_custom_short',
        'output_format_custom_medium',
        'output_format_custom_long',
      );
      foreach (array_keys($field_settings) as $setting) {
        if (!in_array($setting, $fields)) {
          unset($field_settings[$setting]);
        }
      }
      $widgets = array(
        'default_value',
        'default_value_custom',
        'default_value2',
        'default_value_custom2',
        'input_format',
        'input_format_custom',
        'increment',
        'text_parts',
        'year_range',
      );
      foreach (array_keys($widget_settings) as $setting) {
        if (!in_array($setting, $widgets)) {
          unset($widget_settings[$setting]);
        }
      }

      // Save the new settings. Use db_query instead of update_sql to get proper handling for serialized array and
      // because the query must be run immediately so we can rebuild the cache.
      db_query("UPDATE {node_field} SET global_settings = '%s' WHERE field_name='%s'", serialize($field_settings), $field['field_name']);
      db_query("UPDATE {node_field_instance} SET widget_settings = '%s' WHERE field_name='%s'", serialize($widget_settings), $field['field_name']);
      $ret[] = array(
        'success' => TRUE,
        'query' => 'field settings updated to ' . serialize($field_settings) . '<br />widget settings updated to ' . serialize($widget_settings),
      );
    }
  }

  // Rebuild the cache.
  content_clear_type_cache();
  return $ret;
}

/**
 * Date offsets were not getting saved. Need to repair the database.
 * Superceded by update 5103().
 */
function date_update_5101() {
  $ret = array();
  return $ret;
}

/**
 * Make sure date module loads after date_api.
 */
function date_update_5102() {
  variable_del('date_version');
  $ret[] = update_sql("UPDATE {system} SET weight = 1 WHERE name = 'date'");
  return date_db_integrity('5103');
}

/**
 * Data integrity update, moved to Version 2 because it can make
 * lots of db changes and we want people to be prepared for a
 * significant change.
 */
function date_update_5103() {
  $ret = array();
  return $ret;
}

/**
 * Move these caches from 'cache' to 'cache_views' so they get cleared
 * automatically whenever views_invalidate_cache() is called.
 */
function date_update_5104() {
  $ret = array();
  cache_clear_all('date_browser_views', 'cache');
  return $ret;
}

/**
 * Version 5.2 updates.
 */
function date_update_5200() {
  $ret = array();
  module_enable(array(
    'date_timezone',
  ));

  // Make sure date module loads after date_api.
  $ret[] = update_sql("UPDATE {system} SET weight = 1 WHERE name = 'date'");

  // No longer using the cached formats.
  cache_clear_all('date_formats', 'cache', TRUE);
  drupal_load('module', 'content');

  // Granularity names have been changed to conform with keys used in date arrays.
  $replace = array(
    'Y' => 'year',
    'M' => 'month',
    'D' => 'day',
    'H' => 'hour',
    'N' => 'minute',
    'S' => 'second',
  );
  $fields = content_fields();
  foreach ($fields as $field) {
    if (strstr($field['type'], 'date')) {
      $field_settings = unserialize(db_result(db_query("SELECT global_settings from {node_field} where field_name = '%s'", $field['field_name'])));
      $granularity = array();
      foreach ((array) $field_settings['granularity'] as $item) {
        $granularity[] = strtr($item, $replace);
      }
      $field_settings['granularity'] = $granularity;

      // Save the new settings.
      db_query("UPDATE {node_field} SET global_settings = '%s' WHERE field_name='%s'", serialize($field_settings), $field['field_name']);
    }
  }
  date_install_clear();
  content_clear_type_cache();
  return $ret;
}

/**
 * The original code was not working right, repeat this in update_5207.
 *
 * @return unknown
 */
function date_update_5201() {
  $ret = array();
  return $ret;
}

/**
 * Database integrity update, supercedes most previous data integrity updates.
 */
function date_update_5202() {
  return date_db_integrity('5202');
}

/**
 * Data integrity update, supercedes most previous data integrity updates.
 */
function date_update_5203() {

  //return date_data_integrity('5203');
  $ret = array();
  return $ret;
}

/**
 * Get rid of deprecated timezone names.
 */
function date_update_5204() {
  $ret = array();
  drupal_load('module', 'content');
  $fields = content_fields();
  foreach ($fields as $field) {
    if (($field['type'] == 'date' || $field['type'] == 'datestamp') && $field['tz_handling'] == 'date') {
      $db_info = content_database_info($field);
      $table = $db_info['table'];
      $column = $db_info['columns']['timezone']['column'];
      $results = db_query("SELECT DISTINCT {$column} FROM {$table} ORDER BY {$column}");
      while ($row = db_fetch_object($results)) {
        if (!empty($row->timezone_name)) {
          $new = date_timezone_replacement($row->timezone_name);
          if (!empty($new) && $new != $old) {
            db_query("UPDATE {$table} SET {$column} = '%s' WHERE {$column} = '%s'", $new, $row->timezone_name);
          }
        }
      }
    }
  }
  return $ret;
}
function date_update_5205() {
  $ret = array();
  drupal_load('module', 'content');
  $fields = content_fields();
  foreach ($fields as $field) {
    if (strstr($field['type'], 'date')) {
      $field_settings = unserialize(db_result(db_query("SELECT global_settings from {node_field} where field_name = '%s'", $field['field_name'])));
      foreach ($field_settings as $key => $value) {
        if ($key == 'tz_handling' && $value == 'gmt') {
          $field_settings[$key] = 'utc';
        }
      }
      db_query("UPDATE {node_field} SET global_settings = '%s' WHERE field_name = '%s'", serialize($field_settings), $field['field_name']);
    }
  }
  return $ret;
}

/**
 * Granularity options were not saved correctly by CCK if created using checkboxes.
 * Checkboxes have been changed back to a select and we need to fix the values
 * stored in the settings.
 * 
 * The bad values would have been stored in the form
 *   array(
 *     'year' => 'year'
 *     'month' => 'month',
 *     'day' => 0,
 *     'hour' => 0,
 *     'minute' => 0,
 *     'second' => 0,
 *   );
 * 
 * Good values would have been stored in the form
 *   array(
 *     'year' => 'year',
 *     'month' => 'month',
 *   );
 *
 * @return unknown
 */
function date_update_5206() {
  $ret = array();
  $result = db_query("SELECT field_name, global_settings from {node_field} where type LIKE 'date_%'");
  while ($field = db_fetch_array($result)) {

    // Change the format to one date_popup can use.
    $field_settings = unserialize($field['global_settings']);
    $granularity = array_filter($field_settings['granularity']);
    $field_settings['granularity'] = $granularity;
    db_query("UPDATE {node_field} SET global_settings = '%s' WHERE field_name = '%s'", serialize($field_settings), $field['field_name']);
  }
  date_install_clear();
  return $ret;
}

/**
 * Get rid of jscalendar popup widget.
 * Originally update_5201, but that was broken.
 */
function date_update_5207() {
  drupal_load('module', 'content');
  $ret = array();
  if (db_result(db_query("SELECT COUNT(*) FROM {node_field_instance} WHERE widget_type = 'date_js'"))) {
    $replace = module_exists('date_popup') ? 'date_popup' : 'date_text';
    $result = db_query("SELECT field_name, type_name, widget_type from {node_field_instance} where widget_type = 'date_js'");
    while ($widget = db_fetch_array($result)) {
      db_query("UPDATE {node_field_instance} SET widget_type = '{$replace}' WHERE field_name = '%s' AND type_name = '%s'", $widget['field_name'], $widget['type_name']);
    }
    drupal_set_message(t('All date fields using the jscalendar widget have been changed to use the text widget instead, since the jscalendar widget is no longer supported. Enable the Date Popup module to make a jQuery popup calendar available and edit the field settings to select it.'));
    content_clear_type_cache();
  }
  return $ret;
}

/**
 * Swap out the generic Content field handlers for the new
 * date field handlers.
 */
function date_update_5208() {
  $ret = array();
  if (!module_exists('views')) {
    return $ret;
  }
  drupal_load('module', 'views');
  views_load_cache();
  $view_fields = _views_get_fields();
  $date_types = array(
    DATE_ISO,
    DATE_UNIX,
  );
  foreach ($view_fields as $name => $view_field) {
    if (isset($view_field['content_field']) && in_array($view_field['content_field']['type'], $date_types)) {
      $bits = explode('.', $name);
      $sql = "UPDATE {view_tablefield} SET handler = REPLACE(handler, 'content_views_field_handler_', 'date_views_field_handler_') WHERE tablename = '%s' AND field = '%s'";
      db_query($sql, $bits[0], $bits[1]);
    }
  }
  cache_clear_all('*', 'cache_views', true);
  return $ret;
}

/**
 * Update all repeating date delta values with the RRULE
 * so we can use that info in Views when we pull individual items
 * out in a query.
 */
function date_update_5209() {
  $ret = array();
  drupal_load('module', 'content');
  $fields = content_fields();
  foreach ($fields as $field) {
    if (strstr($field['type'], 'date') && !empty($field['repeat'])) {
      $db_info = content_database_info($field);
      $table = $db_info['table'];
      $column = $field['field_name'] . '_rrule';
      $result = db_query("SELECT DISTINCT nid, vid, {$column} FROM {" . $table . "} WHERE {$column} <> ''");
      while ($row = db_fetch_array($result)) {
        $ret[] = update_sql("UPDATE {" . $table . "} SET {$column}='" . $row[$column] . "' WHERE nid=" . $row['nid'] . " AND vid=" . $row['vid']);
      }
    }
  }
  return $ret;
}

/**
 * Empty the stored db for timezones that use timezone 'none'.
 */
function date_update_5210() {
  $ret = array();
  drupal_load('module', 'content');
  $fields = content_fields();
  foreach ($fields as $field) {
    if (strstr($field['type'], 'date') && !empty($field['tz_handling']) && $field['tz_handling'] == 'none') {
      $row = db_result(db_query("SELECT global_settings FROM {node_field} WHERE field_name='" . $field['field_name'] . "'"));
      $settings = unserialize($row);
      $settings['timezone_db'] = '';
      $settings = serialize($settings);
      db_query("UPDATE {node_field} SET global_settings='%s' WHERE field_name='%s'", $settings, $field['field_name']);
    }
  }
  drupal_set_message(t("The database has been updated to correct the stored timezone for fields using timezone 'none'."));
  content_clear_type_cache();
  return $ret;
}

/**
 * See if a table column already exists.
 */
function date_column_exists($table, $column) {
  global $db_type;
  switch ($db_type) {
    case 'mysql':
    case 'mysqli':
      return (bool) db_fetch_object(db_query("SHOW COLUMNS FROM {" . db_escape_table($table) . "} LIKE '" . db_escape_table($column) . "'"));
    case 'postgres':
      return (bool) db_result(db_query("SELECT COUNT(pg_attribute.attname) FROM pg_class, pg_attribute WHERE pg_attribute.attrelid = pg_class.oid AND pg_class.relname = '{" . db_escape_table($table) . "}' AND attname = '" . db_escape_table($column) . "'"));
  }
}
function date_db_integrity($name) {
  $ret = array();
  drupal_load('module', 'content');
  require_once './' . drupal_get_path('module', 'content') . '/content_admin.inc';
  $fields = content_fields();
  foreach ($fields as $field) {
    $db_info = content_database_info($field);
    if ($field['type'] == 'date' || $field['type'] == 'datestamp') {
      $table = $db_info['table'];

      // start with the new column patterns.
      $columns_start = $db_info['columns'];
      $columns_end = $db_info['columns'];

      // alter the start column values to invalid or empty
      // values to force the new columns to be reset.
      $columns_start['value']['length'] = 90;
      if ($field['todate']) {
        if (!date_column_exists($table, $columns_start['value2']['column'])) {
          unset($columns_start['value2']);
        }
        else {
          $columns_start['value2']['length'] = 80;
        }
      }
      if ($field['tz_handling'] == 'date') {
        if (!date_column_exists($table, $columns_start['timezone']['column'])) {
          unset($columns_start['timezone']);
        }
        else {
          $columns_start['timezone']['length'] = 80;
        }
        if (!date_column_exists($table, $columns_start['offset']['column'])) {
          unset($columns_start['offset']);
        }
        else {
          $columns_start['offset']['length'] = 80;
        }
        if ($field['todate']) {
          if (!date_column_exists($table, $columns_start['offset2']['column'])) {
            unset($columns_start['offset2']);
          }
          else {
            $columns_start['offset2']['length'] = 80;
          }
        }
      }
      if ($field['repeat'] == 1) {
        if (!date_column_exists($table, $columns_start['rrule']['column'])) {
          unset($columns_start['rrule']);
        }
        else {
          $columns_start['rrule']['length'] = 80;
        }
      }
      content_alter_db_field($field, $columns_start, $field, $columns_end);
      $message = 'Date database integrity check. Updated table ' . $table . ' to set all columns to accept NULL values.';
      $ret[] = array(
        'success' => TRUE,
        'query' => $message,
      );
    }
  }
  content_clear_type_cache();
  return $ret;
}

/**
 *  Progressive update of date information, integrity checking of all date values.
 *
 * @param name - name of the update
 */
function date_data_integrity($name, $force_recalc = FALSE) {

  // Use this to turn extra debugging on or off.
  $debug = TRUE;
  $ret = array();
  drupal_load('module', 'content');
  require_once './' . drupal_get_path('module', 'content') . '/content_admin.inc';

  // See if being called for the first time
  if (!isset($_SESSION[$update_name]) || empty($_SESSION[$update_name]['search'])) {

    // Find all nids that have date fields and store them in an array.
    $tables = array();
    $_SESSION[$update_name]['search'] = array();
    $_SESSION[$update_name]['fields'] = array();
    $fields = content_fields();
    foreach ($fields as $field) {
      if ($field['type'] == 'date' || $field['type'] == 'datestamp') {
        $_SESSION[$update_name]['fields'][$field['field_name']] = $field;
        $db_info = content_database_info($field);
        $tables[] = $db_info['table'];
      }
    }

    // keep track of progress
    $_SESSION[$update_name]['counted'] = 0;
    $tables = array_unique($tables);
    foreach ($tables as $table) {
      $result = db_query("SELECT nid, vid FROM {" . $table . "} ORDER BY nid, vid");
      while ($row = db_fetch_array($result)) {
        $_SESSION[$update_name]['search'][] = $row['nid'] . ':' . $row['vid'];
      }
    }
    sort($_SESSION[$update_name]['search']);
    $_SESSION[$update_name]['search_all'] = $_SESSION[$update_name]['search'];
    $_SESSION[$update_name]['count_total'] = count($_SESSION[$update_name]['search']);
    $_SESSION[$update_name]['counted'] = 0;
  }
  $_SESSION[$update_name]['changed'] = array();
  $_SESSION[$update_name]['unchanged'] = array();

  // Do 5 updates in each pass.
  for ($i = 0; $i <= 5; $i++) {
    $update = !empty($_SESSION[$update_name]['search']) ? array_shift($_SESSION[$update_name]['search']) : array();
    if (!empty($update)) {
      $ids = explode(':', $update);
      $node = node_load($ids[0], $ids[1]);

      // Iterate through all the date fields in this node and re-compute
      // values to make sure they are correct.
      $needs_fix = FALSE;
      foreach ($_SESSION[$update_name]['fields'] as $field_name => $field) {
        $items = (array) $node->{$field_name};
        $add = array();
        foreach ($items as $delta => $item) {

          // Check for non-required fields that still have the old default values and make them NULL.
          if ($field['type'] == 'date' && !$field['required'] && (substr($item['value'], 0, 10) == '0000-00-00' || substr($item['value'], 0, 10) == '0001-00-00')) {
            $item['value'] = NULL;
            $needs_fix = TRUE;
          }
          if ($field['type'] == 'datestamp' && !$field['required'] && empty($item['value'])) {
            $item['value'] = NULL;
            $needs_fix = TRUE;
          }
          $add[$delta]['value'] = $item['value'];

          // Check for missing todates.
          if ($field['todate']) {
            if (empty($item['value2']) && !empty($item['value']) || $force_recalc) {
              $needs_fix = TRUE;
            }
            $add[$delta]['value2'] = !empty($item['value2']) ? $item['value2'] : $item['value'];
          }

          // Check for missing timezone and offset information.
          if ($field['tz_handling'] == 'date') {
            if (empty($item['offset']) || empty($item['timezone']) || $force_recalc) {
              $needs_fix = TRUE;
              $timezone = date_get_timezone($field['tz_handling'], $item['timezone']);
              $date = date_make_date($item['value'], 'UTC', $field['type']);
              if (!empty($date) && !empty($timezone)) {
                date_timezone_set($date, timezone_open($timezone));
                $add[$delta]['timezone'] = $field['required'] || $item['value'] ? $timezone : NULL;
                $add[$delta]['offset'] = $field['required'] || $item['value'] ? date_offset_get($date) : NULL;
              }
              $date = date_make_date($item['value2'], 'UTC', $field['type']);
              if (!empty($date) && !empty($timezone)) {
                date_timezone_set($date, timezone_open($timezone));
                $add[$delta]['offset2'] = $field['required'] || $item['value'] ? date_offset_get($date) : NULL;
              }
            }
          }
        }
        if (!empty($add)) {
          $node->{$field_name} = $add;
        }
      }
      $_SESSION[$update_name]['counted']++;
      if ($needs_fix) {

        //node_submit($node);
        node_save($node);
        $_SESSION[$update_name]['changed'][] = $node->nid . ($node->vid != $node->nid ? ':' . $node->vid : '');
      }
      else {
        $_SESSION[$update_name]['unchanged'][] = $node->nid . ($node->vid != $node->nid ? ':' . $node->vid : '');
      }
    }
  }

  // See if we are done
  if ($_SESSION[$update_name]['counted'] && $_SESSION[$update_name]['count_total'] && $_SESSION[$update_name]['counted'] < $_SESSION[$update_name]['count_total']) {

    // Not done yet. Return the progress and a progress debug message.
    $progress = floatval($_SESSION[$update_name]['counted'] / $_SESSION[$update_name]['count_total']);
    if ($debug) {
      $message = 'Date data integrity check. Total nodes checked: ' . $_SESSION[$update_name]['counted'] . '<br />Updated nodes: ' . implode(', ', $_SESSION[$update_name]['changed']) . '<br />Unchanged nodes: ' . implode(', ', $_SESSION[$update_name]['unchanged']);
    }
    if ($debug) {
      return array(
        '#finished' => $progress,
        array(
          'success' => TRUE,
          'query' => $message,
        ),
      );
    }
    else {
      return array(
        '#finished' => $progress,
      );
    }
  }
  else {

    // Done. Clean up and indicate we're finished.
    drupal_set_message(t('All nodes with date fields have been checked.'));
    $message = 'Date data integrity check. Total nodes checked: ' . $_SESSION[$update_name]['counted'];
    if ($debug) {
      $message .= '<br />Updated nodes: ' . implode(', ', $_SESSION[$update_name]['changed']) . '<br />Unchanged nodes: ' . implode(', ', $_SESSION[$update_name]['unchanged']);
    }
    unset($_SESSION[$update_name]);
    content_clear_type_cache();
    db_query('DELETE FROM {cache_content}');
    return array(
      '#finished' => 1,
      array(
        'success' => TRUE,
        'query' => $message,
      ),
    );
  }
}

Functions

Namesort descending Description
date_column_exists See if a table column already exists.
date_data_integrity Progressive update of date information, integrity checking of all date values.
date_db_integrity
date_disable Implementation of hook_disable(). Empty the date caches.
date_enable Implementation of hook_enable(). Reset the calendar caches.
date_install Implementation of hook_install(). Reset the date caches.
date_install_clear
date_uninstall Implementation of hook_uninstall().
date_update_1
date_update_2
date_update_3 Data is now stored in per-field tables.
date_update_4
date_update_5
date_update_5100 Prepare for Version 5.2 updates, make changes to field and widget settings.
date_update_5101 Date offsets were not getting saved. Need to repair the database. Superceded by update 5103().
date_update_5102 Make sure date module loads after date_api.
date_update_5103 Data integrity update, moved to Version 2 because it can make lots of db changes and we want people to be prepared for a significant change.
date_update_5104 Move these caches from 'cache' to 'cache_views' so they get cleared automatically whenever views_invalidate_cache() is called.
date_update_5200 Version 5.2 updates.
date_update_5201 The original code was not working right, repeat this in update_5207.
date_update_5202 Database integrity update, supercedes most previous data integrity updates.
date_update_5203 Data integrity update, supercedes most previous data integrity updates.
date_update_5204 Get rid of deprecated timezone names.
date_update_5205
date_update_5206 Granularity options were not saved correctly by CCK if created using checkboxes. Checkboxes have been changed back to a select and we need to fix the values stored in the settings.
date_update_5207 Get rid of jscalendar popup widget. Originally update_5201, but that was broken.
date_update_5208 Swap out the generic Content field handlers for the new date field handlers.
date_update_5209 Update all repeating date delta values with the RRULE so we can use that info in Views when we pull individual items out in a query.
date_update_5210 Empty the stored db for timezones that use timezone 'none'.
date_update_6 Update existing date-specific timezone fields with their offset values Superceded by update 5103, so just skip this step and do it then.
date_update_7 Update 7