r97232 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r97231‎ | r97232 | r97233 >
Date:05:28, 16 September 2011
Author:werdna
Status:deferred (Comments)
Tags:
Comment:
Add some misisng svn add-s
Modified paths:
  • /branches/lqt-updates/extensions/LiquidThreads/LiquidThreads.php (modified) (history)
  • /branches/lqt-updates/extensions/LiquidThreads/classes/model/Object.php (modified) (history)
  • /branches/lqt-updates/extensions/LiquidThreads/classes/view/ChannelView.php (added) (history)
  • /branches/lqt-updates/extensions/LiquidThreads/classes/view/ReplyForm.php (added) (history)

Diff [purge]

Index: branches/lqt-updates/extensions/LiquidThreads/LiquidThreads.php
@@ -246,6 +246,9 @@
247247 $wgAutoloadClasses['ApiLqtForm'] = $dir.'/api/ApiLqtForm.php';
248248 $wgAPIModules['lqtform'] = 'ApiLqtForm';
249249
 250+$wgAutoloadClasses['ApiLqtFormatter'] = $dir.'/api/ApiLqtFormatter.php';
 251+$wgAPIModules['lqtformat'] = 'ApiLqtFormatter';
 252+
250253 // // Path to the LQT directory
251254 // $wgLiquidThreadsExtensionPath = "{$wgScriptPath}/extensions/LiquidThreads";
252255
Index: branches/lqt-updates/extensions/LiquidThreads/classes/model/Object.php
@@ -58,4 +58,23 @@
5959 * @return String
6060 */
6161 abstract public function getUniqueIdentifier();
 62+
 63+ /**
 64+ * Retrieves an object by unique identifier
 65+ * @param $id String: Unique identifier returned by getUniqueIdentifier()
 66+ * @return LiquidThreadsObject
 67+ */
 68+ public static function retrieve($id) {
 69+ static $classes = array(
 70+ 'lqt-post' => 'LiquidThreadsPost',
 71+ 'lqt-topic' => 'LiquidThreadsTopic',
 72+ 'lqt-channel' => 'LiquidThreadsChannel',
 73+ );
 74+
 75+ list($type, $id) = explode('_', $id);
 76+
 77+ $class = $classes[$type];
 78+
 79+ return $class::newFromID( $id );
 80+ }
6281 }
Index: branches/lqt-updates/extensions/LiquidThreads/classes/view/ReplyForm.php
@@ -0,0 +1,61 @@
 2+<?php
 3+
 4+/**
 5+ * Form for posting a new reply to a topic
 6+ */
 7+class LiquidThreadsReplyForm extends LiquidThreadsEditForm {
 8+
 9+ protected $topic;
 10+
 11+ /**
 12+ * Initialises a LiquidThreadsNewTopicForm.
 13+ * @param $user The user viewing this form.
 14+ * @param $topic The topic to reply to
 15+ * @param $replyPost The post to reply to, or NULL
 16+ */
 17+ public function __construct( $user, $topic, $replyPost = null ) {
 18+ parent::__construct( $user );
 19+
 20+ if ( ! $topic instanceof LiquidThreadsTopic ) {
 21+ throw new MWException( "Invalid argument to ".__METHOD__ );
 22+ }
 23+ $this->topic = $topic;
 24+ $this->replyPost = $replyPost;
 25+ }
 26+
 27+ /**
 28+ * Gets the HTML for the form fields, excluding buttons.
 29+ */
 30+ protected function getFormFieldsHTML() {
 31+ $html = '';
 32+
 33+ $html .= $this->getTextbox('lqt-edit-content');
 34+ $html .= $this->getSignatureEditor( LqtView::getUserSignature($this->user) );
 35+
 36+ return $html;
 37+ }
 38+
 39+ public function submit( $request = null ) {
 40+ $text = $request->getVal('lqt-edit-content');
 41+ $sig = $request->getVal('lqt-signature');
 42+
 43+ // Now add the first post
 44+ $post = LiquidThreadsPost::create( $this->topic, $this->replyPost );
 45+ $post->getPendingVersion()->setEditor( $this->user );
 46+ $post->getPendingVersion()->setPoster( $this->user );
 47+ $post->setText( $text );
 48+ $post->setSignature( $sig );
 49+
 50+ $post->save();
 51+
 52+ return true;
 53+ }
 54+
 55+ public function validate( $request = null ) {
 56+ if ( ! $request->getVal( 'lqt-edit-content' ) ) {
 57+ return false;
 58+ }
 59+
 60+ return true;
 61+ }
 62+}
