198 lines
7.1 KiB
PHP
198 lines
7.1 KiB
PHP
|
<?php
|
||
|
/* Copyright (C) 2021 Alexander Rosenberg
|
||
|
* This file is AGPL v3. See LICENSE file for more information
|
||
|
*/
|
||
|
class Album {
|
||
|
private const PATH_PREFIX = 'albums';
|
||
|
private const THUMB_PREFIX = 'thumbnails';
|
||
|
private const NUMBER_REGEX = '/^[0-9]+(\\.[0-9]+)?$/';
|
||
|
|
||
|
private $name;
|
||
|
private $title;
|
||
|
private $thumbnail;
|
||
|
private $images;
|
||
|
private $metadata;
|
||
|
|
||
|
function __construct($name) {
|
||
|
$this->name = $name;
|
||
|
if (!file_exists($this->get_path())) {
|
||
|
$this->invalidate();
|
||
|
} else {
|
||
|
$this->read();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private function read() {
|
||
|
$content = file_get_contents($this->get_path() . '/data.json');
|
||
|
if ($content == null) {
|
||
|
$this->invalidate();
|
||
|
return;
|
||
|
}
|
||
|
$root = json_decode($content);
|
||
|
if ($root == null) {
|
||
|
$this->invalidate();
|
||
|
return;
|
||
|
}
|
||
|
$this->title = $root->{'title'};
|
||
|
$this->thumbnail = $root->{'thumbnail'};
|
||
|
$this->images = $root->{'images'};
|
||
|
$this->metadata = $root->{'metadata'};
|
||
|
}
|
||
|
|
||
|
private function invalidate() {
|
||
|
$this->title = null;
|
||
|
$this->thumbnail = null;
|
||
|
$this->images = null;
|
||
|
}
|
||
|
|
||
|
function is_valid() {
|
||
|
if ($this->title == null || $this->thumbnail == null || $this->images == null) {
|
||
|
return false;
|
||
|
}
|
||
|
if (!is_string($this->title) || !is_string($this->thumbnail) || !is_array($this->images)) {
|
||
|
return false;
|
||
|
}
|
||
|
foreach ($this->images as $image) {
|
||
|
if (!is_string($image)) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
unset($image);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
function get_name() {
|
||
|
return $this->name;
|
||
|
}
|
||
|
|
||
|
function get_path() {
|
||
|
return $this::PATH_PREFIX . '/' . $this->name;
|
||
|
}
|
||
|
|
||
|
function get_title() {
|
||
|
return $this->title;
|
||
|
}
|
||
|
|
||
|
function get_thumbnail() {
|
||
|
return $this->get_path() . '/' . $this->thumbnail;
|
||
|
}
|
||
|
|
||
|
function get_small_thumbnail() {
|
||
|
return $this::THUMB_PREFIX . '/small/' . $this->get_name() . '/' . $this->thumbnail;
|
||
|
}
|
||
|
|
||
|
function get_images() {
|
||
|
return $this->images;
|
||
|
}
|
||
|
|
||
|
function get_html() {
|
||
|
$out = '<a href="view.php?album=' . urlencode($this->get_name()) . '" class="album-wrapper">';
|
||
|
if (file_exists($this->get_thumbnail())) {
|
||
|
$type = mime_content_type($this->get_thumbnail());
|
||
|
}
|
||
|
$category = explode('/', $type)[0];
|
||
|
if (!file_exists($this->get_thumbnail())) {
|
||
|
$out .= '<img class="album-thumbnail" src="missing-image-icon.svg"/>';
|
||
|
} else if ($category == 'audio') {
|
||
|
$out .= '<img class="album-thumbnail" src="music-icon.svg"/>';
|
||
|
} else {
|
||
|
$out .= '<img class="album-thumbnail" src="' . htmlspecialchars($this->get_small_thumbnail(), ENT_QUOTES | ENT_HTML5) . '"/>';
|
||
|
}
|
||
|
$album_len = count($this->get_images());
|
||
|
if ($album_len == 1) {
|
||
|
$out .= '<div class="album-length">' . $album_len . ' Image</div>';
|
||
|
} else {
|
||
|
$out .= '<div class="album-length">' . $album_len . ' Images</div>';
|
||
|
}
|
||
|
$out .= '<div class="album-title">' . htmlspecialchars($this->get_title(), ENT_QUOTES | ENT_HTML5) . '</div>';
|
||
|
$out .= '</a>';
|
||
|
return $out;
|
||
|
}
|
||
|
|
||
|
|
||
|
function get_metadata($image) {
|
||
|
if ($image == null || !in_array($image, $this->images)) {
|
||
|
return null;
|
||
|
}
|
||
|
if ($this->metadata == null || !property_exists($this->metadata, $image)) {
|
||
|
return [
|
||
|
'description' => '',
|
||
|
'date' => '',
|
||
|
'time' => '',
|
||
|
'latitude' => '',
|
||
|
'longitude' => ''
|
||
|
];
|
||
|
}
|
||
|
$description = $this->metadata->{$image}->{'description'};
|
||
|
$date = $this->metadata->{$image}->{'date'};
|
||
|
$time = $this->metadata->{$image}->{'time'};
|
||
|
$lat= $this->metadata->{$image}->{'latitude'};
|
||
|
$lon = $this->metadata->{$image}->{'longitude'};
|
||
|
if (preg_match($this::NUMBER_REGEX, $lat) === false || preg_match($this::NUMBER_REGEX, $lon) === false) {
|
||
|
$lat = null;
|
||
|
$lon = null;
|
||
|
}
|
||
|
return [
|
||
|
'description' => $description == null ? '' : htmlspecialchars($description, ENT_QUOTES | ENT_HTML5),
|
||
|
'date' => $date == null ? '' : htmlspecialchars($date, ENT_QUOTES | ENT_HTML5),
|
||
|
'time' => $time == null ? '' : htmlspecialchars($time, ENT_QUOTES | ENT_HTML5),
|
||
|
'latitude' => $lat == null ? '' : htmlspecialchars($lat, ENT_QUOTES | ENT_HTML5),
|
||
|
'longitude' => $lon == null ? '' : htmlspecialchars($lon, ENT_QUOTES | ENT_HTML5)
|
||
|
];
|
||
|
}
|
||
|
|
||
|
function get_image_index($image) {
|
||
|
for ($i = 0; $i < count($this->images); ++$i) {
|
||
|
if ($image == $this->images[$i]) {
|
||
|
return $i;
|
||
|
}
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
function get_image_entry($image) {
|
||
|
if ($image == null || !in_array($image, $this->images)) {
|
||
|
return null;
|
||
|
}
|
||
|
$index = $this->get_image_index($image);
|
||
|
$rpath = $this->get_path() . '/' . $image;
|
||
|
$path = htmlspecialchars($rpath);
|
||
|
if (file_exists($rpath)) {
|
||
|
$file_size = number_format(filesize($path));
|
||
|
$rtype = mime_content_type($path);
|
||
|
} else {
|
||
|
$file_size = 0;
|
||
|
$rtype = "Unknown";
|
||
|
}
|
||
|
$type = htmlspecialchars($rtype);
|
||
|
$category = explode('/', $type)[0];
|
||
|
$name = htmlspecialchars(basename($path));
|
||
|
$metadata = $this->get_metadata($image);
|
||
|
$entry = '<div class="sidebar-image-wrapper" onclick="set_main_image('
|
||
|
. strval($index) . ')" ' . "data-size='$file_size' data-type='$type' data-name='$name' data-desc='"
|
||
|
. $metadata['description'] . "' data-date='" . $metadata['date'] . "' data-time='" . $metadata['time'] . "' "
|
||
|
. "data-lat='" . $metadata['latitude'] . "' data-lon='" . $metadata['longitude'] . "'>";
|
||
|
if (!file_exists($rpath)) {
|
||
|
$entry .= '<img style="display: none" class="sidebar-image" data-src="missing-image-icon.svg"/>';
|
||
|
} else if ($category == 'video') {
|
||
|
$thumb_name = htmlspecialchars($this->get_name() . '/' . $image);
|
||
|
$entry .= '<img style="display: none" class="sidebar-image" ';
|
||
|
$entry .= 'data-src="' . $thumb_name . '" ';
|
||
|
$entry .= 'data-type="' . $type . '" ';
|
||
|
$entry .= 'data-videopath="' . $path . '"/>';
|
||
|
} else if ($category == 'audio') {
|
||
|
$entry .= '<img class="sidebar-image" src="music-icon.svg" ';
|
||
|
$entry .= 'data-audiotype="' . $type . '" ';
|
||
|
$entry .= 'data-audiopath="' . $path . '"/>';
|
||
|
} else {
|
||
|
list($width, $height) = getimagesize($rpath);
|
||
|
$path = htmlspecialchars($this->get_name() . '/' . $image);
|
||
|
$entry .= '<img style="display: none" class="sidebar-image" data-src="' . $path . '" ' .
|
||
|
'data-size="' . $width . 'x' . $height . '" />';
|
||
|
}
|
||
|
$entry .= '</div>';
|
||
|
return $entry;
|
||
|
}
|
||
|
}
|
||
|
?>
|