From 92b19577173203f10b5e6a04a8d6986b282130d3 Mon Sep 17 00:00:00 2001
From: Ron Shimshock <ron@shimshockgroup.com>
Date: Tue, 3 May 2016 20:28:16 -0500
Subject: [PATCH] Date field support

---
 includes/views_date_format_sql_handler_date.inc    | 59 ++++++++++++++
 .../views_date_format_sql_handler_date_field.inc   | 58 ++++++++++++++
 .../views_date_format_sql_handler_field_date.inc   | 89 ----------------------
 views_date_format_sql.info                         |  3 +-
 views_date_format_sql.module                       | 33 ++++++++
 views_date_format_sql.views.inc                    | 29 ++++++-
 6 files changed, 178 insertions(+), 93 deletions(-)
 create mode 100644 includes/views_date_format_sql_handler_date.inc
 create mode 100644 includes/views_date_format_sql_handler_date_field.inc
 delete mode 100644 includes/views_date_format_sql_handler_field_date.inc

diff --git a/includes/views_date_format_sql_handler_date.inc b/includes/views_date_format_sql_handler_date.inc
new file mode 100644
index 0000000..9775a1d
--- /dev/null
+++ b/includes/views_date_format_sql_handler_date.inc
@@ -0,0 +1,59 @@
+<?php
+/**
+ * @file
+ * This file contains the class to override views_handler_field_date.
+ */
+
+/**
+ * Allows to removes the date formatting from render() and put it in query().
+ */
+class views_date_format_sql_handler_date extends views_handler_field_date {
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['format_date_sql'] = array('default' => FALSE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['format_date_sql'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Use SQL to format date'),
+      '#description' => t('Use the SQL databse to format the date. This enables date values to be used in grouping aggregation.'),
+      '#default_value' => $this->options['format_date_sql'],
+    );
+  }
+
+  function query() {
+    if ($this->options['format_date_sql'] != TRUE) {
+      return parent::query();
+    }
+    $this->ensure_my_table();
+    // Add the field.
+    $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
+
+    $format = $this->options['date_format'];
+    $custom_format = $this->options['custom_date_format'];
+    $format_string = _views_date_format_sql_get_date_format($format, $custom_format);
+
+    $formula = views_date_sql_format($format_string, "$this->table_alias.$this->real_field");
+
+    $this->field_alias = $this->query->add_field(NULL, $formula, "{$this->table_alias}_{$this->real_field}", $params);
+    $this->query->add_groupby($this->field_alias);
+
+    $this->add_additional_fields();
+  }
+
+  function render($values) {
+    if ($this->options['format_date_sql'] != TRUE) {
+      return parent::render($values);
+    }
+    $format = $this->options['date_format'];
+    return $this->get_value($values);
+  }
+
+}
diff --git a/includes/views_date_format_sql_handler_date_field.inc b/includes/views_date_format_sql_handler_date_field.inc
new file mode 100644
index 0000000..f30e920
--- /dev/null
+++ b/includes/views_date_format_sql_handler_date_field.inc
@@ -0,0 +1,58 @@
+<?php
+/**
+ * @file
+ * This file contains the class to override views_handler_field_date.
+ */
+
+/**
+ * Allows to removes the date formatting from render() and put it in query().
+ */
+class views_date_format_sql_handler_date_field extends views_handler_field_field {
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['format_date_sql'] = array('default' => FALSE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['format_date_sql'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Use SQL to format date'),
+      '#description' => t('Use the SQL databse to format the date. This enables date values to be used in grouping aggregation.'),
+      '#default_value' => $this->options['format_date_sql'],
+    );
+  }
+
+  function query($use_groupby = FALSE) {
+    parent::query($use_groupby);
+    if ($this->options['format_date_sql'] != TRUE) {
+      return;
+    }
+
+    $format_string = _views_date_format_sql_get_date_format($this->options['settings']['format_type']);
+    $field_type = ($this->field_info['type'] == 'datestamp') ? 'int' : $this->field_info['type'];
+
+    // If this is a date module filed we have to get the storage field type.
+    $formula = views_date_sql_format($format_string, "$this->table_alias.$this->real_field", $field_type);
+    $this->query->fields[$this->aliases[$this->real_field]]['field'] = $formula;
+    $this->query->fields[$this->aliases[$this->real_field]]['table'] = NULL;
+  }
+
+  /**
+   * Return an array of items for the field.
+   */
+  function set_items($values, $row_id) {
+    if ($this->options['format_date_sql'] == TRUE && $this->view->query->has_aggregate) {
+      // If we get the formatted value from storage, then it should be output as
+      // plain.
+      $this->options['type'] = 'date_plain';
+    }
+    return parent::set_items($values, $row_id);
+  }
+
+}
diff --git a/includes/views_date_format_sql_handler_field_date.inc b/includes/views_date_format_sql_handler_field_date.inc
deleted file mode 100644
index e92f3ff..0000000
--- a/includes/views_date_format_sql_handler_field_date.inc
+++ /dev/null
@@ -1,89 +0,0 @@
-<?php
-/**
- * @file
- * This file contains the class to override views_handler_field_date.
- */
-
-/**
- * Allows to removes the date formatting from render() and put it in query().
- */
-class views_date_format_sql_handler_field_date extends views_handler_field_date {
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['format_date_sql'] = array('default' => FALSE);
-
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-
-    $form['format_date_sql'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Use SQL to format date'),
-      '#description' => t('Use the SQL databse to format the date. This enables date values to be used in grouping aggregation.'),
-      '#default_value' => $this->options['format_date_sql'],
-    );
-  }
-
-  function query() {
-    if ($this->options['format_date_sql'] != TRUE) {
-      return parent::query();
-    }
-    $this->ensure_my_table();
-    // Add the field.
-    $params = $this->options['group_type'] != 'group' ? array('function' => $this->options['group_type']) : array();
-
-    $format = $this->options['date_format'];
-    $custom_format = $this->options['custom_date_format'];
-    $format_string = $this->get_date_format($format, $custom_format);
-    $formula = views_date_sql_format($format_string, "$this->table_alias.$this->real_field");
-
-    $this->field_alias = $this->query->add_field(NULL, $formula, "{$this->table_alias}_{$this->real_field}", $params);
-    $this->query->add_groupby($this->field_alias);
-
-    $this->add_additional_fields();
-  }
-
-  function render($values) {
-    if ($this->options['format_date_sql'] != TRUE) {
-      return parent::render($values);
-    }
-    $format = $this->options['date_format'];
-    return $this->get_value($values);
-  }
-
-  /**
-   * Helper to retrieve the format to a given date format name.
-   * see includes/common.inc:function format_date()
-   */
-  function get_date_format($type = 'medium', $format = '') {
-    switch ($type) {
-      case 'short':
-        $format = variable_get('date_format_short', 'm/d/Y - H:i');
-        break;
-
-      case 'long':
-        $format = variable_get('date_format_long', 'l, F j, Y - H:i');
-        break;
-
-      case 'custom':
-        // No change to format.
-        break;
-
-      case 'medium':
-      default:
-        // Retrieve the format of the custom $type passed.
-        if ($type != 'medium') {
-          $format = variable_get('date_format_' . $type, '');
-        }
-        // Fall back to 'medium'.
-        if ($format === '') {
-          $format = variable_get('date_format_medium', 'D, m/d/Y - H:i');
-        }
-        break;
-    }
-    return $format;
-  }
-}
diff --git a/views_date_format_sql.info b/views_date_format_sql.info
index 9e946b6..8018bff 100644
--- a/views_date_format_sql.info
+++ b/views_date_format_sql.info
@@ -6,4 +6,5 @@ core = 7.x
 files[] = views_date_format_sql.module
 
 ; Views handlers
