ApiQuerySemanticWatchlist::getAllowedParams()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 0
cts 23
cp 0
rs 9.536
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
/**
4
 * API module to get a list of modified properties per page for a persons semantic watchlist.
5
 *
6
 * @since 0.1
7
 *
8
 * @file ApiQuerySemanticWatchlist.php
9
 * @ingroup SemanticWatchlist
10
 * @ingroup API
11
 *
12
 * @licence GNU GPL v3+
13
 * @author Jeroen De Dauw < [email protected] >
14
 */
15
class ApiQuerySemanticWatchlist extends ApiQueryBase {
16
	public function __construct( $main, $action ) {
17
		parent :: __construct( $main, $action, 'sw' );
18
	}
19
20
	/**
21
	 * Retrieve the specil words from the database.
22
	 */
23
	public function execute() {
24
		// Get the requests parameters.
25
		$params = $this->extractRequestParams();
26
		
27
		if ( !( isset( $params['userid'] ) XOR isset( $params['groupids'] ) ) ) {
28
			$this->dieUsage( wfMessage( 'swl-err-userid-xor-groupids' )->text(), 'userid-xor-groupids' );
29
		}
30
		
31
		$isUserFilter = isset( $params['userid'] );
32
		$filter = $isUserFilter ? $params['userid'] : $params['groupids'];
33
		
34
		$this->setupChangeSetQuery( $filter, $isUserFilter, $params['limit'], $params['continue'] );		
35
		
36
		$sets = $this->select( __METHOD__ );
37
		$count = 0;	
38
		$resultSets = array();
39
		
40
		foreach ( $sets as $set ) {
41
			if ( ++$count > $params['limit'] ) {
42
				// We've reached the one extra which shows that
43
				// there are additional pages to be had. Stop here...
44
				$this->setContinueEnumParameter( 'continue', $set->edit_time . '-' . $set->spe_set_id );
45
				break;
46
			}
47
48
			if ( !is_null( Title::newFromID( $set->edit_page_id ) ) ) {
49
				$resultSets[] = SWLChangeSet::newFromDBResult( $set );
50
			}
51
		}
52
		
53
		if ( $params['merge'] ) {
54
			$this->mergeSets( $resultSets );
55
		}
56
		
57
		foreach ( $resultSets as &$set ) {
58
			$set = $set->toArray();
59
			
60
			foreach ( $set['changes'] as $propName => $changes ) {
61
				$this->getResult()->setIndexedTagName( $set['changes'][$propName], 'change' );
62
			}
63
		}
64
		
65
		$this->getResult()->setIndexedTagName( $resultSets, 'set' );
66
		
67
		$this->getResult()->addValue(
68
			null,
69
			'sets',
70
			$resultSets
71
		);
72
	}
73
	
74
	/**
75
	 * Gets a list of change sets belonging to any of the watchlist groups
76
	 * watched by the user, newest first.
77
	 * 
78
	 * @param mixed $filter User ID or array of group IDs
79
	 * @param boolean $isUserFilter
80
	 * @param integer $limit
81
	 * @param string $continue
82
	 */
83
	protected function setupChangeSetQuery( $filter, $isUserFilter, $limit, $continue ) {
84
		$tables = array( 'swl_edits', 'swl_sets_per_edit', 'swl_sets_per_group' );
85
		
86
		if ( $isUserFilter ) {
87
			$tables[] = 'swl_users_per_group';
88
		}
89
		
90
		$this->addTables( $tables );
91
92
		$this->addJoinConds( array(
93
			'swl_sets_per_edit' => array( 'INNER JOIN', array( 'edit_id=spe_edit_id' ) ),
94
			'swl_sets_per_group' => array( 'INNER JOIN', array( 'spe_set_id=spg_set_id' ) ),
95
		) );
96
		
97
		if ( $isUserFilter ) {
98
			$this->addJoinConds( array(
99
				'swl_users_per_group' => array( 'INNER JOIN', array( 'spg_group_id=upg_group_id' ) ),
100
			) );
101
		}
102
		
103
		$this->addFields( array(
104
			'spe_set_id',
105
			'edit_user_name',
106
			'edit_page_id',
107
			'edit_time',
108
			'edit_id'
109
		) );
110
		
111
		$this->addWhere( array(
112
			( $isUserFilter ? 'upg_user_id' : 'spg_group_id' ) => $filter
113
		) );
114
		
115
		$this->addOption( 'DISTINCT' );
116
		$this->addOption( 'LIMIT', $limit + 1 );
117
		$this->addOption( 'ORDER BY', 'edit_time DESC, spe_set_id DESC' );
118
		
119
		if ( !is_null( $continue ) ) {
120
			$continueParams = explode( '-', $continue );
121
			
122
			if ( count( $continueParams ) == 2 ) {
123
				$dbr = wfGetDB( DB_REPLICA );
124
				$this->addWhere( 'edit_time <= ' . $dbr->addQuotes( $continueParams[0] ) );
125
				$this->addWhere( 'spe_set_id <= ' . $dbr->addQuotes( $continueParams[1] ) );					
126
			}
127
			else {
128
				// TODO: error
129
			}
130
		}		
131
	}
132
	
133
	/**
134
	 * Merge change sets belonging to the same edit into one sinlge change set.
135
	 * 
136
	 * @since 0.1
137
	 * 
138
	 * @param array $sets
139
	 */
140
	protected function mergeSets( array &$sets ) {		
141
		if ( count( $sets ) > 1 ) {
142
			$setsPerEdits = array();
143
			
144
			// List the sets per edit.
145
			foreach ( $sets as $set ) {
146
				if ( !array_key_exists( $set->getEdit()->getId(), $setsPerEdits ) ) {
147
					$setsPerEdits[$set->getEdit()->getId()] = array();
148
				}
149
				
150
				$setsPerEdits[$set->getEdit()->getId()][] = $set;
151
			}
152
			
153
			$mergedSets = array();
154
			
155
			// For all edits with more then one set, merge all sets in the first one, 
156
			// and add it to the $mergedSets list.
157
			foreach ( $setsPerEdits as $setsForEdit ) {
158
				$setCount = count( $setsForEdit );
159
				
160
				if ( $setCount > 1 ) {
161
					for ( $i = 1; $i < $setCount; $i++ ) {
162
						$setsForEdit[0]->mergeInChangeSet( $setsForEdit[$i] );
163
					}	
164
				}
165
				
166
				$mergedSets[] = $setsForEdit[0];
167
			}
168
			
169
			$sets = $mergedSets;
170
		}
171
	}
172
	
173
	/**
174
	 * (non-PHPdoc)
175
	 * @see includes/api/ApiBase#getAllowedParams()
176
	 */
177
	public function getAllowedParams() {
178
		return array (
179
			'userid' => array(
180
				ApiBase::PARAM_TYPE => 'integer',
181
			),
182
			'groupids' => array(
183
				ApiBase::PARAM_TYPE => 'integer',
184
				ApiBase::PARAM_ISMULTI => true,
185
			),
186
			'merge' => array(
187
				ApiBase::PARAM_TYPE => 'boolean',
188
				ApiBase::PARAM_DFLT => false,
189
			),
190
			'limit' => array(
191
				ApiBase :: PARAM_DFLT => 20,
192
				ApiBase :: PARAM_TYPE => 'limit',
193
				ApiBase :: PARAM_MIN => 1,
194
				ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
195
				ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
196
			),
197
			'continue' => null,
198
		);
199
		
200
	}
201
202
	/**
203
	 * (non-PHPdoc)
204
	 * @see includes/api/ApiBase#getParamDescription()
205
	 */
206
	public function getParamDescription() {
207
		return array (
208
			'userid' => 'The ID of the user for which to return semantic watchlist data.',
209
			'groupids' => 'The IDs of the groups for which to return semantic watchlist data.',
210
			'merge' => 'Merge sets of changes that belong to the same edit?',
211
			'continue' => 'Offset number from where to continue the query',
212
			'limit'   => 'Max amount of words to return',
213
		);
214
	}
215
216
	/**
217
	 * (non-PHPdoc)
218
	 * @see includes/api/ApiBase#getDescription()
219
	 */
220
	public function getDescription() {
221
		return 'Returns a list of sets of changes for the either specified user of specified group(s).';
222
	}
223
224
	/**
225
	 * (non-PHPdoc)
226
	 * @see includes/api/ApiBase#getExamples()
227
	 */
228
	protected function getExamples() {
229
		return array (
230
			'api.php?action=query&list=semanticwatchlist&swuserid=1',
231
			'api.php?action=query&list=semanticwatchlist&swuserid=1&swlimit=42&swcontinue=20110514143957-9001',
232
			'api.php?action=query&list=semanticwatchlist&swgroupids=1',
233
			'api.php?action=query&list=semanticwatchlist&swgroupids=1|42&swlimit=34',
234
		);
235
	}
236
237
	public function getVersion() {
238
		return __CLASS__ . ': $Id$';
239
	}	
240
	
241
}
242