<?php
/* wppa-admin-functions.php
* Package: wp-photo-album-plus
*
* gp admin functions
* Version 8.0.09.001
*
*/

if ( ! defined( 'ABSPATH' ) ) die( "Can't load this file directly" );

function wppa_backup_settings() {
global $wppa_opt;


	// Make contents
	$contents = '';
	foreach( array_keys( $wppa_opt ) as $key ) {
		$value = str_replace( "\n", "\\n", $wppa_opt[$key] );
		$contents .= $key.":".$value."\n";
	}

	// Find filename
	$filename = sanitize_file_name( basename( wppa_opt( 'backup_filename' ) ) );
	$ext = wppa_get_ext( $filename );
	if ( ! in_array( $ext, array( 'bak', 'skin' ) ) ) {
		$filename = wppa_strip_ext( $filename ) . '.bak';
	}
	if ( $filename == '.bak' ) {
		$filename = 'settings.bak';
	}

	// Forget filename for the next time or another user
	update_option( 'wppa_backup_filename', '' );
	wppa_initialize_runtime();

	// Save to file
	wppa_ok_message( __( 'Backing up to', 'wp-photo-album-plus' ) . ': ' . str_replace( WPPA_ABSPATH, '.../', WPPA_DEPOT_PATH ) . '/' . $filename );
	$bret = wppa_put_contents( WPPA_DEPOT_PATH . '/' . $filename, $contents );

	// Report
	if ( $bret ) {
		wppa_ok_message( __( 'Settings successfully backed up' , 'wp-photo-album-plus') );
	}
	else {
		wppa_error_message( __( 'Unable to backup settings' , 'wp-photo-album-plus') );
	}

	return $bret;
}

function wppa_restore_settings( $fname, $type = '' ) {

	if ( wppa( 'debug' ) ) wppa_dbg_msg( 'Restoring from: '.$fname );
	if ( $type == 'skin' ) {
		$void_these = array(
							'wppa_revision',
							'wppa_allow_debug',
							'wppa_thumb_linkpage',
							'wppa_potd_linkpage',
							'wppa_slideonly_widget_linkpage',
							'wppa_topten_widget_linkpage',
							'wppa_lasten_widget_linkpage',
							'wppa_coverimg_linkpage',
							'wppa_search_linkpage',
							'wppa_album_widget_linkpage',
							'wppa_thumbnail_widget_linkpage',
							'wppa_comment_widget_linkpage',
							'wppa_featen_widget_linkpage',
							'wppa_sphoto_linkpage',
							'wppa_mphoto_linkpage',
							'wppa_xphoto_linkpage',
							'wppa_slideshow_linkpage',
							'wppa_tagcloud_linkpage',
							'wppa_multitag_linkpage',
							'wppa_super_view_linkpage',
							'wppa_upldr_widget_linkpage',
							'wppa_bestof_widget_linkpage',
							'wppa_album_navigator_widget_linkpage',
							'wppa_supersearch_linkpage',
							'wppa_widget_sm_linkpage',
							'wppa_permalink_structure',
							'wppa_rating_max',
							'wppa_file_system',
							'wppa_source_dir',
							 );
	}
	else {
		$void_these = array(
							'wppa_revision',
							'wppa_rating_max',
							'wppa_file_system',
							 );
	}

	// Get file contents
	$buffers = wppa_get_contents_array( $fname );

	// Restore
	if ( $buffers ) {
		foreach( $buffers as $buffer ) {
			$buflen = strlen( $buffer );
			if ( $buflen > '0' && substr( $buffer, 0, 1 ) != '/' ) {	// lines that start with '/' are comment
				$cpos = strpos( $buffer, ':' );
				$delta_l = $buflen - $cpos - 2;
				if ( $cpos && $delta_l >= 0 ) {
					$slug = substr( $buffer, 0, $cpos );
					$value = substr( $buffer, $cpos+1, $delta_l );
					$value = str_replace( '\n', "\n", $value );	// Replace substr '\n' by nl char value
					$value = stripslashes( $value );
					//wppa_dbg_msg( 'Doing|'.$slug.'|'.$value );
					if ( ! in_array( $slug, $void_these ) ) wppa_update_option( $slug, $value );
					else wppa_dbg_msg( $slug.' skipped' );
				}
			}
		}
		wppa_initialize_runtime( true );
		return true;
	}
	else {
		wppa_error_message( __( 'Settings file not found' , 'wp-photo-album-plus') );
		return false;
	}
}

