예제 #1
0
 /**
  * Gets the user provided comment
  * @return string HTML
  */
 public function getComment()
 {
     if ($this->canView(LogPage::DELETED_COMMENT)) {
         $comment = Linker::commentBlock($this->entry->getComment());
         // No hard coded spaces thanx
         $element = ltrim($comment);
         if ($this->entry->isDeleted(LogPage::DELETED_COMMENT)) {
             $element = $this->styleRestricedElement($element);
         }
     } else {
         $element = $this->getRestrictedElement('rev-deleted-comment');
     }
     return $element;
 }
예제 #2
0
 /**
  * Get the array of parameters, converted from legacy format if necessary.
  * @since 1.25
  * @return array
  */
 protected function getParametersForApi()
 {
     return $this->entry->getParameters();
 }
예제 #3
0
파일: LocalFile.php 프로젝트: paladox/2
 /**
  * Record a file upload in the upload log and the image table
  * @param string $oldver
  * @param string $comment
  * @param string $pageText
  * @param bool|array $props
  * @param string|bool $timestamp
  * @param null|User $user
  * @param string[] $tags
  * @return bool
  */
 function recordUpload2($oldver, $comment, $pageText, $props = false, $timestamp = false, $user = null, $tags = array())
 {
     if (is_null($user)) {
         global $wgUser;
         $user = $wgUser;
     }
     $dbw = $this->repo->getMasterDB();
     # Imports or such might force a certain timestamp; otherwise we generate
     # it and can fudge it slightly to keep (name,timestamp) unique on re-upload.
     if ($timestamp === false) {
         $timestamp = $dbw->timestamp();
         $allowTimeKludge = true;
     } else {
         $allowTimeKludge = false;
     }
     $props = $props ?: $this->repo->getFileProps($this->getVirtualUrl());
     $props['description'] = $comment;
     $props['user'] = $user->getId();
     $props['user_text'] = $user->getName();
     $props['timestamp'] = wfTimestamp(TS_MW, $timestamp);
     // DB -> TS_MW
     $this->setProps($props);
     # Fail now if the file isn't there
     if (!$this->fileExists) {
         wfDebug(__METHOD__ . ": File " . $this->getRel() . " went missing!\n");
         return false;
     }
     $dbw->startAtomic(__METHOD__);
     # Test to see if the row exists using INSERT IGNORE
     # This avoids race conditions by locking the row until the commit, and also
     # doesn't deadlock. SELECT FOR UPDATE causes a deadlock for every race condition.
     $dbw->insert('image', array('img_name' => $this->getName(), 'img_size' => $this->size, 'img_width' => intval($this->width), 'img_height' => intval($this->height), 'img_bits' => $this->bits, 'img_media_type' => $this->media_type, 'img_major_mime' => $this->major_mime, 'img_minor_mime' => $this->minor_mime, 'img_timestamp' => $timestamp, 'img_description' => $comment, 'img_user' => $user->getId(), 'img_user_text' => $user->getName(), 'img_metadata' => $dbw->encodeBlob($this->metadata), 'img_sha1' => $this->sha1), __METHOD__, 'IGNORE');
     $reupload = $dbw->affectedRows() == 0;
     if ($reupload) {
         if ($allowTimeKludge) {
             # Use LOCK IN SHARE MODE to ignore any transaction snapshotting
             $ltimestamp = $dbw->selectField('image', 'img_timestamp', array('img_name' => $this->getName()), __METHOD__, array('LOCK IN SHARE MODE'));
             $lUnixtime = $ltimestamp ? wfTimestamp(TS_UNIX, $ltimestamp) : false;
             # Avoid a timestamp that is not newer than the last version
             # TODO: the image/oldimage tables should be like page/revision with an ID field
             if ($lUnixtime && wfTimestamp(TS_UNIX, $timestamp) <= $lUnixtime) {
                 sleep(1);
                 // fast enough re-uploads would go far in the future otherwise
                 $timestamp = $dbw->timestamp($lUnixtime + 1);
                 $this->timestamp = wfTimestamp(TS_MW, $timestamp);
                 // DB -> TS_MW
             }
         }
         # (bug 34993) Note: $oldver can be empty here, if the previous
         # version of the file was broken. Allow registration of the new
         # version to continue anyway, because that's better than having
         # an image that's not fixable by user operations.
         # Collision, this is an update of a file
         # Insert previous contents into oldimage
         $dbw->insertSelect('oldimage', 'image', array('oi_name' => 'img_name', 'oi_archive_name' => $dbw->addQuotes($oldver), 'oi_size' => 'img_size', 'oi_width' => 'img_width', 'oi_height' => 'img_height', 'oi_bits' => 'img_bits', 'oi_timestamp' => 'img_timestamp', 'oi_description' => 'img_description', 'oi_user' => 'img_user', 'oi_user_text' => 'img_user_text', 'oi_metadata' => 'img_metadata', 'oi_media_type' => 'img_media_type', 'oi_major_mime' => 'img_major_mime', 'oi_minor_mime' => 'img_minor_mime', 'oi_sha1' => 'img_sha1'), array('img_name' => $this->getName()), __METHOD__);
         # Update the current image row
         $dbw->update('image', array('img_size' => $this->size, 'img_width' => intval($this->width), 'img_height' => intval($this->height), 'img_bits' => $this->bits, 'img_media_type' => $this->media_type, 'img_major_mime' => $this->major_mime, 'img_minor_mime' => $this->minor_mime, 'img_timestamp' => $timestamp, 'img_description' => $comment, 'img_user' => $user->getId(), 'img_user_text' => $user->getName(), 'img_metadata' => $dbw->encodeBlob($this->metadata), 'img_sha1' => $this->sha1), array('img_name' => $this->getName()), __METHOD__);
     }
     $descTitle = $this->getTitle();
     $descId = $descTitle->getArticleID();
     $wikiPage = new WikiFilePage($descTitle);
     $wikiPage->setFile($this);
     // Add the log entry...
     $logEntry = new ManualLogEntry('upload', $reupload ? 'overwrite' : 'upload');
     $logEntry->setTimestamp($this->timestamp);
     $logEntry->setPerformer($user);
     $logEntry->setComment($comment);
     $logEntry->setTarget($descTitle);
     // Allow people using the api to associate log entries with the upload.
     // Log has a timestamp, but sometimes different from upload timestamp.
     $logEntry->setParameters(array('img_sha1' => $this->sha1, 'img_timestamp' => $timestamp));
     // Note we keep $logId around since during new image
     // creation, page doesn't exist yet, so log_page = 0
     // but we want it to point to the page we're making,
     // so we later modify the log entry.
     // For a similar reason, we avoid making an RC entry
     // now and wait until the page exists.
     $logId = $logEntry->insert();
     if ($descTitle->exists()) {
         // Use own context to get the action text in content language
         $formatter = LogFormatter::newFromEntry($logEntry);
         $formatter->setContext(RequestContext::newExtraneousContext($descTitle));
         $editSummary = $formatter->getPlainActionText();
         $nullRevision = Revision::newNullRevision($dbw, $descId, $editSummary, false, $user);
         if ($nullRevision) {
             $nullRevision->insertOn($dbw);
             Hooks::run('NewRevisionFromEditComplete', array($wikiPage, $nullRevision, $nullRevision->getParentId(), $user));
             $wikiPage->updateRevisionOn($dbw, $nullRevision);
             // Associate null revision id
             $logEntry->setAssociatedRevId($nullRevision->getId());
         }
         $newPageContent = null;
     } else {
         // Make the description page and RC log entry post-commit
         $newPageContent = ContentHandler::makeContent($pageText, $descTitle);
     }
     # Defer purges, page creation, and link updates in case they error out.
     # The most important thing is that files and the DB registry stay synced.
     $dbw->endAtomic(__METHOD__);
     # Do some cache purges after final commit so that:
     # a) Changes are more likely to be seen post-purge
     # b) They won't cause rollback of the log publish/update above
     $that = $this;
     $dbw->onTransactionIdle(function () use($that, $reupload, $wikiPage, $newPageContent, $comment, $user, $logEntry, $logId, $descId, $tags) {
         # Update memcache after the commit
         $that->invalidateCache();
         $updateLogPage = false;
         if ($newPageContent) {
             # New file page; create the description page.
             # There's already a log entry, so don't make a second RC entry
             # CDN and file cache for the description page are purged by doEditContent.
             $status = $wikiPage->doEditContent($newPageContent, $comment, EDIT_NEW | EDIT_SUPPRESS_RC, false, $user);
             if (isset($status->value['revision'])) {
                 // Associate new page revision id
                 $logEntry->setAssociatedRevId($status->value['revision']->getId());
             }
             // This relies on the resetArticleID() call in WikiPage::insertOn(),
             // which is triggered on $descTitle by doEditContent() above.
             if (isset($status->value['revision'])) {
                 /** @var $rev Revision */
                 $rev = $status->value['revision'];
                 $updateLogPage = $rev->getPage();
             }
         } else {
             # Existing file page: invalidate description page cache
             $wikiPage->getTitle()->invalidateCache();
             $wikiPage->getTitle()->purgeSquid();
             # Allow the new file version to be patrolled from the page footer
             Article::purgePatrolFooterCache($descId);
         }
         # Update associated rev id. This should be done by $logEntry->insert() earlier,
         # but setAssociatedRevId() wasn't called at that point yet...
         $logParams = $logEntry->getParameters();
         $logParams['associated_rev_id'] = $logEntry->getAssociatedRevId();
         $update = array('log_params' => LogEntryBase::makeParamBlob($logParams));
         if ($updateLogPage) {
             # Also log page, in case where we just created it above
             $update['log_page'] = $updateLogPage;
         }
         $that->getRepo()->getMasterDB()->update('logging', $update, array('log_id' => $logId), __METHOD__);
         $that->getRepo()->getMasterDB()->insert('log_search', array('ls_field' => 'associated_rev_id', 'ls_value' => $logEntry->getAssociatedRevId(), 'ls_log_id' => $logId), __METHOD__);
         # Now that the log entry is up-to-date, make an RC entry.
         $recentChange = $logEntry->publish($logId);
         if ($tags) {
             ChangeTags::addTags($tags, $recentChange ? $recentChange->getAttribute('rc_id') : null, $logEntry->getAssociatedRevId(), $logId);
         }
         # Run hook for other updates (typically more cache purging)
         Hooks::run('FileUpload', array($that, $reupload, !$newPageContent));
         if ($reupload) {
             # Delete old thumbnails
             $that->purgeThumbnails();
             # Remove the old file from the CDN cache
             DeferredUpdates::addUpdate(new CdnCacheUpdate(array($that->getUrl())), DeferredUpdates::PRESEND);
         } else {
             # Update backlink pages pointing to this title if created
             LinksUpdate::queueRecursiveJobsForTable($that->getTitle(), 'imagelinks');
         }
     });
     if (!$reupload) {
         # This is a new file, so update the image count
         DeferredUpdates::addUpdate(SiteStatsUpdate::factory(array('images' => 1)));
     }
     # Invalidate cache for all pages using this file
     DeferredUpdates::addUpdate(new HTMLCacheUpdate($this->getTitle(), 'imagelinks'));
     return true;
 }
