diff --git a/CHANGELOG-2.x.md b/CHANGELOG-2.x.md index ff5151c3..3fb417a6 100644 --- a/CHANGELOG-2.x.md +++ b/CHANGELOG-2.x.md @@ -9,6 +9,7 @@ * Better handling of vocations: (#345) * Load from vocations.xml (No need to manually set) * Support for Monk vocation +* Better gallery, loads images from images/gallery folder * Reworked account action logs to use a single IP column as varchar(45) for both ipv4 and ipv6 (#289) * Admin Panel: save menu collapse state (https://github.com/slawkens/myaac/commit/55da00520df7463a1d1ca41931df1598e9f2ffeb) diff --git a/common.php b/common.php index 0bddea1e..3ea4681c 100644 --- a/common.php +++ b/common.php @@ -27,7 +27,7 @@ if (version_compare(phpversion(), '8.1', '<')) die('PHP version 8.1 or higher is const MYAAC = true; const MYAAC_VERSION = '2.0-dev'; -const DATABASE_VERSION = 49; +const DATABASE_VERSION = 50; const TABLE_PREFIX = 'myaac_'; define('START_TIME', microtime(true)); define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX')); diff --git a/install/includes/import_base_data.php b/install/includes/import_base_data.php index 59bb923e..be55dd3c 100644 --- a/install/includes/import_base_data.php +++ b/install/includes/import_base_data.php @@ -57,16 +57,6 @@ if (NewsCategory::count() === 0) { } } -if (Gallery::count() === 0) { - Gallery::create([ - 'comment' => 'Demon', - 'image' => 'images/gallery/demon.jpg', - 'thumb' => 'images/gallery/demon_thumb.gif', - 'author' => 'MyAAC', - 'ordering' => 0, - ]); -} - if(FAQ::count() == 0) { FAQ::create([ 'question' => 'What is this?', diff --git a/install/includes/schema.sql b/install/includes/schema.sql index 9a0d2b98..3d97be16 100644 --- a/install/includes/schema.sql +++ b/install/includes/schema.sql @@ -198,18 +198,6 @@ CREATE TABLE IF NOT EXISTS `myaac_pages` UNIQUE (`name`) ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; -CREATE TABLE IF NOT EXISTS `myaac_gallery` -( - `id` int NOT NULL AUTO_INCREMENT, - `comment` varchar(255) NOT NULL DEFAULT '', - `image` varchar(255) NOT NULL, - `thumb` varchar(255) NOT NULL, - `author` varchar(50) NOT NULL DEFAULT '', - `ordering` int NOT NULL DEFAULT 0, - `hide` tinyint NOT NULL DEFAULT 0, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; - CREATE TABLE IF NOT EXISTS `myaac_settings` ( `id` int NOT NULL AUTO_INCREMENT, diff --git a/system/migrations/50-gallery.sql b/system/migrations/50-gallery.sql new file mode 100644 index 00000000..09efb653 --- /dev/null +++ b/system/migrations/50-gallery.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS `myaac_gallery` +( + `id` int NOT NULL AUTO_INCREMENT, + `comment` varchar(255) NOT NULL DEFAULT '', + `image` varchar(255) NOT NULL, + `thumb` varchar(255) NOT NULL, + `author` varchar(50) NOT NULL DEFAULT '', + `ordering` int NOT NULL DEFAULT 0, + `hide` tinyint NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4; diff --git a/system/migrations/50.php b/system/migrations/50.php new file mode 100644 index 00000000..f7df11de --- /dev/null +++ b/system/migrations/50.php @@ -0,0 +1,16 @@ +hasTable(TABLE_PREFIX . 'gallery')) { + $db->dropTable(TABLE_PREFIX . 'gallery'); + } +}; + +$down = function () use ($db) { + if (!$db->hasTable(TABLE_PREFIX . 'gallery')) { + $db->query(file_get_contents(__DIR__ . '/50-gallery.sql')); + } +}; diff --git a/system/pages/gallery.php b/system/pages/gallery.php index cb854fca..ff96ac22 100644 --- a/system/pages/gallery.php +++ b/system/pages/gallery.php @@ -9,316 +9,25 @@ */ use MyAAC\Cache\Cache; -use MyAAC\Models\Gallery as ModelsGallery; - defined('MYAAC') or die('Direct access not allowed!'); $title = 'Gallery'; -$canEdit = hasFlag(FLAG_CONTENT_GALLERY) || superAdmin(); -if($canEdit) { - if(function_exists('imagecreatefrompng')) { - if (!empty($action)) { - if ($action == 'delete' || $action == 'edit' || $action == 'hide' || $action == 'moveup' || $action == 'movedown') - $id = $_REQUEST['id']; +const ALLOWED_EXTENSIONS = ['jpg', 'jpeg', 'png', 'gif', 'webp']; - if (isset($_REQUEST['comment'])) - $comment = stripslashes($_REQUEST['comment']); +$images = Cache::remember('gallery', 5 * 60, function () { + $images = glob(BASE . GALLERY_DIR . '*.*'); - if (isset($_REQUEST['image'])) - $image = $_REQUEST['image']; + $images = array_filter($images, function ($image) { + $ext = pathinfo($image, PATHINFO_EXTENSION); - if (isset($_REQUEST['author'])) - $author = $_REQUEST['author']; + return (in_array($ext, ALLOWED_EXTENSIONS) && !str_contains($image, '_thumb')); + }); - $errors = array(); - - if ($action == 'add') { - if (Gallery::add($comment, $image, $author, $errors)) - $comment = $image = $author = ''; - } else if ($action == 'delete') { - Gallery::delete($id, $errors); - } else if ($action == 'edit') { - if (isset($id) && !isset($name)) { - $tmp = Gallery::get($id); - $comment = $tmp['comment']; - $image = $tmp['image']; - $author = $tmp['author']; - } else { - Gallery::update($id, $comment, $image, $author); - $action = $comment = $image = $author = ''; - } - } else if ($action == 'hide') { - Gallery::toggleHide($id, $errors); - } else if ($action == 'moveup') { - Gallery::move($id, -1, $errors); - } else if ($action == 'movedown') { - Gallery::move($id, 1, $errors); - } - - if (!empty($errors)) - $twig->display('error_box.html.twig', array('errors' => $errors)); - } - - if(!isset($_GET['image'])) { - $twig->display('gallery.form.html.twig', array( - 'link' => getLink('gallery/' . ($action == 'edit' ? 'edit' : 'add')), - 'action' => $action, - 'id' => isset($id) ? $id : null, - 'comment' => isset($comment) ? $comment : null, - 'image' => isset($image) ? $image : null, - 'author' => isset($author) ? $author : null - )); - } - } - else - echo 'You cannot edit/add gallery items as it seems your PHP installation doesnt have GD support enabled. Visit PHP Manual for more info.'; -} - -if(isset($_GET['image'])) -{ - $image = $db->query('SELECT * FROM `' . TABLE_PREFIX . 'gallery` WHERE `id` = ' . $db->quote($_GET['image']) . ' ORDER by `ordering` LIMIT 1;'); - if($image->rowCount() == 1) - $image = $image->fetch(); - else - { - echo 'Image with this id does not exists.'; - return; - } - - $previous_image = $db->query('SELECT `id` FROM `' . TABLE_PREFIX . 'gallery` WHERE `id` = ' . $db->quote($image['id'] - 1) . ' ORDER by `ordering`;'); - if($previous_image->rowCount() == 1) - $previous_image = $previous_image->fetch(); - else - $previous_image = NULL; - - $next_image = $db->query('SELECT `id` FROM `' . TABLE_PREFIX . 'gallery` WHERE `id` = ' . $db->quote($image['id'] + 1) . ' ORDER by `ordering`;'); - if($next_image->rowCount() == 1) - $next_image = $next_image->fetch(); - else - $next_image = NULL; - - $twig->display('gallery.get.html.twig', array( - 'previous' => $previous_image ? $previous_image['id'] : null, - 'next' => $next_image ? $next_image['id'] : null, - 'image' => $image - )); - return; -} - -$images = Cache::remember('gallery_' . ($canEdit ? '1' : '0'), 60, function () use ($db, $canEdit) { - return $db->query('SELECT `id`, `comment`, `image`, `author`, `thumb`' . - ($canEdit ? ', `hide`, `ordering`' : '') . - ' FROM `' . TABLE_PREFIX . 'gallery`' . - (!$canEdit ? ' WHERE `hide` != 1' : '') . - ' ORDER BY `ordering`;')->fetchAll(PDO::FETCH_ASSOC); + return array_map(function ($image) { + return basename($image); + }, $images); }); -$last = count($images); -if(!$last) -{ -?> - There are no images added to gallery yet. -display('gallery.html.twig', array( +$twig->display('gallery.html.twig', [ 'images' => $images, - 'last' => $last, - 'canEdit' => $canEdit -)); - -class Gallery -{ - static public function add($comment, $image, $author, &$errors) - { - global $db; - if(isset($comment[0]) && isset($image[0]) && isset($author[0])) - { - $query = - $db->query( - 'SELECT `ordering`' . - ' FROM `' . TABLE_PREFIX . 'gallery`' . - ' ORDER BY `ordering`' . ' DESC LIMIT 1' - ); - - $ordering = 0; - if($query->rowCount() > 0) { - $query = $query->fetch(); - $ordering = $query['ordering'] + 1; - } - - $pathinfo = pathinfo($image); - $extension = strtolower($pathinfo['extension']); - $thumb_filename = GALLERY_DIR . $pathinfo['filename'] . '_thumb.' . $extension; - $filename = GALLERY_DIR . $pathinfo['filename'] . '.' . $extension; - if($db->insert(TABLE_PREFIX . 'gallery', array( - 'comment' => $comment, - 'image' => $filename, 'author' => $author, - 'thumb' => $thumb_filename, - 'ordering' => $ordering))) { - if(self::generateThumb($db->lastInsertId(), $image, $errors)) - self::resize($image, 650, 500, $filename, $errors); - } - } - else - $errors[] = 'Please fill all inputs.'; - - return !count($errors); - } - - static public function get($id) { - return ModelsGallery::find($id)->toArray(); - } - - static public function update($id, $comment, $image, $author) { - $pathinfo = pathinfo($image); - $extension = strtolower($pathinfo['extension']); - $filename = GALLERY_DIR . $pathinfo['filename'] . '.' . $extension; - - if(ModelsGallery::where('id', $id)->update([ - 'comment' => $comment, - 'image' => $filename, - 'author' => $author - ])) { - if(self::generateThumb($id, $image, $errors)) - self::resize($image, 650, 500, $filename, $errors); - } - } - - static public function delete($id, &$errors) - { - if(isset($id)) - { - $row = ModelsGallery::find($id); - if($row) - if (!$row->delete()) { - $errors[] = 'Fail during delete Gallery'; - } - else - $errors[] = 'Image with id ' . $id . ' does not exists.'; - } - else - $errors[] = 'id not set'; - - return !count($errors); - } - - static public function toggleHide($id, &$errors) - { - if(isset($id)) - { - $row = ModelsGallery::find($id); - if($row) { - $row->hide = $row->hide == 1 ? 0 : 1; - if (!$row->save()) { - $errors[] = 'Fail during toggle hide Gallery'; - } - } else - $errors[] = 'Image with id ' . $id . ' does not exists.'; - } - else - $errors[] = 'id not set'; - - return !count($errors); - } - - static public function move($id, $i, &$errors) - { - global $db; - $query = self::get($id); - if($query !== false) - { - $ordering = $query['ordering'] + $i; - $old_record = $db->select(TABLE_PREFIX . 'gallery', array('ordering' => $ordering)); - if($old_record !== false) { - ModelsGallery::where('ordering', $ordering)->update([ - 'ordering' => $query['ordering'], - ]); - } - - ModelsGallery::where('id', $id)->update([ - 'ordering' => $ordering, - ]); - } - else - $errors[] = 'Image with id ' . $id . ' does not exists.'; - - return !count($errors); - } - - static public function resize($file, $new_width, $new_height, $new_file, &$errors) - { - $pathinfo = pathinfo($file); - $extension = strtolower($pathinfo['extension']); - - switch ($extension) - { - case 'gif': // GIF - $image = imagecreatefromgif($file); - break; - case 'jpg': // JPEG - case 'jpeg': - $image = imagecreatefromjpeg($file); - break; - case 'png': // PNG - $image = imagecreatefrompng($file); - break; - default: - $errors[] = 'Unsupported file format.'; - return false; - } - - $width = imagesx($image); - $height = imagesy($image); - - // create a new temporary image - $tmp_img = imagecreatetruecolor($new_width, $new_height); - - // copy and resize old image into new image - imagecopyresized($tmp_img, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height); - - // save thumbnail into a file - switch($extension) - { - case 'gif': - imagegif($tmp_img, $new_file); - break; - - case 'jpg': - case 'jpeg': - imagejpeg($tmp_img, $new_file); - break; - - case 'png': - imagepng($tmp_img, $new_file); - break; - } - - return true; - } - - static public function generateThumb($id, $file, &$errors) - { - $pathinfo = pathinfo($file); - $extension = strtolower($pathinfo['extension']); - $thumb_filename = GALLERY_DIR . $pathinfo['filename'] . '_thumb.' . $extension; - - if(!self::resize($file, 170, 110, $thumb_filename, $errors)) - return false; - - if(isset($id)) - { - $row = ModelsGallery::find($id); - if($row) { - $row->thumb = $thumb_filename; - $row->save(); - } else - $errors[] = 'Image with id ' . $id . ' does not exists.'; - } - else - $errors[] = 'id not set'; - - return !count($errors); - } -} +]); diff --git a/system/src/Models/Gallery.php b/system/src/Models/Gallery.php deleted file mode 100644 index 4e52c1f0..00000000 --- a/system/src/Models/Gallery.php +++ /dev/null @@ -1,18 +0,0 @@ - - {{ csrf() }} - {% if action == 'edit' %} - - {% endif %} - - - - - - - -
{% if action == 'edit' %}Edit{% else %}Add{% endif %} image
- - - - - - - - - - - - - - - -
Comment:
Image URL:
Author:
-
-
- -

diff --git a/system/templates/gallery.get.html.twig b/system/templates/gallery.get.html.twig deleted file mode 100644 index fa32b932..00000000 --- a/system/templates/gallery.get.html.twig +++ /dev/null @@ -1,15 +0,0 @@ -
- {% if next is not null %} - next - {% endif %} - {% if previous is not null %} - previous - {% endif %} -
- back -
-
-
- -
{{ image.comment }}
-
\ No newline at end of file diff --git a/system/templates/gallery.html.twig b/system/templates/gallery.html.twig index 49e8aafa..7ec35c1d 100644 --- a/system/templates/gallery.html.twig +++ b/system/templates/gallery.html.twig @@ -1,38 +1,31 @@ -Click on the image to enlarge.

-{% set i = 0 %} -{% for image in images %} - {% set i = i + 1 %} - - - - - {% if canEdit %} - - {% endif %} - -
- - - - {{ image.comment }} - - Edit - - - Delete - - - {% if image.hide != 1 %}Hide{% else %}Show{% endif %} - - {% if i != 1 %} - - Move up - - {% endif %} - {% if i != last %} - - Move down - - {% endif %} -
-{% endfor %} + +
+ + {% set i = 1 %} + {% for image in images %} +
+
{{ i }} / {{ images|length }}
+ +
+ + {% set i = i + 1 %} + {% endfor %} + + + + + +
+ + +
+ {% set i = 1 %} + + {% for image in images %} + + {% set i = i + 1 %} + {% endfor %} +
+ + + diff --git a/templates/tibiacom/boxes/gallery.php b/templates/tibiacom/boxes/gallery.php index cee97d02..f68d6380 100644 --- a/templates/tibiacom/boxes/gallery.php +++ b/templates/tibiacom/boxes/gallery.php @@ -1,14 +1,12 @@ display('gallery.html.twig', array( - 'image' => $gallery->toArray() + 'image' => GALLERY_DIR . $configGalleryImageThumb, )); } diff --git a/templates/tibiacom/boxes/templates/gallery.html.twig b/templates/tibiacom/boxes/templates/gallery.html.twig index 7ef321ed..0e066a10 100644 --- a/templates/tibiacom/boxes/templates/gallery.html.twig +++ b/templates/tibiacom/boxes/templates/gallery.html.twig @@ -1,6 +1,6 @@
- - Screenshot of the Day + + Screenshot of the Day
diff --git a/templates/tibiacom/config.ini b/templates/tibiacom/config.ini index 1a606da1..7733627e 100644 --- a/templates/tibiacom/config.ini +++ b/templates/tibiacom/config.ini @@ -15,4 +15,4 @@ network_twitter = "tibia" background_image = "background-artwork.jpg" logo_image = "tibia-logo-artwork-top.gif" -gallery_image_id_from_database = 1 \ No newline at end of file +gallery_image_thumb = "demon_thumb.gif" diff --git a/tools/css/gallery.css b/tools/css/gallery.css new file mode 100644 index 00000000..d62384a4 --- /dev/null +++ b/tools/css/gallery.css @@ -0,0 +1,85 @@ +/* Slideshow container */ +.slideshow-container { + max-width: 1000px; + position: relative; + margin: auto; +} + +/* Hide the images by default */ +.mySlides { + display: none; +} + +/* Next & previous buttons */ +.prev, .next { + cursor: pointer; + position: absolute; + top: 50%; + width: auto; + margin-top: -22px; + padding: 16px; + color: white; + font-weight: bold; + font-size: 18px; + transition: 0.6s ease; + border-radius: 0 3px 3px 0; + user-select: none; +} + +/* Position the "next button" to the right */ +.next { + right: 0; + border-radius: 3px 0 0 3px; +} + +/* On hover, add a black background color with a little bit see-through */ +.prev:hover, .next:hover { + background-color: rgba(0,0,0,0.8); +} + +/* Caption text */ +.text { + color: #f2f2f2; + font-size: 15px; + padding: 8px 12px; + position: absolute; + bottom: 8px; + width: 100%; + text-align: center; +} + +/* Number text (1/3 etc) */ +.numbertext { + color: #f2f2f2; + font-size: 12px; + padding: 8px 12px; + position: absolute; + top: 0; +} + +/* The dots/bullets/indicators */ +.dot { + cursor: pointer; + height: 15px; + width: 15px; + margin: 0 2px; + background-color: #bbb; + border-radius: 50%; + display: inline-block; + transition: background-color 0.6s ease; +} + +.active, .dot:hover { + background-color: #717171; +} + +/* Fading animation */ +.fade-effect { + animation-name: fade-effect; + animation-duration: 1.5s; +} + +@keyframes fade-effect { + from {opacity: .4} + to {opacity: 1} +} diff --git a/tools/js/gallery.js b/tools/js/gallery.js new file mode 100644 index 00000000..8ffb4adf --- /dev/null +++ b/tools/js/gallery.js @@ -0,0 +1,28 @@ +let slideIndex = 1; +showSlides(slideIndex); + +// Next/previous controls +function plusSlides(n) { + showSlides(slideIndex += n); +} + +// Thumbnail image controls +function currentSlide(n) { + showSlides(slideIndex = n); +} + +function showSlides(n) { + let i; + let slides = document.getElementsByClassName("mySlides"); + let dots = document.getElementsByClassName("dot"); + if (n > slides.length) {slideIndex = 1} + if (n < 1) {slideIndex = slides.length} + for (i = 0; i < slides.length; i++) { + slides[i].style.display = "none"; + } + for (i = 0; i < dots.length; i++) { + dots[i].className = dots[i].className.replace(" active", ""); + } + slides[slideIndex-1].style.display = "block"; + dots[slideIndex-1].className += " active"; +} \ No newline at end of file