ApiPurge.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <?php
  2. /**
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along
  14. * with this program; if not, write to the Free Software Foundation, Inc.,
  15. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. * http://www.gnu.org/copyleft/gpl.html
  17. *
  18. * @file
  19. */
  20. use MediaWiki\Logger\LoggerFactory;
  21. /**
  22. * API interface for page purging
  23. * @ingroup API
  24. */
  25. class ApiPurge extends ApiBase {
  26. private $mPageSet = null;
  27. /**
  28. * Purges the cache of a page
  29. */
  30. public function execute() {
  31. $params = $this->extractRequestParams();
  32. $continuationManager = new ApiContinuationManager( $this, [], [] );
  33. $this->setContinuationManager( $continuationManager );
  34. $forceLinkUpdate = $params['forcelinkupdate'];
  35. $forceRecursiveLinkUpdate = $params['forcerecursivelinkupdate'];
  36. $pageSet = $this->getPageSet();
  37. $pageSet->execute();
  38. $result = $pageSet->getInvalidTitlesAndRevisions();
  39. $user = $this->getUser();
  40. foreach ( $pageSet->getGoodTitles() as $title ) {
  41. $r = [];
  42. ApiQueryBase::addTitleInfo( $r, $title );
  43. $page = WikiPage::factory( $title );
  44. if ( !$user->pingLimiter( 'purge' ) ) {
  45. // Directly purge and skip the UI part of purge()
  46. $page->doPurge();
  47. $r['purged'] = true;
  48. } else {
  49. $this->addWarning( 'apierror-ratelimited' );
  50. }
  51. if ( $forceLinkUpdate || $forceRecursiveLinkUpdate ) {
  52. if ( !$user->pingLimiter( 'linkpurge' ) ) {
  53. # Logging to better see expensive usage patterns
  54. if ( $forceRecursiveLinkUpdate ) {
  55. LoggerFactory::getInstance( 'RecursiveLinkPurge' )->info(
  56. "Recursive link purge enqueued for {title}",
  57. [
  58. 'user' => $this->getUser()->getName(),
  59. 'title' => $title->getPrefixedText()
  60. ]
  61. );
  62. }
  63. $page->updateParserCache( [
  64. 'causeAction' => 'api-purge',
  65. 'causeAgent' => $this->getUser()->getName(),
  66. ] );
  67. $page->doSecondaryDataUpdates( [
  68. 'recursive' => $forceRecursiveLinkUpdate,
  69. 'causeAction' => 'api-purge',
  70. 'causeAgent' => $this->getUser()->getName(),
  71. 'defer' => DeferredUpdates::PRESEND,
  72. ] );
  73. $r['linkupdate'] = true;
  74. } else {
  75. $this->addWarning( 'apierror-ratelimited' );
  76. $forceLinkUpdate = false;
  77. }
  78. }
  79. $result[] = $r;
  80. }
  81. $apiResult = $this->getResult();
  82. ApiResult::setIndexedTagName( $result, 'page' );
  83. $apiResult->addValue( null, $this->getModuleName(), $result );
  84. $values = $pageSet->getNormalizedTitlesAsResult( $apiResult );
  85. if ( $values ) {
  86. $apiResult->addValue( null, 'normalized', $values );
  87. }
  88. $values = $pageSet->getConvertedTitlesAsResult( $apiResult );
  89. if ( $values ) {
  90. $apiResult->addValue( null, 'converted', $values );
  91. }
  92. $values = $pageSet->getRedirectTitlesAsResult( $apiResult );
  93. if ( $values ) {
  94. $apiResult->addValue( null, 'redirects', $values );
  95. }
  96. $this->setContinuationManager( null );
  97. $continuationManager->setContinuationIntoResult( $apiResult );
  98. }
  99. /**
  100. * Get a cached instance of an ApiPageSet object
  101. * @return ApiPageSet
  102. */
  103. private function getPageSet() {
  104. if ( $this->mPageSet === null ) {
  105. $this->mPageSet = new ApiPageSet( $this );
  106. }
  107. return $this->mPageSet;
  108. }
  109. public function isWriteMode() {
  110. return true;
  111. }
  112. public function mustBePosted() {
  113. return true;
  114. }
  115. public function getAllowedParams( $flags = 0 ) {
  116. $result = [
  117. 'forcelinkupdate' => false,
  118. 'forcerecursivelinkupdate' => false,
  119. 'continue' => [
  120. ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
  121. ],
  122. ];
  123. if ( $flags ) {
  124. $result += $this->getPageSet()->getFinalParams( $flags );
  125. }
  126. return $result;
  127. }
  128. protected function getExamplesMessages() {
  129. return [
  130. 'action=purge&titles=Main_Page|API'
  131. => 'apihelp-purge-example-simple',
  132. 'action=purge&generator=allpages&gapnamespace=0&gaplimit=10'
  133. => 'apihelp-purge-example-generator',
  134. ];
  135. }
  136. public function getHelpUrls() {
  137. return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Purge';
  138. }
  139. }