// Remake
function wppa_remake_files( $alb = '', $pid = '' ) {
global $wpdb;

	// Init
	$count = '0';

	// Find the album( s ) if any
	if ( ! $alb && ! $pid ) {
		$start_time = wppa_get_option( 'wppa_remake_start', '0' );
		$albums = $wpdb->get_results( "SELECT id FROM $wpdb->wppa_albums", ARRAY_A );
	}
	elseif ( $alb ) {
		$start_time = wppa_get_option( 'wppa_remake_start_album_'.$alb, '0' );
		$albums = array( array( 'id' => $alb ) );
	}
	else $albums = false;

	// Do it with albums
	if ( $albums ) foreach ( $albums as $album ) {
		$source_dir = wppa_get_source_album_dir( $album['id'] );
		if ( wppa_is_dir( $source_dir ) ) {
			$files = wppa_glob( $source_dir.'/*' );
			if ( $files ) foreach ( $files as $file ) {
				if ( ! wppa_is_dir( $file ) ) {
					$filename = basename( $file );
					$photos =
						$wpdb->get_results( $wpdb->prepare(
							"SELECT * FROM $wpdb->wppa_photos
							 WHERE filename = %s
							 OR filename = %s
							 OR ( filename = '' AND name = %s )",
							 $filename,
							 wppa_strip_ext( $filename ) . '.xxx',	// May be a multimedia iten
							 $filename ),
						ARRAY_A );

					if ( $photos ) foreach ( $photos as $photo ) {	// Photo exists
						$modified_time = $photo['modified'];
						if ( $modified_time < $start_time ) {
							wppa_update_single_photo( $file, $photo['id'], $filename );
							$count++;
						}
						if ( wppa_is_time_up( $count ) ) {
							return false;
						}
					}
					else {	// No photo yet
						if ( wppa_switch( 'remake_add' ) ) {
							wppa_insert_photo( $file, $album['id'], $filename );
							$count++;
						}
					}
					if ( wppa_is_time_up( $count ) ) {
						return false;
					}
				}
			}
		}
	}

	// Do it with a single photo
	elseif ( $pid ) {
		$photo = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->wppa_photos WHERE id = %s", $pid ), ARRAY_A );
		if ( $photo ) {
			$file = wppa_get_o1_source_path( $photo['id'] );
			if ( ! wppa_is_file( $file ) ) {
				$file = wppa_get_source_path( $photo['id'] );
			}
			if ( is_file( $file ) ) {
				$name = $photo['filename'];
				wppa_update_single_photo( $file, $pid, $name );
			}
			else return false;
		}
		else return false;
	}
	return true;
}

// display usefull message
function wppa_update_message( $msg, $fixed = false, $id = '' ) {

	echo '<div class="notice notice-info is-dismissible"><p>' . strip_tags( $msg, '<a><br><input><div><em><strong><b>' ) . '</p></div>';
}

// display error message
function wppa_error_message( $msg ) {

	echo '<div class="notice notice-error is-dismissible"><p>' . strip_tags( $msg, '<a><br><input><div><em><strong><b>' ) . '</p></div>';
}

// display warning message
function wppa_warning_message( $msg ) {

	echo '<div class="notice notice-warning is-dismissible"><p>' . strip_tags( $msg, '<a><br><input><div><em><strong><b>' ) . '</p></div>';
}

// display ok message
function wppa_ok_message( $msg ) {

	echo '<div class="notice notice-success is-dismissible"><p>' . strip_tags( $msg, '<a><br><input><div><em><strong><b>' ) . '</p></div>';
}

function wppa_check_numeric( $value, $minval, $target, $maxval = '' ) {
	if ( $maxval == '' ) {
		if ( is_numeric( $value ) && $value >= $minval ) return true;
		wppa_error_message( __( 'Please supply a numeric value greater than or equal to' , 'wp-photo-album-plus') . ' ' . $minval . ' ' . __( 'for' , 'wp-photo-album-plus') . ' ' . $target );
	}
	else {
		if ( is_numeric( $value ) && $value >= $minval && $value <= $maxval ) return true;
		wppa_error_message( __( 'Please supply a numeric value greater than or equal to' , 'wp-photo-album-plus') . ' ' . $minval . ' ' . __( 'and less than or equal to' , 'wp-photo-album-plus') . ' ' . $maxval . ' ' . __( 'for' , 'wp-photo-album-plus') . ' ' . $target );
	}
	return false;
}

// check if albums 'exists'
function wppa_has_albums() {
	return wppa_have_access( '0' );
}

function wppa_user_select( $select = '' ) {
	$result = '';
	$iam = $select == '' ? wppa_get_user() : $select;
	$users = wppa_get_users();
	$sel = $select == '--- public ---' ? 'selected="selected"' : '';
	$result .= '<option value="--- public ---" '.$sel.'>'.__( '--- public ---' , 'wp-photo-album-plus').'</option>';
	foreach ( $users as $usr ) {
		if ( $usr['user_login'] == $iam ) $sel = 'selected="selected"';
		else $sel = '';
		$result .= '<option value="' . esc_attr( $usr['user_login'] ) . '" ' . $sel . '>' . htmlspecialchars( $usr['display_name'] ) . '</option>';
	}
	echo ( $result );
}

