diff options
Diffstat (limited to 'modules/gallery/models/item.php')
| -rw-r--r-- | modules/gallery/models/item.php | 60 | 
1 files changed, 45 insertions, 15 deletions
| diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php index 3cc9dd53..d1c6feb9 100644 --- a/modules/gallery/models/item.php +++ b/modules/gallery/models/item.php @@ -420,8 +420,15 @@ class Item_Model extends ORM_MPTT {      }      $db = Database::instance(); -    // We can't use isset() in this comparison because ORM::__get() confuses it. -    if ($child->{$this->sort_column} !== null) { +    // 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} @@ -443,21 +450,36 @@ class Item_Model extends ORM_MPTT {            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 { -      // If the sort value is null, then we can't take the approach of doing a comparison to get -      // most of the way there.  We have to iterate the entire data set. -      $position = 0; -      $result = $db->query(" -        SELECT id FROM {items} -        WHERE `parent_id` = {$this->id} -          AND `{$this->sort_column}` IS NULL -        ORDER BY `id` ASC"); -    } +      // 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"; +      } -    foreach ($result as $row) { -      $position++; -      if ($row->id == $child->id) { -        break; +      $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; +        }        }      } @@ -564,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);    } @@ -582,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);    } | 
