Index: trunk/extensions/LiquidThreads/classes/View.php |
— | — | @@ -283,7 +283,7 @@ |
284 | 284 | * Return an HTML form element whose value is gotten from the request. |
285 | 285 | * TODO: figure out a clean way to expand this to other forms. |
286 | 286 | */ |
287 | | - function perpetuate( $name, $as ) { |
| 287 | + function perpetuate( $name, $as = 'hidden' ) { |
288 | 288 | $value = $this->request->getVal( $name, '' ); |
289 | 289 | if ( $as == 'hidden' ) { |
290 | 290 | return Xml::hidden( $name, $value ); |
— | — | @@ -298,27 +298,6 @@ |
299 | 299 | '<a href="' . $log_url . '">' . wfMsg( 'lqt_protectedfromreply_link' ) . '</a>' ) ); |
300 | 300 | } |
301 | 301 | |
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 | | - |
323 | 302 | function doInlineEditForm() { |
324 | 303 | $method = $this->request->getVal( 'lqt_method' ); |
325 | 304 | $operand = $this->request->getVal( 'lqt_operand' ); |
— | — | @@ -328,155 +307,406 @@ |
329 | 308 | if ( $method == 'reply' ) { |
330 | 309 | $this->showReplyForm( $thread ); |
331 | 310 | } elseif ( $method == 'talkpage_new_thread' ) { |
332 | | - $this->showNewThreadForm(); |
| 311 | + $this->showNewThreadForm( $this->article ); |
333 | 312 | } elseif ( $method == 'edit' ) { |
334 | 313 | $this->showPostEditingForm( $thread ); |
335 | 314 | } |
336 | 315 | |
337 | 316 | $this->output->setArticleBodyOnly( true ); |
338 | 317 | } |
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; |
362 | 327 | } |
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(); |
383 | 339 | } |
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(); |
403 | 340 | } |
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 | + |
412 | 344 | LqtHooks::$editTalkpage = $talkpage; |
413 | 345 | 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 | + |
418 | 350 | $e = new EditPage( $article ); |
419 | | - |
| 351 | + |
420 | 352 | global $wgRequest; |
421 | 353 | // Quietly force a preview if no subject has been specified. |
422 | | - if ( ( !$valid_subject && $subject ) || ( $subject_expected && !$subject ) ) { |
| 354 | + if ( !$subjectOk ) { |
423 | 355 | // Dirty hack to prevent saving from going ahead |
424 | 356 | $wgRequest->setVal( 'wpPreview', true ); |
425 | | - |
| 357 | + |
426 | 358 | if ( $this->request->wasPosted() ) { |
427 | 359 | if ( !$subject ) { |
428 | 360 | $msg = 'lqt_empty_subject'; |
429 | 361 | } else { |
430 | 362 | $msg = 'lqt_invalid_subject'; |
431 | 363 | } |
432 | | - |
| 364 | + |
433 | 365 | $e->editFormPageTop .= |
434 | 366 | Xml::tags( 'div', array( 'class' => 'error' ), |
435 | 367 | wfMsgExt( $msg, 'parse' ) ); |
436 | 368 | } |
437 | 369 | } |
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 | + ) |
455 | 405 | ); |
456 | | - $wgRequest->setVal( 'wpSummary', $summary ); |
| 406 | + |
| 407 | + if ( $submitted_nonce && $nonce_key ) { |
| 408 | + global $wgMemc; |
| 409 | + $wgMemc->set( $nonce_key, 1, 3600 ); |
| 410 | + } |
457 | 411 | } |
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 | + |
459 | 463 | // 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 | + |
467 | 469 | $e->suppressIntro = true; |
468 | 470 | $e->editFormTextBeforeContent .= |
469 | 471 | $this->perpetuate( 'lqt_method', 'hidden' ) . |
470 | 472 | $this->perpetuate( 'lqt_operand', 'hidden' ) . |
471 | 473 | Xml::hidden( 'lqt_nonce', wfGenerateToken() ) . |
472 | 474 | 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; |
473 | 681 | |
| 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 ) { |
474 | 704 | $signatureText = $this->request->getVal( 'wpLqtSignature', null ); |
475 | 705 | |
476 | 706 | 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(); |
481 | 711 | } |
482 | 712 | } |
483 | 713 | |
— | — | @@ -497,137 +727,135 @@ |
498 | 728 | ); |
499 | 729 | |
500 | 730 | $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" ); |
518 | 741 | } |
519 | 742 | } |
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 ); |
534 | 750 | } |
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" ); |
553 | 776 | } |
554 | 777 | } |
| 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']); |
555 | 811 | |
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 ); |
568 | 824 | } |
| 825 | + |
| 826 | + return $thread; |
569 | 827 | } |
570 | 828 | |
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 ) |
573 | 830 | { |
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 { |
579 | 843 | global $wgUser; |
580 | 844 | $signature = LqtView::getUserSignature( $wgUser ); |
581 | | - $noSignature = true; |
582 | 845 | } |
| 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']; |
583 | 853 | |
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 | + ); |
586 | 859 | |
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 | | - |
632 | 860 | return $thread; |
633 | 861 | } |
634 | 862 | |
Index: trunk/extensions/LiquidThreads/classes/Dispatch.php |
— | — | @@ -67,8 +67,7 @@ |
68 | 68 | // this clause and the next must be in this order. |
69 | 69 | $viewname = 'ThreadDiffView'; |
70 | 70 | } else if ( $action == 'history' |
71 | | - || $request->getVal( 'diff', null ) !== null |
72 | | - || $request->getVal( 'oldid', null ) !== null ) { |
| 71 | + || $request->getVal( 'diff', null ) !== null ) { |
73 | 72 | $viewname = 'IndividualThreadHistoryView'; |
74 | 73 | } else if ( $action == 'protect' || $action == 'unprotect' ) { |
75 | 74 | $viewname = 'ThreadProtectionFormView'; |
Index: trunk/extensions/LiquidThreads/pages/ThreadPermalinkView.php |
— | — | @@ -206,7 +206,8 @@ |
207 | 207 | } |
208 | 208 | |
209 | 209 | // 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 ) ) { |
211 | 212 | // Rewrite to lqt_method = edit |
212 | 213 | $this->request->setVal( 'lqt_method', 'edit' ); |
213 | 214 | $this->request->setVal( 'lqt_operand', $this->thread->id() ); |
Index: trunk/extensions/LiquidThreads/pages/TalkpageView.php |
— | — | @@ -304,7 +304,7 @@ |
305 | 305 | if ( $this->methodApplies( 'talkpage_new_thread' ) ) { |
306 | 306 | $params = array( 'class' => 'lqt-new-thread lqt-edit-form' ); |
307 | 307 | $this->output->addHTML( Xml::openElement( 'div', $params ) ); |
308 | | - $this->showNewThreadForm(); |
| 308 | + $this->showNewThreadForm( $this->article ); |
309 | 309 | $this->output->addHTML( Xml::closeElement( 'div' ) ); |
310 | 310 | } else { |
311 | 311 | $this->output->addHTML( Xml::tags( 'div', |
Index: trunk/extensions/LiquidThreads/api/ApiThreadAction.php |
— | — | @@ -297,8 +297,15 @@ |
298 | 298 | $article->getTitle()->resetArticleID( $articleId ); |
299 | 299 | $title->resetArticleID( $articleId ); |
300 | 300 | |
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 | + ) ); |
303 | 310 | |
304 | 311 | $maxLag = wfGetLB()->getMaxLag(); |
305 | 312 | $maxLag = $maxLag[1]; |
— | — | @@ -404,8 +411,16 @@ |
405 | 412 | return; |
406 | 413 | } |
407 | 414 | |
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 | + ) ); |
410 | 425 | |
411 | 426 | $maxLag = wfGetLB()->getMaxLag(); |
412 | 427 | $maxLag = $maxLag[1]; |
— | — | @@ -518,8 +533,15 @@ |
519 | 534 | $article->getTitle()->resetArticleID( $articleId ); |
520 | 535 | $title->resetArticleID( $articleId ); |
521 | 536 | |
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 | + ) ); |
524 | 546 | |
525 | 547 | $maxLag = wfGetLB()->getMaxLag(); |
526 | 548 | $maxLag = $maxLag[1]; |
— | — | @@ -780,4 +802,4 @@ |
781 | 803 | public function getVersion() { |
782 | 804 | return __CLASS__ . ': $Id$'; |
783 | 805 | } |
784 | | -} |
\ No newline at end of file |
| 806 | +} |