$db_info['table'], 'left_field' => 'vid', 'field' => 'vid', ); $columns = array(); $arguments = array(); $filters = array(); foreach ($db_info['columns'] as $column => $attributes) { $columns[] = $attributes['column']; $sorts[] = !empty($attributes['sortable']) ? TRUE : FALSE; // Identify likely filters and arguments for each column based on field type. switch ($attributes['type']) { case 'numeric': case 'int': case 'mediumint': case 'tinyint': case 'bigint': case 'serial': case 'float': $filters[] = 'views_handler_filter_numeric_content'; $arguments[] = 'views_handler_argument_content'; break; default: $filters[] = 'views_handler_filter_string_content'; $arguments[] = 'views_handler_argument_string_content'; break; } } $data[$columns[0]] = array( 'group' => t($field_types[$field['type']]['label']), 'title' => t($field['widget']['label']) .' ('. $field['field_name'] .')', 'help' => t($field_types[$field['type']]['label']) .' - '. t('Appears in : @types', array('@types' => implode(', ', $types))), 'field' => array( 'field' => $columns[0], 'tablename' => $db_info['table'], 'handler' => 'views_handler_field_content_multiple', 'click sortable' => $sorts[0], 'additional fields' => $columns, 'content_field_name' => $field['field_name'], 'allow_empty' => TRUE, ), 'argument' => array( 'field' => $columns[0], 'tablename' => $db_info['table'], 'handler' => $arguments[0], 'name field' => '', // TODO 'additional fields' => $columns, 'content_field_name' => $field['field_name'], 'allow_empty' => TRUE, ), 'filter' => array( 'field' => $columns[0], 'title' => t($field['widget']['label']), 'tablename' => $db_info['table'], 'handler' => $filters[0], 'additional fields' => $columns, 'content_field_name' => $field['field_name'], 'allow_empty' => TRUE, ), ); // TODO do we need different handling for sorts with Views 2, // especially when relationships are involved? if (!empty($sorts[0])) { $data[$columns[0]]['sort'] = array( 'field' => $columns[0], 'tablename' => $db_info['table'], 'handler' => 'views_handler_sort_content', 'additional fields' => $columns, 'content_field_name' => $field['field_name'], 'allow_empty' => TRUE, ); } // TODO : provide automatic filters, sorts, and arguments for each column, not just the first? return array($table_alias => $data); } } /** * The subclass simply adds properties, * for field-specific subclasses to use if they need to. */ class views_handler_filter_string_content extends views_handler_filter_string { var $content_field; function construct() { parent::construct(); $this->content_field = content_fields($this->definition['content_field_name']); $this->additional_fields = $this->definition['additional fields']; } } /** * The subclass simply adds properties, * for field-specific subclasses to use if they need to. */ class views_handler_filter_numeric_content extends views_handler_filter_numeric { var $content_field; function construct() { parent::construct(); $this->content_field = content_fields($this->definition['content_field_name']); $this->additional_fields = $this->definition['additional fields']; } } /** * The subclass simply adds properties, * for field-specific subclasses to use if they need to. */ class views_handler_filter_many_to_one_content extends views_handler_filter_many_to_one { var $content_field; function construct() { parent::construct(); $this->content_field = content_fields($this->definition['content_field_name']); $this->additional_fields = $this->definition['additional fields']; $field = $this->content_field; $this->value_title = $field['widget']['label']; $this->value_options = $this->allowed_values(); } // Get allowed values from hook_allowed_values(), if any, // or from content_allowed_values(); function allowed_values() { $field = $this->content_field; $function = $field['module'] .'_allowed_values'; $options = function_exists($function) ? $function($field) : content_allowed_values($field); return (array) $options; } } /** * The subclass simply adds properties, * for field-specific subclasses to use if they need to. */ class views_handler_sort_content extends views_handler_sort { var $content_field; function construct() { parent::construct(); $this->content_field = content_fields($this->definition['content_field_name']); $this->additional_fields = $this->definition['additional fields']; } } /** * The subclass simply adds properties, * for field-specific subclasses to use if they need to. */ class views_handler_argument_content extends views_handler_argument { var $content_field; function construct() { parent::construct(); $this->content_field = content_fields($this->definition['content_field_name']); $this->additional_fields = $this->definition['additional fields']; } } /** * The subclass simply adds properties, * for field-specific subclasses to use if they need to. */ class views_handler_argument_string_content extends views_handler_argument_string { var $content_field; function construct() { parent::construct(); $this->content_field = content_fields($this->definition['content_field_name']); $this->additional_fields = $this->definition['additional fields']; } } /** * The subclass adds basic field and formatter info, * for field-specific subclasses to use if they need to. * * Fields could extend this class if they want field and formatter handling * but don't want the multiple value grouping options created by * views_handler_field_content_multiple. */ class views_handler_field_content extends views_handler_field_node { var $content_field; function construct() { parent::construct(); $this->content_field = content_fields($this->definition['content_field_name']); } /** * This provides a method of controlling field-level access in Views. */ function access() { // Avoid FALSE returns for non-existant hooks by using module_implements() // to check only modules that implement the hook. $modules = module_implements('content_views_access'); foreach ($modules as $module) { if (module_invoke($module, 'content_views_access', $this->definition['content_field_name']) === FALSE) { return FALSE; } } return parent::access(); } function options(&$options) { parent::options($options); $field = $this->content_field; // Override views_handler_field_node's default label $options['label'] = $field['widget']['label']; $options['format'] = 'default'; } /** * Provide formatter option. */ function options_form(&$form, &$form_state) { parent::options_form($form, $form_state); // TODO : do we want the 'link to node' checkbox ? // That's usually formatters business... $field = $this->content_field; $options = $this->options; $field_types = _content_field_types(); $formatters = array(); if (is_array($field_types[$field['type']]['formatters'])) { foreach ($field_types[$field['type']]['formatters'] as $name => $info) { $formatters[$name] = t($info['label']); } } $form['format'] = array( '#title' => t('Format'), '#type' => 'select', '#options' => $formatters, '#required' => TRUE, '#default_value' => $options['format'], ); } function options_validate($form, &$form_state) { } /** * Provide text for the administrative summary */ function admin_summary() { // Display the formatter name. $field = $this->content_field; $field_types = _content_field_types(); if (isset($field_types[$field['type']]['formatters'][$this->options['format']])) { return t($field_types[$field['type']]['formatters'][$this->options['format']]['label']); } } function render($values) { $field = $this->content_field; $options = $this->options; $db_info = content_database_info($field); // $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'; $item = array(); foreach ($db_info['columns'] as $column => $attributes) { $item[$column] = $values->{$this->table_alias .'_'. $attributes['column']}; } return content_format($field, $item, $options['format'], $values); } } /** * 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. */ 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' => '