예제 #4
0
 /**
  * Get a RecentChanges object for the log entry
  * @param int $newId
  * @return RecentChange
  * @since 1.23
  */
 public function getRecentChange($newId = 0)
 {
     $formatter = LogFormatter::newFromEntry($this);
     $context = RequestContext::newExtraneousContext($this->getTarget());
     $formatter->setContext($context);
     $logpage = SpecialPage::getTitleFor('Log', $this->getType());
     $user = $this->getPerformer();
     $ip = "";
     if ($user->isAnon()) {
         /*
          * "MediaWiki default" and friends may have
          * no IP address in their name
          */
         if (IP::isIPAddress($user->getName())) {
             $ip = $user->getName();
         }
     }
     return RecentChange::newLogEntry($this->getTimestamp(), $logpage, $user, $formatter->getPlainActionText(), $ip, $this->getType(), $this->getSubtype(), $this->getTarget(), $this->getComment(), LogEntryBase::makeParamBlob($this->getParameters()), $newId, $formatter->getIRCActionComment());
 }
예제 #5
0
 protected function expandDatabaseRow($data, $legacy)
 {
     return ['log_type' => $data['type'], 'log_action' => $data['action'], 'log_timestamp' => isset($data['timestamp']) ? $data['timestamp'] : wfTimestampNow(), 'log_user' => isset($data['user']) ? $data['user'] : 0, 'log_user_text' => isset($data['user_text']) ? $data['user_text'] : 'User', 'log_namespace' => isset($data['namespace']) ? $data['namespace'] : NS_MAIN, 'log_title' => isset($data['title']) ? $data['title'] : 'Main_Page', 'log_page' => isset($data['page']) ? $data['page'] : 0, 'log_comment' => isset($data['comment']) ? $data['comment'] : '', 'log_params' => $legacy ? LogPage::makeParamBlob($data['params']) : LogEntryBase::makeParamBlob($data['params']), 'log_deleted' => isset($data['deleted']) ? $data['deleted'] : 0];
 }