function wppa_copy_photo( $photoid, $albumto ) {
global $wpdb;

	$err = '1';
	// Check args
	if ( ! is_numeric( $photoid ) || ! is_numeric( $albumto ) ) return $err;

	$err = '2';
	// Find photo details
	$photo = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->wppa_photos
											  WHERE id = %s", $photoid ), ARRAY_A );
	if ( ! $photo ) return $err;
	$albumfrom 	= $photo['album'];
	$album 		= $albumto;
	$ext 		= $photo['ext'];
	$name 		= $photo['name'];
	$porder		= '0';
	$desc 		= $photo['description'];
	$linkurl 	= $photo['linkurl'];
	$linktitle 	= $photo['linktitle'];
	$linktarget = $photo['linktarget'];
	$status 	= $photo['status'];
	$filename 	= $photo['filename'];
	$location	= $photo['location'];
	$oldimage 	= wppa_get_photo_path( strval( intval( $photo['id'] ) ) );
	$oldthumb 	= wppa_get_thumb_path( strval( intval( $photo['id'] ) ) );
	$tags 		= $photo['tags'];
	$exifdtm 	= $photo['exifdtm'];
	$custom 	= $photo['custom'];
	$stereo 	= $photo['stereo'];
	$panorama 	= $photo['panorama'];

	$err = '3';
	// Make new db table entry
	$owner = wppa_switch( 'copy_owner' ) ? $photo['owner'] : wppa_get_user();
	$time = wppa_switch( 'copy_timestamp' ) ? $photo['timestamp'] : time();
	$id = wppa_create_photo_entry( array( 	'album' 		=> $album,
											'ext' 			=> $ext,
											'name' 			=> $name,
											'p_order' 		=> $porder,
											'description' 	=> $desc,
											'linkurl' 		=> $linkurl,
											'linktitle' 	=> $linktitle,
											'linktarget' 	=> $linktarget,
											'timestamp' 	=> $time,
											'owner' 		=> $owner,
											'status' 		=> $status,
											'filename' 		=> $filename,
											'location' 		=> $location,
											'tags' 			=> $tags,
											'exifdtm' 		=> $exifdtm,
											'videox' 		=> $photo['videox'],
											'videoy' 		=> $photo['videoy'],
											'custom' 		=> wppa_switch( 'copy_custom' ) ? $photo['custom'] : '',
											'stereo' 		=> $photo['stereo'],
											'panorama' 		=> $photo['panorama'],
											'photox' 		=> 0, //$photo['photox'],
											'photoy' 		=> 0, //$photo['photoy'],
											'thumbx' 		=> 0, //$photo['thumbx'],
											'thumby' 		=> 0, //$photo['thumby'],
											'duration' 		=> $photo['duration'],

										 )
								 );
	if ( ! $id ) return $err;
	wppa_invalidate_treecounts( $album );
	wppa_index_add( 'photo', $id );

	$err = '4';
	// Find copied photo details
	$id = strval( intval( $id ) );
	if ( ! $id ) return $err;
	$image_id = $id;
	$newimage = wppa_strip_ext( wppa_get_photo_path( $image_id, false ) ) . '.' . wppa_get_ext( $oldimage );
	$newthumb = wppa_strip_ext( wppa_get_thumb_path( $image_id, false ) ) . '.' . wppa_get_ext( $oldthumb );

	$err = '5';
	// Do the filesystem copy
	if ( wppa_is_video( $photo['id'] ) ) {
		if ( ! wppa_copy_video_files( $photo['id'], $image_id ) ) return $err;
	}
	elseif ( wppa_has_audio( $photo['id'] ) ) {
		if ( ! wppa_copy_audio_files( $photo['id'], $image_id ) ) return $err;
	}

	$err = '6';
	// Copy photo or poster
	if ( wppa_is_file( $oldimage ) ) {
		if ( ! wppa_copy( $oldimage, $newimage ) ) return $err;
	}

	$err = '7';
	// Copy thumbnail
	if ( wppa_is_file( $oldthumb ) ) {
		if ( ! wppa_copy( $oldthumb, $newthumb ) ) return $err;
	}

	$err = '8';
	// Copy to cloudinary
	if ( wppa_opt( 'cdn_service' ) == 'cloudinary' || wppa_opt( 'cdn_service' ) == 'cloudinarymaintenance' ) {
		wppa_upload_to_cloudinary( $id );
	}

	$err = '9';
	// Copy source
	wppa_copy_source( $filename, $albumfrom, $albumto );

	$err = '10';
	// Copy Exif and iptc
	wppa_copy_exif( $photoid, $id );
	wppa_copy_iptc( $photoid, $id );

	// Bubble album timestamp
	if ( ! wppa_switch( 'copy_timestamp' ) ) wppa_update_album( array( 'id' => $albumto, 'modified' => time() ) );
	return false;	// No error
}
function wppa_copy_exif( $fromphoto, $tophoto ) {
global $wpdb;

	$exiflines = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->wppa_exif WHERE photo = %d", $fromphoto ), ARRAY_A );
	if ( $exiflines ) foreach ( $exiflines as $line ) {
		$bret = wppa_create_exif_entry( array( 'photo' => $tophoto, 'tag' => $line['tag'], 'description' => $line['description'], 'status' => $line['status'] ) );
	}
}
function wppa_copy_iptc( $fromphoto, $tophoto ) {
global $wpdb;

	$iptclines = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->wppa_iptc WHERE photo = %d", $fromphoto ), ARRAY_A );
	if ( $iptclines ) foreach ( $iptclines as $line ) {
		$bret = wppa_create_iptc_entry( array( 'photo' => $tophoto, 'tag' => $line['tag'], 'description' => $line['description'], 'status' => $line['status'] ) );
	}
}

