<?php /***************************************************************************** * PhotoPage.php * Contains the photo page template. * * Kabuki CMS (C) 2013-2016, Aaron van Geffen *****************************************************************************/ class PhotoPage extends Template { private $photo; private $metaData; private $tag; public function __construct(Image $photo) { $this->photo = $photo; } public function html_main() { $this->photoNav(); $this->photo(); echo ' <div class="row mt-5"> <div class="col-lg-9"> <div id="sub_photo" class="content-box">'; $this->userActions(); echo ' <h2 class="entry-title">', $this->photo->getTitle(), '</h2>'; $this->printTags('Album', 'Album', false); $this->printTags('Tagged People', 'Person', true); echo ' </div> </div> <div class="col-lg-3">'; $this->photoMeta(); echo ' </div> </div> <script type="text/javascript" src="', BASEURL, '/js/photonav.js"></script>'; } protected function photo() { echo ' <a href="', $this->photo->getUrl(), '"> <div id="photo_frame">'; if ($this->photo->isPortrait()) { echo ' <figure id="photo-figure" class="portrait-figure">', $this->photo->getInlineImage(null, 960, 'normal-photo'), $this->photo->getInlineImage(null, 960, 'blur-photo'), ' </figure>'; } else { $className = $this->photo->isPanorama() ? 'panorama-figure' : 'landscape-figure'; echo ' <figure id="photo-figure" class="', $className, '">', $this->photo->getInlineImage(1280, null, 'normal-photo'), $this->photo->getInlineImage(1280, null, 'blur-photo'), ' </figure>'; } echo ' </figure> </div> </a>'; } public function setTag(Tag $tag) { $this->tag = $tag; } private function photoNav() { if ($previousUrl = $this->photo->getUrlForPreviousInSet($this->tag)) echo ' <a href="', $previousUrl, '#photo_frame" id="previous_photo"><i class="bi bi-arrow-left"></i></a>'; else echo ' <span id="previous_photo"><i class="bi bi-arrow-left"></i></span>'; if ($nextUrl = $this->photo->getUrlForNextInSet($this->tag)) echo ' <a href="', $nextUrl, '#photo_frame" id="next_photo"><i class="bi bi-arrow-right"></i></a>'; else echo ' <span id="next_photo"><i class="bi bi-arrow-right"></i></span>'; } private function photoMeta() { echo ' <ul class="list-group photo_meta">'; foreach ($this->metaData as $header => $body) { echo ' <li class="list-group-item"> <h4>', $header, '</h4> ', $body, ' </li>'; } echo ' </ul>'; } private function printTags($header, $tagKind, $allowLinkingNewTags) { static $nextTagListId = 1; $tagListId = 'tagList' . ($nextTagListId++); echo ' <h3>', $header, '</h3> <ul id="', $tagListId, '" class="tag-list">'; foreach ($this->photo->getTags() as $tag) { if ($tag->kind !== $tagKind) continue; echo ' <li id="tag-', $tag->id_tag, '"> <div class="input-group"> <a class="input-group-text" href="', $tag->getUrl(), '" title="View all posts tagged ', $tag->tag, '"> ', $tag->tag, ' </a>'; if ($tag->kind === 'Person') { echo ' <a class="delete-tag btn btn-danger px-1" title="Unlink this tag from this photo" href="#" data-id="', $tag->id_tag, '"> <i class="bi bi-x"></i> </a>'; } echo ' </div> </li>'; } static $nextNewTagId = 1; $newTagId = 'newTag' . ($nextNewTagId++); if ($allowLinkingNewTags) { echo ' <li style="position: relative"> <input class="form-control w-auto" type="text" id="', $newTagId, '" placeholder="Type to link a new tag"> </li>'; } echo ' </ul>'; $this->printNewTagScript($tagKind, $tagListId, $newTagId); } private function printNewTagScript($tagKind, $tagListId, $newTagId) { echo ' <script type="text/javascript" src="', BASEURL, '/js/ajax.js"></script> <script type="text/javascript" src="', BASEURL, '/js/autosuggest.js"></script> <script type="text/javascript"> setTimeout(function() { const removeTag = function(event) { event.preventDefault(); const request = new HttpRequest("post", "', $this->photo->getPageUrl(), '", "id_tag=" + this.dataset["id"] + "&delete", (response) => { if (!response.success) { return; } const tagNode = document.getElementById("tag-" + this.dataset["id"]); tagNode.parentNode.removeChild(tagNode); }); }; let tagRemovalTargets = document.querySelectorAll(".delete-tag"); tagRemovalTargets.forEach(el => el.addEventListener("click", removeTag)); let tag_autosuggest = new TagAutoSuggest({ inputElement: "', $newTagId, '", listElement: "', $tagListId, '", baseUrl: "', BASEURL, '", appendCallback: (item) => { const request = new HttpRequest("post", "', $this->photo->getPageUrl(), '", "id_tag=" + item.id_tag, (response) => { const newListItem = document.createElement("li"); newListItem.id = "tag-" + item.id_tag; const newInputGroup = document.createElement("div"); newInputGroup.className = "input-group"; newListItem.appendChild(newInputGroup); const newLink = document.createElement("a"); newLink.className = "input-group-text"; newLink.href = item.url; newLink.title = "View all posts tagged " + item.label; newLink.textContent = item.label; newInputGroup.appendChild(newLink); const removeLink = document.createElement("a"); removeLink.className = "delete-tag btn btn-danger px-1"; removeLink.dataset["id"] = item.id_tag; removeLink.href = "#"; removeLink.innerHTML = \'<i class="bi bi-x"></i>\'; removeLink.addEventListener("click", removeTag); newInputGroup.appendChild(removeLink); const list = document.getElementById("', $tagListId, '"); list.insertBefore(newListItem, list.querySelector("li:last-child")); }, this); } }); }, 100); </script>'; } public function setMetaData(array $metaData) { $this->metaData = $metaData; } public function userActions() { if (!$this->photo->isOwnedBy(Registry::get('user'))) return; echo ' <div class="float-end"> <a class="btn btn-primary" href="', $this->photo->getEditUrl(), '"> <i class="bi bi-pencil"></i> Edit</a> <a class="btn btn-danger" href="', $this->photo->getDeleteUrl(), '&', Session::getSessionTokenKey(), '=', Session::getSessionToken(), '" onclick="return confirm(\'Are you sure you want to delete this photo?\');"', '"><i class="bi bi-pencil"></i> Delete</a></a> </div>'; } }