class views_plugin_style extends views_plugin {
var $row_tokens = array();
var $row_plugin;
function init(&$view, &$display, $options = NULL) {
$this->view = &$view;
$this->display = &$display;
$this->unpack_options($this->options, isset($options) ? $options : $display->handler->get_option('style_options'));
if ($this->uses_row_plugin() && $display->handler->get_option('row_plugin')) {
$this->row_plugin = $display->handler->get_plugin('row');
}
$this->options += array(
'grouping' => array(),
);
$this->definition += array(
'uses grouping' => TRUE,
);
}
function destroy() {
parent::destroy();
if (isset($this->row_plugin)) {
$this->row_plugin->destroy();
}
}
function uses_row_plugin() {
return !empty($this->definition['uses row plugin']);
}
function uses_row_class() {
return !empty($this->definition['uses row class']);
}
function uses_fields() {
$row_uses_fields = FALSE;
if ($this->uses_row_plugin() && !empty($this->row_plugin)) {
$row_uses_fields = $this->row_plugin->uses_fields();
}
return $row_uses_fields || !empty($this->definition['uses fields']) || !empty($this->options['uses_fields']);
}
function uses_tokens() {
if ($this->uses_row_class()) {
$class = $this->options['row_class'];
if (strpos($class, '[') !== FALSE || strpos($class, '!') !== FALSE || strpos($class, '%') !== FALSE) {
return TRUE;
}
}
}
function get_row_class($row_index) {
if ($this->uses_row_class() && $this->options['row_class']) {
$has_tokens = FALSE;
if ($this->uses_fields() && $this->view->field) {
$has_tokens = TRUE;
}
$classes = explode(' ', $this->options['row_class']);
foreach ($classes as &$class) {
if ($has_tokens) {
$class = _views_tokenized_clean_css_identifier($class, $this, $row_index);
}
else {
$class = backdrop_clean_css_identifier($class, array());
}
}
return implode(' ', $classes);
}
}
function tokenize_value($value, $row_index) {
if (strpos($value, '[') !== FALSE || strpos($value, '!') !== FALSE || strpos($value, '%') !== FALSE) {
$fake_item = array(
'alter_text' => TRUE,
'text' => $value,
);
$tokens = isset($this->row_tokens[$row_index]) ? $this->row_tokens[$row_index] : array();
if (!empty($this->view->build_info['substitutions'])) {
$tokens += $this->view->build_info['substitutions'];
}
if ($tokens) {
$value = strtr($value, $tokens);
}
}
return $value;
}
function even_empty() {
return !empty($this->definition['even empty']);
}
function option_definition() {
$options = parent::option_definition();
$options['grouping'] = array('default' => array());
if ($this->uses_row_class()) {
$options['row_class'] = array('default' => '');
$options['default_row_class'] = array('default' => TRUE, 'bool' => TRUE);
$options['row_class_special'] = array('default' => TRUE, 'bool' => TRUE);
}
$options['uses_fields'] = array('default' => FALSE, 'bool' => TRUE);
return $options;
}
function options_form(&$form, &$form_state) {
parent::options_form($form, $form_state);
if ($this->uses_fields() && $this->definition['uses grouping']) {
$options = array('' => t('- None -'));
$field_labels = $this->display->handler->get_field_labels(TRUE);
$options += $field_labels;
if (count($options) > 1) {
if (is_string($this->options['grouping'])) {
$grouping = $this->options['grouping'];
$this->options['grouping'] = array();
$this->options['grouping'][0]['field'] = $grouping;
}
if (isset($this->options['group_rendered']) && is_string($this->options['group_rendered'])) {
$this->options['grouping'][0]['rendered'] = $this->options['group_rendered'];
unset($this->options['group_rendered']);
}
$c = count($this->options['grouping']);
for ($i = 0; $i <= $c; $i++) {
$grouping = !empty($this->options['grouping'][$i]) ? $this->options['grouping'][$i] : array();
$grouping += array('field' => '', 'rendered' => TRUE, 'rendered_strip' => FALSE);
$form['grouping'][$i]['field'] = array(
'#type' => 'select',
'#title' => t('Grouping field Nr.@number', array('@number' => $i + 1)),
'#options' => $options,
'#default_value' => $grouping['field'],
'#description' => t('You may optionally specify a field by which to group the records. Leave blank to not group.'),
);
$form['grouping'][$i]['rendered'] = array(
'#type' => 'checkbox',
'#title' => t('Use rendered output to group rows'),
'#default_value' => $grouping['rendered'],
'#description' => t('If enabled the rendered output of the grouping field is used to group the rows.'),
'#states' => array(
'invisible' => array(
':input[name="style_options[grouping][' . $i . '][field]"]' => array('value' => ''),
),
),
);
$form['grouping'][$i]['rendered_strip'] = array(
'#type' => 'checkbox',
'#title' => t('Remove tags from rendered output'),
'#default_value' => $grouping['rendered_strip'],
'#states' => array(
'invisible' => array(
':input[name="style_options[grouping][' . $i . '][field]"]' => array('value' => ''),
),
),
);
}
}
}
if ($this->uses_row_class()) {
$form['row_class'] = array(
'#title' => t('Row class'),
'#description' => t('The class to provide on each row.'),
'#type' => 'textfield',
'#default_value' => $this->options['row_class'],
);
if ($this->uses_fields()) {
$form['row_class']['#description'] .= ' ' . t('You may use field tokens from as per the "Replacement patterns" used in "Rewrite the output of this field" for all fields.');
}
$form['default_row_class'] = array(
'#title' => t('Add views row classes'),
'#description' => t('Add the default row classes like views-row-1 to the output. You can use this to quickly reduce the amount of markup the view provides by default, at the cost of making it more difficult to apply CSS.'),
'#type' => 'checkbox',
'#default_value' => $this->options['default_row_class'],
);
$form['row_class_special'] = array(
'#title' => t('Add striping (odd/even), first/last row classes'),
'#description' => t('Add css classes to the first and last line, as well as odd/even classes for striping.'),
'#type' => 'checkbox',
'#default_value' => $this->options['row_class_special'],
);
}
if (!$this->uses_fields() || !empty($this->options['uses_fields'])) {
$form['uses_fields'] = array(
'#type' => 'checkbox',
'#title' => t('Force using fields'),
'#description' => t('If neither the row nor the style plugin supports fields, this field allows to enable them, so you can for example use groupby.'),
'#default_value' => $this->options['uses_fields'],
);
}
}
function options_validate(&$form, &$form_state) {
if (isset($form_state['values']['style_options']['grouping'])) {
foreach ($form_state['values']['style_options']['grouping'] as $index => $grouping) {
if (empty($grouping['field'])) {
unset($form_state['values']['style_options']['grouping'][$index]);
}
}
}
}
function build_sort() {
return TRUE;
}
function build_sort_post() {
}
function pre_render($result) {
if (!empty($this->row_plugin)) {
$this->row_plugin->pre_render($result);
}
}
function render() {
if ($this->uses_row_plugin() && empty($this->row_plugin)) {
debug('views_plugin_style_default: Missing row plugin');
return;
}
$sets = $this->render_grouping(
$this->view->result,
$this->options['grouping'],
TRUE
);
return $this->render_grouping_sets($sets);
}
function render_grouping_sets($sets, $level = 0) {
$output = '';
foreach ($sets as $set) {
$row = reset($set['rows']);
if (is_array($row) && isset($row['group'])) {
$output .= theme(views_theme_functions('views_view_grouping', $this->view, $this->display),
array(
'view' => $this->view,
'grouping' => $this->options['grouping'][$level],
'grouping_level' => $level,
'rows' => $set['rows'],
'title' => $set['group'])
);
}
else {
if ($this->uses_row_plugin()) {
foreach ($set['rows'] as $index => $row) {
$this->view->row_index = $index;
$set['rows'][$index] = $this->row_plugin->render($row);
}
}
$output .= theme($this->theme_functions(),
array(
'view' => $this->view,
'options' => $this->options,
'grouping_level' => $level,
'rows' => $set['rows'],
'title' => $set['group'])
);
}
}
unset($this->view->row_index);
return $output;
}
function render_grouping($records, $groupings = array(), $group_rendered = NULL) {
if (is_string($groupings)) {
$rendered = $group_rendered === NULL ? TRUE : $group_rendered;
$groupings = array(array('field' => $groupings, 'rendered' => $rendered));
}
$this->render_fields($this->view->result);
$sets = array();
if ($groupings) {
foreach ($records as $index => $row) {
$set = &$sets;
foreach ($groupings as $info) {
$field = $info['field'];
$rendered = isset($info['rendered']) ? $info['rendered'] : $group_rendered;
$rendered_strip = isset($info['rendered_strip']) ? $info['rendered_strip'] : FALSE;
$grouping = '';
$group_content = '';
if (isset($this->view->field[$field])) {
$group_content = $this->get_field($index, $field);
if ($this->view->field[$field]->options['label']) {
$group_content = $this->view->field[$field]->options['label'] . ': ' . $group_content;
}
if ($rendered) {
$grouping = $group_content;
if ($rendered_strip) {
$group_content = $grouping = strip_tags(htmlspecialchars_decode($group_content));
}
}
else {
$grouping = $this->get_field_value($index, $field);
if (!is_scalar($grouping)) {
$grouping = md5(serialize($grouping));
}
}
}
if (empty($set[$grouping])) {
$set[$grouping]['group'] = $group_content;
$set[$grouping]['rows'] = array();
}
$set = &$set[$grouping]['rows'];
}
$set[$index] = $row;
}
}
else {
$sets[''] = array(
'group' => '',
'rows' => $records,
);
}
if ($group_rendered === NULL) {
$old_style_sets = array();
foreach ($sets as $group) {
$old_style_sets[$group['group']] = $group['rows'];
}
$sets = $old_style_sets;
}
return $sets;
}
function render_fields($result) {
if (!$this->uses_fields()) {
return;
}
if (!isset($this->rendered_fields)) {
$this->rendered_fields = array();
$this->view->row_index = 0;
$keys = array_keys($this->view->field);
if (!empty($keys)) {
foreach ($result as $count => $row) {
$this->view->row_index = $count;
foreach ($keys as $id) {
$this->rendered_fields[$count][$id] = $this->view->field[$id]->theme($row);
}
$this->row_tokens[$count] = $this->view->field[$id]->get_render_tokens(array());
}
}
unset($this->view->row_index);
}
return $this->rendered_fields;
}
function get_field($index, $field) {
if (!isset($this->rendered_fields)) {
$this->render_fields($this->view->result);
}
if (isset($this->rendered_fields[$index][$field])) {
return $this->rendered_fields[$index][$field];
}
}
function get_field_value($index, $field) {
$this->view->row_index = $index;
$value = $this->view->field[$field]->get_value($this->view->result[$index]);
unset($this->view->row_index);
return $value;
}
function validate() {
$errors = parent::validate();
if ($this->uses_row_plugin()) {
$plugin = $this->display->handler->get_plugin('row');
if (empty($plugin)) {
$errors[] = t('Style @style requires a row style but the row plugin is invalid.', array('@style' => $this->definition['title']));
}
else {
$result = $plugin->validate();
if (!empty($result) && is_array($result)) {
$errors = array_merge($errors, $result);
}
}
}
return $errors;
}
function query() {
parent::query();
if (isset($this->row_plugin)) {
$this->row_plugin->query();
}
}
}