Fix API output formatting (change lines delimited with * as bold)
[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 public function __construct( $main, $action ) {
36 parent::__construct( $main, $action );
37 }
38
39 /**
40 * Changes preferences of the current user.
41 */
42 public function execute() {
43 $user = $this->getUser();
44
45 if ( $user->isAnon() ) {
46 $this->dieUsage( 'Anonymous users cannot change preferences', 'notloggedin' );
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( 'all' );
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 // A key for a multiselect option.
88 $validation = true;
89 $value = (bool)$value;
90 break;
91 case 'userjs':
92 // Allow non-default preferences prefixed with 'userjs-', to be set by user scripts
93 if ( strlen( $key ) > 255 ) {
94 $validation = "key too long (no more than 255 bytes allowed)";
95 } elseif ( preg_match( "/[^a-zA-Z0-9_-]/", $key ) !== 0 ) {
96 $validation = "invalid key (only a-z, A-Z, 0-9, _, - allowed)";
97 } else {
98 $validation = true;
99 }
100 break;
101 case 'unused':
102 default:
103 $validation = "not a valid preference";
104 break;
105 }
106 if ( $validation === true ) {
107 $user->setOption( $key, $value );
108 $changed = true;
109 } else {
110 $this->setWarning( "Validation error for '$key': $validation" );
111 }
112 }
113
114 if ( $changed ) {
115 // Commit changes
116 $user->saveSettings();
117 }
118
119 $this->getResult()->addValue( null, $this->getModuleName(), 'success' );
120 }
121
122 public function mustBePosted() {
123 return true;
124 }
125
126 public function isWriteMode() {
127 return true;
128 }
129
130 public function getAllowedParams() {
131 return array(
132 'token' => array(
133 ApiBase::PARAM_TYPE => 'string',
134 ApiBase::PARAM_REQUIRED => true
135 ),
136 'reset' => false,
137 'change' => array(
138 ApiBase::PARAM_ISMULTI => true,
139 ),
140 'optionname' => array(
141 ApiBase::PARAM_TYPE => 'string',
142 ),
143 'optionvalue' => array(
144 ApiBase::PARAM_TYPE => 'string',
145 ),
146 );
147 }
148
149 public function getResultProperties() {
150 return array(
151 '' => array(
152 '*' => array(
153 ApiBase::PROP_TYPE => array(
154 'success'
155 )
156 )
157 )
158 );
159 }
160
161 public function getParamDescription() {
162 return array(
163 'token' => 'An options token previously obtained through the action=tokens',
164 'reset' => 'Resets all preferences to the site defaults',
165 'change' => 'List of changes, formatted name=value (e.g. skin=vector), value cannot contain pipe characters',
166 'optionname' => 'A name of a option which should have an optionvalue set',
167 'optionvalue' => 'A value of the option specified by the optionname, can contain pipe characters',
168 );
169 }
170
171 public function getDescription() {
172 return array(
173 'Change preferences of the current user',
174 'Only options which are registered in core or in one of installed extensions,',
175 'or as options with keys prefixed with \'userjs-\' (intended to be used by user scripts), can be set.'
176 );
177 }
178
179 public function getPossibleErrors() {
180 return array_merge( parent::getPossibleErrors(), array(
181 array( 'code' => 'notloggedin', 'info' => 'Anonymous users cannot change preferences' ),
182 array( 'code' => 'nochanges', 'info' => 'No changes were requested' ),
183 ) );
184 }
185
186 public function needsToken() {
187 return true;
188 }
189
190 public function getTokenSalt() {
191 return '';
192 }
193
194 public function getHelpUrls() {
195 return 'https://www.mediawiki.org/wiki/API:Options';
196 }
197
198 public function getExamples() {
199 return array(
200 'api.php?action=options&reset=&token=123ABC',
201 'api.php?action=options&change=skin=vector|hideminor=1&token=123ABC',
202 'api.php?action=options&reset=&change=skin=monobook&optionname=nickname&optionvalue=[[User:Beau|Beau]]%20([[User_talk:Beau|talk]])&token=123ABC',
203 );
204 }
205
206 public function getVersion() {
207 return __CLASS__ . ': $Id$';
208 }
209 }