2014-04-05 14:02:53 +00:00
< ? php
###
2014-10-21 11:45:11 +00:00
# @name Photo Module
2015-02-01 21:08:37 +00:00
# @copyright 2015 by Tobias Reich
2014-04-05 14:02:53 +00:00
###
if ( ! defined ( 'LYCHEE' )) exit ( 'Error: Direct access is not allowed!' );
class Photo extends Module {
private $database = null ;
2014-04-11 22:30:26 +00:00
private $settings = null ;
2014-04-05 14:02:53 +00:00
private $photoIDs = null ;
2015-04-13 19:09:28 +00:00
public static $validTypes = array (
2014-04-25 08:13:43 +00:00
IMAGETYPE_JPEG ,
IMAGETYPE_GIF ,
IMAGETYPE_PNG
2014-05-23 13:47:48 +00:00
);
2016-01-19 10:03:28 +00:00
2015-04-13 19:09:28 +00:00
public static $validExtensions = array (
2014-04-25 08:13:43 +00:00
'.jpg' ,
'.jpeg' ,
'.png' ,
'.gif'
2014-05-23 13:47:48 +00:00
);
2014-04-25 08:13:43 +00:00
2014-04-11 22:30:26 +00:00
public function __construct ( $database , $plugins , $settings , $photoIDs ) {
2014-04-05 14:02:53 +00:00
# Init vars
$this -> database = $database ;
$this -> plugins = $plugins ;
2014-04-11 22:30:26 +00:00
$this -> settings = $settings ;
2014-04-05 14:02:53 +00:00
$this -> photoIDs = $photoIDs ;
return true ;
}
2015-06-28 21:09:41 +00:00
public function add ( $files , $albumID = 0 , $description = '' , $tags = '' , $returnOnError = false ) {
# Use $returnOnError if you want to handle errors by your own
# e.g. when calling this functions inside an if-condition
2014-04-11 22:30:26 +00:00
2014-04-19 19:07:36 +00:00
# Check dependencies
2015-06-27 19:03:27 +00:00
self :: dependencies ( isset ( $this -> database , $this -> settings , $files ));
2014-04-11 22:30:26 +00:00
2014-05-16 21:24:11 +00:00
# Check permissions
2014-11-06 21:25:27 +00:00
if ( hasPermissions ( LYCHEE_UPLOADS ) === false ||
hasPermissions ( LYCHEE_UPLOADS_BIG ) === false ||
2014-12-06 13:29:17 +00:00
hasPermissions ( LYCHEE_UPLOADS_THUMB ) === false ) {
2014-11-06 21:25:27 +00:00
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'An upload-folder is missing or not readable and writable' );
exit ( 'Error: An upload-folder is missing or not readable and writable!' );
2014-05-16 21:24:11 +00:00
}
2014-04-11 22:30:26 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 0 , func_get_args ());
switch ( $albumID ) {
case 's' :
# s for public (share)
$public = 1 ;
$star = 0 ;
$albumID = 0 ;
break ;
case 'f' :
# f for starred (fav)
$star = 1 ;
$public = 0 ;
$albumID = 0 ;
break ;
2014-06-29 13:40:06 +00:00
case 'r' :
# r for recent
$public = 0 ;
$star = 0 ;
$albumID = 0 ;
break ;
2014-04-11 22:30:26 +00:00
default :
$star = 0 ;
$public = 0 ;
break ;
}
foreach ( $files as $file ) {
2015-08-29 19:55:32 +00:00
# Check if file exceeds the upload_max_filesize directive
if ( $file [ 'error' ] === UPLOAD_ERR_INI_SIZE ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'The uploaded file exceeds the upload_max_filesize directive in php.ini' );
if ( $returnOnError === true ) return false ;
exit ( 'Error: The uploaded file exceeds the upload_max_filesize directive in php.ini!' );
}
# Check if file was only partially uploaded
if ( $file [ 'error' ] === UPLOAD_ERR_PARTIAL ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'The uploaded file was only partially uploaded' );
if ( $returnOnError === true ) return false ;
exit ( 'Error: The uploaded file was only partially uploaded!' );
}
# Check if writing file to disk failed
if ( $file [ 'error' ] === UPLOAD_ERR_CANT_WRITE ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'Failed to write photo to disk' );
if ( $returnOnError === true ) return false ;
exit ( 'Error: Failed to write photo to disk!' );
}
# Check if a extension stopped the file upload
if ( $file [ 'error' ] === UPLOAD_ERR_EXTENSION ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'A PHP extension stopped the file upload' );
if ( $returnOnError === true ) return false ;
exit ( 'Error: A PHP extension stopped the file upload!' );
}
# Check if the upload was successful
if ( $file [ 'error' ] !== UPLOAD_ERR_OK ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'Upload contains an error (' . $file [ 'error' ] . ')' );
if ( $returnOnError === true ) return false ;
exit ( 'Error: Upload failed!' );
}
2014-04-25 08:13:43 +00:00
# Verify extension
2014-05-20 10:44:08 +00:00
$extension = getExtension ( $file [ 'name' ]);
2016-01-19 10:03:28 +00:00
if ( ! in_array ( strtolower ( $extension ), self :: $validExtensions , true )) {
2015-04-13 19:09:28 +00:00
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'Photo format not supported' );
2015-06-28 21:09:41 +00:00
if ( $returnOnError === true ) return false ;
2015-04-13 19:09:28 +00:00
exit ( 'Error: Photo format not supported!' );
}
2014-04-25 08:13:43 +00:00
# Verify image
$type = @ exif_imagetype ( $file [ 'tmp_name' ]);
2016-01-19 10:03:28 +00:00
if ( ! in_array ( $type , self :: $validTypes , true )) {
2015-04-13 19:09:28 +00:00
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'Photo type not supported' );
2015-06-28 21:09:41 +00:00
if ( $returnOnError === true ) return false ;
2015-04-13 19:09:28 +00:00
exit ( 'Error: Photo type not supported!' );
}
2014-04-11 22:30:26 +00:00
2014-04-25 08:13:43 +00:00
# Generate id
2014-04-11 22:30:26 +00:00
$id = str_replace ( '.' , '' , microtime ( true ));
while ( strlen ( $id ) < 14 ) $id .= 0 ;
2014-08-22 20:02:58 +00:00
# Set paths
2014-04-11 22:30:26 +00:00
$tmp_name = $file [ 'tmp_name' ];
2014-04-26 15:05:42 +00:00
$photo_name = md5 ( $id ) . $extension ;
2014-04-13 12:08:18 +00:00
$path = LYCHEE_UPLOADS_BIG . $photo_name ;
2014-04-11 22:30:26 +00:00
2014-08-22 20:02:58 +00:00
# Calculate checksum
$checksum = sha1_file ( $tmp_name );
2014-08-27 19:17:05 +00:00
if ( $checksum === false ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'Could not calculate checksum for photo' );
2015-06-28 21:09:41 +00:00
if ( $returnOnError === true ) return false ;
2014-08-27 19:17:05 +00:00
exit ( 'Error: Could not calculate checksum for photo!' );
}
2014-08-22 20:02:58 +00:00
# Check if image exists based on checksum
if ( $checksum === false ) {
$checksum = '' ;
$exists = false ;
2014-04-11 22:30:26 +00:00
} else {
2014-08-22 20:02:58 +00:00
2014-08-22 20:14:50 +00:00
$exists = $this -> exists ( $checksum );
if ( $exists !== false ) {
$photo_name = $exists [ 'photo_name' ];
$path = $exists [ 'path' ];
$path_thumb = $exists [ 'path_thumb' ];
2015-01-22 20:19:55 +00:00
$medium = ( $exists [ 'medium' ] === '1' ? 1 : 0 );
2014-08-22 20:02:58 +00:00
$exists = true ;
2014-05-08 18:50:18 +00:00
}
2014-08-22 20:02:58 +00:00
2014-04-11 22:30:26 +00:00
}
2014-08-22 20:02:58 +00:00
if ( $exists === false ) {
# Import if not uploaded via web
if ( ! is_uploaded_file ( $tmp_name )) {
if ( !@ copy ( $tmp_name , $path )) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'Could not copy photo to uploads' );
2015-06-28 21:09:41 +00:00
if ( $returnOnError === true ) return false ;
2014-08-22 20:02:58 +00:00
exit ( 'Error: Could not copy photo to uploads!' );
} else @ unlink ( $tmp_name );
} else {
if ( !@ move_uploaded_file ( $tmp_name , $path )) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'Could not move photo to uploads' );
2015-06-28 21:09:41 +00:00
if ( $returnOnError === true ) return false ;
2014-08-22 20:02:58 +00:00
exit ( 'Error: Could not move photo to uploads!' );
}
}
2015-06-27 19:03:27 +00:00
} else {
# Photo already exists
# Check if the user wants to skip duplicates
if ( $this -> settings [ 'skipDuplicates' ] === '1' ) {
Log :: notice ( $this -> database , __METHOD__ , __LINE__ , 'Skipped upload of existing photo because skipDuplicates is activated' );
2015-06-28 21:09:41 +00:00
if ( $returnOnError === true ) return false ;
2015-06-27 19:03:27 +00:00
exit ( 'Warning: This photo has been skipped because it\'s already in your library.' );
}
2014-08-22 20:02:58 +00:00
}
2014-07-20 14:45:30 +00:00
2014-04-11 22:30:26 +00:00
# Read infos
$info = $this -> getInfo ( $path );
# Use title of file if IPTC title missing
2014-08-29 19:16:10 +00:00
if ( $info [ 'title' ] === '' ) $info [ 'title' ] = substr ( basename ( $file [ 'name' ], $extension ), 0 , 30 );
2014-04-11 22:30:26 +00:00
# Use description parameter if set
if ( $description === '' ) $description = $info [ 'description' ];
2014-08-22 20:02:58 +00:00
if ( $exists === false ) {
# Set orientation based on EXIF data
2014-10-18 14:57:09 +00:00
if ( $file [ 'type' ] === 'image/jpeg' && isset ( $info [ 'orientation' ]) && $info [ 'orientation' ] !== '' ) {
$adjustFile = $this -> adjustFile ( $path , $info );
if ( $adjustFile !== false ) $info = $adjustFile ;
else Log :: notice ( $this -> database , __METHOD__ , __LINE__ , 'Skipped adjustment of photo (' . $info [ 'title' ] . ')' );
2014-08-22 20:02:58 +00:00
}
# Set original date
2014-10-08 20:55:36 +00:00
if ( $info [ 'takestamp' ] !== '' && $info [ 'takestamp' ] !== 0 ) @ touch ( $path , $info [ 'takestamp' ]);
2014-08-22 20:02:58 +00:00
# Create Thumb
2014-10-18 14:57:09 +00:00
if ( ! $this -> createThumb ( $path , $photo_name , $info [ 'type' ], $info [ 'width' ], $info [ 'height' ])) {
2014-08-22 20:02:58 +00:00
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'Could not create thumbnail for photo' );
2015-06-28 21:09:41 +00:00
if ( $returnOnError === true ) return false ;
2014-08-22 20:02:58 +00:00
exit ( 'Error: Could not create thumbnail for photo!' );
}
2014-04-11 22:30:26 +00:00
2014-10-10 22:52:15 +00:00
# Create Medium
2015-01-22 20:19:55 +00:00
if ( $this -> createMedium ( $path , $photo_name , $info [ 'width' ], $info [ 'height' ])) $medium = 1 ;
else $medium = 0 ;
2014-10-10 22:52:15 +00:00
2014-08-22 20:02:58 +00:00
# Set thumb url
$path_thumb = md5 ( $id ) . '.jpeg' ;
2014-04-13 10:10:49 +00:00
2014-05-08 18:50:18 +00:00
}
2014-04-11 22:30:26 +00:00
# Save to DB
2014-10-11 14:09:10 +00:00
$values = array ( LYCHEE_TABLE_PHOTOS , $id , $info [ 'title' ], $photo_name , $description , $tags , $info [ 'type' ], $info [ 'width' ], $info [ 'height' ], $info [ 'size' ], $info [ 'iso' ], $info [ 'aperture' ], $info [ 'make' ], $info [ 'model' ], $info [ 'shutter' ], $info [ 'focal' ], $info [ 'takestamp' ], $path_thumb , $albumID , $public , $star , $checksum , $medium );
$query = Database :: prepare ( $this -> database , " INSERT INTO ? (id, title, url, description, tags, type, width, height, size, iso, aperture, make, model, shutter, focal, takestamp, thumbUrl, album, public, star, checksum, medium) VALUES ('?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?') " , $values );
2014-04-11 22:30:26 +00:00
$result = $this -> database -> query ( $query );
2014-05-08 18:50:18 +00:00
if ( ! $result ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , $this -> database -> error );
2015-06-28 21:09:41 +00:00
if ( $returnOnError === true ) return false ;
2014-05-08 18:50:18 +00:00
exit ( 'Error: Could not save photo in database!' );
}
2014-04-11 22:30:26 +00:00
}
# Call plugins
$this -> plugins ( __METHOD__ , 1 , func_get_args ());
return true ;
}
2014-08-22 20:54:33 +00:00
private function exists ( $checksum , $photoID = null ) {
2014-08-22 20:14:50 +00:00
# Check dependencies
self :: dependencies ( isset ( $this -> database , $checksum ));
2014-08-22 20:54:33 +00:00
# Exclude $photoID from select when $photoID is set
2014-10-11 14:09:10 +00:00
if ( isset ( $photoID )) $query = Database :: prepare ( $this -> database , " SELECT id, url, thumbUrl, medium FROM ? WHERE checksum = '?' AND id <> '?' LIMIT 1 " , array ( LYCHEE_TABLE_PHOTOS , $checksum , $photoID ));
else $query = Database :: prepare ( $this -> database , " SELECT id, url, thumbUrl, medium FROM ? WHERE checksum = '?' LIMIT 1 " , array ( LYCHEE_TABLE_PHOTOS , $checksum ));
2014-08-22 20:54:33 +00:00
2014-08-22 20:14:50 +00:00
$result = $this -> database -> query ( $query );
if ( ! $result ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'Could not check for existing photos with the same checksum' );
return false ;
}
if ( $result -> num_rows === 1 ) {
2014-08-22 20:34:59 +00:00
$result = $result -> fetch_object ();
2014-08-22 20:14:50 +00:00
$return = array (
2014-08-22 20:34:59 +00:00
'photo_name' => $result -> url ,
'path' => LYCHEE_UPLOADS_BIG . $result -> url ,
2014-10-11 14:09:10 +00:00
'path_thumb' => $result -> thumbUrl ,
'medium' => $result -> medium
2014-08-22 20:14:50 +00:00
);
return $return ;
}
return false ;
}
2014-10-18 14:57:09 +00:00
private function createThumb ( $url , $filename , $type , $width , $height ) {
2014-04-11 22:30:26 +00:00
2014-04-19 19:07:36 +00:00
# Check dependencies
2014-10-18 14:57:09 +00:00
self :: dependencies ( isset ( $this -> database , $this -> settings , $url , $filename , $type , $width , $height ));
2014-04-11 22:30:26 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 0 , func_get_args ());
2014-10-18 14:57:09 +00:00
# Size of the thumbnail
$newWidth = 200 ;
$newHeight = 200 ;
$photoName = explode ( '.' , $filename );
2014-04-13 12:08:18 +00:00
$newUrl = LYCHEE_UPLOADS_THUMB . $photoName [ 0 ] . '.jpeg' ;
$newUrl2x = LYCHEE_UPLOADS_THUMB . $photoName [ 0 ] . '@2x.jpeg' ;
2014-04-11 22:30:26 +00:00
2014-10-10 22:52:15 +00:00
# Create thumbnails with Imagick
2014-08-29 22:11:26 +00:00
if ( extension_loaded ( 'imagick' ) && $this -> settings [ 'imagick' ] === '1' ) {
2014-04-11 22:30:26 +00:00
# Read image
$thumb = new Imagick ();
$thumb -> readImage ( $url );
$thumb -> setImageCompressionQuality ( $this -> settings [ 'thumbQuality' ]);
$thumb -> setImageFormat ( 'jpeg' );
# Copy image for 2nd thumb version
$thumb2x = clone $thumb ;
# Create 1st version
2014-10-18 14:57:09 +00:00
$thumb -> cropThumbnailImage ( $newWidth , $newHeight );
2014-04-11 22:30:26 +00:00
$thumb -> writeImage ( $newUrl );
2014-04-19 15:32:33 +00:00
$thumb -> clear ();
$thumb -> destroy ();
2014-04-11 22:30:26 +00:00
# Create 2nd version
2014-10-18 14:57:09 +00:00
$thumb2x -> cropThumbnailImage ( $newWidth * 2 , $newHeight * 2 );
2014-04-11 22:30:26 +00:00
$thumb2x -> writeImage ( $newUrl2x );
$thumb2x -> clear ();
$thumb2x -> destroy ();
} else {
2014-10-18 14:57:09 +00:00
# Create image
$thumb = imagecreatetruecolor ( $newWidth , $newHeight );
$thumb2x = imagecreatetruecolor ( $newWidth * 2 , $newHeight * 2 );
2014-10-10 22:52:15 +00:00
2014-10-18 14:57:09 +00:00
# Set position
if ( $width < $height ) {
$newSize = $width ;
2014-04-11 22:30:26 +00:00
$startWidth = 0 ;
2014-10-18 14:57:09 +00:00
$startHeight = $height / 2 - $width / 2 ;
2014-04-11 22:30:26 +00:00
} else {
2014-10-18 14:57:09 +00:00
$newSize = $height ;
$startWidth = $width / 2 - $height / 2 ;
2014-04-11 22:30:26 +00:00
$startHeight = 0 ;
}
# Create new image
2014-10-18 14:57:09 +00:00
switch ( $type ) {
2014-04-11 22:30:26 +00:00
case 'image/jpeg' : $sourceImg = imagecreatefromjpeg ( $url ); break ;
case 'image/png' : $sourceImg = imagecreatefrompng ( $url ); break ;
case 'image/gif' : $sourceImg = imagecreatefromgif ( $url ); break ;
2014-05-08 18:50:18 +00:00
default : Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'Type of photo is not supported' );
return false ;
break ;
2014-04-11 22:30:26 +00:00
}
2014-04-19 15:32:33 +00:00
# Create thumb
2014-10-18 14:57:09 +00:00
fastimagecopyresampled ( $thumb , $sourceImg , 0 , 0 , $startWidth , $startHeight , $newWidth , $newHeight , $newSize , $newSize );
2014-04-11 22:30:26 +00:00
imagejpeg ( $thumb , $newUrl , $this -> settings [ 'thumbQuality' ]);
2014-04-19 15:32:33 +00:00
imagedestroy ( $thumb );
# Create retina thumb
2014-10-18 14:57:09 +00:00
fastimagecopyresampled ( $thumb2x , $sourceImg , 0 , 0 , $startWidth , $startHeight , $newWidth * 2 , $newHeight * 2 , $newSize , $newSize );
2014-04-11 22:30:26 +00:00
imagejpeg ( $thumb2x , $newUrl2x , $this -> settings [ 'thumbQuality' ]);
2014-04-19 15:32:33 +00:00
imagedestroy ( $thumb2x );
# Free memory
imagedestroy ( $sourceImg );
2014-04-11 22:30:26 +00:00
}
# Call plugins
$this -> plugins ( __METHOD__ , 1 , func_get_args ());
return true ;
}
2014-10-11 14:09:10 +00:00
private function createMedium ( $url , $filename , $width , $height ) {
2014-10-10 22:52:15 +00:00
2015-04-06 17:08:58 +00:00
# Function creates a smaller version of a photo when its size is bigger than a preset size
# Excepts the following:
# (string) $url = Path to the photo-file
# (string) $filename = Name of the photo-file
# (int) $width = Width of the photo
# (int) $height = Height of the photo
# Returns the following
# (boolean) true = Success
# (boolean) false = Failure
2014-10-10 22:52:15 +00:00
# Check dependencies
self :: dependencies ( isset ( $this -> database , $this -> settings , $url , $filename , $width , $height ));
# Call plugins
$this -> plugins ( __METHOD__ , 0 , func_get_args ());
2014-12-06 13:29:17 +00:00
# Set to true when creation of medium-photo failed
$error = false ;
2014-10-18 14:57:09 +00:00
# Size of the medium-photo
2014-10-11 14:09:10 +00:00
# When changing these values,
# also change the size detection in the front-end
2014-10-18 14:57:09 +00:00
$newWidth = 1920 ;
$newHeight = 1080 ;
2014-10-11 14:09:10 +00:00
2014-12-06 13:29:17 +00:00
# Check permissions
if ( hasPermissions ( LYCHEE_UPLOADS_MEDIUM ) === false ) {
# Permissions are missing
Log :: notice ( $this -> database , __METHOD__ , __LINE__ , 'Skipped creation of medium-photo, because uploads/medium/ is missing or not readable and writable.' );
$error = true ;
}
2014-10-10 22:52:15 +00:00
# Is photo big enough?
2014-10-11 14:09:10 +00:00
# Is medium activated?
# Is Imagick installed and activated?
2014-12-06 13:29:17 +00:00
if (( $error === false ) &&
( $width > $newWidth || $height > $newHeight ) &&
2014-10-11 14:09:10 +00:00
( $this -> settings [ 'medium' ] === '1' ) &&
2014-10-10 22:52:15 +00:00
( extension_loaded ( 'imagick' ) && $this -> settings [ 'imagick' ] === '1' )) {
$newUrl = LYCHEE_UPLOADS_MEDIUM . $filename ;
# Read image
$medium = new Imagick ();
$medium -> readImage ( $url );
2014-12-06 13:29:17 +00:00
# Adjust image
2014-10-10 22:52:15 +00:00
$medium -> scaleImage ( $newWidth , $newHeight , true );
2014-12-06 13:29:17 +00:00
# Save image
try { $medium -> writeImage ( $newUrl ); }
catch ( ImagickException $err ) {
Log :: notice ( $this -> database , __METHOD__ , __LINE__ , 'Could not save medium-photo: ' . $err -> getMessage ());
$error = true ;
}
2014-10-10 22:52:15 +00:00
$medium -> clear ();
$medium -> destroy ();
} else {
# Photo too small or
2014-10-11 14:09:10 +00:00
# Medium is deactivated or
2014-10-10 22:52:15 +00:00
# Imagick not installed
$error = true ;
}
# Call plugins
$this -> plugins ( __METHOD__ , 1 , func_get_args ());
if ( $error === true ) return false ;
return true ;
}
2014-08-26 18:26:14 +00:00
public function adjustFile ( $path , $info ) {
2014-04-12 12:15:21 +00:00
2015-04-06 17:08:58 +00:00
# Function rotates and flips a photo based on its EXIF orientation
# Excepts the following:
# (string) $path = Path to the photo-file
# (array) $info = ['orientation', 'width', 'height']
# Returns the following
# (array) $info = ['orientation', 'width', 'height'] = Success
# (boolean) false = Failure
2014-04-19 19:07:36 +00:00
# Check dependencies
2014-06-25 12:50:49 +00:00
self :: dependencies ( isset ( $path , $info ));
2014-04-12 12:15:21 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 0 , func_get_args ());
2014-10-18 14:57:09 +00:00
$swapSize = false ;
2014-08-29 22:11:26 +00:00
if ( extension_loaded ( 'imagick' ) && $this -> settings [ 'imagick' ] === '1' ) {
2014-04-12 12:15:21 +00:00
switch ( $info [ 'orientation' ]) {
case 3 :
$rotateImage = 180 ;
break ;
case 6 :
2014-10-18 14:57:09 +00:00
$rotateImage = 90 ;
$swapSize = true ;
2014-04-12 12:15:21 +00:00
break ;
case 8 :
2014-10-18 14:57:09 +00:00
$rotateImage = 270 ;
$swapSize = true ;
break ;
default :
return false ;
2014-04-12 12:15:21 +00:00
break ;
}
2014-04-19 15:32:33 +00:00
if ( $rotateImage !== 0 ) {
2014-04-12 12:15:21 +00:00
$image = new Imagick ();
$image -> readImage ( $path );
$image -> rotateImage ( new ImagickPixel (), $rotateImage );
2014-10-18 14:57:09 +00:00
$image -> setImageOrientation ( 1 );
2014-04-12 12:15:21 +00:00
$image -> writeImage ( $path );
$image -> clear ();
$image -> destroy ();
}
} else {
2014-04-19 15:32:33 +00:00
$newWidth = $info [ 'width' ];
$newHeight = $info [ 'height' ];
$sourceImg = imagecreatefromjpeg ( $path );
2014-04-12 12:15:21 +00:00
switch ( $info [ 'orientation' ]) {
case 2 :
# mirror
# not yet implemented
2014-10-18 14:57:09 +00:00
return false ;
2014-04-12 12:15:21 +00:00
break ;
case 3 :
2014-04-19 15:32:33 +00:00
$sourceImg = imagerotate ( $sourceImg , - 180 , 0 );
2014-04-12 12:15:21 +00:00
break ;
case 4 :
# rotate 180 and mirror
# not yet implemented
2014-10-18 14:57:09 +00:00
return false ;
2014-04-12 12:15:21 +00:00
break ;
case 5 :
# rotate 90 and mirror
# not yet implemented
2014-10-18 14:57:09 +00:00
return false ;
2014-04-12 12:15:21 +00:00
break ;
case 6 :
2014-04-19 15:32:33 +00:00
$sourceImg = imagerotate ( $sourceImg , - 90 , 0 );
$newWidth = $info [ 'height' ];
$newHeight = $info [ 'width' ];
2014-10-18 14:57:09 +00:00
$swapSize = true ;
2014-04-12 12:15:21 +00:00
break ;
case 7 :
# rotate -90 and mirror
# not yet implemented
2014-10-18 14:57:09 +00:00
return false ;
2014-04-12 12:15:21 +00:00
break ;
case 8 :
2014-04-19 15:32:33 +00:00
$sourceImg = imagerotate ( $sourceImg , 90 , 0 );
$newWidth = $info [ 'height' ];
$newHeight = $info [ 'width' ];
2014-10-18 14:57:09 +00:00
$swapSize = true ;
2014-04-12 12:15:21 +00:00
break ;
2014-10-18 14:57:09 +00:00
default :
return false ;
break ;
2014-04-12 12:15:21 +00:00
2014-10-18 14:57:09 +00:00
}
2014-04-19 15:32:33 +00:00
2014-10-18 14:57:09 +00:00
# Recreate photo
$newSourceImg = imagecreatetruecolor ( $newWidth , $newHeight );
imagecopyresampled ( $newSourceImg , $sourceImg , 0 , 0 , 0 , 0 , $newWidth , $newHeight , $newWidth , $newHeight );
imagejpeg ( $newSourceImg , $path , 100 );
2014-04-19 15:32:33 +00:00
2014-10-18 14:57:09 +00:00
# Free memory
imagedestroy ( $sourceImg );
imagedestroy ( $newSourceImg );
2014-04-12 12:15:21 +00:00
}
# Call plugins
$this -> plugins ( __METHOD__ , 1 , func_get_args ());
2014-10-18 14:57:09 +00:00
# SwapSize should be true when the image has been rotated
# Return new dimensions in this case
if ( $swapSize === true ) {
$swapSize = $info [ 'width' ];
$info [ 'width' ] = $info [ 'height' ];
$info [ 'height' ] = $swapSize ;
}
return $info ;
2014-04-12 12:15:21 +00:00
}
2015-03-11 23:11:16 +00:00
public static function prepareData ( $data ) {
2015-04-06 17:08:58 +00:00
# Function turns photo-attributes into a front-end friendly format. Note that some attributes remain unchanged.
# Excepts the following:
# (array) $data = ['id', 'title', 'tags', 'public', 'star', 'album', 'thumbUrl', 'takestamp', 'url']
# Returns the following:
# (array) $photo
2015-03-11 23:11:16 +00:00
2015-03-12 11:57:48 +00:00
# Check dependencies
self :: dependencies ( isset ( $data ));
2015-03-11 23:11:16 +00:00
# Init
$photo = null ;
2015-03-12 11:57:48 +00:00
# Set unchanged attributes
2015-03-11 23:11:16 +00:00
$photo [ 'id' ] = $data [ 'id' ];
$photo [ 'title' ] = $data [ 'title' ];
$photo [ 'tags' ] = $data [ 'tags' ];
$photo [ 'public' ] = $data [ 'public' ];
$photo [ 'star' ] = $data [ 'star' ];
$photo [ 'album' ] = $data [ 'album' ];
# Parse urls
$photo [ 'thumbUrl' ] = LYCHEE_URL_UPLOADS_THUMB . $data [ 'thumbUrl' ];
$photo [ 'url' ] = LYCHEE_URL_UPLOADS_BIG . $data [ 'url' ];
# Use takestamp as sysdate when possible
if ( isset ( $data [ 'takestamp' ]) && $data [ 'takestamp' ] !== '0' ) {
# Use takestamp
$photo [ 'cameraDate' ] = '1' ;
$photo [ 'sysdate' ] = date ( 'd F Y' , $data [ 'takestamp' ]);
} else {
# Use sysstamp from the id
$photo [ 'cameraDate' ] = '0' ;
$photo [ 'sysdate' ] = date ( 'd F Y' , substr ( $data [ 'id' ], 0 , - 4 ));
}
return $photo ;
}
2014-04-05 14:02:53 +00:00
public function get ( $albumID ) {
2015-04-06 16:48:52 +00:00
# Functions returns data of a photo
# Excepts the following:
# (string) $albumID = Album which is currently visible to the user
# Returns the following:
# (array) $photo
2014-04-19 19:07:36 +00:00
# Check dependencies
2014-06-25 12:50:49 +00:00
self :: dependencies ( isset ( $this -> database , $this -> photoIDs ));
2014-04-05 14:02:53 +00:00
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 0 , func_get_args ());
2014-04-05 14:02:53 +00:00
# Get photo
2014-08-30 05:05:26 +00:00
$query = Database :: prepare ( $this -> database , " SELECT * FROM ? WHERE id = '?' LIMIT 1 " , array ( LYCHEE_TABLE_PHOTOS , $this -> photoIDs ));
2014-08-29 19:16:10 +00:00
$photos = $this -> database -> query ( $query );
2014-04-05 14:02:53 +00:00
$photo = $photos -> fetch_assoc ();
# Parse photo
2014-04-05 14:22:46 +00:00
$photo [ 'sysdate' ] = date ( 'd M. Y' , substr ( $photo [ 'id' ], 0 , - 4 ));
2014-04-13 10:35:59 +00:00
if ( strlen ( $photo [ 'takestamp' ]) > 1 ) $photo [ 'takedate' ] = date ( 'd M. Y' , $photo [ 'takestamp' ]);
2014-04-05 14:02:53 +00:00
2014-10-11 14:09:10 +00:00
# Parse medium
2015-02-28 22:42:28 +00:00
if ( $photo [ 'medium' ] === '1' ) $photo [ 'medium' ] = LYCHEE_URL_UPLOADS_MEDIUM . $photo [ 'url' ];
else $photo [ 'medium' ] = '' ;
2014-10-11 14:09:10 +00:00
# Parse paths
2014-08-23 15:07:46 +00:00
$photo [ 'url' ] = LYCHEE_URL_UPLOADS_BIG . $photo [ 'url' ];
$photo [ 'thumbUrl' ] = LYCHEE_URL_UPLOADS_THUMB . $photo [ 'thumbUrl' ];
2014-07-12 18:12:38 +00:00
2014-04-05 14:02:53 +00:00
if ( $albumID != 'false' ) {
2015-04-06 16:48:52 +00:00
# Only show photo as public when parent album is public
# Check if parent album is not 'Unsorted'
if ( $photo [ 'album' ] !== '0' ) {
2014-04-05 14:02:53 +00:00
# Get album
2014-08-30 05:05:26 +00:00
$query = Database :: prepare ( $this -> database , " SELECT public FROM ? WHERE id = '?' LIMIT 1 " , array ( LYCHEE_TABLE_ALBUMS , $photo [ 'album' ]));
2014-08-29 19:16:10 +00:00
$albums = $this -> database -> query ( $query );
$album = $albums -> fetch_assoc ();
2014-04-05 14:02:53 +00:00
# Parse album
2015-04-06 16:48:52 +00:00
$photo [ 'public' ] = ( $album [ 'public' ] === '1' ? '2' : $photo [ 'public' ]);
2014-04-05 14:02:53 +00:00
}
$photo [ 'original_album' ] = $photo [ 'album' ];
2014-07-18 22:00:00 +00:00
$photo [ 'album' ] = $albumID ;
2014-04-05 14:02:53 +00:00
}
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 1 , func_get_args ());
2014-04-05 14:02:53 +00:00
return $photo ;
}
2014-08-26 18:26:14 +00:00
public function getInfo ( $url ) {
2014-04-11 22:30:26 +00:00
2015-04-06 16:48:52 +00:00
# Functions returns information and metadata of a photo
# Excepts the following:
# (string) $url = Path to photo-file
# Returns the following:
# (array) $return
2014-04-19 19:07:36 +00:00
# Check dependencies
2014-06-25 12:50:49 +00:00
self :: dependencies ( isset ( $this -> database , $url ));
2014-04-11 22:30:26 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 0 , func_get_args ());
$iptcArray = array ();
$info = getimagesize ( $url , $iptcArray );
# General information
$return [ 'type' ] = $info [ 'mime' ];
$return [ 'width' ] = $info [ 0 ];
$return [ 'height' ] = $info [ 1 ];
# Size
$size = filesize ( $url ) / 1024 ;
if ( $size >= 1024 ) $return [ 'size' ] = round ( $size / 1024 , 1 ) . ' MB' ;
else $return [ 'size' ] = round ( $size , 1 ) . ' KB' ;
# IPTC Metadata Fallback
$return [ 'title' ] = '' ;
$return [ 'description' ] = '' ;
# IPTC Metadata
if ( isset ( $iptcArray [ 'APP13' ])) {
$iptcInfo = iptcparse ( $iptcArray [ 'APP13' ]);
if ( is_array ( $iptcInfo )) {
$temp = @ $iptcInfo [ '2#105' ][ 0 ];
if ( isset ( $temp ) && strlen ( $temp ) > 0 ) $return [ 'title' ] = $temp ;
$temp = @ $iptcInfo [ '2#120' ][ 0 ];
if ( isset ( $temp ) && strlen ( $temp ) > 0 ) $return [ 'description' ] = $temp ;
2014-08-26 14:07:59 +00:00
$temp = @ $iptcInfo [ '2#005' ][ 0 ];
if ( isset ( $temp ) && strlen ( $temp ) > 0 && $return [ 'title' ] === '' ) $return [ 'title' ] = $temp ;
2014-04-11 22:30:26 +00:00
}
}
# EXIF Metadata Fallback
$return [ 'orientation' ] = '' ;
$return [ 'iso' ] = '' ;
$return [ 'aperture' ] = '' ;
$return [ 'make' ] = '' ;
$return [ 'model' ] = '' ;
$return [ 'shutter' ] = '' ;
$return [ 'focal' ] = '' ;
2014-04-26 14:48:40 +00:00
$return [ 'takestamp' ] = 0 ;
2014-04-11 22:30:26 +00:00
# Read EXIF
if ( $info [ 'mime' ] == 'image/jpeg' ) $exif = @ exif_read_data ( $url , 'EXIF' , 0 );
else $exif = false ;
# EXIF Metadata
if ( $exif !== false ) {
if ( isset ( $exif [ 'Orientation' ])) $return [ 'orientation' ] = $exif [ 'Orientation' ];
else if ( isset ( $exif [ 'IFD0' ][ 'Orientation' ])) $return [ 'orientation' ] = $exif [ 'IFD0' ][ 'Orientation' ];
$temp = @ $exif [ 'ISOSpeedRatings' ];
if ( isset ( $temp )) $return [ 'iso' ] = $temp ;
$temp = @ $exif [ 'COMPUTED' ][ 'ApertureFNumber' ];
if ( isset ( $temp )) $return [ 'aperture' ] = $temp ;
$temp = @ $exif [ 'Make' ];
2014-04-25 14:36:31 +00:00
if ( isset ( $temp )) $return [ 'make' ] = trim ( $temp );
2014-04-11 22:30:26 +00:00
$temp = @ $exif [ 'Model' ];
2014-04-25 14:36:31 +00:00
if ( isset ( $temp )) $return [ 'model' ] = trim ( $temp );
2014-04-11 22:30:26 +00:00
$temp = @ $exif [ 'ExposureTime' ];
2014-12-19 20:39:43 +00:00
if ( isset ( $temp )) $return [ 'shutter' ] = $exif [ 'ExposureTime' ] . ' s' ;
2014-04-11 22:30:26 +00:00
$temp = @ $exif [ 'FocalLength' ];
2014-12-21 21:50:56 +00:00
if ( isset ( $temp )) {
if ( strpos ( $temp , '/' ) !== FALSE ) {
$temp = explode ( '/' , $temp , 2 );
$temp = $temp [ 0 ] / $temp [ 1 ];
$temp = round ( $temp , 1 );
$return [ 'focal' ] = $temp . ' mm' ;
}
$return [ 'focal' ] = $temp . ' mm' ;
}
2014-04-11 22:30:26 +00:00
$temp = @ $exif [ 'DateTimeOriginal' ];
if ( isset ( $temp )) $return [ 'takestamp' ] = strtotime ( $temp );
}
# Call plugins
$this -> plugins ( __METHOD__ , 1 , func_get_args ());
return $return ;
}
2014-04-05 14:02:53 +00:00
public function getArchive () {
2015-04-06 16:48:52 +00:00
# Functions starts a download of a photo
# Returns the following:
# (boolean + output) true = Success
# (boolean) false = Failure
2014-04-19 19:07:36 +00:00
# Check dependencies
2014-06-25 12:50:49 +00:00
self :: dependencies ( isset ( $this -> database , $this -> photoIDs ));
2014-04-05 14:02:53 +00:00
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 0 , func_get_args ());
2014-04-05 14:02:53 +00:00
# Get photo
2014-08-30 05:05:26 +00:00
$query = Database :: prepare ( $this -> database , " SELECT title, url FROM ? WHERE id = '?' LIMIT 1 " , array ( LYCHEE_TABLE_PHOTOS , $this -> photoIDs ));
2014-08-29 19:16:10 +00:00
$photos = $this -> database -> query ( $query );
2014-04-05 14:02:53 +00:00
$photo = $photos -> fetch_object ();
2015-04-06 16:48:52 +00:00
# Error in database query
if ( ! $photos ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , $this -> database -> error );
return false ;
}
# Photo not found
if ( $photo === null ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'Album not found. Cannot start download.' );
return false ;
}
2014-04-05 14:02:53 +00:00
# Get extension
2014-05-20 10:44:08 +00:00
$extension = getExtension ( $photo -> url );
2014-05-08 18:50:18 +00:00
if ( $extension === false ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'Invalid photo extension' );
return false ;
}
2014-04-05 14:02:53 +00:00
2014-08-30 17:18:09 +00:00
# Illicit chars
$badChars = array_merge (
array_map ( 'chr' , range ( 0 , 31 )),
array ( " < " , " > " , " : " , '"' , " / " , " \\ " , " | " , " ? " , " * " )
);
2014-04-05 14:02:53 +00:00
# Parse title
if ( $photo -> title == '' ) $photo -> title = 'Untitled' ;
2014-08-30 17:18:09 +00:00
# Escape title
2014-08-30 18:03:38 +00:00
$photo -> title = str_replace ( $badChars , '' , $photo -> title );
2014-08-30 17:18:09 +00:00
2014-04-05 14:02:53 +00:00
# Set headers
header ( " Content-Type: application/octet-stream " );
2014-05-20 10:31:48 +00:00
header ( " Content-Disposition: attachment; filename= \" " . $photo -> title . $extension . " \" " );
2014-04-13 12:08:18 +00:00
header ( " Content-Length: " . filesize ( LYCHEE_UPLOADS_BIG . $photo -> url ));
2014-04-05 14:02:53 +00:00
# Send file
2014-04-13 12:08:18 +00:00
readfile ( LYCHEE_UPLOADS_BIG . $photo -> url );
2014-04-05 14:02:53 +00:00
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 1 , func_get_args ());
2014-04-05 14:02:53 +00:00
return true ;
}
2014-04-25 08:13:43 +00:00
public function setTitle ( $title ) {
2014-04-05 14:02:53 +00:00
2015-04-06 16:48:52 +00:00
# Functions sets the title of a photo
# Excepts the following:
# (string) $title = Title with a maximum length of 50 chars
# Returns the following:
# (boolean) true = Success
# (boolean) false = Failure
2014-04-19 19:07:36 +00:00
# Check dependencies
2014-06-25 12:50:49 +00:00
self :: dependencies ( isset ( $this -> database , $this -> photoIDs ));
2014-04-05 14:02:53 +00:00
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 0 , func_get_args ());
2014-04-05 14:02:53 +00:00
# Set title
2014-08-30 05:05:26 +00:00
$query = Database :: prepare ( $this -> database , " UPDATE ? SET title = '?' WHERE id IN (?) " , array ( LYCHEE_TABLE_PHOTOS , $title , $this -> photoIDs ));
2014-08-29 19:16:10 +00:00
$result = $this -> database -> query ( $query );
2014-04-05 14:02:53 +00:00
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 1 , func_get_args ());
2014-05-08 18:50:18 +00:00
if ( ! $result ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , $this -> database -> error );
return false ;
}
2014-04-05 14:02:53 +00:00
return true ;
}
2014-04-25 08:13:43 +00:00
public function setDescription ( $description ) {
2014-04-05 14:02:53 +00:00
2015-04-06 16:48:52 +00:00
# Functions sets the description of a photo
# Excepts the following:
# (string) $description = Description with a maximum length of 1000 chars
# Returns the following:
# (boolean) true = Success
# (boolean) false = Failure
2014-04-19 19:07:36 +00:00
# Check dependencies
2014-06-25 12:50:49 +00:00
self :: dependencies ( isset ( $this -> database , $this -> photoIDs ));
2014-04-05 14:02:53 +00:00
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 0 , func_get_args ());
2014-04-05 14:02:53 +00:00
# Set description
2014-08-30 05:05:26 +00:00
$query = Database :: prepare ( $this -> database , " UPDATE ? SET description = '?' WHERE id IN ('?') " , array ( LYCHEE_TABLE_PHOTOS , $description , $this -> photoIDs ));
2014-08-29 19:16:10 +00:00
$result = $this -> database -> query ( $query );
2014-04-05 14:02:53 +00:00
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 1 , func_get_args ());
2014-05-08 18:50:18 +00:00
if ( ! $result ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , $this -> database -> error );
return false ;
}
2014-04-05 14:02:53 +00:00
return true ;
}
public function setStar () {
2015-04-06 16:48:52 +00:00
# Functions stars a photo
# Returns the following:
# (boolean) true = Success
# (boolean) false = Failure
2014-04-19 19:07:36 +00:00
# Check dependencies
2014-06-25 12:50:49 +00:00
self :: dependencies ( isset ( $this -> database , $this -> photoIDs ));
2014-04-05 14:02:53 +00:00
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 0 , func_get_args ());
2014-04-05 14:02:53 +00:00
# Init vars
$error = false ;
# Get photos
2014-08-30 05:05:26 +00:00
$query = Database :: prepare ( $this -> database , " SELECT id, star FROM ? WHERE id IN (?) " , array ( LYCHEE_TABLE_PHOTOS , $this -> photoIDs ));
2014-08-29 19:16:10 +00:00
$photos = $this -> database -> query ( $query );
2014-04-05 14:02:53 +00:00
# For each photo
while ( $photo = $photos -> fetch_object ()) {
# Invert star
$star = ( $photo -> star == 0 ? 1 : 0 );
# Set star
2014-08-30 05:05:26 +00:00
$query = Database :: prepare ( $this -> database , " UPDATE ? SET star = '?' WHERE id = '?' " , array ( LYCHEE_TABLE_PHOTOS , $star , $photo -> id ));
2014-08-29 19:16:10 +00:00
$star = $this -> database -> query ( $query );
2014-04-05 14:02:53 +00:00
if ( ! $star ) $error = true ;
}
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 1 , func_get_args ());
2014-05-30 14:57:15 +00:00
if ( $error === true ) {
2014-05-08 18:50:18 +00:00
Log :: error ( $this -> database , __METHOD__ , __LINE__ , $this -> database -> error );
return false ;
}
2014-04-05 14:02:53 +00:00
return true ;
}
2014-04-25 08:13:43 +00:00
public function getPublic ( $password ) {
2014-04-05 14:02:53 +00:00
2015-04-06 16:48:52 +00:00
# Functions checks if photo or parent album is public
# Returns the following:
# (int) 0 = Photo private and parent album private
# (int) 1 = Album public, but password incorrect
# (int) 2 = Photo public or album public and password correct
2014-04-19 19:07:36 +00:00
# Check dependencies
2014-06-25 12:50:49 +00:00
self :: dependencies ( isset ( $this -> database , $this -> photoIDs ));
2014-04-05 14:02:53 +00:00
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 0 , func_get_args ());
2014-04-05 14:02:53 +00:00
# Get photo
2014-08-30 05:05:26 +00:00
$query = Database :: prepare ( $this -> database , " SELECT public, album FROM ? WHERE id = '?' LIMIT 1 " , array ( LYCHEE_TABLE_PHOTOS , $this -> photoIDs ));
2014-08-29 19:16:10 +00:00
$photos = $this -> database -> query ( $query );
2014-04-05 14:02:53 +00:00
$photo = $photos -> fetch_object ();
# Check if public
2015-04-06 16:48:52 +00:00
if ( $photo -> public === '1' ) {
# Photo public
return 2 ;
} else {
# Check if album public
2014-04-05 14:02:53 +00:00
$album = new Album ( $this -> database , null , null , $photo -> album );
2014-08-29 19:16:10 +00:00
$agP = $album -> getPublic ();
2015-04-06 16:48:52 +00:00
$acP = $album -> checkPassword ( $password );
# Album public and password correct
if ( $agP === true && $acP === true ) return 2 ;
# Album public, but password incorrect
if ( $agP === true && $acP === false ) return 1 ;
2014-04-05 14:02:53 +00:00
}
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 1 , func_get_args ());
2015-04-06 16:48:52 +00:00
# Photo private
return 0 ;
2014-04-05 14:02:53 +00:00
}
public function setPublic () {
2015-04-06 16:48:52 +00:00
# Functions toggles the public property of a photo
# Returns the following:
# (boolean) true = Success
# (boolean) false = Failure
2014-04-19 19:07:36 +00:00
# Check dependencies
2014-06-25 12:50:49 +00:00
self :: dependencies ( isset ( $this -> database , $this -> photoIDs ));
2014-04-05 14:02:53 +00:00
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 0 , func_get_args ());
2014-04-05 14:02:53 +00:00
# Get public
2014-08-30 05:05:26 +00:00
$query = Database :: prepare ( $this -> database , " SELECT public FROM ? WHERE id = '?' LIMIT 1 " , array ( LYCHEE_TABLE_PHOTOS , $this -> photoIDs ));
2014-08-29 19:16:10 +00:00
$photos = $this -> database -> query ( $query );
2014-04-05 14:02:53 +00:00
$photo = $photos -> fetch_object ();
# Invert public
$public = ( $photo -> public == 0 ? 1 : 0 );
# Set public
2014-08-30 05:05:26 +00:00
$query = Database :: prepare ( $this -> database , " UPDATE ? SET public = '?' WHERE id = '?' " , array ( LYCHEE_TABLE_PHOTOS , $public , $this -> photoIDs ));
2014-08-29 19:16:10 +00:00
$result = $this -> database -> query ( $query );
2014-04-05 14:02:53 +00:00
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 1 , func_get_args ());
2014-05-08 18:50:18 +00:00
if ( ! $result ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , $this -> database -> error );
return false ;
}
2014-04-05 14:02:53 +00:00
return true ;
}
function setAlbum ( $albumID ) {
2015-04-06 16:48:52 +00:00
# Functions sets the parent album of a photo
# Returns the following:
# (boolean) true = Success
# (boolean) false = Failure
2014-04-19 19:07:36 +00:00
# Check dependencies
2014-06-25 12:50:49 +00:00
self :: dependencies ( isset ( $this -> database , $this -> photoIDs ));
2014-04-05 14:02:53 +00:00
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 0 , func_get_args ());
2014-04-05 14:02:53 +00:00
# Set album
2014-08-30 05:05:26 +00:00
$query = Database :: prepare ( $this -> database , " UPDATE ? SET album = '?' WHERE id IN (?) " , array ( LYCHEE_TABLE_PHOTOS , $albumID , $this -> photoIDs ));
2014-08-29 19:16:10 +00:00
$result = $this -> database -> query ( $query );
2014-04-05 14:02:53 +00:00
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 1 , func_get_args ());
2014-05-08 18:50:18 +00:00
if ( ! $result ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , $this -> database -> error );
return false ;
}
2014-04-05 14:02:53 +00:00
return true ;
}
public function setTags ( $tags ) {
2015-04-06 16:48:52 +00:00
# Functions sets the tags of a photo
# Excepts the following:
# (string) $tags = Comma separated list of tags with a maximum length of 1000 chars
# Returns the following:
# (boolean) true = Success
# (boolean) false = Failure
2014-04-19 19:07:36 +00:00
# Check dependencies
2014-06-25 12:50:49 +00:00
self :: dependencies ( isset ( $this -> database , $this -> photoIDs ));
2014-04-05 14:02:53 +00:00
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 0 , func_get_args ());
2014-04-05 14:02:53 +00:00
# Parse tags
$tags = preg_replace ( '/(\ ,\ )|(\ ,)|(,\ )|(,{1,}\ {0,})|(,$|^,)/' , ',' , $tags );
2014-04-18 19:27:52 +00:00
$tags = preg_replace ( '/,$|^,|(\ ){0,}$/' , '' , $tags );
2014-04-05 14:02:53 +00:00
# Set tags
2014-08-30 05:05:26 +00:00
$query = Database :: prepare ( $this -> database , " UPDATE ? SET tags = '?' WHERE id IN (?) " , array ( LYCHEE_TABLE_PHOTOS , $tags , $this -> photoIDs ));
2014-08-29 19:16:10 +00:00
$result = $this -> database -> query ( $query );
2014-04-05 14:02:53 +00:00
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 1 , func_get_args ());
2014-05-08 18:50:18 +00:00
if ( ! $result ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , $this -> database -> error );
return false ;
}
2014-04-05 14:02:53 +00:00
return true ;
}
2014-08-22 21:31:09 +00:00
public function duplicate () {
2015-04-06 16:48:52 +00:00
# Functions duplicates a photo
# Returns the following:
# (boolean) true = Success
# (boolean) false = Failure
2014-08-22 21:31:09 +00:00
# Check dependencies
self :: dependencies ( isset ( $this -> database , $this -> photoIDs ));
# Call plugins
$this -> plugins ( __METHOD__ , 0 , func_get_args ());
# Get photos
2014-08-30 05:05:26 +00:00
$query = Database :: prepare ( $this -> database , " SELECT id, checksum FROM ? WHERE id IN (?) " , array ( LYCHEE_TABLE_PHOTOS , $this -> photoIDs ));
2014-08-29 19:16:10 +00:00
$photos = $this -> database -> query ( $query );
2014-08-22 21:31:09 +00:00
if ( ! $photos ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , $this -> database -> error );
return false ;
}
# For each photo
while ( $photo = $photos -> fetch_object ()) {
# Generate id
$id = str_replace ( '.' , '' , microtime ( true ));
while ( strlen ( $id ) < 14 ) $id .= 0 ;
# Duplicate entry
2014-08-30 05:05:26 +00:00
$values = array ( LYCHEE_TABLE_PHOTOS , $id , LYCHEE_TABLE_PHOTOS , $photo -> id );
2014-08-29 19:16:10 +00:00
$query = Database :: prepare ( $this -> database , " INSERT INTO ? (id, title, url, description, tags, type, width, height, size, iso, aperture, make, model, shutter, focal, takestamp, thumbUrl, album, public, star, checksum) SELECT '?' AS id, title, url, description, tags, type, width, height, size, iso, aperture, make, model, shutter, focal, takestamp, thumbUrl, album, public, star, checksum FROM ? WHERE id = '?' " , $values );
$duplicate = $this -> database -> query ( $query );
2014-08-22 21:31:09 +00:00
if ( ! $duplicate ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , $this -> database -> error );
return false ;
}
}
return true ;
}
2014-04-05 14:02:53 +00:00
public function delete () {
2015-04-06 16:48:52 +00:00
# Functions deletes a photo with all its data and files
# Returns the following:
# (boolean) true = Success
# (boolean) false = Failure
2014-04-19 19:07:36 +00:00
# Check dependencies
2014-06-25 12:50:49 +00:00
self :: dependencies ( isset ( $this -> database , $this -> photoIDs ));
2014-04-05 14:02:53 +00:00
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 0 , func_get_args ());
2014-04-05 14:02:53 +00:00
# Get photos
2014-08-30 05:05:26 +00:00
$query = Database :: prepare ( $this -> database , " SELECT id, url, thumbUrl, checksum FROM ? WHERE id IN (?) " , array ( LYCHEE_TABLE_PHOTOS , $this -> photoIDs ));
2014-08-29 19:16:10 +00:00
$photos = $this -> database -> query ( $query );
2014-05-08 18:50:18 +00:00
if ( ! $photos ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , $this -> database -> error );
return false ;
}
2014-04-05 14:02:53 +00:00
# For each photo
while ( $photo = $photos -> fetch_object ()) {
2014-08-22 20:54:33 +00:00
# Check if other photos are referring to this images
# If so, only delete the db entry
if ( $this -> exists ( $photo -> checksum , $photo -> id ) === false ) {
2014-04-05 14:02:53 +00:00
2014-08-22 20:54:33 +00:00
# Get retina thumb url
$thumbUrl2x = explode ( " . " , $photo -> thumbUrl );
$thumbUrl2x = $thumbUrl2x [ 0 ] . '@2x.' . $thumbUrl2x [ 1 ];
2014-05-08 18:50:18 +00:00
2014-08-22 20:54:33 +00:00
# Delete big
if ( file_exists ( LYCHEE_UPLOADS_BIG . $photo -> url ) &&! unlink ( LYCHEE_UPLOADS_BIG . $photo -> url )) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'Could not delete photo in uploads/big/' );
return false ;
}
2014-10-11 14:09:10 +00:00
# Delete medium
if ( file_exists ( LYCHEE_UPLOADS_MEDIUM . $photo -> url ) &&! unlink ( LYCHEE_UPLOADS_MEDIUM . $photo -> url )) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'Could not delete photo in uploads/medium/' );
return false ;
}
2014-08-22 20:54:33 +00:00
# Delete thumb
if ( file_exists ( LYCHEE_UPLOADS_THUMB . $photo -> thumbUrl ) &&! unlink ( LYCHEE_UPLOADS_THUMB . $photo -> thumbUrl )) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'Could not delete photo in uploads/thumb/' );
return false ;
}
# Delete thumb@2x
if ( file_exists ( LYCHEE_UPLOADS_THUMB . $thumbUrl2x ) &&! unlink ( LYCHEE_UPLOADS_THUMB . $thumbUrl2x )) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , 'Could not delete high-res photo in uploads/thumb/' );
return false ;
}
2014-05-08 18:50:18 +00:00
}
2014-04-05 14:02:53 +00:00
# Delete db entry
2014-08-30 05:05:26 +00:00
$query = Database :: prepare ( $this -> database , " DELETE FROM ? WHERE id = '?' " , array ( LYCHEE_TABLE_PHOTOS , $photo -> id ));
2014-08-29 19:16:10 +00:00
$delete = $this -> database -> query ( $query );
2014-05-08 18:50:18 +00:00
if ( ! $delete ) {
Log :: error ( $this -> database , __METHOD__ , __LINE__ , $this -> database -> error );
return false ;
}
2014-04-05 14:02:53 +00:00
}
2014-04-05 14:25:49 +00:00
# Call plugins
$this -> plugins ( __METHOD__ , 1 , func_get_args ());
2014-04-05 14:02:53 +00:00
return true ;
}
}
2015-12-07 21:44:42 +00:00
?>