public static function onUploadComplete(UploadBase $oForm) { wfProfileIn(__METHOD__); $oLocalFile = $oForm->getLocalFile(); $oScribeProducer = new ScribeEventProducer('edit'); if ($oScribeProducer->buildEditPackage(self::$oPage, self::$oUser, self::$oRevision, null, $oLocalFile)) { $oScribeProducer->sendLog(); } wfProfileOut(__METHOD__); return true; }
private function loadRequest($request) { global $wgUser; $this->mRequest = $request; $this->mAction = $request->getInt(ADD_RESOURCE_ACTION_FIELD); switch ($this->mAction) { case ADD_RESOURCE_ACTION_UPLOAD: $this->mUpload = UploadBase::createFromRequest($request); # used by copied processUpload() $this->mUploadClicked = true; $this->mComment = $request->getVal('wpUploadDescription'); break; case ADD_RESOURCE_ACTION_SUBPAGE: $this->mSubpageDest = $request->getVal('wpSubpageDest'); break; case ADD_RESOURCE_ACTION_LINK: $this->mLinkUrl = $request->getVal('wpLinkUrl'); $this->mLinkTitle = $request->getVal('wpLinkTitle'); $this->mLinkDesc = $request->getVal('wpLinkDesc'); break; default: break; } $this->mTokenOk = $wgUser->matchEditToken($request->getVal('wpEditToken')); $this->mCancelUpload = false; }
protected function checkPermission() { $permissionRequired = UploadBase::isAllowed($this->getUser()); if ($permissionRequired !== true) { throw new PermissionsError($permissionRequired); } }
/** * Perform the actual upload. Returns a suitable result array on success; * dies on failure. * * @return array */ protected function performUpload() { // Use comment as initial page text by default if (is_null($this->mParams['text'])) { $this->mParams['text'] = $this->mParams['comment']; } $file = $this->mUpload->getLocalFile(); $watch = $this->getWatchlistValue($this->mParams['watchlist'], $file->getTitle()); // Deprecated parameters if ($this->mParams['watch']) { $watch = true; } // No errors, no warnings: do the upload $status = $this->mUpload->performUpload($this->mParams['comment'], $this->mParams['text'], $watch, $this->getUser()); if (!$status->isGood()) { $error = $status->getErrorsArray(); if (count($error) == 1 && $error[0][0] == 'async') { // The upload can not be performed right now, because the user // requested so return array('result' => 'Queued', 'statuskey' => $error[0][1]); } else { $this->getResult()->setIndexedTagName($error, 'error'); $this->dieUsage('An internal error occurred', 'internal-error', 0, $error); } } $file = $this->mUpload->getLocalFile(); $result['result'] = 'Success'; $result['filename'] = $file->getName(); return $result; }
/** * There is no need to stash the image twice */ public function stashSession($key = null) { if (!empty($this->mSessionKey)) { return $this->mSessionKey; } return parent::stashSession(); }
/** * Add "replace" button to File pages * Add "remove" action to MenuButtons on premium video file pages * This button will remove a video from a wiki but keep it on the Video Wiki. */ public static function onSkinTemplateNavigation($skin, &$tabs) { global $wgUser; $app = F::app(); $title = $app->wg->Title; if ($title instanceof Title && $title->getNamespace() == NS_FILE && $title->exists()) { $file = wfFindFile($title); if ($file instanceof File && UploadBase::userCanReUpload($wgUser, $file->getName())) { if (WikiaFileHelper::isFileTypeVideo($file)) { $uploadTitle = SpecialPage::getTitleFor('WikiaVideoAdd'); $href = $uploadTitle->getFullURL(array('name' => $file->getName())); } else { $uploadTitle = SpecialPage::getTitleFor('Upload'); $href = $uploadTitle->getFullURL(array('wpDestFile' => $file->getName(), 'wpForReUpload' => 1)); } $tabs['actions']['replace-file'] = array('class' => 'replace-file', 'text' => wfMessage('file-page-replace-button'), 'href' => $href); } } // Ignore Video Wiki videos beyond this point if ($app->wg->CityId == self::VIDEO_WIKI) { return true; } if (WikiaFileHelper::isFileTypeVideo($title)) { $file = wfFindFile($title); if (!$file->isLocal()) { // Prevent move tab being shown. unset($tabs['actions']['move']); } } return true; }
public function run() { $scope = RequestContext::importScopedSession($this->params['session']); $context = RequestContext::getMain(); try { $user = $context->getUser(); if (!$user->isLoggedIn()) { $this->setLastError("Could not load the author user from session."); return false; } if (count($_SESSION) === 0) { // Empty session probably indicates that we didn't associate // with the session correctly. Note that being able to load // the user does not necessarily mean the session was loaded. // Most likely cause by suhosin.session.encrypt = On. $this->setLastError("Error associating with user session. " . "Try setting suhosin.session.encrypt = Off"); return false; } UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Poll', 'stage' => 'publish', 'status' => Status::newGood())); $upload = new UploadFromStash($user); // @todo initialize() causes a GET, ideally we could frontload the antivirus // checks and anything else to the stash stage (which includes concatenation and // the local file is thus already there). That way, instead of GET+PUT, there could // just be a COPY operation from the stash to the public zone. $upload->initialize($this->params['filekey'], $this->params['filename']); // Check if the local file checks out (this is generally a no-op) $verification = $upload->verifyUpload(); if ($verification['status'] !== UploadBase::OK) { $status = Status::newFatal('verification-error'); $status->value = array('verification' => $verification); UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'publish', 'status' => $status)); $this->setLastError("Could not verify upload."); return false; } // Upload the stashed file to a permanent location $status = $upload->performUpload($this->params['comment'], $this->params['text'], $this->params['watch'], $user); if (!$status->isGood()) { UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'publish', 'status' => $status)); $this->setLastError($status->getWikiText()); return false; } // Build the image info array while we have the local reference handy $apiMain = new ApiMain(); // dummy object (XXX) $imageInfo = $upload->getImageInfo($apiMain->getResult()); // Cleanup any temporary local file $upload->cleanupTempFile(); // Cache the info so the user doesn't have to wait forever to get the final info UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Success', 'stage' => 'publish', 'filename' => $upload->getLocalFile()->getName(), 'imageinfo' => $imageInfo, 'status' => Status::newGood())); } catch (MWException $e) { UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'publish', 'status' => Status::newFatal('api-error-publishfailed'))); $this->setLastError(get_class($e) . ": " . $e->getText()); // To prevent potential database referential integrity issues. // See bug 32551. MWExceptionHandler::rollbackMasterChangesAndLog($e); return false; } return true; }
function isUploadEnabled() { if (\UploadBase::isEnabled() == true) { return true; } else { return false; } }
function isUploadAllowed() { global $wgUser; if (\UploadBase::isAllowed($wgUser) == true) { return true; } else { return false; } }
/** * Handle image upload * * Returns array with uploaded files details or error details */ public function uploadImage($uploadFieldName = self::DEFAULT_FILE_FIELD_NAME, $destFileName = null, $forceOverwrite = false) { global $IP, $wgRequest, $wgUser; wfProfileIn(__METHOD__); $ret = false; // check whether upload is enabled (RT #53714) if (!WikiaPhotoGalleryHelper::isUploadAllowed()) { $ret = array('error' => true, 'message' => wfMsg('uploaddisabled')); wfProfileOut(__METHOD__); return $ret; } $imageName = stripslashes(!empty($destFileName) ? $destFileName : $wgRequest->getFileName($uploadFieldName)); // validate name and content of uploaded photo $nameValidation = $this->checkImageName($imageName, $uploadFieldName); if ($nameValidation == UploadBase::SUCCESS) { // get path to uploaded image $imagePath = $wgRequest->getFileTempName($uploadFieldName); // check if image with this name is already uploaded if ($this->imageExists($imageName) && !$forceOverwrite) { // upload as temporary file $this->log(__METHOD__, "image '{$imageName}' already exists!"); $tempName = $this->tempFileName($wgUser); $title = Title::makeTitle(NS_FILE, $tempName); $localRepo = RepoGroup::singleton()->getLocalRepo(); $file = new FakeLocalFile($title, $localRepo); $file->upload($wgRequest->getFileTempName($uploadFieldName), '', ''); // store uploaded image in GarbageCollector (image will be removed if not used) $tempId = $this->tempFileStoreInfo($tempName); // generate thumbnail (to fit 200x200 box) of temporary file $width = min(WikiaPhotoGalleryHelper::thumbnailMaxWidth, $file->width); $height = min(WikiaPhotoGalleryHelper::thumbnailMaxHeight, $file->height); $thumbnail = $file->transform(array('height' => $height, 'width' => $width)); // split uploaded file name into name + extension (foo-bar.png => foo-bar + png) list($fileName, $extensionsName) = UploadBase::splitExtensions($imageName); $extensionName = !empty($extensionsName) ? end($extensionsName) : ''; $this->log(__METHOD__, 'upload successful'); $ret = array('conflict' => true, 'name' => $imageName, 'nameParts' => array($fileName, $extensionName), 'tempId' => $tempId, 'size' => array('height' => $file->height, 'width' => $file->width), 'thumbnail' => array('height' => $thumbnail->height, 'url' => $thumbnail->url, 'width' => $thumbnail->width)); } else { // use regular MW upload $this->log(__METHOD__, "image '{$imageName}' is new one - uploading as MW file"); $this->log(__METHOD__, "uploading '{$imagePath}' as File:{$imageName}"); // create title and file objects for MW image to create $imageTitle = Title::newFromText($imageName, NS_FILE); $imageFile = new LocalFile($imageTitle, RepoGroup::singleton()->getLocalRepo()); // perform upload $result = $imageFile->upload($imagePath, '', ''); $this->log(__METHOD__, !empty($result->ok) ? 'upload successful' : 'upload failed'); $ret = array('success' => !empty($result->ok), 'name' => $imageName, 'size' => array('height' => !empty($result->ok) ? $imageFile->getHeight() : 0, 'width' => !empty($result->ok) ? $imageFile->getWidth() : 0)); } } else { $reason = $nameValidation; $this->log(__METHOD__, "upload failed - file name is not valid (error #{$reason})"); $ret = array('error' => true, 'reason' => $reason, 'message' => $this->translateError($reason)); } wfProfileOut(__METHOD__); return $ret; }
/** * Perform the actual upload. Returns a suitable result array on success; * dies on failure. * * @param array $warnings Array of Api upload warnings * @return array */ protected function performUpload($warnings) { // Use comment as initial page text by default if (is_null($this->mParams['text'])) { $this->mParams['text'] = $this->mParams['comment']; } /** @var $file File */ $file = $this->mUpload->getLocalFile(); // For preferences mode, we want to watch if 'watchdefault' is set or // if the *file* doesn't exist and 'watchcreations' is set. But // getWatchlistValue()'s automatic handling checks if the *title* // exists or not, so we need to check both prefs manually. $watch = $this->getWatchlistValue($this->mParams['watchlist'], $file->getTitle(), 'watchdefault'); if (!$watch && $this->mParams['watchlist'] == 'preferences' && !$file->exists()) { $watch = $this->getWatchlistValue($this->mParams['watchlist'], $file->getTitle(), 'watchcreations'); } // Deprecated parameters if ($this->mParams['watch']) { $watch = true; } // No errors, no warnings: do the upload if ($this->mParams['async']) { $progress = UploadBase::getSessionStatus($this->mParams['filekey']); if ($progress && $progress['result'] === 'Poll') { $this->dieUsage("Upload from stash already in progress.", 'publishfailed'); } UploadBase::setSessionStatus($this->mParams['filekey'], array('result' => 'Poll', 'stage' => 'queued', 'status' => Status::newGood())); $ok = JobQueueGroup::singleton()->push(new PublishStashedFileJob(Title::makeTitle(NS_FILE, $this->mParams['filename']), array('filename' => $this->mParams['filename'], 'filekey' => $this->mParams['filekey'], 'comment' => $this->mParams['comment'], 'text' => $this->mParams['text'], 'watch' => $watch, 'session' => $this->getContext()->exportSession()))); if ($ok) { $result['result'] = 'Poll'; } else { UploadBase::setSessionStatus($this->mParams['filekey'], false); $this->dieUsage("Failed to start PublishStashedFile.php", 'publishfailed'); } } else { /** @var $status Status */ $status = $this->mUpload->performUpload($this->mParams['comment'], $this->mParams['text'], $watch, $this->getUser()); if (!$status->isGood()) { $error = $status->getErrorsArray(); if (count($error) == 1 && $error[0][0] == 'async') { // The upload can not be performed right now, because the user // requested so return array('result' => 'Queued', 'statuskey' => $error[0][1]); } $this->getResult()->setIndexedTagName($error, 'error'); $this->dieUsage('An internal error occurred', 'internal-error', 0, $error); } $result['result'] = 'Success'; } $result['filename'] = $file->getName(); if ($warnings && count($warnings) > 0) { $result['warnings'] = $warnings; } return $result; }
public function run() { $scope = RequestContext::importScopedSession($this->params['session']); $this->addTeardownCallback(function () use(&$scope) { ScopedCallback::consume($scope); // T126450 }); $context = RequestContext::getMain(); $user = $context->getUser(); try { if (!$user->isLoggedIn()) { $this->setLastError("Could not load the author user from session."); return false; } UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Poll', 'stage' => 'publish', 'status' => Status::newGood()]); $upload = new UploadFromStash($user); // @todo initialize() causes a GET, ideally we could frontload the antivirus // checks and anything else to the stash stage (which includes concatenation and // the local file is thus already there). That way, instead of GET+PUT, there could // just be a COPY operation from the stash to the public zone. $upload->initialize($this->params['filekey'], $this->params['filename']); // Check if the local file checks out (this is generally a no-op) $verification = $upload->verifyUpload(); if ($verification['status'] !== UploadBase::OK) { $status = Status::newFatal('verification-error'); $status->value = ['verification' => $verification]; UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Failure', 'stage' => 'publish', 'status' => $status]); $this->setLastError("Could not verify upload."); return false; } // Upload the stashed file to a permanent location $status = $upload->performUpload($this->params['comment'], $this->params['text'], $this->params['watch'], $user, isset($this->params['tags']) ? $this->params['tags'] : []); if (!$status->isGood()) { UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Failure', 'stage' => 'publish', 'status' => $status]); $this->setLastError($status->getWikiText(false, false, 'en')); return false; } // Build the image info array while we have the local reference handy $apiMain = new ApiMain(); // dummy object (XXX) $imageInfo = $upload->getImageInfo($apiMain->getResult()); // Cleanup any temporary local file $upload->cleanupTempFile(); // Cache the info so the user doesn't have to wait forever to get the final info UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Success', 'stage' => 'publish', 'filename' => $upload->getLocalFile()->getName(), 'imageinfo' => $imageInfo, 'status' => Status::newGood()]); } catch (Exception $e) { UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Failure', 'stage' => 'publish', 'status' => Status::newFatal('api-error-publishfailed')]); $this->setLastError(get_class($e) . ": " . $e->getMessage()); // To prevent potential database referential integrity issues. // See bug 32551. MWExceptionHandler::rollbackMasterChangesAndLog($e); return false; } return true; }
/** * @return array */ public function verifyUpload() { # Check for a post_max_size or upload_max_size overflow, so that a # proper error can be shown to the user if (is_null($this->mTempPath) || $this->isEmptyFile()) { if ($this->mUpload->isIniSizeOverflow()) { return array('status' => UploadBase::FILE_TOO_LARGE, 'max' => min(self::getMaxUploadSize($this->getSourceType()), wfShorthandToInteger(ini_get('upload_max_filesize')), wfShorthandToInteger(ini_get('post_max_size')))); } } return parent::verifyUpload(); }
public function run() { $scope = RequestContext::importScopedSession($this->params['session']); $context = RequestContext::getMain(); try { $user = $context->getUser(); if (!$user->isLoggedIn()) { $this->setLastError("Could not load the author user from session."); return false; } if (count($_SESSION) === 0) { // Empty session probably indicates that we didn't associate // with the session correctly. Note that being able to load // the user does not necessarily mean the session was loaded. // Most likely cause by suhosin.session.encrypt = On. $this->setLastError("Error associating with user session. " . "Try setting suhosin.session.encrypt = Off"); return false; } UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Poll', 'stage' => 'assembling', 'status' => Status::newGood())); $upload = new UploadFromChunks($user); $upload->continueChunks($this->params['filename'], $this->params['filekey'], $context->getRequest()); // Combine all of the chunks into a local file and upload that to a new stash file $status = $upload->concatenateChunks(); if (!$status->isGood()) { UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'assembling', 'status' => $status)); $this->setLastError($status->getWikiText()); return false; } // We have a new filekey for the fully concatenated file $newFileKey = $upload->getLocalFile()->getFileKey(); // Remove the old stash file row and first chunk file $upload->stash->removeFileNoAuth($this->params['filekey']); // Build the image info array while we have the local reference handy $apiMain = new ApiMain(); // dummy object (XXX) $imageInfo = $upload->getImageInfo($apiMain->getResult()); // Cleanup any temporary local file $upload->cleanupTempFile(); // Cache the info so the user doesn't have to wait forever to get the final info UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Success', 'stage' => 'assembling', 'filekey' => $newFileKey, 'imageinfo' => $imageInfo, 'status' => Status::newGood())); } catch (MWException $e) { UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'assembling', 'status' => Status::newFatal('api-error-stashfailed'))); $this->setLastError(get_class($e) . ": " . $e->getText()); // To be extra robust. MWExceptionHandler::rollbackMasterChangesAndLog($e); return false; } return true; }
/** * Initialize instance variables from request and create an Upload handler * * @param WebRequest $request The request to extract variables from */ protected function loadRequest($request) { global $wgUser, $wgMaxUploadFiles; // let's make the parent happy wfSuppressWarnings(); $_FILES['wpUploadFile'] = $_FILES['wpUploadFile0']; wfRestoreWarnings(); // Guess the desired name from the filename if not provided $this->mDesiredDestNames = array(); $this->mUploads = array(); // deal with session keys, if we have some pick the first one, for now $vals = $request->getValues(); $fromsession = false; foreach ($vals as $k => $v) { if (preg_match("@^wpSessionKey@", $k)) { $request->setVal('wpSessionKey', $v); $fromsession = true; $filenum = preg_replace("@wpSessionKey@", '', $k); $request->setVal('wpDestFile', $request->getVal('wpDestFile' . $filenum)); $up = UploadBase::createFromRequest($request); $this->mUploads[] = $up; $this->mDesiredDestNames[] = $request->getVal('wpDestFile' . $filenum); } } parent::loadRequest($request); $this->mUploadClicked = $request->wasPosted() && ($request->getCheck('wpUpload') || $request->getCheck('wpUploadIgnoreWarning')); if (!$fromsession) { for ($i = 0; $i < $wgMaxUploadFiles; $i++) { $this->mDesiredDestNames[$i] = $request->getText('wpDestFile' . $i); if (!$this->mDesiredDestNames[$i] && $request->getFileName('wpUploadFile' . $i) !== null) { $this->mDesiredDestNames[$i] = $request->getFileName('wpUploadFile' . $i); } wfSuppressWarnings(); $request->setVal('wpUploadFile', $_FILES['wpUploadFile' . $i]); wfRestoreWarnings(); $request->setVal('wpDestFile', $request->getVal('wpDestFile' . $i)); move_uploaded_file('wpUploadFile' . $i, 'wpUploadFile'); wfSuppressWarnings(); $_FILES['wpUploadFile'] = $_FILES['wpUploadFile' . $i]; wfRestoreWarnings(); $up = UploadBase::createFromRequest($request); if ($up) { $this->mUploads[] = $up; } } } $this->mDesiredDestName = $this->mDesiredDestNames[0]; $this->mUpload = $this->mUploads[0]; }
public function run() { $scope = RequestContext::importScopedSession($this->params['session']); $this->addTeardownCallback(function () use(&$scope) { ScopedCallback::consume($scope); // T126450 }); $context = RequestContext::getMain(); $user = $context->getUser(); try { if (!$user->isLoggedIn()) { $this->setLastError("Could not load the author user from session."); return false; } UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Poll', 'stage' => 'assembling', 'status' => Status::newGood()]); $upload = new UploadFromChunks($user); $upload->continueChunks($this->params['filename'], $this->params['filekey'], new WebRequestUpload($context->getRequest(), 'null')); // Combine all of the chunks into a local file and upload that to a new stash file $status = $upload->concatenateChunks(); if (!$status->isGood()) { UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Failure', 'stage' => 'assembling', 'status' => $status]); $this->setLastError($status->getWikiText(false, false, 'en')); return false; } // We can only get warnings like 'duplicate' after concatenating the chunks $status = Status::newGood(); $status->value = ['warnings' => $upload->checkWarnings()]; // We have a new filekey for the fully concatenated file $newFileKey = $upload->getStashFile()->getFileKey(); // Remove the old stash file row and first chunk file $upload->stash->removeFileNoAuth($this->params['filekey']); // Build the image info array while we have the local reference handy $apiMain = new ApiMain(); // dummy object (XXX) $imageInfo = $upload->getImageInfo($apiMain->getResult()); // Cleanup any temporary local file $upload->cleanupTempFile(); // Cache the info so the user doesn't have to wait forever to get the final info UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Success', 'stage' => 'assembling', 'filekey' => $newFileKey, 'imageinfo' => $imageInfo, 'status' => $status]); } catch (Exception $e) { UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Failure', 'stage' => 'assembling', 'status' => Status::newFatal('api-error-stashfailed')]); $this->setLastError(get_class($e) . ": " . $e->getMessage()); // To be extra robust. MWExceptionHandler::rollbackMasterChangesAndLog($e); return false; } return true; }
function loadFile($type) { global $wgRequest, $wgUser; $ext = $type; $file_name = "Drawio_" . $wgRequest->getVal('drawio') . "." . $ext; $wgRequest->setVal('wpDestFile', $file_name); $wgRequest->setVal('wpIgnoreWarning', '1'); $wgRequest->setVal('wpDestFileWarningAck', '1'); $wgRequest->setVal('wpUploadDescription', ""); $wgRequest->setVal('action', ""); if ($type == "png") { $file_type = "image/png"; $pngval = $wgRequest->getVal($type); $comma_pos = strpos($pngval, ','); if ($comma_pos === false) { $file_body = stripslashes($pngval); } else { $file_body = base64_decode(substr($pngval, $comma_pos + 1)); } } else { $file_type = "text/xml"; $file_body = $wgRequest->getVal($type); } $file_len = strlen($file_body); if ($file_len > 0) { $_FILES['wpUploadFile']['name'] = $file_name; $_FILES['wpUploadFile']['type'] = $file_type; $_FILES['wpUploadFile']['error'] = 0; $_FILES['wpUploadFile']['size'] = $file_len; // $tmp_name = $_SERVER["DOCUMENT_ROOT"] . "tmp/tmp_".rand(0,1000).rand(0,1000).".".$ext; $tmp_name = wfTempDir() . "tmp_" . rand(0, 1000) . rand(0, 1000) . "." . $ext; $f = fopen($tmp_name, "w"); fwrite($f, $file_body); fclose($f); $_FILES['wpUploadFile']['tmp_name'] = $tmp_name; // Upload $form = UploadBase::createFromRequest($wgRequest, null); $outcome = $form->verifyUpload(); $res = $form->performUpload("", "", true, $wgUser); if (file_exists($tmp_name)) { unlink($tmp_name); } } // $outcome['request'] = $wgRequest; // $outcome['form'] = $form; return $outcome; }
/** */ 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; list($partName, $extList) = UploadBase::splitExtensions($filename); if (UploadBase::checkFileExtensionList($extList, $wgFileBlacklist)) { return 'unknown/unknown'; } if ($wgCheckFileExtensions && $wgStrictFileExtensions && !UploadBase::checkFileExtensionList($extList, $wgFileExtensions)) { return 'unknown/unknown'; } if ($wgVerifyMimeType && in_array(strtolower($type), $wgMimeTypeBlacklist)) { return 'unknown/unknown'; } } return $type; }
public function run() { $scope = RequestContext::importScopedSession($this->params['session']); $context = RequestContext::getMain(); try { $user = $context->getUser(); if (!$user->isLoggedIn()) { $this->setLastError("Could not load the author user from session."); return false; } UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Poll', 'stage' => 'assembling', 'status' => Status::newGood())); $upload = new UploadFromChunks($user); $upload->continueChunks($this->params['filename'], $this->params['filekey'], $context->getRequest()); // Combine all of the chunks into a local file and upload that to a new stash file $status = $upload->concatenateChunks(); if (!$status->isGood()) { UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'assembling', 'status' => $status)); $this->setLastError($status->getWikiText()); return false; } // We have a new filekey for the fully concatenated file $newFileKey = $upload->getLocalFile()->getFileKey(); // Remove the old stash file row and first chunk file $upload->stash->removeFileNoAuth($this->params['filekey']); // Build the image info array while we have the local reference handy $apiMain = new ApiMain(); // dummy object (XXX) $imageInfo = $upload->getImageInfo($apiMain->getResult()); // Cleanup any temporary local file $upload->cleanupTempFile(); // Cache the info so the user doesn't have to wait forever to get the final info UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Success', 'stage' => 'assembling', 'filekey' => $newFileKey, 'imageinfo' => $imageInfo, 'status' => Status::newGood())); } catch (MWException $e) { UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'assembling', 'status' => Status::newFatal('api-error-stashfailed'))); $this->setLastError(get_class($e) . ": " . $e->getText()); return false; } return true; }
public function execute() { global $wgUser; // Check whether upload is enabled if ( !UploadBase::isEnabled() ) { $this->dieUsageMsg( array( 'uploaddisabled' ) ); } $this->mParams = $this->extractRequestParams(); $this->validateParams( $this->mParams ); $request = $this->getMain()->getRequest(); $this->mUpload = new ResumableUploadHandler; $status = $this->mUpload->initialize( $request->getVal( 'done', null ), $request->getVal( 'offset', null ), $request->getVal( 'filename', null ), $request->getVal( 'chunksession', null ), $request->getFileTempName( 'chunk' ), $request->getFileSize( 'chunk' ), $request->getSessionData( UploadBase::getSessionKeyname() ) ); if ( $status !== true ) { $this->dieUsage( $status, 'chunk-init-error' ); } $ret = $this->performUpload( ); if(is_array($ret)) { foreach($ret as $key => $val) { $this->getResult()->addValue(null, $key, $val); } } else { $this->dieUsage($ret, 'error'); } }
private function execute3rdPartyVideo($url) { if (empty(F::app()->wg->allowNonPremiumVideos)) { $this->dieUsage('Only premium videos are allowed', 'onlyallowpremium'); } if (!preg_match('/^https?:\\/\\//', $url)) { $url = 'http://' . $url; } try { $apiwrapper = ApiWrapperFactory::getInstance()->getApiWrapper($url); } catch (Exception $e) { $this->dieUsage('There was an issue with ApiWrapper', 'apiwrapper-error'); } if (empty($apiwrapper)) { $this->dieUsageMsg('The supplied video does not exist'); } $duplicate = $this->getVideoDuplicate($apiwrapper->getProvider(), $apiwrapper->getVideoId()); $result = array('provider' => $apiwrapper->getProvider(), 'videoId' => $apiwrapper->getVideoId()); if ($duplicate) { $result['title'] = $duplicate->getTitle()->getText(); $result['url'] = $duplicate->getUrl(); } else { // Check whether upload is enabled if (!UploadBase::isEnabled()) { $this->dieUsageMsg('uploaddisabled'); } F::app()->wg->DisableProxy = true; $this->mUpload = new UploadFromUrl(); $this->mUpload->initializeFromRequest(new FauxRequest(array('wpUpload' => 1, 'wpSourceType' => 'web', 'wpUploadFileURL' => $apiwrapper->getThumbnailUrl()), true)); $this->mUpload->fetchFile(); $this->checkPermissions(); $this->verifyUpload(); $tempFile = $this->createTempFile($this->mUpload->getTempPath()); $result['title'] = $apiwrapper->getTitle(); $result['tempUrl'] = $tempFile->getUrl(); $result['tempName'] = $tempFile->getName(); } return $result; }
function topLinks() { global $wgOut, $wgUser; $sep = " |\n"; $s = $this->mainPageLink() . $sep . $this->specialLink('Recentchanges'); if ($wgOut->isArticle()) { $s .= $sep . '<strong>' . $this->editThisPage() . '</strong>' . $sep . $this->historyLink(); } /* show links to different language variants */ $s .= $this->variantLinks(); $s .= $this->extensionTabLinks(); if ($wgUser->isAnon()) { $s .= $sep . $this->specialLink('Userlogin'); } else { /* show user page and user talk links */ $s .= $sep . $this->link($wgUser->getUserPage(), wfMsgHtml('mypage')); $s .= $sep . $this->link($wgUser->getTalkPage(), wfMsgHtml('mytalk')); if ($wgUser->getNewtalk()) { $s .= ' *'; } /* show watchlist link */ $s .= $sep . $this->specialLink('Watchlist'); /* show my contributions link */ $s .= $sep . $this->link(SpecialPage::getSafeTitleFor('Contributions', $wgUser->getName()), wfMsgHtml('mycontris')); /* show my preferences link */ $s .= $sep . $this->specialLink('Preferences'); /* show upload file link */ if (UploadBase::isEnabled() && UploadBase::isAllowed($wgUser) === true) { $s .= $sep . $this->getUploadLink(); } /* show log out link */ $s .= $sep . $this->specialLink('Userlogout'); } $s .= $sep . $this->specialPagesList(); return $s; }
/** * Get result information for an image revision * * @param File $file * @param array $prop Array of properties to get (in the keys) * @param ApiResult $result * @param array $thumbParams Containing 'width' and 'height' items, or null * @param array|bool|string $opts Options for data fetching. * This is an array consisting of the keys: * 'version': The metadata version for the metadata option * 'language': The language for extmetadata property * 'multilang': Return all translations in extmetadata property * 'revdelUser': User to use when checking whether to show revision-deleted fields. * @return array Result array */ static function getInfo($file, $prop, $result, $thumbParams = null, $opts = false) { global $wgContLang; $anyHidden = false; if (!$opts || is_string($opts)) { $opts = array('version' => $opts ?: 'latest', 'language' => $wgContLang, 'multilang' => false, 'extmetadatafilter' => array(), 'revdelUser' => null); } $version = $opts['version']; $vals = array(ApiResult::META_TYPE => 'assoc'); // Timestamp is shown even if the file is revdelete'd in interface // so do same here. if (isset($prop['timestamp'])) { $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $file->getTimestamp()); } // Handle external callers who don't pass revdelUser if (isset($opts['revdelUser']) && $opts['revdelUser']) { $revdelUser = $opts['revdelUser']; $canShowField = function ($field) use($file, $revdelUser) { return $file->userCan($field, $revdelUser); }; } else { $canShowField = function ($field) use($file) { return !$file->isDeleted($field); }; } $user = isset($prop['user']); $userid = isset($prop['userid']); if ($user || $userid) { if ($file->isDeleted(File::DELETED_USER)) { $vals['userhidden'] = true; $anyHidden = true; } if ($canShowField(File::DELETED_USER)) { if ($user) { $vals['user'] = $file->getUser(); } if ($userid) { $vals['userid'] = $file->getUser('id'); } if (!$file->getUser('id')) { $vals['anon'] = true; } } } // This is shown even if the file is revdelete'd in interface // so do same here. if (isset($prop['size']) || isset($prop['dimensions'])) { $vals['size'] = intval($file->getSize()); $vals['width'] = intval($file->getWidth()); $vals['height'] = intval($file->getHeight()); $pageCount = $file->pageCount(); if ($pageCount !== false) { $vals['pagecount'] = $pageCount; } // length as in how many seconds long a video is. $length = $file->getLength(); if ($length) { // Call it duration, because "length" can be ambiguous. $vals['duration'] = (double) $length; } } $pcomment = isset($prop['parsedcomment']); $comment = isset($prop['comment']); if ($pcomment || $comment) { if ($file->isDeleted(File::DELETED_COMMENT)) { $vals['commenthidden'] = true; $anyHidden = true; } if ($canShowField(File::DELETED_COMMENT)) { if ($pcomment) { $vals['parsedcomment'] = Linker::formatComment($file->getDescription(File::RAW), $file->getTitle()); } if ($comment) { $vals['comment'] = $file->getDescription(File::RAW); } } } $canonicaltitle = isset($prop['canonicaltitle']); $url = isset($prop['url']); $sha1 = isset($prop['sha1']); $meta = isset($prop['metadata']); $extmetadata = isset($prop['extmetadata']); $commonmeta = isset($prop['commonmetadata']); $mime = isset($prop['mime']); $mediatype = isset($prop['mediatype']); $archive = isset($prop['archivename']); $bitdepth = isset($prop['bitdepth']); $uploadwarning = isset($prop['uploadwarning']); if ($uploadwarning) { $vals['html'] = SpecialUpload::getExistsWarning(UploadBase::getExistsWarning($file)); } if ($file->isDeleted(File::DELETED_FILE)) { $vals['filehidden'] = true; $anyHidden = true; } if ($anyHidden && $file->isDeleted(File::DELETED_RESTRICTED)) { $vals['suppressed'] = true; } if (!$canShowField(File::DELETED_FILE)) { //Early return, tidier than indenting all following things one level return $vals; } if ($canonicaltitle) { $vals['canonicaltitle'] = $file->getTitle()->getPrefixedText(); } if ($url) { if (!is_null($thumbParams)) { $mto = $file->transform($thumbParams); self::$transformCount++; if ($mto && !$mto->isError()) { $vals['thumburl'] = wfExpandUrl($mto->getUrl(), PROTO_CURRENT); // bug 23834 - If the URL's are the same, we haven't resized it, so shouldn't give the wanted // thumbnail sizes for the thumbnail actual size if ($mto->getUrl() !== $file->getUrl()) { $vals['thumbwidth'] = intval($mto->getWidth()); $vals['thumbheight'] = intval($mto->getHeight()); } else { $vals['thumbwidth'] = intval($file->getWidth()); $vals['thumbheight'] = intval($file->getHeight()); } if (isset($prop['thumbmime']) && $file->getHandler()) { list(, $mime) = $file->getHandler()->getThumbType($mto->getExtension(), $file->getMimeType(), $thumbParams); $vals['thumbmime'] = $mime; } } elseif ($mto && $mto->isError()) { $vals['thumberror'] = $mto->toText(); } } $vals['url'] = wfExpandUrl($file->getFullURL(), PROTO_CURRENT); $vals['descriptionurl'] = wfExpandUrl($file->getDescriptionUrl(), PROTO_CURRENT); } if ($sha1) { $vals['sha1'] = wfBaseConvert($file->getSha1(), 36, 16, 40); } if ($meta) { wfSuppressWarnings(); $metadata = unserialize($file->getMetadata()); wfRestoreWarnings(); if ($metadata && $version !== 'latest') { $metadata = $file->convertMetadataVersion($metadata, $version); } $vals['metadata'] = $metadata ? self::processMetaData($metadata, $result) : null; } if ($commonmeta) { $metaArray = $file->getCommonMetaArray(); $vals['commonmetadata'] = $metaArray ? self::processMetaData($metaArray, $result) : array(); } if ($extmetadata) { // Note, this should return an array where all the keys // start with a letter, and all the values are strings. // Thus there should be no issue with format=xml. $format = new FormatMetadata(); $format->setSingleLanguage(!$opts['multilang']); $format->getContext()->setLanguage($opts['language']); $extmetaArray = $format->fetchExtendedMetadata($file); if ($opts['extmetadatafilter']) { $extmetaArray = array_intersect_key($extmetaArray, array_flip($opts['extmetadatafilter'])); } $vals['extmetadata'] = $extmetaArray; } if ($mime) { $vals['mime'] = $file->getMimeType(); } if ($mediatype) { $vals['mediatype'] = $file->getMediaType(); } if ($archive && $file->isOld()) { $vals['archivename'] = $file->getArchiveName(); } if ($bitdepth) { $vals['bitdepth'] = $file->getBitDepth(); } return $vals; }
/** * Add upload JS to the OutputPage */ protected function addUploadJS() { $config = $this->getConfig(); $useAjaxDestCheck = $config->get('UseAjax') && $config->get('AjaxUploadDestCheck'); $useAjaxLicensePreview = $config->get('UseAjax') && $config->get('AjaxLicensePreview') && $config->get('EnableAPI'); $this->mMaxUploadSize['*'] = UploadBase::getMaxUploadSize(); $scriptVars = array('wgAjaxUploadDestCheck' => $useAjaxDestCheck, 'wgAjaxLicensePreview' => $useAjaxLicensePreview, 'wgUploadAutoFill' => !$this->mForReUpload && $this->mDestFile === '', 'wgUploadSourceIds' => $this->mSourceIds, 'wgCheckFileExtensions' => $config->get('CheckFileExtensions'), 'wgStrictFileExtensions' => $config->get('StrictFileExtensions'), 'wgFileExtensions' => array_values(array_unique($config->get('FileExtensions'))), 'wgCapitalizeUploads' => MWNamespace::isCapitalized(NS_FILE), 'wgMaxUploadSize' => $this->mMaxUploadSize, 'wgFileCanRotate' => SpecialUpload::rotationEnabled()); $out = $this->getOutput(); $out->addJsConfigVars($scriptVars); $out->addModules(array('mediawiki.action.edit', 'mediawiki.special.upload')); }
/** * Add upload JS to the OutputPage */ protected function addUploadJS() { global $wgUseAjax, $wgAjaxUploadDestCheck, $wgAjaxLicensePreview, $wgEnableAPI, $wgStrictFileExtensions; $useAjaxDestCheck = $wgUseAjax && $wgAjaxUploadDestCheck; $useAjaxLicensePreview = $wgUseAjax && $wgAjaxLicensePreview && $wgEnableAPI; $this->mMaxUploadSize['*'] = UploadBase::getMaxUploadSize(); $scriptVars = array('wgAjaxUploadDestCheck' => $useAjaxDestCheck, 'wgAjaxLicensePreview' => $useAjaxLicensePreview, 'wgUploadAutoFill' => !$this->mForReUpload && $this->mDestFile === '', 'wgUploadSourceIds' => $this->mSourceIds, 'wgStrictFileExtensions' => $wgStrictFileExtensions, 'wgCapitalizeUploads' => MWNamespace::isCapitalized(NS_FILE), 'wgMaxUploadSize' => $this->mMaxUploadSize); $out = $this->getOutput(); $out->addJsConfigVars($scriptVars); $out->addModules(array('mediawiki.action.edit', 'mediawiki.legacy.upload', 'mediawiki.special.upload')); }
/** * Print out the various links at the bottom of the image page, e.g. reupload, * external editing (and instructions link) etc. */ protected function uploadLinksBox() { global $wgEnableUploads; if (!$wgEnableUploads) { return; } $this->loadFile(); if (!$this->mPage->getFile()->isLocal()) { return; } $out = $this->getContext()->getOutput(); $out->addHTML("<ul>\n"); # "Upload a new version of this file" link $canUpload = $this->getTitle()->userCan('upload', $this->getContext()->getUser()); if ($canUpload && UploadBase::userCanReUpload($this->getContext()->getUser(), $this->mPage->getFile()->name)) { $ulink = Linker::makeExternalLink($this->getUploadUrl(), wfMessage('uploadnewversion-linktext')->text()); $out->addHTML("<li id=\"mw-imagepage-reupload-link\"><div class=\"plainlinks\">{$ulink}</div></li>\n"); } else { $out->addHTML("<li id=\"mw-imagepage-upload-disallowed\">" . $this->getContext()->msg('upload-disallowed-here')->escaped() . "</li>\n"); } $out->addHTML("</ul>\n"); }
/** * @return string */ function topLinks() { $sep = " |\n"; $s = $this->getSkin()->mainPageLink() . $sep . Linker::specialLink('Recentchanges'); if ($this->data['isarticle']) { $s .= $sep . '<strong>' . $this->editThisPage() . '</strong>' . $sep . $this->talkLink() . $sep . $this->historyLink(); } /* show links to different language variants */ $s .= $this->variantLinks(); $s .= $this->extensionTabLinks(); if (!$this->data['loggedin']) { $s .= $sep . Linker::specialLink('Userlogin'); } else { /* show user page and user talk links */ $user = $this->getSkin()->getUser(); $s .= $sep . Linker::link($user->getUserPage(), wfMessage('mypage')->escaped()); $s .= $sep . Linker::link($user->getTalkPage(), wfMessage('mytalk')->escaped()); if ($user->getNewtalk()) { $s .= ' *'; } /* show watchlist link */ $s .= $sep . Linker::specialLink('Watchlist'); /* show my contributions link */ $s .= $sep . Linker::link(SpecialPage::getSafeTitleFor('Contributions', $this->data['username']), wfMessage('mycontris')->escaped()); /* show my preferences link */ $s .= $sep . Linker::specialLink('Preferences'); /* show upload file link */ if (UploadBase::isEnabled() && UploadBase::isAllowed($user) === true) { $s .= $sep . $this->getUploadLink(); } /* show log out link */ $s .= $sep . Linker::specialLink('Userlogout'); } $s .= $sep . $this->specialPagesList(); return $s; }
if ($wgMetaNamespace === false) { $wgMetaNamespace = str_replace(' ', '_', $wgSitename); } // Default value is 2000 or the suhosin limit if it is between 1 and 2000 if ($wgResourceLoaderMaxQueryLength === false) { $suhosinMaxValueLength = (int) ini_get('suhosin.get.max_value_length'); if ($suhosinMaxValueLength > 0 && $suhosinMaxValueLength < 2000) { $wgResourceLoaderMaxQueryLength = $suhosinMaxValueLength; } else { $wgResourceLoaderMaxQueryLength = 2000; } unset($suhosinMaxValueLength); } // Ensure the minimum chunk size is less than PHP upload limits or the maximum // upload size. $wgMinUploadChunkSize = min($wgMinUploadChunkSize, UploadBase::getMaxUploadSize('file'), UploadBase::getMaxPhpUploadSize(), (wfShorthandToInteger(ini_get('post_max_size') ?: ini_get('hhvm.server.max_post_size'), PHP_INT_MAX) ?: PHP_INT_MAX) - 1024); /** * Definitions of the NS_ constants are in Defines.php * @private */ $wgCanonicalNamespaceNames = [NS_MEDIA => 'Media', NS_SPECIAL => 'Special', NS_TALK => 'Talk', NS_USER => 'User', NS_USER_TALK => 'User_talk', NS_PROJECT => 'Project', NS_PROJECT_TALK => 'Project_talk', NS_FILE => 'File', NS_FILE_TALK => 'File_talk', NS_MEDIAWIKI => 'MediaWiki', NS_MEDIAWIKI_TALK => 'MediaWiki_talk', NS_TEMPLATE => 'Template', NS_TEMPLATE_TALK => 'Template_talk', NS_HELP => 'Help', NS_HELP_TALK => 'Help_talk', NS_CATEGORY => 'Category', NS_CATEGORY_TALK => 'Category_talk']; /// @todo UGLY UGLY if (is_array($wgExtraNamespaces)) { $wgCanonicalNamespaceNames = $wgCanonicalNamespaceNames + $wgExtraNamespaces; } // These are now the same, always // To determine the user language, use $wgLang->getCode() $wgContLanguageCode = $wgLanguageCode; // Easy to forget to falsify $wgDebugToolbar for static caches. // If file cache or CDN cache is on, just disable this (DWIMD). if ($wgUseFileCache || $wgUseSquid) {
public function getAllowedParams() { $params = ['filename' => [ApiBase::PARAM_TYPE => 'string'], 'comment' => [ApiBase::PARAM_DFLT => ''], 'tags' => [ApiBase::PARAM_TYPE => 'tags', ApiBase::PARAM_ISMULTI => true], 'text' => [ApiBase::PARAM_TYPE => 'text'], 'watch' => [ApiBase::PARAM_DFLT => false, ApiBase::PARAM_DEPRECATED => true], 'watchlist' => [ApiBase::PARAM_DFLT => 'preferences', ApiBase::PARAM_TYPE => ['watch', 'preferences', 'nochange']], 'ignorewarnings' => false, 'file' => [ApiBase::PARAM_TYPE => 'upload'], 'url' => null, 'filekey' => null, 'sessionkey' => [ApiBase::PARAM_DEPRECATED => true], 'stash' => false, 'filesize' => [ApiBase::PARAM_TYPE => 'integer', ApiBase::PARAM_MIN => 0, ApiBase::PARAM_MAX => UploadBase::getMaxUploadSize()], 'offset' => [ApiBase::PARAM_TYPE => 'integer', ApiBase::PARAM_MIN => 0], 'chunk' => [ApiBase::PARAM_TYPE => 'upload'], 'async' => false, 'checkstatus' => false]; return $params; }
/** * Print out the various links at the bottom of the image page, e.g. reupload, * external editing (and instructions link) etc. */ protected function uploadLinksBox() { global $wgUser, $wgOut, $wgEnableUploads, $wgUseExternalEditor; if (!$wgEnableUploads) { return; } $this->loadFile(); if (!$this->img->isLocal()) { return; } $sk = $wgUser->getSkin(); $wgOut->addHTML("<br /><ul>\n"); # "Upload a new version of this file" link if (UploadBase::userCanReUpload($wgUser, $this->img->name)) { $ulink = $sk->makeExternalLink($this->getUploadUrl(), wfMsg('uploadnewversion-linktext')); $wgOut->addHTML("<li id=\"mw-imagepage-reupload-link\"><div class=\"plainlinks\">{$ulink}</div></li>\n"); } # External editing link if ($wgUseExternalEditor) { $elink = $sk->link($this->mTitle, wfMsgHtml('edit-externally'), array(), array('action' => 'edit', 'externaledit' => 'true', 'mode' => 'file'), array('known', 'noclasses')); $wgOut->addHTML('<li id="mw-imagepage-edit-external">' . $elink . ' <small>' . wfMsgExt('edit-externally-help', array('parseinline')) . "</small></li>\n"); } $wgOut->addHTML("</ul>\n"); }