diff options
| author | Chad Kieffer <ckieffer@bernie.local> | 2009-09-21 23:08:57 -0600 | 
|---|---|---|
| committer | Chad Kieffer <ckieffer@bernie.local> | 2009-09-21 23:08:57 -0600 | 
| commit | 95945ca18bde4b4ca096d660581fd60d7f06bff5 (patch) | |
| tree | e8693bd26a37dbfc2abdc2aec7617c09180eb4af /modules/gallery/models | |
| parent | 68f3dab7f202fbd9b690f4db27cc4f4038e58d2f (diff) | |
| parent | e5a78d39ec49332054cbc1a398d7c110e1d9191c (diff) | |
Merge branch 'master' of git://github.com/gallery/gallery3
Diffstat (limited to 'modules/gallery/models')
| -rw-r--r-- | modules/gallery/models/item.php | 95 | 
1 files changed, 69 insertions, 26 deletions
| diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php index a87997c6..ff02daf8 100644 --- a/modules/gallery/models/item.php +++ b/modules/gallery/models/item.php @@ -412,39 +412,74 @@ class Item_Model extends ORM_MPTT {     * Find the position of the given child id in this album.  The resulting value is 1-indexed, so     * the first child in the album is at position 1.     */ -  public function get_position($child_id) { +  public function get_position($child) {      if ($this->sort_order == "DESC") {        $comp = ">";      } else {        $comp = "<";      } -      $db = Database::instance(); -    $position = $db->query(" -      SELECT COUNT(*) AS position FROM {items} -      WHERE `parent_id` = {$this->id} -        AND `{$this->sort_column}` $comp (SELECT `{$this->sort_column}` -                                          FROM {items} WHERE `id` = $child_id)") -      ->current()->position; -    // We stopped short of our target value in the sort (notice that we're using a < comparator -    // above) because it's possible that we have duplicate values in the sort column.  An -    // equality check would just arbitrarily pick one of those multiple possible equivalent -    // columns, which would mean that if you choose a sort order that has duplicates, it'd pick -    // any one of them as the child's "position". -    // -    // Fix this by doing a 2nd query where we iterate over the equivalent columns and add them to -    // our base value. -    $result = $db->query(" -      SELECT id FROM {items} -      WHERE `parent_id` = {$this->id} -        AND `{$this->sort_column}` = (SELECT `{$this->sort_column}` -                                      FROM {items} WHERE `id` = $child_id) -      ORDER BY `id` ASC"); -    foreach ($result as $row) { -      $position++; -      if ($row->id == $child_id) { -        break; +    // If the comparison column has NULLs in it, we can't use comparators on it and will have to +    // deal with it the hard way. +    $count = $db->from("items") +      ->where("parent_id", $this->id) +      ->where($this->sort_column, NULL) +      ->count_records(); + +    if (empty($count)) { +      // There are no NULLs in the sort column, so we can just use it directly. +      $position = $db->query(" +        SELECT COUNT(*) AS position FROM {items} +        WHERE `parent_id` = {$this->id} +          AND `{$this->sort_column}` $comp (SELECT `{$this->sort_column}` +                                            FROM {items} WHERE `id` = $child->id)") +        ->current()->position; + +      // We stopped short of our target value in the sort (notice that we're using a < comparator +      // above) because it's possible that we have duplicate values in the sort column.  An +      // equality check would just arbitrarily pick one of those multiple possible equivalent +      // columns, which would mean that if you choose a sort order that has duplicates, it'd pick +      // any one of them as the child's "position". +      // +      // Fix this by doing a 2nd query where we iterate over the equivalent columns and add them to +      // our base value. +      $result = $db->query(" +        SELECT id FROM {items} +        WHERE `parent_id` = {$this->id} +          AND `{$this->sort_column}` = (SELECT `{$this->sort_column}` +                                        FROM {items} WHERE `id` = $child->id) +        ORDER BY `id` ASC"); +      foreach ($result as $row) { +        $position++; +        if ($row->id == $child->id) { +          break; +        } +      } +    } else { +      // There are NULLs in the sort column, so we can't use MySQL comparators.  Fall back to +      // iterating over every child row to get to the current one.  This can be wildly inefficient +      // for really large albums, but it should be a rare case that the user is sorting an album +      // with null values in the sort column. +      // +      // Reproduce the children() functionality here using Database directly to avoid loading the +      // whole ORM for each row. +      $orderby = array($this->sort_column => $this->sort_order); +      // Use id as a tie breaker +      if ($this->sort_column != "id") { +        $orderby["id"] = "ASC"; +      } + +      $position = 0; +      foreach ($db->select("id") +               ->from("items") +               ->where("parent_id", $this->id) +               ->orderby($orderby) +               ->get() as $row) { +        $position++; +        if ($row->id == $child->id) { +          break; +        }        }      } @@ -551,6 +586,10 @@ class Item_Model extends ORM_MPTT {    function children($limit=null, $offset=0, $where=array(), $orderby=null) {      if (empty($orderby)) {        $orderby = array($this->sort_column => $this->sort_order); +      // Use id as a tie breaker +      if ($this->sort_column != "id") { +        $orderby["id"] = "ASC"; +      }      }      return parent::children($limit, $offset, $where, $orderby);    } @@ -569,6 +608,10 @@ class Item_Model extends ORM_MPTT {    function descendants($limit=null, $offset=0, $where=array(), $orderby=null) {      if (empty($orderby)) {        $orderby = array($this->sort_column => $this->sort_order); +      // Use id as a tie breaker +      if ($this->sort_column != "id") { +        $orderby["id"] = "ASC"; +      }      }      return parent::descendants($limit, $offset, $where, $orderby);    } | 
