$wgTrivialMimeDetection = true; //don't use fancy mime detection, just check the file extension for jpg/gif/png. require_once 'Image.php'; require_once 'StreamFile.php'; // Get input parameters $fileName = isset($_REQUEST['f']) ? $_REQUEST['f'] : ''; $width = isset($_REQUEST['w']) ? intval($_REQUEST['w']) : 0; $page = isset($_REQUEST['p']) ? intval($_REQUEST['p']) : null; if (get_magic_quotes_gpc()) { $fileName = stripslashes($fileName); } $pre_render = isset($_REQUEST['r']) && $_REQUEST['r'] != "0"; // Some basic input validation $fileName = strtr($fileName, '\\/', '__'); // Work out paths, carefully avoiding constructing an Image object because that won't work yet $imagePath = wfImageDir($fileName) . '/' . $fileName; $thumbName = "{$width}px-{$fileName}"; if (!is_null($page)) { $thumbName = 'page' . $page . '-' . $thumbName; } if ($pre_render) { $thumbName .= '.png'; } $thumbPath = wfImageThumbDir($fileName) . '/' . $thumbName; if (is_file($thumbPath) && filemtime($thumbPath) >= filemtime($imagePath)) { wfStreamFile($thumbPath); // Can't log profiling data with no Setup.php exit; } // OK, no valid thumbnail, time to get out the heavy machinery wfProfileOut('thumb.php-start');
/** * Move the uploaded file from its temporary location to the final * destination. If a previous version of the file exists, move * it into the archive subdirectory. * * @todo If the later save fails, we may have disappeared the original file. * * @param string $saveName * @param string $tempName full path to the temporary file * @param bool $useRename if true, doesn't check that the source file * is a PHP-managed upload temporary */ function saveUploadedFile($saveName, $tempName, $useRename = false) { global $wgOut; $fname = "SpecialUpload::saveUploadedFile"; $dest = wfImageDir($saveName); $archive = wfImageArchiveDir($saveName); if (!is_dir($dest)) { wfMkdirParents($dest); } if (!is_dir($archive)) { wfMkdirParents($archive); } $this->mSavedFile = "{$dest}/{$saveName}"; if (is_file($this->mSavedFile)) { $this->mUploadOldVersion = gmdate('YmdHis') . "!{$saveName}"; wfSuppressWarnings(); $success = rename($this->mSavedFile, "{$archive}/{$this->mUploadOldVersion}"); wfRestoreWarnings(); if (!$success) { $wgOut->showFileRenameError($this->mSavedFile, "{$archive}/{$this->mUploadOldVersion}"); return false; } else { wfDebug("{$fname}: moved file " . $this->mSavedFile . " to {$archive}/{$this->mUploadOldVersion}\n"); } } else { $this->mUploadOldVersion = ''; } wfSuppressWarnings(); $success = $useRename ? rename($tempName, $this->mSavedFile) : move_uploaded_file($tempName, $this->mSavedFile); wfRestoreWarnings(); if (!$success) { $wgOut->showFileCopyError($tempName, $this->mSavedFile); return false; } else { wfDebug("{$fname}: wrote tempfile {$tempName} to " . $this->mSavedFile . "\n"); } chmod($this->mSavedFile, 0644); return true; }
/** * Restore all or specified deleted revisions to the given file. * Permissions and logging are left to the caller. * * May throw database exceptions on error. * * @param $versions set of record ids of deleted items to restore, * or empty to restore all revisions. * @return the number of file revisions restored if successful, * or false on failure */ function restore($versions = array(), $Unsuppress = false) { global $wgUser; if (!FileStore::lock()) { wfDebug(__METHOD__ . " could not acquire filestore lock\n"); return false; } $transaction = new FSTransaction(); try { $dbw = wfGetDB(DB_MASTER); $dbw->begin(); // Re-confirm whether this image presently exists; // if no we'll need to create an image record for the // first item we restore. $exists = $dbw->selectField('image', '1', array('img_name' => $this->name), __METHOD__); // Fetch all or selected archived revisions for the file, // sorted from the most recent to the oldest. $conditions = array('fa_name' => $this->name); if ($versions) { $conditions['fa_id'] = $versions; } $result = $dbw->select('filearchive', '*', $conditions, __METHOD__, array('ORDER BY' => 'fa_timestamp DESC')); if ($dbw->numRows($result) < count($versions)) { // There's some kind of conflict or confusion; // we can't restore everything we were asked to. wfDebug(__METHOD__ . ": couldn't find requested items\n"); $dbw->rollback(); FileStore::unlock(); return false; } if ($dbw->numRows($result) == 0) { // Nothing to do. wfDebug(__METHOD__ . ": nothing to do\n"); $dbw->rollback(); FileStore::unlock(); return true; } $revisions = 0; while ($row = $dbw->fetchObject($result)) { if ($Unsuppress) { // Currently, fa_deleted flags fall off upon restore, lets be careful about this } else { if ($row->fa_deleted & Revision::DELETED_RESTRICTED && !$wgUser->isAllowed('hiderevision')) { // Skip restoring file revisions that the user cannot restore continue; } } $revisions++; $store = FileStore::get($row->fa_storage_group); if (!$store) { wfDebug(__METHOD__ . ": skipping row with no file.\n"); continue; } if ($revisions == 1 && !$exists) { $destDir = wfImageDir($row->fa_name); if (!is_dir($destDir)) { wfMkdirParents($destDir); } $destPath = $destDir . DIRECTORY_SEPARATOR . $row->fa_name; // We may have to fill in data if this was originally // an archived file revision. if (is_null($row->fa_metadata)) { $tempFile = $store->filePath($row->fa_storage_key); $magic = MimeMagic::singleton(); $mime = $magic->guessMimeType($tempFile, true); $media_type = $magic->getMediaType($tempFile, $mime); list($major_mime, $minor_mime) = self::splitMime($mime); $handler = MediaHandler::getHandler($mime); if ($handler) { $metadata = $handler->getMetadata($image, $tempFile); } else { $metadata = ''; } } else { $metadata = $row->fa_metadata; $major_mime = $row->fa_major_mime; $minor_mime = $row->fa_minor_mime; $media_type = $row->fa_media_type; } $table = 'image'; $fields = array('img_name' => $row->fa_name, 'img_size' => $row->fa_size, 'img_width' => $row->fa_width, 'img_height' => $row->fa_height, 'img_metadata' => $metadata, 'img_bits' => $row->fa_bits, 'img_media_type' => $media_type, 'img_major_mime' => $major_mime, 'img_minor_mime' => $minor_mime, 'img_description' => $row->fa_description, 'img_user' => $row->fa_user, 'img_user_text' => $row->fa_user_text, 'img_timestamp' => $row->fa_timestamp); } else { $archiveName = $row->fa_archive_name; if ($archiveName == '') { // This was originally a current version; we // have to devise a new archive name for it. // Format is <timestamp of archiving>!<name> $archiveName = wfTimestamp(TS_MW, $row->fa_deleted_timestamp) . '!' . $row->fa_name; } $destDir = wfImageArchiveDir($row->fa_name); if (!is_dir($destDir)) { wfMkdirParents($destDir); } $destPath = $destDir . DIRECTORY_SEPARATOR . $archiveName; $table = 'oldimage'; $fields = array('oi_name' => $row->fa_name, 'oi_archive_name' => $archiveName, 'oi_size' => $row->fa_size, 'oi_width' => $row->fa_width, 'oi_height' => $row->fa_height, 'oi_bits' => $row->fa_bits, 'oi_description' => $row->fa_description, 'oi_user' => $row->fa_user, 'oi_user_text' => $row->fa_user_text, 'oi_timestamp' => $row->fa_timestamp); } $dbw->insert($table, $fields, __METHOD__); // @todo this delete is not totally safe, potentially $dbw->delete('filearchive', array('fa_id' => $row->fa_id), __METHOD__); // Check if any other stored revisions use this file; // if so, we shouldn't remove the file from the deletion // archives so they will still work. $useCount = $dbw->selectField('filearchive', 'COUNT(*)', array('fa_storage_group' => $row->fa_storage_group, 'fa_storage_key' => $row->fa_storage_key), __METHOD__); if ($useCount == 0) { wfDebug(__METHOD__ . ": nothing else using {$row->fa_storage_key}, will deleting after\n"); $flags = FileStore::DELETE_ORIGINAL; } else { $flags = 0; } $transaction->add($store->export($row->fa_storage_key, $destPath, $flags)); } $dbw->immediateCommit(); } catch (MWException $e) { wfDebug(__METHOD__ . " caught error, aborting\n"); $transaction->rollback(); throw $e; } $transaction->commit(); FileStore::unlock(); if ($revisions > 0) { if (!$exists) { wfDebug(__METHOD__ . " restored {$revisions} items, creating a new current\n"); // Update site_stats $site_stats = $dbw->tableName('site_stats'); $dbw->query("UPDATE {$site_stats} SET ss_images=ss_images+1", __METHOD__); $this->purgeEverything(); } else { wfDebug(__METHOD__ . " restored {$revisions} as archived versions\n"); $this->purgeDescription(); } } return $revisions; }
function revert() { global $wgOut, $wgRequest, $wgUser; $oldimage = $wgRequest->getText('oldimage'); if (strlen($oldimage) < 16) { $wgOut->showUnexpectedValueError('oldimage', htmlspecialchars($oldimage)); return; } if (strstr($oldimage, "/") || strstr($oldimage, "\\")) { $wgOut->showUnexpectedValueError('oldimage', htmlspecialchars($oldimage)); return; } if (wfReadOnly()) { $wgOut->readOnlyPage(); return; } if ($wgUser->isAnon()) { $wgOut->showErrorPage('uploadnologin', 'uploadnologintext'); return; } if (!$this->mTitle->userCanEdit()) { $wgOut->sysopRequired(); return; } if ($wgUser->isBlocked()) { return $this->blockedIPpage(); } if (!$wgUser->matchEditToken($wgRequest->getVal('wpEditToken'), $oldimage)) { $wgOut->showErrorPage('internalerror', 'sessionfailure'); return; } $name = substr($oldimage, 15); $dest = wfImageDir($name); $archive = wfImageArchiveDir($name); $curfile = "{$dest}/{$name}"; if (!is_dir($dest)) { wfMkdirParents($dest); } if (!is_dir($archive)) { wfMkdirParents($archive); } if (!is_file($curfile)) { $wgOut->showFileNotFoundError(htmlspecialchars($curfile)); return; } $oldver = wfTimestampNow() . "!{$name}"; $dbr =& wfGetDB(DB_SLAVE); $size = $dbr->selectField('oldimage', 'oi_size', array('oi_archive_name' => $oldimage)); if (!rename($curfile, "{$archive}/{$oldver}")) { $wgOut->showFileRenameError($curfile, "{$archive}/{$oldver}"); return; } if (!copy("{$archive}/{$oldimage}", $curfile)) { $wgOut->showFileCopyError("{$archive}/{$oldimage}", $curfile); return; } # Record upload and update metadata cache $img = Image::newFromName($name); $img->recordUpload($oldver, wfMsg("reverted")); $wgOut->setPagetitle(wfMsg('actioncomplete')); $wgOut->setRobotpolicy('noindex,nofollow'); $wgOut->addHTML(wfMsg('imagereverted')); $descTitle = $img->getTitle(); $wgOut->returnToMain(false, $descTitle->getPrefixedText()); }
function filePath($name) { return wfImageDir($name) . "/{$name}"; }