Quellcode durchsuchen

Dealt with the chado date format (ISO date rather then expected Unix timestamp) -field & filter, default views sort works; also made these handlers the default for chado tables

Lacey Sanderson vor 12 Jahren
Ursprung
Commit
54cbcec5c2

+ 7 - 0
tripal_views/tripal_views.api.inc

@@ -441,6 +441,13 @@ function tripal_views_get_integration_array_for_chado_table($table_name, $base_t
           'sort' => array('name' => 'chado_views_handler_sort'),
         );
       }
+      elseif (preg_match('/^datetime/', $field_schema['type'])) {
+        $defn_array['fields'][$field_name]['handlers'] = array(
+          'field' => array('name' => 'chado_views_handler_field_date'),
+          'filter' => array('name' => 'chado_views_handler_filter_date'),
+          'sort' => array('name' => 'views_handler_sort_date'),
+        );
+      }
       else {
         $defn_array['fields'][$field_name]['handlers'] = array(
           'field' => array('name' => 'chado_views_handler_field'),

+ 0 - 12
tripal_views/tripal_views.views.inc

@@ -161,18 +161,6 @@ function tripal_views_views_handlers() {
       'chado_views_handler_sort' => array(
         'parent' => 'views_handler_sort'
       ),
-      'chado_views_handler_sort_date' => array(
-        'parent' => 'views_handler_sort_date'
-      ),
-      'chado_views_handler_sort_formula' => array(
-        'parent' => 'views_handler_sort_formula'
-      ),
-      'chado_views_handler_sort_menu_hierarchy' => array(
-        'parent' => 'views_handler_sort_menu_hierarchy'
-      ),
-      'chado_views_handler_sort_random' => array(
-        'parent' => 'views_handler_sort_random'
-      ),
     ),
   );
 }

+ 16 - 0
tripal_views/views/handlers/chado_views_handler_field_date.inc

