isLoggedIn()) throw new NotAllowedException(); // Viewing an album? if (isset($_GET['tag'])) { $tag = Tag::fromSlug($_GET['tag']); $id_tag = $tag->id_tag; $title = $tag->tag; $header_box = $this->getHeaderBox($tag); } // View the album root. else { $id_tag = 1; $tag = Tag::fromId($id_tag); $title = 'Albums'; } // What page are we at? $current_page = isset($_GET['page']) ? (int) $_GET['page'] : 1; parent::__construct($title . ' - Page ' . $current_page . ' - ' . SITE_TITLE); if (isset($header_box)) $this->page->adopt($header_box); // Who contributed to this album? $contributors = $tag->getContributorList(); // Enumerate possible filters $filters = []; if (!empty($contributors)) { $filters[''] = ['id_user' => null, 'label' => '', 'caption' => 'All photos', 'link' => $tag->getUrl()]; foreach ($contributors as $contributor) { $filters[$contributor['slug']] = [ 'id_user' => $contributor['id_user'], 'label' => $contributor['first_name'], 'caption' => sprintf('By %s (%s photos)', $contributor['first_name'], $contributor['num_assets']), 'link' => $tag->getUrl() . '?by=' . $contributor['slug'], ]; } } // Limit to a particular uploader? $active_filter = ''; $id_user_uploaded = null; if (!empty($_GET['by'])) { if (!isset($filters[$_GET['by']])) throw new UnexpectedValueException('Invalid filter for this album or tag.'); $active_filter = $_GET['by']; $id_user_uploaded = $filters[$active_filter]['id_user']; $filters[$active_filter]['is_active'] = true; } // Add an interface to query and modify the album/tag $buttons = $this->getAlbumButtons($tag, $active_filter); $button_strip = new AlbumButtonBox($buttons, $filters, $active_filter); $this->page->adopt($button_strip); // Fetch subalbums, but only if we're on the first page. if ($current_page === 1) { $albums = $this->getAlbums($id_tag); $index = new AlbumIndex($albums); $this->page->adopt($index); } // Are we viewing a person tag? $is_person = $tag->kind === 'Person'; // Load a photo mosaic for the current tag. list($mosaic, $total_count) = $this->getPhotoMosaic($id_tag, $id_user_uploaded, $current_page, !$is_person); if (isset($mosaic)) { $index = new PhotosIndex($mosaic, Registry::get('user')->isAdmin()); $this->page->adopt($index); $url_params = []; if (isset($tag)) $url_params['in'] = $tag->id_tag; if (!empty($active_filter)) $url_params['by'] = $active_filter; $url_suffix = http_build_query($url_params); $index->setUrlSuffix('?' . $url_suffix); $menu_items = $this->getEditMenuItems('&' . $url_suffix); $index->setEditMenuItems($menu_items); } // Make a page index as needed, while we're at it. if ($total_count > self::PER_PAGE) { $index = new PageIndex([ 'recordCount' => $total_count, 'items_per_page' => self::PER_PAGE, 'start' => ($current_page - 1) * self::PER_PAGE, 'base_url' => $tag->getUrl(), 'page_slug' => 'page/%PAGE%/' . (!empty($active_filter) ? '?by=' . $active_filter : ''), 'index_class' => 'pagination-lg justify-content-around justify-content-lg-center', ]); $this->page->adopt(new PageIndexWidget($index)); } // Set the canonical url. $this->page->setCanonicalUrl($tag->getUrl() . ($current_page > 1 ? 'page/' . $current_page . '/' : '')); } public function getPhotoMosaic($id_tag, $id_user_uploaded, $page, $sort_linear) { // Create an iterator. list($this->iterator, $total_count) = AssetIterator::getByOptions([ 'id_tag' => $id_tag, 'id_user_uploaded' => $id_user_uploaded, 'order' => 'date_captured', 'direction' => $sort_linear ? 'asc' : 'desc', 'limit' => self::PER_PAGE, 'page' => $page, ], true); $mosaic = $total_count > 0 ? new PhotoMosaic($this->iterator) : null; return [$mosaic, $total_count]; } private function getAlbums($id_tag) { // Fetch subalbums. $subalbums = Tag::getAlbums($id_tag); // What assets are we using? $id_assets = array_map(function($album) { return (int) $album['id_asset_thumb']; }, $subalbums); // Fetch assets for thumbnails. $assets = Asset::fromIds($id_assets, 'object'); // Build album list. $albums = []; foreach ($subalbums as $album) { $albums[$album['id_tag']] = [ 'id_tag' => $album['id_tag'], 'caption' => $album['tag'], 'link' => BASEURL . '/' . $album['slug'] . '/', 'thumbnail' => !empty($album['id_asset_thumb']) && isset($assets[$album['id_asset_thumb']]) ? $assets[$album['id_asset_thumb']]->getImage() : null, ]; } return $albums; } private function getAlbumButtons(Tag $tag, $active_filter) { $buttons = []; $user = Registry::get('user'); if ($user->isLoggedIn()) { $suffix = !empty($active_filter) ? '&by=' . $active_filter : ''; $buttons[] = [ 'url' => BASEURL . '/download/?tag=' . $tag->id_tag . $suffix, 'caption' => 'Download album', ]; } if ($tag->id_parent != 0) { if ($tag->kind === 'Album') { $buttons[] = [ 'url' => BASEURL . '/uploadmedia/?tag=' . $tag->id_tag, 'caption' => 'Upload photos here', ]; } if ($user->isAdmin()) { if ($tag->kind === 'Album') { $buttons[] = [ 'url' => BASEURL . '/editalbum/?id=' . $tag->id_tag, 'caption' => 'Edit album', ]; } elseif ($tag->kind === 'Person') { $buttons[] = [ 'url' => BASEURL . '/edittag/?id=' . $tag->id_tag, 'caption' => 'Edit tag', ]; } } } if ($user->isAdmin() && (!isset($tag) || $tag->kind === 'Album')) { $buttons[] = [ 'url' => BASEURL . '/addalbum/?tag=' . $tag->id_tag, 'caption' => 'Create subalbum', ]; } return $buttons; } private function getEditMenuItems($url_suffix) { $items = []; $sess = '&' . Session::getSessionTokenKey() . '=' . Session::getSessionToken(); if (Registry::get('user')->isLoggedIn()) { $items[] = [ 'label' => 'Edit image', 'uri' => fn($image) => $image->getEditUrl() . $url_suffix, ]; $items[] = [ 'label' => 'Delete image', 'uri' => fn($image) => $image->getDeleteUrl() . $url_suffix . $sess, 'onclick' => 'return confirm(\'Are you sure you want to delete this image?\');', ]; } if (Registry::get('user')->isAdmin()) { $items[] = [ 'label' => 'Make album cover', 'uri' => fn($image) => $image->getEditUrl() . $url_suffix . '&album_cover' . $sess, ]; $items[] = [ 'label' => 'Increase priority', 'uri' => fn($image) => $image->getEditUrl() . $url_suffix . '&inc_prio' . $sess, ]; $items[] = [ 'label' => 'Decrease priority', 'uri' => fn($image) => $image->getEditUrl() . $url_suffix . '&dec_prio' . $sess, ]; } return $items; } private function getHeaderBox(Tag $tag) { // Can we go up a level? if ($tag->id_parent != 0) { $ptag = Tag::fromId($tag->id_parent); $back_link = BASEURL . '/' . (!empty($ptag->slug) ? $ptag->slug . '/' : ''); $back_link_title = 'Back to "' . $ptag->tag . '"'; } elseif ($tag->kind === 'Person') { $back_link = BASEURL . '/people/'; $back_link_title = 'Back to "People"'; } $description = !empty($tag->description) ? $tag->description : ''; return new AlbumHeaderBox($tag->tag, $description, $back_link, $back_link_title); } public function __destruct() { if (isset($this->iterator)) $this->iterator->clean(); } }