diff --git a/php/Access/Admin.php b/php/Access/Admin.php index bc2f4a1..30fde25 100644 --- a/php/Access/Admin.php +++ b/php/Access/Admin.php @@ -61,6 +61,7 @@ final class Admin extends Access { // $_GET functions case 'Album::getArchive': self::getAlbumArchiveAction(); break; + case 'Photo::getArchive': self::getPhotoArchiveAction(); break; case 'Photo::getPhoto': self::getPhotoFileAction(); break; } @@ -341,6 +342,15 @@ final class Admin extends Access { } + private static function getPhotoArchiveAction() { + + Validator::required(isset($_GET['photoIDs']), __METHOD__); + + $photo = new Photo($_GET['photoIDs']); + $photo->getArchive(); + + } + private static function getPhotoFileAction() { Validator::required(isset($_GET['photoID']), __METHOD__); diff --git a/php/Modules/Photo.php b/php/Modules/Photo.php index eaa4f9a..006baec 100755 --- a/php/Modules/Photo.php +++ b/php/Modules/Photo.php @@ -948,6 +948,33 @@ final class Photo { } + /** + * Starts a download of photos. + * @return resource|boolean Sends a ZIP-file or returns false on failure. + */ + public function getArchive() { + + // Check dependencies + Validator::required(isset($this->photoIDs), __METHOD__); + + // Call plugins + Plugins::get()->activate(__METHOD__, 0, func_get_args()); + + $archive = new Archive('Photos'); + + $query = Database::prepare(Database::get(), 'SELECT title, url FROM ? WHERE id IN (?)', array(LYCHEE_TABLE_PHOTOS, $this->photoIDs)); + + if (!$archive->addPhotos('', $query)) return false; + + $archive->send(); + + // Call plugins + Plugins::get()->activate(__METHOD__, 1, func_get_args()); + + return true; + + } + /** * Sets the title of a photo. * @return boolean Returns true when successful. diff --git a/src/scripts/contextMenu.js b/src/scripts/contextMenu.js index 938052e..e5af8cc 100644 --- a/src/scripts/contextMenu.js +++ b/src/scripts/contextMenu.js @@ -244,6 +244,7 @@ contextMenu.photo = function(photoID, e) { // in order to keep the selection let items = [ + { title: build.iconic('cloud-download') + 'Download', fn: () => photo.getPhoto(photoID) }, { title: build.iconic('star') + 'Star', fn: () => photo.setStar([ photoID ]) }, { title: build.iconic('tag') + 'Tags', fn: () => photo.editTags([ photoID ]) }, { }, @@ -268,6 +269,7 @@ contextMenu.photoMulti = function(photoIDs, e) { // in order to keep the selection and multiselect let items = [ + { title: build.iconic('cloud-download') + 'Download All', fn: () => photo.getArchive(photoIDs) }, { title: build.iconic('star') + 'Star All', fn: () => photo.setStar(photoIDs) }, { title: build.iconic('tag') + 'Tag All', fn: () => photo.editTags(photoIDs) }, { }, diff --git a/src/scripts/photo.js b/src/scripts/photo.js index 7c14efa..0e606c7 100644 --- a/src/scripts/photo.js +++ b/src/scripts/photo.js @@ -647,6 +647,20 @@ photo.getPhoto = function(photoID) { } +photo.getArchive = function(photoIDs) { + + let link + let url = `${ api.path }?function=Photo::getArchive&photoIDs=${ photoIDs.join(',') }` + + if (location.href.indexOf('index.html')>0) link = location.href.replace(location.hash, '').replace('index.html', url) + else link = location.href.replace(location.hash, '') + url + + if (lychee.publicMode===true) link += `&password=${ encodeURIComponent(password.value) }` + + location.href = link + +} + photo.getDirectLink = function() { let url = ''