You are here

protected function Table::setTotalsRow in Views Aggregator Plus 8

Write the aggregated results back into the View results totals (footer).

Parameters

array $values: An array of field value arrays, indexed by field name and 'column'.

1 call to Table::setTotalsRow()
Table::preRender in src/Plugin/views/style/Table.php
Note that this class being a views_plugin, rather than a views_handler, it does not have a post_execute() function.

File

src/Plugin/views/style/Table.php, line 1172

Class

Table
Style plugin to render each item as a row in a table.

Namespace

Drupal\views_aggregator\Plugin\views\style

Code

protected function setTotalsRow(array $values) {
  $totals = [];
  foreach ($values as $field_name => $group) {
    if (!empty($this->options['info'][$field_name]['has_aggr_column']) && isset($group['column'])) {

      // For Commerce fields - only care about the following operations.
      $commerce_operations = [
        'sum',
        'average',
        'median',
        'maximum',
        'minimum',
        'range',
      ];

      // Check which column operation we have on the field.
      $col_operation = substr($this->options['info'][$field_name]['aggr_column'], 17);
      $total = $group['column'];
      if ($this
        ->isRenderable($field_name, TRUE)) {
        $field_handler = $this->view->field[$field_name];
        $is_webform_value = is_a($field_handler, 'webform_handler_field_submission_data');

        // This is to make render_text() work properly.
        $field_handler->original_value = $total;
        $separator = $this->options['info'][$field_name]['aggr_par_column'];
        $totals[$field_name] = $is_webform_value ? $this
          ->renderNewWebformValue($field_handler, 0, $total, $separator) : $this
          ->renderNewValue($field_handler, NULL, $total, $separator);
      }
      else {
        $totals[$field_name] = [
          '#markup' => $total,
        ];
      }

      // Calculate proper totals for commerce fields with
      // multiple currencies in one column (results per currency).
      // Conditions:
      // 1. the commerce_values array is set AND
      // 2. the field has more than one currency AND
      // 3. more than one entry per currency AND
      // 4. it is a math function (sum, min, max average, median)
      if (isset($this->commerce_field_values)) {
        if (array_key_exists($field_name, $this->commerce_field_values)) {
          if (in_array($col_operation, $commerce_operations)) {
            if (count($this->commerce_field_values[$field_name]) > 1) {
              $currency_formatter = \Drupal::service('commerce_price.currency_formatter');
              $options = [
                'currency_display' => $field_handler->options['settings']['currency_display'],
              ];
              $commerce_rendered = [];
              foreach ($this->commerce_field_values[$field_name] as $currency_code => $number) {

                // Do the operations in case we have multiple values.
                if (count($number) > 1) {
                  if ($col_operation == 'sum') {
                    $new_value = array_sum($number);
                  }
                  elseif ($col_operation == 'average') {
                    $new_value = array_sum($number) / count($number);
                  }
                  elseif ($col_operation == 'min') {
                    $new_value = min($number);
                  }
                  elseif ($col_operation == 'max') {
                    $new_value = max($number);
                  }
                  elseif ($col_operation == 'median') {
                    sort($number);

                    // Total numbers in array.
                    $count = count($number);

                    // Find the middle value, or the lowest middle value.
                    $middleval = floor(($count - 1) / 2);

                    // Odd number, middle is the median.
                    if ($count % 2) {
                      $new_value = $number[$middleval];
                    }
                    else {
                      $low = $number[$middleval];
                      $high = $number[$middleval + 1];
                      $new_value = ($low + $high) / 2;
                    }
                  }
                  elseif ($col_operation == 'range') {
                    $new_value_min = $currency_formatter
                      ->format(min($number), $currency_code, $options);
                    $new_value_max = $currency_formatter
                      ->format(max($number), $currency_code, $options);
                  }
                  if ($col_operation == 'range') {
                    $commerce_rendered[] = $new_value_min . ' - ' . $new_value_max;
                  }
                  else {
                    $commerce_rendered[] = $currency_formatter
                      ->format($new_value, $currency_code, $options);
                  }
                }
                else {
                  $commerce_rendered[] = $currency_formatter
                    ->format($number[0], $currency_code, $options);
                }
              }
              $commerce_new_total = implode('<br/>', $commerce_rendered);
              $totals[$field_name] = [
                '#markup' => $commerce_new_total,
              ];
            }
          }
        }
      }
    }
  }
  return $totals;
}