@@ -85,6 +85,22 @@ class chado_views_handler_field_date extends views_handler_field_date {
    *   The values retrieved from the database.
    */
   function render($values) {
+
+    // Check the format of the date is a UNIX timestamp and otherwise convert
+    if (!is_array($values->{$this->field_alias})) {
+      if (!preg_match('/^\d+$/',$values->{$this->field_alias})) {
+         $values->{$this->field_alias} = strtotime($values->{$this->field_alias});
+      }
+    }
+    else {
+      if (!preg_match('/^\d+$/',$values->{$this->field_alias}[0])) {
+        foreach ($values->{$this->field_alias} as $k => $v) {
+         $values->{$this->field_alias}[$k] = strtotime($v);
+        }
+      }
+    }
+
+    // render the items
     return chado_wrapper_render_items($this, $values);
   }
 

+ 95 - 27
tripal_views/views/handlers/chado_views_handler_filter_date.inc

@@ -7,6 +7,8 @@
  * Handles fields which may be aggregated during the chado join process. There are options
  * to filter the base table based on an aggregated table or just filter the aggregated
  * table (showing blank for that field if there are no records in the aggregated table).
+ *
+ * @todo make handle aggregation
  */
 class chado_views_handler_filter_date extends views_handler_filter_date {
 
@@ -43,49 +45,115 @@ class chado_views_handler_filter_date extends views_handler_filter_date {
   }
 
   /**
-   * If the table to be filtered is not aggregated uses the parent::query()
-   * However, if it is uses postgresql any() function to compare
+   * Called by query if the operator is between
    */
-  function query() {
+  function op_between($field) {
 
-    // make optional
-    // if it is not set or empty then don't restrict the query
-    if (!$this->value) {
-      return;
+    // Check whether we have a UNIX timestamp or an ISO Timestamp
+    $check = db_fetch_object(db_query("SELECT $this->real_field as val FROM $this->table WHERE $this->real_field IS NOT NULL LIMIT 1"));
+    if (preg_match('/^\d+$/',$check->val)) {
+      // this is a unix timestamp
+      $is_unix = TRUE;
+    }
+    else {
+      // this is an ISO Timestamp
+      $is_unix = FALSE;
     }
 
-    $this->ensure_my_table();
+    if ($this->operator == 'between') {
+      $a = intval(strtotime($this->value['min'], 0));
+      $b = intval(strtotime($this->value['max'], 0));
+    }
+    else {
+      $a = intval(strtotime($this->value['max'], 0));
+      $b = intval(strtotime($this->value['min'], 0));
+    }
 
-    $table = $this->query->get_table_info($this->table);
-    if (preg_match('/aggregator/', $table['join']->definition['handler'])) {
-      $this->aggregated = TRUE;
+    if ($this->value['type'] == 'offset') {
+      $a = '***CURRENT_TIME***' . sprintf('%+d', $a); // keep sign
+      $b = '***CURRENT_TIME***' . sprintf('%+d', $b); // keep sign
+    }
+    // %s is safe here because strtotime scrubbed the input and we might
+    // have a string if using offset.
+    if ($is_unix) {
+      if ($this->operator == 'between') {
+        $this->query->add_where($this->options['group'], "$field >= %s", $a);
+        $this->query->add_where($this->options['group'], "$field <= %s", $b);
+      }
+      else {
+        $this->query->add_where($this->options['group'], "$field >= %s OR $field <= %s", array($a, $b));
+      }
     }
     else {
-      $this->aggregated = FALSE;
+      if ($this->operator == 'between') {
+        $this->query->add_where($this->options['group'], "CAST(EXTRACT(EPOCH FROM $field) as integer) >= %s", $a);
+        $this->query->add_where($this->options['group'], "CAST(EXTRACT(EPOCH FROM $field) as integer) <= %s", $b);
+      }
+      else {
+        $this->query->add_where($this->options['group'], "CAST(EXTRACT(EPOCH FROM $field) as integer) >= %s OR CAST(EXTRACT(EPOCH FROM $field) as integer) <= %s", array($a, $b));
+      }
     }
+  }
 
-    if (!$this->aggregated) {
-      parent::query();
+  /**
+   * Called by query if the operator is not between or empty
+   */
+  function op_simple($field) {
+    $value = intval(strtotime($this->value['value'], 0));
+
+    // Check whether we have a UNIX timestamp or an ISO Timestamp
+    $check = db_fetch_object(db_query("SELECT $this->real_field as val FROM $this->table WHERE $this->real_field IS NOT NULL LIMIT 1"));
+    if (preg_match('/^\d+$/',$check->val)) {
+      // this is a unix timestamp
+      $is_unix = TRUE;
     }
     else {
+      // this is an ISO Timestamp
+      $is_unix = FALSE;
+    }
 
-      // Only base records with value in the aggregated field
-      // This doesn't restrict the items in the aggregate field
-      $this->ensure_my_table();
-      $field = "$this->table_alias.$this->real_field";
-      if ($this->options['agg']['records_with']) {
-        $where = "'%s' = ANY($field)";
-        $this->query->add_where($this->options['group'], $where, $this->value);
+    if ($is_unix) {
+      if (!empty($this->value['type']) && $this->value['type'] == 'offset') {
+        $value = '***CURRENT_TIME***' . sprintf('%+d', $value); // keep sign
       }
-
-      // To restrict the items in the aggregate...
-      // Tell the join handler about the filter
-      // so it can be done in the join query
-      if ($this->options['agg']['aggregates_with']) {
-        $table['join']->filter[] = $field . " = '" . $this->value . "'";
+      $this->query->add_where($this->options['group'], "$field $this->operator %s", $value);
+    }
+    else {
+      if (!empty($this->value['type']) && $this->value['type'] == 'offset') {
+        $value = '***CURRENT_TIME***' . sprintf('%+d', $value); // keep sign
       }
+      $this->query->add_where($this->options['group'], "CAST(EXTRACT(EPOCH FROM $field) as integer) $this->operator %s", $value);
     }
+  }
 
+  /**
+   * Validate that the time values convert to something usable.
+   *
+   * We modify it to
+   * - fix a bug in the views handler for single values
+   *    $value['value'] didn't exist
+   * - fix a pass by reference error
+   *    changed form_error to form_set_error
+   */
+  function validate_valid_time(&$form, $operator, $value) {
+    $operators = $this->operators();
+
+    if ($operators[$operator]['values'] == 1) {
+      $convert = strtotime($value);
+      if (!empty($form) && ($convert == -1 || $convert === FALSE)) {
+        form_set_error($form['value'], t('Invalid date format.'));
+      }
+    }
+    elseif ($operators[$operator]['values'] == 2) {
+      $min = strtotime($value['min']);
+      if ($min == -1 || $min === FALSE) {
+        form_set_error($form['min'], t('Invalid date format.'));
+      }
+      $max = strtotime($value['max']);
+      if ($max == -1 || $max === FALSE) {
+        form_set_error($form['max'], t('Invalid date format.'));
+      }
+    }
   }
 
 }

+ 0 - 58
tripal_views/views/handlers/chado_views_handler_sort_date.inc

@@ -1,58 +0,0 @@
-<?php
-
-/**
- * @file
- * A chado wrapper for the views_handler_sort_date.
- *
- * Handles fields which may be aggregated during the chado join process. Sorting of
- * aggregated fields required PostgreSQL 9.0 due to postgresql limitations. Sorting of
- * non-aggregated fields works for all PostgreSQL versions.
- */
-class chado_views_handler_sort extends views_handler_sort_date {
-
-  /**
-   * Defines the options form (form available to admin when they add a field to a view)
-   */
-  function options_form(&$form, &$form_state) {
-
-    $form['msg'] = array(
-      '#type' => 'item',
-      '#value' => '<b>Sorting of aggregated fields only works for PostgreSQL 9.0+. This is due to lack of support at the database level. With lower postgreSQL versions, no sorting is applied.</b>'
-    );
-
-    parent::options_form($form, $form_state);
-  }
-
-  /**
-   * Adds the sort to the query only if the field isn't aggregated
-   * If the field is aggregated then the sort has to be applied at the join handler level
-   */
-  function query() {
-
-    // Determine if the current field is part of an aggregated table
-    $table = $this->query->get_table_info($this->table);
-    if (preg_match('/aggregator/', $table['join']->definition['handler'])) {
-      $this->aggregated = TRUE;
-    }
-    else {
-      $this->aggregated = FALSE;
-    }
-
-    // One day when the aggregated sort will work (ie: Postgresql 9.0+)
-    // it will need to be applied in join handler
-    // thus tell join handler about the sort
-    $table['join']->sort[] = array(
-      'table' => $table['alias'],
-      'field' => $this->options['field'],
-      'order' => $this->options['order']
-    );
-
-
-    // if not then add the sort
-    if (!$this->aggregated) {
-      parent::query();
-    }
-
-  }
-
-}

+ 0 - 58
tripal_views/views/handlers/chado_views_handler_sort_formula.inc

@@ -1,58 +0,0 @@
-<?php
-
-/**
- * @file
- * A chado wrapper for the views_handler_sort_formula.
- *
- * Handles fields which may be aggregated during the chado join process. Sorting of
- * aggregated fields required PostgreSQL 9.0 due to postgresql limitations. Sorting of
- * non-aggregated fields works for all PostgreSQL versions.
- */
-class chado_views_handler_sort extends views_handler_sort_formula {
-
-  /**
-   * Defines the options form (form available to admin when they add a field to a view)
-   */
-  function options_form(&$form, &$form_state) {
-
-    $form['msg'] = array(
-      '#type' => 'item',
-      '#value' => '<b>Sorting of aggregated fields only works for PostgreSQL 9.0+. This is due to lack of support at the database level. With lower postgreSQL versions, no sorting is applied.</b>'
-    );
-
-    parent::options_form($form, $form_state);
-  }
-
-  /**
-   * Adds the sort to the query only if the field isn't aggregated
-   * If the field is aggregated then the sort has to be applied at the join handler level
-   */
-  function query() {
-
-    // Determine if the current field is part of an aggregated table
-    $table = $this->query->get_table_info($this->table);
-    if (preg_match('/aggregator/', $table['join']->definition['handler'])) {
-      $this->aggregated = TRUE;
-    }
-    else {
-      $this->aggregated = FALSE;
-    }
-
-    // One day when the aggregated sort will work (ie: Postgresql 9.0+)
-    // it will need to be applied in join handler
-    // thus tell join handler about the sort
-    $table['join']->sort[] = array(
-      'table' => $table['alias'],
-      'field' => $this->options['field'],
-      'order' => $this->options['order']
-    );
-
-
-    // if not then add the sort
-    if (!$this->aggregated) {
-      parent::query();
-    }
-
-  }
-
-}

+ 0 - 58
tripal_views/views/handlers/chado_views_handler_sort_menu_hierarchy.inc

@@ -1,58 +0,0 @@
-<?php
-
-/**
- * @file
- * A chado wrapper for the views_handler_sort_menu_hierarchy.
- *
- * Handles fields which may be aggregated during the chado join process. Sorting of
- * aggregated fields required PostgreSQL 9.0 due to postgresql limitations. Sorting of
- * non-aggregated fields works for all PostgreSQL versions.
- */
-class chado_views_handler_sort extends views_handler_sort_menu_hierarchy {
-
-  /**
-   * Defines the options form (form available to admin when they add a field to a view)
-   */
-  function options_form(&$form, &$form_state) {
-
-    $form['msg'] = array(
-      '#type' => 'item',
-      '#value' => '<b>Sorting of aggregated fields only works for PostgreSQL 9.0+. This is due to lack of support at the database level. With lower postgreSQL versions, no sorting is applied.</b>'
-    );
-
-    parent::options_form($form, $form_state);
-  }
-
-  /**
-   * Adds the sort to the query only if the field isn't aggregated
-   * If the field is aggregated then the sort has to be applied at the join handler level
-   */
-  function query() {
-
-    // Determine if the current field is part of an aggregated table
-    $table = $this->query->get_table_info($this->table);
-    if (preg_match('/aggregator/', $table['join']->definition['handler'])) {
-      $this->aggregated = TRUE;
-    }
-    else {
-      $this->aggregated = FALSE;
-    }
-
-    // One day when the aggregated sort will work (ie: Postgresql 9.0+)
-    // it will need to be applied in join handler
-    // thus tell join handler about the sort
-    $table['join']->sort[] = array(
-      'table' => $table['alias'],
-      'field' => $this->options['field'],
-      'order' => $this->options['order']
-    );
-
-
-    // if not then add the sort
-    if (!$this->aggregated) {
-      parent::query();
-    }
-
-  }
-
-}

+ 0 - 58
tripal_views/views/handlers/chado_views_handler_sort_random.inc

@@ -1,58 +0,0 @@
-<?php
-
-/**
- * @file
- * A chado wrapper for the views_handler_sort_random.
- *
- * Handles fields which may be aggregated during the chado join process. Sorting of
- * aggregated fields required PostgreSQL 9.0 due to postgresql limitations. Sorting of
- * non-aggregated fields works for all PostgreSQL versions.
- */
-class chado_views_handler_sort extends views_handler_sort_random {
-
-  /**
-   * Defines the options form (form available to admin when they add a field to a view)
-   */
-  function options_form(&$form, &$form_state) {
-
-    $form['msg'] = array(
-      '#type' => 'item',
-      '#value' => '<b>Sorting of aggregated fields only works for PostgreSQL 9.0+. This is due to lack of support at the database level. With lower postgreSQL versions, no sorting is applied.</b>'
-    );
-
-    parent::options_form($form, $form_state);
-  }
-
-  /**
-   * Adds the sort to the query only if the field isn't aggregated
-   * If the field is aggregated then the sort has to be applied at the join handler level
-   */
-  function query() {
-
-    // Determine if the current field is part of an aggregated table
-    $table = $this->query->get_table_info($this->table);
-    if (preg_match('/aggregator/', $table['join']->definition['handler'])) {
-      $this->aggregated = TRUE;
-    }
-    else {
-      $this->aggregated = FALSE;
-    }
-
-    // One day when the aggregated sort will work (ie: Postgresql 9.0+)
-    // it will need to be applied in join handler
-    // thus tell join handler about the sort
-    $table['join']->sort[] = array(
-      'table' => $table['alias'],
-      'field' => $this->options['field'],
-      'order' => $this->options['order']
-    );
-
-
-    // if not then add the sort
-    if (!$this->aggregated) {
-      parent::query();
-    }
-
-  }
-
-}