Index: trunk/phase3/includes/WikiPage.php |
— | — | @@ -119,128 +119,6 @@ |
120 | 120 | } |
121 | 121 | |
122 | 122 | /** |
123 | | - * If this page is a redirect, get its target |
124 | | - * |
125 | | - * The target will be fetched from the redirect table if possible. |
126 | | - * If this page doesn't have an entry there, call insertRedirect() |
127 | | - * @return Title|mixed object, or null if this page is not a redirect |
128 | | - */ |
129 | | - public function getRedirectTarget() { |
130 | | - if ( !$this->mTitle->isRedirect() ) { |
131 | | - return null; |
132 | | - } |
133 | | - |
134 | | - if ( $this->mRedirectTarget !== null ) { |
135 | | - return $this->mRedirectTarget; |
136 | | - } |
137 | | - |
138 | | - # Query the redirect table |
139 | | - $dbr = wfGetDB( DB_SLAVE ); |
140 | | - $row = $dbr->selectRow( 'redirect', |
141 | | - array( 'rd_namespace', 'rd_title', 'rd_fragment', 'rd_interwiki' ), |
142 | | - array( 'rd_from' => $this->getId() ), |
143 | | - __METHOD__ |
144 | | - ); |
145 | | - |
146 | | - // rd_fragment and rd_interwiki were added later, populate them if empty |
147 | | - if ( $row && !is_null( $row->rd_fragment ) && !is_null( $row->rd_interwiki ) ) { |
148 | | - return $this->mRedirectTarget = Title::makeTitle( |
149 | | - $row->rd_namespace, $row->rd_title, |
150 | | - $row->rd_fragment, $row->rd_interwiki ); |
151 | | - } |
152 | | - |
153 | | - # This page doesn't have an entry in the redirect table |
154 | | - return $this->mRedirectTarget = $this->insertRedirect(); |
155 | | - } |
156 | | - |
157 | | - /** |
158 | | - * Insert an entry for this page into the redirect table. |
159 | | - * |
160 | | - * Don't call this function directly unless you know what you're doing. |
161 | | - * @return Title object or null if not a redirect |
162 | | - */ |
163 | | - public function insertRedirect() { |
164 | | - // recurse through to only get the final target |
165 | | - $retval = Title::newFromRedirectRecurse( $this->getRawText() ); |
166 | | - if ( !$retval ) { |
167 | | - return null; |
168 | | - } |
169 | | - $this->insertRedirectEntry( $retval ); |
170 | | - return $retval; |
171 | | - } |
172 | | - |
173 | | - /** |
174 | | - * Insert or update the redirect table entry for this page to indicate |
175 | | - * it redirects to $rt . |
176 | | - * @param $rt Title redirect target |
177 | | - */ |
178 | | - public function insertRedirectEntry( $rt ) { |
179 | | - $dbw = wfGetDB( DB_MASTER ); |
180 | | - $dbw->replace( 'redirect', array( 'rd_from' ), |
181 | | - array( |
182 | | - 'rd_from' => $this->getId(), |
183 | | - 'rd_namespace' => $rt->getNamespace(), |
184 | | - 'rd_title' => $rt->getDBkey(), |
185 | | - 'rd_fragment' => $rt->getFragment(), |
186 | | - 'rd_interwiki' => $rt->getInterwiki(), |
187 | | - ), |
188 | | - __METHOD__ |
189 | | - ); |
190 | | - } |
191 | | - |
192 | | - /** |
193 | | - * Get the Title object or URL this page redirects to |
194 | | - * |
195 | | - * @return mixed false, Title of in-wiki target, or string with URL |
196 | | - */ |
197 | | - public function followRedirect() { |
198 | | - return $this->getRedirectURL( $this->getRedirectTarget() ); |
199 | | - } |
200 | | - |
201 | | - /** |
202 | | - * Get the Title object or URL to use for a redirect. We use Title |
203 | | - * objects for same-wiki, non-special redirects and URLs for everything |
204 | | - * else. |
205 | | - * @param $rt Title Redirect target |
206 | | - * @return mixed false, Title object of local target, or string with URL |
207 | | - */ |
208 | | - public function getRedirectURL( $rt ) { |
209 | | - if ( !$rt ) { |
210 | | - return false; |
211 | | - } |
212 | | - |
213 | | - if ( $rt->isExternal() ) { |
214 | | - if ( $rt->isLocal() ) { |
215 | | - // Offsite wikis need an HTTP redirect. |
216 | | - // |
217 | | - // This can be hard to reverse and may produce loops, |
218 | | - // so they may be disabled in the site configuration. |
219 | | - $source = $this->mTitle->getFullURL( 'redirect=no' ); |
220 | | - return $rt->getFullURL( 'rdfrom=' . urlencode( $source ) ); |
221 | | - } else { |
222 | | - // External pages pages without "local" bit set are not valid |
223 | | - // redirect targets |
224 | | - return false; |
225 | | - } |
226 | | - } |
227 | | - |
228 | | - if ( $rt->isSpecialPage() ) { |
229 | | - // Gotta handle redirects to special pages differently: |
230 | | - // Fill the HTTP response "Location" header and ignore |
231 | | - // the rest of the page we're on. |
232 | | - // |
233 | | - // Some pages are not valid targets |
234 | | - if ( $rt->isValidRedirectTarget() ) { |
235 | | - return $rt->getFullURL(); |
236 | | - } else { |
237 | | - return false; |
238 | | - } |
239 | | - } |
240 | | - |
241 | | - return $rt; |
242 | | - } |
243 | | - |
244 | | - /** |
245 | 123 | * Get the title object of the article |
246 | 124 | * @return Title object of this page |
247 | 125 | */ |
— | — | @@ -265,36 +143,6 @@ |
266 | 144 | } |
267 | 145 | |
268 | 146 | /** |
269 | | - * Get the text that needs to be saved in order to undo all revisions |
270 | | - * between $undo and $undoafter. Revisions must belong to the same page, |
271 | | - * must exist and must not be deleted |
272 | | - * @param $undo Revision |
273 | | - * @param $undoafter Revision Must be an earlier revision than $undo |
274 | | - * @return mixed string on success, false on failure |
275 | | - */ |
276 | | - public function getUndoText( Revision $undo, Revision $undoafter = null ) { |
277 | | - $cur_text = $this->getRawText(); |
278 | | - if ( $cur_text === false ) { |
279 | | - return false; // no page |
280 | | - } |
281 | | - $undo_text = $undo->getText(); |
282 | | - $undoafter_text = $undoafter->getText(); |
283 | | - |
284 | | - if ( $cur_text == $undo_text ) { |
285 | | - # No use doing a merge if it's just a straight revert. |
286 | | - return $undoafter_text; |
287 | | - } |
288 | | - |
289 | | - $undone_text = ''; |
290 | | - |
291 | | - if ( !wfMerge( $undo_text, $undoafter_text, $cur_text, $undone_text ) ) { |
292 | | - return false; |
293 | | - } |
294 | | - |
295 | | - return $undone_text; |
296 | | - } |
297 | | - |
298 | | - /** |
299 | 147 | * Return the list of revision fields that should be selected to create |
300 | 148 | * a new page. |
301 | 149 | * |
— | — | @@ -445,49 +293,6 @@ |
446 | 294 | } |
447 | 295 | |
448 | 296 | /** |
449 | | - * Determine whether a page would be suitable for being counted as an |
450 | | - * article in the site_stats table based on the title & its content |
451 | | - * |
452 | | - * @param $editInfo Object or false: object returned by prepareTextForEdit(), |
453 | | - * if false, the current database state will be used |
454 | | - * @return Boolean |
455 | | - */ |
456 | | - public function isCountable( $editInfo = false ) { |
457 | | - global $wgArticleCountMethod; |
458 | | - |
459 | | - if ( !$this->mTitle->isContentPage() ) { |
460 | | - return false; |
461 | | - } |
462 | | - |
463 | | - $text = $editInfo ? $editInfo->pst : false; |
464 | | - |
465 | | - if ( $this->isRedirect( $text ) ) { |
466 | | - return false; |
467 | | - } |
468 | | - |
469 | | - switch ( $wgArticleCountMethod ) { |
470 | | - case 'any': |
471 | | - return true; |
472 | | - case 'comma': |
473 | | - if ( $text === false ) { |
474 | | - $text = $this->getRawText(); |
475 | | - } |
476 | | - return strpos( $text, ',' ) !== false; |
477 | | - case 'link': |
478 | | - if ( $editInfo ) { |
479 | | - // ParserOutput::getLinks() is a 2D array of page links, so |
480 | | - // to be really correct we would need to recurse in the array |
481 | | - // but the main array should only have items in it if there are |
482 | | - // links. |
483 | | - return (bool)count( $editInfo->output->getLinks() ); |
484 | | - } else { |
485 | | - return (bool)wfGetDB( DB_SLAVE )->selectField( 'pagelinks', 1, |
486 | | - array( 'pl_from' => $this->getId() ), __METHOD__ ); |
487 | | - } |
488 | | - } |
489 | | - } |
490 | | - |
491 | | - /** |
492 | 297 | * Tests if the article text represents a redirect |
493 | 298 | * |
494 | 299 | * @param $text mixed string containing article contents, or boolean |
— | — | @@ -714,6 +519,171 @@ |
715 | 520 | } |
716 | 521 | |
717 | 522 | /** |
| 523 | + * Determine whether a page would be suitable for being counted as an |
| 524 | + * article in the site_stats table based on the title & its content |
| 525 | + * |
| 526 | + * @param $editInfo Object or false: object returned by prepareTextForEdit(), |
| 527 | + * if false, the current database state will be used |
| 528 | + * @return Boolean |
| 529 | + */ |
| 530 | + public function isCountable( $editInfo = false ) { |
| 531 | + global $wgArticleCountMethod; |
| 532 | + |
| 533 | + if ( !$this->mTitle->isContentPage() ) { |
| 534 | + return false; |
| 535 | + } |
| 536 | + |
| 537 | + $text = $editInfo ? $editInfo->pst : false; |
| 538 | + |
| 539 | + if ( $this->isRedirect( $text ) ) { |
| 540 | + return false; |
| 541 | + } |
| 542 | + |
| 543 | + switch ( $wgArticleCountMethod ) { |
| 544 | + case 'any': |
| 545 | + return true; |
| 546 | + case 'comma': |
| 547 | + if ( $text === false ) { |
| 548 | + $text = $this->getRawText(); |
| 549 | + } |
| 550 | + return strpos( $text, ',' ) !== false; |
| 551 | + case 'link': |
| 552 | + if ( $editInfo ) { |
| 553 | + // ParserOutput::getLinks() is a 2D array of page links, so |
| 554 | + // to be really correct we would need to recurse in the array |
| 555 | + // but the main array should only have items in it if there are |
| 556 | + // links. |
| 557 | + return (bool)count( $editInfo->output->getLinks() ); |
| 558 | + } else { |
| 559 | + return (bool)wfGetDB( DB_SLAVE )->selectField( 'pagelinks', 1, |
| 560 | + array( 'pl_from' => $this->getId() ), __METHOD__ ); |
| 561 | + } |
| 562 | + } |
| 563 | + } |
| 564 | + |
| 565 | + /** |
| 566 | + * If this page is a redirect, get its target |
| 567 | + * |
| 568 | + * The target will be fetched from the redirect table if possible. |
| 569 | + * If this page doesn't have an entry there, call insertRedirect() |
| 570 | + * @return Title|mixed object, or null if this page is not a redirect |
| 571 | + */ |
| 572 | + public function getRedirectTarget() { |
| 573 | + if ( !$this->mTitle->isRedirect() ) { |
| 574 | + return null; |
| 575 | + } |
| 576 | + |
| 577 | + if ( $this->mRedirectTarget !== null ) { |
| 578 | + return $this->mRedirectTarget; |
| 579 | + } |
| 580 | + |
| 581 | + # Query the redirect table |
| 582 | + $dbr = wfGetDB( DB_SLAVE ); |
| 583 | + $row = $dbr->selectRow( 'redirect', |
| 584 | + array( 'rd_namespace', 'rd_title', 'rd_fragment', 'rd_interwiki' ), |
| 585 | + array( 'rd_from' => $this->getId() ), |
| 586 | + __METHOD__ |
| 587 | + ); |
| 588 | + |
| 589 | + // rd_fragment and rd_interwiki were added later, populate them if empty |
| 590 | + if ( $row && !is_null( $row->rd_fragment ) && !is_null( $row->rd_interwiki ) ) { |
| 591 | + return $this->mRedirectTarget = Title::makeTitle( |
| 592 | + $row->rd_namespace, $row->rd_title, |
| 593 | + $row->rd_fragment, $row->rd_interwiki ); |
| 594 | + } |
| 595 | + |
| 596 | + # This page doesn't have an entry in the redirect table |
| 597 | + return $this->mRedirectTarget = $this->insertRedirect(); |
| 598 | + } |
| 599 | + |
| 600 | + /** |
| 601 | + * Insert an entry for this page into the redirect table. |
| 602 | + * |
| 603 | + * Don't call this function directly unless you know what you're doing. |
| 604 | + * @return Title object or null if not a redirect |
| 605 | + */ |
| 606 | + public function insertRedirect() { |
| 607 | + // recurse through to only get the final target |
| 608 | + $retval = Title::newFromRedirectRecurse( $this->getRawText() ); |
| 609 | + if ( !$retval ) { |
| 610 | + return null; |
| 611 | + } |
| 612 | + $this->insertRedirectEntry( $retval ); |
| 613 | + return $retval; |
| 614 | + } |
| 615 | + |
| 616 | + /** |
| 617 | + * Insert or update the redirect table entry for this page to indicate |
| 618 | + * it redirects to $rt . |
| 619 | + * @param $rt Title redirect target |
| 620 | + */ |
| 621 | + public function insertRedirectEntry( $rt ) { |
| 622 | + $dbw = wfGetDB( DB_MASTER ); |
| 623 | + $dbw->replace( 'redirect', array( 'rd_from' ), |
| 624 | + array( |
| 625 | + 'rd_from' => $this->getId(), |
| 626 | + 'rd_namespace' => $rt->getNamespace(), |
| 627 | + 'rd_title' => $rt->getDBkey(), |
| 628 | + 'rd_fragment' => $rt->getFragment(), |
| 629 | + 'rd_interwiki' => $rt->getInterwiki(), |
| 630 | + ), |
| 631 | + __METHOD__ |
| 632 | + ); |
| 633 | + } |
| 634 | + |
| 635 | + /** |
| 636 | + * Get the Title object or URL this page redirects to |
| 637 | + * |
| 638 | + * @return mixed false, Title of in-wiki target, or string with URL |
| 639 | + */ |
| 640 | + public function followRedirect() { |
| 641 | + return $this->getRedirectURL( $this->getRedirectTarget() ); |
| 642 | + } |
| 643 | + |
| 644 | + /** |
| 645 | + * Get the Title object or URL to use for a redirect. We use Title |
| 646 | + * objects for same-wiki, non-special redirects and URLs for everything |
| 647 | + * else. |
| 648 | + * @param $rt Title Redirect target |
| 649 | + * @return mixed false, Title object of local target, or string with URL |
| 650 | + */ |
| 651 | + public function getRedirectURL( $rt ) { |
| 652 | + if ( !$rt ) { |
| 653 | + return false; |
| 654 | + } |
| 655 | + |
| 656 | + if ( $rt->isExternal() ) { |
| 657 | + if ( $rt->isLocal() ) { |
| 658 | + // Offsite wikis need an HTTP redirect. |
| 659 | + // |
| 660 | + // This can be hard to reverse and may produce loops, |
| 661 | + // so they may be disabled in the site configuration. |
| 662 | + $source = $this->mTitle->getFullURL( 'redirect=no' ); |
| 663 | + return $rt->getFullURL( 'rdfrom=' . urlencode( $source ) ); |
| 664 | + } else { |
| 665 | + // External pages pages without "local" bit set are not valid |
| 666 | + // redirect targets |
| 667 | + return false; |
| 668 | + } |
| 669 | + } |
| 670 | + |
| 671 | + if ( $rt->isSpecialPage() ) { |
| 672 | + // Gotta handle redirects to special pages differently: |
| 673 | + // Fill the HTTP response "Location" header and ignore |
| 674 | + // the rest of the page we're on. |
| 675 | + // |
| 676 | + // Some pages are not valid targets |
| 677 | + if ( $rt->isValidRedirectTarget() ) { |
| 678 | + return $rt->getFullURL(); |
| 679 | + } else { |
| 680 | + return false; |
| 681 | + } |
| 682 | + } |
| 683 | + |
| 684 | + return $rt; |
| 685 | + } |
| 686 | + |
| 687 | + /** |
718 | 688 | * Get a list of users who have edited this article, not including the user who made |
719 | 689 | * the most recent revision, which you can get from $article->getUser() if you want it |
720 | 690 | * @return UserArrayFromResult |
— | — | @@ -1100,6 +1070,36 @@ |
1101 | 1071 | } |
1102 | 1072 | |
1103 | 1073 | /** |
| 1074 | + * Get the text that needs to be saved in order to undo all revisions |
| 1075 | + * between $undo and $undoafter. Revisions must belong to the same page, |
| 1076 | + * must exist and must not be deleted |
| 1077 | + * @param $undo Revision |
| 1078 | + * @param $undoafter Revision Must be an earlier revision than $undo |
| 1079 | + * @return mixed string on success, false on failure |
| 1080 | + */ |
| 1081 | + public function getUndoText( Revision $undo, Revision $undoafter = null ) { |
| 1082 | + $cur_text = $this->getRawText(); |
| 1083 | + if ( $cur_text === false ) { |
| 1084 | + return false; // no page |
| 1085 | + } |
| 1086 | + $undo_text = $undo->getText(); |
| 1087 | + $undoafter_text = $undoafter->getText(); |
| 1088 | + |
| 1089 | + if ( $cur_text == $undo_text ) { |
| 1090 | + # No use doing a merge if it's just a straight revert. |
| 1091 | + return $undoafter_text; |
| 1092 | + } |
| 1093 | + |
| 1094 | + $undone_text = ''; |
| 1095 | + |
| 1096 | + if ( !wfMerge( $undo_text, $undoafter_text, $cur_text, $undone_text ) ) { |
| 1097 | + return false; |
| 1098 | + } |
| 1099 | + |
| 1100 | + return $undone_text; |
| 1101 | + } |
| 1102 | + |
| 1103 | + /** |
1104 | 1104 | * @param $section empty/null/false or a section number (0, 1, 2, T1, T2...) |
1105 | 1105 | * @param $text String: new text of the section |
1106 | 1106 | * @param $sectionTitle String: new section's subject, only if $section is 'new' |