r23089 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r23088‎ | r23089 | r23090 >
Date:06:35, 19 June 2007
Author:david
Status:old
Tags:
Comment:
New LiveThread class, with enough implemented for a little of the real view code to work.
Modified paths:
  • /branches/liquidthreads/extensions/LqtExtension.php (modified) (history)
  • /branches/liquidthreads/extensions/LqtModel.php (modified) (history)
  • /branches/liquidthreads/maintenance/lqt.sql (modified) (history)

Diff [purge]

Index: branches/liquidthreads/maintenance/lqt.sql
@@ -2,12 +2,14 @@
33 thread_id int(8) unsigned NOT NULL auto_increment,
44 thread_root int(8) unsigned NOT NULL,
55 thread_article int(8) unsigned NOT NULL,
6 - thread_path varchar(1000000) NOT NULL,
 6+ thread_path text NOT NULL,
77 thread_summary_page int(8) unsigned NULL,
88 thread_touched char(14) binary NOT NULL default '',
99
1010 PRIMARY KEY thread_id (thread_id),
11 - UNIQUE INDEX thread_id (thread_id)
 11+ UNIQUE INDEX thread_id (thread_id),
 12+ INDEX( thread_path(255) ),
 13+ INDEX thread_touched (thread_touched)
1214 ) TYPE=InnoDB;
1315
1416 /*
Index: branches/liquidthreads/extensions/LqtExtension.php
@@ -84,21 +84,21 @@
8585 $startdate = Date::now()->nDaysAgo($this->archive_start_days)->midnight();
8686 $recentstartdate = $startdate->nDaysAgo($this->archive_recent_days);
8787 $g->addQuery('fresh',
88 - array('thread_article' => $this->article->getID(),
89 - 'thread_subthread_of is null',
90 - '(thread_touched >= ' . $startdate->text() .
91 - ' OR thread_summary_page is NULL)'),
92 - array('ORDER BY' => 'thread_touched DESC' ));
 88+ array('thread.thread_article' => $this->article->getID(),
 89+ 'instr(thread.thread_path, ".")' => '0',
 90+ '(thread.thread_timestamp >= ' . $startdate->text() .
 91+ ' OR thread.thread_summary_page is NULL)'),
 92+ array('ORDER BY thread.thread_timestamp DESC'));
9393 $g->addQuery('archived',
94 - array('thread_article' => $this->article->getID(),
95 - 'thread_subthread_of is null',
96 - 'thread_summary_page is not null',
97 - 'thread_touched < ' . $startdate->text()),
98 - array('ORDER BY' => 'thread_touched DESC'));
 94+ array('thread.thread_article' => $this->article->getID(),
 95+ 'instr(thread.thread_path, ".")' => '0',
 96+ 'thread.thread_summary_page is not null',
 97+ 'thread.thread_timestamp < ' . $startdate->text()),
 98+ array('ORDER BY thread.thread_timestamp DESC'));
9999 $g->extendQuery('archived', 'recently-archived',
100 - array('( thread_touched >=' . $recentstartdate->text() .
 100+ array('( thread.thread_timestamp >=' . $recentstartdate->text() .
101101 ' OR rev_timestamp >= ' . $recentstartdate->text() . ')',
102 - 'page_id = thread_summary_page', 'page_latest = rev_id'),
 102+ 'page_id = thread.thread_summary_page', 'page_latest = rev_id'),
103103 array(),
104104 array('page', 'revision'));
105105 return $g;
@@ -131,7 +131,7 @@
132132 function permalinkUrl( $thread, $method = null, $operand = null ) {
133133 $query = $method ? "lqt_method=$method" : "";
134134 $query = $operand ? "$query&lqt_operand={$operand->id()}" : $query;
135 - return $thread->rootPost()->getTitle()->getFullUrl($query);
 135+ return $thread->root()->getTitle()->getFullUrl($query);
136136 }
137137
138138 function talkpageUrl( $title, $method = null, $operand = null ) {
@@ -197,7 +197,7 @@
198198 }
199199 $article = new Article($t);
200200 } else {
201 - $article = $thread->rootPost();
 201+ $article = $thread->root();
202202 }
203203
204204 $e = new EditPage($article);
@@ -261,7 +261,7 @@
262262 }
263263
264264 function renameThread($t,$s) {
265 - $this->simplePageMove($t->rootPost()->getTitle(),$s);
 265+ $this->simplePageMove($t->root()->getTitle(),$s);
266266 // TODO here create a redirect from old page to new.
267267 foreach( $t->subthreads() as $st ) {
268268 $this->renameThread($st, $s);
@@ -354,16 +354,16 @@
355355 }
356356
357357 function showThreadFooter( $thread ) {
358 - $color_number = $this->selectNewUserColor( $thread->rootPost()->originalAuthor() );
 358+ $color_number = $this->selectNewUserColor( $thread->root()->originalAuthor() );
359359 $this->output->addHTML(wfOpenElement('ul', array('class'=>"lqt_footer" )));
360360
361361 $this->output->addHTML( wfOpenElement( 'li', array('class'=>"lqt_author_sig lqt_post_color_$color_number") ) );
362 - $p = new Parser(); $sig = $p->getUserSig( $thread->rootPost()->originalAuthor() );
 362+ $p = new Parser(); $sig = $p->getUserSig( $thread->root()->originalAuthor() );
363363 $this->output->addWikitext( $sig, false );
364364 $this->output->addHTML( wfCloseElement( 'li' ) );
365365
366366 $this->output->addHTML( wfOpenElement( 'li' ) );
367 - $d = new Date($thread->touched());
 367+ $d = new Date($thread->timestamp());
368368 $this->output->addHTML( $d->lastMonth()->text() );
369369 $this->output->addHTML( wfCloseElement( 'li' ) );
370370
@@ -394,9 +394,9 @@
395395 }
396396
397397 function showRootPost( $thread ) {
398 - $post = $thread->rootPost();
 398+ $post = $thread->root();
399399
400 -/* $color_number = $this->selectNewUserColor( $thread->rootPost()->originalAuthor() );
 400+/* $color_number = $this->selectNewUserColor( $thread->root()->originalAuthor() );
401401 $this->openDiv( "lqt_post lqt_post_color_$color_number" );*/
402402 $this->openDiv( 'lqt_post' );
403403
@@ -429,10 +429,10 @@
430430 function showThread( $thread ) {
431431 $this->showThreadHeading( $thread );
432432
433 - $touched = new Date($thread->touched());
 433+ $timestamp = new Date($thread->timestamp());
434434 if( $thread->summary() ) {
435435 $this->showSummary($thread);
436 - } else if ( $touched->isBefore(Date::now()->nDaysAgo($this->archive_start_days))
 436+ } else if ( $timestamp->isBefore(Date::now()->nDaysAgo($this->archive_start_days))
437437 && !$thread->summary() && !$thread->superthread() ) {
438438 $this->output->addHTML("<p class=\"lqt_summary_notice\">If this discussion seems to be concluded, you are encouraged to <a href=\"{$this->permalinkUrl($thread, 'summarize')}\">write a summary</a>. There have been no changes here for at least $this->archive_start_days days.</p>");
439439 }
@@ -596,8 +596,8 @@
597597 $this->output->setPageTitle( "Talk:" . $this->title->getText() ); // TODO non-main namespaces.
598598 $this->addJSandCSS();
599599
600 - lqtCheapTest( );
601 - return;
 600+ // lqtCheapTest( );
 601+ // return;
602602
603603 $this->showHeader();
604604
@@ -643,8 +643,8 @@
644644 $where = array('thread_article' => $this->article->getID(),
645645 'thread_subthread_of is null',
646646 'thread_summary_page is not null',
647 - 'thread_touched < ' . $startdate->text());
648 - $options = array('ORDER BY' => 'thread_touched DESC');
 647+ 'thread_timestamp < ' . $startdate->text());
 648+ $options = array('ORDER BY' => 'thread_timestamp DESC');
