Moved item_Model::get_position() method to the Item helper. It now calls the viewable() method on every query.

This commit is contained in:
Jérémy Subtil 2011-01-08 22:57:09 +01:00
parent de5b06ae74
commit 0d7e951aa5
2 changed files with 89 additions and 75 deletions

View File

@ -304,4 +304,89 @@ class item_Core {
->where("rand_key", "<", random::percent())
->order_by("rand_key", "DESC");
}
/**
* Find the position of the given item in its parent album. The resulting
* value is 1-indexed, so the first child in the album is at position 1.
*/
static function get_position($item, $where=array()) {
$album = $item->parent();
if (!strcasecmp($album->sort_order, "DESC")) {
$comp = ">";
} else {
$comp = "<";
}
$query_model = ORM::factory("item");
// 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 = $query_model->viewable()
->where("parent_id", "=", $album->id)
->where($album->sort_column, "IS", null)
->merge_where($where)
->count_all();
if (empty($count)) {
// There are no NULLs in the sort column, so we can just use it directly.
$sort_column = $album->sort_column;
$position = $query_model->viewable()
->where("parent_id", "=", $album->id)
->where($sort_column, $comp, $item->$sort_column)
->merge_where($where)
->count_all();
// 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.
foreach ($query_model->viewable()
->select("id")
->where("parent_id", "=", $album->id)
->where($sort_column, "=", $item->$sort_column)
->merge_where($where)
->order_by(array("id" => "ASC"))
->find_all() as $row) {
$position++;
if ($row->id == $item->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.
$order_by = array($album->sort_column => $album->sort_order);
// Use id as a tie breaker
if ($album->sort_column != "id") {
$order_by["id"] = "ASC";
}
$position = 0;
foreach ($query_model->viewable()
->select("id")
->where("parent_id", "=", $album->id)
->merge_where($where)
->order_by($order_by)
->find_all() as $row) {
$position++;
if ($row->id == $item->id) {
break;
}
}
}
return $position;
}
}

View File

@ -546,83 +546,12 @@ class Item_Model_Core 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.
*
* This method stands as a backward compatibility for gallery 3.0, and will
* be deprecated in version 3.1.
*/
public function get_position($child, $where=array()) {
if (!strcasecmp($this->sort_order, "DESC")) {
$comp = ">";
} else {
$comp = "<";
}
$db = db::build();
// 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, "IS", null)
->merge_where($where)
->count_records();
if (empty($count)) {
// There are no NULLs in the sort column, so we can just use it directly.
$sort_column = $this->sort_column;
$position = $db->from("items")
->where("parent_id", "=", $this->id)
->where($sort_column, $comp, $child->$sort_column)
->merge_where($where)
->count_records();
// 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.
foreach ($db
->select("id")
->from("items")
->where("parent_id", "=", $this->id)
->where($sort_column, "=", $child->$sort_column)
->merge_where($where)
->order_by(array("id" => "ASC"))
->execute() 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.
$order_by = array($this->sort_column => $this->sort_order);
// Use id as a tie breaker
if ($this->sort_column != "id") {
$order_by["id"] = "ASC";
}
$position = 0;
foreach ($db->select("id")
->from("items")
->where("parent_id", "=", $this->id)
->merge_where($where)
->order_by($order_by)
->execute() as $row) {
$position++;
if ($row->id == $child->id) {
break;
}
}
}
return $position;
return item::get_position($child, $where);
}
/**