requireAdminLogin()
->setPageTitle(WT_I18N::translate('Media'));
require_once WT_ROOT.'includes/functions/functions_print_lists.php';
require_once WT_ROOT.'includes/functions/functions_print_facts.php';
require_once WT_ROOT.'includes/functions/functions_edit.php';
require_once WT_ROOT.'includes/functions/functions_import.php';
require_once WT_ROOT.'includes/functions/functions_mediadb.php';
// editing must be enabled
if (!$ALLOW_EDIT_GEDCOM) {
$controller->pageHeader();
echo "";
echo WT_I18N::translate('Media management features are not available when online editing is disabled.');
echo " ";
exit;
}
/**
* This functions checks if an existing directory is physically writeable
* The standard PHP function only checks for the R/O attribute and doesn't
* detect authorisation by ACL.
*/
function dir_is_writable($dir) {
$err_write = false;
$handle = @fopen(filename_decode($dir."x.y"), "w+");
if ($handle) {
$i = fclose($handle);
$err_write = true;
@unlink(filename_decode($dir."x.y"));
}
return($err_write);
}
/**
* Moves a file from one location to another, creating destination directory if needed
* used by the routines that move files between the standard media directory and the protected media directory
*/
function move_file($src, $dest) {
global $MEDIA_FIREWALL_ROOTDIR, $MEDIA_DIRECTORY;
// sometimes thumbnail files are set to something like "images/media.gif", this ensures we do not move them
// check to make sure the src file is in the standard or protected media directories
if (strpos($src, $MEDIA_FIREWALL_ROOTDIR.$MEDIA_DIRECTORY)!==0 && strpos($src, $MEDIA_DIRECTORY)!==0) {
return false;
}
// check to make sure the dest file is in the standard or protected media directories
if (strpos($dest, $MEDIA_FIREWALL_ROOTDIR.$MEDIA_DIRECTORY)!==0 && strpos($dest, $MEDIA_DIRECTORY)!==0) {
return false;
}
$destdir = dirname($dest);
if (!is_dir($destdir)) {
@mkdirs($destdir);
if (!is_dir($destdir)) {
echo '
', WT_I18N::translate('Directory could not be created'), ' (', $destdir, ')
';
return true;
}
/**
* Recursively moves files from standard media directory to the protected media directory
* and vice-versa. Operates directly on the filesystem, does not use the db.
*/
function move_files($path, $protect) {
global $MEDIA_FIREWALL_THUMBS, $starttime, $operation_count;
$timelimit=get_site_setting('MAX_EXECUTION_TIME');
if ($dir=@opendir($path)) {
while (($element=readdir($dir))!== false) {
$exectime = time() - $starttime;
if (($timelimit != 0) && ($timelimit - $exectime) < 3) {
// bail now to ensure nothing is lost
echo "
".WT_I18N::translate('The execution time limit was reached. Try the command again to move the rest of the files.')."
";
return;
}
// do not move certain files...
if ($element!= "." && $element!= ".." && $element!=".svn" && $element!="watermark" && $element!="thumbs" && $element!=".htaccess" && $element!="index.php" && $element!="MediaInfo.txt" && $element!="ThumbsInfo.txt") {
$filename = $path."/".$element;
if (is_dir($filename)) {
// call this function recursively on this directory
move_files($filename, $protect);
} else {
$operation_count++;
if ($operation_count % 10) {
// flush the buffer so the user can tell something is happening
flush();
}
if ($protect) {
// Move single file and optionally its corresponding thumbnail to protected dir
if (file_exists($filename)) {
move_file($filename, get_media_firewall_path($filename));
}
if ($MEDIA_FIREWALL_THUMBS) {
$thumbnail = thumbnail_file($filename, false);
if (file_exists($thumbnail)) {
move_file($thumbnail, get_media_firewall_path($thumbnail));
}
}
} else {
// Move single file and its corresponding thumbnail to standard dir
$filename = get_media_standard_path($filename);
if (file_exists(get_media_firewall_path($filename))) {
move_file(get_media_firewall_path($filename), $filename);
}
$thumbnail = thumbnail_file($filename, false);
if (file_exists(get_media_firewall_path($thumbnail))) {
move_file(get_media_firewall_path($thumbnail), $thumbnail);
}
}
}
}
}
echo "";
$action="filter";
closedir($dir);
}
return;
}
/**
* Recursively sets the permissions on files
* Operates directly on the filesystem, does not use the db.
*/
function set_perms($path) {
global $MEDIA_FIREWALL_ROOTDIR, $MEDIA_DIRECTORY, $starttime, $operation_count;
if (strpos($path."/", $MEDIA_FIREWALL_ROOTDIR.$MEDIA_DIRECTORY)!==0 && strpos($path."/", $MEDIA_DIRECTORY)!==0) {
return false;
}
$timelimit=get_site_setting('MAX_EXECUTION_TIME');
if ($dir=@opendir($path)) {
while (($element=readdir($dir))!== false) {
$exectime = time() - $starttime;
if (($timelimit != 0) && ($timelimit - $exectime) < 3) {
// bail now to ensure nothing is lost
echo "
".WT_I18N::translate('The execution time limit was reached. Try the command again on a smaller directory.')."
";
return;
}
// do not set perms on certain files...
if ($element!= '.' && $element!= '..' && $element!='.svn') {
$fullpath = $path.'/'.$element;
if (is_dir($fullpath)) {
if (@chmod($fullpath, WT_PERM_EXE)) {
echo '
".WT_I18N::translate('Thumbnail directory not removed.')."
";
AddToLog($thumbdir." -- ".WT_I18N::translate('Thumbnail directory not removed.'), 'media');
} else if (!$resthumb_fw) {
echo "
".WT_I18N::translate('Thumbnail directory not removed.')."
";
AddToLog($thumbdir_fw." -- ".WT_I18N::translate('Thumbnail directory not removed.'), 'media');
} else {
echo WT_I18N::translate('Thumbnail directory successfully removed.');
AddToLog($thumbdir." -- ".WT_I18N::translate('Thumbnail directory successfully removed.'), 'media');
}
}
}
// Back up to this directory's parent
$i = strrpos(substr($directory, 0, -1), '/');
$directory = trim(substr($directory, 0, $i), '/').'/';
$action="filter";
echo "
";
}
/**
* This action generates a thumbnail for the file
*
* @name $action->thumbnail
*/
if ($action == "thumbnail") {
echo "
";
echo "
";
// TODO: add option to generate thumbnails for all images on page
// Cycle through $medialist and skip all exisiting thumbs
// Check if $all is true, if so generate thumbnails for all files that do
// not yet have any thumbnails created. Otherwise only the file specified.
if ($all == 'yes') {
$medialist = get_medialist(true, $directory);
foreach ($medialist as $key => $media) {
if (!($MEDIA_EXTERNAL && isFileExternal($filename))) {
$thumbnail = str_replace("$MEDIA_DIRECTORY", $MEDIA_DIRECTORY."thumbs/", check_media_depth($media["FILE"], "NOTRUNC"));
if (!media_exists($thumbnail)) {
// can't use thumbnail_file or $media["THUMB"] or $media["THUMBEXISTS"] because it they reference the icon from WT_IMAGES
if (generate_thumbnail($media["FILE"], $thumbnail)) {
echo WT_I18N::translate('Thumbnail %s generated automatically.', $thumbnail);
AddToLog("Thumbnail {$thumbnail} generated automatically.", 'edit');
} else {
echo "";
echo WT_I18N::translate('Thumbnail %s could not be generated automatically.', $thumbnail);
echo "";
AddToLog("Thumbnail {$thumbnail} could not be generated automatically.", 'edit');
}
echo " ";
}
}
}
}
else if ($all != 'yes') {
if (!($MEDIA_EXTERNAL && isFileExternal($filename))) {
$thumbnail = str_replace("$MEDIA_DIRECTORY", $MEDIA_DIRECTORY."thumbs/", check_media_depth($filename, "NOTRUNC"));
if (generate_thumbnail($filename, $thumbnail)) {
echo WT_I18N::translate('Thumbnail %s generated automatically.', $thumbnail);
AddToLog("Thumbnail {$thumbnail} generated automatically.", 'edit');
}
else {
echo "";
echo WT_I18N::translate('Thumbnail %s could not be generated automatically.', $thumbnail);
echo "";
AddToLog("Thumbnail {$thumbnail} could not be generated automatically.", 'edit');
}
}
}
$action = "filter";
echo "
";
}
// Move single file and optionally its corresponding thumbnail to protected dir
if ($action == "moveprotected") {
echo "
";
echo "
";
if (strpos($filename, "../") !== false) {
// don't allow user to access directories outside of media dir
echo "
".WT_I18N::translate('Blank name or illegal characters in name')."
";
} else {
if (file_exists($filename)) {
move_file($filename, get_media_firewall_path($filename));
}
if ($MEDIA_FIREWALL_THUMBS) {
$thumbnail = thumbnail_file($filename, false);
if (file_exists($thumbnail)) {
move_file($thumbnail, get_media_firewall_path($thumbnail));
}
}
}
echo "
";
$action="filter";
}
// Move single file and its corresponding thumbnail to standard dir
if ($action == "movestandard") {
echo "
";
echo "
";
if (strpos($filename, "../") !== false) {
// don't allow user to access directories outside of media dir
echo "
".WT_I18N::translate('Blank name or illegal characters in name')."
";
$action="filter";
}
// Upload media items
if ($action == "upload") {
process_uploadMedia_form();
$medialist = get_medialist();
$action = "filter";
}
$allowDelete = true;
$removeObject = true;
// Remove object: same as Delete file, except file isn't deleted
if ($action == "removeobject") {
$action = "deletefile";
$allowDelete = false;
$removeObject = true;
}
// Remove link: same as Delete file, except file isn't deleted
if ($action == "removelinks") {
$action = "deletefile";
$allowDelete = false;
$removeObject = false;
}
// Delete file
if ($action == "deletefile") {
echo "
";
echo "
";
$xrefs = array($xref);
$onegedcom = true;
//-- get all of the XREFS associated with this record
//-- and check if the file is used in multiple gedcoms
$myFile = str_replace($MEDIA_DIRECTORY, "", $filename);
//-- figure out how many levels are in this file
$mlevels = preg_split("~[/\\\]~", $filename);
$statement=WT_DB::prepare("SELECT * FROM `##media` WHERE m_file LIKE ?")->execute(array("%{$myFile}"));
while ($row=$statement->fetch(PDO::FETCH_ASSOC)) {
$rlevels = preg_split("~[/\\\]~", $row["m_file"]);
//-- make sure we only delete a file at the same level of directories
//-- see 1825257
$match = true;
$k=0;
$i=count($rlevels)-1;
$j=count($mlevels)-1;
while ($i>=0 && $j>=0) {
if ($rlevels[$i] != $mlevels[$j]) {
$match = false;
break;
}
$j--;
$i--;
$k++;
if ($k>$MEDIA_DIRECTORY_LEVELS) break;
}
if ($match) {
if ($row["m_gedfile"]!=WT_GED_ID) $onegedcom = false;
else $xrefs[] = $row["m_media"];
}
}
$statement->closeCursor();
$xrefs = array_unique($xrefs);
$finalResult = true;
if ($allowDelete) {
if (!$onegedcom) {
echo "".WT_I18N::translate('This file is linked to another genealogical database on this server. It cannot be deleted, moved, or renamed until these links have been removed.')."
".WT_I18N::translate('Media file could not be deleted.')." ";
$finalResult = false;
}
if (isFileExternal($filename)) {
echo "".WT_I18N::translate('This media object does not exist as a file on this server. It cannot be deleted, moved, or renamed.')."
".WT_I18N::translate('Media file could not be deleted.')." ";
$finalResult = false;
}
if ($finalResult) {
// Check if file exists. If so, delete it
$server_filename = get_server_filename($filename);
if (file_exists($server_filename) && $allowDelete) {
if (@unlink($server_filename)) {
echo WT_I18N::translate('Media file successfully deleted.')." ";
AddToLog($server_filename." -- ".WT_I18N::translate('Media file successfully deleted.'), 'edit');
} else {
$finalResult = false;
echo "".WT_I18N::translate('Media file could not be deleted.')." ";
AddToLog($server_filename." -- ".WT_I18N::translate('Media file could not be deleted.'), 'edit');
}
}
// Check if thumbnail exists. If so, delete it.
$thumbnail = str_replace("$MEDIA_DIRECTORY", $MEDIA_DIRECTORY."thumbs/", $filename);
$server_thumbnail = get_server_filename($thumbnail);
if (file_exists($server_thumbnail) && $allowDelete) {
if (@unlink($server_thumbnail)) {
echo WT_I18N::translate('Thumbnail file successfully deleted.')." ";
AddToLog($server_thumbnail." -- ".WT_I18N::translate('Thumbnail file successfully deleted.'), 'edit');
} else {
$finalResult = false;
echo "".WT_I18N::translate('Thumbnail file could not be deleted.')." ";
AddToLog($server_thumbnail." -- ".WT_I18N::translate('Thumbnail file could not be deleted.'), 'edit');
}
}
}
}
//-- loop through all of the found xrefs and delete any references to them
foreach ($xrefs as $ind=>$xref) {
// Remove references to media file from gedcom and database
// Check for XREF
if ($xref != "") {
$links = get_media_relations($xref);
foreach ($links as $pid=>$type) {
$gedrec = find_gedcom_record($pid, WT_GED_ID, true);
$gedrec = remove_subrecord($gedrec, "OBJE", $xref, -1);
replace_gedrec($pid, WT_GED_ID, $gedrec);
echo WT_I18N::translate('Record %s successfully updated.', $pid), ' ';
}
// Remove media object from gedcom
if (find_gedcom_record($xref, WT_GED_ID)) {
delete_gedrec($xref, WT_GED_ID);
echo WT_I18N::translate('Record %s successfully removed from GEDCOM.', $xref), ' ';
} else {
echo "".WT_I18N::translate('This media object does not exist as a file on this server. It cannot be deleted, moved, or renamed.')." ";
$finalResult = false;
}
/* I've commented this out, as I have no idea what it is supposed to do. We've just deleted a
* file, so why are we creating a new media object for it???
// Record changes to the Media object
accept_all_changes($xref, WT_GED_ID);
$objerec = find_gedcom_record($xref, WT_GED_ID);
// Add the same file as a new object
if ($finalResult && !$removeObject && $objerec!="") {
$xref = get_new_xref("OBJE");
$objerec = preg_replace("/0 @.*@ OBJE/", "0 @".$xref."@ OBJE", $objerec);
if (append_gedrec($objerec, WT_GED_ID)) {
echo WT_I18N::translate('Record %s successfully added to GEDCOM.', $xref);
} else {
$finalResult = false;
echo "";
echo WT_I18N::translate('Record %s could not be added to GEDCOM.', $xref);
echo "";
}
echo " ";
}
*/
}
}
if ($finalResult) echo WT_I18N::translate('Update successful');
$action = "filter";
echo "
";
}
/**
* Generate link flyout menu
*
* @param string $mediaid
*/
function print_link_menu($mediaid) {
global $TEXT_DIRECTION;
$classSuffix = "";
if ($TEXT_DIRECTION=="rtl") $classSuffix = "_rtl";
// main link displayed on page
$menu = new WT_Menu();
// GEDFact assistant Add Media Links =======================
if (array_key_exists('GEDFact_assistant', WT_Module::getActiveModules())) {
$menu->addLabel(WT_I18N::translate('Manage links'));
$menu->addOnclick("return ilinkitem('$mediaid', 'manage')");
$menu->addFlyout("left");
// Do not echo submunu
} else {
$menu->addLabel(WT_I18N::translate('Set link'));
$menu->addClass('', 'submenu');
$submenu = new WT_Menu(WT_I18N::translate('To Person'));
$submenu->addClass("submenuitem".$classSuffix);
$submenu->addOnClick("return ilinkitem('$mediaid', 'person')");
$menu->addSubMenu($submenu);
$submenu = new WT_Menu(WT_I18N::translate('To Family'));
$submenu->addClass("submenuitem".$classSuffix);
$submenu->addOnClick("return ilinkitem('$mediaid', 'family')");
$menu->addSubMenu($submenu);
$submenu = new WT_Menu(WT_I18N::translate('To Source'));
$submenu->addClass("submenuitem".$classSuffix);
$submenu->addOnClick("return ilinkitem('$mediaid', 'source')");
$menu->addSubMenu($submenu);
}
echo $menu->getMenu();
}
$savedOutput = ob_get_clean();
// "Help for this page" link
echo '
', help_link('manage_media'), '
';
?>
';
// Tell the user where he is
echo '
';
echo '
';
echo WT_I18N::translate('Current directory');
echo ': ';
// if ($USE_MEDIA_FIREWALL) { echo $MEDIA_FIREWALL_ROOTDIR; }
echo ''.substr($directory, 0, -1).'';
echo ' ';
// Calculation to determine whether files are protected or not -------------------------
// Check if media directory and thumbs directory are empty
$clean = false;
$files = array();
$thumbfiles = array();
$files_fw = array();
$thumbfiles_fw = array();
$resdir = false;
$resthumb = false;
// Media directory check
if (@is_dir(filename_decode($directory))) {
$handle = opendir(filename_decode($directory));
$files = array();
while (false !== ($file = readdir($handle))) {
if (!in_array($file, $BADMEDIA)) $files[] = $file;
}
closedir($handle);
}
// Thumbs directory check
if (@is_dir(filename_decode($thumbdir))) {
$handle = opendir(filename_decode($thumbdir));
$thumbfiles = array();
while (false !== ($file = readdir($handle))) {
if (!in_array($file, $BADMEDIA)) $thumbfiles[] = $file;
}
closedir($handle);
}
// Media Firewall Media directory check
if (@is_dir(filename_decode($directory_fw))) {
$handle = opendir(filename_decode($directory_fw));
$files_fw = array();
while (false !== ($file = readdir($handle))) {
if (!in_array($file, $BADMEDIA)) $files_fw[] = $file;
}
closedir($handle);
}
// Media Firewall Thumbs directory check
if (@is_dir(filename_decode($thumbdir_fw))) {
$handle = opendir(filename_decode($thumbdir_fw));
$thumbfiles_fw = array();
while (false !== ($file = readdir($handle))) {
if (!in_array($file, $BADMEDIA)) $thumbfiles_fw[] = $file;
}
closedir($handle);
}
$protected_files = count($files_fw);
$standard_files = count($files);
// echo " ";
echo "";
echo "
";
echo "
\n";
flush();
if ($subclick == "none") {
echo "\n";
} else {
// Get the list of media items
/**
* This is the default action for the page
*
* Displays a list of dirs and files. Displaying only
* thumbnails as the images may be large and we do not want large delays
* while administering the file structure
*
* @name $action->filter
*/
// only check for externalLinks when dealing with the root folder
$showExternal = ($directory == $MEDIA_DIRECTORY) ? true : false;
$medialist=get_medialist(true, $directory, false, false, $showExternal);
// Show link to previous folder
$levels = explode('/', $directory);
$pdir = '';
for ($i=0; $i';
$uplink .= $pdir;
$uplink .= "";
$uplink2 = "";
}
// display the directory list
if (count($dirs) || $pdir != '') {
sort($dirs);
if ($pdir != '') {
echo "
";
echo "
";
echo $uplink2;
echo "
";
echo "
";
echo $uplink;
echo "
";
echo "
";
}
foreach ($dirs as $indexval => $dir) {
if ($dir{0}!='.') {
echo '
';
echo '
';
// directory options
echo '
';
if ($USE_MEDIA_FIREWALL && $is_std_media_writable) {
echo '
';
}
}
}
echo '';
echo ' ';
// display the images
if (count($medialist) && ($subclick=='search' || $subclick=='all')) {
if (WT_USE_LIGHTBOX) {
// Get Lightbox config variables
// Following two lines are temporarily removed as they cause problems. BH 07/01/2011
//$album = new lightbox_WT_Module();
//$album->getPreLoadContent();
}
// Sort the media list according to the user's wishes
$sortedMediaList = $medialist; // Default sort (by title) has already been done
if ($sortby=='file') uasort($sortedMediaList, 'filesort');
// Set up for two passes, the first showing URLs, the second normal files
$controller
->addExternalJavascript(WT_STATIC_URL.'js/jquery/jquery.dataTables.min.js')
->addInlineJavascript('
jQuery("#media_table").dataTable( {
"sDom": \'<"H"pf<"dt-clear">irl>t<"F"pl>\',
'.WT_I18N::datatablesI18N().',
"bJQueryUI": true,
"bAutoWidth":false,
"aaSorting": [[ 1, "asc" ]],
"iDisplayLength": 10,
"sPaginationType": "full_numbers",
"aoColumnDefs": [
{ "bSortable": false, "aTargets": [ 0,1 ] }
]
});
');
?>