Index: branches/lqt-updates/extensions/LiquidThreads/classes/view/ChannelView.php
@@ -0,0 +1,385 @@
 2+<?php
 3+
 4+class LiquidThreadsChannelView extends LQTView {
 5+ protected $channel;
 6+ protected $mShowItems = array( 'options', 'toc' );
 7+ protected $baseUrl;
 8+
 9+ /**
 10+ * Default constructor
 11+ * @param $channel The LiquidThreadsChannel to show.
 12+ */
 13+ function __construct( $channel ) {
 14+ $this->channel = $channel;
 15+
 16+ // Assume we want to go to the current title.
 17+ global $wgTitle, $wgRequest;
 18+ $query = array();
 19+ $copyQueryElements = array(
 20+ 'limit',
 21+ 'offset',
 22+ 'dir',
 23+ 'order',
 24+ 'sort',
 25+ 'asc',
 26+ 'desc'
 27+ );
 28+
 29+ foreach( $copyQueryElements as $name ) {
 30+ if ( $wgRequest->getCheck('name') ) {
 31+ $query[$name] = $wgRequest->getVal($name);
 32+ }
 33+ }
 34+
 35+ $this->baseUrl = $wgTitle->getFullURL( $query );
 36+ }
 37+
 38+ /**
 39+ * Shows this view.
 40+ * @param $action Any action to take
 41+ */
 42+ function show( $action = null ) {
 43+ // Temporarily disabled
 44+// // Expose feed links.
 45+// global $wgFeedClasses;
 46+// $apiParams = array( 'action' => 'feedthreads', 'type' => 'replies|newthreads',
 47+// 'talkpage' => $this->title->getPrefixedText() );
 48+// $urlPrefix = wfScript( 'api' ) . '?';
 49+// foreach ( $wgFeedClasses as $format => $class ) {
 50+// $theseParams = $apiParams + array( 'feedformat' => $format );
 51+// $url = $urlPrefix . wfArrayToCGI( $theseParams );
 52+// $this->output->addFeedLink( $format, $url );
 53+// }
 54+
 55+ $html = '';
 56+
 57+ // Set up a per-page header for new threads, search box, and sorting stuff.
 58+
 59+ $talkpageHeader = '';
 60+
 61+ if ( /*Thread::canUserPost( $this->user, $this->article )*/ true ) {
 62+ $newThreadText = wfMsgExt( 'lqt_new_thread', 'parseinline' );
 63+ $query = array(
 64+ 'lqt_action' => 'new-topic',
 65+ 'lqt_target' => $this->channel->getUniqueIdentifier()
 66+ );
 67+
 68+ $newThreadUrl = wfAppendQuery( $this->getBaseUrl(), $query );
 69+
 70+ $newThreadLink = Html::rawElement(
 71+ 'a',
 72+ array(
 73+ 'lqt_channel' => $this->channel->getID(),
 74+ 'href' => $newThreadUrl,
 75+ ),
 76+ $newThreadText
 77+ );
 78+
 79+ $newThreadLink = Xml::tags(
 80+ 'strong',
 81+ array( 'class' => 'lqt_start_discussion' ),
 82+ $newThreadLink
 83+ );
 84+
 85+ $talkpageHeader .= $newThreadLink;
 86+ }
 87+
 88+ $talkpageHeader = Xml::tags(
 89+ 'div',
 90+ array( 'class' => 'lqt-talkpage-header' ),
 91+ $talkpageHeader
 92+ );
 93+
 94+ if ( $this->shouldShow('options') ) {
 95+ $html .= $talkpageHeader;
 96+ } elseif ( $this->shouldShow('simplenew') ) {
 97+ $html .= $newThreadLink;
 98+ }
 99+
 100+ if ( count($action) > 0 && $action[0] == 'new-topic' ) {
 101+ global $wgUser, $wgRequest;
 102+ $form = new LiquidThreadsNewTopicForm( $wgUser, $this->channel );
 103+ $formOutput = $form->show( $wgRequest );
 104+
 105+ if ( $formOutput !== true ) {
 106+ $html .= $formOutput;
 107+ } else {
 108+ $this->refresh();
 109+ return false;
 110+ }
 111+ }
 112+
 113+ $pager = $this->getPager();
 114+
 115+ $topics = array();
 116+ foreach( $pager->getRows() as $row ) {
 117+ $topics[$row->lqt_id] = LiquidThreadsTopic::newFromRow( $row );
 118+ }
 119+
 120+ if ( count( $topics ) > 0 && $this->shouldShow('toc') ) {
 121+ $html .= $this->getTOC( $topics );
 122+ } elseif ( count($topics) == 0 ) {
 123+ $html .= Xml::tags( 'div', array( 'class' => 'lqt-no-threads' ),
 124+ wfMsgExt( 'lqt-no-threads', 'parseinline' ) );
 125+ }
 126+
 127+ $html .= $pager->getNavigationBar();
 128+ $html .= Xml::openElement( 'div',
 129+ array(
 130+ 'class' => 'lqt-threads lqt-talkpage-threads',
 131+ 'id' => $this->channel->getUniqueIdentifier(),
 132+ ) );
 133+
 134+ $formatter = LiquidThreadsTopicFormatter::singleton();
 135+ $context = new LiquidThreadsTopicFormatterContext;
 136+ $doneReply = false;
 137+ $replyPost = -1;
 138+ $context->set( 'action', $action );
 139+ $context->set( 'base-url', $this->getBaseUrl() );
 140+
 141+ foreach ( $topics as $topic ) {
 142+ $html .= $formatter->getHTML( $topic, $context );
 143+ }
 144+
 145+ $html .= Xml::closeElement( 'div' ) . $pager->getNavigationBar();
 146+
 147+ global $wgOut;
 148+ $wgOut->addModules( 'ext.liquidThreads' );
 149+ $wgOut->addHTML( $html );
 150+
 151+ return false;
 152+ }
 153+
 154+ function refresh() {
 155+ global $wgOut;
 156+ $wgOut->redirect( $this->channel->getTitle()->getFullURL() );
 157+ }
 158+
 159+ function getTOC( $topics ) {
 160+ global $wgLang;
 161+
 162+ $html = '';
 163+
 164+ $h2_header = Xml::tags( 'h2', null, wfMsgExt( 'lqt_contents_title', 'parseinline' ) );
 165+
 166+ // Header row
 167+ $headerRow = '';
 168+ $headers = array( 'lqt_toc_thread_title',
 169+ 'lqt_toc_thread_replycount', 'lqt_toc_thread_modified' );
 170+ foreach ( $headers as $msg ) {
 171+ $headerRow .= Xml::tags( 'th', null, wfMsgExt( $msg, 'parseinline' ) );
 172+ }
 173+ $headerRow = Xml::tags( 'tr', null, $headerRow );
 174+ $headerRow = Xml::tags( 'thead', null, $headerRow );
 175+
 176+ // Table body
 177+ $rows = array();
 178+ foreach ( $topics as $topic ) {
 179+ $row = '';
 180+ $anchor = '#' . LiquidThreadsFormatter::getAnchor($topic);
 181+ $subject = Xml::element( 'a', array( 'href' => $anchor ),
 182+ $topic->getSubject() );
 183+ $row .= Xml::tags( 'td', null, $subject );
 184+
 185+ $replyCount = $wgLang->formatNum( $topic->getPostCount() );
 186+ $row .= Xml::element( 'td', null, $replyCount ); // TODO
 187+
 188+// $timestamp = 'timestamp';
 189+ $timestamp = $wgLang->timeanddate( $topic->getTouchedTime(), true );
 190+ $row .= Xml::element( 'td', null, $timestamp );
 191+
 192+ $row = Xml::tags( 'tr', null, $row );
 193+ $rows[] = $row;
 194+ }
 195+
 196+ $html .= $headerRow . "\n" . Xml::tags( 'tbody', null, implode( "\n", $rows ) );
 197+ $html = $h2_header . Xml::tags( 'table', array( 'class' => 'lqt_toc' ), $html );
 198+ // wrap our output in a div for containment
 199+ $html = Xml::tags( 'div', array( 'class' => 'lqt-contents-wrapper' ), $html );
 200+
 201+ return $html;
 202+ }
 203+
 204+ function getList( $kind, $class, $id, $contents ) {
 205+ $html = '';
 206+ foreach ( $contents as $li ) {
 207+ $html .= Xml::tags( 'li', null, $li );
 208+ }
 209+ $html = Xml::tags( $kind, array( 'class' => $class, 'id' => $id ), $html );
 210+
 211+ return $html;
 212+ }
 213+
 214+ function getPager() {
 215+ return new LiquidThreadsChannelPager( $this->channel );
 216+ }
 217+
 218+ // Hide a number of items from the view
 219+ // Valid values: toc, options, header
 220+ function hideItems( $items ) {
 221+ $this->mShowItems = array_diff( $this->mShowItems, (array)$items );
 222+ }
 223+
 224+ // Show a number of items in the view
 225+ // Valid values: toc, options, header
 226+ function showItems( $items ) {
 227+ $this->mShowItems = array_merge( $this->mShowItems, (array)$items );
 228+ }
 229+
 230+ // Whether or not to show an item
 231+ function shouldShow( $item ) {
 232+ return in_array( $item, $this->mShowItems );
 233+ }
 234+
 235+ // Set the items shown
 236+ function setShownItems( $items ) {
 237+ $this->mShowItems = $items;
 238+ }
 239+
 240+ /**
 241+ * Gets the base URL to return to this specific page.
 242+ */
 243+ public function getBaseURL() {
 244+ return $this->baseUrl;
 245+ }
 246+
 247+ /**
 248+ * Sets the base URL to return to this specific page.
 249+ */
 250+ public function setBaseURL( $baseUrl ) {
 251+ $this->baseUrl = $baseUrl;
 252+ }
 253+}
 254+
 255+class LiquidThreadsChannelPager extends IndexPager {
 256+ function __construct( $channel ) {
 257+ $this->channel = $channel;
 258+
 259+ parent::__construct();
 260+
 261+ $this->mLimit = $this->getPageLimit();
 262+ }
 263+
 264+ function getPageLimit() {
 265+ global $wgRequest;
 266+ $requestedLimit = $wgRequest->getVal( 'limit', null );
 267+ if ( $requestedLimit ) {
 268+ return $requestedLimit;
 269+ }
 270+
 271+ global $wgLiquidThreadsDefaultPageLimit;
 272+ return $wgLiquidThreadsDefaultPageLimit;
 273+ }
 274+
 275+ function getQueryInfo() {
 276+ $queryInfo = array(
 277+ 'tables' => array( 'lqt_topic', 'lqt_topic_version' ),
 278+ 'fields' => '*',
 279+ 'conds' => array(
 280+ 'lqt_channel' => $this->channel->getID(),
 281+ ),
 282+ 'join_conds' => array(
 283+ 'lqt_topic_version' => array( 'left join',
 284+ array( 'lqt_current_version=ltv_id' ) ),
 285+ ),
 286+ );
 287+
 288+ return $queryInfo;
 289+ }
 290+
 291+ // Adapted from getBody().
 292+ function getRows() {
 293+ if ( !$this->mQueryDone ) {
 294+ $this->doQuery();
 295+ }
 296+
 297+ # Don't use any extra rows returned by the query
 298+ $numRows = min( $this->mResult->numRows(), $this->mLimit );
 299+
 300+ $rows = array();
 301+
 302+ if ( $numRows ) {
 303+ if ( $this->mIsBackwards ) {
 304+ for ( $i = $numRows - 1; $i >= 0; $i-- ) {
 305+ $this->mResult->seek( $i );
 306+ $row = $this->mResult->fetchObject();
 307+ $rows[] = $row;
 308+ }
 309+ } else {
 310+ $this->mResult->seek( 0 );
 311+ for ( $i = 0; $i < $numRows; $i++ ) {
 312+ $row = $this->mResult->fetchObject();
 313+ $rows[] = $row;
 314+ }
 315+ }
 316+ }
 317+
 318+ return $rows;
 319+ }
 320+
 321+ function formatRow( $row ) {
 322+ // No-op, we get the list of rows from getRows()
 323+ }
 324+
 325+ function getIndexField() {
 326+ return 'lqt_touched';
 327+ }
 328+
 329+ function getDefaultDirections() {
 330+ return true; // Descending
 331+ }
 332+
 333+ /**
 334+ * A navigation bar with images
 335+ * Stolen from TablePager because it's pretty.
 336+ */
 337+ function getNavigationBar() {
 338+ global $wgStylePath, $wgContLang;
 339+
 340+ if ( method_exists( $this, 'isNavigationBarShown' ) &&
 341+ !$this->isNavigationBarShown() )
 342+ return '';
 343+
 344+ $path = "$wgStylePath/common/images";
 345+ $labels = array(
 346+ 'first' => 'table_pager_first',
 347+ 'prev' => 'table_pager_prev',
 348+ 'next' => 'table_pager_next',
 349+ 'last' => 'table_pager_last',
 350+ );
 351+ $images = array(
 352+ 'first' => $wgContLang->isRTL() ? 'arrow_last_25.png' : 'arrow_first_25.png',
 353+ 'prev' => $wgContLang->isRTL() ? 'arrow_right_25.png' : 'arrow_left_25.png',
 354+ 'next' => $wgContLang->isRTL() ? 'arrow_left_25.png' : 'arrow_right_25.png',
 355+ 'last' => $wgContLang->isRTL() ? 'arrow_first_25.png' : 'arrow_last_25.png',
 356+ );
 357+ $disabledImages = array(
 358+ 'first' => $wgContLang->isRTL() ? 'arrow_disabled_last_25.png' : 'arrow_disabled_first_25.png',
 359+ 'prev' => $wgContLang->isRTL() ? 'arrow_disabled_right_25.png' : 'arrow_disabled_left_25.png',
 360+ 'next' => $wgContLang->isRTL() ? 'arrow_disabled_left_25.png' : 'arrow_disabled_right_25.png',
 361+ 'last' => $wgContLang->isRTL() ? 'arrow_disabled_first_25.png' : 'arrow_disabled_last_25.png',
 362+ );
 363+
 364+ $linkTexts = array();
 365+ $disabledTexts = array();
 366+ foreach ( $labels as $type => $label ) {
 367+ $msgLabel = wfMsgHtml( $label );
 368+ $linkTexts[$type] = "<img src=\"$path/{$images[$type]}\" alt=\"$msgLabel\"/><br />$msgLabel";
 369+ $disabledTexts[$type] = "<img src=\"$path/{$disabledImages[$type]}\" alt=\"$msgLabel\"/><br />$msgLabel";
 370+ }
 371+ $links = $this->getPagingLinks( $linkTexts, $disabledTexts );
 372+
 373+ $navClass = htmlspecialchars( $this->getNavClass() );
 374+ $s = "<table class=\"$navClass\" align=\"center\" cellpadding=\"3\"><tr>\n";
 375+ $cellAttrs = 'valign="top" align="center" width="' . 100 / count( $links ) . '%"';
 376+ foreach ( $labels as $type => $label ) {
 377+ $s .= "<td $cellAttrs>{$links[$type]}</td>\n";
 378+ }
 379+ $s .= "</tr></table>\n";
 380+ return $s;
 381+ }
 382+
 383+ function getNavClass() {
 384+ return 'TalkpagePager_nav';
 385+ }
 386+}
Property changes on: branches/lqt-updates/extensions/LiquidThreads/classes/view/ChannelView.php
___________________________________________________________________
Added: svn:executable
1387 + *

Follow-up revisions

RevisionCommit summaryAuthorDate
r97233Since I accidentally committed most of it in r97232, commit my formatter API ...werdna05:29, 16 September 2011

Comments

#Comment by Nikerabbit (talk | contribs)   05:44, 16 September 2011
return $class::newFromID( $id );

Don't we usually use the ::factory() pattern in this kind of cases?

#Comment by Werdna (talk | contribs)   05:47, 16 September 2011

I don't understand, what do you mean by the ::factory() pattern?

Status & tagging log