254 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			254 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?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>';
 | 
						|
	}
 | 
						|
}
 |