? 885014.patch
? 885014_2.patch
? 885014_3.patch
Index: includes/entity.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/entity.inc,v
retrieving revision 1.13
diff -u -p -r1.13 entity.inc
--- includes/entity.inc	22 Aug 2010 16:11:12 -0000	1.13
+++ includes/entity.inc	2 Sep 2010 18:35:37 -0000
@@ -480,6 +480,24 @@ class EntityFieldQuery {
    * @see EntityFieldQuery::range()
    */
   public $range = array();
+  
+  /**
+   * The query pager.
+   *
+   * @var array
+   *
+   * @see EntityFieldQuery::pager()
+   */
+  public $pager = array();
+  
+  /**
+   * The tablesort header.
+   *
+   * @var array
+   *
+   * @see EntityFieldQuery::tablesort()
+   */
+  public $tablesort = array();
 
   /**
    * Query behavior for deleted data.
@@ -801,6 +819,57 @@ class EntityFieldQuery {
     );
     return $this;
   }
+  
+  /**
+   * Enable a pager for the query.
+   *
+   * @param $limit
+   *   An integer specifying the number of elements per page.  If passed a false
+   *   value (FALSE, 0, NULL), the pager is disabled.
+   * @param $element
+   *   An optional integer to distinguish between multiple pagers on one page.
+   *
+   * @return EntityFieldQuery
+   *   The called object.
+   */
+  public function pager($limit = 10, $element = NULL) {
+    $this->pager = array(
+      'limit' => $limit,
+      'element' => $element,
+    );
+    return $this;
+  }
+  
+  /**
+   * Enable sortable tables for this query.
+   *
+   * @param $header
+   *   An EFQ Header array
+   *   Transformed into an SQL header array for orderByHeader on query execution.
+   *
+   * @return EntityFieldQuery
+   *   The called object.
+   */
+  public function tablesort($header) {
+    // If we have any ordering by fields, we need to populate $this->fields
+    // and save $field and $index for later use.
+    foreach ($header as $key => $options) {
+      if (!is_array($options)) {
+        continue;
+      }
+      
+      if (isset($options['field'])) {
+        $field = field_info_field($options['field']['field_name']);
+        $index = count($this->fields);
+        $this->fields[$index] = $field;
+        $options['field']['field'] = $field;
+        $options['field']['index'] = $index;
+        $header[$key] = $options;
+      }  
+    }
+    $this->tablesort = $header;
+    return $this;
+  }
 
   /**
    * Filters on the data being deleted.
@@ -1033,6 +1102,38 @@ class EntityFieldQuery {
       }
     }
     $this->processProperty($select_query, $base_table);
+    
+    if (count($this->pager)) {
+      $select_query = $select_query->extend('PagerDefault');
+      $select_query->limit($this->pager['limit']);
+      $select_query->element($this->pager['element']);
+    }
+    
+    // Transform the EFQ header and pass it to TableSort.
+    if (count($this->tablesort)) {
+      $sql_header = array();
+      foreach ($this->tablesort as $key => $options) {
+        if (!is_array($options)) {
+          $sql_header[$key] = $options;
+          continue;
+        }
+        
+        if (isset($options['entity']) && isset($id_map[$options['entity']])) {
+          $options['field'] = $id_map[$options['entity']];
+          unset($options['entity']);
+        }
+        elseif (isset($options['property'])) {
+          $options['field'] = "$base_table." . $options['property'];
+          unset($options['entity']);
+        }
+
+        $sql_header[$key] = $options;
+      }
+      $this->tablesort = $sql_header;
+      $select_query = $select_query->extend('TableSort');
+      $select_query->orderByHeader($sql_header);
+    }
+    
     return $this->finishQuery($select_query);
   }
 
Index: modules/field/modules/field_sql_storage/field_sql_storage.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/field_sql_storage/field_sql_storage.module,v
retrieving revision 1.51
diff -u -p -r1.51 field_sql_storage.module
--- modules/field/modules/field_sql_storage/field_sql_storage.module	22 Aug 2010 16:11:12 -0000	1.51
+++ modules/field/modules/field_sql_storage/field_sql_storage.module	2 Sep 2010 18:35:39 -0000
@@ -549,8 +549,16 @@ function field_sql_storage_field_storage
   if (isset($query->deleted)) {
     $select_query->condition("$field_base_table.deleted", (int) $query->deleted);
   }
+  
+  // Check if tablesort needs to order by a property.
+  $has_tablesort_property = FALSE;
+  foreach ($query->tablesort as $key => $options) {
+    if (is_array($options) && isset($options['property'])) {
+      $has_tablesort_property = TRUE;
+    }
+  }
 
-  if ($query->propertyConditions || $query->propertyOrder) {
+  if ($query->propertyConditions || $query->propertyOrder || $has_tablesort_property) {
     if (empty($query->entityConditions['entity_type']['value'])) {
       throw new EntityFieldQueryException('Property conditions and orders must have an entity type defined.');
     }
@@ -567,6 +575,49 @@ function field_sql_storage_field_storage
     $sql_field = $key == 'entity_type' ? 'fcet.type' : "$field_base_table.$key";
     $query->orderBy($sql_field, $direction);
   }
+  
+  if (count($query->pager)) {
+    $select_query = $select_query->extend('PagerDefault');
+    $select_query->limit($query->pager['limit']);
+    $select_query->element($query->pager['element']);
+  }
+  
+  // Transform the EFQ header and pass it to TableSort.
+  if (count($query->tablesort)) {
+    $sql_header = array();
+    foreach ($query->tablesort as $key => $options) {
+      if (!is_array($options)) {
+        $sql_header[$key] = $options;
+        continue;
+      }
+      
+      if (isset($options['field'])) {
+        $field = $options['field']['field'];
+        $index = $options['field']['index'];
+        $table_alias = $table_aliases[$index];
+        $options['field'] = "$table_alias." . _field_sql_storage_columnname($field['field_name'], $options['field']['column']);
+      }
+      elseif (isset($options['entity'])) {
+        if ($options['entity'] == 'entity_type') {
+          $options['field'] = 'fcet.type';
+        }
+        else {
+          $options['field'] = "$field_base_table." . $options['entity'];
+        }
+        unset($options['entity']);
+      }
+      elseif (isset($options['property'])) {
+        $options['field'] = "$entity_base_table." . $options['property'];  
+        unset($options['property']);
+      }
+      
+      $sql_header[$key] = $options;
+    }
+    $query->tablesort = $sql_header;
+    $select_query = $select_query->extend('TableSort');
+    $select_query->orderByHeader($sql_header);
+  }
+
   return $query->finishQuery($select_query, $id_key);
 }
 