-files[] = includes/views_date_format_sql_handler_field_date.inc
+files[] = includes/views_date_format_sql_handler_date.inc
+files[] = includes/views_date_format_sql_handler_date_field.inc
diff --git a/views_date_format_sql.module b/views_date_format_sql.module
index 52f8aa7..9fd8107 100644
--- a/views_date_format_sql.module
+++ b/views_date_format_sql.module
@@ -8,3 +8,36 @@ function views_date_format_sql_views_api() {
     'api' => 3,
   );
 }
+
+/**
+ * Helper to retrieve the format to a given date format name.
+ * see includes/common.inc:function format_date()
+ */
+function _views_date_format_sql_get_date_format($type = 'medium', $format = '') {
+  switch ($type) {
+    case 'short':
+      $format = variable_get('date_format_short', 'm/d/Y - H:i');
+      break;
+
+    case 'long':
+      $format = variable_get('date_format_long', 'l, F j, Y - H:i');
+      break;
+
+    case 'custom':
+      // No change to format.
+      break;
+
+    case 'medium':
+    default:
+      // Retrieve the format of the custom $type passed.
+      if ($type != 'medium') {
+        $format = variable_get('date_format_' . $type, '');
+      }
+      // Fall back to 'medium'.
+      if ($format === '') {
+        $format = variable_get('date_format_medium', 'D, m/d/Y - H:i');
+      }
+      break;
+  }
+  return $format;
+}
diff --git a/views_date_format_sql.views.inc b/views_date_format_sql.views.inc
index bacef9c..b8b2307 100644
--- a/views_date_format_sql.views.inc
+++ b/views_date_format_sql.views.inc
@@ -10,10 +10,33 @@
 function views_date_format_sql_views_data_alter(&$data) {
   // Loops through fields definitions looking for date fields
   // and change the standard date handler with our own.
-  foreach ($data as $module => $table) {
-    foreach ($table as $id => $field) {
+  foreach ($data as $module => &$table) {
+    foreach ($table as $id => &$field) {
       if (isset($field['field']['handler']) && $field['field']['handler'] == 'views_handler_field_date') {
-        $data[$module][$id]['field']['handler'] = 'views_date_format_sql_handler_field_date';
+        if (isset($field['field']['is date']) && $field['field']['is date'] == TRUE) {
+          $field['field']['handler'] = 'views_date_format_sql_handler_date';
+        }
+        else {
+          $field['field']['handler'] = 'views_date_format_sql_handler_date_field';
+        }
+      }
+    }
+  }
+}
+
+/**
+ * Implements hook_field_views_data_alter().
+ */
+function views_date_format_sql_field_views_data_alter(&$result, $field, $module) {
+  if ($module == 'date') {
+    foreach ($result as $table => $data) {
+      foreach ($data as $column => $value) {
+        // The old 'entity_id' and 'revision_id' values got rewritten in Views.
+        // The old values are still there with a 'moved to' key, so ignore them.
+        if (isset($value['field']) && !isset($value['field']['moved to'])) {
+          $result[$table][$column]['field']['handler'] = 'views_date_format_sql_handler_date_field';
+          $result[$table][$column]['field']['add fields to query'] = TRUE;
+        }
       }
     }
   }
-- 
2.8.2

