diff --git a/models/Asset.php b/models/Asset.php index 3fc9d046..45f8c1b6 100644 --- a/models/Asset.php +++ b/models/Asset.php @@ -697,27 +697,48 @@ class Asset $params); } - public function getUrlForPreviousInSet(?Tag $tag) + protected function getUrlForAdjacentInSet($prevNext, ?Tag $tag) { + $next = $prevNext === 'next'; + $previous = !$next; + + $where = []; + $params = [ + 'id_asset' => $this->id_asset, + 'date_captured' => $this->date_captured, + ]; + + // Direction depends on whether we're browsing a tag or timeline + if (isset($tag)) + { + $where[] = 't.id_tag = {int:id_tag}'; + $params['id_tag'] = $tag->id_tag; + $params['where_op'] = $previous ? '<' : '>'; + $params['order_dir'] = $previous ? 'DESC' : 'ASC'; + } + else + { + $params['where_op'] = $previous ? '>' : '<'; + $params['order_dir'] = $previous ? 'ASC' : 'DESC'; + } + + // Use complete ordering when sorting the set + $where[] = '(a.date_captured, a.id_asset) {raw:where_op} ' . + '({datetime:date_captured}, {int:id_asset})'; + + // Stringify conditions together + $where = '(' . implode(') AND (', $where) . ')'; + + // Run query, leaving out tags table if not required $row = Registry::get('db')->queryAssoc(' SELECT a.* - ' . (isset($tag) ? ' - FROM assets_tags AS t - INNER JOIN assets AS a ON a.id_asset = t.id_asset - WHERE t.id_tag = {int:id_tag} AND - (a.date_captured, a.id_asset) < ({datetime:date_captured}, {int:id_asset}) - ORDER BY a.date_captured DESC, a.id_asset DESC' - : ' FROM assets AS a - WHERE (a.date_captured, a.id_asset) > ({datetime:date_captured}, {int:id_asset}) - ORDER BY date_captured ASC, a.id_asset ASC') - . ' + ' . (isset($tag) ? ' + INNER JOIN assets_tags AS t ON a.id_asset = t.id_asset' : '') . ' + WHERE ' . $where . ' + ORDER BY a.date_captured {raw:order_dir}, a.id_asset {raw:order_dir} LIMIT 1', - [ - 'id_asset' => $this->id_asset, - 'id_tag' => isset($tag) ? $tag->id_tag : null, - 'date_captured' => $this->date_captured, - ]); + $params); if ($row) { @@ -728,34 +749,13 @@ class Asset return false; } + public function getUrlForPreviousInSet(?Tag $tag) + { + return $this->getUrlForAdjacentInSet('previous', $tag); + } + public function getUrlForNextInSet(?Tag $tag) { - $row = Registry::get('db')->queryAssoc(' - SELECT a.* - ' . (isset($tag) ? ' - FROM assets_tags AS t - INNER JOIN assets AS a ON a.id_asset = t.id_asset - WHERE t.id_tag = {int:id_tag} AND - (a.date_captured, a.id_asset) > ({datetime:date_captured}, {int:id_asset}) - ORDER BY a.date_captured ASC, a.id_asset ASC' - : ' - FROM assets AS a - WHERE (a.date_captured, a.id_asset) < ({datetime:date_captured}, {int:id_asset}) - ORDER BY date_captured DESC, a.id_asset DESC') - . ' - LIMIT 1', - [ - 'id_asset' => $this->id_asset, - 'id_tag' => isset($tag) ? $tag->id_tag : null, - 'date_captured' => $this->date_captured, - ]); - - if ($row) - { - $obj = self::byRow($row, 'object'); - return $obj->getPageUrl() . ($tag ? '?in=' . $tag->id_tag : ''); - } - else - return false; + return $this->getUrlForAdjacentInSet('next', $tag); } }