Add an interface for getting "standard" file metadata.
[lhc/web/wiklou.git] / includes / api / ApiOptions.php
1 <?php
2 /**
3 *
4 *
5 * Created on Apr 15, 2012
6 *
7 * Copyright © 2012 Szymon Świerkosz beau@adres.pl
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 * http://www.gnu.org/copyleft/gpl.html
23 *
24 * @file
25 */
26
27 /**
28 * API module that facilitates the changing of user's preferences.
29 * Requires API write mode to be enabled.
30 *
31 * @ingroup API
32 */
33 class ApiOptions extends ApiBase {
34
35 /**
36 * Changes preferences of the current user.
37 */
38 public function execute() {
39 $user = $this->getUser();
40
41 if ( $user->isAnon() ) {
42 $this->dieUsage( 'Anonymous users cannot change preferences', 'notloggedin' );
43 }
44
45 if ( !$user->isAllowed( 'editmyoptions' ) ) {
46 $this->dieUsage( 'You don\'t have permission to edit your options', 'permissiondenied' );
47 }
48
49 $params = $this->extractRequestParams();
50 $changed = false;
51
52 if ( isset( $params['optionvalue'] ) && !isset( $params['optionname'] ) ) {
53 $this->dieUsageMsg( array( 'missingparam', 'optionname' ) );
54 }
55
56 if ( $params['reset'] ) {
57 $user->resetOptions( $params['resetkinds'] );
58 $changed = true;
59 }
60
61 $changes = array();
62 if ( count( $params['change'] ) ) {
63 foreach ( $params['change'] as $entry ) {
64 $array = explode( '=', $entry, 2 );
65 $changes[$array[0]] = isset( $array[1] ) ? $array[1] : null;
66 }
67 }
68 if ( isset( $params['optionname'] ) ) {
69 $newValue = isset( $params['optionvalue'] ) ? $params['optionvalue'] : null;
70 $changes[$params['optionname']] = $newValue;
71 }
72 if ( !$changed && !count( $changes ) ) {
73 $this->dieUsage( 'No changes were requested', 'nochanges' );
74 }
75
76 $prefs = Preferences::getPreferences( $user, $this->getContext() );
77 $prefsKinds = $user->getOptionKinds( $this->getContext(), $changes );
78
79 foreach ( $changes as $key => $value ) {
80 switch ( $prefsKinds[$key] ) {
81 case 'registered':
82 // Regular option.
83 $field = HTMLForm::loadInputFromParameters( $key, $prefs[$key] );
84 $validation = $field->validate( $value, $user->getOptions() );
85 break;
86 case 'registered-multiselect':
87 case 'registered-checkmatrix':
88 // A key for a multiselect or checkmatrix option.
89 $validation = true;
90 $value = $value !== null ? (bool)$value : null;
91 break;
92 case 'userjs':
93 // Allow non-default preferences prefixed with 'userjs-', to be set by user scripts
94 if ( strlen( $key ) > 255 ) {
95 $validation = "key too long (no more than 255 bytes allowed)";
96 } elseif ( preg_match( "/[^a-zA-Z0-9_-]/", $key ) !== 0 ) {
97 $validation = "invalid key (only a-z, A-Z, 0-9, _, - allowed)";
98 } else {
99 $validation = true;
100 }
101 break;
102 case 'unused':
103 default:
104 $validation = "not a valid preference";
105 break;
106 }
107 if ( $validation === true ) {
108 $user->setOption( $key, $value );
109 $changed = true;
110 } else {
111 $this->setWarning( "Validation error for '$key': $validation" );
112 }
113 }
114
115 if ( $changed ) {
116 // Commit changes
117 $user->saveSettings();
118 }
119
120 $this->getResult()->addValue( null, $this->getModuleName(), 'success' );
121 }
122
123 public function mustBePosted() {
124 return true;
125 }
126
127 public function isWriteMode() {
128 return true;
129 }
130
131 public function getAllowedParams() {
132 $optionKinds = User::listOptionKinds();
133 $optionKinds[] = 'all';
134
135 return array(
136 'token' => array(
137 ApiBase::PARAM_TYPE => 'string',
138 ApiBase::PARAM_REQUIRED => true
139 ),
140 'reset' => false,
141 'resetkinds' => array(
142 ApiBase::PARAM_TYPE => $optionKinds,
143 ApiBase::PARAM_DFLT => 'all',
144 ApiBase::PARAM_ISMULTI => true
145 ),
146 'change' => array(
147 ApiBase::PARAM_ISMULTI => true,
148 ),
149 'optionname' => array(
150 ApiBase::PARAM_TYPE => 'string',
151 ),
152 'optionvalue' => array(
153 ApiBase::PARAM_TYPE => 'string',
154 ),
155 );
156 }
157
158 public function getResultProperties() {
159 return array(
160 '' => array(
161 '*' => array(
162 ApiBase::PROP_TYPE => array(
163 'success'
164 )
165 )
166 )
167 );
168 }
169
170 public function getParamDescription() {
171 return array(
172 'token' => 'An options token previously obtained through the action=tokens',
173 'reset' => 'Resets preferences to the site defaults',
174 'resetkinds' => 'List of types of options to reset when the "reset" option is set',
175 'change' => 'List of changes, formatted name=value (e.g. skin=vector), value cannot contain pipe characters. If no value is given (not even an equals sign), e.g., optionname|otheroption|..., the option will be reset to its default value',
176 'optionname' => 'A name of a option which should have an optionvalue set',
177 'optionvalue' => 'A value of the option specified by the optionname, can contain pipe characters',
178 );
179 }
180
181 public function getDescription() {
182 return array(
183 'Change preferences of the current user',
184 'Only options which are registered in core or in one of installed extensions,',
185 'or as options with keys prefixed with \'userjs-\' (intended to be used by user scripts), can be set.'
186 );
187 }
188
189 public function getPossibleErrors() {
190 return array_merge( parent::getPossibleErrors(), array(
191 array( 'code' => 'notloggedin', 'info' => 'Anonymous users cannot change preferences' ),
192 array( 'code' => 'nochanges', 'info' => 'No changes were requested' ),
193 ) );
194 }
195
196 public function needsToken() {
197 return true;
198 }
199
200 public function getTokenSalt() {
201 return '';
202 }
203
204 public function getHelpUrls() {
205 return 'https://www.mediawiki.org/wiki/API:Options';
206 }
207
208 public function getExamples() {
209 return array(
210 'api.php?action=options&reset=&token=123ABC',
211 'api.php?action=options&change=skin=vector|hideminor=1&token=123ABC',
212 'api.php?action=options&reset=&change=skin=monobook&optionname=nickname&optionvalue=[[User:Beau|Beau]]%20([[User_talk:Beau|talk]])&token=123ABC',
213 );
214 }
215 }