|
@@ -11,14 +11,57 @@ class TripalFieldQuery extends EntityFieldQuery {
|
|
|
*/
|
|
|
protected $includes = array();
|
|
|
|
|
|
+ /**
|
|
|
+ * These member variables keep track of join relationships with the
|
|
|
+ * tripal_entity table. This is useful for non Tripal Storage API fields that
|
|
|
+ * want to filter based on on other Drupal tables. The most important
|
|
|
+ * example for this would be Drupal Views. These variables are only meant
|
|
|
+ * to be used by the tripal_field_storage_query() function as that is the
|
|
|
+ * only storage system that should be doing quries on the tripal_entity
|
|
|
+ * table itself.
|
|
|
+ */
|
|
|
+ public $relationships = [];
|
|
|
+ public $relationshipConditions = [];
|
|
|
|
|
|
/**
|
|
|
- * This function is for views integration.
|
|
|
- *
|
|
|
- *
|
|
|
+ * Adds a relationsihp via a table join to the tripal_entity table
|
|
|
+ *
|
|
|
+ * This is specific for Drupal schema tables and is useful for Views
|
|
|
+ * integration when non Tripal Storage API fields are attached to an entity.
|
|
|
+ *
|
|
|
+ * @param $table
|
|
|
+ * The name of the table to join.
|
|
|
+ * @param $alias
|
|
|
+ * The alias for the table.
|
|
|
+ * @param $field
|
|
|
+ * The field to join on.
|
|
|
*/
|
|
|
- public function entityRelationJoin($base_table, $base_field, $table, $field, $value, $op) {
|
|
|
+ public function addRelationship($table, $alias, $field) {
|
|
|
+ $this->relationships[$alias] = [
|
|
|
+ 'table' => $table,
|
|
|
+ 'field' => $field,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * Adds a where statement to a relationship.
|
|
|
+ *
|
|
|
+ * The relationship is added by the $table
|
|
|
+ */
|
|
|
+ public function relationshipCondition($table, $field, $value, $op) {
|
|
|
|
|
|
+ $table_alias = '';
|
|
|
+ // Get the alias for this table.
|
|
|
+ foreach ($this->relationships as $alias => $details) {
|
|
|
+ if ($details['table'] == $table) {
|
|
|
+ $table_alias = $alias;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $this->relationshipConditions[$table_alias] = [
|
|
|
+ 'field' => $field,
|
|
|
+ 'value' => $value,
|
|
|
+ 'op' => $op,
|
|
|
+ ];
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -74,12 +117,14 @@ class TripalFieldQuery extends EntityFieldQuery {
|
|
|
// If there are no fields then default to the original
|
|
|
// EntityFieldQuery() functionality.
|
|
|
else {
|
|
|
- $results = call_user_func($this->queryCallback(), $this);
|
|
|
+ $callback = $this->queryCallback();
|
|
|
+ $results = call_user_func($callback, $this);
|
|
|
}
|
|
|
|
|
|
+ // 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 value: ' . $this->queryCallback());
|
|
|
+ throw new Exception('Query callback function did not provide a numeric count value: ' . $this->queryCallback());
|
|
|
}
|
|
|
return $results;
|
|
|
}
|
|
@@ -87,6 +132,50 @@ class TripalFieldQuery extends EntityFieldQuery {
|
|
|
return $results;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Overides the EntityFieldQuery::queryCallback function.
|
|
|
+ */
|
|
|
+ public function queryCallback() {
|
|
|
+
|
|
|
+ // Use the override from $this->executeCallback. It can be set either
|
|
|
+ // while building the query, or using hook_entity_query_alter().
|
|
|
+ if (function_exists($this->executeCallback)) {
|
|
|
+ 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)) {
|
|
|
+ return array(
|
|
|
+ $this,
|
|
|
+ 'propertyQuery',
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // If no override, find the storage engine to be used.
|
|
|
+ foreach ($this->fields as $field) {
|
|
|
+ if (!isset($storage)) {
|
|
|
+ $storage = $field['storage']['module'];
|
|
|
+ }
|
|
|
+ elseif ($storage != $field['storage']['module']) {
|
|
|
+ throw new EntityFieldQueryException(t("Can't handle more than one field storage engine"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ($storage) {
|
|
|
+
|
|
|
+ // Use hook_field_storage_query() from the field storage.
|
|
|
+ return $storage . '_field_storage_query';
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ throw new EntityFieldQueryException(t("Field storage engine not found."));
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* Determines the query callback to use for this entity query.
|
|
@@ -104,11 +193,19 @@ class TripalFieldQuery extends EntityFieldQuery {
|
|
|
*
|
|
|
*/
|
|
|
protected function queryStorageCallback($storage) {
|
|
|
+
|
|
|
// Use the override from $this->executeCallback. It can be set either
|
|
|
// while building the query, or using hook_entity_query_alter().
|
|
|
if (function_exists($this->executeCallback)) {
|
|
|
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)) {
|