You are here

class views_handler_field_content_multiple in Content Construction Kit (CCK) 6

An extended subclass for field handling that adds multiple field grouping.

Fields that want multiple value grouping options in addition to basic field and formatter handling can extend this class.

Hierarchy

Expanded class hierarchy of views_handler_field_content_multiple

1 string reference to 'views_handler_field_content_multiple'
content_views_field_views_data in includes/content.views.inc

File

includes/content.views.inc, line 339

View source
class views_handler_field_content_multiple extends views_handler_field_content {
  var $defer_query;
  function options(&$options) {
    parent::options($options);
    $field = $this->content_field;
    $options['multiple'] = array(
      'group' => TRUE,
      'multiple_number' => '',
      'multiple_from' => '',
      'multiple_reversed' => FALSE,
    );
  }

  /**
   * Provide 'group multiple values' option.
   */
  function options_form(&$form, &$form_state) {
    parent::options_form($form, $form_state);
    $field = $this->content_field;
    $options = $this->options;
    $form['multiple'] = array(
      '#access' => $field['multiple'],
    );
    $form['multiple']['group'] = array(
      '#title' => t('Group multiple values'),
      '#type' => 'checkbox',
      '#default_value' => $options['multiple']['group'],
    );
    $form['multiple']['multiple_number'] = array(
      '#type' => 'textfield',
      '#size' => 5,
      '#field_prefix' => t('Show') . ' ',
      '#field_suffix' => t(' values,'),
      '#default_value' => $options['multiple']['multiple_number'],
      '#prefix' => '<div class="container-inline">',
    );
    $form['multiple']['multiple_from'] = array(
      '#type' => 'textfield',
      '#size' => 5,
      '#field_prefix' => t('Starting from') . ' ',
      '#default_value' => $options['multiple']['multiple_from'],
    );
    $form['multiple']['multiple_reversed'] = array(
      '#title' => t('Start from last values'),
      '#type' => 'checkbox',
      '#default_value' => $options['multiple']['multiple_reversed'],
      '#suffix' => '</div>',
    );
  }
  function query() {
    $field = $this->content_field;
    $options = $this->options;

    //  if (in_array($field['handler'], array('content_views_field_handler_group', 'content_views_field_handler_first', 'content_views_field_handler_last'))) {
    // TODO : multiple_number / multiple_from
    // We can also optimize the query when only one value should be retrieved
    $this->defer_query = $options['multiple']['group'] && $field['multiple'];

    // If this is not a grouped field, use the generic field handler query.
    if (!$this->defer_query) {
      return parent::query();
    }

    // We don't add anything to the query. The data is retrieved in pre_render()
    // in order to avoid duplicate results.
    $this->field_alias = $this->real_field;

    // If the field is sortable (table sort), we just have to join the table
    // ("Node: Distinct" will be required to avoid duplicates...)
    // if ($field['sortable']) {
    //   $this->ensure_my_table();
    // }
  }
  function pre_render($values) {

    // There are no values to render in a summary view.
    if (isset($this->view->build_info['summary'])) {
      return parent::pre_render($values);
    }

    // If this is not a grouped field, use the parent pre_render().
    if (!$this->defer_query || empty($values)) {
      return parent::pre_render($values);
    }
    $field = $this->content_field;
    $db_info = content_database_info($field);
    $options = $this->options;
    $this->field_values = array();

    // Build the list of nids to retrieve.
    // TODO : try fetching from cache_content first ??
    $nids = array();
    foreach ($values as $value) {
      $nids[] = $value->nid;
    }

    // List columns to retrieve.
    $table_alias = content_views_tablename($field);
    $query_columns = array(
      "{$table_alias}.delta AS delta",
    );
    foreach ($db_info['columns'] as $column => $attributes) {
      $query_columns[] = "{$table_alias}.{$attributes['column']} AS {$column}";
    }

    // Note : this query doesn't need to run through db_rewrite_sql, since the
    // nids we retrieve have been selected by the views query, which already takes
    // care of this.
    $query = "SELECT node.nid, " . implode(', ', $query_columns) . " FROM {node} node" . " LEFT JOIN {" . $db_info['table'] . "} {$table_alias} ON node.vid = {$table_alias}.vid" . " WHERE node.nid IN (" . implode(',', $nids) . ")" . " ORDER BY node.nid ASC, {$table_alias}.delta " . ($options['multiple']['multiple_reversed'] ? 'DESC' : 'ASC');

    // TODO : Select all deltas or only a subset.
    $result = $options['multiple']['multiple_number'] ? db_query_range($query, $options['multiple']['multiple_from'], $options['multiple']['multiple_number']) : db_query($query);
    while ($item = db_fetch_array($result)) {
      $this->field_values[$item['nid']][$item['delta']] = $item;
    }
  }
  function render($values) {

    // If this is not a grouped field, use the parent render().
    if (!$this->defer_query || empty($this->field_values)) {
      return parent::render($values);
    }
    $field = $this->content_field;
    $options = $this->options;

    // $values will be used as a fake $node object;
    // we provide a build_mode for rendering.
    // TODO : we can stick any value in there -
    // what would make most sense ?  row_style ?
    $values->build_mode = 'views';
    $items = array();
    foreach ($this->field_values[$values->{$this->additional_fields['nid']}] as $item) {
      $items[] = content_format($field, $item, $options['format'], $values);
    }
    if (count($items) > 1) {

      // TODO : could we use generic field display ?
      return theme('content_view_multiple_field', $items, $field, $values);
    }
    else {
      return $items[0];
    }
  }

}

Members