You are here

views_summarize.module in Views Summarize 1.1.x

Defines the functionality and Drupal hooks for this module.

File

views_summarize.module
View source
<?php

/**
 * @file
 * Defines the functionality and Drupal hooks for this module.
 */
use Drupal\Core\Render\Element;

/**
 * Implements hook_theme().
 */
function views_summarize_theme() {
  return [
    // This is for themeing the form for the Views Summarized table Settings.
    'views_summarize_style_plugin_summarized_table' => [
      'render element' => 'form',
    ],
  ];
}

/**
 * Display a view as a table summary.
 */
function template_preprocess_views_summarize_view_summarized_table(&$variables) {
  template_preprocess_views_view_table($variables);
  if (empty($variables['rows']) || !is_array($variables['rows']) || !count($variables['rows'])) {
    return;
  }
  $view = $variables['view'];
  $options = $view->style_plugin->options;
  if (isset($options['summary_only'])) {
    $variables['summary_only'] = $options['summary_only'];
  }
  $data = [];
  foreach ($variables['rows'] as $row) {
    foreach ($row['columns'] as $field => $field_definition) {
      if (empty($field_definition['content'])) {
        $data[$field][] = '';
      }
      else {
        foreach ($field_definition['content'] as $field_output) {
          if (empty($field_output['field_output']['#markup'])) {
            $data[$field][] = '';
          }
          else {
            $data[$field][] = $field_output['field_output']['#markup']
              ->__toString();
          }
        }
      }
    }
  }

  // Use the first entity in the result set to get the entity field definition.
  // If there are multiple types of entities and/or bundles included in the
  // field list, this could produce unexpected results.
  $field_definitions = $view->result[0]->_entity
    ->getFieldDefinitions();
  $variables['summarized'] = [];
  foreach ($options['info'] as $field => $settings) {
    if (isset($data[$field])) {

      // Get the display's field settings.
      $field_settings = [];
      if (!empty($view->field[$field]->options['settings'])) {
        $field_settings = $view->field[$field]->options['settings'];
      }

      // Get the field instance settings.
      $field_config_settings = [];
      if (!empty($field_definitions[$field])) {
        $field_config_settings = $field_definitions[$field]
          ->getSettings();
      }
      $theme_function = 'views_summarize_type_' . $settings['summarize'];
      $options = [
        'field' => $field,
        'views_field_settings' => $field_settings,
        'field_instance_settings' => $field_config_settings,
      ];
      $theme_variables = [
        'data' => $data[$field],
        'options' => $options,
      ];
      $variables['summarized'][$field] = $theme_function($theme_variables);
    }
  }
}

/**
 * Themes the form for the Views Summarized table Settings.
 *
 * This is almost the same as template_preprocess_views_ui_style_plugin_table().
 */
function template_preprocess_views_summarize_style_plugin_summarized_table(&$variables) {
  $form = $variables['form'];
  $header = [
    t('Field'),
    t('Column'),
    t('Align'),
    t('Summarize'),
    t('Separator'),
    [
      'data' => t('Sortable'),
      'align' => 'center',
    ],
    [
      'data' => t('Default order'),
      'align' => 'center',
    ],
    [
      'data' => t('Default sort'),
      'align' => 'center',
    ],
    [
      'data' => t('Hide empty column'),
      'align' => 'center',
    ],
    [
      'data' => t('Responsive'),
      'align' => 'center',
    ],
  ];
  $rows = [];
  foreach (Element::children($form['columns']) as $id) {
    $row = [];
    $row[]['data'] = $form['info'][$id]['name'];
    $row[]['data'] = $form['columns'][$id];
    $row[]['data'] = $form['info'][$id]['align'];
    $row[]['data'] = $form['info'][$id]['summarize'];
    $row[]['data'] = $form['info'][$id]['separator'];
    if (!empty($form['info'][$id]['sortable'])) {
      $row[] = [
        'data' => $form['info'][$id]['sortable'],
        'align' => 'center',
      ];
      $row[] = [
        'data' => $form['info'][$id]['default_sort_order'],
        'align' => 'center',
      ];
      $row[] = [
        'data' => $form['default'][$id],
        'align' => 'center',
      ];
    }
    else {
      $row[] = '';
      $row[] = '';
      $row[] = '';
    }
    $row[] = [
      'data' => $form['info'][$id]['empty_column'],
      'align' => 'center',
    ];
    $row[] = [
      'data' => $form['info'][$id]['responsive'],
      'align' => 'center',
    ];
    $rows[] = $row;
  }

  // Add the special 'None' row.
  $rows[] = [
    [
      'data' => t('None'),
      'colspan' => 6,
    ],
    [
      'align' => 'center',
      'data' => $form['default'][-1],
    ],
    [
      'colspan' => 2,
    ],
  ];

  // Save the table render array in the $variables variable.
  $variables['table'] = [
    '#type' => 'table',
    '#theme' => 'table__views_summarize_style_plugin_summarized_table',
    '#header' => $header,
    '#rows' => $rows,
  ];

  // Unset elements from the form array that are used to build the table so that
  // they are not rendered twice.
  unset($form['default']);
  unset($form['info']);
  unset($form['columns']);
  $variables['form'] = $form;
}

