/**
  * @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);
 }
Example #2
0
 /**
  * @return FileRepo
  */
 function getRepo()
 {
     if (!isset($this->repo)) {
         $this->repo = RepoGroup::singleton()->getLocalRepo();
     }
     return $this->repo;
 }
Example #3
0
 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");
         }
     }
 }
Example #4
0
 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;
 }
Example #7
0
 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);
 }
Example #11
0
 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;
 }
Example #13
0
 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;
 }
Example #15
0
 protected function getFileDuplicate($filepath)
 {
     $duplicates = RepoGroup::singleton()->findBySha1(FSFile::getSha1Base36FromPath($filepath));
     if (count($duplicates) > 0) {
         return $duplicates[0];
     }
     return null;
 }
Example #16
0
 /**
  * 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;
 }
Example #17
0
 /**
  * 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);
 }
Example #18
0
 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;
	}
Example #21
0
 /**
  * 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();
 }
Example #22
0
 /**
  * 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;
 }
Example #26
0
 /**
  * @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();
 }
Example #29
0
 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);
 }
Example #30
0
 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());
 }