/** * Add new access rows when a new item is added. * * @param Item_Model $item * @return void */ static function add_item($item) { $access_intent = ORM::factory("access_intent", $item->id); if ($access_intent->loaded) { throw new Exception("@todo ITEM_ALREADY_ADDED {$item->id}"); } $access_intent = ORM::factory("access_intent"); $access_intent->item_id = $item->id; $access_intent->save(); // Create a new access cache entry and copy the parents values. $access_cache = ORM::factory("access_cache"); $access_cache->item_id = $item->id; if ($item->id != 1) { $parent_access_cache = ORM::factory("access_cache")->where("item_id", $item->parent()->id)->find(); foreach (self::_get_all_groups() as $group) { foreach (ORM::factory("permission")->find_all() as $perm) { $field = "{$perm->name}_{$group->id}"; if ($perm->name == "view") { $item->{$field} = $item->parent()->{$field}; } else { $access_cache->{$field} = $parent_access_cache->{$field}; } } } } $item->save(); $access_cache->save(); }
/** * 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. * * @param Item_Model $item * @param array $where an array of arrays, each compatible with ORM::where() */ 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 inequality 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 position count. 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; }