function wppa_rotate( $id, $ang ) {
global $wpdb;

	// Check args
	$err = '1';
	if ( ! is_numeric( $id ) || ( ! in_array( $ang, array( 'rotright', 'rot180', 'rotleft', 'flip', 'flop' ) ) ) ) return $err;

	// Get the ext
	$err = '2';
	$ext = $wpdb->get_var( $wpdb->prepare( "SELECT ext FROM $wpdb->wppa_photos
											WHERE id = %d", $id ) );
	if ( ! $ext ) return $err;

	// Get the image
	$err = '3';
	$file = wppa_get_photo_path( $id );
	if ( ! is_file( $file ) ) return $err;

	// Get the imgdetails
	$err = '4';
	$img = getimagesize( $file );
	if ( ! $img ) return $err;

	// Get the image
	switch ( $img[2] ) {
		case 1:	// gif
			$err = '5';
			$source = wppa_imagecreatefromgif( $file );
			break;
		case 2: // jpg
			$err = '6';
			$source = wppa_imagecreatefromjpeg( $file );
			break;
		case 3: // png
			$err = '7';
			$source = wppa_imagecreatefrompng( $file );
			break;
		default: // unsupported mimetype
			$err = '10';
			$source = false;
	}
	if ( ! $source ) return $err;

	// Rotate the image
	$err = '11';
	switch( $ang ) {

		case 'rotright':
			$rotate = imagerotate( $source, -90, 0 );
			if ( ! $rotate ) {
				return $err;
			}
			break;
		case 'rot180':
			$rotate = imagerotate( $source, 180, 0 );
			if ( ! $rotate ) {
				return $err;
			}
			break;
		case 'rotleft':
			$rotate = imagerotate( $source, 90, 0 );
			if ( ! $rotate ) {
				return $err;
			}
			break;
		case 'flip':
			if ( ! imageflip( $source, IMG_FLIP_VERTICAL ) ) {
				return $err;
			}
			$rotate = $source;
			break;
		case 'flop':
			if ( ! imageflip( $source, IMG_FLIP_HORIZONTAL ) ) {
				return $err;
			}
			$rotate = $source;
			break;
		default:
			return $err;
	}

	// Save the image
	switch ( $img[2] ) {
		case 1:
			$err = '15';
			$bret = wppa_imagegif( $rotate, $file, 95 );
			break;
		case 2:
			$err = '16';
			$bret = wppa_imagejpeg( $rotate, $file );
			break;
		case 3:
			$err = '17';
			$bret = wppa_imagepng( $rotate, $file, 6 );
			break;
		default:
			$err = '20';
			$bret = false;
	}
	if ( ! $bret ) return $err;

	// Destroy the source
	@ imagedestroy( $source );

	// Destroy the result
	@ imagedestroy( $rotate );

	// Clear stored dimensions
	wppa_update_photo( array( 	'id' 	 => $id,
								'thumbx' => '0',
								'thumby' => '0',
								'photox' => '0',
								'photoy' => '0',
							)
						);

	$err = '30';

	// Recreate the thumbnail, do NOT use source: source can not be rotated
	$bret = wppa_create_thumbnail( $id, false );
	if ( ! $bret ) return $err;

	// Return success
	return false;
}

// Remove illegal files in WPPA_DEPOT_PATH
function wppa_sanitize_files() {

	// Get this users depot directory
	$depot = WPPA_DEPOT_PATH;
	_wppa_sanitze_files( $depot );
}

function _wppa_sanitze_files( $root ) {

	$allowed_types = wppa_get_supported_extensions();
	if ( wppa_user_is( 'administrator' ) ) {
		$allowed_types = array_merge( $allowed_types, array( 'amf', 'pmf', 'csv' ) );
	}
	if ( current_user_can( 'wppa_settings' ) ) {
		$allowed_types = array_merge( $allowed_types, array( 'bak', 'skin' ) );
	}

	$paths = $root.'/*';
	$files = wppa_glob( $paths );

	$count = '0';
	if ( $files ) foreach ( $files as $file ) {

		if ( wppa_is_file( $file ) ) {

			// Check extension
			$ext = strtolower( wppa_get_ext( $file ) );
			if ( ! in_array( $ext, $allowed_types ) ) {
				if ( basename( $file ) != 'index.php' ) {
					wppa_unlink( $file );
					wppa_error_message( sprintf( __( 'File %s is of an unsupported filetype and has been removed.' , 'wp-photo-album-plus'), basename( wppa_sanitize_file_name( $file ) ) ) );
				}
				$count++;
			}
		}
		elseif ( wppa_is_dir( $file ) ) {
			$entry = basename( $file );
			if ( $entry != '.' && $entry != '..' ) {
				_wppa_sanitze_files( $file );
			}
		}
	}
	return $count;
}

function wppa_admin_page_links( $curpage, $pagesize, $count, $link, $extra = '' ) {

	if ( $pagesize < '1' ) return;	// Pagination is off

	$prevpage 		= $curpage - '1';
	$nextpage 		= $curpage + '1';
	$prevurl 		= $link.'&wppa-page='.$prevpage.$extra;
	$pagurl 		= $link.'&wppa-page=';
	$nexturl 		= $link.'&wppa-page='.$nextpage.$extra;
	$npages 		= ceil( $count / $pagesize );
	$lastpagecount 	= $count % $pagesize;
	if ( ! $lastpagecount ) {
		$lastpagecount = $pagesize;
	}

	if ( $npages > '1' ) {
		echo '<div style="line-height:1.5em" >';
		if ( $curpage != '1' ) {
			?><a href="<?php echo( $prevurl ) ?>"><?php _e( 'Prev page' , 'wp-photo-album-plus') ?></a><?php
		}

/*
		$i = '1';
		while ( $i <= $npages ) {
			if ( $i == $curpage ) {
				echo ' <span style="padding:0 0.25em;" >' . $i . '</span>';
			}
			else {
				echo
					' <a' .
						' href="' . $pagurl . $i . $extra . '"' .
						' style="border:1px solid;padding:0 0.25em;line-height:1.7em;"' .
						( $i == $npages ? ' title="' . $lastpagecount . '"' : '' ) .
						' >' .
						$i .
					'</a>';
			}
			$i++;
		}
*/

		echo '<select onchange="document.location = jQuery( this ).val()" >';
		$i = '1';
		while ( $i <= $npages ) {
			if ( $i == $curpage ) {
				echo '<option selected="selected" >' . $i . '</option>';
			}
			else {
				echo '<option value="' . $pagurl . $i . $extra . '"' . ( $i == $npages ? ' title="' . $lastpagecount . '"' : '' ) . ' >' . $i . '</option>';
			}
			$i++;
		}
		echo '</select>';


		if ( $curpage != $npages ) {
			echo
				' <a href="' . $nexturl . '" >' .
					__( 'Next page', 'wp-photo-album-plus' ) .
				'</a>';
		}
		echo '</div><br />&nbsp;';
	}
}

function wppa_update_single_photo( $file, $id, $name ) {
global $wpdb;

	$photo = $wpdb->get_row( $wpdb->prepare( "SELECT id, name, ext, album, filename FROM $wpdb->wppa_photos WHERE id = %s", $id ), ARRAY_A );

	// Find extension
	$ext = $photo['ext'];

	if ( $ext == 'xxx' ) {
		$ext = strtolower( wppa_get_ext( $file ) ); 	// Copy from source
		if ( $ext == 'jpeg' ) $ext = 'jpg';
	}

	// Make proper oriented source
	wppa_make_o1_source( $id );

	// Make the files
	wppa_make_the_photo_files( $file, $id, $ext );

	// and add watermark ( optionally ) to fullsize image only
	wppa_add_watermark( $id );

	// create new thumbnail
	wppa_create_thumbnail( $id );

	// Update filename if not present. this is for backward compatibility when there were no filenames saved yet
	if ( ! wppa_get_photo_item( $id, 'filename' ) ) {
		wppa_update_photo( array( 'id' => $id, 'filename' => $name ) );
	}

	// Clear magick stack
	wppa_update_photo( array( 'id' => $id, 'magickstack' => '' ) );

	// Update modified timestamp
	wppa_update_modified( $id );
	wppa_dbg_msg( 'Update single photo: '.$name.' in album '.$photo['album'], 'green' );
}

function wppa_update_photo_files( $file, $xname ) {
global $wpdb;
global $allphotos;

	if ( $xname == '' ) $name = basename( $file );
	else $name = __( $xname , 'wp-photo-album-plus');

	// Find photo entries that apply to the supplied filename
	$query = $wpdb->prepare(
			"SELECT * FROM $wpdb->wppa_photos WHERE ".
			"filename = %s OR ".
			"filename = %s OR ".
			"( filename = '' AND name = %s ) OR ".
			"( filename = %s )",
			wppa_sanitize_file_name( basename( $file ) ),								// Usual
			$name,																		// Filename is different in is_wppa_tree import
			$name,																		// Old; pre saving filenames
			wppa_strip_ext( wppa_sanitize_file_name( basename( $file ) ) ) . '.xxx'		// Media poster file
		);
	$photos = $wpdb->get_results( $query, ARRAY_A );

//	wppa_log( 'dbg', $query.' count='.($photos?count($photos):'0') );

	// If photo entries found, process them all
	if ( $photos ) {
		foreach ( $photos as $photo ) {

			// Find photo details
			$id 	= $photo['id'];
			$ext 	= wppa_is_video( $id ) ? 'jpg' : $photo['ext'];
			$alb 	= $photo['album'];

			// Save the new source
			wppa_save_source( $file, basename( $file ), $alb );

			// Remake the files
			wppa_make_the_photo_files( $file, $id, $ext );

			// and add watermark ( optionally ) to fullsize image only
			wppa_add_watermark( $id );

			// create new thumbnail
			if ( wppa_switch( 'watermark_thumbs' ) ) {
				wppa_create_thumbnail( $id );
			}

			// Make proper oriented source
			wppa_make_o1_source( $id );

			// Update filename if still empty ( Old )
			if ( ! $photo['filename'] ) {
				$wpdb->query( $wpdb->prepare( "UPDATE $wpdb->wppa_photos SET filename = %s WHERE id = %s", wppa_sanitize_file_name( basename( $file ) ), $id ) );
			}

			// Update modified flag
			wppa_update_photo( ['id' => $id, 'modified' => time()] );
		}
		return count( $photos );
	}
	return false;
}

function wppa_insert_photo( $file = '', $alb = '', $name = '', $desc = '', $porder = '0', $id = '0', $linkurl = '', $linktitle = '' ) {
global $wpdb;
global $warning_given_small;

	$album = wppa_cache_album( $alb );

	if ( ! wppa_allow_uploads( $alb ) ) {
		if ( is_admin() && ! wppa( 'ajax' ) ) {
			wppa_error_message( __( 'Album is full' , 'wp-photo-album-plus' ) );
		}
		else {
			wppa_alert( __( 'Album is full' , 'wp-photo-album-plus' ) );
		}
		return false;
	}

	if ( $file != '' && $alb != '' ) {
		// Get the name if not given
		if ( $name == '' ) $name = basename( $file );
		// Sanitize name
		$filename 	= wppa_sanitize_file_name( $name );
		$name 		= wppa_sanitize_photo_name( $name );

		// If not dups allowed and its already here, quit
		if ( wppa_get( 'nodups' ) || wppa_switch( 'void_dups' ) ) {
			$exists = wppa_is_file_duplicate_photo( $filename, $alb );
			if ( $exists ) {
				if ( wppa_get( 'del-after-p' ) ) {
					wppa_unlink( $file );
					$msg = __( 'Photo %s already exists in album number %s. Removed from depot.' , 'wp-photo-album-plus');
				}
				else {
					$msg = __( 'Photo %s already exists in album number %s.' , 'wp-photo-album-plus');
				}
				wppa_warning_message( sprintf( $msg, $name, $alb ) );

				return false;
			}
		}

		// Verify file exists
		if ( ! wppa( 'is_remote' ) && ! file_exists( $file ) ) {
			if ( ! wppa_is_dir( dirname( $file ) ) ) {
				wppa_error_message( htmlentities( 'Error: Directory '.dirname( $file ).' does not exist.' ) );
				return false;
			}
			if ( ! is_writable( dirname( $file ) ) ) {
				wppa_error_message( htmlentities( 'Error: Directory '.dirname( $file ).' is not writable.' ) );
				return false;
			}
			wppa_error_message( htmlentities( 'Error: File '.$file.' does not exist.' ) );
			return false;
		}
		elseif ( wppa( 'is_remote' ) ) {
			if ( ! wppa_is_url_a_photo( $file ) ) {
				if ( wppa( 'ajax' ) ) {
					wppa( 'ajax_import_files_error', __( 'Not found', 'wp-photo-album-plus') );
				}
				return false;
			}
			else { // Is a photo. Maybe found a different ext.
				$filename 	= wppa_strip_ext( $filename ) . '.' . wppa_get_ext( $file );
				$name 		= wppa_strip_ext( $name ) . '.' . wppa_get_ext( $file );
			}
		}

		// Get and verify the size
		$img_size = getimagesize( $file );

		// Assume success finding image size
		if ( $img_size ) {
			if ( wppa_check_memory_limit( '', $img_size['0'], $img_size['1'] ) === false ) {
				wppa_error_message( htmlentities( sprintf( __( 'ERROR: Attempt to upload a photo that is too large to process (%s).' , 'wp-photo-album-plus'), $name ).wppa_check_memory_limit() ) );
				wppa( 'ajax_import_files_error', __( 'Too big', 'wp-photo-album-plus' ) );
				return false;
			}
			if ( ! $warning_given_small && ( $img_size['0'] < wppa_get_minisize() && $img_size['1'] < wppa_get_minisize() ) ) {
				wppa_warning_message( htmlentities( __( 'WARNING: You are uploading photos that are too small. Photos must be larger than the thumbnail size and larger than the coverphotosize.' , 'wp-photo-album-plus') ) );
				wppa( 'ajax_import_files_error', __( 'Too small', 'wp-photo-album-plus' ) );
				$warning_given_small = true;
			}
		}

		// No image size found
		else {
			wppa_error_message( htmlentities( __( 'ERROR: Unable to retrieve image size of' , 'wp-photo-album-plus').' '.$file.' '.__( 'Are you sure it is a photo?' , 'wp-photo-album-plus') ) );
			wppa( 'ajax_import_files_error', __( 'No photo found', 'wp-photo-album-plus' ) );
			return false;
		}

		// Get ext based on mimetype, regardless of ext
		switch( $img_size[2] ) { 	// mime type
			case 1: $ext = 'gif'; break;
			case 2: $ext = 'jpg'; break;
			case 3: $ext = 'png'; break;
			default:
				wppa_error_message( htmentities( __( 'Unsupported mime type encountered:' , 'wp-photo-album-plus').' '.$img_size[2].'.' ) );
				return false;
		}
		// Get an id if not yet there
		if ( $id == '0' ) {
			$id = wppa_nextkey( WPPA_PHOTOS );
		}
		// Get opt deflt desc if empty
		if ( $desc == '' && wppa_switch( 'apply_newphoto_desc' ) ) {
			$desc = stripslashes( wppa_opt( 'newphoto_description' ) );
		}
		// Reset rating
		$mrat = '0';
		// Find ( new ) owner
		$owner = wppa_get_user();
		// Validate album
		if ( !is_numeric( $alb ) || $alb < '1' ) {
			wppa_error_message( __( 'Album not known while trying to add a photo' , 'wp-photo-album-plus') );
			return false;
		}
		if ( ! wppa_have_access( $alb ) ) {
			wppa_error_message( htmlentities( sprintf( __( 'Album %s does not exist or is not accessible while trying to add a photo' , 'wp-photo-album-plus'), $alb ) ) );
			return false;
		}
		$status = ( wppa_switch( 'moderatephoto' ) && ! current_user_can( 'wppa_admin' ) ) ? 'pending' : wppa_opt( 'wppa_status_new' );

		// Add photo to db
		$id = wppa_create_photo_entry( array( 	'id' => $id,
												'album' => $alb,
												'ext' => $ext,
												'name' => $name,
												'p_order' => $porder,
												'description' => $desc,
												'linkurl' => $linkurl,
												'linktitle' => $linktitle,
											//	'owner' => $owner,
												'status' => $status,
												'filename' => $filename
											 ) );
		if ( ! $id ) {
			wppa_error_message( __( 'Could not insert photo.' , 'wp-photo-album-plus') );
		}
		else {	// Save the source
			wppa_save_source( $file, $filename, $alb );
			wppa_make_o1_source( $id );
			wppa_invalidate_treecounts( $alb );
			wppa_update_album( array( 'id' => $alb, 'modified' => time() ) );
			wppa_flush_upldr_cache( 'photoid', $id );
		}

		// For photo file creation, if possible, use proper oriented source file, not temp file and also not url
		$t = wppa_get_o1_source_path( $id );
		if ( is_file( $t ) ) {
			$file = $t;
		}
		else {
			$t = wppa_get_source_path( $id );
			if ( is_file( $t ) ) {
				$file = $t;
			}
		}

		// Make the photo files.
		if ( wppa_make_the_photo_files( $file, $id, $ext, ! wppa_does_thumb_need_watermark( $id ) ) ) {

			// Repair photoname if not supplied and not standard
			wppa_set_default_name( $id );

			// Tags
			wppa_set_default_tags( $id );

			// Custom fields defaults
			wppa_set_default_custom( $id );

			// Index
			wppa_index_add( 'photo', $id );

			// and add watermark ( optionally ) to fullsize image only
			wppa_add_watermark( $id );

			// also to thumbnail?
			if ( wppa_does_thumb_need_watermark( $id ) ) {
				wppa_create_thumbnail( $id );
			}
			// Is it a default coverimage?
			wppa_check_coverimage( $id );

			return $id;
		}
	}
	else {
		wppa_error_message( __( 'ERROR: Unknown file or album.' , 'wp-photo-album-plus') );
		return false;
	}
}

function wppa_admin_spinner() {

	$result = 	'<img' .
					' id="wppa-admin-spinner"' .
					' src="' . wppa_get_imgdir( wppa_use_svg( 'admin' ) ? 'loader.svg' : 'loader.gif' ) . '"' .
					' alt="Spinner"' .
					' style="' .
						'position:fixed;' .
						'left:50%;' .
						'top:50%;' .
						'margin-left:-33px;' .
						'margin-top:-33px;' .
						'z-index:9999999;' .
						'"' .
					' />' .
				'<script type="text/javascript" >' .
				/*	'jQuery( "#wppa-admin-spinner" ).css( { left:(screen.width/2-33),top:(screen.height/2-33) } );' . */
					'jQuery(document).ready( function() { ' .
							'setTimeout( "wppaTestAdminReady()", 200 ); ' .
						'} );' .
					'function wppaTestAdminReady() { ' .
						' if ( document.readyState === "complete" ) {' .
							'jQuery( "#wppa-admin-spinner" ).fadeOut(); ' .
						' } else { ' .
							' setTimeout( "wppaTestAdminReady()", 200 ); ' .
						'}' .
					'}' .
				'</script>';

	echo $result;
}

// Export db table to .csv file
function wppa_export_table( $table ) {
global $wpdb;

	// Open outputfile
	$path = WPPA_UPLOAD_PATH . '/temp/' . $table . '.csv';
	$file = wppa_fopen( $path, 'wb' );
	if ( ! $file ) {
		return false;
	}

	// Init output buffer
	$result = '';

	// Get the fieldnames
	$fields = $wpdb->get_results( "DESCRIBE ".$table."", ARRAY_A );

	// Write the .csv header
	if ( is_array( $fields ) ) {
		foreach( $fields as $field ) {
			$result .= $field['Field'] . wppa_opt( 'csv_sep' );
		}
		$result = rtrim( $result, wppa_opt( 'csv_sep' ) ) . "\n";
	}
	fwrite( $file, $result );

	// Init getting the data
	$count = $wpdb->get_var( "SELECT COUNT(*) FROM " . $table . "" );
	$iters = ceil( $count / 1000 );
	$iter  = 0;

	// Read chunks of 1000 rows
	while ( $iter < $iters ) {
		$query = "SELECT * FROM " . $table . " ORDER BY id LIMIT " . 1000 * $iter . ",1000";
		$data  = $wpdb->get_results( $query, ARRAY_N );

		// Process rows
		if ( $data ) {
			foreach( $data as $row ) {

				// Write to file
				fputcsv( $file, $row, wppa_opt( 'csv_sep' ) );
			}
		}
		$iter++;
	}

	// Close file
	fclose( $file );

	// Done !
	return true;
}

// Convert one text token to a .csv token
function wppa_prep_for_csv( $data ) {

	// Replace " by ""
	$result = str_replace( '"', '""', $data );

	if ( wppa_is_int( $result ) ) {
		$result = strval( intval( $result ) );
	}
	elseif ( $result ) {
		$result = '"' . $result . '"';
	}
	return $result;
}

function wppa_album_admin_footer() {
global $wpdb;

	$albcount 		= $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->wppa_albums" );
	$photocount 	= $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->wppa_photos" );
	$pendingcount 	= $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->wppa_photos WHERE status = 'pending'" );
	$schedulecount 	= $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->wppa_photos WHERE status = 'scheduled'" );

	echo sprintf(__('There are <strong>%d</strong> albums and <strong>%d</strong> photos in the system.', 'wp-photo-album-plus'), $albcount, $photocount);
	if ( $pendingcount ) echo ' '.sprintf(__('<strong>%d</strong> photos are pending moderation.', 'wp-photo-album-plus'), $pendingcount);
	if ( $schedulecount ) echo ' '.sprintf(__('<strong>%d</strong> photos are scheduled for later publishing.', 'wp-photo-album-plus'), $pendingcount);

	$lastalbum = $wpdb->get_row( "SELECT id, name FROM $wpdb->wppa_albums ORDER BY id DESC LIMIT 1", ARRAY_A );
	if ( $lastalbum ) echo '<br />'.sprintf(__('The most recently added album is <strong>%s</strong> (%d).', 'wp-photo-album-plus'), __(stripslashes($lastalbum['name']), 'wp-photo-album-plus'), $lastalbum['id']);
	$lastphoto = $wpdb->get_row( "SELECT id, name, album FROM $wpdb->wppa_photos ORDER BY timestamp DESC LIMIT 1", ARRAY_A );
	if ( ! $lastphoto ) {
		echo '<br />'.__('There are no photos yet', 'wp-photo-album-plus');
		return;
	}
	if ( $lastphoto['album'] < '1' ) {
		$trashed = true;
		$album = - ( $lastphoto['album'] + '9' );
	}
	else {
		$trashed = false;
		$album = $lastphoto['album'];
	}
	$lastphotoalbum = $wpdb->get_row($wpdb->prepare( "SELECT id, name FROM $wpdb->wppa_albums WHERE id = %s", $album), ARRAY_A );
	if ( $lastphoto ) {
		echo '<br />'.sprintf(__('The most recently added photo is <strong>%s</strong> (%d)', 'wp-photo-album-plus'), __(stripslashes($lastphoto['name']), 'wp-photo-album-plus'), $lastphoto['id']);
		if ( $lastphotoalbum ) {
			echo ' '.sprintf(__('in album <strong>%s</strong> (%d).', 'wp-photo-album-plus'), __(stripslashes($lastphotoalbum['name']), 'wp-photo-album-plus'), $lastphotoalbum['id']);
		}
		if ( $trashed ) {
			echo ' <span style="color:red" >' . __('Deleted', 'wp-photo-album-plus' ) . '</span>';
		}
	}
}

// edit album url
function wppa_ea_url($edit_id, $tab = 'edit') {

	$nonce = wp_create_nonce('wppa-nonce');

	return wppa_dbg_url(get_admin_url().'admin.php?page=wppa_admin_menu&amp;tab='.$tab.'&amp;edit-id='.$edit_id.'&amp;wppa-nonce='.$nonce);
}

// Convert a non 360 deg spheric panorama photo to 360 deg by padding
function wppa_make_360( $id, $degs ) {

	// Does source exist?
	$file = wppa_get_source_path( $id );
	if ( ! wppa_is_file( $file ) ) {
		return false;
	}

	$img_tmp = null;

	// If $degs > 360, first trim to 360
	if ( $degs > 360 ) {
		$img_old = imagecreatefromjpeg( $file );
		$sizes = getimagesize( $file );
		$w_old = $sizes[0];
		$h_old = $sizes[1];
		$w_tmp = round( $w_old * 360 / $degs );
		$img_tmp = imagecreatetruecolor( $w_tmp, $h_old );
		imagecopy( $img_tmp, $img_old, 0, 0, round( ( $w_old - $w_tmp ) / 2 ), 0, $w_tmp, $h_old );
		$w_old = $w_tmp;
	}

	// Get current size if <= 360
	else {
		$sizes = getimagesize( $file );
		$w_old = $sizes[0];
		$h_old = $sizes[1];
	}

	// Compute new sizes
	$w_new = $w_old * 360 / $degs;
	$h_new = $w_new / 2;

	// Compute compressionfactor
	$c = 1.0;
	$w_max = wppa_opt( 'panorama_max' );
	if ( $w_new > $w_max ) {
		$c = $w_max / $w_new;
	}

	// Correct new sizes for compressionfactor
	$w_new = round( $w_new * $c );
	$h_new = round( $h_new * $c );

	// Create old image
	if ( $img_tmp ) {
		$image_old = $img_tmp;
	}
	else {
		$image_old = imagecreatefromjpeg( $file );
	}

	// Create canvas
	$canvas = imagecreatetruecolor( $w_new, $h_new );

	// Compute coords
	$dst_x = round( ( $w_new - $w_old * $c ) / 2 );
	$dst_y = round( ( $h_new - $h_old * $c ) / 2 );
	$src_x = 0;
	$src_y = 0;
	$dst_w = round( $w_old * $c );
	$dst_h = round( $h_old * $c );
	$src_w = $w_old;
	$src_h = $h_old;

	// Copy into canvas
	if ( ! imagecopyresampled( $canvas, $image_old, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) ) {
		return false;
	}

	// Save new image as o1 source
	$dst_path = wppa_get_o1_source_path( $id );
	if ( ! wppa_imagejpeg( $canvas, $dst_path, wppa_opt( 'jpeg_quality' ) ) ) {
		return false;
	}

	// Housekeeping
	imagedestroy( $canvas );
	wppa_bump_photo_rev();
	wppa_bump_thumb_rev();

	// All done
	return true;
}
