r62684 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r62683‎ | r62684 | r62685 >
Date:00:48, 19 February 2010
Author:werdna
Status:deferred
Tags:
Comment:
Major refactoring of LiquidThreads post/reply logic. Now split a 200-line function with if() blocks all over the place into 3 100-line functions. Also refactored postEditUpdates() while I was at it, which was also in a major shambles. Ding, dong, showEditingFormInGeneral() is dead.
Modified paths:
  • /trunk/extensions/LiquidThreads/api/ApiThreadAction.php (modified) (history)
  • /trunk/extensions/LiquidThreads/classes/Dispatch.php (modified) (history)
  • /trunk/extensions/LiquidThreads/classes/View.php (modified) (history)
  • /trunk/extensions/LiquidThreads/pages/TalkpageView.php (modified) (history)
  • /trunk/extensions/LiquidThreads/pages/ThreadPermalinkView.php (modified) (history)

Diff [purge]

Index: trunk/extensions/LiquidThreads/classes/View.php
@@ -283,7 +283,7 @@
284284 * Return an HTML form element whose value is gotten from the request.
285285 * TODO: figure out a clean way to expand this to other forms.
286286 */
287 - function perpetuate( $name, $as ) {
 287+ function perpetuate( $name, $as = 'hidden' ) {
288288 $value = $this->request->getVal( $name, '' );
289289 if ( $as == 'hidden' ) {
290290 return Xml::hidden( $name, $value );
@@ -298,27 +298,6 @@
299299 '<a href="' . $log_url . '">' . wfMsg( 'lqt_protectedfromreply_link' ) . '</a>' ) );
300300 }
301301
302 - function showNewThreadForm() {
303 - $this->showEditingFormInGeneral( null, 'new', null );
304 - }
305 -
306 - function showPostEditingForm( $thread ) {
307 - $this->showEditingFormInGeneral( $thread, 'editExisting', null );
308 - }
309 -
310 - function showReplyForm( $thread ) {
311 - if ( $thread->root()->getTitle()->userCan( 'edit' ) ) {
312 - $this->showEditingFormInGeneral( null, 'reply', $thread );
313 - } else {
314 - $this->showReplyProtectedNotice( $thread );
315 - }
316 - }
317 -
318 - function showSummarizeForm( $thread ) {
319 - $this->output->addWikiMsg( 'lqt-summarize-intro' );
320 - $this->showEditingFormInGeneral( $thread, 'summarize', $thread );
321 - }
322 -
323302 function doInlineEditForm() {
324303 $method = $this->request->getVal( 'lqt_method' );
325304 $operand = $this->request->getVal( 'lqt_operand' );
@@ -328,155 +307,406 @@
329308 if ( $method == 'reply' ) {
330309 $this->showReplyForm( $thread );
331310 } elseif ( $method == 'talkpage_new_thread' ) {
332 - $this->showNewThreadForm();
 311+ $this->showNewThreadForm( $this->article );
333312 } elseif ( $method == 'edit' ) {
334313 $this->showPostEditingForm( $thread );
335314 }
336315
337316 $this->output->setArticleBodyOnly( true );
338317 }
339 -
340 - private function showEditingFormInGeneral( $thread, $edit_type, $edit_applies_to ) {
341 - /**
342 - * EditPage needs an Article. If there isn't a real one, as for new posts,
343 - * replies, and new summaries, we need to generate a title. Auto-generated
344 - * titles are based on the subject line. If the subject line is blank, we
345 - * can temporarily use a random scratch title. It's fine if the title changes
346 - * throughout the edit cycle, since the article doesn't exist yet anyways.
347 - */
348 -
349 - // Check permissions
350 - if ( $edit_type == 'new' ) {
351 - if ( Thread::canUserPost( $this->user, $this->article ) !== true ) {
352 - $this->output->addWikiMsg( 'lqt-protected-newthread' );
353 - return;
354 - }
355 - } elseif ( $edit_type == 'reply' ) {
356 - $perm_result = $edit_applies_to->canUserReply( $this->user );
357 - if ( $perm_result !== true ) {
358 - $msg = "lqt-protected-reply-$perm_result";
359 - $this->output->addWikiMsg( $msg );
360 - return;
361 - }
 318+
 319+ function showNewThreadForm( $talkpage ) {
 320+ $submitted_nonce = $this->request->getVal( 'lqt_nonce' );
 321+ $nonce_key = wfMemcKey( 'lqt-nonce', $submitted_nonce, $this->user->getName() );
 322+ if ( ! $this->handleNonce( $submitted_nonce, $nonce_key ) ) return;
 323+
 324+ if ( Thread::canUserPost( $this->user, $this->article ) !== true ) {
 325+ $this->output->addWikiMsg( 'lqt-protected-newthread' );
 326+ return;
362327 }
363 -
364 - // Check if we actually want a subject, pull the submitted subject, and validate it.
365 - $subject_expected = ( $edit_type == 'new' ||
366 - $thread && $thread->isTopmostThread() ) &&
367 - $edit_type != 'summarize';
368 - $subject = $this->request->getVal( 'lqt_subject_field', '' );
369 - $valid_subject = true;
370 -
371 - if ( $edit_type == 'summarize' && $edit_applies_to->summary() ) {
372 - $article = $edit_applies_to->summary();
373 - } elseif ( $edit_type == 'summarize' ) {
374 - $t = $this->newSummaryTitle( $edit_applies_to );
375 - $article = new Article( $t );
376 - } elseif ( !$thread ) {
377 - $t = null;
378 -
379 - $subjectOk = Thread::validateSubject( $subject, $t,
380 - $edit_applies_to, $this->article );
381 - if ( ! $subjectOk ) {
382 - $subject = false;
 328+ $subject = $this->request->getVal( 'lqt_subject_field', false );
 329+
 330+ $t = null;
 331+
 332+ $subjectOk = Thread::validateSubject( $subject, $t,
 333+ null, $this->article );
 334+ if ( ! $subjectOk ) {
 335+ try {
 336+ $t = $this->newThreadTitle( $subject );
 337+ } catch ( MWException $excep ) {
 338+ $t = $this->scratchTitle();
383339 }
384 -
385 - if ( !$subject && $subject_expected ) {
386 - // Dodgy title
387 - $valid_subject = false;
388 - } elseif ( ! $t ) {
389 - try {
390 - if ( $edit_type == 'new' ) {
391 - $t = $this->newThreadTitle( $subject );
392 - } elseif ( $edit_type == 'reply' ) {
393 - $t = $this->newReplyTitle( $subject, $edit_applies_to );
394 - }
395 - } catch ( MWException $excep ) {
396 - $t = $this->scratchTitle();
397 - $valid_subject = false;
398 - }
399 - }
400 - $article = new Article( $t );
401 - } else {
402 - $article = $thread->root();
403340 }
404 -
405 - $talkpage = $this->article;
406 - if ( $thread ) {
407 - $talkpage = $thread->article();
408 - } elseif ( $edit_applies_to ) {
409 - $talkpage = $edit_applies_to->article();
410 - }
411 -
 341+
 342+ $article = new Article( $t );
 343+
412344 LqtHooks::$editTalkpage = $talkpage;
413345 LqtHooks::$editArticle = $article;
414 - LqtHooks::$editThread = $thread;
415 - LqtHooks::$editType = $edit_type;
416 - LqtHooks::$editAppliesTo = $edit_applies_to;
417 -
 346+ LqtHooks::$editThread = null;
 347+ LqtHooks::$editType = 'new';
 348+ LqtHooks::$editAppliesTo = null;
 349+
418350 $e = new EditPage( $article );
419 -
 351+
420352 global $wgRequest;
421353 // Quietly force a preview if no subject has been specified.
422 - if ( ( !$valid_subject && $subject ) || ( $subject_expected && !$subject ) ) {
 354+ if ( !$subjectOk ) {
423355 // Dirty hack to prevent saving from going ahead
424356 $wgRequest->setVal( 'wpPreview', true );
425 -
 357+
426358 if ( $this->request->wasPosted() ) {
427359 if ( !$subject ) {
428360 $msg = 'lqt_empty_subject';
429361 } else {
430362 $msg = 'lqt_invalid_subject';
431363 }
432 -
 364+
433365 $e->editFormPageTop .=
434366 Xml::tags( 'div', array( 'class' => 'error' ),
435367 wfMsgExt( $msg, 'parse' ) );
436368 }
437369 }
438 -
439 - // For new posts and replies, remove the summary field and use a boilerplate
440 - // default.
441 - if ( $edit_type == 'new' ) {
442 - $e->mShowSummaryField = false;
443 -
444 - $summary = wfMsgForContent( 'lqt-newpost-summary', $subject );
445 - $wgRequest->setVal( 'wpSummary', $summary );
446 - } elseif ( $edit_type == 'reply' ) {
447 - $e->mShowSummaryField = false;
448 -
449 - $reply_subject = $edit_applies_to->subject();
450 - $reply_title = $edit_applies_to->title()->getPrefixedText();
451 - $summary = wfMsgForContent(
452 - 'lqt-reply-summary',
453 - $reply_subject,
454 - $reply_title
 370+
 371+ $e->suppressIntro = true;
 372+ $e->editFormTextBeforeContent .=
 373+ $this->perpetuate( 'lqt_method', 'hidden' ) .
 374+ $this->perpetuate( 'lqt_operand', 'hidden' ) .
 375+ Xml::hidden( 'lqt_nonce', wfGenerateToken() );
 376+
 377+ $e->mShowSummaryField = false;
 378+
 379+ $summary = wfMsgForContent( 'lqt-newpost-summary', $subject );
 380+ $wgRequest->setVal( 'wpSummary', $summary );
 381+
 382+ list( $signatureEditor, $signatureHTML ) = $this->getSignatureEditor( $this->user );
 383+
 384+ $e->editFormTextAfterContent .=
 385+ $signatureEditor;
 386+ $e->previewTextAfterContent .=
 387+ Xml::tags( 'p', null, $signatureHTML );
 388+
 389+ $e->editFormTextBeforeContent .= $this->getSubjectEditor( '', $subject );
 390+
 391+ $e->edit();
 392+
 393+ if ( $e->didSave ) {
 394+ $signature = $this->request->getVal( 'wpLqtSignature', null );
 395+
 396+ $thread = LqtView::newPostMetadataUpdates(
 397+ array(
 398+ 'talkpage' => $talkpage,
 399+ 'text' => $e->textbox1,
 400+ 'summary' => $e->summary,
 401+ 'signature' => $signature,
 402+ 'root' => $article,
 403+ 'subject' => $subject,
 404+ )
455405 );
456 - $wgRequest->setVal( 'wpSummary', $summary );
 406+
 407+ if ( $submitted_nonce && $nonce_key ) {
 408+ global $wgMemc;
 409+ $wgMemc->set( $nonce_key, 1, 3600 );
 410+ }
457411 }
458 -
 412+
 413+ if ( $this->output->getRedirect() != '' ) {
 414+ $redirectTitle = clone $talkpage->getTitle();
 415+ $redirectTitle->setFragment( '#' . $this->anchorName( $thread ) );
 416+ $this->output->redirect( $this->title->getFullURL() );
 417+ }
 418+
 419+ }
 420+
 421+ function showReplyForm( $thread ) {
 422+ global $wgRequest;
 423+
 424+ $submitted_nonce = $this->request->getVal( 'lqt_nonce' );
 425+ $nonce_key = wfMemcKey( 'lqt-nonce', $submitted_nonce, $this->user->getName() );
 426+ if ( ! $this->handleNonce( $submitted_nonce, $nonce_key ) ) return;
 427+
 428+ $perm_result = $thread->canUserReply( $this->user );
 429+ if ( $perm_result !== true ) {
 430+ $this->showReplyProtectedNotice( $thread );
 431+ return;
 432+ }
 433+
 434+ try {
 435+ $t = $this->newReplyTitle( null, $thread );
 436+ } catch ( MWException $excep ) {
 437+ $t = $this->scratchTitle();
 438+ $valid_subject = false;
 439+ }
 440+
 441+ $article = new Article( $t );
 442+ $talkpage = $thread->article();
 443+
 444+ LqtHooks::$editTalkpage = $talkpage;
 445+ LqtHooks::$editArticle = $article;
 446+ LqtHooks::$editThread = $thread;
 447+ LqtHooks::$editType = 'reply';
 448+ LqtHooks::$editAppliesTo = $thread;
 449+
 450+ $e = new EditPage( $article );
 451+
 452+ $e->mShowSummaryField = false;
 453+
 454+ $reply_subject = $thread->subject();
 455+ $reply_title = $thread->title()->getPrefixedText();
 456+ $summary = wfMsgForContent(
 457+ 'lqt-reply-summary',
 458+ $reply_subject,
 459+ $reply_title
 460+ );
 461+ $wgRequest->setVal( 'wpSummary', $summary );
 462+
459463 // Add an offset so it works if it's on the wrong page.
460 - if ( $edit_applies_to ) {
461 - $dbr = wfGetDB( DB_SLAVE );
462 - $offset = wfTimestamp( TS_UNIX, $edit_applies_to->topmostThread()->modified() );
463 - $offset++;
464 - $offset = $dbr->timestamp( $offset );
465 - } else $offset = '';
466 -
 464+ $dbr = wfGetDB( DB_SLAVE );
 465+ $offset = wfTimestamp( TS_UNIX, $thread->topmostThread()->sortkey() );
 466+ $offset++;
 467+ $offset = $dbr->timestamp( $offset );
 468+
467469 $e->suppressIntro = true;
468470 $e->editFormTextBeforeContent .=
469471 $this->perpetuate( 'lqt_method', 'hidden' ) .
470472 $this->perpetuate( 'lqt_operand', 'hidden' ) .
471473 Xml::hidden( 'lqt_nonce', wfGenerateToken() ) .
472474 Xml::hidden( 'offset', $offset );
 475+
 476+ list( $signatureEditor, $signatureHTML ) = $this->getSignatureEditor( $this->user );
 477+
 478+ $e->editFormTextAfterContent .=
 479+ $signatureEditor;
 480+ $e->previewTextAfterContent .=
 481+ Xml::tags( 'p', null, $signatureHTML );
 482+
 483+ $e->edit();
 484+
 485+ if ( $e->didSave ) {
 486+ $bump = $this->request->getBool( 'wpBumpThread' );
 487+ $signature = $this->request->getVal( 'wpLqtSignature', null );
 488+
 489+ $newThread = LqtView::replyMetadataUpdates(
 490+ array(
 491+ 'replyTo' => $thread,
 492+ 'text' => $e->textbox1,
 493+ 'summary' => $e->summary,
 494+ 'bump' => $bump,
 495+ 'signature' => $signature,
 496+ 'root' => $article,
 497+ )
 498+ );
 499+
 500+ if ( $submitted_nonce && $nonce_key ) {
 501+ global $wgMemc;
 502+ $wgMemc->set( $nonce_key, 1, 3600 );
 503+ }
 504+ }
 505+
 506+ if ( $this->output->getRedirect() != '' ) {
 507+ $redirectTitle = clone $talkpage->getTitle();
 508+ $redirectTitle->setFragment( '#' . $this->anchorName( $newThread ) );
 509+ $this->output->redirect( $this->title->getFullURL() );
 510+ }
 511+ }
 512+
 513+ function showPostEditingForm( $thread ) {
 514+ $submitted_nonce = $this->request->getVal( 'lqt_nonce' );
 515+ $nonce_key = wfMemcKey( 'lqt-nonce', $submitted_nonce, $this->user->getName() );
 516+ if ( ! $this->handleNonce( $submitted_nonce, $nonce_key ) ) return;
 517+
 518+ $subject_expected = $thread->isTopmostThread();
 519+ $subject = $this->request->getVal( 'lqt_subject_field', '' );
 520+
 521+ if (!$subject) {
 522+ $subject = $thread->subject();
 523+ }
 524+
 525+ $t = null;
 526+ $subjectOk = Thread::validateSubject( $subject, $t,
 527+ $thread->superthread(), $this->article );
 528+ if ( ! $subjectOk ) {
 529+ $subject = false;
 530+ }
 531+
 532+ $article = $thread->root();
 533+ $talkpage = $thread->article();
 534+
 535+ LqtHooks::$editTalkpage = $talkpage;
 536+ LqtHooks::$editArticle = $article;
 537+ LqtHooks::$editThread = $thread;
 538+ LqtHooks::$editType = 'edit';
 539+ LqtHooks::$editAppliesTo = $thread;
 540+
 541+ $e = new EditPage( $article );
 542+
 543+ global $wgRequest;
 544+ // Quietly force a preview if no subject has been specified.
 545+ if ( !$subjectOk ) {
 546+ // Dirty hack to prevent saving from going ahead
 547+ $wgRequest->setVal( 'wpPreview', true );
 548+
 549+ if ( $this->request->wasPosted() ) {
 550+ $e->editFormPageTop .=
 551+ Xml::tags( 'div', array( 'class' => 'error' ),
 552+ wfMsgExt( 'lqt_invalid_subject', 'parse' ) );
 553+ }
 554+ }
 555+
 556+ // Add an offset so it works if it's on the wrong page.
 557+ $dbr = wfGetDB( DB_SLAVE );
 558+ $offset = wfTimestamp( TS_UNIX, $thread->topmostThread()->sortkey() );
 559+ $offset++;
 560+ $offset = $dbr->timestamp( $offset );
 561+
 562+ $e->suppressIntro = true;
 563+ $e->editFormTextBeforeContent .=
 564+ $this->perpetuate( 'lqt_method', 'hidden' ) .
 565+ $this->perpetuate( 'lqt_operand', 'hidden' ) .
 566+ Xml::hidden( 'lqt_nonce', wfGenerateToken() ) .
 567+ Xml::hidden( 'offset', $offset );
 568+
 569+ list( $signatureEditor, $signatureHTML ) = $this->getSignatureEditor( $thread );
 570+
 571+ $e->editFormTextAfterContent .=
 572+ $signatureEditor;
 573+ $e->previewTextAfterContent .=
 574+ Xml::tags( 'p', null, $signatureHTML );
 575+
 576+ $e->editFormTextBeforeContent .= $this->getSubjectEditor( $thread->subject(), $subject );
 577+
 578+ $e->edit();
 579+
 580+ if ( $e->didSave ) {
 581+ $bump = $this->request->getBool( 'wpBumpThread' );
 582+ $signature = $this->request->getVal( 'wpLqtSignature', null );
 583+
 584+ LqtView::editMetadataUpdates(
 585+ array(
 586+ 'thread' => $thread,
 587+ 'text' => $e->textbox1,
 588+ 'summary' => $e->summary,
 589+ 'bump' => $bump,
 590+ 'subject' => $subject,
 591+ 'signature' => $signature,
 592+ 'root' => $article,
 593+ )
 594+ );
 595+
 596+ if ( $submitted_nonce && $nonce_key ) {
 597+ global $wgMemc;
 598+ $wgMemc->set( $nonce_key, 1, 3600 );
 599+ }
 600+ }
 601+
 602+ if ( $this->output->getRedirect() != '' ) {
 603+ $redirectTitle = clone $talkpage->getTitle();
 604+ $redirectTitle->setFragment( '#' . $this->anchorName( $thread ) );
 605+ $this->output->redirect( $this->title->getFullURL() );
 606+ }
 607+
 608+ }
 609+
 610+ function showSummarizeForm( $thread ) {
 611+ $submitted_nonce = $this->request->getVal( 'lqt_nonce' );
 612+ $nonce_key = wfMemcKey( 'lqt-nonce', $submitted_nonce, $this->user->getName() );
 613+ if ( ! $this->handleNonce( $submitted_nonce, $nonce_key ) ) return;
 614+
 615+ if ( $thread->summary() ) {
 616+ $article = $thread->summary();
 617+ } else {
 618+ $t = $this->newSummaryTitle( $thread );
 619+ $article = new Article( $t );
 620+ }
 621+
 622+ $this->output->addWikiMsg( 'lqt-summarize-intro' );
 623+
 624+ $talkpage = $thread->article();
 625+
 626+ LqtHooks::$editTalkpage = $talkpage;
 627+ LqtHooks::$editArticle = $article;
 628+ LqtHooks::$editThread = $thread;
 629+ LqtHooks::$editType = 'summarize';
 630+ LqtHooks::$editAppliesTo = $thread;
 631+
 632+ $e = new EditPage( $article );
 633+
 634+ // Add an offset so it works if it's on the wrong page.
 635+ $dbr = wfGetDB( DB_SLAVE );
 636+ $offset = wfTimestamp( TS_UNIX, $thread->topmostThread()->sortkey() );
 637+ $offset++;
 638+ $offset = $dbr->timestamp( $offset );
 639+
 640+ $e->suppressIntro = true;
 641+ $e->editFormTextBeforeContent .=
 642+ $this->perpetuate( 'lqt_method', 'hidden' ) .
 643+ $this->perpetuate( 'lqt_operand', 'hidden' ) .
 644+ Xml::hidden( 'lqt_nonce', wfGenerateToken() ) .
 645+ Xml::hidden( 'offset', $offset );
 646+
 647+ $e->edit();
 648+
 649+ if ( $e->didSave ) {
 650+ $bump = $this->request->getBool( 'wpBumpThread' );
 651+
 652+ LqtView::summarizeMetadataUpdates(
 653+ array(
 654+ 'thread' => $thread,
 655+ 'article' => $article,
 656+ 'summary' => $e->summary,
 657+ 'bump' => $bump,
 658+ )
 659+ );
 660+
 661+ if ( $submitted_nonce && $nonce_key ) {
 662+ global $wgMemc;
 663+ $wgMemc->set( $nonce_key, 1, 3600 );
 664+ }
 665+ }
 666+
 667+ if ( $this->output->getRedirect() != '' ) {
 668+ $redirectTitle = clone $talkpage->getTitle();
 669+ $redirectTitle->setFragment( '#' . $this->anchorName( $thread ) );
 670+ $this->output->redirect( $this->title->getFullURL() );
 671+ }
 672+
 673+ }
 674+
 675+ public function handleNonce( $submitted_nonce, $nonce_key ) {
 676+ // Add a one-time random string to a hidden field. Store the random string
 677+ // in memcached on submit and don't allow the edit to go ahead if it's already
 678+ // been added.
 679+ if ( $submitted_nonce ) {
 680+ global $wgMemc;
473681
 682+ if ( $wgMemc->get( $nonce_key ) ) {
 683+ $this->output->redirect( $this->article->getTitle()->getFullURL() );
 684+ return false;
 685+ }
 686+ }
 687+
 688+ return true;
 689+ }
 690+
 691+ public function getSubjectEditor( $db_subject, $subject ) {
 692+ if ( $subject === false ) $subject = $db_subject;
 693+
 694+ $subject_label = wfMsg( 'lqt_subject' );
 695+
 696+ $attr = array( 'tabindex' => 1 );
 697+
 698+ return Xml::inputLabel( $subject_label, 'lqt_subject_field',
 699+ 'lqt_subject_field', 60, $subject, $attr ) .
 700+ Xml::element( 'br' );
 701+ }
 702+
 703+ public function getSignatureEditor( $from ) {
474704 $signatureText = $this->request->getVal( 'wpLqtSignature', null );
475705
476706 if ( is_null( $signatureText ) ) {
477 - if ( !$thread && $edit_type != 'summarize' ) {
478 - $signatureText = LqtView::getUserSignature( $this->user );
479 - } else {
480 - $signatureText = $thread->signature();
 707+ if ( $from instanceof User || $from instanceof StubUser ) {
 708+ $signatureText = LqtView::getUserSignature( $from );
 709+ } elseif ( $from instanceof Thread ) {
 710+ $signatureText = $from->signature();
481711 }
482712 }
483713
@@ -497,137 +727,135 @@
498728 );
499729
500730 $signatureEditor = $signaturePreview . $signatureEditBox;
501 -
502 - $e->editFormTextAfterContent .=
503 - $signatureEditor;
504 - $e->previewTextAfterContent .=
505 - Xml::tags( 'p', null, $signatureHTML );
506 -
507 - // Add a one-time random string to a hidden field. Store the random string
508 - // in memcached on submit and don't allow the edit to go ahead if it's already
509 - // been added.
510 - $submitted_nonce = $this->request->getVal( 'lqt_nonce' );
511 - if ( $submitted_nonce ) {
512 - global $wgMemc;
513 -
514 - $nonce_key = wfMemcKey( 'lqt-nonce', $submitted_nonce, $this->user->getName() );
515 - if ( $wgMemc->get( $nonce_key ) ) {
516 - $this->output->redirect( $this->article->getTitle()->getFullURL() );
517 - return;
 731+
 732+ return array( $signatureEditor, $signatureHTML );
 733+ }
 734+
 735+ static function replyMetadataUpdates( $data = array() ) {
 736+ $requiredFields = array( 'replyTo', 'root', 'text' );
 737+
 738+ foreach( $requiredFields as $f ) {
 739+ if ( !isset($data[$f]) ) {
 740+ throw new MWException( "Missing required field $f" );
518741 }
519742 }
520 -
521 - if ( $subject_expected ) {
522 - wfLoadExtensionMessages( 'LiquidThreads' );
523 - // This is a top-level post; show the subject line.
524 - $db_subject = $thread ? $thread->subjectWithoutIncrement() : '';
525 - $subject = $this->request->getVal( 'lqt_subject_field', $db_subject );
526 - $subject_label = wfMsg( 'lqt_subject' );
527 -
528 - $attr = array( 'tabindex' => 1 );
529 -
530 - $e->editFormTextBeforeContent .=
531 - Xml::inputLabel( $subject_label, 'lqt_subject_field',
532 - 'lqt_subject_field', 60, $subject, $attr ) .
533 - Xml::element( 'br' );
 743+
 744+ $signature = null;
 745+ if ( isset( $data['signature'] ) ) {
 746+ $signature = $data['signature'];
 747+ } else {
 748+ global $wgUser;
 749+ $signature = LqtView::getUserSignature( $wgUser );
534750 }
535 -
536 - $e->edit();
537 -
538 - // Override what happens in EditPage::showEditForm, called from $e->edit():
539 -
540 - $this->output->setArticleFlag( false );
541 -
542 - if ( $e->didSave ) {
543 - $bump = $this->request->getBool( 'wpBumpThread' );
544 -
545 - $thread = self::postEditUpdates(
546 - $edit_type, $edit_applies_to, $article,
547 - $this->article, $subject, $e->summary, $thread,
548 - $e->textbox1, $bump, $signatureText
549 - );
550 -
551 - if ( $submitted_nonce && $nonce_key ) {
552 - $wgMemc->set( $nonce_key, 1, 3600 );
 751+
 752+ $summary = isset($data['summary']) ? $data['summary'] : '';
 753+
 754+ $replyTo = $data['replyTo'];
 755+ $root = $data['root'];
 756+ $text = $data['text'];
 757+ $bump = !empty($data['bump']);
 758+
 759+ $subject = $replyTo->subject();
 760+ $talkpage = $replyTo->article();
 761+
 762+ $thread = Thread::create(
 763+ $root, $talkpage, $replyTo, Threads::TYPE_NORMAL, $subject,
 764+ $summary, $bump, $signature
 765+ );
 766+
 767+ return $thread;
 768+ }
 769+
 770+ static function summarizeMetadataUpdates( $data = array() ) {
 771+ $requiredFields = array( 'thread', 'article', 'summary' );
 772+
 773+ foreach( $requiredFields as $f ) {
 774+ if ( !isset($data[$f]) ) {
 775+ throw new MWException( "Missing required field $f" );
553776 }
554777 }
 778+
 779+ extract( $data );
 780+
 781+ $bump = isset($bump) ? $bump : null;
 782+
 783+ $thread->setSummary( $article );
 784+ $thread->commitRevision(
 785+ Threads::CHANGE_EDITED_SUMMARY, $thread, $summary, $bump );
 786+
 787+ return $thread;
 788+ }
 789+
 790+ static function editMetadataUpdates( $data = array() ) {
 791+ $requiredFields = array( 'thread', 'text', 'summary' );
 792+
 793+ foreach( $requiredFields as $f ) {
 794+ if ( !isset($data[$f]) ) {
 795+ throw new MWException( "Missing required field $f" );
 796+ }
 797+ }
 798+
 799+ $thread = $data['thread'];
 800+
 801+ // Use a separate type if the content is blanked.
 802+ $type = strlen( trim( $data['text'] ) )
 803+ ? Threads::CHANGE_EDITED_ROOT
 804+ : Threads::CHANGE_ROOT_BLANKED;
 805+
 806+ if ( isset( $data['signature'] ) ) {
 807+ $thread->setSignature( $data['signature'] );
 808+ }
 809+
 810+ $bump = !empty($data['bump']);
555811
556 - // A redirect without $e->didSave will happen if the new text is blank (EditPage::attemptSave).
557 - // This results in a new Thread object not being created for replies and new discussions,
558 - // so $thread is null. In that case, just allow editpage to redirect back to the talk page.
559 - if ( $this->output->getRedirect() != '' && $thread ) {
560 - $redirectTitle = clone $thread->article()->getTitle();
561 - $redirectTitle->setFragment( '#' . $this->anchorName( $thread ) );
562 - $this->output->redirect( $this->title->getFullURL() );
563 - } else if ( $this->output->getRedirect() != '' && $edit_applies_to ) {
564 - // For summaries:
565 - $redirectTitle = clone $edit_applies_to->article()->getTitle();
566 - $redirectTitle->setFragment( '#' . $this->anchorName( $edit_applies_to ) );
567 - $this->output->redirect( $redirectTitle->getFullURL() );
 812+ // Add the history entry.
 813+ $thread->commitRevision( $type, $thread, $data['summary'], $bump );
 814+
 815+ // Update subject if applicable.
 816+ if ( $thread->isTopmostThread() && !empty( $data['subject'] ) &&
 817+ $data['subject'] != $thread->subject() ) {
 818+ $thread->setSubject( $data['subject'] );
 819+ $thread->commitRevision( Threads::CHANGE_EDITED_SUBJECT,
 820+ $thread, $summary );
 821+
 822+ // Disabled page-moving for now.
 823+ // $this->renameThread( $thread, $subject, $e->summary );
568824 }
 825+
 826+ return $thread;
569827 }
570828
571 - static function postEditUpdates( $edit_type, $edit_applies_to, $edit_page, $article,
572 - $subject, $edit_summary, $thread, $new_text, $bump = null, $signature = null )
 829+ static function newPostMetadataUpdates( $data )
573830 {
574 - // Update metadata - create and update thread and thread revision objects as
575 - // appropriate.
576 -
577 - $noSignature = false;
578 - if ( is_null( $signature ) ) {
 831+ $requiredFields = array( 'talkpage', 'root', 'text', 'subject' );
 832+
 833+ foreach( $requiredFields as $f ) {
 834+ if ( !isset($data[$f]) ) {
 835+ throw new MWException( "Missing required field $f" );
 836+ }
 837+ }
 838+
 839+ $signature = null;
 840+ if ( isset( $data['signature'] ) ) {
 841+ $signature = $data['signature'];
 842+ } else {
579843 global $wgUser;
580844 $signature = LqtView::getUserSignature( $wgUser );
581 - $noSignature = true;
582845 }
 846+
 847+ $summary = isset($data['summary']) ? $data['summary'] : '';
 848+
 849+ $talkpage = $data['talkpage'];
 850+ $root = $data['root'];
 851+ $text = $data['text'];
 852+ $subject = $data['subject'];
583853
584 - if ( $edit_type == 'reply' ) {
585 - $subject = $edit_applies_to->subject();
 854+ $thread = Thread::create(
 855+ $root, $talkpage, null,
 856+ Threads::TYPE_NORMAL, $subject,
 857+ $summary, null, $signature
 858+ );
586859
587 - $thread = Thread::create(
588 - $edit_page, $article, $edit_applies_to,
589 - Threads::TYPE_NORMAL, $subject,
590 - $edit_summary, $bump, $signature
591 - );
592 -
593 - global $wgUser;
594 - NewMessages::markThreadAsReadByUser( $edit_applies_to, $wgUser );
595 - } elseif ( $edit_type == 'summarize' ) {
596 - $edit_applies_to->setSummary( $edit_page );
597 - $edit_applies_to->commitRevision(
598 - Threads::CHANGE_EDITED_SUMMARY,
599 - $edit_applies_to, $edit_summary,
600 - $bump
601 - );
602 - } elseif ( $edit_type == 'editExisting' ) {
603 - // Use a separate type if the content is blanked.
604 - $type = strlen( trim( $new_text ) )
605 - ? Threads::CHANGE_EDITED_ROOT
606 - : Threads::CHANGE_ROOT_BLANKED;
607 -
608 - if ( $signature && !$noSignature ) {
609 - $thread->setSignature( $signature );
610 - }
611 -
612 - // Add the history entry.
613 - $thread->commitRevision( $type, $thread, $edit_summary, $bump );
614 -
615 - // Update subject if applicable.
616 - if ( $subject && $subject != $thread->subject() ) {
617 - $thread->setSubject( $subject );
618 - $thread->commitRevision( Threads::CHANGE_EDITED_SUBJECT,
619 - $thread, $e->summary );
620 -
621 - // Disabled page-moving for now.
622 - // $this->renameThread( $thread, $subject, $e->summary );
623 - }
624 - } else {
625 - $thread = Thread::create(
626 - $edit_page, $article, null,
627 - Threads::TYPE_NORMAL, $subject,
628 - $edit_summary, null, $signature
629 - );
630 - }
631 -
632860 return $thread;
633861 }
634862
Index: trunk/extensions/LiquidThreads/classes/Dispatch.php
@@ -67,8 +67,7 @@
6868 // this clause and the next must be in this order.
6969 $viewname = 'ThreadDiffView';
7070 } else if ( $action == 'history'
71 - || $request->getVal( 'diff', null ) !== null
72 - || $request->getVal( 'oldid', null ) !== null ) {
 71+ || $request->getVal( 'diff', null ) !== null ) {
7372 $viewname = 'IndividualThreadHistoryView';
7473 } else if ( $action == 'protect' || $action == 'unprotect' ) {
7574 $viewname = 'ThreadProtectionFormView';
Index: trunk/extensions/LiquidThreads/pages/ThreadPermalinkView.php
@@ -206,7 +206,8 @@
207207 }
208208
209209 // Handle action=edit stuff
210 - if ( $this->request->getVal( 'action' ) == 'edit' ) {
 210+ if ( $this->request->getVal( 'action' ) == 'edit' &&
 211+ !$this->request->getVal( 'lqt_method', null ) ) {
211212 // Rewrite to lqt_method = edit
212213 $this->request->setVal( 'lqt_method', 'edit' );
213214 $this->request->setVal( 'lqt_operand', $this->thread->id() );
Index: trunk/extensions/LiquidThreads/pages/TalkpageView.php
@@ -304,7 +304,7 @@
305305 if ( $this->methodApplies( 'talkpage_new_thread' ) ) {
306306 $params = array( 'class' => 'lqt-new-thread lqt-edit-form' );
307307 $this->output->addHTML( Xml::openElement( 'div', $params ) );
308 - $this->showNewThreadForm();
 308+ $this->showNewThreadForm( $this->article );
309309 $this->output->addHTML( Xml::closeElement( 'div' ) );
310310 } else {
311311 $this->output->addHTML( Xml::tags( 'div',
Index: trunk/extensions/LiquidThreads/api/ApiThreadAction.php
@@ -297,8 +297,15 @@
298298 $article->getTitle()->resetArticleID( $articleId );
299299 $title->resetArticleID( $articleId );
300300
301 - $thread = LqtView::postEditUpdates( 'new', null, $article, $talkpage,
302 - $subject, $summary, null, $text, $bump, $signature );
 301+ $thread = LqtView::newPostMetadataUpdates(
 302+ array(
 303+ 'root' => $article,
 304+ 'talkpage' => $talkpage,
 305+ 'subject' => $subject,
 306+ 'signature' => $signature,
 307+ 'summary' => $summary,
 308+ 'text' => $text,
 309+ ) );
303310
304311 $maxLag = wfGetLB()->getMaxLag();
305312 $maxLag = $maxLag[1];
@@ -404,8 +411,16 @@
405412 return;
406413 }
407414
408 - $thread = LqtView::postEditUpdates( 'editExisting', null, $article, $talkpage,
409 - $subject, $summary, $thread, $text, $bump, $signature );
 415+ $thread = LqtView::editMetadataUpdates(
 416+ array(
 417+ 'root' => $article,
 418+ 'thread' => $thread,
 419+ 'subject' => $subject,
 420+ 'signature' => $signature,
 421+ 'summary' => $summary,
 422+ 'text' => $text,
 423+ 'bump' => $bump,
 424+ ) );
410425
411426 $maxLag = wfGetLB()->getMaxLag();
412427 $maxLag = $maxLag[1];
@@ -518,8 +533,15 @@
519534 $article->getTitle()->resetArticleID( $articleId );
520535 $title->resetArticleID( $articleId );
521536
522 - $thread = LqtView::postEditUpdates( 'reply', $replyTo, $article, $talkpage,
523 - $subject, $summary, null, $text, $bump, $signature );
 537+ $thread = LqtView::replyMetadataUpdates(
 538+ array(
 539+ 'root' => $article,
 540+ 'replyTo' => $replyTo,
 541+ 'signature' => $signature,
 542+ 'summary' => $summary,
 543+ 'text' => $text,
 544+ 'bump' => $bump,
 545+ ) );
524546
525547 $maxLag = wfGetLB()->getMaxLag();
526548 $maxLag = $maxLag[1];
@@ -780,4 +802,4 @@
781803 public function getVersion() {
782804 return __CLASS__ . ': $Id$';
783805 }
784 -}
\ No newline at end of file
 806+}

Status & tagging log