You are here

function drush_computed_field_tools_recompute in Computed Field Tools 6

Recompute given computed field.

Parameters

string $field_name: Field name to recompute.

File

./computed_field_tools.drush.inc, line 36
Computed Field Tools module drush integration.

Code

function drush_computed_field_tools_recompute($field_name = '') {
  $field = content_fields($field_name);
  $silent = drush_get_option('silent');
  if (empty($field)) {
    if (!$silent) {
      $computed_fields = computed_field_tools_get_computed_fields_as_options();
      drush_log(dt('Content field not found. Did you mean one of these: @fields', array(
        '@fields' => implode(', ', $computed_fields),
      )), 'error');
      drush_log(dt('F.ex: "drush cft-r @field"', array(
        '@field' => key($computed_fields),
      )), 'error');
    }
    return;
  }
  if ($field['type'] != 'computed') {
    if (!$silent) {
      $computed_fields = computed_field_tools_get_computed_fields_as_options();
      drush_log(dt('Content field not a computed field. Did you mean one of these: @fields', array(
        '@fields' => implode(', ', $computed_fields),
      )), 'error');
      drush_log(dt('F.ex: "drush cft-r @field"', array(
        '@field' => key($computed_fields),
      )), 'error');
    }
    return;
  }

  // Get node types.
  $types = array();
  $result = db_query("\n    SELECT nt.name, nt.type FROM {" . content_instance_tablename() . "} nfi\n    LEFT JOIN {node_type} nt ON nt.type = nfi.type_name\n    WHERE nfi.field_name = '%s'\n    AND nfi.widget_active = 1\n    ORDER BY nt.name ASC", $field['field_name']);
  while ($type = db_fetch_array($result)) {
    $types[] = $type['type'];
  }
  $total_count = db_result(db_query("SELECT COUNT(*) as total_count FROM {node} node\n     WHERE node.type IN (" . db_placeholders($types, 'text') . ") ", $types));
  if (!$silent) {
    drush_log(dt('Recomputing @count nodes...', array(
      '@count' => $total_count,
    )), 'ok');
  }
  $db_info = content_database_info($field);
  $db_table = $db_info['table'];
  $field_db_column_name = $db_info['columns']['value']['column'];
  $field_db_column_type = $db_info['columns']['value']['type'];
  $results = db_query("\n    SELECT n.vid, cf." . $field_db_column_name . " AS existing_value FROM {node} n\n    LEFT JOIN {" . $db_table . "} cf ON cf.vid=n.vid\n    WHERE n.type IN (" . db_placeholders($types, 'text') . ")\n    ORDER BY n.nid ASC", $types);
  $batch_size = 1000;
  $start_time = microtime(TRUE);
  date_default_timezone_set('UTC');

  // Re-compute the given nodes.
  $counter = 1;
  while ($result = db_fetch_object($results)) {
    $node = node_load(array(
      'vid' => $result->vid,
    ));
    $node_field = isset($node->{$field}['field_name']) ? $node->{$field}['field_name'] : array(
      0 => array(
        'value' => NULL,
      ),
    );
    _computed_field_compute_value($node, $field, $node_field);

    // Only store changed values.
    if ($result->existing_value != $node_field[0]['value']) {
      db_query("UPDATE {" . $db_table . "} SET `" . $field_db_column_name . "` = " . db_type_placeholder($field_db_column_type) . " WHERE `vid` = %d", $node_field[0]['value'], $result->vid);
      if (db_affected_rows() < 1) {

        // Entry is not yet created, so lets insert.
        db_query("INSERT INTO {" . $db_table . "} SET `" . $field_db_column_name . "` = " . db_type_placeholder($field_db_column_type) . ", `vid` = %d, `nid` = %d", $node_field[0]['value'], $result->vid, $node->nid);
      }

      // Clear the content cache for the element so that the changes will be
      // visible at once.
      $cid = 'content:' . $node->nid . ':' . $node->vid;
      cache_clear_all($cid, content_cache_tablename());
    }
    if (!$silent && $counter % $batch_size == 0) {
      $estimated_seconds_left = round($total_count * (microtime(TRUE) - $start_time) / $counter);
      $estimated_time_left = date('H:i:s', $estimated_seconds_left);
      drush_log(dt('Recomputed @counter/@total_count. Estimated time left: @time_left', array(
        '@counter' => $counter,
        '@total_count' => $total_count,
        '@time_left' => $estimated_time_left,
      )), 'ok');

      // Prevent memory usage to fill up by static variable in node_load().
      node_load(NULL, NULL, TRUE);
    }
    $counter++;
  }
  if (!$silent) {
    $time_spent = date('H:i:s', round(microtime(TRUE) - $start_time));
    drush_log(dt('Recomputed @total_count fields over @time_spent for @field.', array(
      '@total_count' => $total_count,
      '@time_spent' => $time_spent,
      '@field' => $field_name,
    )), 'ok');
    return;
  }
}