Completed
Branch master (537795)
by
unknown
33:10
created

ApiPurge   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 174
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 15

Importance

Changes 0
Metric Value
dl 0
loc 174
rs 9.1666
c 0
b 0
f 0
wmc 26
lcom 1
cbo 15

8 Methods

Rating   Name   Duplication   Size   Complexity  
F execute() 0 106 16
A getPageSet() 0 7 2
A isWriteMode() 0 3 1
A mustBePosted() 0 4 1
A getHelpFlags() 0 11 2
A getAllowedParams() 0 14 2
A getExamplesMessages() 0 8 1
A getHelpUrls() 0 3 1
1
<?php
2
3
/**
4
 * API for MediaWiki 1.14+
5
 *
6
 * Created on Sep 2, 2008
7
 *
8
 * Copyright © 2008 Chad Horohoe
9
 *
10
 * This program is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License along
21
 * with this program; if not, write to the Free Software Foundation, Inc.,
22
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23
 * http://www.gnu.org/copyleft/gpl.html
24
 *
25
 * @file
26
 */
27
use MediaWiki\Logger\LoggerFactory;
28
29
/**
30
 * API interface for page purging
31
 * @ingroup API
32
 */
33
class ApiPurge extends ApiBase {
34
	private $mPageSet;
35
36
	/**
37
	 * Purges the cache of a page
38
	 */
39
	public function execute() {
40
		$main = $this->getMain();
41
		if ( !$main->isInternalMode() && !$main->getRequest()->wasPosted() ) {
42
			$this->logFeatureUsage( 'purge-via-GET' );
43
			$this->setWarning( 'Use of action=purge via GET is deprecated. Use POST instead.' );
44
		}
45
46
		$params = $this->extractRequestParams();
47
48
		$continuationManager = new ApiContinuationManager( $this, [], [] );
49
		$this->setContinuationManager( $continuationManager );
50
51
		$forceLinkUpdate = $params['forcelinkupdate'];
52
		$forceRecursiveLinkUpdate = $params['forcerecursivelinkupdate'];
53
		$pageSet = $this->getPageSet();
54
		$pageSet->execute();
55
56
		$result = $pageSet->getInvalidTitlesAndRevisions();
57
		$user = $this->getUser();
58
59
		foreach ( $pageSet->getGoodTitles() as $title ) {
60
			$r = [];
61
			ApiQueryBase::addTitleInfo( $r, $title );
62
			$page = WikiPage::factory( $title );
63
			if ( !$user->pingLimiter( 'purge' ) ) {
64
				$flags = WikiPage::PURGE_ALL;
65
				if ( !$this->getRequest()->wasPosted() ) {
66
					$flags ^= WikiPage::PURGE_GLOBAL_PCACHE; // skip DB_MASTER write
67
				}
68
				// Directly purge and skip the UI part of purge()
69
				$page->doPurge( $flags );
70
				$r['purged'] = true;
71
			} else {
72
				$error = $this->parseMsg( [ 'actionthrottledtext' ] );
73
				$this->setWarning( $error['info'] );
74
			}
75
76
			if ( $forceLinkUpdate || $forceRecursiveLinkUpdate ) {
77
				if ( !$user->pingLimiter( 'linkpurge' ) ) {
78
					$popts = $page->makeParserOptions( 'canonical' );
79
80
					# Parse content; note that HTML generation is only needed if we want to cache the result.
81
					$content = $page->getContent( Revision::RAW );
82
					if ( $content ) {
83
						$enableParserCache = $this->getConfig()->get( 'EnableParserCache' );
84
						$p_result = $content->getParserOutput(
85
							$title,
86
							$page->getLatest(),
87
							$popts,
88
							$enableParserCache
89
						);
90
91
						# Logging to better see expensive usage patterns
92
						if ( $forceRecursiveLinkUpdate ) {
93
							LoggerFactory::getInstance( 'RecursiveLinkPurge' )->info(
94
								"Recursive link purge enqueued for {title}",
95
								[
96
									'user' => $this->getUser()->getName(),
97
									'title' => $title->getPrefixedText()
98
								]
99
							);
100
						}
101
102
						# Update the links tables
103
						$updates = $content->getSecondaryDataUpdates(
104
							$title, null, $forceRecursiveLinkUpdate, $p_result );
105
						foreach ( $updates as $update ) {
106
							DeferredUpdates::addUpdate( $update, DeferredUpdates::PRESEND );
107
						}
108
109
						$r['linkupdate'] = true;
110
111
						if ( $enableParserCache ) {
112
							$pcache = ParserCache::singleton();
113
							$pcache->save( $p_result, $page, $popts );
0 ignored issues
show
Bug introduced by
It seems like $page defined by \WikiPage::factory($title) on line 62 can be null; however, ParserCache::save() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
114
						}
115
					}
116
				} else {
117
					$error = $this->parseMsg( [ 'actionthrottledtext' ] );
118
					$this->setWarning( $error['info'] );
119
					$forceLinkUpdate = false;
120
				}
121
			}
122
123
			$result[] = $r;
124
		}
125
		$apiResult = $this->getResult();
126
		ApiResult::setIndexedTagName( $result, 'page' );
127
		$apiResult->addValue( null, $this->getModuleName(), $result );
128
129
		$values = $pageSet->getNormalizedTitlesAsResult( $apiResult );
130
		if ( $values ) {
131
			$apiResult->addValue( null, 'normalized', $values );
132
		}
133
		$values = $pageSet->getConvertedTitlesAsResult( $apiResult );
134
		if ( $values ) {
135
			$apiResult->addValue( null, 'converted', $values );
136
		}
137
		$values = $pageSet->getRedirectTitlesAsResult( $apiResult );
138
		if ( $values ) {
139
			$apiResult->addValue( null, 'redirects', $values );
140
		}
141
142
		$this->setContinuationManager( null );
143
		$continuationManager->setContinuationIntoResult( $apiResult );
144
	}
145
146
	/**
147
	 * Get a cached instance of an ApiPageSet object
148
	 * @return ApiPageSet
149
	 */
150
	private function getPageSet() {
151
		if ( !isset( $this->mPageSet ) ) {
152
			$this->mPageSet = new ApiPageSet( $this );
153
		}
154
155
		return $this->mPageSet;
156
	}
157
158
	public function isWriteMode() {
159
		return true;
160
	}
161
162
	public function mustBePosted() {
163
		// Anonymous users are not allowed a non-POST request
164
		return !$this->getUser()->isAllowed( 'purge' );
165
	}
166
167
	protected function getHelpFlags() {
168
		$flags = parent::getHelpFlags();
169
170
		// Claim that we must be posted for the purposes of help and paraminfo.
171
		// @todo Remove this when self::mustBePosted() is updated for T145649
172
		if ( !in_array( 'mustbeposted', $flags, true ) ) {
173
			$flags[] = 'mustbeposted';
174
		}
175
176
		return $flags;
177
	}
178
179
	public function getAllowedParams( $flags = 0 ) {
180
		$result = [
181
			'forcelinkupdate' => false,
182
			'forcerecursivelinkupdate' => false,
183
			'continue' => [
184
				ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
185
			],
186
		];
187
		if ( $flags ) {
188
			$result += $this->getPageSet()->getFinalParams( $flags );
189
		}
190
191
		return $result;
192
	}
193
194
	protected function getExamplesMessages() {
195
		return [
196
			'action=purge&titles=Main_Page|API'
197
				=> 'apihelp-purge-example-simple',
198
			'action=purge&generator=allpages&gapnamespace=0&gaplimit=10'
199
				=> 'apihelp-purge-example-generator',
200
		];
201
	}
202
203
	public function getHelpUrls() {
204
		return 'https://www.mediawiki.org/wiki/API:Purge';
205
	}
206
}
207