Merge "Make Special:MediaStatistics show a total count of file sizes"
[lhc/web/wiklou.git] / includes / api / ApiTag.php
1 <?php
2
3 /**
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 * http://www.gnu.org/copyleft/gpl.html
18 *
19 * @file
20 */
21
22 /**
23 * @ingroup API
24 * @since 1.25
25 */
26 class ApiTag extends ApiBase {
27
28 protected function getAvailableTags() {
29 return ChangeTags::listExplicitlyDefinedTags();
30 }
31
32 public function execute() {
33 $params = $this->extractRequestParams();
34 $user = $this->getUser();
35
36 // make sure the user is allowed
37 if ( !$user->isAllowed( 'changetags' ) ) {
38 $this->dieUsage( "You don't have permission to add or remove change tags from individual edits",
39 'permissiondenied' );
40 }
41
42 if ( $user->isBlocked() ) {
43 $block = $user->getBlock();
44
45 // Die using the appropriate message depending on block type
46 if ( $block->getType() == TYPE_AUTO ) {
47 $this->dieUsage(
48 'Your IP address has been blocked automatically, because it was used by a blocked user',
49 'autoblocked',
50 0,
51 array( 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $block ) )
52 );
53 } else {
54 $this->dieUsage(
55 'You have been blocked from editing',
56 'blocked',
57 0,
58 array( 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $block ) )
59 );
60 }
61 }
62
63 // validate and process each revid, rcid and logid
64 $this->requireAtLeastOneParameter( $params, 'revid', 'rcid', 'logid' );
65 $ret = array();
66 if ( $params['revid'] ) {
67 foreach ( $params['revid'] as $id ) {
68 $ret[] = $this->processIndividual( 'revid', $params, $id );
69 }
70 }
71 if ( $params['rcid'] ) {
72 foreach ( $params['rcid'] as $id ) {
73 $ret[] = $this->processIndividual( 'rcid', $params, $id );
74 }
75 }
76 if ( $params['logid'] ) {
77 foreach ( $params['logid'] as $id ) {
78 $ret[] = $this->processIndividual( 'logid', $params, $id );
79 }
80 }
81
82 ApiResult::setIndexedTagName( $ret, 'result' );
83 $this->getResult()->addValue( null, $this->getModuleName(), $ret );
84 }
85
86 protected static function validateLogId( $logid ) {
87 $dbr = wfGetDB( DB_SLAVE );
88 $result = $dbr->selectField( 'logging', 'log_id', array( 'log_id' => $logid ),
89 __METHOD__ );
90 return (bool)$result;
91 }
92
93 protected function processIndividual( $type, $params, $id ) {
94 $idResult = array( $type => $id );
95
96 // validate the ID
97 $valid = false;
98 switch ( $type ) {
99 case 'rcid':
100 $valid = RecentChange::newFromId( $id );
101 break;
102 case 'revid':
103 $valid = Revision::newFromId( $id );
104 break;
105 case 'logid':
106 $valid = self::validateLogId( $id );
107 break;
108 }
109
110 if ( !$valid ) {
111 $idResult['status'] = 'error';
112 $idResult += $this->parseMsg( array( "nosuch$type", $id ) );
113 return $idResult;
114 }
115
116 $status = ChangeTags::updateTagsWithChecks( $params['add'],
117 $params['remove'],
118 ( $type === 'rcid' ? $id : null ),
119 ( $type === 'revid' ? $id : null ),
120 ( $type === 'logid' ? $id : null ),
121 null,
122 $params['reason'],
123 $this->getUser() );
124
125 if ( !$status->isOK() ) {
126 if ( $status->hasMessage( 'actionthrottledtext' ) ) {
127 $idResult['status'] = 'skipped';
128 } else {
129 $idResult['status'] = 'failure';
130 $idResult['errors'] = $this->getErrorFormatter()->arrayFromStatus( $status, 'error' );
131 }
132 } else {
133 $idResult['status'] = 'success';
134 if ( is_null( $status->value->logId ) ) {
135 $idResult['noop'] = '';
136 } else {
137 $idResult['actionlogid'] = $status->value->logId;
138 $idResult['added'] = $status->value->addedTags;
139 ApiResult::setIndexedTagName( $idResult['added'], 't' );
140 $idResult['removed'] = $status->value->removedTags;
141 ApiResult::setIndexedTagName( $idResult['removed'], 't' );
142 }
143 }
144 return $idResult;
145 }
146
147 public function mustBePosted() {
148 return true;
149 }
150
151 public function isWriteMode() {
152 return true;
153 }
154
155 public function getAllowedParams() {
156 return array(
157 'rcid' => array(
158 ApiBase::PARAM_TYPE => 'integer',
159 ApiBase::PARAM_ISMULTI => true,
160 ),
161 'revid' => array(
162 ApiBase::PARAM_TYPE => 'integer',
163 ApiBase::PARAM_ISMULTI => true,
164 ),
165 'logid' => array(
166 ApiBase::PARAM_TYPE => 'integer',
167 ApiBase::PARAM_ISMULTI => true,
168 ),
169 'add' => array(
170 ApiBase::PARAM_TYPE => $this->getAvailableTags(),
171 ApiBase::PARAM_ISMULTI => true,
172 ),
173 'remove' => array(
174 ApiBase::PARAM_TYPE => 'string',
175 ApiBase::PARAM_ISMULTI => true,
176 ),
177 'reason' => array(
178 ApiBase::PARAM_DFLT => '',
179 ),
180 );
181 }
182
183 public function needsToken() {
184 return 'csrf';
185 }
186
187 protected function getExamplesMessages() {
188 return array(
189 'action=tag&revid=123&add=vandalism&token=123ABC'
190 => 'apihelp-tag-example-rev',
191 'action=tag&logid=123&remove=spam&reason=Wrongly+applied&token=123ABC'
192 => 'apihelp-tag-example-log',
193 );
194 }
195
196 public function getHelpUrls() {
197 return 'https://www.mediawiki.org/wiki/API:Tag';
198 }
199 }