Browse Source

Fixed bug where normal field queries stopped working with views

Stephen Ficklin 6 years ago
parent
commit
56d63efe2b

+ 62 - 48
tripal/includes/TripalFieldQuery.inc

@@ -57,17 +57,22 @@ class TripalFieldQuery extends EntityFieldQuery {
       }
     }
     
-    $this->relationshipConditions[$table_alias] = [
-      'field' => $field,
-      'value' => $value,
-      'op' => $op,      
-    ];
+    if ($table_alias) {
+      $this->relationshipConditions[$table_alias] = [
+        'field' => $field,
+        'value' => $value,
+        'op' => $op,      
+      ];
+    }
   }
 
   /**
    * Overrides the EntityFieldQuery::execute() function.
    */
   public function execute() {
+    // Initialize the results array.
+    $results = array();
+    
     // Give a chance for other modules to alter the query.
     drupal_alter('entity_query', $this);
     $this->altered = TRUE;
@@ -85,51 +90,71 @@ class TripalFieldQuery extends EntityFieldQuery {
         $this->field_storage[$field['storage']['type']] = $field['storage']['module'];
       }
 
-      // Initialize the results array.
-      $results = array();
-
       // Iterate through the field storage types and call each one.
       foreach ($this->field_storage as $storage_type => $storage_module) {
-        // Execute the query using the correct callback.
         $callback = $this->queryStorageCallback($storage_module);
-
         $st_results = call_user_func($callback, $this);
-        // If this is the first storage type to be queries then save these
-        // as the current results list.
-        if (count($results) == 0) {
-          $results = $st_results;
-        }
-        // If other results already exist then we want to find the intersection
-        // of the two and only save those.
-        else {
-          $intersection = array(
-            'TripalEntity' => array(),
-          );
-          foreach ($st_results['TripalEntity'] as $entity_id => $stub) {
-            if (array_key_exists($entity_id, $results['TripalEntity'])) {
-              $intersection['TripalEntity'][$entity_id] = $stub;
-            }
-          }
-          $results = $intersection;
-        }
+        $results = $this->_intersectResults($results, $st_results);
       }
     }
