ApiQueryQueryPage.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <?php
  2. /**
  3. *
  4. *
  5. * Created on Dec 22, 2010
  6. *
  7. * Copyright © 2010 Roan Kattouw "<Firstname>.<Lastname>@gmail.com"
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License along
  20. * with this program; if not, write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  22. * http://www.gnu.org/copyleft/gpl.html
  23. *
  24. * @file
  25. */
  26. /**
  27. * Query module to get the results of a QueryPage-based special page
  28. *
  29. * @ingroup API
  30. */
  31. class ApiQueryQueryPage extends ApiQueryGeneratorBase {
  32. private $qpMap;
  33. public function __construct( ApiQuery $query, $moduleName ) {
  34. parent::__construct( $query, $moduleName, 'qp' );
  35. // Build mapping from special page names to QueryPage classes
  36. $uselessQueryPages = $this->getConfig()->get( 'APIUselessQueryPages' );
  37. $this->qpMap = [];
  38. foreach ( QueryPage::getPages() as $page ) {
  39. if ( !in_array( $page[1], $uselessQueryPages ) ) {
  40. $this->qpMap[$page[1]] = $page[0];
  41. }
  42. }
  43. }
  44. public function execute() {
  45. $this->run();
  46. }
  47. public function executeGenerator( $resultPageSet ) {
  48. $this->run( $resultPageSet );
  49. }
  50. /**
  51. * @param ApiPageSet $resultPageSet
  52. */
  53. public function run( $resultPageSet = null ) {
  54. $params = $this->extractRequestParams();
  55. $result = $this->getResult();
  56. /** @var QueryPage $qp */
  57. $qp = new $this->qpMap[$params['page']]();
  58. if ( !$qp->userCanExecute( $this->getUser() ) ) {
  59. $this->dieWithError( 'apierror-specialpage-cantexecute' );
  60. }
  61. $r = [ 'name' => $params['page'] ];
  62. if ( $qp->isCached() ) {
  63. if ( !$qp->isCacheable() ) {
  64. $r['disabled'] = true;
  65. } else {
  66. $r['cached'] = true;
  67. $ts = $qp->getCachedTimestamp();
  68. if ( $ts ) {
  69. $r['cachedtimestamp'] = wfTimestamp( TS_ISO_8601, $ts );
  70. }
  71. $r['maxresults'] = $this->getConfig()->get( 'QueryCacheLimit' );
  72. }
  73. }
  74. $result->addValue( [ 'query' ], $this->getModuleName(), $r );
  75. if ( $qp->isCached() && !$qp->isCacheable() ) {
  76. // Disabled query page, don't run the query
  77. return;
  78. }
  79. $res = $qp->doQuery( $params['offset'], $params['limit'] + 1 );
  80. $count = 0;
  81. $titles = [];
  82. foreach ( $res as $row ) {
  83. if ( ++$count > $params['limit'] ) {
  84. // We've had enough
  85. $this->setContinueEnumParameter( 'offset', $params['offset'] + $params['limit'] );
  86. break;
  87. }
  88. $title = Title::makeTitle( $row->namespace, $row->title );
  89. if ( is_null( $resultPageSet ) ) {
  90. $data = [ 'value' => $row->value ];
  91. if ( $qp->usesTimestamps() ) {
  92. $data['timestamp'] = wfTimestamp( TS_ISO_8601, $row->value );
  93. }
  94. self::addTitleInfo( $data, $title );
  95. foreach ( $row as $field => $value ) {
  96. if ( !in_array( $field, [ 'namespace', 'title', 'value', 'qc_type' ] ) ) {
  97. $data['databaseResult'][$field] = $value;
  98. }
  99. }
  100. $fit = $result->addValue( [ 'query', $this->getModuleName(), 'results' ], null, $data );
  101. if ( !$fit ) {
  102. $this->setContinueEnumParameter( 'offset', $params['offset'] + $count - 1 );
  103. break;
  104. }
  105. } else {
  106. $titles[] = $title;
  107. }
  108. }
  109. if ( is_null( $resultPageSet ) ) {
  110. $result->addIndexedTagName(
  111. [ 'query', $this->getModuleName(), 'results' ],
  112. 'page'
  113. );
  114. } else {
  115. $resultPageSet->populateFromTitles( $titles );
  116. }
  117. }
  118. public function getCacheMode( $params ) {
  119. /** @var QueryPage $qp */
  120. $qp = new $this->qpMap[$params['page']]();
  121. if ( $qp->getRestriction() != '' ) {
  122. return 'private';
  123. }
  124. return 'public';
  125. }
  126. public function getAllowedParams() {
  127. return [
  128. 'page' => [
  129. ApiBase::PARAM_TYPE => array_keys( $this->qpMap ),
  130. ApiBase::PARAM_REQUIRED => true
  131. ],
  132. 'offset' => [
  133. ApiBase::PARAM_DFLT => 0,
  134. ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
  135. ],
  136. 'limit' => [
  137. ApiBase::PARAM_DFLT => 10,
  138. ApiBase::PARAM_TYPE => 'limit',
  139. ApiBase::PARAM_MIN => 1,
  140. ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
  141. ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
  142. ],
  143. ];
  144. }
  145. protected function getExamplesMessages() {
  146. return [
  147. 'action=query&list=querypage&qppage=Ancientpages'
  148. => 'apihelp-query+querypage-example-ancientpages',
  149. ];
  150. }
  151. public function getHelpUrls() {
  152. return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Querypage';
  153. }
  154. }