function showFile() { $i = strpos($this->mBasePath, '/'); $i = $i === false ? 0 : $i + 1; $filename = substr($this->mBasePath, $i); $i = strpos($filename, '.'); if ($i !== false) { $ext = substr($filename, $i + 1); $mime = MimeMagic::singleton(); $ctype = $mime->guessTypesForExtension($ext); } else { $ctype = 'application/octet-stream'; } $contents = $this->svn->getFile($this->mBasePath, $this->mRev == 'HEAD' ? null : $this->mRev); if ($this->mAction == 'raw' || $this->mAction == 'download') { global $wgOut; $wgOut->disable(); if ($this->mAction == 'raw') { header('Content-Type: ' . $ctype); } else { header('Content-Type: application/octet-stream'); } header('Content-Length: ' . strlen($contents)); print $contents; return; } if (substr($ctype, 0, 5) == 'text/') { return Xml::element('pre', array('style' => 'overflow: auto;'), $contents); } else { return wfMsgHTML('codebrowse-binary-file'); } }
/** * This is called upon loading the special page. It should write output to the page with $wgOut. * * @param string $par The portion of the URI after Special:StaticDocServer/ */ public function execute($par) { #TODO: switch to $this->getOuput() and $this->getRequest() when we upgrade MW global $wgOut, $wgRequest; $wgOut->disable(); $found = FALSE; list($productName, $versionName, $path) = explode('/', $par, 3); if (substr($par, -1, 1) == '/') { $par .= 'index.html'; } // Validate parameters are set if (isset($productName) && isset($versionName) && PonyDocsProduct::GetProductByShortName($productName) && PonyDocsProductVersion::GetVersionByName($productName, $versionName)) { $filename = PONYDOCS_STATIC_DIR . "/{$par}"; if (file_exists($filename)) { $found = TRUE; } } if (!$found) { $wgRequest->response()->header("HTTP/1.1 404 Not Found"); echo "<html>\n"; echo "<head><title>Not Found</title></head>\n"; echo "<body>\n"; echo "<h1>Bad Request</h1>\n"; echo "<div>The documentation you have requested does not exist.</div>\n"; echo "</body>\n"; echo "</html>\n"; } else { $mimeMagic = MimeMagic::singleton(); $pathParts = pathinfo($filename); /* get mime-type for a specific file */ header('Content-type: ' . $mimeMagic->guessTypesForExtension($pathParts['extension'])); readfile($filename); } }
function getMimeType() { if (!isset($this->mime)) { $magic = MimeMagic::singleton(); $this->mime = $magic->guessMimeType($this->path); } return $this->mime; }
/** * Utility function: Get a new file object for a file on disk but not actually in db. * * File must be in the path returned by getFilePath() * @param string $name File name * @param string $type MIME type [optional] * @return UnregisteredLocalFile */ protected function dataFile($name, $type = null) { if (!$type) { // Autodetect by file extension for the lazy. $magic = MimeMagic::singleton(); $parts = explode($name, '.'); $type = $magic->guessTypesForExtension($parts[count($parts) - 1]); } return new UnregisteredLocalFile(false, $this->repo, "mwstore://localtesting/data/{$name}", $type); }
/** */ function wfGetType($filename, $safe = true) { global $wgTrivialMimeDetection; $ext = strrchr($filename, '.'); $ext = $ext === false ? '' : strtolower(substr($ext, 1)); # trivial detection by file extension, # used for thumbnails (thumb.php) if ($wgTrivialMimeDetection) { switch ($ext) { case 'gif': return 'image/gif'; case 'png': return 'image/png'; case 'jpg': return 'image/jpeg'; case 'jpeg': return 'image/jpeg'; } return 'unknown/unknown'; } $magic = MimeMagic::singleton(); // Use the extension only, rather than magic numbers, to avoid opening // up vulnerabilities due to uploads of files with allowed extensions // but disallowed types. $type = $magic->guessTypesForExtension($ext); /** * Double-check some security settings that were done on upload but might * have changed since. */ if ($safe) { global $wgFileBlacklist, $wgCheckFileExtensions, $wgStrictFileExtensions, $wgFileExtensions, $wgVerifyMimeType, $wgMimeTypeBlacklist, $wgRequest; $form = new UploadForm($wgRequest); list($partName, $extList) = $form->splitExtensions($filename); if ($form->checkFileExtensionList($extList, $wgFileBlacklist)) { return 'unknown/unknown'; } if ($wgCheckFileExtensions && $wgStrictFileExtensions && !$form->checkFileExtensionList($extList, $wgFileExtensions)) { return 'unknown/unknown'; } if ($wgVerifyMimeType && in_array(strtolower($type), $wgMimeTypeBlacklist)) { return 'unknown/unknown'; } } return $type; }
function setType( $image ) { $this->mimetype = $image->getMimeType(); $this->mediatype = $image->getMediaType(); #FIXME: ugly hack! do this on upload! if ( $this->mimetype == 'unknown/unknown' ) { $mime = MimeMagic::singleton(); $ext = preg_replace('!^.*\.([^.]+)$!', '\1', $image->getName()); $this->mimetype = $mime->guessTypesForExtension($ext); $this->mediatype = $mime->getMediaType(null, $this->mimetype); } if ( preg_match('!/(x-)?ogg$!', $this->mimetype) ) { if ( $this->mediatype == MEDIATYPE_AUDIO ) $this->mimetype = 'audio/ogg'; elseif ( $this->mediatype == MEDIATYPE_VIDEO ) $this->mimetype = 'video/ogg'; else $this->mimetype = 'application/ogg'; } }
/** */ function wfGetType($filename) { global $wgTrivialMimeDetection; # trivial detection by file extension, # used for thumbnails (thumb.php) if ($wgTrivialMimeDetection) { $ext = strtolower(strrchr($filename, '.')); switch ($ext) { case '.gif': return 'image/gif'; case '.png': return 'image/png'; case '.jpg': return 'image/jpeg'; case '.jpeg': return 'image/jpeg'; } return 'unknown/unknown'; } else { $magic =& MimeMagic::singleton(); return $magic->guessMimeType($filename); //full fancy mime detection } }
/** * Given a mime type, return a comma separated list of allowed extensions. * * @param $mime String mime type * @return String Comma separated list of allowed extensions (e.g. ".ogg, .oga") */ private function getExtensionList($mime) { $exts = MimeMagic::singleton()->getExtensionsForType($mime); if ($exts === null) { return ''; } $extArray = explode(' ', $exts); $extArray = array_unique($extArray); foreach ($extArray as &$ext) { $ext = '.' . $ext; } return $this->getLanguage()->commaList($extArray); }
function getThumbType($ext, $mime) { global $wgDjvuOutputExtension; static $mime; if (!isset($mime)) { $magic = MimeMagic::singleton(); $mime = $magic->guessTypesForExtension($wgDjvuOutputExtension); } return array($wgDjvuOutputExtension, $mime); }
/** * @access private */ function processCreation() { global $wgCityId, $wgSpecialContactEmail; global $wgLanguageCode, $wgServer; // If not configured, fall back to a default just in case. $wgSpecialContactEmail = empty($wgSpecialContactEmail) ? "*****@*****.**" : $wgSpecialContactEmail; $user = $this->getUser(); $output = $this->getOutput(); $request = $this->getRequest(); $output->setPageTitle($this->msg('specialcontact-pagetitle')->text()); $output->setRobotpolicy('noindex,nofollow'); $output->setArticleRelated(false); //build common top of both emails $uid = $user->getID(); $m_shared = ''; if (empty($uid)) { $m_shared .= "USER IS NOT LOGGED IN\n"; } $m_shared .= !empty($this->mRealName) ? $this->mRealName : (!empty($this->mUserName) ? $this->mUserName : '******'); $m_shared .= " ({$this->mEmail})"; $m_shared .= " " . (!empty($this->mUserName) ? $wgServer . "/wiki/User:"******" ", "_", $this->mUserName)) : $wgServer) . "\n"; //start wikia debug info, sent only to the internal email, not cc'd $items = array(); $items[] = 'wkID: ' . $wgCityId; $items[] = 'wkLang: ' . $wgLanguageCode; //always add the IP $items[] = 'IP:' . $request->getIP(); //if they are logged in, add the ID(and name) and their lang if (!empty($uid)) { $items[] = 'uID: ' . $uid . " (User:"******")"; $items[] = 'uLang: ' . $user->getGlobalPreference('language'); } if (!empty($this->mReferral)) { $items[] = 'referral: ' . $this->mReferral; } //smush it all together $info = $this->mBrowser . "\n\n"; if (!empty($uid)) { $info .= 'http://community.wikia.com/wiki/Special:LookUpUser/' . urlencode(str_replace(" ", "_", $this->mUserName)) . "_\n"; } $info .= 'http://community.wikia.com/wiki/Special:LookUpUser/' . $this->mEmail . "\n\n"; $info .= "A/B Tests: " . $this->mAbTestInfo . "\n\n"; // giving it its own line so that it stands out more $info .= implode("; ", $items) . "\n\n"; //end wikia debug data $body = "\n{$this->mProblemDesc}\n\n----\n" . $m_shared . $info; if ($this->mCCme) { $mcc = $this->msg('specialcontact-ccheader')->text() . "\n\n"; $mcc .= $m_shared . "\n{$this->mProblemDesc}\n"; } $mail_user = new MailAddress($this->mEmail); $mail_community = new MailAddress($wgSpecialContactEmail, 'Wikia Support'); $errors = ''; #to us, from user if (F::app()->checkSkin('wikiamobile')) { //We want an easy way to know that feedback comes from a mobile $this->mProblem = 'Mobile: ' . $this->mProblem; } $subject = $this->msg('specialcontact-mailsub')->text() . (!empty($this->mProblem) ? ' - ' . $this->mProblem : ''); $screenshot = $request->getFileTempname('wpScreenshot'); $magic = MimeMagic::singleton(); $screenshots = array(); if (!empty($screenshot)) { foreach ($screenshot as $image) { if (!empty($image)) { $extList = ''; $mime = $magic->guessMimeType($image); if ($mime !== 'unknown/unknown') { # Get a space separated list of extensions $extList = $magic->getExtensionsForType($mime); $ext_file = strtok($extList, ' '); } else { $mime = 'application/octet-stream'; } $screenshots[] = array('file' => $image, 'ext' => $ext_file, 'mime' => $mime); } } if (!empty($screenshots)) { $body .= "\n\nScreenshot attached."; } } # send mail to wgSpecialContactEmail # PLATFORM-212 -> To: and From: fields are set to wgSpecialContactEmail, ReplyTo: field is the user email $result = UserMailer::send($mail_community, $mail_community, $subject, $body, $mail_user, null, 'SpecialContact', 0, $screenshots); if (!$result->isOK()) { $errors .= "\n" . $result->getMessage(); } #to user, from us (but only if the first one didnt error, dont want to echo the user on an email we didnt get) if (empty($errors) && $this->mCCme && $user->isEmailConfirmed()) { $result = UserMailer::send($mail_user, $mail_community, $this->msg('specialcontact-mailsubcc')->text(), $mcc, $mail_user, null, 'SpecialContactCC'); if (!$result->isOK()) { $errors .= "\n" . $result->getMessage(); } } if (!empty($errors)) { $output->addHTML($this->formatError($this->err)); } /********************************************************/ #sending done, show message #parse this message to allow wiki links (BugId: 1048) $output->addHTML($this->msg('specialcontact-submitcomplete')->parseAsBlock()); $mp = Title::newMainPage(); $output->addReturnTo($mp); return; }
/** * BC wrapper for MimeMagic::singleton() * @deprecated */ function &wfGetMimeMagic() { return MimeMagic::singleton(); }
/** * @param $upload UploadBase * @param $mime * @param $error * @return bool */ public static function insertJobs($upload, $mime, &$error) { global $wgPdfCreateThumbnailsInJobQueue; if (!$wgPdfCreateThumbnailsInJobQueue) { return true; } if (!MimeMagic::singleton()->isMatchingExtension('pdf', $mime)) { return true; // not a PDF, abort } $title = $upload->getTitle(); $uploadFile = $upload->getLocalFile(); if (is_null($uploadFile)) { wfDebugLog('thumbnails', '$uploadFile seems to be null, should never happen...'); return true; // should never happen, but it's better to be secure } $metadata = $uploadFile->getMetadata(); $unserialized = unserialize($metadata); $pages = intval($unserialized['Pages']); $jobs = array(); for ($i = 1; $i <= $pages; $i++) { $jobs[] = new CreatePdfThumbnailsJob($title, array('page' => $i, 'jobtype' => self::BIG_THUMB)); $jobs[] = new CreatePdfThumbnailsJob($title, array('page' => $i, 'jobtype' => self::SMALL_THUMB)); } Job::batchInsert($jobs); return true; }
function setUp() { $this->mimeMagic = MimeMagic::singleton(); parent::setUp(); }
function imageInfo($filename) { $info = array('width' => 0, 'height' => 0, 'bits' => 0, 'media' => '', 'major' => '', 'minor' => ''); $magic = MimeMagic::singleton(); $mime = $magic->guessMimeType($filename, true); list($info['major'], $info['minor']) = explode('/', $mime); $info['media'] = $magic->getMediaType($filename, $mime); $image = UnregisteredLocalFile::newFromPath($filename, $mime); $info['width'] = $image->getWidth(); $info['height'] = $image->getHeight(); $gis = $image->getImageSize($filename); if (isset($gis['bits'])) { $info['bits'] = $gis['bits']; } return $info; }
function getMediaType() { $magic = MimeMagic::singleton(); return $magic->getMediaType(null, $this->getMimeType()); }
} else { $commentText = file_get_contents($f); if (!$commentText) { echo " Failed to load comment file {$f}, using default comment. "; } } } if (!$commentText) { $commentText = $comment; } } # Import the file if (isset($options['dry'])) { echo " publishing {$file} by '" . $wgUser->getName() . "', comment '{$commentText}'... "; } else { $mwProps = new MWFileProps(MimeMagic::singleton()); $props = $mwProps->getPropsFromPath($file, true); $flags = 0; $publishOptions = []; $handler = MediaHandler::getHandler($props['mime']); if ($handler) { $publishOptions['headers'] = $handler->getStreamHeaders($props['metadata']); } else { $publishOptions['headers'] = []; } $archive = $image->publish($file, $flags, $publishOptions); if (!$archive->isGood()) { echo "failed. (" . $archive->getWikiText(false, false, 'en') . ")\n"; $failed++; continue; }
public static function send($headers, $to, $from, $subject, $body, $priority = 0, $attachments = null) { global $wgEnotifMaxRecips, $wgSMTP; wfProfileIn(__METHOD__); require_once 'Mail2.php'; require_once 'Mail2/mime.php'; $logContext = array_merge($headers, ['issue' => 'SOC-910', 'method' => __METHOD__, 'to' => $to, 'subject' => $subject]); WikiaLogger::instance()->info('Queuing email for SendGrid', $logContext); wfSuppressWarnings(); $headers['Subject'] = UserMailer::quotedPrintable($subject); // Add a header for the server-name (helps us route where SendGrid will send bounces). if (!empty($_SERVER) && isset($_SERVER['SERVER_NAME'])) { $headers["X-ServerName"] = $_SERVER['SERVER_NAME']; } try { $mail_object =& Mail2::factory(WikiaSendgridMailer::$factory, $wgSMTP); } catch (Exception $e) { $logContext['errorMessage'] = $e->getMessage(); WikiaLogger::instance()->info('Failed to create mail object', $logContext); wfDebug("PEAR::Mail factory failed: " . $e->getMessage() . "\n"); wfRestoreWarnings(); wfProfileOut(__METHOD__); return $e->getMessage(); } $email_body_txt = $email_body_html = ""; if (is_array($body)) { if (isset($body['text'])) { $email_body_txt = $body['text']; } if (isset($body['html'])) { $email_body_html = $body['html']; } } else { $email_body_txt = $body; } $mime = new Mail_mime(); $mime->setTXTBody($email_body_txt); $params = array('head_charset' => 'UTF-8', 'html_charset' => 'UTF-8', 'text_charset' => 'UTF-8', 'text_encoding' => 'quoted-printable', 'html_encoding' => 'quoted-printable'); # send email with attachements if (!empty($attachments)) { if (!is_array($attachments)) { $attachments = array($attachments); } foreach ($attachments as $file) { if (!is_array($file)) { $magic = MimeMagic::singleton(); $mimeType = $magic->guessMimeType($file); $ext_file = end(explode('.', $file)); $file = array('file' => $file, 'ext' => $ext_file, 'mime' => $mimeType); } $filename = $file['file']; $ext_filename = $file['ext']; if (!file_exists($filename)) { continue; } $name = $filename; #basename( $filename ); if ($ext_filename) { $name = $filename . "." . $ext_filename; } $mime->addAttachment($filename, $file['mime'], $name); } } # Old version (1.16 MW with Wikia changes) of sendHTML method if ($email_body_html) { $mime->setHTMLBody($email_body_html); //do not ever try to call these lines in reverse order } $body = $mime->get($params); $headers = $mime->headers($headers); wfDebug("Sending mail via WikiaSendgridMailer::send\n"); $chunks = array_chunk((array) $to, $wgEnotifMaxRecips); foreach ($chunks as $chunk) { $headers['To'] = $chunk; $status = self::sendWithPear($mail_object, $chunk, $headers, $body); if (!$status->isOK()) { $logContext['errorMessage'] = $status->getMessage(); WikiaLogger::instance()->info('Failed to create mail object', $logContext); wfRestoreWarnings(); wfProfileOut(__METHOD__); return $status->getMessage(); } } wfProfileOut(__METHOD__); # return false to return Status::newGood() in UserMailer::send method return false; }
/** * This function registers all of the MW hook functions necessary for the * map extension to function. These hooks are added using the array_unshift * function in order to get the hook added first. This is because if another * extension returns false from its hook function, it will short-circuit * any hooks that come later in the list. **/ function wfGoogleMaps_Install() { global $wgGoogleMapsKey, $wgGoogleMapsKeys, $wgGoogleMapsDisableEditorsMap, $wgGoogleMapsEnablePaths, $wgGoogleMapsDefaults, $wgGoogleMapsMessages, $wgGoogleMapsCustomMessages, $wgGoogleMapsUrlPath, $wgXhtmlNamespaces, $wgGoogleMapsTemplateVariables, $wgJsMimeType, $wgLanguageCode, $wgLang, $wgParser, $wgProxyKey, $wgVersion, $wgGoogleMaps, $wgHooks, $wgScriptPath, $wgSpecialPages, $wgTitle; // set up some default values for the various extension configuration parameters // to keep from getting PHP notices if running in strict mode if (!isset($wgGoogleMapsKey)) { $wgGoogleMapsKey = null; } if (!isset($wgGoogleMapsKeys)) { $wgGoogleMapsKeys = array(); } if (!isset($wgGoogleMapsDisableEditorsMap)) { $wgGoogleMapsDisableEditorsMap = false; } if (!isset($wgGoogleMapsEnablePaths)) { $wgGoogleMapsEnablePaths = false; } if (!isset($wgGoogleMapsDefaults)) { $wgGoogleMapsDefaults = null; } if (!isset($wgGoogleMapsCustomMessages)) { $wgGoogleMapsCustomMessages = null; } if (!isset($wgGoogleMapsUrlPath)) { $wgGoogleMapsUrlPath = "{$wgScriptPath}/extensions/GoogleMaps"; } if (!isset($wgXhtmlNamespaces)) { $wgXhtmlNamespaces = null; } if (!isset($wgGoogleMapsTemplateVariables)) { $wgGoogleMapsTemplateVariables = false; } // make poly-lines work with IE in MW 1.9+. See MW bug #7667 if (is_array($wgXhtmlNamespaces)) { $wgXhtmlNamespaces['v'] = 'urn:schemas-microsoft-com:vml'; $wgGoogleMapsEnablePaths = true; } // determine the proper API key. if any of the array keys in the mApiKeys // array matches the current page URL, that key is used. otherwise, the // default in mApiKey is used. $longest = 0; if (is_array($wgGoogleMapsKeys)) { foreach (array_keys($wgGoogleMapsKeys) as $key) { $path = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; if (strlen($key) > $longest && substr($path, 0, strlen($key)) == $key) { $longest = strlen($key); $wgGoogleMapsKey = $wgGoogleMapsKeys[$key]; } } } // add the google mime types $magic = null; if (version_compare($wgVersion, "1.8") >= 0) { $magic = MimeMagic::singleton(); } else { $magic = wfGetMimeMagic(); } $magic->mExtToMime['kml'] = 'application/vnd.google-earth.kml+xml'; $magic->mExtToMime['kmz'] = 'application/vnd.google-earth.kmz'; // instantiate the extension $wgGoogleMaps = new GoogleMaps($wgGoogleMapsKey, $wgGoogleMapsUrlPath, $wgGoogleMapsEnablePaths, $wgGoogleMapsDefaults, $wgGoogleMapsMessages, $wgGoogleMapsCustomMessages, $wgGoogleMapsTemplateVariables, $wgJsMimeType, $wgLang, $wgProxyKey, $wgTitle); // This hook will add the interactive editing map to the article edit page. // This hook was introduced in MW 1.6 $editHook = array($wgGoogleMaps, 'editForm'); if (version_compare($wgVersion, "1.6") >= 0) { if (!$wgGoogleMapsDisableEditorsMap) { $wgHooks['EditPageBeforeEditToolbar'][] = $editHook; } } // This hook will do some post-processing on the javascript that has been added // to an article. $hook = 'wfGoogleMaps_CommentJS'; if (isset($wgHooks['ParserAfterTidy']) && is_array($wgHooks['ParserAfterTidy'])) { array_unshift($wgHooks['ParserAfterTidy'], $hook); } else { $wgHooks['ParserAfterTidy'] = array($hook); } // This hook will be called any time the parser encounters a <googlemap> // tag in an article. This will render the actual Google map code in // the article. /* // This is no longer needed due to wfGoogleMaps_InstallParser if( version_compare( $wgVersion, "1.6" ) >= 0 ) { $wgParser->setHook( 'googlemap', array( $wgGoogleMaps, 'render16' ) ); $wgParser->setHook( 'googlemapkml', array( $wgGoogleMaps, 'renderKmlLink' ) ); } else { $wgParser->setHook( 'googlemap', 'wfGoogleMaps_Render15' ); $wgParser->setHook( 'googlemapkml', 'wfGoogleMaps_RenderKmlLink15' ); } */ // Set up the special page $wgSpecialPages['GoogleMapsKML'] = array('GoogleMapsKML', 'GoogleMapsKML'); }
/** * 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; }
$wgPdfPostProcessor = 'convert'; $wgPdfInfo = 'pdfinfo'; $wgPdftoText = 'pdftotext'; $wgPdfOutputExtension = 'jpg'; $wgPdfHandlerDpi = 150; // This setting, if enabled, will put creating thumbnails into a job queue, // so they do not have to be created on-the-fly, // but rather inconspicuously during normal wiki browsing // if setting to true, make sure to migrate CreatePdfThumbnailsJob to PdfHandlerTask! $wgPdfCreateThumbnailsInJobQueue = false; // To upload new PDF files you'll need to do this too: // $wgFileExtensions[] = 'pdf'; $dir = dirname(__FILE__) . '/'; $wgExtensionMessagesFiles['PdfHandler'] = $dir . 'PdfHandler.i18n.php'; $wgAutoloadClasses['PdfImage'] = $dir . 'PdfHandler.image.php'; $wgAutoloadClasses['PdfHandler'] = $dir . 'PdfHandler_body.php'; $wgAutoloadClasses['CreatePdfThumbnailsJob'] = $dir . 'CreatePdfThumbnailsJob.class.php'; $wgAutoloadClasses['PdfHandlerTask'] = $dir . 'PdfHandlerTask.class.php'; $wgMediaHandlers['application/pdf'] = 'PdfHandler'; $wgJobClasses['createPdfThumbnailsJob'] = 'CreatePdfThumbnailsJob'; $wgHooks['UploadVerifyFile'][] = function ($upload, $mime, &$error) { global $wgPdfCreateThumbnailsInJobQueue; if (!$wgPdfCreateThumbnailsInJobQueue) { return true; } if (!MimeMagic::singleton()->isMatchingExtension('pdf', $mime)) { return true; // not a PDF, abort } return PdfHandlerTask::onUploadVerifyFile($upload, $mime, $error); };
/** * Checks if the mime type of the uploaded file matches the file extension. * * @param string $mime the mime type of the uploaded file * @param string $extension The filename extension that the file is to be served with * @return bool */ function verifyExtension( $mime, $extension ) { $magic = MimeMagic::singleton(); if ( !$mime || $mime == 'unknown' || $mime == 'unknown/unknown' ) if ( !$magic->isRecognizableExtension( $extension ) ) { wfDebug( __METHOD__ . ": passing file with unknown detected mime type; unrecognized extension '$extension', can't verify\n" ); return true; } else { wfDebug( __METHOD__ . ": rejecting file with unknown detected mime type; recognized extension '$extension', so probably invalid file\n" ); return false; } $match = $magic->isMatchingExtension( $extension, $mime ); if ( $match === null ) { wfDebug( __METHOD__ . ": no file extension known for mime type $mime, passing file\n" ); return true; } elseif ( $match === true ) { wfDebug( __METHOD__ . ": mime type $mime matches extension $extension, passing file\n" ); # TODO: if it's a bitmap, make sure PHP or ImageMagic resp. can handle it! return true; } else { wfDebug( __METHOD__ . ": mime type $mime mismatches file extension $extension, rejecting file\n" ); return false; } }
/** * @param string $storagePath * @param string|null $content * @param string|null $fsPath * @return string * @since 1.27 */ public function guessMimeInternal($storagePath, $content, $fsPath) { $magic = MimeMagic::singleton(); // Trust the extension of the storage path (caller must validate) $ext = FileBackend::extensionFromPath($storagePath); $type = $magic->guessTypesForExtension($ext); // For files without a valid extension (or one at all), inspect the contents if (!$type && $fsPath) { $type = $magic->guessMimeType($fsPath, false); } elseif (!$type && strlen($content)) { $tmpFile = TempFSFile::factory('mime_'); file_put_contents($tmpFile->getPath(), $content); $type = $magic->guessMimeType($tmpFile->getPath(), false); } return $type ?: 'unknown/unknown'; }
/** * Get an associative array containing information about a file in the local filesystem. * * @param string $path Absolute local filesystem path * @param mixed $ext The file extension, or true to extract it from the filename. * Set it to false to ignore the extension. */ static function getPropsFromPath($path, $ext = true) { wfProfileIn(__METHOD__); wfDebug(__METHOD__ . ": Getting file info for {$path}\n"); $info = array('fileExists' => file_exists($path) && !is_dir($path)); $gis = false; if ($info['fileExists']) { $magic = MimeMagic::singleton(); $info['mime'] = $magic->guessMimeType($path, $ext); list($info['major_mime'], $info['minor_mime']) = self::splitMime($info['mime']); $info['media_type'] = $magic->getMediaType($path, $info['mime']); # Get size in bytes $info['size'] = filesize($path); # Height, width and metadata $handler = MediaHandler::getHandler($info['mime']); if ($handler) { $tempImage = (object) array(); $info['metadata'] = $handler->getMetadata($tempImage, $path); $gis = $handler->getImageSize($tempImage, $path, $info['metadata']); } else { $gis = false; $info['metadata'] = ''; } $info['sha1'] = self::sha1Base36($path); wfDebug(__METHOD__ . ": {$path} loaded, {$info['size']} bytes, {$info['mime']}.\n"); } else { $info['mime'] = NULL; $info['media_type'] = MEDIATYPE_UNKNOWN; $info['metadata'] = ''; $info['sha1'] = ''; wfDebug(__METHOD__ . ": {$path} NOT FOUND!\n"); } if ($gis) { # NOTE: $gis[2] contains a code for the image type. This is no longer used. $info['width'] = $gis[0]; $info['height'] = $gis[1]; if (isset($gis['bits'])) { $info['bits'] = $gis['bits']; } else { $info['bits'] = 0; } } else { $info['width'] = 0; $info['height'] = 0; $info['bits'] = 0; } wfProfileOut(__METHOD__); return $info; }
/** * Tests the WebP MIME detection. This should really be a separate test, but sticking it * here for now. * * @dataProvider provideTestGetMimeType */ public function testGuessMimeType($path) { $mime = MimeMagic::singleton(); $this->assertEquals('image/webp', $mime->guessMimeType($path, false)); }
/** * Find or guess extension -- ensuring that our extension matches our mime type. * Since these files are constructed from php tempnames they may not start off * with an extension. * XXX this is somewhat redundant with the checks that ApiUpload.php does with incoming * uploads versus the desired filename. Maybe we can get that passed to us... */ public static function getExtensionForPath($path) { // Does this have an extension? $n = strrpos($path, '.'); $extension = null; if ($n !== false) { $extension = $n ? substr($path, $n + 1) : ''; } else { // If not, assume that it should be related to the mime type of the original file. $magic = MimeMagic::singleton(); $mimeType = $magic->guessMimeType($path); $extensions = explode(' ', MimeMagic::singleton()->getExtensionsForType($mimeType)); if (count($extensions)) { $extension = $extensions[0]; } } if (is_null($extension)) { throw new UploadStashFileException("extension is null"); } return File::normalizeExtension($extension); }
/** * Checks if the mime type of the uploaded file matches the file extension. * * @param string $mime the mime type of the uploaded file * @param string $extension the filename extension that the file is to be served with * @return Boolean */ public static function verifyExtension($mime, $extension) { $magic = MimeMagic::singleton(); if (!$mime || $mime == 'unknown' || $mime == 'unknown/unknown') { if (!$magic->isRecognizableExtension($extension)) { wfDebug(__METHOD__ . ": passing file with unknown detected mime type; " . "unrecognized extension '{$extension}', can't verify\n"); return true; } else { wfDebug(__METHOD__ . ": rejecting file with unknown detected mime type; " . "recognized extension '{$extension}', so probably invalid file\n"); return false; } } $match = $magic->isMatchingExtension($extension, $mime); if ($match === null) { if ($magic->getTypesForExtension($extension) !== null) { wfDebug(__METHOD__ . ": No extension known for {$mime}, but we know a mime for {$extension}\n"); return false; } else { wfDebug(__METHOD__ . ": no file extension known for mime type {$mime}, passing file\n"); return true; } } elseif ($match === true) { wfDebug(__METHOD__ . ": mime type {$mime} matches extension {$extension}, passing file\n"); #TODO: if it's a bitmap, make sure PHP or ImageMagic resp. can handle it! return true; } else { wfDebug(__METHOD__ . ": mime type {$mime} mismatches file extension {$extension}, rejecting file\n"); return false; } }
/** * Checks if file extensions are compatible * * @param $old File Old file * @param string $new New name * * @return bool|null */ static function checkExtensionCompatibility(File $old, $new) { $oldMime = $old->getMimeType(); $n = strrpos($new, '.'); $newExt = self::normalizeExtension($n ? substr($new, $n + 1) : ''); $mimeMagic = MimeMagic::singleton(); return $mimeMagic->isMatchingExtension($newExt, $oldMime); }
/** * @return int|string */ function getMediaType() { if (isset($this->mInfo['mediatype'])) { return $this->mInfo['mediatype']; } $magic = MimeMagic::singleton(); return $magic->getMediaType(null, $this->getMimeType()); }
/** * Get the thumbnail extension and MIME type for a given source MIME type * * @param string $ext Extension of original file * @param string $mime MIME type of original file * @param array $params Handler specific rendering parameters * @return array Thumbnail extension and MIME type */ function getThumbType($ext, $mime, $params = null) { $magic = MimeMagic::singleton(); if (!$ext || $magic->isMatchingExtension($ext, $mime) === false) { // The extension is not valid for this MIME type and we do // recognize the MIME type $extensions = $magic->getExtensionsForType($mime); if ($extensions) { return [strtok($extensions, ' '), $mime]; } } // The extension is correct (true) or the MIME type is unknown to // MediaWiki (null) return [$ext, $mime]; }
/** * Find or guess extension -- ensuring that our extension matches our mime type. * Since these files are constructed from php tempnames they may not start off * with an extension. * XXX this is somewhat redundant with the checks that ApiUpload.php does with incoming * uploads versus the desired filename. Maybe we can get that passed to us... * @param $path * @throws UploadStashFileException * @return string */ public static function getExtensionForPath($path) { global $wgFileBlacklist; // Does this have an extension? $n = strrpos($path, '.'); $extension = null; if ($n !== false) { $extension = $n ? substr($path, $n + 1) : ''; } else { // If not, assume that it should be related to the mime type of the original file. $magic = MimeMagic::singleton(); $mimeType = $magic->guessMimeType($path); $extensions = explode(' ', MimeMagic::singleton()->getExtensionsForType($mimeType)); if (count($extensions)) { $extension = $extensions[0]; } } if (is_null($extension)) { throw new UploadStashFileException("extension is null"); } $extension = File::normalizeExtension($extension); if (in_array($extension, $wgFileBlacklist)) { // The file should already be checked for being evil. // However, if somehow we got here, we definitely // don't want to give it an extension of .php and // put it in a web accesible directory. return ''; } return $extension; }