Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

1169 lines (1004 sloc) 46.079 kb
<?php /*
ocPortal
Copyright (c) ocProducts, 2004-2012
See text/EN/licence.txt for full licencing information.
NOTE TO PROGRAMMERS:
Do not edit this file. If you need to make changes, save your changed file to the appropriate *_custom folder
**** If you ignore this advice, then your website upgrades (e.g. for bug fixes) will likely kill your changes ****
*/
/*EXTRA FUNCTIONS: shell_exec*/
/**
* @license http://opensource.org/licenses/cpal_1.0 Common Public Attribution License
* @copyright ocProducts Ltd
* @package galleries
*/
/**
* Get width,height,length of a video file. Note: unfortunately mpeg is not possible without huge amounts of code.
*
* @param PATH The path to the video file
* @param string The original filename of the video file (so we can find the file type from the file extension)
* @param boolean Whether to skip over errored files instead of dying. We don't currently make use of this as our readers aren't sophisticard enough to properly spot erroneous situations.
* @return ~array The triplet of width/height/length (possibly containing NULL's for when we can't detect properties) (false: error)
*/
function get_video_details($file_path,$filename,$delay_errors=false)
{
unset($delay_errors);
$info=NULL;
$extension=get_file_extension($filename);
$file=@fopen($file_path,'rb');
if ($file===false) return false;
switch ($extension)
{
case 'wmv':
$info=_get_wmv_details($file);
break;
case 'asf':
$info=_get_wmv_details($file);
break;
case 'avi':
$info=_get_avi_details($file);
break;
case 'rm':
$info=_get_ram_details($file);
break;
case 'ram':
$info=_get_ram_details($file);
break;
case 'qt':
$info=_get_mov_details($file);
break;
case 'mov':
$info=_get_mov_details($file);
break;
case 'mp4':
$info=_get_mov_details($file);
break;
case 'm4v':
$info=_get_mov_details($file);
break;
default:
if (file_exists(get_file_base().'/sources_custom/getid3/getid3.php'))
{
error_reporting(0);
if (!defined('GETID3_HELPERAPPSDIR')) define('GETID3_HELPERAPPSDIR',get_file_base().'/sources_custom/getid3/helperapps');
require_code('getid3/getid3');
if (class_exists('getID3'))
{
$id3_ob=new getID3();
$_info=$id3_ob->analyze($file_path);
$info=array(
isset($_info['video']['resolution_x'])?$_info['video']['resolution_x']:NULL,
isset($_info['video']['resolution_y'])?$_info['video']['resolution_y']:NULL,
array_key_exists('playtime_seconds',$_info)?intval($_info['playtime_seconds']):NULL,
);
if (isset($_info['meta']['onMetaData']['width'])) $info[0]=intval($_info['meta']['onMetaData']['width']);
if (isset($_info['meta']['onMetaData']['height'])) $info[1]=intval($_info['meta']['onMetaData']['height']);
require_code('mime_types');
$mime_type=get_mime_type($extension);
if (substr($mime_type,0,6)=='audio/')
{
$info[0]=NULL;
$info[1]=NULL;
}
}
}
break;
}
fclose($file);
if (is_null($info)) return array(NULL,NULL,NULL);
return $info;
}
/**
* Read an integer from the given binary chunk. The integer is in intel endian form.
*
* @param string The binary chunk
* @return integer The integer
*/
function read_intel_endian_int($buffer)
{
if (strlen($buffer)==2)
{
return ord($buffer[0])|(ord($buffer[1])<<8);
}
if (strlen($buffer)<4) warn_exit(do_lang_tempcode('CORRUPT_FILE',do_lang('VIDEO'))); // Error
return ord($buffer[0])|(ord($buffer[1])<<8)|(ord($buffer[2])<<16)|(ord($buffer[3])<<24);
}
/**
* Read an integer from the given binary chunk. The integer is in network endian form.
*
* @param string The binary chunk
* @return integer The integer
*/
function read_network_endian_int($buffer)
{
if (strlen($buffer)==2)
{
return ord($buffer[1])|(ord($buffer[0])<<8);
}
if (strlen($buffer)<4) warn_exit(do_lang_tempcode('CORRUPT_FILE',do_lang('VIDEO'))); // Error
return ord($buffer[3])|(ord($buffer[2])<<8)|(ord($buffer[1])<<16)|(ord($buffer[0])<<24);
}
/**
* Get width,height,length of a .wmv video file.
*
* @param resource The file handle
* @return array The triplet (possibly containing NULL's for when we can't detect properties)
*/
function _get_wmv_details($file)
{
// Read in chunks
list($_,$width,$height,$length)=_get_wmv_details_do_chunk_list($file);
return array($width,$height,$length);
}
/**
* Get chunk-bytes-read,width,height,length of a chunk list of a .wmv video file.
*
* @param resource The file handle
* @param ?integer The length of the current chunk list (NULL: covers full file)
* @return ?array The quartet (possibly containing NULL's for when we can't detect properties) (NULL: error)
*/
function _get_wmv_details_do_chunk_list($file,$chunk_length=NULL)
{
$length=NULL;
$width=NULL;
$height=NULL;
$count=0;
while ((!feof($file)) && ((is_null($chunk_length)) || ($count<$chunk_length)) && ((is_null($length)) || (is_null($width)) || (is_null($height))))
{
// Read in chunk info
$a=read_intel_endian_int(fread($file,4));
$b=read_intel_endian_int(fread($file,4));
$c=read_intel_endian_int(fread($file,4));
$d=read_intel_endian_int(fread($file,4));
$sub_chunk_length=read_intel_endian_int(fread($file,4));
$count+=$sub_chunk_length;
if ($sub_chunk_length<=24) return NULL; // Some kind of error that would cause mayhem
fseek($file,4,SEEK_CUR); // Can't read 64 bit
// Header chunk
if (($a==intval(0x75B22630)) && ($b==intval(0x11CF668E)) && ($c==intval(0xAA00D9A6)) && ($d==intval(0x6CCE6200)))
{
fseek($file,6,SEEK_CUR);
$info=_get_wmv_details_do_chunk_list($file,$sub_chunk_length-30);
$sub_chunk_length=24;
if (!is_null($info[1])) $width=$info[1];
if (!is_null($info[2])) $height=$info[2];
if (!is_null($info[3])) $length=$info[3];
}
// Header object
if (($a==intval(0x8CABDCA1)) && ($b==intval(0x11CFA947)) && ($c==intval(0xC000E48E)) && ($d==intval(0x6553200C)))
{
fseek($file,48,SEEK_CUR);
$length=intval(round(read_intel_endian_int(fread($file,4))/10000000));
$sub_chunk_length-=52;
}
// Stream header object
if (($a==intval(0xB7DC0791)) && ($b==intval(0x11CFA9B7)) && ($c==intval(0xC000E68E)) && ($d==intval(0x6553200C)))
{
// Read in chunk info
$a=read_intel_endian_int(fread($file,4));
$b=read_intel_endian_int(fread($file,4));
$c=read_intel_endian_int(fread($file,4));
$d=read_intel_endian_int(fread($file,4));
$sub_chunk_length-=16;
if (($a==intval(0xBC19EFC0)) && ($b==intval(0x11CF5B4D)) && ($c==intval(0x8000FDA8)) && ($d==intval(0x2B445C5F))) // Video chunk
{
fseek($file,38,SEEK_CUR);
$width=read_intel_endian_int(fread($file,4));
$height=read_intel_endian_int(fread($file,4));
$sub_chunk_length-=46;
}
}
fseek($file,$sub_chunk_length-24,SEEK_CUR);
}
return array($count,$width,$height,$length);
}
/**
* Get width,height,length of a .avi video file.
*
* @param resource The file handle
* @return array The triplet (possibly containing NULL's for when we can't detect properties)
*/
function _get_avi_details($file)
{
fseek($file,32,SEEK_CUR);
$microseconds_per_frame=read_intel_endian_int(fread($file,4));
fseek($file,12,SEEK_CUR);
$num_frames=read_intel_endian_int(fread($file,4));
$length=intval(round(floatval($num_frames*$microseconds_per_frame)/1000/1000));
fseek($file,12,SEEK_CUR);
$width=read_intel_endian_int(fread($file,4));
$height=read_intel_endian_int(fread($file,4));
return array($width,$height,$length);
}
/**
* Get width,height,length of a .rm/.ram video file.
*
* @param resource The file handle
* @return ?array The triplet (possibly containing NULL's for when we can't detect properties) (NULL: error)
*/
function _get_ram_details($file) // + rm
{
$length=NULL;
$width=NULL;
$height=NULL;
// Read in chunks
while ((!feof($file)) && ((is_null($length)) || (is_null($width)) || (is_null($height))))
{
$type=fread($file,4);
$size=read_network_endian_int(fread($file,4));
if ($size<=8) return NULL;
if ($type=='PROP')
{
fseek($file,22,SEEK_CUR);
$length=intval(round(read_network_endian_int(fread($file,4))/1000));
return array($width,$height,$length);
} else fseek($file,$size-8,SEEK_CUR);
}
return array($width,$height,$length);
}
/**
* Get width,height,length of a .mov/.qt video file.
*
* @param resource The file handle
* @return ?array The triplet (possibly containing NULL's for when we can't detect properties) (NULL: error)
*/
function _get_mov_details($file)
{
// Read in atoms
$info=_get_mov_details_do_atom_list($file);
if (is_null($info)) return NULL;
list($_,$width,$height,$length)=$info;
return array($width,$height,$length);
}
/**
* Get chunk-bytes-read,width,height,length of a atom list of a .mov/.qt video file.
*
* @param resource The file handle
* @param ?integer The length of the current atom list (NULL: covers full file)
* @return array The quartet (possibly containing NULL's for when we can't detect properties)
*/
function _get_mov_details_do_atom_list($file,$atom_size=NULL)
{
$length=NULL;
$width=NULL;
$height=NULL;
$count=0;
while ((!feof($file)) && ((is_null($atom_size)) || ($count<$atom_size)) && ((is_null($length)) || (is_null($width)) || (is_null($height))))
{
$next_read=fread($file,4);
if (strlen($next_read)<4) return array($count,$width,$height,$length); // END / problem
$size=read_network_endian_int($next_read);
if ($size<8) // NB: uuid atom can be of size 8 (i.e. empty) on some rare files
{
return array($count,$width,$height,$length); // END / problem
}
$count+=4;
if ($size==0)
{
// $qt_atom=true;
fseek($file,8,SEEK_CUR);
$size=read_network_endian_int(fread($file,4));
$count+=12;
}// else $qt_atom=false;
$type=fread($file,4);
$count+=4;
if ($type=='mvhd')
{
fseek($file,12,SEEK_CUR);
$time_scale=read_network_endian_int(fread($file,4));
$duration=read_network_endian_int(fread($file,4));
$length=intval(round(floatval($duration)/floatval($time_scale)));
fseek($file,80,SEEK_CUR);
$count+=20+80;
}
elseif ($type=='tkhd')
{
fseek($file,76,SEEK_CUR);
$_width=read_network_endian_int(fread($file,2));
fseek($file,2,SEEK_CUR); // fixed point - but we don't want decimal fraction part
$_height=read_network_endian_int(fread($file,2));
fseek($file,2,SEEK_CUR); // fixed point - but we don't want decimal fraction part
$count+=76+8;
if ($_width>0) $width=$_width;
if ($_height>0) $height=$_height;
}
elseif ($type=='moov') // moov contains more atoms, and the one we need for length
{
$info=_get_mov_details_do_atom_list($file,$size-$count);
$count+=$info[0];
if (!is_null($info[1])) $width=$info[1];
if (!is_null($info[2])) $height=$info[2];
if (!is_null($info[3])) $length=$info[3];
}
elseif ($type=='trak') // trak contains more atoms, and the one we need for width and height
{
$info=_get_mov_details_do_atom_list($file,$size-$count);
$count+=$info[0];
if (!is_null($info[1])) $width=$info[1];
if (!is_null($info[2])) $height=$info[2];
if (!is_null($info[3])) $length=$info[3];
} else
{
fseek($file,$size-8,SEEK_CUR);
$count+=$size-8;
}
}
return array($count,$width,$height,$length);
}
/**
* Add an image to a specified gallery.
*
* @param SHORT_TEXT Image title
* @param ID_TEXT The gallery name
* @param LONG_TEXT The image comments
* @param URLPATH The URL to the actual image
* @param URLPATH The URL to the thumbnail of the actual image
* @param BINARY Whether the image has been validated for display on the site
* @param BINARY Whether the image may be rated
* @param BINARY Whether the image may be commented upon
* @param BINARY Whether the image may be trackbacked
* @param LONG_TEXT Hidden notes associated with the image
* @param ?MEMBER The submitter (NULL: current member)
* @param ?TIME The time of adding (NULL: now)
* @param ?TIME The time of editing (NULL: never)
* @param integer The number of views
* @param ?AUTO_LINK Force an ID (NULL: don't force an ID)
* @return AUTO_LINK The ID of the new entry
*/
function add_image($title,$cat,$comments,$url,$thumb_url,$validated,$allow_rating,$allow_comments,$allow_trackbacks,$notes,$submitter=NULL,$add_date=NULL,$edit_date=NULL,$views=0,$id=NULL)
{
if (is_null($submitter)) $submitter=get_member();
if (is_null($add_date)) $add_date=time();
if (!addon_installed('unvalidated')) $validated=1;
$map=array('title'=>insert_lang_comcode($title,2),'edit_date'=>$edit_date,'image_views'=>$views,'add_date'=>$add_date,'allow_rating'=>$allow_rating,'allow_comments'=>$allow_comments,'allow_trackbacks'=>$allow_trackbacks,'notes'=>$notes,'submitter'=>$submitter,'url'=>$url,'thumb_url'=>$thumb_url,'comments'=>insert_lang_comcode($comments,3),'cat'=>$cat,'validated'=>$validated);
if (!is_null($id)) $map['id']=$id;
$id=$GLOBALS['SITE_DB']->query_insert('images',$map,true);
log_it('ADD_IMAGE',strval($id),$title);
require_code('seo2');
seo_meta_set_for_implicit('image',strval($id),array($comments),$comments);
if ($validated==1)
{
require_lang('galleries');
require_code('notifications');
$subject=do_lang('IMAGE_NOTIFICATION_MAIL_SUBJECT',get_site_name(),strip_comcode($title));
$self_url=build_url(array('page'=>'galleries','type'=>'image','id'=>$id),get_module_zone('galleries'),NULL,false,false,true);
$mail=do_lang('IMAGE_NOTIFICATION_MAIL',comcode_escape(get_site_name()),comcode_escape($title),array(comcode_escape($self_url->evaluate())));
dispatch_notification('gallery_entry',$cat,$subject,$mail);
}
decache('side_root_galleries');
decache('main_gallery_embed');
decache('main_download_category');
decache('main_image_fader');
return $id;
}
/**
* Edit an image in a specified gallery.
*
* @param AUTO_LINK The ID of the image to edit
* @param SHORT_TEXT Image title
* @param ID_TEXT The gallery name
* @param LONG_TEXT The image comments
* @param URLPATH The URL to the actual image
* @param URLPATH The URL to the thumbnail of the actual image
* @param BINARY Whether the image has been validated for display on the site
* @param BINARY Whether the image may be rated
* @param BINARY Whether the image may be commented upon
* @param BINARY Whether the image may be trackbacked
* @param LONG_TEXT Hidden notes associated with the image
* @param SHORT_TEXT Meta keywords
* @param LONG_TEXT Meta description
*/
function edit_image($id,$title,$cat,$comments,$url,$thumb_url,$validated,$allow_rating,$allow_comments,$allow_trackbacks,$notes,$meta_keywords,$meta_description)
{
require_code('urls2');
suggest_new_idmoniker_for('galleries','image',strval($id),($title=='')?$comments:$title);
$_comments=$GLOBALS['SITE_DB']->query_value('images','comments',array('id'=>$id));
$_title=$GLOBALS['SITE_DB']->query_value('images','title',array('id'=>$id));
decache('main_gallery_embed');
require_code('files2');
delete_upload('uploads/galleries','images','url','id',$id,$url);
delete_upload('uploads/galleries_thumbs','images','thumb_url','id',$id,$thumb_url);
if (!addon_installed('unvalidated')) $validated=1;
require_code('submit');
$just_validated=(!content_validated('image',strval($id))) && ($validated==1);
if ($just_validated)
{
send_content_validated_notification('image',strval($id));
}
$GLOBALS['SITE_DB']->query_update('images',array('title'=>lang_remap_comcode($_title,$title),'edit_date'=>time(),'allow_rating'=>$allow_rating,'allow_comments'=>$allow_comments,'allow_trackbacks'=>$allow_trackbacks,'notes'=>$notes,'validated'=>$validated,'cat'=>$cat,'comments'=>lang_remap_comcode($_comments,$comments),'url'=>$url,'thumb_url'=>$thumb_url),array('id'=>$id),'',1);
$self_url=build_url(array('page'=>'galleries','type'=>'image','id'=>$id),get_module_zone('galleries'),NULL,false,false,true);
if ($just_validated)
{
require_lang('galleries');
require_code('notifications');
$subject=do_lang('IMAGE_NOTIFICATION_MAIL_SUBJECT',get_site_name(),strip_comcode($title));
$mail=do_lang('IMAGE_NOTIFICATION_MAIL',comcode_escape(get_site_name()),comcode_escape($title),array(comcode_escape($self_url->evaluate())));
dispatch_notification('gallery_entry',$cat,$subject,$mail);
}
log_it('EDIT_IMAGE',strval($id),$title);
require_code('seo2');
seo_meta_set_for_explicit('image',strval($id),$meta_keywords,$meta_description);
decache('main_download_category');
decache('main_image_fader');
require_lang('galleries');
require_code('feedback');
update_spacer_post($allow_comments!=0,'images',strval($id),$self_url,do_lang('VIEW_IMAGE','','','',get_site_default_lang()),get_value('comment_forum__images'));
}
/**
* Delete a specified image from the database, and delete the file if possible.
*
* @param AUTO_LINK The ID of the image
* @param boolean Whether to delete the actual file also
*/
function delete_image($id,$delete_full)
{
$rows=$GLOBALS['SITE_DB']->query_select('images',array('title','comments','cat'),array('id'=>$id));
$title=$rows[0]['title'];
$comments=$rows[0]['comments'];
$cat=$rows[0]['cat'];
log_it('DELETE_IMAGE',strval($id),get_translated_text($title));
delete_lang($comments);
delete_lang($title);
// Delete file
if ($delete_full)
{
require_code('files2');
delete_upload('uploads/galleries','images','url','id',$id);
delete_upload('uploads/galleries_thumbs','images','thumb_url','id',$id);
}
// Delete from database
$GLOBALS['SITE_DB']->query_delete('images',array('id'=>$id),'',1);
$GLOBALS['SITE_DB']->query_delete('rating',array('rating_for_type'=>'images','rating_for_id'=>$id));
$GLOBALS['SITE_DB']->query_delete('trackbacks',array('trackback_for_type'=>'images','trackback_for_id'=>$id));
require_code('seo2');
seo_meta_erase_storage('image',strval($id));
decache('side_root_galleries');
decache('main_gallery_embed');
decache('main_image_fader');
}
/**
* Create a video thumbnail.
*
* @param URLPATH Video to get thumbail from (must be local)
* @param ?PATH Where to save to (NULL: decide for ourselves)
* @return URLPATH Thumbnail, only valid if expected_output_path was passed as NULL (blank: could not generate)
*/
function create_video_thumb($src_url,$expected_output_path=NULL)
{
// Audio ones should have automatic thumbnails
require_code('mime_types');
$file_ext=get_file_extension($src_url);
$input_mime_type=get_mime_type($file_ext);
if (preg_match('#audio\/#i',$input_mime_type)!=0)
{
return find_theme_image('audio_thumb',true);
}
// Try one of the hooks for video types
$ve_hooks=find_all_hooks('systems','video_embed');
foreach (array_keys($ve_hooks) as $ve_hook)
{
require_code('hooks/systems/video_embed/'.$ve_hook);
$ve_ob=object_factory('Hook_video_embed_'.$ve_hook);
$thumbnail=$ve_ob->get_video_thumbnail($src_url);
if (!is_null($thumbnail)) return $thumbnail;
}
// Ok, gonna try hard using what FFMPEG techniques we can...
if (substr($src_url,0,strlen(get_custom_base_url().'/'))==get_custom_base_url().'/') $src_url=substr($src_url,strlen(get_custom_base_url().'/'));
if (!url_is_local($src_url)) return '';
$src_file=get_custom_file_base().'/'.rawurldecode($src_url);
$src_file=preg_replace('#(\\\|/)#',DIRECTORY_SEPARATOR,$src_file);
if (class_exists('ffmpeg_movie'))
{
$filename='thumb_'.md5(uniqid('')).'1.jpg';
if (is_null($expected_output_path))
$expected_output_path=get_custom_file_base().'/uploads/galleries/'.$filename;
if (file_exists($expected_output_path))
return 'uploads/galleries/'.rawurlencode(basename($expected_output_path));
$movie=@(new ffmpeg_movie($src_file,false));
if ($movie!==false)
{
if ($movie->getFrameCount()==0) return '';
$frame=$movie->getFrame(min($movie->getFrameCount(),25));
$gd_img=$frame->toGDImage();
@imagejpeg($gd_img,$expected_output_path);
if (file_exists($expected_output_path))
{
require_code('images');
if ((get_option('is_on_gd')=='1') && (function_exists('imagecreatefromstring')))
convert_image($expected_output_path,$expected_output_path,-1,-1,intval(get_option('thumb_width')),true,NULL,true);
return 'uploads/galleries/'.rawurlencode(basename($expected_output_path));
}
}
}
$ffmpeg_path=get_option('ffmpeg_path');
if (($ffmpeg_path!='') && (strpos(@ini_get('disable_functions'),'shell_exec')===false))
{
$filename='thumb_'.md5(uniqid(strval(post_param_integer('thumbnail_auto_position',1)))).'%d.jpg';
$dest_file=get_custom_file_base().'/uploads/galleries/'.$filename;
if (is_null($expected_output_path))
$expected_output_path=str_replace('%d','1',$dest_file);
if ((file_exists($dest_file)) && (is_null(post_param_integer('thumbnail_auto_position',NULL))))
return 'uploads/galleries/'.rawurlencode(basename($expected_output_path));
@unlink($dest_file); // So "if (@filesize($expected_output_path)) break;" will definitely fail if error
$dest_file=preg_replace('#(\\\|/)#',DIRECTORY_SEPARATOR,$dest_file);
$at=display_seconds_period(post_param_integer('thumbnail_auto_position',1));
if (strlen($at)==5) $at='00:'.$at;
$shell_command='"'.$ffmpeg_path.'ffmpeg" -i '.@escapeshellarg($src_file).' -an -ss '.$at.' -r 1 -vframes 1 -y '.@escapeshellarg($dest_file);
$shell_commands=array($shell_command,$shell_command.' -map 0.0:0.0',$shell_command.' -map 0.1:0.0');
foreach ($shell_commands as $shell_command)
{
shell_exec($shell_command);
if (@filesize($expected_output_path)) break;
}
if (file_exists(str_replace('%d','1',$dest_file)))
{
require_code('images');
if ((get_option('is_on_gd')=='1') && (function_exists('imagecreatefromstring')))
{
convert_image(str_replace('%d','1',$dest_file),$expected_output_path,-1,-1,intval(get_option('thumb_width')),true,NULL,true);
} else
{
copy(str_replace('%d','1',$dest_file),$expected_output_path);
fix_permissions($expected_output_path);
sync_file($expected_output_path);
}
return 'uploads/galleries/'.rawurlencode(basename($expected_output_path));
}
}
return '';
}
/**
* Add a video to a specified gallery.
*
* @param SHORT_TEXT Video title
* @param ID_TEXT The gallery name
* @param LONG_TEXT The video comments
* @param URLPATH The URL to the actual video
* @param URLPATH The URL to the thumbnail of the actual video
* @param BINARY Whether the video has been validated for display on the site
* @param BINARY Whether the video may be rated
* @param BINARY Whether the video may be commented upon
* @param BINARY Whether the video may be trackbacked
* @param LONG_TEXT Hidden notes associated with the video
* @param integer The length of the video
* @param integer The width of the video
* @param integer The height of the video
* @param ?MEMBER The submitter (NULL: current member)
* @param ?TIME The time of adding (NULL: now)
* @param ?TIME The time of editing (NULL: never)
* @param integer The number of views
* @param ?AUTO_LINK Force an ID (NULL: don't force an ID)
* @return AUTO_LINK The ID of the new entry
*/
function add_video($title,$cat,$comments,$url,$thumb_url,$validated,$allow_rating,$allow_comments,$allow_trackbacks,$notes,$video_length,$video_width,$video_height,$submitter=NULL,$add_date=NULL,$edit_date=NULL,$views=0,$id=NULL)
{
if (is_null($submitter)) $submitter=get_member();
if (is_null($add_date)) $add_date=time();
require_code('transcoding');
$url=transcode_video($url,'videos','url',NULL,'video_width','video_height');
if (!addon_installed('unvalidated')) $validated=1;
$map=array('title'=>insert_lang_comcode($title,2),'edit_date'=>$edit_date,'video_views'=>$views,'add_date'=>$add_date,'allow_rating'=>$allow_rating,'allow_comments'=>$allow_comments,'allow_trackbacks'=>$allow_trackbacks,'notes'=>$notes,'submitter'=>$submitter,'url'=>$url,'thumb_url'=>$thumb_url,'comments'=>insert_lang_comcode($comments,3),'cat'=>$cat,'validated'=>$validated,'video_length'=>$video_length,'video_width'=>$video_width,'video_height'=>$video_height);
if (!is_null($id)) $map['id']=$id;
$id=$GLOBALS['SITE_DB']->query_insert('videos',$map,true);
log_it('ADD_VIDEO',strval($id),$title);
if ($validated==1)
{
require_lang('galleries');
require_code('notifications');
$subject=do_lang('VIDEO_NOTIFICATION_MAIL_SUBJECT',get_site_name(),strip_comcode($title));
$self_url=build_url(array('page'=>'galleries','type'=>'video','id'=>$id),get_module_zone('galleries'),NULL,false,false,true);
$mail=do_lang('VIDEO_NOTIFICATION_MAIL',comcode_escape(get_site_name()),comcode_escape($title),array(comcode_escape($self_url->evaluate())));
dispatch_notification('gallery_entry',$cat,$subject,$mail);
}
require_code('seo2');
seo_meta_set_for_implicit('video',strval($id),array($comments),$comments);
decache('side_root_galleries');
decache('main_gallery_embed');
return $id;
}
/**
* Edit a video in a specified gallery.
*
* @param AUTO_LINK The ID of the entry to edit
* @param SHORT_TEXT Video title
* @param ID_TEXT The gallery name
* @param LONG_TEXT The video comments
* @param URLPATH The URL to the actual video
* @param URLPATH The URL to the thumbnail of the actual video
* @param BINARY Whether the video has been validated for display on the site
* @param BINARY Whether the video may be rated
* @param BINARY Whether the video may be commented upon
* @param BINARY Whether the video may be trackbacked
* @param LONG_TEXT Hidden notes associated with the video
* @param integer The length of the video
* @param integer The width of the video
* @param integer The height of the video
* @param SHORT_TEXT Meta keywords
* @param LONG_TEXT Meta description
*/
function edit_video($id,$title,$cat,$comments,$url,$thumb_url,$validated,$allow_rating,$allow_comments,$allow_trackbacks,$notes,$video_length,$video_width,$video_height,$meta_keywords,$meta_description)
{
require_code('urls2');
suggest_new_idmoniker_for('galleries','video',strval($id),($title=='')?$comments:$title);
$_title=$GLOBALS['SITE_DB']->query_value('videos','title',array('id'=>$id));
$_comments=$GLOBALS['SITE_DB']->query_value('videos','comments',array('id'=>$id));
require_code('files2');
delete_upload('uploads/galleries','videos','url','id',$id,$url);
delete_upload('uploads/galleries_thumbs','videos','thumb_url','id',$id,$thumb_url);
require_code('transcoding');
$url=transcode_video($url,'videos','url',NULL,'video_width','video_height');
if (!addon_installed('unvalidated')) $validated=1;
require_code('submit');
$just_validated=(!content_validated('video',strval($id))) && ($validated==1);
if ($just_validated)
{
send_content_validated_notification('video',strval($id));
}
$GLOBALS['SITE_DB']->query_update('videos',array('title'=>lang_remap_comcode($_title,$title),'edit_date'=>time(),'allow_rating'=>$allow_rating,'allow_comments'=>$allow_comments,'allow_trackbacks'=>$allow_trackbacks,'notes'=>$notes,'validated'=>$validated,'cat'=>$cat,'comments'=>lang_remap_comcode($_comments,$comments),'url'=>$url,'thumb_url'=>$thumb_url,'video_length'=>$video_length,'video_width'=>$video_width,'video_height'=>$video_height),array('id'=>$id),'',1);
$self_url=build_url(array('page'=>'galleries','type'=>'video','id'=>$id),get_module_zone('galleries'),NULL,false,false,true);
if ($just_validated)
{
require_lang('galleries');
require_code('notifications');
$subject=do_lang('VIDEO_NOTIFICATION_MAIL_SUBJECT',get_site_name(),strip_comcode($title));
$mail=do_lang('VIDEO_NOTIFICATION_MAIL',comcode_escape(get_site_name()),comcode_escape($title),array(comcode_escape($self_url->evaluate())));
dispatch_notification('gallery_entry',$cat,$subject,$mail);
}
log_it('EDIT_VIDEO',strval($id),$title);
require_code('seo2');
seo_meta_set_for_explicit('video',strval($id),$meta_keywords,$meta_description);
decache('main_gallery_embed');
require_lang('galleries');
require_code('feedback');
update_spacer_post($allow_comments!=0,'videos',strval($id),$self_url,do_lang('VIEW_VIDEO','','','',get_site_default_lang()),get_value('comment_forum__videos'));
}
/**
* Delete a video in a specified gallery.
*
* @param AUTO_LINK The ID of the entry to delete
* @param boolean Whether to delete the actual video file from disk as well as the entry
*/
function delete_video($id,$delete_full)
{
$rows=$GLOBALS['SITE_DB']->query_select('videos',array('title','comments','cat'),array('id'=>$id));
$title=$rows[0]['title'];
$comments=$rows[0]['comments'];
$cat=$rows[0]['cat'];
log_it('DELETE_VIDEO',strval($id),get_translated_text($title));
delete_lang($title);
delete_lang($comments);
if ($delete_full)
{
require_code('files2');
delete_upload('uploads/galleries','videos','url','id',$id);
delete_upload('uploads/galleries_thumbs','videos','thumb_url','id',$id);
}
// Delete from database
$GLOBALS['SITE_DB']->query_delete('videos',array('id'=>$id),'',1);
$GLOBALS['SITE_DB']->query_delete('rating',array('rating_for_type'=>'videos','rating_for_id'=>$id));
$GLOBALS['SITE_DB']->query_delete('trackbacks',array('trackback_for_type'=>'videos','trackback_for_id'=>$id));
require_code('seo2');
seo_meta_erase_storage('video',strval($id));
decache('side_root_galleries');
decache('main_gallery_embed');
}
/**
* Watermarks an image with the appropriate gallery watermarks.
*
* @param ID_TEXT The name of the gallery for the image
* @param PATH The path to the image file
* @param string The original file name of the image
*/
function watermark_gallery_image($gallery,$file_path,$filename)
{
// We can't watermark an image we can't save
require_code('images');
if (!function_exists('imagecreatefromstring')) return;
if (!is_saveable_image($filename)) return;
// We need to find the most applicable gallery watermarks
$watermark_top_left='';
$watermark_top_right='';
$watermark_bottom_left='';
$watermark_bottom_right='';
do
{
if ($gallery=='') return; // We couldn't find any matermarks
$_gallery=$GLOBALS['SITE_DB']->query_select('galleries',array('parent_id','watermark_top_left','watermark_top_right','watermark_bottom_left','watermark_bottom_right'),array('name'=>$gallery),'',1);
$watermark_top_left=$_gallery[0]['watermark_top_left'];
$watermark_top_right=$_gallery[0]['watermark_top_right'];
$watermark_bottom_left=$_gallery[0]['watermark_bottom_left'];
$watermark_bottom_right=$_gallery[0]['watermark_bottom_right'];
$gallery=$_gallery[0]['parent_id'];
}
while (($watermark_top_left=='') && ($watermark_top_right=='') && ($watermark_bottom_left=='') && ($watermark_bottom_right==''));
// Now we must apply the watermarks
$ext=get_file_extension($filename);
$source=@imagecreatefromstring(file_get_contents($file_path));
if ($source===false) return; // We couldn't load it for some reason
// Apply the watermarks
_watermark_corner($source,$watermark_top_left,0,0);
_watermark_corner($source,$watermark_top_right,1,0);
_watermark_corner($source,$watermark_bottom_left,0,1);
_watermark_corner($source,$watermark_bottom_right,1,1);
// Save
if ($ext=='png') imagepng($source,$file_path);
elseif (($ext=='jpg') || ($ext=='jpeg')) imagejpeg($source,$file_path);
elseif ((function_exists('imagegif')) && ($ext=='gif')) imagegif($source,$file_path);
// Clean up
imagedestroy($source);
}
/**
* Watermark the corner of an image.
*
* @param resource The image resource being watermarked
* @param URLPATH The (local) URL to the watermark file
* @param BINARY Whether a right hand side corner is being watermarked
* @param BINARY Whether a bottom edge corner is being watermarked
*/
function _watermark_corner(/*&*/$source,$watermark_url,$x,$y)
{
if ($watermark_url!='')
{
$watermark=@imagecreatefromstring(file_get_contents(rawurldecode($watermark_url)));
if ($watermark!==false)
{
imagecolortransparent($watermark,imagecolorallocate($watermark,255,0,255));
if ($x==1) $x=imagesx($source)-imagesx($watermark);
if ($y==1) $y=imagesy($source)-imagesy($watermark);
imagecopy($source,$watermark,$x,$y,0,0,imagesx($watermark),imagesy($watermark));
imagedestroy($watermark);
}
}
}
/**
* Make sure the detailed image file is not bigger than the defined box width.
*
* @param PATH The path to the image file
* @param string The original filename of the image
* @param integer The box width
*/
function constrain_gallery_image_to_max_size($file_path,$filename,$box_width)
{
// We can't watermark an image we can't save
require_code('images');
if (!is_saveable_image($filename)) return;
if ((get_option('is_on_gd')=='1') && (function_exists('imagecreatefromstring')))
convert_image($file_path,$file_path,-1,-1,$box_width,false,get_file_extension($filename),true,true);
}
/**
* Add a gallery with the specified parameters.
*
* @param ID_TEXT The gallery codename
* @param SHORT_TEXT The full human-readeable name of the gallery
* @param LONG_TEXT The description of the gallery
* @param SHORT_TEXT Teaser text for the gallery
* @param LONG_TEXT Hidden notes associated with the gallery
* @param ID_TEXT The parent gallery (blank: no parent)
* @param BINARY Whether images may be put in this gallery
* @param BINARY Whether videos may be put in this gallery
* @param BINARY Whether the gallery serves as a container for automatically created member galleries
* @param BINARY Whether the gallery uses the flow mode interface
* @param URLPATH The representative image of the gallery (blank: none)
* @param URLPATH Watermark (blank: none)
* @param URLPATH Watermark (blank: none)
* @param URLPATH Watermark (blank: none)
* @param URLPATH Watermark (blank: none)
* @param BINARY Whether rating are allowed
* @param BINARY Whether comments are allowed
* @param boolean Whether to skip the check for whether the gallery exists (useful for importers)
* @param ?TIME The add time (NULL: now)
* @param ?MEMBER The gallery owner (NULL: nobody)
*/
function add_gallery($name,$fullname,$description,$teaser,$notes,$parent_id,$accept_images=1,$accept_videos=1,$is_member_synched=0,$flow_mode_interface=0,$rep_image='',$watermark_top_left='',$watermark_top_right='',$watermark_bottom_left='',$watermark_bottom_right='',$allow_rating=1,$allow_comments=1,$skip_exists_check=false,$add_date=NULL,$g_owner=NULL)
{
if (is_null($add_date)) $add_date=time();
require_code('type_validation');
if (!is_alphanumeric($name)) warn_exit(do_lang_tempcode('BAD_CODENAME'));
if (!$skip_exists_check)
{
$test=$GLOBALS['SITE_DB']->query_value_null_ok('galleries','name',array('name'=>$name));
if (!is_null($test)) warn_exit(do_lang_tempcode('ALREADY_EXISTS',escape_html($name)));
}
$GLOBALS['SITE_DB']->query_insert('galleries',
array('name'=>$name,'add_date'=>$add_date,'description'=>insert_lang_comcode($description,2),'teaser'=>insert_lang_comcode($teaser,2),'notes'=>$notes,
'fullname'=>insert_lang($fullname,1),
'watermark_top_left'=>$watermark_top_left,'watermark_top_right'=>$watermark_top_right,
'watermark_bottom_left'=>$watermark_bottom_left,'watermark_bottom_right'=>$watermark_bottom_right,
'parent_id'=>$parent_id,'accept_images'=>$accept_images,'rep_image'=>$rep_image,
'accept_videos'=>$accept_videos,'is_member_synched'=>$is_member_synched,'flow_mode_interface'=>$flow_mode_interface,
'allow_rating'=>$allow_rating,'allow_comments'=>$allow_comments,'g_owner'=>$g_owner,
'gallery_views'=>0,
));
log_it('ADD_GALLERY',$name,$fullname);
require_code('seo2');
seo_meta_set_for_implicit('gallery',$name,array($fullname,$description),$description);
if (function_exists('decache'))
{
decache('main_top_galleries');
decache('main_recent_galleries');
decache('main_root_galleries');
decache('side_root_galleries');
}
}
/**
* Edit a gallery.
*
* @param ID_TEXT The old gallery codename (in case we are renaming)
* @param ID_TEXT The gallery codename (maybe the same as the old one)
* @param SHORT_TEXT The full human-readeable name of the gallery
* @param LONG_TEXT The description of the gallery
* @param SHORT_TEXT Teaser text for the gallery
* @param LONG_TEXT Hidden notes associated with the gallery
* @param ?ID_TEXT The parent gallery (NULL: no parent)
* @param BINARY Whether images may be put in this gallery
* @param BINARY Whether videos may be put in this gallery
* @param BINARY Whether the gallery serves as a container for automatically created member galleries
* @param BINARY Whether the gallery uses the flow mode interface
* @param URLPATH The representative image of the gallery (blank: none)
* @param URLPATH Watermark (blank: none)
* @param URLPATH Watermark (blank: none)
* @param URLPATH Watermark (blank: none)
* @param URLPATH Watermark (blank: none)
* @param ?SHORT_TEXT Meta keywords for this resource (NULL: do not edit)
* @param ?LONG_TEXT Meta description for this resource (NULL: do not edit)
* @param BINARY Whether rating are allowed
* @param BINARY Whether comments are allowed
* @param ?MEMBER The gallery owner (NULL: nobody)
*/
function edit_gallery($old_name,$name,$fullname,$description,$teaser,$notes,$parent_id=NULL,$accept_images=1,$accept_videos=1,$is_member_synched=0,$flow_mode_interface=0,$rep_image='',$watermark_top_left='',$watermark_top_right='',$watermark_bottom_left='',$watermark_bottom_right='',$meta_keywords=NULL,$meta_description=NULL,$allow_rating=1,$allow_comments=1,$g_owner=NULL)
{
require_code('urls2');
suggest_new_idmoniker_for('galleries','misc',$name,$fullname);
$under_category_id=$parent_id;
while (($under_category_id!='') && ($under_category_id!=STRING_MAGIC_NULL))
{
if ($name==$under_category_id) warn_exit(do_lang_tempcode('OWN_PARENT_ERROR'));
$under_category_id=$GLOBALS['SITE_DB']->query_value('galleries','parent_id',array('name'=>$under_category_id));
}
if (is_null($parent_id)) $parent_id='';
require_code('seo2');
if ($old_name!=$name)
{
require_code('type_validation');
if (!is_alphanumeric($name)) warn_exit(do_lang_tempcode('BAD_CODENAME'));
$test=$GLOBALS['SITE_DB']->query_value_null_ok('galleries','name',array('name'=>$name));
if (!is_null($test)) warn_exit(do_lang_tempcode('ALREADY_EXISTS',escape_html($name)));
seo_meta_erase_storage('gallery',$old_name);
$GLOBALS['SITE_DB']->query_update('images',array('cat'=>$name),array('cat'=>$old_name));
$GLOBALS['SITE_DB']->query_update('videos',array('cat'=>$name),array('cat'=>$old_name));
$GLOBALS['SITE_DB']->query_update('galleries',array('parent_id'=>$name),array('parent_id'=>$old_name));
$types=$GLOBALS['SITE_DB']->query_select('award_types',array('id'),array('a_content_type'=>'gallery'));
foreach ($types as $type)
{
$GLOBALS['SITE_DB']->query_update('award_archive',array('content_id'=>$name),array('content_id'=>$old_name,'a_type_id'=>$type['id']));
}
}
if (!is_null($meta_keywords)) seo_meta_set_for_explicit('gallery',$name,$meta_keywords,$meta_description);
$myrows=$GLOBALS['SITE_DB']->query_select('galleries',array('fullname','description','teaser'),array('name'=>$old_name),'',1);
if (!array_key_exists(0,$myrows)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
$myrow=$myrows[0];
$map=array('name'=>$name,'notes'=>$notes,'fullname'=>lang_remap($myrow['fullname'],$fullname),
'description'=>lang_remap_comcode($myrow['description'],$description),'teaser'=>lang_remap_comcode($myrow['teaser'],$teaser),'parent_id'=>$parent_id,'accept_images'=>$accept_images,
'accept_videos'=>$accept_videos,'is_member_synched'=>$is_member_synched,'flow_mode_interface'=>$flow_mode_interface,
'allow_rating'=>$allow_rating,'allow_comments'=>$allow_comments,'g_owner'=>$g_owner);
require_code('files2');
if (!is_null($rep_image))
{
$map['rep_image']=$rep_image;
delete_upload('uploads/grepimages','galleries','rep_image','name',$old_name,$rep_image);
}
if (!is_null($watermark_top_left))
{
$map['watermark_top_left']=$watermark_top_left;
delete_upload('uploads/watermarks','galleries','watermark_top_left','name',$old_name,$watermark_top_left);
}
if (!is_null($watermark_top_right))
{
$map['watermark_top_right']=$watermark_top_right;
delete_upload('uploads/watermarks','galleries','watermark_top_right','name',$old_name,$watermark_top_right);
}
if (!is_null($watermark_bottom_left))
{
$map['watermark_bottom_left']=$watermark_bottom_left;
delete_upload('uploads/watermarks','galleries','watermark_bottom_left','name',$old_name,$watermark_bottom_left);
}
if (!is_null($watermark_bottom_right))
{
$map['watermark_bottom_right']=$watermark_bottom_right;
delete_upload('uploads/watermarks','galleries','watermark_bottom_right','name',$old_name,$watermark_bottom_right);
}
$GLOBALS['SITE_DB']->query_update('galleries',$map,array('name'=>$old_name),'',1);
log_it('EDIT_GALLERY',$name,$fullname);
$GLOBALS['SITE_DB']->query_update('group_category_access',array('category_name'=>$name),array('module_the_name'=>'galleries','category_name'=>$old_name));
decache('main_top_galleries');
decache('main_recent_galleries');
decache('main_root_galleries');
decache('side_root_galleries');
require_code('feedback');
update_spacer_post($allow_comments!=0,'galleries',$name,build_url(array('page'=>'galleries','type'=>'misc','id'=>$name),get_module_zone('galleries'),NULL,false,false,true),$fullname,get_value('comment_forum__galleries'));
}
/**
* Delete a specified gallery.
*
* @param ID_TEXT The gallery codename
*/
function delete_gallery($name)
{
if ($name=='') warn_exit(do_lang_tempcode('NO_DELETE_ROOT'));
$rows=$GLOBALS['SITE_DB']->query_select('galleries',array('*'),array('name'=>$name),'',1);
if (!array_key_exists(0,$rows)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
require_code('files2');
delete_upload('uploads/grepimages','galleries','rep_image','name',$name);
delete_upload('uploads/watermarks','galleries','watermark_top_left','name',$name);
delete_upload('uploads/watermarks','galleries','watermark_top_right','name',$name);
delete_upload('uploads/watermarks','galleries','watermark_bottom_left','name',$name);
delete_upload('uploads/watermarks','galleries','watermark_bottom_right','name',$name);
log_it('DELETE_GALLERY',$name,get_translated_text($rows[0]['fullname']));
delete_lang($rows[0]['fullname']);
delete_lang($rows[0]['description']);
delete_lang($rows[0]['teaser']);
// Images and videos are deleted, because we are deleting the _gallery_, not just a category (nobody is going to be deleting galleries with the expectation of moving the image to a different one in bulk - unlike download categories, for example).
if (function_exists('set_time_limit')) @set_time_limit(0);
do
{
$images=$GLOBALS['SITE_DB']->query_select('images',array('id'),array('cat'=>$name),'',200);
foreach ($images as $image)
{
delete_image($image['id'],false);
}
}
while ($images!=array());
do
{
$videos=$GLOBALS['SITE_DB']->query_select('videos',array('id'),array('cat'=>$name),'',200);
foreach ($videos as $video)
{
delete_video($video['id'],false);
}
}
while ($images!=array());
//... but the subgalleries remain
$GLOBALS['SITE_DB']->query_update('galleries',array('parent_id'=>$rows[0]['parent_id']),array('parent_id'=>$name));
$GLOBALS['SITE_DB']->query_delete('galleries',array('name'=>$name),'',1);
$GLOBALS['SITE_DB']->query_delete('rating',array('rating_for_type'=>'images','rating_for_id'=>$name));
$GLOBALS['SITE_DB']->query_delete('rating',array('rating_for_type'=>'videos','rating_for_id'=>$name));
require_code('seo2');
seo_meta_erase_storage('gallery',$name);
$GLOBALS['SITE_DB']->query_delete('group_category_access',array('module_the_name'=>'galleries','category_name'=>$name));
$GLOBALS['SITE_DB']->query_delete('gsp',array('module_the_name'=>'galleries','category_name'=>$name));
decache('main_top_galleries');
decache('main_recent_galleries');
decache('main_root_galleries');
decache('side_root_galleries');
}
/**
* The UI shows member galleries that do not exist. If it is a member gallery, and it does not exist, it'll need making, before something can be added. This gallery performs the check and makes the gallery if needed.
*
* @param ID_TEXT The gallery name
*/
function make_member_gallery_if_needed($cat)
{
// If it is a non-member gallery, it must surely exist, as we have no interface to choose non-existant ones (it's safe enough to assume it hasn't been deleted suddenly)
if (substr($cat,0,7)!='member_') return;
// Test to see if it exists
$test=$GLOBALS['SITE_DB']->query_value_null_ok('galleries','name',array('name'=>$cat));
if (is_null($test))
{
$parts=explode('_',$cat,3);
$member=intval($parts[1]); // Almost certainly going to be same as get_member(), but we might as well be general here
if (!has_specific_permission($member,'have_personal_category','cms_galleries')) return;
// Find about parent (new gallery inherits)
$parent_id=$parts[2];
$_parent_info=$GLOBALS['SITE_DB']->query_select('galleries',array('accept_images','accept_videos','flow_mode_interface','fullname'),array('name'=>$parent_id),'',1);
if (!array_key_exists(0,$_parent_info)) fatal_exit(do_lang_tempcode('INTERNAL_ERROR'));
$parent_info=$_parent_info[0];
$username=$GLOBALS['FORUM_DRIVER']->get_username($member);
if (is_null($username)) warn_exit(do_lang_tempcode('_USER_NO_EXIST',escape_html($username)));
add_gallery($cat,do_lang('PERSONAL_GALLERY_OF',$username,get_translated_text($parent_info['fullname'])),'','','',$parent_id,$parent_info['accept_images'],$parent_info['accept_videos'],0,$parent_info['flow_mode_interface']);
$rows=$GLOBALS['SITE_DB']->query_select('group_category_access',array('group_id'),array('module_the_name'=>'galleries','category_name'=>$parent_id));
foreach ($rows as $row)
{
$GLOBALS['SITE_DB']->query_insert('group_category_access',array('module_the_name'=>'galleries','category_name'=>$cat,'group_id'=>$row['group_id']));
}
}
}
Jump to Line
Something went wrong with that request. Please try again.