/**
  * @param AbstractRevision $revision Revision object
  * @param array $row Revision row
  * @param array $metadata;
  */
 public function onAfterInsert($revision, array $row, array $metadata)
 {
     global $wgRCFeeds;
     // No action on imported revisions
     if (isset($metadata['imported']) && $metadata['imported']) {
         return;
     }
     $action = $revision->getChangeType();
     $revisionId = $revision->getRevisionId()->getAlphadecimal();
     $timestamp = $revision->getRevisionId()->getTimestamp();
     /** @var Workflow $workflow */
     $workflow = $metadata['workflow'];
     $user = $revision->getUser();
     if (!$this->isAllowed($revision, $action)) {
         return;
     }
     $title = $this->getRcTitle($workflow, $revision->getChangeType());
     $attribs = array('rc_namespace' => $title->getNamespace(), 'rc_title' => $title->getDBkey(), 'rc_user' => $row['rev_user_id'], 'rc_user_text' => $this->usernames->get(wfWikiId(), $row['rev_user_id'], $row['rev_user_ip']), 'rc_type' => RC_FLOW, 'rc_source' => self::SRC_FLOW, 'rc_minor' => 0, 'rc_bot' => 0, 'rc_patrolled' => $user->isAllowed('autopatrol') ? 1 : 0, 'rc_old_len' => $revision->getPreviousContentLength(), 'rc_new_len' => $revision->getContentLength(), 'rc_this_oldid' => 0, 'rc_last_oldid' => 0, 'rc_log_type' => null, 'rc_params' => serialize(array('flow-workflow-change' => array('action' => $action, 'revision_type' => get_class($revision), 'revision' => $revisionId, 'workflow' => $workflow->getId()->getAlphadecimal()))), 'rc_cur_id' => 0, 'rc_comment' => '', 'rc_timestamp' => $timestamp, 'rc_deleted' => 0);
     $rc = $this->rcFactory->newFromRow((object) $attribs);
     $rc->save(true);
     // Insert into db
     $feeds = $wgRCFeeds;
     // Override the IRC formatter with our own formatter
     foreach (array_keys($feeds) as $name) {
         $feeds[$name]['original_formatter'] = $feeds[$name]['formatter'];
         $feeds[$name]['formatter'] = $this->ircFormatter;
     }
     // pre-load the irc formatter which will be triggered via hook
     $this->ircFormatter->associate($rc, array('revision' => $revision) + $metadata);
     // run the feeds/irc/etc external notifications
     $rc->notifyRCFeeds($feeds);
 }
 public function testPartialMissingAsFalse()
 {
     $query = $this->getMock('Flow\\Repository\\UserName\\UserNameQuery');
     $query->expects($this->once())->method('execute')->with('fakewiki', array(610, 408))->will($this->returnValue(array((object) array('user_id' => '408', 'user_name' => 'chuck'))));
     $batch = new UserNameBatch($query);
     $batch->add('fakewiki', 610);
     $batch->add('fakewiki', 408);
     $this->assertEquals(false, $batch->get('fakewiki', 610));
 }
 /**
  * Returns pretty-printed user links + user tool links for history and
  * RecentChanges pages.
  *
  * Moderation-aware.
  *
  * @param  AbstractRevision $revision        Revision to display
  * @return string                            HTML
  * @throws PermissionException
  */
 public function getUserLinks(AbstractRevision $revision)
 {
     if (!$revision->isModerated() && !$this->permissions->isAllowed($revision, 'history')) {
         throw new PermissionException('Insufficient permissions to see userlinks for rev_id = ' . $revision->getRevisionId()->getAlphadecimal());
     }
     // if this specific revision is moderated, its usertext can always be
     // displayed, since it will be the moderator user
     static $cache;
     $userid = $revision->getUserId();
     $userip = $revision->getUserIp();
     if (isset($cache[$userid][$userip])) {
         return $cache[$userid][$userip];
     }
     $username = $this->usernames->get(wfWikiId(), $userid, $userip);
     return $cache[$userid][$userip] = Linker::userLink($userid, $username) . Linker::userToolLinks($userid, $username);
 }
 /**
  * Mimic Echo parameter formatting
  *
  * @param string $param The requested i18n parameter
  * @param AbstractRevision|AbstractRevision[] $revision The revision or
  *  revisions to format or an array of revisions
  * @param UUID $workflowId The UUID of the workflow $revision belongs tow
  * @param IContextSource $ctx
  * @param FormatterRow|null $row
  * @return mixed A valid parameter for a core Message instance. These
  *  parameters will be used with Message::parse
  * @throws FlowException
  */
 public function processParam($param, $revision, UUID $workflowId, IContextSource $ctx, FormatterRow $row = null)
 {
     switch ($param) {
         case 'creator-text':
             if ($revision instanceof PostRevision) {
                 return $this->usernames->getFromTuple($revision->getCreatorTuple());
             } else {
                 return '';
             }
         case 'user-text':
             return $this->usernames->getFromTuple($revision->getUserTuple());
         case 'user-links':
             return Message::rawParam($this->templating->getUserLinks($revision));
         case 'summary':
             if (!$this->permissions->isAllowed($revision, 'view')) {
                 return '';
             }
             /*
              * Fetch in HTML; unparsed wikitext in summary is pointless.
              * Larger-scale wikis will likely also store content in html, so no
              * Parsoid roundtrip is needed then (and if it *is*, it'll already
              * be needed to render Flow discussions, so this is manageable)
              */
             $content = $this->templating->getContent($revision, 'fixed-html');
             // strip html tags and decode to plaintext
             $content = Utils::htmlToPlaintext($content, 140, $ctx->getLanguage());
             return Message::plaintextParam($content);
         case 'wikitext':
             if (!$this->permissions->isAllowed($revision, 'view')) {
                 return '';
             }
             $content = $this->templating->getContent($revision, 'wikitext');
             // This must be escaped and marked raw to prevent special chars in
             // content, like $1, from changing the i18n result
             return Message::plaintextParam($content);
             // This is potentially two networked round trips, much too expensive for
             // the rendering loop
         // This is potentially two networked round trips, much too expensive for
         // the rendering loop
         case 'prev-wikitext':
             if ($revision->isFirstRevision()) {
                 return '';
             }
             if ($row === null) {
                 $previousRevision = $revision->getCollection()->getPrevRevision($revision);
             } else {
                 $previousRevision = $row->previousRevision;
             }
             if (!$previousRevision) {
                 return '';
             }
             if (!$this->permissions->isAllowed($previousRevision, 'view')) {
                 return '';
             }
             $content = $this->templating->getContent($previousRevision, 'wikitext');
             return Message::plaintextParam($content);
         case 'workflow-url':
             return $this->urlGenerator->workflowLink(null, $workflowId)->getFullUrl();
         case 'post-url':
             if (!$revision instanceof PostRevision) {
                 throw new FlowException('Expected PostRevision but received' . get_class($revision));
             }
             return $this->urlGenerator->postLink(null, $workflowId, $revision->getPostId())->getFullUrl();
         case 'moderated-reason':
             // don-t parse wikitext in the moderation reason
             return Message::plaintextParam($revision->getModeratedReason());
         case 'topic-of-post':
             if (!$revision instanceof PostRevision) {
                 throw new FlowException('Expected PostRevision but received ' . get_class($revision));
             }
             $root = $revision->getRootPost();
             if (!$this->permissions->isAllowed($root, 'view')) {
                 return '';
             }
             $content = $this->templating->getContent($root, 'wikitext');
             return Message::plaintextParam($content);
         case 'post-of-summary':
             if (!$revision instanceof PostSummary) {
                 throw new FlowException('Expected PostSummary but received ' . get_class($revision));
             }
             /** @var PostRevision $post */
             $post = $revision->getCollection()->getPost()->getLastRevision();
             if (!$this->permissions->isAllowed($post, 'view')) {
                 return '';
             }
             if ($post->isTopicTitle()) {
                 return Message::plaintextParam($this->templating->getContent($post, 'wikitext'));
             } else {
                 return Message::rawParam($this->templating->getContent($post, 'fixed-html'));
             }
         case 'bundle-count':
             return Message::numParam(count($revision));
         default:
             wfWarn(__METHOD__ . ': Unknown formatter parameter: ' . $param);
             return '';
     }
 }