649649
650650 $annotations = array("Searching for threads");
651651
@@ -662,13 +662,13 @@
663663 if ($s && ctype_digit($s) && strlen($s) == 6 && !$ignore_dates) {
664664 $this->selstart = new Date( "{$s}01000000" );
665665 $this->starti = array_search($s, $months);
666 - $where[] = 'thread_touched >= ' . $this->selstart->text();
 666+ $where[] = 'thread_timestamp >= ' . $this->selstart->text();
667667 }
668668 $e = $r->getVal('lqt_archive_end');
669669 if ($e && ctype_digit($e) && strlen($e) == 6 && !$ignore_dates) {
670670 $this->selend = new Date("{$e}01000000");
671671 $this->endi = array_search($e, $months);
672 - $where[] = 'thread_touched < ' . $this->selend->nextMonth()->text();
 672+ $where[] = 'thread_timestamp < ' . $this->selend->nextMonth()->text();
673673 }
674674 if ( isset($this->selstart) && isset($this->selend) ) {
675675
@@ -847,10 +847,10 @@
848848 $this->article = $t->article(); # for creating reply threads.
849849
850850 // Make a link back to the talk page, including the correct archive month.
851 - if (Date::now()->nDaysAgo(30)->midnight()->isBefore( new Date($t->touched()) ))
 851+ if (Date::now()->nDaysAgo(30)->midnight()->isBefore( new Date($t->timestamp()) ))
852852 $query = '';
853853 else
854 - $query = 'lqt_archive_month=' . substr($t->touched(),0,6);
 854+ $query = 'lqt_archive_month=' . substr($t->timestamp(),0,6);
855855
856856 $talkpage = $t->article()->getTitle()->getTalkpage();
857857 $talkpage_link = $this->user->getSkin()->makeKnownLinkObj($talkpage, '', $query);
Index: branches/liquidthreads/extensions/LqtModel.php
@@ -102,26 +102,165 @@
103103 }
104104
105105 class LiveThread {
 106+ /* ID references to other objects that are loaded on demand: */
 107+ protected $rootId;
 108+ protected $articleId;
 109+ protected $summaryId;
 110+ protected $superthreadId;
106111
 112+ /* Actual objects loaded on demand from the above when accessors are called: */
 113+ protected $root;
 114+ protected $article;
 115+ protected $summary;
 116+ protected $superthread;
 117+
 118+ /* Simple strings: */
 119+ protected $subject;
 120+ protected $timestamp;
 121+
 122+ /* Identity */
 123+ protected $id;
 124+
 125+ function __construct($line, $children) {
 126+ $this->id = $line->thread_id;
 127+ $this->rootId = $line->thread_root;
 128+ $this->articleId = $line->thread_article;
 129+ $this->summaryId = $line->thread_summary_page;
 130+ $this->path = $line->thread_path;
 131+ $this->timestamp = $line->thread_timestamp;
 132+ $this->replies = $children;
 133+ }
 134+
 135+ function setSuperthread($thread) {
 136+ $this->superthreadId = $thread->id();
 137+ $this->touch();
 138+ }
 139+
 140+ function superthread() {
 141+ if ( !$this->superthreadId ) return null;
 142+ if ( !$this->superthread ) $this->superthread = Thread::newFromId($this->superthreadId);
 143+ return $this->superthread;
 144+ }
 145+
 146+ function topmostThread() {
 147+ if ( !$this->superthread() ) return $this;
 148+ else return $this->superthread()->topmostThread();
 149+ }
 150+
 151+ function setArticle($a) {
 152+ $this->articleId = $a->getID();
 153+ $this->touch();
 154+ }
 155+
 156+ function article() {
 157+ if ( !$this->articleId ) return null;
 158+ if ( !$this->article ) $this->article = new Article(Title::newFromID($this->articleId));
 159+ return $this->article;
 160+ }
 161+
 162+ function id() {
 163+ return $this->id;
 164+ }
 165+
 166+ function root() {
 167+ if ( !$this->rootId ) return null;
 168+ if ( !$this->root ) $this->root = new Post( Title::newFromID( $this->rootId ) );
 169+ return $this->root;
 170+ }
 171+
 172+ function summary() {
 173+ if ( !$this->summaryId ) return null;
 174+ if ( !$this->summary ) $this->summary = new Post( Title::newFromID( $this->summaryId ) );
 175+ return $this->summary;
 176+ }
 177+
 178+ function setSummary( $post ) {
 179+ $this->summaryId = $post->getID();
 180+ $this->updateRecord();
 181+ }
 182+
 183+ function wikilink() {
 184+ return $this->root()->getTitle()->getPrefixedText();
 185+ }
 186+
 187+ function wikilinkWithoutIncrement() {
 188+ $foo = explode( ' ', $this->wikilink() );
 189+ array_pop($foo);
 190+ return implode( ' ', $foo );
 191+ }
 192+
 193+ function hasDistinctSubject() {
 194+ if( $this->superthread() ) {
 195+ return $this->superthread()->subjectWithoutIncrement()
 196+ != $this->subjectWithoutIncrement();
 197+ } else {
 198+ return true;
 199+ }
 200+ }
 201+
 202+ function subject() {
 203+ return $this->root()->getTitle()->getText();
 204+ return $this->subject;
 205+ }
 206+
 207+ function subjectWithoutIncrement() {
 208+ $foo = explode( ' ', $this->subject() );
 209+ array_pop($foo);
 210+ return implode( ' ', $foo );
 211+ }
 212+
 213+ function increment() {
 214+ return array_pop( explode(' ', $this->subject()) );
 215+ }
 216+
 217+ function hasSubthreads() {
 218+ return count($replies) != 0;
 219+ }
 220+
 221+ function subthreads() {
 222+ return $this->replies;
 223+ }
 224+
 225+ function timestamp() {
 226+ return $this->timestamp;
 227+ }
 228+
 229+ protected function updateRecord() {
 230+ $dbr =& wfGetDB( DB_MASTER );
 231+ $res = $dbr->update( 'lqt_thread',
 232+ /* SET */ array( 'thread_root_post' => $this->rootId,
 233+ 'thread_article' => $this->articleId,
 234+ 'thread_subthread_of' => $this->superthreadId,
 235+ 'thread_summary_page' => $this->summaryId,
 236+ 'thread_subject' => $this->subject,
 237+ 'thread_timestamp' => $this->timestamp ),
 238+ /* WHERE */ array( 'thread_id' => $this->id, ),
 239+ __METHOD__);
 240+ }
107241 }
108242
109243 /** Module of factory methods. */
110244 class Threads {
111245
112 - static function threadsWhere( $where_clause, $options = array(), $extra_tables = array() ) {
 246+ static function threadsWhere( $where, $options = array(), $extra_tables = array() ) {
113247 $dbr =& wfGetDB( DB_SLAVE );
114 - if ( is_array($where_clause) ) {
115 - $where = implode( 'and ', $where_clause );
 248+ if ( is_array($where) ) $where = $dbr->makeList( $where, LIST_AND );
 249+ if ( is_array($options) ) $options = implode(',', $options);
 250+ if( is_array($extra_tables) && count($extra_tables) != 0 ) {
 251+ $tables = implode(',', $extra_tables) . ', ';
 252+ } else if ( is_string( $extra_tables ) ) {
 253+ $tables = $extra_tables . ', ';
116254 } else {
117 - $where = $where_clause;
 255+ $tables = "";
118256 }
119 -
 257+
120258 /* Select the client's threads, AND all their children: */
121259
122260 $sql = <<< SQL
123 -SELECT children.* FROM thread, thread children
 261+SELECT children.* FROM $tables thread, thread children
124262 WHERE $where AND
125263 children.thread_path LIKE CONCAT(thread.thread_path, "%")
 264+$options
126265 SQL;
127266 $res = $dbr->query($sql);
128267
@@ -137,23 +276,25 @@
138277 Threads::setDeepArray( $tree, $line, $path );
139278
140279 }
141 - function createThreads( $thread ) {
142 - $subthreads = array();
143 - foreach( $thread as $key => $val ) {
144 - if ( $key != 'root' ) {
145 - $subthreads[] = createThreads( $val );
146 - }
147 - }
148 - return Threads::newLiveThreadFromDBLine( $thread['root'], $subthreads );
149 - }
 280+
150281 $threads = array();
151282 foreach( $tree as $root ) {
152 - $threads[] = createThreads($root);
 283+ $threads[] = Threads::createThreads($root);
153284 }
154285
155286 return $threads;
156287 }
157288
 289+ private static function createThreads( $thread ) {
 290+ $subthreads = array();
 291+ foreach( $thread as $key => $val ) {
 292+ if ( $key != 'root' ) {
 293+ $subthreads[] = Threads::createThreads( $val );
 294+ }
 295+ }
 296+ return new LiveThread( $thread['root'], $subthreads );
 297+ }
 298+
158299 /** setDeepArray( $a, $v, array(1,2,3) ) <=> $a[1][2][3]['root'] = $v; */
159300 private static function setDeepArray( &$a, $v, $p ) {
160301 if( count($p) == 1 ) {
@@ -163,27 +304,14 @@
164305 $a[$p[0]] = array();
165306 Threads::setDeepArray( $a[$p[0]], $v, array_slice($p, 1) );
166307 }
167 - }
168 -
169 - static function newLiveThreadFromDBLine( $line, $children ) {
170 - $t = new LiveThread();
171 - $t->id = $line->thread_id;
172 - $t->rootId = $line->thread_root;
173 - $t->articleId = $line->thread_article;
174 - $t->summaryId = $line->thread_summary_page;
175 - $t->path = $line->thread_path;
176 - $t->touched = $line->thread_touched;
177 - $t->replies = $children;
178 - return $t;
179 - }
180 -
 308+ }
181309 }
182 -
 310+/*
183311 function lqtCheapTest() {
184 - $threads = Threads::threadsWhere( "thread.thread_id = 1" );
 312+ $threads = Threads::threadsWhere( "thread.thread_id = 1", "order by thread_timestamp" );
185313 function cheapShowThread($t) {
186314 global $wgOut;
187 - $wgOut->addHTML($t->id);
 315+ $wgOut->addHTML($t->id());
188316 $wgOut->addHTML('<dl><dd>');
189317 foreach( $t->replies as $r ) {
190318 cheapShowThread($r);
@@ -194,7 +322,7 @@
195323 cheapShowThread($t);
196324 }
197325 }
198 -
 326+*/
199327 class QueryGroup {
200328 protected $queries;
201329
@@ -221,7 +349,7 @@
222350 function query($name) {
223351 if ( !array_key_exists($name,$this->queries) ) return array();
224352 list($where, $options, $extra_tables) = $this->queries[$name];
225 - return Thread::threadsWhere($where, $options, $extra_tables);
 353+ return Threads::threadsWhere($where, $options, $extra_tables);
226354 }
227355 }
228356

Status & tagging log