-    // If there are no fields then default to the original
-    // EntityFieldQuery() functionality.
-    else {
+            
+    // If we have relationships, then handle those.
+    if (!empty($this->relationships)) {
+      $st_results = tripal_field_storage_query($this);
+      $results = $this->_intersectResults($results, $st_results);
+      
+      // Are there any other callbacks that need running other than
+      // propertyQuery as we would have run those with the relationships.
       $callback = $this->queryCallback();
-      $results = call_user_func($callback, $this);
+      if ($callback != 'propertyQuery' and $callback != 'tripal_field_storage_query') {
+        $st_results = call_user_func($callback, $this);
+        $results = $this->_intersectResults($results, $st_results);
+      }
+    }
+    // There are no fields or relationships so just use the default 
+    // callback for the query.
+    else if (!$this->fields){
+      $callback = $this->queryCallback();
+      $st_results = call_user_func($callback, $this);
+      $results = $this->_intersectResults($results, $st_results);
     }
 
     // If this is a count query then it should return a numeric value.
-    if ($results and $this->count) {
-      if (!is_numeric($results)) {
-        throw new Exception('Query callback function did not provide a numeric count value: ' . $this->queryCallback());
+    if ($this->count) {
+      if (!$results or !is_array($results)) {
+        return 0;
+      }
+      return count($results['TripalEntity']);
+    }
+    return $results;
+  }
+  
+  /**
+   * Generates an intersection of results from different storage back-ends.
+   */
+  protected function _intersectResults($current_results, $new_results) {
+    if ($this->count) {
+      return $new_results;
+    }
+    // If we currently don't have any results then just allow all through.
+    // This is the first result set.
+    if (empty($current_results)) {
+      return $new_results;
+    }
+    
+    // Iterate through all of the new results and only include those that
+    // exist in both the current and new.
+    $intersection = [];
+    foreach ($new_results['TripalEntity'] as $entity_id => $stub) {
+      if (array_key_exists($entity_id, $current_results['TripalEntity'])) {
+        $intersection[$entity_id] = $stub;
       }
-      return $results;
+    }
+    if (count($intersection) > 0) {
+      return ['TripalEntity' => $intersection];
     }
     else {
-      return $results;
+      return [];
     }
   }
   
@@ -144,11 +169,6 @@ class TripalFieldQuery extends EntityFieldQuery {
       return $this->executeCallback;
     }
     
-    // If we have relationships then we need to join on the tripal_entity
-    // table and that always occurs using the tripal_field_storage_query.
-    if (!empty($this->relationships)) {
-      return 'tripal_field_storage_query';
-    }
     // If there are no field conditions and sorts, and no execute callback
     // then we default to querying entity tables in SQL.
     if (empty($this->fields)) {
@@ -200,12 +220,6 @@ class TripalFieldQuery extends EntityFieldQuery {
       return $this->executeCallback;
     }
     
-    // If we have relationships then we need to join on the tripal_entity
-    // table and that always occurs using the tripal_field_storage_query.
-    if (!empty($this->relationships)) {
-      return 'tripal_field_storage_query';
-    }
-    
     // If there are no field conditions and sorts, and no execute callback
     // then we default to querying entity tables in SQL.
     if (empty($this->fields)) {

+ 4 - 4
tripal/includes/tripal.field_storage.inc

@@ -144,13 +144,13 @@ function tripal_field_storage_query($query) {
     $select->where('1=0');
   }
 
+//   dpm($query);
+//   dpm($select->__toString());
+//   dpm($select->getArguments());
+  
   // Perform the query and return the results.
   $entities = $select->execute();
   
-  if ($query->count) {
-    return $entities->rowCount();
-  }
-  
   $result = array(
     'TripalEntity' => array(),
   );

+ 12 - 5
tripal/tripal_views_query.inc

@@ -111,6 +111,7 @@ class tripal_views_query extends views_plugin_query {
       // followed by the table column.  We have to handle both because
       // a TripalEntity can have both types attached.
       $elements = explode('.', $field_name);
+      $field = NULL;
       if (count($elements) > 2) {
         $bundle_term = array_shift($elements);
         $field_name = array_shift($elements);
@@ -121,12 +122,18 @@ class tripal_views_query extends views_plugin_query {
       if (count($elements) == 2) {
         $field_name = array_shift($elements);
         $element_name = array_shift($elements);
+        
+        // At this point we're still not 100% sure if we have a
+        // Tripal Storage API field or not.  One quick way to
+        // tell is to see if we get a field using the $field_name. if so the
+        // field name comes in as the second element.
+        $field = field_info_field($element_name);
+        if ($field) {
+          $field_name = $element_name;
+          $element_name = '';
+        }
       }
-
-      // At this point we're still not 100% sure if we have a 
-      // Tripal Storage API field or not.  One quick way to
-      // tell is to see if we get a field using the $field_name
-      $field = field_info_field($field_name);
+      
       if ($field) { 
         $instance = field_info_instance('TripalEntity', $field_name, $this->query->entityConditions['bundle']['value']);
 

+ 4 - 8
tripal_chado/includes/tripal_chado.field_storage.inc

@@ -737,22 +737,18 @@ function tripal_chado_field_storage_query($query) {
   // Only include records that are deleted.  Tripal doesn't keep track of
   // records that are deleted that need purging separately so we can do nothing
   // with this.
-  if (isset($query->deleted)) {
+  if (property_exists($query, 'deleted') and $query->deleted) {
     // There won't ever be field data marked as deleted so just created a
     // condition that always evaluates to false.
     $cquery->where('1=0');
   }
 
- //dpm($cquery->__toString());
- //dpm($cquery->getArguments());
+  // Please keep these dpm's they help with debugging
+  // dpm($cquery->__toString());
+  // dpm($cquery->getArguments());
 
   $records = $cquery->execute();
 
-  // If the query is a count query then just return the  total count.
-  if ($query->count) {
-    return $records->rowCount();
-  }
-
   // If this is not a count query then return the results.
   $result = array();
   while ($record = $records->fetchObject()) {