TripalFieldQuery.inc
File
tripal/includes/TripalFieldQuery.incView source
- <?php
-
-
- /**
- * Extends the EntityFieldQuery to support queries from multiple storage types.
- */
- class TripalFieldQuery extends EntityFieldQuery {
-
- /**
- * Holds a list of fields that should be included in the results
- */
- protected $includes = array();
-
- /**
- * Overrides the EntityFieldQuery::execute() function.
- */
- public function execute() {
- // Give a chance for other modules to alter the query.
- drupal_alter('entity_query', $this);
- $this->altered = TRUE;
-
- // Initialize the pager.
- $this->initializePager();
-
- // If there are fields then we need to support multiple backends, call
- // the function for each one and merge the results.
- if ($this->fields) {
-
- // Build the list of all of the different field storage types used
- // for this query.
- foreach ($this->fields as $field) {
- $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;
- }
- }
- }
- // If there are no fields then default to the original
- // EntityFieldQuery() functionality.
- else {
- $results = call_user_func($this->queryCallback(), $this);
- }
-
- if ($results and $this->count) {
- if (!is_numeric($results)) {
- throw new Exception('Query callback function did not provide a numeric value: ' . $this->queryCallback());
- }
- return $results;
- }
- else {
- return $results;
- }
- }
-
- /**
- * Determines the query callback to use for this entity query.
- *
- * This function is a replacement for queryCallback() from the
- * parent EntityFieldQuery class because that class only allows a single
- * storage type per query.
- *
- * @param $storage
- * The storage module
- *
- * @throws EntityFieldQueryException
- * @return
- * A callback that can be used with call_user_func().
- *
- */
- 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 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 ($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."));
- }
- }
- }