From bfeccabcdbd62ac072a410ea1439373e4a5a5ac7 Mon Sep 17 00:00:00 2001 From: onli Date: Sun, 30 Apr 2017 20:38:24 +0200 Subject: [PATCH] Rework media library directory move Initial motivation for this rework was to add support for the responsive thumbnnails (#474). But it also is a re-implementation instead of an enahncement of the existing code because the moveMediaDirectory function had grown into a mess. It was very hard to debug possible renaming bugs, like https://board.s9y.org/viewtopic.php?f=3&t=21185. This approach uses several small functions instead that can be combined and re-used. --- include/admin/images.inc.php | 39 +- include/functions_images.inc.php | 564 ++++++++-------------------- templates/2k11/admin/media_pane.tpl | 3 +- 3 files changed, 176 insertions(+), 430 deletions(-) diff --git a/include/admin/images.inc.php b/include/admin/images.inc.php index b567d40e..16ff24d9 100644 --- a/include/admin/images.inc.php +++ b/include/admin/images.inc.php @@ -127,30 +127,26 @@ switch ($serendipity['GET']['adminAction']) { echo '
' . sprintf(MULTICHECK_NO_ITEM, $_SERVER['HTTP_REFERER']) . '
'."\n"; break; } - if (is_array($serendipity['POST']['multiDelete']) && isset($serendipity['POST']['oldDir']) && empty($serendipity['POST']['newDir']) && isset($_POST['toggle_move'])) { + if (is_array($serendipity['POST']['multiDelete']) && isset($serendipity['POST']['oldDir']) && (! isset($serendipity['POST']['newDir'])) && isset($_POST['toggle_move'])) { echo '
' . sprintf(MULTICHECK_NO_DIR, $_SERVER['HTTP_REFERER']) . '
'."\n"; break; } // case bulk multimove (leave the fake oldDir being send as an empty dir) - if (isset($serendipity['POST']['oldDir']) && !empty($serendipity['POST']['newDir'])) { + if (isset($serendipity['POST']['newDir'])) { $messages = array(); $multiMoveImages = $serendipity['POST']['multiDelete']; // The 'multiDelete' key name should better be renamed to 'multiCheck', but this would need to change 2k11/admin/serendipity_editor.js, images.inc.tpl, media_items.tpl, media_pane.tpl and this file unset($serendipity['POST']['multiDelete']); - $oDir = ''; // oldDir is relative to Uploads/, since we can not specify a directory of a ML bulk move directly - $nDir = serendipity_specialchars((string)$serendipity['POST']['newDir'] . '/'); // relative to Uploads/ + $nDir = serendipity_specialchars(serendipity_dirSlash('end', (string)$serendipity['POST']['newDir'])); // relative to Uploads/ - if ($oDir != $nDir) { - foreach($multiMoveImages AS $mkey => $move_id) { - $file = serendipity_fetchImageFromDatabase((int)$move_id); - $oDir = $file['path']; // this now is the exact oldDir path of this ID - if (serendipity_moveMediaDirectory($oDir, $nDir, 'file', (int)$move_id, $file)) { - $messages[] = sprintf(' ' . MEDIA_DIRECTORY_MOVED . "\n", $nDir); - } else { - $messages[] = sprintf(' ' . MEDIA_DIRECTORY_MOVE_ERROR . "\n", $nDir); - } + foreach($multiMoveImages AS $mkey => $move_id) { + if (serendipity_moveMediaDirectory('', $nDir, 'file', (int)$move_id)) { + $messages[] = sprintf(' ' . MEDIA_DIRECTORY_MOVED . "\n", $nDir); + } else { + $messages[] = sprintf(' ' . MEDIA_DIRECTORY_MOVE_ERROR . "\n", $nDir); } } + $data['messages'] = $messages; unset($messages); // remember to return to last selected media library directory @@ -182,21 +178,10 @@ switch ($serendipity['GET']['adminAction']) { case 'rename': $serendipity['GET']['fid'] = (int)$serendipity['GET']['fid']; - $file = serendipity_fetchImageFromDatabase($serendipity['GET']['fid']); - - if (LANG_CHARSET == 'UTF-8') { - // yeah, turn on content to be a real utf-8 string, which it isn't at this point! Else serendipity_makeFilename() can not work! - $serendipity['GET']['newname'] = utf8_encode($serendipity['GET']['newname']); - } - $serendipity['GET']['newname'] = str_replace(' ', '_', $serendipity['GET']['newname']); // keep serendipity_uploadSecure(URL) whitespace convert behaviour, when using serendipity_makeFilename() - $serendipity['GET']['newname'] = serendipity_uploadSecure(serendipity_makeFilename($serendipity['GET']['newname']), true); - - if (!is_array($file) || !serendipity_checkFormToken() || !serendipity_checkPermission('adminImagesDelete') || - (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid'])) { + if (!serendipity_checkFormToken() || !serendipity_checkPermission('adminImagesDelete')) { return; } - // since this is a javascript action only, all event success/error action messages have moved into js - serendipity_moveMediaDirectory(null, $serendipity['GET']['newname'], 'file', $serendipity['GET']['fid'], $file); + serendipity_renameFile($serendipity['GET']['fid'], $serendipity['GET']['newname']); break; case 'properties': @@ -492,7 +477,7 @@ switch ($serendipity['GET']['adminAction']) { if ($oldDir != $newDir) { //is this possible? Ian: YES! Change an already set directory. ob_start(); - serendipity_moveMediaDirectory($oldDir, $newDir); + serendipity_renameDir($oldDir, $newDir); $data['messages'] = ob_get_contents(); ob_end_clean(); $use_dir = $newDir; diff --git a/include/functions_images.inc.php b/include/functions_images.inc.php index 3cbf6755..47291dc5 100644 --- a/include/functions_images.inc.php +++ b/include/functions_images.inc.php @@ -2109,6 +2109,21 @@ function serendipity_escapeshellarg($string) { return escapeshellarg(str_replace('%', '', $string)); } + + +/** + * Move file with all thumbnails to given directory and update database and entries + * */ +function serendipity_moveFileTo($id, $dir) { + global $serendipity; + $file = serendipity_fetchImageFromDatabase($id); + + serendipity_renameFile($id, $file['name'], $dir); + serendipity_updateImageInDatabase(array('path' => $dir), $id); + serendipity_updateImageInEntries($id); + return true; +} + /** * Rename a media directory * @@ -2116,7 +2131,147 @@ function serendipity_escapeshellarg($string) { * @param string Old directory name * @param string New directory name */ -function serendipity_renameDir($old, $new) { +function serendipity_renameDir($oldDir, $newDir) { + global $serendipity; + # Plan: 1. Get id of all images under $oldDir (including those in subdirs) + # 2. Move $oldDir to newDir + # 3. Update image (path) in database + # 3. Update image in entries via serendipity_updateImageInEntries + $imgBase = serendipity_dirSlash('end', $serendipity['serendipityPath'] . $serendipity['uploadPath']); + + $total = null; + $images = serendipity_fetchImagesFromDatabase(0, 0, $total, false, false, $oldDir); + + if (! file_exists("${imgBase}${newDir}")) { + rename("${imgBase}${oldDir}", "${imgBase}${newDir}"); + + foreach($images as $image) { + serendipity_updateImageInDatabase( + array('path' => preg_replace('@' . preg_quote(serendipity_dirSlash('end', $oldDir)) . '@', serendipity_dirSlash('end', $newDir), $image['path'], 1)), // we use preg_replace and not str_replace to be able to limit to exacty one replacement, preventing issues when a path has loops in it + $image['id'] + ); + serendipity_updateImageInEntries($image['id']); + } + + return true; + } + return false; + +} + +/** + * Rename a file in the ML (upload folder and database). Also edit entries to use the new name, and move the thumbnails + * + * @param Id of the image to be renamed + * @param The new name (without extension) + * @path The new path to be prepended to the new name, if the file is also to be moved + * */ +function serendipity_renameFile($id, $newName, $path = null) { + global $serendipity; + $file = serendipity_fetchImageFromDatabase($id); + + if (!is_array($file) || (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid'])) { + return; + } + $oldName = $file['name']; + + if (LANG_CHARSET == 'UTF-8') { + $newName = utf8_encode($newName); + } + + if ($path === null) { + $path = $file['path']; + } + + $newName = serendipity_uploadSecure(serendipity_makeFilename($newName), true); + $imgBase = $serendipity['serendipityPath'] . $serendipity['uploadPath']; + + $newPath = "{$imgBase}{$path}{$newName}.{$file['extension']}"; + + rename("{$imgBase}{$file['path']}{$file['realname']}", $newPath); + + serendipity_renameThumbnails($id, "{$path}$newName"); + + serendipity_updateImageInDatabase(array('name' => $newName, 'realname' => basename($newPath)), $id); + serendipity_updateImageInEntries($id); +} + +/** + * Rename thumbnails linked to $id + * + * */ +function serendipity_renameThumbnails($id, $newName) { + global $serendipity; + + $file = serendipity_fetchImageFromDatabase($id); + + $thumbnails = serendipity_getThumbnails($id); + foreach($thumbnails as $thumbnail) { + $newThumbnail = str_replace("{$file['path']}{$file['name']}", $newName, $thumbnail); + rename($thumbnail, $newThumbnail); + } + return true; +} + +/** + * Get an array of existing thumbnails linked to the image with the given id + * + * */ +function serendipity_getThumbnails($id) { + global $serendipity; + + $file = serendipity_fetchImageFromDatabase($id); + $name = $file['name']; + + $imagePath = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $file['path'] . $file['realname']; + $thumbnailBase = str_replace($file['extension'], '', $imagePath); + $uploadDir = dirname($imagePath); + + return glob("$thumbnailBase*{$file['thumbnail_name']}.{$file['extension']}"); +} + +/** + * Set image references to current path in all articles linking to them via the ML + * */ +function serendipity_updateImageInEntries($id) { + global $serendipity; + + $file = serendipity_fetchImageFromDatabase($id); + $imageHTTPPath = $serendipity['defaultBaseURL'] . $serendipity['uploadHTTPPath'] . $file['path'] . $file['realname']; + $thumbnailHTTPPath = str_replace(".{$file['extension']}", "{$file['thumbnail_name']}.{$file['extension']}", $imageHTTPPath); + + + $q = "SELECT id, body, extended FROM {$serendipity['dbPrefix']}entries + WHERE + body LIKE '%%' OR extended LIKE '%%'"; + + $entries = serendipity_db_query($q, false, 'assoc'); + + if (is_array($entries) && !empty($entries)) { + foreach($entries as $entry) { + $pattern = "@(.*) src=[\"']([^'\"]+)[\"']@"; + + $callback = function($matches) use ($imageHTTPPath, $thumbnailHTTPPath) { + if (strpos(matches[2], "{$file['thumbnail_name']}.{$file['extension']}") === false) { + // the image linked not to the thumbnail + return "{$matches[1]} src='$imageHTTPPath'"; + } else { + return "{$matches[1]} src='$thumbnailHTTPPath'"; + } + }; + + $entry['body'] = preg_replace_callback($pattern, $callback, $entry['body']); + $entry['extended'] = preg_replace_callback($pattern, $callback, $entry['extended']); + + $uq = "UPDATE {$serendipity['dbPrefix']}entries + SET + body = '" . serendipity_db_escape_string($entry['body']) . "' , + extended = '" . serendipity_db_escape_string($entry['extended']) . "' + WHERE + id = " . serendipity_db_escape_string($entry['id']); + serendipity_db_query($uq); + } + } } /** @@ -3378,7 +3533,10 @@ function serendipity_checkMediaSize($file) { } /** - * Moves a media directory + * DEPRECATED. Use the functions serendipity_renameDir and serendipity_moveFile instead. This is only + * a wrapper around those, for backwards compatibility + * + * Moves a media directory * * @param string The old directory. * This can be NULL or (an empty / a) STRING for re-name/multiCheck move comparison events @@ -3391,407 +3549,11 @@ function serendipity_checkMediaSize($file) { */ function serendipity_moveMediaDirectory($oldDir, $newDir, $type = 'dir', $item_id = null, $file = null) { global $serendipity; - - // paranoid case for updating an old image id entry - else we have a new entry incrementary - if (is_null($item_id) && isset($file['id']) && $file['id'] > 0) $item_id = $file['id']; - - if (!$item_id || $item_id < 1) { - // only print message if not posting a case_directoryEdit submit - if (empty($serendipity['POST']['save'])) { - echo ' '; - printf(ERROR_FILE_NOT_EXISTS, $item_id); - echo "\n"; - return false; - } - } - - // Prepare data for the database, any hooks and the real file move, by case AREA: - // DIR = Media directory form edit, - // FILE = File rename or File bulk move, - // FILEDIR = Media properties form edit - - // images.inc case 'directoryEdit', which is ML Directories form, via ML case 'directorySelect' if ($type == 'dir') { - - $real_oldDir = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $oldDir; - $real_newDir = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $newDir; - - if (!is_dir($real_oldDir)) { - echo ' '; - printf(ERROR_FILE_NOT_EXISTS, $oldDir); - echo "\n"; - return false; - } - - if (is_dir($real_newDir)) { - echo ' '; - printf(ERROR_FILE_EXISTS, $newDir); - echo "\n"; - return false; - } - - if (!rename($real_oldDir, $real_newDir)) { - echo ' '; - printf(MEDIA_DIRECTORY_MOVE_ERROR, $newDir); - echo "\n"; - return false; - } - - echo ' '; - printf(MEDIA_DIRECTORY_MOVED, $newDir); - echo "\n"; - - $dirs = serendipity_db_query("SELECT id, path - FROM {$serendipity['dbPrefix']}images - WHERE path LIKE '" . serendipity_db_escape_string($oldDir) . "%'", false, 'assoc'); - if (is_array($dirs)) { - foreach($dirs AS $dir) { - $old = $dir['path']; - $new = preg_replace('@^(' . preg_quote($oldDir) . ')@i', $newDir, $old); - serendipity_db_query("UPDATE {$serendipity['dbPrefix']}images - SET path = '" . serendipity_db_escape_string($new) . "' - WHERE id = {$dir['id']}"); - } - } - - $dirs = serendipity_db_query("SELECT groupid, artifact_id, artifact_type, artifact_mode, artifact_index - FROM {$serendipity['dbPrefix']}access - WHERE artifact_type = 'directory' - AND artifact_index LIKE '" . serendipity_db_escape_string($oldDir) . "%'", false, 'assoc'); - if (is_array($dirs)) { - foreach($dirs AS $dir) { - $old = $dir['artifact_index']; - $new = preg_replace('@^(' . preg_quote($oldDir) . ')@i', $newDir, $old); - serendipity_db_query("UPDATE {$serendipity['dbPrefix']}access - SET artifact_index = '" . serendipity_db_escape_string($new) . "' - WHERE groupid = '" . serendipity_db_escape_string($dir['groupid']) . "' - AND artifact_id = '" . serendipity_db_escape_string($dir['artifact_id']) . "' - AND artifact_type = '" . serendipity_db_escape_string($dir['artifact_type']) . "' - AND artifact_mode = '" . serendipity_db_escape_string($dir['artifact_mode']) . "' - AND artifact_index = '" . serendipity_db_escape_string($dir['artifact_index']) . "'"); - } - } - // hook into staticpage for the renaming regex replacements - // first and last two are null - only differ by being set already by their default var for the last two - $renameValues = array(array( - 'from' => null, - 'to' => null, - 'thumb' => $serendipity['thumbSuffix'], - 'fthumb' => null, - 'oldDir' => $oldDir, - 'newDir' => $newDir, - 'type' => $type, - 'item_id' => $item_id, - 'file' => $file - )); - // Changing a ML directory via directoryEdit needs to run through entries too! - serendipity_plugin_api::hook_event('backend_media_rename', $renameValues); - - // case 'rename' OR 'multidelete' (bulk multimove) - } else if ($type == 'file') { - - // active in mean of eval or executable - if (serendipity_isActiveFile(basename($newDir))) { - echo ' '; - printf(ERROR_FILE_FORBIDDEN, serendipity_specialchars($newDir)); - echo "\n"; - return false; - } - if (!empty($file['hotlink'])) { - $newHotlinkFile = (false === strpos($newDir, $file['extension'])) ? $newDir . (empty($file['extension']) ? '' : '.' . $file['extension']) : $newDir; - serendipity_updateImageInDatabase(array('realname' => $newHotlinkFile, 'name' => $newDir), $item_id); - } else { - $parts = pathinfo($newDir); - - // build new, thumb and old file names relative to Serendipity root path - if ($oldDir === null && $newDir != 'uploadRoot') { - - // case single file re-name event (newDir = newName is passed without path!) - $newName = $newDir; // for better readability - // do we really need this? - if ($parts['extension'] != $file['extension']) { - $file_new = $file['path'] . $newName . (empty($file['extension']) ? '' : '.' . $file['extension']); - $file_old = $file['path'] . $file['name'] . (empty($file['extension']) ? '' : '.' . $file['extension']); - } else { - $file_new = $file['path'] . $newName; - $file_old = $file['path'] . $file['name']; - } - // build full thumb file names - $file_newthumb = $file['path'] . $newName . (!empty($file['thumbnail_name']) ? '.' . $file['thumbnail_name'] : '') . (empty($file['extension']) ? '' : '.' . $file['extension']); - $file_oldthumb = $file['path'] . $file['name'] . (!empty($file['thumbnail_name']) ? '.' . $file['thumbnail_name'] : '') . (empty($file['extension']) ? '' : '.' . $file['extension']); - $newThumb = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $file_newthumb; - $oldThumb = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $file_oldthumb; - - } else { - - // case bulkmove event (newDir is passed inclusive path! and normally w/o the filename, but we better check this though) - $newDir = ($newDir == 'uploadRoot') ? '' : $newDir; // Take care: remove temporary 'uploadRoot' string, in case of moving a subdir file into upload root by bulkmove - $_newDir = str_replace($file['name'] . (empty($file['extension']) ? '' : '.' . $file['extension']), '', $newDir); - // do we really need this? - if ($parts['extension'] != $file['extension']) { - $file_new = $_newDir . $file['name'] . (empty($file['extension']) ? '' : '.' . $file['extension']); - $file_old = $file['path'] . $file['name'] . (empty($file['extension']) ? '' : '.' . $file['extension']); - } else { - $file_new = $_newDir . $file['name']; - $file_old = $file['path'] . $file['name']; - } - - } - - // build full origin and new file path names - $newfile = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $file_new; - $oldfile = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $file_old; - - // check files existence - if (file_exists($oldfile) && !file_exists($newfile)) { - - // for the paranoid, securely check these build filenames again, since we really need a real file set to continue! - $newparts = pathinfo($newfile); - if ($newparts['dirname'] == '.' || (!empty($file['extension']) && empty($newparts['extension'])) || empty($newparts['filename'])) { - // error new file build mismatch - echo ' ' . $newfile . ' ' . ERROR_SOMETHING . "\n"; - return false; - } - - // Case re-name event, keeping a possible moved directory name for a single file - if ($oldDir === null) { - // Move the origin file - @rename($oldfile, $newfile); - // do not re-name again, if item has no thumb name (eg zip object file case) and old thumb actually exists (possible missing pdf preview image on WinOS with IM) - if (($newThumb != $newfile) && file_exists($oldThumb)) { - // the thumb file - @rename($oldThumb, $newThumb); // Keep both rename() error disabled, since we have to avoid any output in renaiming cases - } - - // hook into staticpage for the renaming regex replacements - $renameValues = array(array( - 'from' => $oldfile, - 'to' => $newfile, - 'thumb' => $serendipity['thumbSuffix'], - 'fthumb' => $file['thumbnail_name'], - 'oldDir' => $oldDir, - 'newDir' => $newDir, - 'type' => $type, - 'item_id' => $item_id, - 'file' => $file - )); - serendipity_plugin_api::hook_event('backend_media_rename', $renameValues); - - // renaming filenames has to update mediaproperties if set - $q = "UPDATE {$serendipity['dbPrefix']}mediaproperties - SET value = '" . serendipity_db_escape_string($newName . (empty($file['extension']) ? '' : '.' . $file['extension'])) . "' - WHERE mediaid = " . (int)$item_id . ' AND property = "realname" AND value = "' . $file['realname'] . '"'; - serendipity_db_query($q); - $q = "UPDATE {$serendipity['dbPrefix']}mediaproperties - SET value = '" . serendipity_db_escape_string($newName) . "' - WHERE mediaid = " . (int)$item_id . ' AND property = "name" AND value = "' . $file['name'] .'"'; - serendipity_db_query($q); - $q = "UPDATE {$serendipity['dbPrefix']}mediaproperties - SET value = '" . serendipity_db_escape_string($newName . (empty($file['extension']) ? '' : '.' . $file['extension'])) . "' - WHERE mediaid = " . (int)$item_id . ' AND property = "TITLE" AND value = "' . $file['realname'] .'"'; - serendipity_db_query($q); - - serendipity_updateImageInDatabase(array('thumbnail_name' => $renameValues[0]['thumb'], 'realname' => $newName . (empty($file['extension']) ? '' : '.' . $file['extension']), 'name' => $newName), $item_id); - - // Forward user to overview (we don't want the user's back button to rename things again) ?? What does this do? Check!!! - } - - // Case Move or Bulkmove event - // newDir can now be used for the uploads directory root path too - // Do not allow an empty string or not set newDir for the build call so we do not conflict with rename calls, which are single files only and is done above - // BULKMOVE vars oldfile and newfile are fullpath based see above - elseif (!empty($newfile)) { - - if ($newDir == 'uploadRoot') $newDir = ''; // now move back into root of /uploads dir - - // hook into staticpage for the renaming regex replacements - $renameValues = array(array( - 'from' => $oldfile, - 'to' => $newfile, - 'thumb' => $serendipity['thumbSuffix'], - 'fthumb' => $file['thumbnail_name'], - 'oldDir' => $oldDir, - 'newDir' => $newDir, - 'type' => $type, - 'item_id' => $item_id, - 'file' => $file - )); - serendipity_plugin_api::hook_event('backend_media_rename', $renameValues); // eg. for staticpage entries path regex replacements - - // Move the origin file - try { rename($oldfile, $newfile); } catch (Exception $e) { echo ' ' . ERROR_SOMETHING . ': '.$e->getMessage() . "\n"; } - - // do still need this? YES, it is definitely false, so we would not need the ternary - // Rename newDir + file name in case it is called by the Bulk Move and not by rename - $newDirFile = (false === strpos($newDir, $file['name'])) ? $newDir . $file['name'] : $newDir; - - foreach($renameValues AS $renameData) { - // build full thumb file names - $thisOldThumb = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $renameData['oldDir'] . $file['name'] . (!empty($renameData['fthumb']) ? '.' . $renameData['fthumb'] : '.' . $serendipity['thumbSuffix']) . (empty($file['extension']) ? '' : '.' . $file['extension']); - $thisNewThumb = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $newDirFile . (!empty($file['thumbnail_name']) ? '.' . $renameData['thumb'] : '.' . $serendipity['thumbSuffix']) . (empty($file['extension']) ? '' : '.' . $file['extension']); - // Check for existent old thumb files first, to not need to disable rename by @rename(), then move the thumb file and catch any wrong renaming - if (($thisNewThumb != $newfile) && file_exists($thisOldThumb)) { - // the thumb file and catch any wrong renaming - try { rename($thisOldThumb, $thisNewThumb); } catch (Exception $e) { echo ' ' . ERROR_SOMETHING . ': '.$e->getMessage() . "\n"; } - } - } - - serendipity_updateImageInDatabase(array('thumbnail_name' => $renameValues[0]['thumb'], 'path' => $newDir, 'realname' => $file['realname'], 'name' => $file['name']), $item_id); - // Forward user to overview (we don't want the user's back button to rename things again) - } else { - //void - } - } else { - if (!file_exists($oldfile)) { - echo ' ' . ERROR_FILE_NOT_EXISTS . "\n"; - } elseif (file_exists($newfile)) { - echo ' ' . ERROR_FILE_EXISTS . "\n"; - } else { - echo ' ' . ERROR_SOMETHING . "\n"; - } - - return false; - } - } - - // used solely by serendipity_parsePropertyForm base_properties when changing the file selected path within mediaproperties form - } elseif ($type == 'filedir') { - - serendipity_db_query("UPDATE {$serendipity['dbPrefix']}images - SET path = '" . serendipity_db_escape_string($newDir) . "' - WHERE id = " . (int)$item_id); - $pick = serendipity_db_query("SELECT * FROM {$serendipity['dbPrefix']}images - WHERE id = " . (int)$item_id, true, 'assoc'); - - // Move thumbs - Rebuild full origin and new file path names by the new picked file array - $oldfile = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $oldDir . $pick['name'] . (empty($pick['extension']) ? '' : '.' . $pick['extension']); - $newfile = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $newDir . $pick['name'] . (empty($pick['extension']) ? '' : '.' . $pick['extension']); - - // hook into staticpage for the renaming regex replacements - $renameValues = array(array( - 'from' => $oldfile, - 'to' => $newfile, - 'thumb' => $serendipity['thumbSuffix'], - 'fthumb' => $pick['thumbnail_name'], - 'oldDir' => $oldDir, - 'newDir' => $newDir, - 'type' => $type, - 'item_id' => $item_id, - 'file' => $pick, - 'name' => $pick['name'] - )); - serendipity_plugin_api::hook_event('backend_media_rename', $renameValues); - - // Move the origin file - try { rename($oldfile, $newfile); } catch (Exception $e) { echo ' ' . ERROR_SOMETHING . ': '.$e->getMessage() . "\n"; } - - foreach($renameValues AS $renameData) { - $thisOldThumb = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $oldDir . $pick['name'] . (!empty($renameData['fthumb']) ? '.' . $renameData['fthumb'] : '') . (empty($pick['extension']) ? '' : '.' . $pick['extension']); - $thisNewThumb = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $newDir . $pick['name'] . (!empty($pick['thumbnail_name']) ? '.' . $pick['thumbnail_name'] : '') . (empty($pick['extension']) ? '' : '.' . $pick['extension']); - // Check for existent old thumb files first, to not need to disable rename by @rename(),then move the thumb file and catch any wrong renaming - if (($thisNewThumb != $newfile) && file_exists($thisOldThumb)) { - // the thumb file and catch any wrong renaming - try { rename($thisOldThumb, $thisNewThumb); } catch (Exception $e) { echo ' ' . ERROR_SOMETHING . ': '.$e->getMessage() . "\n"; } - } - } - // no need to use serendipity_updateImageInDatabase() here since already done in this case start - // ???? Forward user to overview (we don't want the user's back button to rename things again) - - // prepare for message - $thisnew = (empty($newDir) ? $serendipity['uploadPath'] : '') . $newDir . $pick['name']; - $thisExt = isset($pick['extension']) ? '.'.$pick['extension'] : ''; - - if (file_exists($newfile)) { - echo ' '; - printf(MEDIA_DIRECTORY_MOVED, $thisnew . $thisExt); - echo "\n"; - } - - } // case dir, file, filedir end - - // Entry REPLACEMENT AREA - - // Only MySQL supported, since I don't know how to use REGEXPs differently. // Ian: we should improve this to all! - if ($serendipity['dbType'] != 'mysql' && $serendipity['dbType'] != 'mysqli') { - echo ' ' . MEDIA_DIRECTORY_MOVE_ENTRY . "\n"; - return true; + serendipity_renameDir($oldDir, $newDir); + } else { + return serendipity_moveFileTo($item_id, $newDir); } - - // Prepare the SELECT query for filetypes - if ($type == 'filedir' || $type == 'file') { - - // get the right $file, which is array or null, by type - $_file = ($type == 'filedir') ? $pick : $file; - // check oldDir in bulkmove case - $oldDir = ($type == 'file' && !is_null($oldDir)) ? str_replace($_file['name'].'.'.$_file['extension'], '', $oldDir) : $oldDir; - - // Path patterns to SELECT en detail to not pick path parts in a loop - if ($oldDir === null) {// care for file renaming with oldpath - $oldDirFile = $_file['path'] . $_file['name'] . (($_file['extension']) ? '.'.$_file['extension'] : ''); - $oldDirThumb = $_file['path'] . $_file['name'] . '.' . $_file['thumbnail_name'] . (($_file['extension']) ? '.'.$_file['extension'] : ''); - } else { - $oldDirFile = $oldDir . $_file['name'] . (($_file['extension']) ? '.'.$_file['extension'] : ''); - $oldDirThumb = $oldDir . $_file['name'] . '.' . $_file['thumbnail_name'] . (($_file['extension']) ? '.'.$_file['extension'] : ''); - } - if ($type == 'filedir' && !isset($newDirFile)) { - $newDirFile = (strpos($newDir, $_file['name']) === FALSE) ? $newDir . $_file['name'] : $newDir; - } - if ($type == 'file' && $oldDir === null) { - $newDirFile = (empty($newDirFile)) ? $newDir : $newDirFile; // for file renamings $newDirFile has to be $newDir ( which is subdir and new NAME w/o ext) - } - $ispOldFile = $serendipity['serendipityPath'] . $serendipity['uploadHTTPPath'] . $oldDirFile; - - } elseif($type == 'dir') { - // since this is case 'dir', we do not have a filename and have to rename replacement File vars to oldDir and newDir values for the update preg_replace match - $oldDirFile = $oldDir; - $newDirFile = $newDir; - $ispOldFile = $serendipity['serendipityPath'] . $serendipity['uploadHTTPPath'] . $oldDirFile . (($_file['extension']) ? '.'.$_file['extension'] : ''); - } - - // Please note: imageselectorplus plugin quickblog is either quickblog:FullPath or quickblog:|?(none|plugin|js|_blank)|FullPath - // SELECTing the entries uses a more detailled approach to be as precise as possible, thus we need to reset these vars for the preg_replace later on in some cases - $q = "SELECT id, body, extended - FROM {$serendipity['dbPrefix']}entries - WHERE body REGEXP '(src=|href=|window.open.|