/**
 * Creates the markup for a no summary column.
 */
function views_summarize_type_none($variables) {
  return [
    '#markup' => '',
  ];
}

/**
 * Creates the markup for the total number of non-empty values in this column.
 */
function views_summarize_type_count($variables) {
  $data = $variables['data'];
  if (!empty($data) && is_array($data)) {
    foreach ($data as $val) {
      $data2[] = strip_tags($val);
    }
  }
  $label = t('Count:');
  $count = count(array_filter($data2, '_views_summarize_type_count_filter'));
  return [
    '#markup' => '<div class="label">' . $label . '</div> ' . $count,
  ];
}

/**
 * Checks whether the given value is set (i.e., not null) or not.
 *
 * @param int $value
 *   The value to check.
 */
function _views_summarize_type_count_filter($value) {
  return isset($value);
}

/**
 * Creates the markup for the total value for a numeric column.
 */
function views_summarize_type_total($variables) {
  $data = $variables['data'];
  $options = $variables['options'];
  $total = 0;
  if (!empty($data) && is_array($data)) {
    foreach ($data as $val) {
      $total += floatval(_views_summarize_get_cleaned_value($val, $options));
    }
  }
  $label = t('Total:');
  $summary = _views_summarize_get_formatted_summary($total, $options);
  return [
    '#markup' => '<div class="label">' . $label . '</div> ' . $summary,
  ];
}

/**
 * Creates the markup for the total value for a currency amount.
 */
function views_summarize_type_currency($variables) {
  $data = $variables['data'];
  $options = $variables['options'];
  $total = 0;
  if (!empty($data) && is_array($data)) {
    foreach ($data as $val) {
      $total += floatval(_views_summarize_get_cleaned_value($val, $options));
    }
  }
  $label = t('Total:');
  $result = _views_summarize_get_formatted_summary($total, $options);
  $prefix_suffix = _views_summarize_get_prefix_suffix($variables['options']);
  $summary = $prefix_suffix['prefix'] . $result . $prefix_suffix['suffix'];
  return [
    '#markup' => '<div class="label">' . $label . '</div>' . $summary,
  ];
}

/**
 * Creates the markup for the total value for an average column.
 *
 * The average calculation includes empty data values.
 */
function views_summarize_type_average($variables) {
  $data = $variables['data'];
  $options = $variables['options'];
  $total = 0;
  if (!empty($data) && is_array($data)) {
    foreach ($data as $val) {
      $total += floatval(_views_summarize_get_cleaned_value($val, $options));
    }
  }
  $label = t('Average (including empty values):');
  $summary = _views_summarize_get_formatted_summary($total / count($data), $options);
  return [
    '#markup' => '<div class="label">' . $label . '</div> ' . $summary,
  ];
}

/**
 * Creates the markup for the total value for an average column.
 *
 * The average calculation excludes empty data values.
 */
function views_summarize_type_average_no_empties($variables) {
  $data = $variables['data'];
  $options = $variables['options'];
  $total = 0;
  $count = 0;
  if (!empty($data) && is_array($data)) {
    foreach ($data as $val) {
      if (isset($val) && $val != '') {
        $total += floatval(_views_summarize_get_cleaned_value($val, $options));
        $count++;
      }
    }
  }
  if ($total != 0 && $count != 0) {
    $summary = _views_summarize_get_formatted_summary($total / $count, $options);
  }
  else {
    $summary = sprintf("%.2f", '0');
  }
  $label = t('Average (excluding empty values):');
  return [
    '#markup' => '<div class="label">' . $label . '</div> ' . $summary,
  ];
}

/**
 * Creates the markup for the maximum and minimum values in this column.
 */
function views_summarize_type_range($variables) {
  $data = $variables['data'];
  $header = [
    [
      'data' => t('Range'),
      'colspan' => 2,
    ],
  ];
  $rows = [];
  if (!empty($data) && is_array($data)) {
    $rows = [
      [
        t('Min'),
        strip_tags(min($data)),
      ],
      [
        t('Max'),
        strip_tags(max($data)),
      ],
    ];
  }
  $table = [
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => $rows,
  ];
  return $table;
}

/**
 * Creates the markup for a spread table in this column.
 */
