ApiQueryPagesWithProp   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 146
Duplicated Lines 4.79 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
dl 7
loc 146
rs 10
c 0
b 0
f 0
wmc 20
lcom 1
cbo 5

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A execute() 0 3 1
A getCacheMode() 0 3 1
A executeGenerator() 0 3 1
F run() 7 74 13
B getAllowedParams() 0 35 1
A getExamplesMessages() 0 8 1
A getHelpUrls() 0 3 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Created on December 31, 2012
4
 *
5
 * Copyright © 2012 Brad Jorsch <[email protected]>
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License along
18
 * with this program; if not, write to the Free Software Foundation, Inc.,
19
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
 * http://www.gnu.org/copyleft/gpl.html
21
 *
22
 * @file
23
 * @since 1.21
24
 * @author Brad Jorsch
25
 */
26
27
/**
28
 * A query module to enumerate pages that use a particular prop
29
 *
30
 * @ingroup API
31
 * @since 1.21
32
 */
33
class ApiQueryPagesWithProp extends ApiQueryGeneratorBase {
34
35
	public function __construct( ApiQuery $query, $moduleName ) {
36
		parent::__construct( $query, $moduleName, 'pwp' );
37
	}
38
39
	public function execute() {
40
		$this->run();
41
	}
42
43
	public function getCacheMode( $params ) {
44
		return 'public';
45
	}
46
47
	public function executeGenerator( $resultPageSet ) {
48
		$this->run( $resultPageSet );
49
	}
50
51
	/**
52
	 * @param ApiPageSet $resultPageSet
53
	 * @return void
54
	 */
55
	private function run( $resultPageSet = null ) {
56
		$params = $this->extractRequestParams();
57
58
		$prop = array_flip( $params['prop'] );
59
		$fld_ids = isset( $prop['ids'] );
60
		$fld_title = isset( $prop['title'] );
61
		$fld_value = isset( $prop['value'] );
62
63 View Code Duplication
		if ( $resultPageSet === null ) {
64
			$this->addFields( [ 'page_id' ] );
65
			$this->addFieldsIf( [ 'page_title', 'page_namespace' ], $fld_title );
66
			$this->addFieldsIf( 'pp_value', $fld_value );
67
		} else {
68
			$this->addFields( $resultPageSet->getPageTableFields() );
69
		}
70
		$this->addTables( [ 'page_props', 'page' ] );
71
		$this->addWhere( 'pp_page=page_id' );
72
		$this->addWhereFld( 'pp_propname', $params['propname'] );
73
74
		$dir = ( $params['dir'] == 'ascending' ) ? 'newer' : 'older';
75
76
		if ( $params['continue'] ) {
77
			$cont = explode( '|', $params['continue'] );
78
			$this->dieContinueUsageIf( count( $cont ) != 1 );
79
80
			// Add a WHERE clause
81
			$from = (int)$cont[0];
82
			$this->addWhereRange( 'pp_page', $dir, $from, null );
83
		}
84
85
		$sort = ( $params['dir'] === 'descending' ? ' DESC' : '' );
86
		$this->addOption( 'ORDER BY', 'pp_page' . $sort );
87
88
		$limit = $params['limit'];
89
		$this->addOption( 'LIMIT', $limit + 1 );
90
91
		$result = $this->getResult();
92
		$count = 0;
93
		foreach ( $this->select( __METHOD__ ) as $row ) {
94
			if ( ++$count > $limit ) {
95
				// We've reached the one extra which shows that there are
96
				// additional pages to be had. Stop here...
97
				$this->setContinueEnumParameter( 'continue', $row->page_id );
98
				break;
99
			}
100
101
			if ( $resultPageSet === null ) {
102
				$vals = [
103
					ApiResult::META_TYPE => 'assoc',
104
				];
105
				if ( $fld_ids ) {
106
					$vals['pageid'] = (int)$row->page_id;
107
				}
108
				if ( $fld_title ) {
109
					$title = Title::makeTitle( $row->page_namespace, $row->page_title );
110
					ApiQueryBase::addTitleInfo( $vals, $title );
111
				}
112
				if ( $fld_value ) {
113
					$vals['value'] = $row->pp_value;
114
				}
115
				$fit = $result->addValue( [ 'query', $this->getModuleName() ], null, $vals );
116
				if ( !$fit ) {
117
					$this->setContinueEnumParameter( 'continue', $row->page_id );
118
					break;
119
				}
120
			} else {
121
				$resultPageSet->processDbRow( $row );
0 ignored issues
show
Bug introduced by
It seems like $row defined by $row on line 93 can be null; however, ApiPageSet::processDbRow() 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...
122
			}
123
		}
124
125
		if ( $resultPageSet === null ) {
126
			$result->addIndexedTagName( [ 'query', $this->getModuleName() ], 'page' );
127
		}
128
	}
129
130
	public function getAllowedParams() {
131
		return [
132
			'propname' => [
133
				ApiBase::PARAM_TYPE => 'string',
134
				ApiBase::PARAM_REQUIRED => true,
135
			],
136
			'prop' => [
137
				ApiBase::PARAM_DFLT => 'ids|title',
138
				ApiBase::PARAM_ISMULTI => true,
139
				ApiBase::PARAM_TYPE => [
140
					'ids',
141
					'title',
142
					'value',
143
				],
144
				ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
145
			],
146
			'continue' => [
147
				ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
148
			],
149
			'limit' => [
150
				ApiBase::PARAM_TYPE => 'limit',
151
				ApiBase::PARAM_DFLT => 10,
152
				ApiBase::PARAM_MIN => 1,
153
				ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
154
				ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
155
			],
156
			'dir' => [
157
				ApiBase::PARAM_DFLT => 'ascending',
158
				ApiBase::PARAM_TYPE => [
159
					'ascending',
160
					'descending',
161
				]
162
			],
163
		];
164
	}
165
166
	protected function getExamplesMessages() {
167
		return [
168
			'action=query&list=pageswithprop&pwppropname=displaytitle&pwpprop=ids|title|value'
169
				=> 'apihelp-query+pageswithprop-example-simple',
170
			'action=query&generator=pageswithprop&gpwppropname=notoc&prop=info'
171
				=> 'apihelp-query+pageswithprop-example-generator',
172
		];
173
	}
174
175
	public function getHelpUrls() {
176
		return 'https://www.mediawiki.org/wiki/API:Pageswithprop';
177
	}
178
}
179