private function createFeedItem($row) { global $wgOut; $thread = Thread::newFromRow($row); $linker = new Linker(); $titleStr = $thread->subject(); $completeText = $thread->root()->getContent(); $completeText = $wgOut->parse($completeText); $threadTitle = clone $thread->topmostThread()->title(); $threadTitle->setFragment('#' . $thread->getAnchorName()); $titleUrl = $threadTitle->getFullURL(); $timestamp = $thread->created(); $user = $thread->author()->getName(); // Grab the title for the superthread, if one exists. $stTitle = null; if ($thread->hasSuperThread()) { $stTitle = clone $thread->topmostThread()->title(); $stTitle->setFragment('#' . $thread->superthread()->getAnchorName()); } // Prefix content with a quick description $userLink = $linker->userLink($thread->author()->getId(), $user); $talkpageLink = $linker->link($thread->getTitle()); $superthreadLink = $linker->link($stTitle); $description = wfMsgExt($thread->hasSuperThread() ? 'lqt-feed-reply-intro' : 'lqt-feed-new-thread-intro', array('parse', 'replaceafter'), array($talkpageLink, $userLink, $superthreadLink)); $completeText = $description . $completeText; return new FeedItem($titleStr, $completeText, $titleUrl, $timestamp, $user); }
private function createFeedItem($row) { $thread = Thread::newFromRow($row); $titleStr = $thread->subject(); $completeText = $thread->root()->getContent(); $completeText = $this->getOutput()->parse($completeText); $threadTitle = clone $thread->topmostThread()->title(); $threadTitle->setFragment('#' . $thread->getAnchorName()); $titleUrl = $threadTitle->getFullURL(); $timestamp = $thread->created(); $user = $thread->author()->getName(); // Prefix content with a quick description $userLink = Linker::userLink($thread->author()->getId(), $user); $talkpageLink = Linker::link($thread->getTitle()); if ($thread->hasSuperThread()) { $stTitle = clone $thread->topmostThread()->title(); $stTitle->setFragment('#' . $thread->superthread()->getAnchorName()); $superthreadLink = Linker::link($stTitle); $description = wfMessage('lqt-feed-reply-intro')->rawParams($talkpageLink, $userLink, $superthreadLink)->params($user)->parseAsBlock(); } else { // Third param is unused $description = wfMessage('lqt-feed-new-thread-intro')->rawParams($talkpageLink, $userLink, '')->params($user)->parseAsBlock(); } $completeText = $description . $completeText; return new FeedItem($titleStr, $completeText, $titleUrl, $timestamp, $user); }
static function loadFromResult($res, $db, $bulkLoad = false) { $rows = array(); $threads = array(); foreach ($res as $row) { $rows[] = $row; if (!$bulkLoad) { $threads[$row->thread_id] = Thread::newFromRow($row); } } if (!$bulkLoad) { return $threads; } return Thread::bulkLoad($rows); }
static function bulkLoad($rows) { // Preload subthreads $top_thread_ids = array(); $all_thread_rows = $rows; $pageIds = array(); $linkBatch = new LinkBatch(); $userIds = array(); $loadEditorsFor = array(); $dbr = wfGetDB(DB_SLAVE); if (!is_array(self::$replyCacheById)) { self::$replyCacheById = array(); } // Build a list of threads for which to pull replies, and page IDs to pull data for. // Also, pre-initialise the reply cache. foreach ($rows as $row) { if ($row->thread_ancestor) { $top_thread_ids[] = $row->thread_ancestor; } else { $top_thread_ids[] = $row->thread_id; } // Grab page data while we're here. if ($row->thread_root) { $pageIds[] = $row->thread_root; } if ($row->thread_summary_page) { $pageIds[] = $row->thread_summary_page; } if (!isset(self::$replyCacheById[$row->thread_id])) { self::$replyCacheById[$row->thread_id] = array(); } } $all_thread_ids = $top_thread_ids; // Pull replies to the threads provided, and as above, pull page IDs to pull data for, // pre-initialise the reply cache, and stash the row object for later use. if (count($top_thread_ids)) { $res = $dbr->select('thread', '*', array('thread_ancestor' => $top_thread_ids, 'thread_type != ' . $dbr->addQuotes(Threads::TYPE_DELETED)), __METHOD__); foreach ($res as $row) { // Grab page data while we're here. if ($row->thread_root) { $pageIds[] = $row->thread_root; } if ($row->thread_summary_page) { $pageIds[] = $row->thread_summary_page; } $all_thread_rows[] = $row; $all_thread_ids[$row->thread_id] = $row->thread_id; } } // Pull thread reactions if (count($all_thread_ids)) { $res = $dbr->select('thread_reaction', '*', array('tr_thread' => $all_thread_ids), __METHOD__); foreach ($res as $row) { $thread_id = $row->tr_thread; $user = $row->tr_user_text; $info = array('type' => $row->tr_type, 'user-id' => $row->tr_user, 'user-name' => $row->tr_user_text, 'value' => $row->tr_value); $type = $info['type']; $user = $info['user-name']; if (!isset(self::$reactionCacheById[$thread_id])) { self::$reactionCacheById[$thread_id] = array(); } if (!isset(self::$reactionCacheById[$thread_id][$type])) { self::$reactionCacheById[$thread_id][$type] = array(); } self::$reactionCacheById[$thread_id][$type][$user] = $info; } } // Preload page data (restrictions, and preload Article object with everything from // the page table. Also, precache the title and article objects for pulling later. $articlesById = array(); if (count($pageIds)) { // Pull restriction info. Needs to come first because otherwise it's done per // page by loadPageData. $restrictionRows = array_fill_keys($pageIds, array()); $res = $dbr->select('page_restrictions', '*', array('pr_page' => $pageIds), __METHOD__); foreach ($res as $row) { $restrictionRows[$row->pr_page][] = $row; } $res = $dbr->select('page', '*', array('page_id' => $pageIds), __METHOD__); foreach ($res as $row) { $t = Title::newFromRow($row); if (isset($restrictionRows[$t->getArticleId()])) { $t->loadRestrictionsFromRows($restrictionRows[$t->getArticleId()], $row->page_restrictions); } $article = new Article($t); $article->loadPageData($row); self::$titleCacheById[$t->getArticleId()] = $t; $articlesById[$article->getId()] = $article; if (count(self::$titleCacheById) > 10000) { self::$titleCacheById = array(); } } } // For every thread we have a row object for, load a Thread object, add the user and // user talk pages to a link batch, cache the relevant user id/name pair, and // populate the reply cache. foreach ($all_thread_rows as $row) { $thread = Thread::newFromRow($row, null); if (isset($articlesById[$thread->rootId])) { $thread->root = $articlesById[$thread->rootId]; } // User cache data $t = Title::makeTitleSafe(NS_USER, $row->thread_author_name); $linkBatch->addObj($t); $t = Title::makeTitleSafe(NS_USER_TALK, $row->thread_author_name); $linkBatch->addObj($t); User::$idCacheByName[$row->thread_author_name] = $row->thread_author_id; $userIds[$row->thread_author_id] = true; if ($row->thread_editedness > Threads::EDITED_BY_AUTHOR) { $loadEditorsFor[$row->thread_root] = $thread; $thread->setEditors(array()); } } // Pull list of users who have edited if (count($loadEditorsFor)) { $res = $dbr->select('revision', array('rev_user_text', 'rev_page'), array('rev_page' => array_keys($loadEditorsFor), 'rev_parent_id != ' . $dbr->addQuotes(0)), __METHOD__); foreach ($res as $row) { $pageid = $row->rev_page; $editor = $row->rev_user_text; $t = $loadEditorsFor[$pageid]; $t->addEditor($editor); } } // Pull link batch data. $linkBatch->execute(); $threads = array(); // Fill and return an array with the threads that were actually requested. foreach ($rows as $row) { $threads[$row->thread_id] = Threads::$cache_by_id[$row->thread_id]; } return $threads; }
protected function renderThread($row, $params, &$entry) { // Set up OutputPage $out = $this->getOutput(); $oldOutputText = $out->getHTML(); $out->clearHTML(); // Setup $thread = Thread::newFromRow($row); $article = $thread->root(); if (!$article) { return; } $title = $article->getTitle(); $user = $this->getUser(); $request = $this->getRequest(); $view = new LqtView($out, $article, $title, $user, $request); // Parameters $view->threadNestingLevel = $params['renderlevel']; $renderpos = $params['renderthreadpos']; $rendercount = $params['renderthreadcount']; $options = array(); if (isset($params['rendermaxthreadcount'])) { $options['maxCount'] = $params['rendermaxthreadcount']; } if (isset($params['rendermaxdepth'])) { $options['maxDepth'] = $params['rendermaxdepth']; } if (isset($params['renderstartrepliesat'])) { $options['startAt'] = $params['renderstartrepliesat']; } $view->showThread($thread, $renderpos, $rendercount, $options); $result = $out->getHTML(); $out->clearHTML(); $out->addHTML($oldOutputText); $entry['content'] = $result; }
static function dumpThreadData($writer, &$out, $row, $title) { // Is it a thread if (empty($row->thread_id) || $row->thread_type >= 2) { return true; } $thread = Thread::newFromRow($row); $threadInfo = "\n"; $attribs = array(); $attribs['ThreadSubject'] = $thread->subject(); if ($thread->hasSuperThread()) { if ($thread->superThread()->title()) { $attribs['ThreadParent'] = $thread->superThread()->title()->getPrefixedText(); } if ($thread->topmostThread()->title()) { $attribs['ThreadAncestor'] = $thread->topmostThread()->title()->getPrefixedText(); } } $attribs['ThreadPage'] = $thread->getTitle()->getPrefixedText(); $attribs['ThreadID'] = $thread->id(); if ($thread->hasSummary() && $thread->summary()) { $attribs['ThreadSummaryPage'] = $thread->summary()->getTitle()->getPrefixedText(); } $attribs['ThreadAuthor'] = $thread->author()->getName(); $attribs['ThreadEditStatus'] = self::$editedStati[$thread->editedness()]; $attribs['ThreadType'] = self::$threadTypes[$thread->type()]; $attribs['ThreadSignature'] = $thread->signature(); foreach ($attribs as $key => $value) { $threadInfo .= "\t" . Xml::element($key, null, $value) . "\n"; } $out .= UtfNormal::cleanUp(Xml::tags('DiscussionThreading', null, $threadInfo) . "\n"); return true; }