Move up devunt's name to Developers
[lhc/web/wiklou.git] / includes / api / ApiQueryORM.php
1 <?php
2
3 /**
4 * Base query module for querying results from ORMTables.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * @since 1.21
22 *
23 * @file
24 * @ingroup API
25 *
26 * @license GNU GPL v2+
27 * @author Jeroen De Dauw < jeroendedauw@gmail.com >
28 */
29 abstract class ApiQueryORM extends ApiQueryBase {
30
31 /**
32 * Returns an instance of the IORMTable table being queried.
33 *
34 * @since 1.21
35 *
36 * @return IORMTable
37 */
38 abstract protected function getTable();
39
40 /**
41 * Returns the name of the individual rows.
42 * For example: page, user, contest, campaign, etc.
43 * This is used to appropriately name elements in XML.
44 * Deriving classes typically override this method.
45 *
46 * @since 1.21
47 *
48 * @return string
49 */
50 protected function getRowName() {
51 return 'item';
52 }
53
54 /**
55 * Returns the name of the list of rows.
56 * For example: pages, users, contests, campaigns, etc.
57 * This is used to appropriately name nodes in the output.
58 * Deriving classes typically override this method.
59 *
60 * @since 1.21
61 *
62 * @return string
63 */
64 protected function getListName() {
65 return 'items';
66 }
67
68 /**
69 * Returns the path to where the items results should be added in the result.
70 *
71 * @since 1.21
72 *
73 * @return null|string|array
74 */
75 protected function getResultPath() {
76 return null;
77 }
78
79 /**
80 * Get the parameters, find out what the conditions for the query are,
81 * run it, and add the results.
82 *
83 * @since 1.21
84 */
85 public function execute() {
86 $params = $this->getParams();
87
88 if ( !in_array( 'id', $params['props'] ) ) {
89 $params['props'][] = 'id';
90 }
91
92 $results = $this->getResults( $params, $this->getConditions( $params ) );
93 $this->addResults( $params, $results );
94 }
95
96 /**
97 * Get the request parameters and remove all params set
98 * to null (ie those that are not actually provided).
99 *
100 * @since 1.21
101 *
102 * @return array
103 */
104 protected function getParams() {
105 return array_filter(
106 $this->extractRequestParams(),
107 function ( $prop ) {
108 return isset( $prop );
109 }
110 );
111 }
112
113 /**
114 * Get the conditions for the query. These will be provided as
115 * regular parameters, together with limit, props, continue,
116 * and possibly others which we need to get rid off.
117 *
118 * @since 1.21
119 *
120 * @param array $params
121 *
122 * @return array
123 */
124 protected function getConditions( array $params ) {
125 $conditions = array();
126 $fields = $this->getTable()->getFields();
127
128 foreach ( $params as $name => $value ) {
129 if ( array_key_exists( $name, $fields ) ) {
130 $conditions[$name] = $value;
131 }
132 }
133
134 return $conditions;
135 }
136
137 /**
138 * Get the actual results.
139 *
140 * @since 1.21
141 *
142 * @param array $params
143 * @param array $conditions
144 *
145 * @return ORMResult
146 */
147 protected function getResults( array $params, array $conditions ) {
148 return $this->getTable()->select(
149 $params['props'],
150 $conditions,
151 array(
152 'LIMIT' => $params['limit'] + 1,
153 'ORDER BY' => $this->getTable()->getPrefixedField( 'id' ) . ' ASC',
154 ),
155 __METHOD__
156 );
157 }
158
159 /**
160 * Serialize the results and add them to the result object.
161 *
162 * @since 1.21
163 *
164 * @param array $params
165 * @param ORMResult $results
166 */
167 protected function addResults( array $params, ORMResult $results ) {
168 $serializedResults = array();
169 $count = 0;
170
171 foreach ( $results as /* IORMRow */ $result ) {
172 if ( ++$count > $params['limit'] ) {
173 // We've reached the one extra which shows that
174 // there are additional pages to be had. Stop here...
175 $this->setContinueEnumParameter( 'continue', $result->getId() );
176 break;
177 }
178
179 $serializedResults[] = $this->formatRow( $result, $params );
180 }
181
182 $this->setIndexedTagNames( $serializedResults );
183 $this->addSerializedResults( $serializedResults );
184 }
185
186 /**
187 * Formats a row to it's desired output format.
188 *
189 * @since 1.21
190 *
191 * @param IORMRow $result
192 * @param array $params
193 *
194 * @return mixed
195 */
196 protected function formatRow( IORMRow $result, array $params ) {
197 return $result->toArray( $params['props'] );
198 }
199
200 /**
201 * Set the tag names for formats such as XML.
202 *
203 * @since 1.21
204 *
205 * @param array $serializedResults
206 */
207 protected function setIndexedTagNames( array &$serializedResults ) {
208 ApiResult::setIndexedTagName( $serializedResults, $this->getRowName() );
209 }
210
211 /**
212 * Add the serialized results to the result object.
213 *
214 * @since 1.21
215 *
216 * @param array $serializedResults
217 */
218 protected function addSerializedResults( array $serializedResults ) {
219 $this->getResult()->addValue(
220 $this->getResultPath(),
221 $this->getListName(),
222 $serializedResults
223 );
224 }
225
226 /**
227 * @see ApiBase::getAllowedParams()
228 * @return array
229 */
230 public function getAllowedParams() {
231 $params = array(
232 'props' => array(
233 ApiBase::PARAM_TYPE => $this->getTable()->getFieldNames(),
234 ApiBase::PARAM_ISMULTI => true,
235 ApiBase::PARAM_REQUIRED => true,
236 ApiBase::PARAM_HELP_MSG => 'api-orm-param-props',
237 ),
238 'limit' => array(
239 ApiBase::PARAM_DFLT => 20,
240 ApiBase::PARAM_TYPE => 'limit',
241 ApiBase::PARAM_MIN => 1,
242 ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
243 ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2,
244 ApiBase::PARAM_HELP_MSG => 'api-orm-param-limit',
245 ),
246 'continue' => array(
247 ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
248 ),
249 );
250
251 return array_merge( $this->getTable()->getAPIParams(), $params );
252 }
253
254 /**
255 * @see ApiBase::getParamDescription()
256 * @deprecated since 1.25
257 * @return array
258 */
259 public function getParamDescription() {
260 $descriptions = array(
261 'props' => 'Fields to query',
262 'continue' => 'Offset number from where to continue the query',
263 'limit' => 'Max amount of rows to return',
264 );
265
266 return array_merge( $this->getTable()->getFieldDescriptions(), $descriptions );
267 }
268 }