function views_summarize_type_spread($variables) {
  $data = $variables['data'];
  $hist = [];
  $header = [
    [
      'data' => t('Spread'),
      'colspan' => 2,
    ],
  ];
  $rows = [];
  if (!empty($data) && is_array($data)) {
    foreach ($data as $val) {
      if (!isset($hist[$val])) {
        $hist[$val] = 0;
      }
      $hist[$val]++;
    }
    foreach ($hist as $value => $count) {
      if (empty($value)) {
        $empty_string = t('(empty)')
          ->__toString();
        $rows[$empty_string] = [
          $empty_string,
          $count,
        ];
      }
      else {
        $value = strip_tags($value);
        $rows[$value] = [
          $value,
          $count,
        ];
      }
    }
    ksort($rows, SORT_NATURAL);
  }
  $table = [
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => $rows,
  ];
  return $table;
}

/**
 * Gets the record's value after stripping invalid characters.
 *
 * @param type $value
 *   The value from which to strip invalid characters.
 * @param type $options
 *   The options element of the variables array that is passed into the summary
 *   theme function.
 *
 * @return array
 *  The value with invalid characters removed.
 */
function _views_summarize_get_cleaned_value($value, $options) {
  $value = preg_replace('/[^0-9\\.\\,\\-]/', '', strip_tags($value));
  if (!empty($options['views_field_settings']['thousand_separator'])) {
    $value = str_replace($options['views_field_settings']['thousand_separator'], '', $value);
  }
  if (!empty($options['views_field_settings']['decimal_separator'])) {
    $value = str_replace($options['views_field_settings']['decimal_separator'], '.', $value);
  }
  return $value;
}

/**
 * Gets the summary's formatted result.
 *
 * @param type $total
 *   The summary to format.
 * @param type $options
 *   The options element of the variables array that is passed into the summary
 *   theme function.
 *
 * @return array
 *   The format settings in an associative array.
 */
function _views_summarize_get_formatted_summary($total, $options) {
  $format_settings = [
    'scale' => 0,
    'decimal_separator' => NULL,
    'thousand_separator' => NULL,
  ];
  if (!empty($options['views_field_settings']['scale'])) {
    $format_settings['scale'] = $options['views_field_settings']['scale'];
  }
  if (!empty($options['views_field_settings']['decimal_separator'])) {
    $format_settings['decimal_separator'] = $options['views_field_settings']['decimal_separator'];
  }
  if (!empty($options['views_field_settings']['thousand_separator'])) {
    $format_settings['thousand_separator'] = $options['views_field_settings']['thousand_separator'];
  }
  $summary = number_format($total, $format_settings['scale'], $format_settings['decimal_separator'], $format_settings['thousand_separator']);
  return $summary;
}

/**
 * Gets the prefix and suffix for a summary's output, if they exist.
 *
 * @param type $options
 *   The options element of the variables array that is passed into the summary
 *   theme function.
 *
 * @return array
 *   The prefix and suffix in an associative array.
 */
function _views_summarize_get_prefix_suffix($options) {
  $prefix_suffix = [
    'prefix' => '',
    'suffix' => '',
  ];
  if (!empty($options['views_field_settings']['prefix_suffix'])) {
    if (!empty($options['field_instance_settings']['prefix'])) {
      $prefix_suffix['prefix'] = $options['field_instance_settings']['prefix'];
    }
    if (!empty($options['field_instance_settings']['suffix'])) {
      $prefix_suffix['suffix'] = $options['field_instance_settings']['suffix'];
    }
  }
  return $prefix_suffix;
}

Functions

Namesort descending Description
template_preprocess_views_summarize_style_plugin_summarized_table Themes the form for the Views Summarized table Settings.
template_preprocess_views_summarize_view_summarized_table Display a view as a table summary.
views_summarize_theme Implements hook_theme().
views_summarize_type_average Creates the markup for the total value for an average column.
views_summarize_type_average_no_empties Creates the markup for the total value for an average column.
views_summarize_type_count Creates the markup for the total number of non-empty values in this column.
views_summarize_type_currency Creates the markup for the total value for a currency amount.
views_summarize_type_none Creates the markup for a no summary column.
views_summarize_type_range Creates the markup for the maximum and minimum values in this column.
views_summarize_type_spread Creates the markup for a spread table in this column.
views_summarize_type_total Creates the markup for the total value for a numeric column.
_views_summarize_get_cleaned_value Gets the record's value after stripping invalid characters.
_views_summarize_get_formatted_summary Gets the summary's formatted result.
_views_summarize_get_prefix_suffix Gets the prefix and suffix for a summary's output, if they exist.
_views_summarize_type_count_filter Checks whether the given value is set (i.e., not null) or not.