diff --git a/controllers/ViewPhoto.php b/controllers/ViewPhoto.php index e6a8c390..ab53c0ff 100644 --- a/controllers/ViewPhoto.php +++ b/controllers/ViewPhoto.php @@ -8,6 +8,8 @@ class ViewPhoto extends HTMLController { + private Image $photo; + public function __construct() { // Ensure we're logged in at this point. @@ -19,44 +21,36 @@ class ViewPhoto extends HTMLController if (empty($photo)) throw new NotFoundException(); + $this->photo = $photo->getImage(); + Session::resetSessionToken(); - parent::__construct($photo->getTitle() . ' - ' . SITE_TITLE); + parent::__construct($this->photo->getTitle() . ' - ' . SITE_TITLE); if (!empty($_POST)) - $this->handleTagging($photo->getImage()); + $this->handleTagging(); else - $this->handleViewPhoto($photo); + $this->handleViewPhoto(); } - private function handleViewPhoto(Asset $photo) + private function handleViewPhoto() { - $page = new PhotoPage($photo->getImage()); + $page = new PhotoPage($this->photo); - // Exif data? - $exif = EXIF::fromFile($photo->getFullPath()); - if ($exif) - $page->setExif($exif); + // Any (EXIF) meta data? + $metaData = $this->prepareMetaData(); + $page->setMetaData($metaData); // What tag are we browsing? $tag = isset($_GET['in']) ? Tag::fromId($_GET['in']) : null; - $id_tag = isset($tag) ? $tag->id_tag : null; - - // Find previous photo in set. - $previous_url = $photo->getUrlForPreviousInSet($id_tag); - if ($previous_url) - $page->setPreviousPhotoUrl($previous_url); - - // ... and the next photo, too. - $next_url = $photo->getUrlForNextInSet($id_tag); - if ($next_url) - $page->setNextPhotoUrl($next_url); + if (isset($tag)) + $page->setTag($tag); $this->page->adopt($page); - $this->page->setCanonicalUrl($photo->getPageUrl()); + $this->page->setCanonicalUrl($this->photo->getPageUrl()); } - private function handleTagging(Image $photo) + private function handleTagging() { header('Content-Type: text/json; charset=utf-8'); @@ -70,7 +64,7 @@ class ViewPhoto extends HTMLController // We are! if (!isset($_POST['delete'])) { - $photo->linkTags([(int) $_POST['id_tag']]); + $this->photo->linkTags([(int) $_POST['id_tag']]); echo json_encode(['success' => true]); exit; } @@ -78,9 +72,43 @@ class ViewPhoto extends HTMLController // ... deleting, that is. else { - $photo->unlinkTags([(int) $_POST['id_tag']]); + $this->photo->unlinkTags([(int) $_POST['id_tag']]); echo json_encode(['success' => true]); exit; } } + + private function prepareMetaData() + { + if (!($exif = EXIF::fromFile($this->photo->getFullPath()))) + throw new UnexpectedValueException('Photo file not found!'); + + $metaData = []; + + if (!empty($exif->created_timestamp)) + $metaData['Date Taken'] = date("j M Y, H:i:s", $exif->created_timestamp); + + if ($author = $this->photo->getAuthor()) + $metaData['Uploaded by'] = $author->getfullName(); + + if (!empty($exif->camera)) + $metaData['Camera Model'] = $exif->camera; + + if (!empty($exif->shutter_speed)) + $metaData['Shutter Speed'] = $exif->shutterSpeedFraction(); + + if (!empty($exif->aperture)) + $metaData['Aperture'] = 'f/' . number_format($exif->aperture, 1); + + if (!empty($exif->focal_length)) + $metaData['Focal Length'] = $exif->focal_length . ' mm'; + + if (!empty($exif->iso)) + $metaData['ISO Speed'] = $exif->iso; + + if (!empty($exif->software)) + $metaData['Software'] = $exif->software; + + return $metaData; + } } diff --git a/models/Asset.php b/models/Asset.php index 5779761d..93e77bc4 100644 --- a/models/Asset.php +++ b/models/Asset.php @@ -697,11 +697,11 @@ class Asset $params); } - public function getUrlForPreviousInSet($id_tag = null) + public function getUrlForPreviousInSet(?Tag $tag) { $row = Registry::get('db')->queryAssoc(' SELECT a.* - ' . (isset($id_tag) ? ' + ' . (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 @@ -715,24 +715,24 @@ class Asset LIMIT 1', [ 'id_asset' => $this->id_asset, - 'id_tag' => $id_tag, + 'id_tag' => $tag->id_tag, 'date_captured' => $this->date_captured, ]); if ($row) { $obj = self::byRow($row, 'object'); - return $obj->getPageUrl() . ($id_tag ? '?in=' . $id_tag : ''); + return $obj->getPageUrl() . ($tag ? '?in=' . $tag->id_tag : ''); } else return false; } - public function getUrlForNextInSet($id_tag = null) + public function getUrlForNextInSet(?Tag $tag) { $row = Registry::get('db')->queryAssoc(' SELECT a.* - ' . (isset($id_tag) ? ' + ' . (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 @@ -746,14 +746,14 @@ class Asset LIMIT 1', [ 'id_asset' => $this->id_asset, - 'id_tag' => $id_tag, + 'id_tag' => $tag->id_tag, 'date_captured' => $this->date_captured, ]); if ($row) { $obj = self::byRow($row, 'object'); - return $obj->getPageUrl() . ($id_tag ? '?in=' . $id_tag : ''); + return $obj->getPageUrl() . ($tag ? '?in=' . $tag->id_tag : ''); } else return false; diff --git a/public/css/default.css b/public/css/default.css index c119c9dc..84e02f18 100644 --- a/public/css/default.css +++ b/public/css/default.css @@ -523,7 +523,7 @@ a#previous_photo:hover, a#next_photo:hover { right: 0; } -#sub_photo h2, #sub_photo h3, #photo_exif_box h3, #user_actions_box h3 { +#sub_photo h2, #sub_photo h3 { margin-bottom: 1rem; } #sub_photo #tag_list { @@ -542,18 +542,17 @@ a#previous_photo:hover, a#next_photo:hover { opacity: 1.0; } - -#photo_exif_box dt { +.photo_meta { + background-color: var(--bs-body-bg); + box-shadow: 0 0.25rem 0.5rem rgba(0,0,0,0.1); +} +.photo_meta li { + padding: 0.6rem 1rem; +} +.photo_meta h4 { + font-family: 'Coda', sans-serif; + font-size: inherit; font-weight: bold; - float: left; - clear: left; - width: 120px; -} -#photo_exif_box dt:after { - content: ':'; -} -#photo_exif_box dd { - float: left; margin: 0; } @@ -583,13 +582,6 @@ a#previous_photo:hover, a#next_photo:hover { #previous_photo, #next_photo { display: none; } - - #sub_photo, #photo_exif_box { - float: none; - margin: 30px 0; - padding: 10px; - width: auto; - } } diff --git a/templates/PhotoPage.php b/templates/PhotoPage.php index 9554106d..3f34e3df 100644 --- a/templates/PhotoPage.php +++ b/templates/PhotoPage.php @@ -8,26 +8,15 @@ class PhotoPage extends Template { - protected $photo; - private $exif; - private $previous_photo_url = ''; - private $next_photo_url = ''; + private $photo; + private $metaData; + private $tag; public function __construct(Image $photo) { $this->photo = $photo; } - public function setPreviousPhotoUrl($url) - { - $this->previous_photo_url = $url; - } - - public function setNextPhotoUrl($url) - { - $this->next_photo_url = $url; - } - public function html_main() { $this->photoNav(); @@ -35,8 +24,12 @@ class PhotoPage extends Template echo '