/** * @desc Uploads an image on a wki * * @static * @param string $imageUrl url address to original file * @param Object $oImageData an object with obligatory field "name" and optional fields: "comment", "description" * @param User | null $user optional User's class instance (the file will be "uploaded" by this user) * * @return array */ public static function uploadImageFromUrl($imageUrl, $oImageData, $user = null) { // disable recentchange hooks global $wgHooks; $wgHooks['RecentChange_save'] = array(); $wgHooks['RecentChange_beforeSave'] = array(); /* prepare temporary file */ $data = array('wpUpload' => 1, 'wpSourceType' => 'web', 'wpUploadFileURL' => $imageUrl); //validate of optional image data foreach (array(self::FILE_DATA_COMMENT_OPION_NAME, self::FILE_DATA_DESC_OPION_NAME) as $option) { if (!isset($oImageData->{$option})) { $oImageData->{$option} = $oImageData->name; } } $upload = F::build('UploadFromUrl'); /* @var $upload UploadFromUrl */ $upload->initializeFromRequest(F::build('FauxRequest', array($data, true))); $upload->fetchFile(); $upload->verifyUpload(); // create destination file $title = Title::newFromText($oImageData->name, NS_FILE); $file = F::build('WikiaLocalFile', array($title, RepoGroup::singleton()->getLocalRepo())); /* @var $file WikiaLocalFile */ /* real upload */ $result = $file->upload($upload->getTempPath(), $oImageData->comment, $oImageData->description, File::DELETE_SOURCE, false, false, $user); return array('status' => $result->ok, 'page_id' => $title->getArticleID(), 'errors' => $result->errors); }
/** * @return FileRepo */ function getRepo() { if (!isset($this->repo)) { $this->repo = RepoGroup::singleton()->getLocalRepo(); } return $this->repo; }
public function execute() { $repo = RepoGroup::singleton()->getLocalRepo(); $dbr = $repo->getSlaveDb(); // how far back should this look for files to delete? global $wgUploadStashMaxAge; $this->output("Getting list of files to clean up...\n"); $res = $dbr->select('uploadstash', 'us_key', 'us_timestamp < ' . $dbr->addQuotes($dbr->timestamp(time() - $wgUploadStashMaxAge)), __METHOD__); if (!is_object($res) || $res->numRows() == 0) { $this->output("No files to cleanup!\n"); // nothing to do. return; } // finish the read before starting writes. $keys = array(); foreach ($res as $row) { array_push($keys, $row->us_key); } $this->output('Removing ' . count($keys) . " file(s)...\n"); // this could be done some other, more direct/efficient way, but using // UploadStash's own methods means it's less likely to fall accidentally // out-of-date someday $stash = new UploadStash($repo); foreach ($keys as $key) { try { $stash->getFile($key, true); $stash->removeFileNoAuth($key); } catch (UploadStashBadPathException $ex) { $this->output("Failed removing stashed upload with key: {$key}\n"); } } }
public static function parserFunction($parser, $vid = null, $img = null) { global $wgTitle, $wgContLang; wfLoadExtensionMessages('WHVid'); if ($vid === null || $img === null) { return '<div class="errorbox">' . wfMsg('missing-params') . '</div>'; } $vid = htmlspecialchars($vid); $divId = "whvid-" . md5($vid . mt_rand(1, 1000)); $vidUrl = self::getVidUrl($vid); $imgTitle = Title::newFromURL($img, NS_IMAGE); $imgUrl = null; if ($imgTitle) { $imgFile = RepoGroup::singleton()->findFile($imgTitle); $smallImgUrl = ''; $largeImgUrl = ''; if ($imgFile) { $width = 550; $height = 309; $thumb = $imgFile->getThumbnail($width, $height); $largeImgUrl = wfGetPad($thumb->getUrl()); $width = 240; //$height = 135; $thumb = $imgFile->getThumbnail($width); $smallImgUrl = wfGetPad($thumb->getUrl()); } } return $parser->insertStripItem(wfMsgForContent('embed-html', $divId, $vidUrl, $largeImgUrl, $smallImgUrl)); }
public function execute() { $params = $this->extractRequestParams(); $modulePrefix = $this->getModulePrefix(); $prop = array_flip($params['prop']); $scale = $this->getScale($params); $result = $this->getResult(); if (!$params['filekey'] && !$params['sessionkey']) { $this->dieUsage("One of filekey or sessionkey must be supplied", 'nofilekey'); } // Alias sessionkey to filekey, but give an existing filekey precedence. if (!$params['filekey'] && $params['sessionkey']) { $params['filekey'] = $params['sessionkey']; } try { $stash = RepoGroup::singleton()->getLocalRepo()->getUploadStash($this->getUser()); foreach ($params['filekey'] as $filekey) { $file = $stash->getFile($filekey); $finalThumbParam = $this->mergeThumbParams($file, $scale, $params['urlparam']); $imageInfo = ApiQueryImageInfo::getInfo($file, $prop, $result, $finalThumbParam); $result->addValue(array('query', $this->getModuleName()), null, $imageInfo); $result->addIndexedTagName(array('query', $this->getModuleName()), $modulePrefix); } // @todo Update exception handling here to understand current getFile exceptions } catch (UploadStashFileNotFoundException $e) { $this->dieUsage("File not found: " . $e->getMessage(), "invalidsessiondata"); } catch (UploadStashBadPathException $e) { $this->dieUsage("Bad path: " . $e->getMessage(), "invalidsessiondata"); } }
public function getLocalFile() { if (is_null($this->mLocalFile)) { $this->mLocalFile = new FakeLocalFile(Title::newFromText('Temp_file_' . time() . '.jpg', NS_FILE), RepoGroup::singleton()->getLocalRepo()); } return $this->mLocalFile; }
public function execute() { global $wgCityId; $db = wfGetDB(DB_MASTER); (new WikiaSQL())->SELECT('*')->FROM('page')->WHERE('page_is_redirect')->EQUAL_TO(1)->runLoop($db, function ($a, $row) use($db) { $title = Title::newFromID($row->page_id); if (!$title->isDeleted()) { $rev = Revision::newFromTitle($title); $text = $rev->getText(); $rt = Title::newFromRedirectRecurse($text); if (!$rt) { // page is marked as redirect but $text is not valid redirect $this->output('Fixed ID: ' . $title->getArticleID() . ' Title: ' . $title->getText() . "\n"); // Fix page table (new WikiaSQL())->UPDATE('page')->SET('page_is_redirect', 0)->WHERE('page_id')->EQUAL_TO($row->page_id)->RUN($db); // remove redirect from redirect table (new WikiaSQL())->DELETE('redirect')->WHERE('rd_from')->EQUAL_TO($row->page_id)->RUN($db); // clear cache LinkCache::singleton()->addGoodLinkObj($row->page_id, $title, strlen($text), 0, $rev->getId()); if ($title->getNamespace() == NS_FILE) { RepoGroup::singleton()->getLocalRepo()->invalidateImageRedirect($title); } } } }); }
public function execute() { $pageIds = $this->getPageSet()->getAllTitlesByNamespace(); // Make sure we have files in the title set: if (!empty($pageIds[NS_FILE])) { $titles = array_keys($pageIds[NS_FILE]); asort($titles); // Ensure the order is always the same $result = $this->getResult(); $images = RepoGroup::singleton()->findFiles($titles); foreach ($images as $img) { // if its a "transcode" add the transcode status table output if (TimedMediaHandlerHooks::isTranscodableTitle($img->getTitle())) { $transcodeStatus = WebVideoTranscode::getTranscodeState($img->getTitle()->getDBKey()); // remove useless properties foreach ($transcodeStatus as $key => &$val) { unset($val['id']); unset($val['image_name']); unset($val['key']); } $result->addValue(array('query', 'pages', $img->getTitle()->getArticleID()), 'transcodestatus', $transcodeStatus); } } } }
public function execute() { $repo = RepoGroup::singleton()->getLocalRepo(); $dbr = $repo->getSlaveDb(); $this->output("Getting list of files to clean up...\n"); $res = $dbr->select('uploadstash', 'us_key', 'us_timestamp < ' . $dbr->timestamp(time() - UploadStash::REPO_AGE * 3600), __METHOD__); if (!is_object($res) || $res->numRows() == 0) { // nothing to do. return false; } // finish the read before starting writes. $keys = array(); foreach ($res as $row) { array_push($keys, $row->us_key); } $this->output('Removing ' . count($keys) . " file(s)...\n"); // this could be done some other, more direct/efficient way, but using // UploadStash's own methods means it's less likely to fall accidentally // out-of-date someday $stash = new UploadStash($repo); foreach ($keys as $key) { $stash->getFile($key, true); $stash->removeFileNoAuth($key); } }
function execute() { $subdir = $this->getOption('subdir', ''); $verbose = $this->hasOption('verbose'); $repo = RepoGroup::singleton()->getLocalRepo(); if ($repo->hasSha1Storage()) { $this->error("Local repo uses SHA-1 file storage names; aborting.", 1); } $directory = $repo->getZonePath('public'); if ($subdir != '') { $directory .= "/{$subdir}/"; } if ($verbose) { $this->output("Scanning files under {$directory}:\n"); } $list = $repo->getBackend()->getFileList(['dir' => $directory]); if ($list === null) { $this->error("Could not get file listing.", 1); } $pathBatch = []; foreach ($list as $path) { if (preg_match('#^(thumb|deleted)/#', $path)) { continue; // handle ugly nested containers on stock installs } $pathBatch[] = $path; if (count($pathBatch) >= $this->mBatchSize) { $this->checkFiles($repo, $pathBatch, $verbose); $pathBatch = []; } } $this->checkFiles($repo, $pathBatch, $verbose); }
private function setUpForeignRepo() { global $wgUploadDirectory; $this->setMwGlobals('wgForeignFileRepos', [['class' => 'ForeignAPIRepo', 'name' => 'wikimediacommons', 'backend' => 'wikimediacommons-backend', 'apibase' => 'https://commons.wikimedia.org/w/api.php', 'hashLevels' => 2, 'fetchDescription' => true, 'descriptionCacheExpiry' => 43200, 'apiThumbCacheExpiry' => 86400, 'directory' => $wgUploadDirectory]]); RepoGroup::destroySingleton(); FileBackendGroup::destroySingleton(); }
function filePath($name) { if (!isset($this->repo)) { $this->repo = RepoGroup::singleton()->getLocalRepo(); } return $this->repo->getRootDirectory() . '/' . $this->repo->getHashPath($name) . $name; }
function execute() { $lastName = $this->getOption('start', ''); $repo = RepoGroup::singleton()->getLocalRepo(); $dbr = $repo->getSlaveDB(); $be = $repo->getBackend(); $mtime1 = $dbr->timestampOrNull($this->getOption('mtimeafter', null)); $mtime2 = $dbr->timestampOrNull($this->getOption('mtimebefore', null)); $joinTables = array('image'); $joinConds = array('image' => array('INNER JOIN', 'img_name = page_title')); if ($mtime1 || $mtime2) { $joinTables[] = 'logging'; $on = array('log_page = page_id', 'log_type' => array('upload', 'move', 'delete')); if ($mtime1) { $on[] = "log_timestamp > {$dbr->addQuotes($mtime1)}"; } if ($mtime2) { $on[] = "log_timestamp < {$dbr->addQuotes($mtime2)}"; } $joinConds['logging'] = array('INNER JOIN', $on); } do { $res = $dbr->select(array_merge(array('page'), $joinTables), array('img_name' => 'DISTINCT(page_title)'), array('page_namespace' => NS_FILE, "page_title >= " . $dbr->addQuotes($lastName)), __METHOD__, array('ORDER BY' => 'page_title', 'LIMIT' => $this->mBatchSize), $joinConds); // Check if any of these files are missing... $pathsByName = array(); foreach ($res as $row) { $file = $repo->newFile($row->img_name); $pathsByName[$row->img_name] = $file->getPath(); $lastName = $row->img_name; } $be->preloadFileStat(array('srcs' => $pathsByName)); foreach ($pathsByName as $path) { if ($be->fileExists(array('src' => $path)) === false) { $this->output("{$path}\n"); } } // Find all missing old versions of any of the files in this batch... if (count($pathsByName)) { $ores = $dbr->select('oldimage', array('oi_name', 'oi_archive_name'), array('oi_name' => array_keys($pathsByName)), __METHOD__); $checkPaths = array(); foreach ($ores as $row) { if (!strlen($row->oi_archive_name)) { continue; // broken row } $file = $repo->newFromArchiveName($row->oi_name, $row->oi_archive_name); $checkPaths[] = $file->getPath(); } foreach (array_chunk($checkPaths, $this->mBatchSize) as $paths) { $be->preloadFileStat(array('srcs' => $paths)); foreach ($paths as $path) { if ($be->fileExists(array('src' => $path)) === false) { $this->output("{$path}\n"); } } } } } while ($res->numRows() >= $this->mBatchSize); }
public function getLocalFile() { if (is_null($this->mLocalFile)) { //TODO: find out what namespace constant 6 is $this->mLocalFile = new FakeLocalFile(Title::newFromText('Temp_file_' . time(), 6), RepoGroup::singleton()->getLocalRepo()); } return $this->mLocalFile; }
protected function getFileDuplicate($filepath) { $duplicates = RepoGroup::singleton()->findBySha1(FSFile::getSha1Base36FromPath($filepath)); if (count($duplicates) > 0) { return $duplicates[0]; } return null; }
/** * Get a FileCache instance. Typically, only one instance of FileCache * is needed in a MediaWiki invocation. */ static function singleton() { if (self::$instance) { return self::$instance; } self::$instance = new FileCache(RepoGroup::singleton()); return self::$instance; }
/** * add video * @param string $url * @return string error message or array( $videoTitle, $videoPageId, $videoProvider ) */ public function addVideo($url) { global $wgIsGhostVideo; wfProfileIn(__METHOD__); if (!$this->wg->User->isAllowed('videoupload')) { wfProfileOut(__METHOD__); return wfMessage('videos-error-admin-only')->plain(); } if (empty($url)) { wfProfileOut(__METHOD__); return wfMessage('videos-error-no-video-url')->text(); } $vHelper = new VideoHandlerHelper(); # @TODO Commenting out to fix MAIN-4436 -- Should be fixed correctly when content team is back # if ( !$vHelper->isVideoProviderSupported( $url ) ) { # wfProfileOut( __METHOD__ ); # return wfMessage( 'videos-error-provider-not-supported' )->parse(); # } try { // is it a WikiLink? $title = Title::newFromText($url, NS_FILE); if (!$title || !WikiaFileHelper::isFileTypeVideo($title)) { $title = Title::newFromText(str_replace(array('[[', ']]'), array('', ''), $url), NS_FILE); } if (!$title || !WikiaFileHelper::isFileTypeVideo($title)) { $file = $this->getVideoFileByUrl($url); if ($file) { $title = $file->getTitle(); } } if ($title && WikiaFileHelper::isFileTypeVideo($title)) { $videoTitle = $title; $videoPageId = $title->getArticleId(); $videoProvider = ''; wfRunHooks('AddPremiumVideo', array($title)); } else { if (empty($this->wg->allowNonPremiumVideos)) { wfProfileOut(__METHOD__); return wfMessage('videohandler-non-premium')->parse(); } list($videoTitle, $videoPageId, $videoProvider) = $this->addVideoVideoHandlers($url); $file = RepoGroup::singleton()->findFile($videoTitle); } if (!$file instanceof File) { WikiaLogger::instance()->error('\\VideoHandlerHelper->adDefaultVideoDescription() - File is empty', ['exception' => new Exception(), 'url' => $url, 'title' => $title, 'videoTitle' => $videoTitle, 'videoPageId' => $videoPageId, 'videoProvider' => $videoProvider, 'wgIsGhostVideo' => $wgIsGhostVideo]); wfProfileOut(__METHOD__); return wfMessage('videos-something-went-wrong')->parse(); } else { // Add a default description if available and one doesn't already exist $vHelper->addDefaultVideoDescription($file); } } catch (Exception $e) { wfProfileOut(__METHOD__); return $e->getMessage(); } wfProfileOut(__METHOD__); return array($videoTitle, $videoPageId, $videoProvider); }
protected function update_images_bug_28348($start = null) { $this->output("Correcting fi_img_timestamp column in flaggedimages\n"); $db = wfGetDB(DB_MASTER); if ($start === null) { $start = $db->selectField('flaggedimages', 'MIN(fi_rev_id)', false, __METHOD__); } $end = $db->selectField('flaggedimages', 'MAX(fi_rev_id)', false, __METHOD__); if (is_null($start) || is_null($end)) { $this->output("...flaggedimages table seems to be empty.\n"); return; } # Do remaining chunk $end += $this->mBatchSize - 1; $blockStart = $start; $blockEnd = $start + $this->mBatchSize - 1; $count = $changed = 0; while ($blockEnd <= $end) { $this->output("...doing fi_rev_id from {$blockStart} to {$blockEnd}\n"); $cond = "fi_rev_id BETWEEN {$blockStart} AND {$blockEnd} AND fi_img_timestamp IS NOT NULL" . " AND img_name IS NULL AND oi_name IS NULL"; // optimize $res = $db->select(array('flaggedimages', 'image', 'oldimage'), '*', $cond, __FUNCTION__, array(), array('image' => array('LEFT JOIN', 'img_sha1 = fi_img_sha1 AND img_timestamp = fi_img_timestamp'), 'oldimage' => array('LEFT JOIN', 'oi_sha1 = fi_img_sha1 AND oi_timestamp = fi_img_timestamp'))); $db->begin(); # Go through and clean up missing items, as well as correct fr_quality... foreach ($res as $row) { $count++; $fi_img_timestamp = trim($row->fi_img_timestamp); // clear pad garbage if (!$fi_img_timestamp) { continue; // nothing to check } $time = wfTimestamp(TS_MW, $fi_img_timestamp); $sha1 = $row->fi_img_sha1; # Check if the specified file exists... $file = RepoGroup::singleton()->findFileFromKey($sha1, array('time' => $time)); if (!$file) { // doesn't exist? $time = wfTimestamp(TS_MW, wfTimestamp(TS_UNIX, $time) + 1); # Check if the fi_img_timestamp value is off by 1 second... $file = RepoGroup::singleton()->findFileFromKey($sha1, array('time' => $time)); if ($file) { $this->output("fixed file {$row->fi_name} reference in rev ID {$row->fi_rev_id}\n"); # Fix the fi_img_timestamp value... $db->update('flaggedimages', array('fi_img_timestamp' => $db->timestamp($time)), array('fi_rev_id' => $row->fi_rev_id, 'fi_name' => $row->fi_name), __METHOD__); $changed++; } } } $db->commit(); $db->freeResult($res); $blockStart += $this->mBatchSize; $blockEnd += $this->mBatchSize; wfWaitForSlaves(5); } $this->output("fi_img_timestamp column fixes complete ... {$count} rows [{$changed} changed]\n"); }
/** * 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; }
protected function getInitialisedRepoGroup() { $repoGroup = RepoGroup::singleton(); if ( !$repoGroup->reposInitialised ) { $repoGroup->initialiseRepos(); } return $repoGroup; }
/** * Fulfil the request; shows the form or deletes the file, * pending authentication, confirmation, etc. */ public function execute() { global $wgOut, $wgRequest, $wgUser, $wgUploadMaintenance; $permissionErrors = $this->title->getUserPermissionsErrors('delete', $wgUser); if (count($permissionErrors)) { throw new PermissionsError('delete', $permissionErrors); } if (wfReadOnly()) { throw new ReadOnlyError(); } if ($wgUploadMaintenance) { throw new ErrorPageError('filedelete-maintenance-title', 'filedelete-maintenance'); } $this->setHeaders(); $this->oldimage = $wgRequest->getText('oldimage', false); $token = $wgRequest->getText('wpEditToken'); # Flag to hide all contents of the archived revisions $suppress = $wgRequest->getVal('wpSuppress') && $wgUser->isAllowed('suppressrevision'); if ($this->oldimage) { $this->oldfile = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName($this->title, $this->oldimage); } if (!self::haveDeletableFile($this->file, $this->oldfile, $this->oldimage)) { $wgOut->addHTML($this->prepareMessage('filedelete-nofile')); $wgOut->addReturnTo($this->title); return; } // Perform the deletion if appropriate if ($wgRequest->wasPosted() && $wgUser->matchEditToken($token, $this->oldimage)) { $deleteReasonList = $wgRequest->getText('wpDeleteReasonList'); $deleteReason = $wgRequest->getText('wpReason'); if ($deleteReasonList == 'other') { $reason = $deleteReason; } elseif ($deleteReason != '') { // Entry from drop down menu + additional comment $reason = $deleteReasonList . wfMessage('colon-separator')->inContentLanguage()->text() . $deleteReason; } else { $reason = $deleteReasonList; } $status = self::doDelete($this->title, $this->file, $this->oldimage, $reason, $suppress, $wgUser); if (!$status->isGood()) { $wgOut->addHTML('<h2>' . $this->prepareMessage('filedeleteerror-short') . "</h2>\n"); $wgOut->addWikiText('<div class="error">' . $status->getWikiText('filedeleteerror-short', 'filedeleteerror-long') . '</div>'); } if ($status->ok) { $wgOut->setPageTitle(wfMessage('actioncomplete')); $wgOut->addHTML($this->prepareMessage('filedelete-success')); // Return to the main page if we just deleted all versions of the // file, otherwise go back to the description page $wgOut->addReturnTo($this->oldimage ? $this->title : Title::newMainPage()); WatchAction::doWatchOrUnwatch($wgRequest->getCheck('wpWatch'), $this->title, $wgUser); } return; } $this->showForm(); $this->showLogEntries(); }
/** * Fulfil the request; shows the form or deletes the file, * pending authentication, confirmation, etc. */ public function execute() { global $wgOut, $wgRequest, $wgUser; $this->setHeaders(); if (wfReadOnly()) { $wgOut->readOnlyPage(); return; } $permission_errors = $this->title->getUserPermissionsErrors('delete', $wgUser); if (count($permission_errors) > 0) { $wgOut->showPermissionsErrorPage($permission_errors); return; } $this->oldimage = $wgRequest->getText('oldimage', false); $token = $wgRequest->getText('wpEditToken'); # Flag to hide all contents of the archived revisions $suppress = $wgRequest->getVal('wpSuppress') && $wgUser->isAllowed('suppressrevision'); if ($this->oldimage && !self::isValidOldSpec($this->oldimage)) { $wgOut->showUnexpectedValueError('oldimage', htmlspecialchars($this->oldimage)); return; } if ($this->oldimage) { $this->oldfile = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName($this->title, $this->oldimage); } if (!self::haveDeletableFile($this->file, $this->oldfile, $this->oldimage)) { $wgOut->addHTML($this->prepareMessage('filedelete-nofile')); $wgOut->addReturnTo($this->title); return; } // Perform the deletion if appropriate if ($wgRequest->wasPosted() && $wgUser->matchEditToken($token, $this->oldimage)) { $this->DeleteReasonList = $wgRequest->getText('wpDeleteReasonList'); $this->DeleteReason = $wgRequest->getText('wpReason'); $reason = $this->DeleteReasonList; if ($reason != 'other' && $this->DeleteReason != '') { // Entry from drop down menu + additional comment $reason .= wfMsgForContent('colon-separator') . $this->DeleteReason; } elseif ($reason == 'other') { $reason = $this->DeleteReason; } $status = self::doDelete($this->title, $this->file, $this->oldimage, $reason, $suppress); if (!$status->isGood()) { $wgOut->addWikiText($status->getWikiText('filedeleteerror-short', 'filedeleteerror-long')); } if ($status->ok) { $wgOut->setPagetitle(wfMsg('actioncomplete')); $wgOut->addHTML($this->prepareMessage('filedelete-success')); // Return to the main page if we just deleted all versions of the // file, otherwise go back to the description page $wgOut->addReturnTo($this->oldimage ? $this->title : Title::newMainPage()); } return; } $this->showForm(); $this->showLogEntries(); }
public function execute() { if (!$this->hasOption('delete')) { $this->output("Use --delete to actually confirm this script\n"); return; } # Data should come off the master, wrapped in a transaction $dbw = $this->getDB(DB_MASTER); $dbw->begin(__METHOD__); $repo = RepoGroup::singleton()->getLocalRepo(); # Get "active" revisions from the filearchive table $this->output("Searching for and deleting archived files...\n"); $res = $dbw->select('filearchive', array('fa_id', 'fa_storage_group', 'fa_storage_key', 'fa_sha1'), '', __METHOD__); $count = 0; foreach ($res as $row) { $key = $row->fa_storage_key; if (!strlen($key)) { $this->output("Entry with ID {$row->fa_id} has empty key, skipping\n"); continue; } $group = $row->fa_storage_group; $id = $row->fa_id; $path = $repo->getZonePath('deleted') . '/' . $repo->getDeletedHashPath($key) . $key; if (isset($row->fa_sha1)) { $sha1 = $row->fa_sha1; } else { // old row, populate from key $sha1 = LocalRepo::getHashFromKey($key); } // Check if the file is used anywhere... $inuse = $dbw->selectField('oldimage', '1', array('oi_sha1' => $sha1, $dbw->bitAnd('oi_deleted', File::DELETED_FILE) => File::DELETED_FILE), __METHOD__, array('FOR UPDATE')); $needForce = true; if (!$repo->fileExists($path)) { $this->output("Notice - file '{$key}' not found in group '{$group}'\n"); } elseif ($inuse) { $this->output("Notice - file '{$key}' is still in use\n"); } elseif (!$repo->quickPurge($path)) { $this->output("Unable to remove file {$path}, skipping\n"); continue; // don't delete even with --force } else { $needForce = false; } if ($needForce) { if ($this->hasOption('force')) { $this->output("Got --force, deleting DB entry\n"); } else { continue; } } $count++; $dbw->delete('filearchive', array('fa_id' => $id), __METHOD__); } $dbw->commit(__METHOD__); $this->output("Done! [{$count} file(s)]\n"); }
public function execute() { global $wgUploadStashMaxAge; $repo = RepoGroup::singleton()->getLocalRepo(); $dbr = $repo->getSlaveDb(); // how far back should this look for files to delete? $cutoff = time() - $wgUploadStashMaxAge; $this->output("Getting list of files to clean up...\n"); $res = $dbr->select('uploadstash', 'us_key', 'us_timestamp < ' . $dbr->addQuotes($dbr->timestamp($cutoff)), __METHOD__); if (!is_object($res) || $res->numRows() == 0) { $this->output("No files to cleanup!\n"); // nothing to do. return; } // finish the read before starting writes. $keys = array(); foreach ($res as $row) { array_push($keys, $row->us_key); } $this->output('Removing ' . count($keys) . " file(s)...\n"); // this could be done some other, more direct/efficient way, but using // UploadStash's own methods means it's less likely to fall accidentally // out-of-date someday $stash = new UploadStash($repo); $i = 0; foreach ($keys as $key) { $i++; try { $stash->getFile($key, true); $stash->removeFileNoAuth($key); } catch (UploadStashBadPathException $ex) { $this->output("Failed removing stashed upload with key: {$key}\n"); } catch (UploadStashZeroLengthFileException $ex) { $this->output("Failed removing stashed upload with key: {$key}\n"); } if ($i % 100 == 0) { $this->output("{$i}\n"); } } $this->output("{$i} done\n"); $tempRepo = $repo->getTempRepo(); $dir = $tempRepo->getZonePath('thumb'); $iterator = $tempRepo->getBackend()->getFileList(array('dir' => $dir)); $this->output("Deleting old thumbnails...\n"); $i = 0; foreach ($iterator as $file) { $i++; if (wfTimestamp(TS_UNIX, $tempRepo->getFileTimestamp("{$dir}/{$file}")) < $cutoff) { $tempRepo->quickPurge("{$dir}/{$file}"); } if ($i % 100 == 0) { $this->output("{$i}\n"); } } $this->output("{$i} done\n"); }
/** * Helper function -- given a file on the filesystem, find matching * content in the db (and associated articles) and remove them. * * @param string $filePath Path to file on the filesystem * * @return bool */ public function deleteFileByContent($filePath) { $hash = FSFile::getSha1Base36FromPath($filePath); $dupes = RepoGroup::singleton()->findBySha1($hash); $success = true; foreach ($dupes as $dupe) { $success &= $this->deleteFileByTitle($dupe->getTitle()); } return $success; }
/** * @param string $provider Ex: youtube * @param string $videoId Video id from provider * @return array */ private function execute3rdPartyVideo($provider, $videoId) { $tempVideo = new WikiaLocalFile(Title::newFromText(uniqid('Temp_', true), NS_FILE), RepoGroup::singleton()->getLocalRepo()); // forceMime makes sure the correct file properties are set and sent to the handler when afterSetProps is called $tempVideo->forceMime('video/' . $provider); $tempVideo->setVideoId($videoId); $tempVideo->afterSetProps(); $options = ['autoplay' => true, 'isAjax' => true]; return array('embedCode' => json_encode($tempVideo->getEmbedCode(self::EMBED_WIDTH, $options))); }
public function tearDown() { foreach ($this->savedGlobals as $var => $val) { $GLOBALS[$var] = $val; } // Restore backends RepoGroup::destroySingleton(); FileBackendGroup::destroySingleton(); $this->teardownUploadDir($this->uploadDir); }
protected function tearDown() { foreach ($this->savedGlobals as $var => $val) { $GLOBALS[$var] = $val; } // Restore backends RepoGroup::destroySingleton(); FileBackendGroup::destroySingleton(); parent::tearDown(); }
public function __construct($request = null) { global $wgRequest; parent::__construct('UploadStash', 'upload'); try { $this->stash = RepoGroup::singleton()->getLocalRepo()->getUploadStash(); } catch (UploadStashNotAvailableException $e) { return null; } $this->loadRequest(is_null($request) ? $wgRequest : $request); }
public function testBug29408() { $this->setMwGlobals('wgUser', self::$users['uploader']->user); $repo = RepoGroup::singleton()->getLocalRepo(); $stash = new UploadStash($repo); // Throws exception caught by PHPUnit on failure $file = $stash->stashFile($this->bug29408File); // We'll never reach this point if we hit bug 29408 $this->assertTrue(true, 'Unrecognized file without extension'); $stash->removeFile($file->getFileKey()); }