-
-
Save neamtua/d2b37dbeb9130ad384ad to your computer and use it in GitHub Desktop.
<?php | |
$startTime = microtime(); | |
# config | |
$dir = './'; // path to folder of images | |
$recursive = true; // scan all folders in selected path, recursively | |
$imageExtensions = array('jpg', 'png', 'gif', 'jpeg'); // the image types you want to display | |
$perPage = 16; // how many images to show per page (multiple of 4 recommended) | |
$showFileInfo = true; // display file information beneath the image | |
$isAdmin = false; // display delete option for each image | |
# variables | |
$imageList = array(); | |
$currentPage = isset($_GET['p']) ? (int)$_GET['p'] : 1; | |
# functions | |
function dateSort($a, $b) | |
{ | |
if ($a['created']==$b['created']) return 0; | |
return ($a['created'] > $b['created']) ? -1 : 1; | |
} | |
function deleteImage($path, $currentPage) | |
{ | |
unlink($path); | |
header('Location: ./?p='.$currentPage); | |
} | |
# get all images | |
if ($recursive) { | |
$iterator = new RecursiveDirectoryIterator($dir); | |
foreach ($iterator as $path => $info) { | |
$extension = explode('.', $path); | |
if (in_array(strtolower(array_pop($extension)), $imageExtensions)) { | |
$hash = md5($path); | |
# delete image | |
if ($isAdmin and isset($_GET['del']) && $_GET['del']==$hash) | |
deleteImage($path, $currentPage); | |
$imageList[] = array('path' => $path, 'created' => filemtime($path), 'hash' => $hash); | |
} | |
} | |
} else { | |
if ($handle = opendir($dir)) { | |
while (false !== ($path = readdir($handle))) { | |
$extension = explode('.', $path); | |
if (in_array(strtolower(array_pop($extension)), $imageExtensions)) { | |
$hash = md5($path); | |
# delete image | |
if ($isAdmin and isset($_GET['del']) && $_GET['del']==$hash) | |
deleteImage($path, $currentPage); | |
$imageList[$hash] = array('path' => $path, 'created' => filemtime($path), 'hash' => $hash); | |
} | |
} | |
closedir($handle); | |
} | |
} | |
# sort by newest | |
usort($imageList, 'dateSort'); | |
# get pagination calculations | |
$noImages = count($imageList); | |
$noPages = round($noImages/$perPage, 0, PHP_ROUND_HALF_UP); | |
$pageStart = ($currentPage-1)*$perPage; | |
$pageEnd = $pageStart+$perPage; | |
if ($pageEnd > $noImages) | |
$pageEnd = $noImages; | |
# display html | |
?> | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<title>Fally's Image Lister</title> | |
<!-- Bootstrap --> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/0.9.9/magnific-popup.css"> | |
<style type="text/css"> | |
.thumb { | |
display: block; | |
overflow: hidden; | |
height: 155px; | |
width: 250px; | |
} | |
.thumb img { | |
display: block; | |
min-width: 100%; | |
min-height: 100%; | |
-ms-interpolation-mode: bicubic; | |
} | |
</style> | |
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> | |
<!-- WARNING: Respond.js doesn't work if you view the page via file:// --> | |
<!--[if lt IE 9]> | |
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> | |
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> | |
<![endif]--> | |
</head> | |
<body> | |
<div class="container"> | |
<div class="row"> | |
<div class="col-md-12 col-sm-12"> | |
<h1><a href="./">Images</a></h1> | |
</div> | |
</div> | |
<?php if ($noPages > 1): ?> | |
<div class="row"> | |
<div class="col-md-12"> | |
<nav> | |
<ul class="pager"> | |
<li class="previous <?=$currentPage==1?'disabled':''?>"><a href="./?p=<?=$currentPage-1?>"><span aria-hidden="true">←</span> Newer</a></li> | |
<li>Page <?=$currentPage?> / <?=$noPages?></li> | |
<li class="next <?=$currentPage==$noPages?'disabled':''?>"><a href="./?p=<?=$currentPage+1?>">Older <span aria-hidden="true">→</span></a></li> | |
</ul> | |
</nav> | |
</div> | |
</div> | |
<?php endif; ?> | |
<?php | |
for ($i=$pageStart;$i<$pageEnd;$i++): | |
if (($i+1)%4==1) | |
echo '<div class="row">'; | |
?> | |
<div class="col-sm-2 col-md-3"> | |
<div class="thumbnail"> | |
<div class="thumb"> | |
<a href="<?=$imageList[$i]['path']?>" class="lightbox"> | |
<img src="<?=$imageList[$i]['path']?>" /> | |
</a> | |
</div> | |
<?php | |
if ($showFileInfo): | |
$imageSize = getimagesize($imageList[$i]['path']); | |
$fileSize = number_format(filesize($imageList[$i]['path'])); | |
$fileName = basename($imageList[$i]['path']); | |
?> | |
<div class="caption"> | |
<h5><strong><?=$fileName?></strong></h5> | |
<p><span class="glyphicon glyphicon-picture"></span> <?=$imageSize['mime']?></p> | |
<p><span class="glyphicon glyphicon-paperclip"></span> <?=$fileSize?> bytes</p> | |
<p><span class="glyphicon glyphicon-time"></span> <?=date('Y-m-d H:i:s', $imageList[$i]['created'])?></p> | |
</div> | |
<?php endif; ?> | |
<?php if ($isAdmin): ?> | |
<div class="caption"> | |
<p><a href="./?p=<?=$currentPage?>&del=<?=$imageList[$i]['hash']?>" class="btn btn-danger confirm-delete" data-id="<?=$i?>">Delete</a></p> | |
</div> | |
<?php endif; ?> | |
</div> | |
</div> | |
<?php | |
if (($i+1)%4==0) | |
echo '</div>'; | |
endfor; | |
if ($i%4!=0) | |
echo '</div>'; | |
?> | |
<?php if ($noPages > 1): ?> | |
<div class="row"> | |
<div class="col-md-12"> | |
<nav> | |
<ul class="pager"> | |
<li class="previous <?=$currentPage==1?'disabled':''?>"><a href="./?p=<?=$currentPage-1?>"><span aria-hidden="true">←</span> Newer</a></li> | |
<li>Page <?=$currentPage?> / <?=$noPages?></li> | |
<li class="next <?=$currentPage==$noPages?'disabled':''?>"><a href="./?p=<?=$currentPage+1?>">Older <span aria-hidden="true">→</span></a></li> | |
</ul> | |
</nav> | |
</div> | |
</div> | |
<?php endif; ?> | |
</div> | |
<!-- Modal --> | |
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-hidden="true"> | |
<div class="modal-dialog"> | |
<div class="modal-content"> | |
<div class="modal-header"> | |
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | |
<h4 class="modal-title" id="myModalLabel">Delete file</h4> | |
</div> | |
<div class="modal-body"> | |
<p>You are about to delete a file.</p> | |
<p>Do you want to proceed?</p> | |
</div> | |
<div class="modal-footer"> | |
<a href="#" id="btnYes" class="btn btn-danger">Yes</a> | |
<a href="#" data-dismiss="modal" class="btn btn-default">No</a> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> | |
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/0.9.9/jquery.magnific-popup.min.js"></script> | |
<script type="text/javascript"> | |
$(document).ready(function() { | |
$('.lightbox').magnificPopup({type:'image'}); | |
$('#myModal').on('show', function() { | |
var id = $(this).data('id'), | |
removeBtn = $(this).find('.danger'); | |
}) | |
$('.confirm-delete').on('click', function(e) { | |
e.preventDefault(); | |
var id = $(this).data('id'); | |
$('#myModal').data('id', id).modal('show'); | |
}); | |
$('#btnYes').click(function() { | |
// handle deletion here | |
var id = $('#myModal').data('id'); | |
document.location = $('[data-id='+id+']').attr('href'); | |
$('#myModal').modal('hide'); | |
}); | |
}); | |
</script> | |
<p class="text-center">I've found <strong><?=number_format($noImages, 0, '.', ' ')?></strong> images and loaded the page in <strong><?=microtime()-$startTime?></strong> seconds</p> | |
<p class="text-center">This page uses <a href="http://getbootstrap.com/" target="_blank">Bootstrap</a>, <a href="http://jquery.com/" target="_blank">jQuery</a> and <a href="http://dimsemenov.com/plugins/magnific-popup/" target="_blank">Magnific Popup</a></p> | |
<p class="text-center">Made by <a href="http://fally.ro" target="_blank">Andrei Neamțu</a></p> | |
</body> | |
</html> |
Is what I needed and was too lazy to write. Since you have requested feedback: this script assumes that it is saved as index.php
so navigation uses links of ./
which break if you name it gallery.php
because you have a different index doing a different thing.
I just did a find and replace for href="./
to href="<?=basename($_SERVER["SCRIPT_FILENAME"], ".php")?>.php
which fixed it for this use case but you may want to check if it is indeed index.php
or not.
Sorry to necro your old throwaway gallery but hey who doesn't like knowing someone is using their thing.
Also, here, have a free darkmode:
body {
background: #2e2e2e;
}
p {
color: #797979
}
.thumbnail {
background-color: #1d1d1d;
opacity: 95%;
border: 1px solid #1d1d1d;
}
strong {
color: #e5b567;
}
h1>a {
color: #e87d3e;
}
.pager li > a {
color: #b05279;
background-color: #1d1d1d !important;
border: 1px solid #1d1d1d
}
.disabled li > a {
color: #9e86c8;
}
Is what I needed and was too lazy to write. Since you have requested feedback: this script assumes that it is saved as
index.php
so navigation uses links of./
which break if you name itgallery.php
because you have a different index doing a different thing. I just did a find and replace forhref="./
tohref="<?=basename($_SERVER["SCRIPT_FILENAME"], ".php")?>.php
which fixed it for this use case but you may want to check if it is indeedindex.php
or not. Sorry to necro your old throwaway gallery but hey who doesn't like knowing someone is using their thing.Also, here, have a free darkmode:
body { background: #2e2e2e; } p { color: #797979 } .thumbnail { background-color: #1d1d1d; opacity: 95%; border: 1px solid #1d1d1d; } strong { color: #e5b567; } h1>a { color: #e87d3e; } .pager li > a { color: #b05279; background-color: #1d1d1d !important; border: 1px solid #1d1d1d } .disabled li > a { color: #9e86c8; }
Hey, thanks for using this and i'm glad at least someone's used it. I've totally forgotten about it until today, i could totally make a better version now. Thanks for the additions.
This is a simple, one page script that you can use to create a gallery from the images on your server. It includes an admin mode that allows you to show a delete button for each file. It has a basic pagination and it sorts file by their modification timestamp, from newest to oldest.
So far, it's not very responsive in design.
Feedback is appreciated.