MediaWiki  REL1_22
ApiOptions.php
Go to the documentation of this file.
00001 <?php
00033 class ApiOptions extends ApiBase {
00034 
00038     public function execute() {
00039         $user = $this->getUser();
00040 
00041         if ( $user->isAnon() ) {
00042             $this->dieUsage( 'Anonymous users cannot change preferences', 'notloggedin' );
00043         }
00044 
00045         if ( !$user->isAllowed( 'editmyoptions' ) ) {
00046             $this->dieUsage( 'You don\'t have permission to edit your options', 'permissiondenied' );
00047         }
00048 
00049         $params = $this->extractRequestParams();
00050         $changed = false;
00051 
00052         if ( isset( $params['optionvalue'] ) && !isset( $params['optionname'] ) ) {
00053             $this->dieUsageMsg( array( 'missingparam', 'optionname' ) );
00054         }
00055 
00056         if ( $params['reset'] ) {
00057             $user->resetOptions( $params['resetkinds'], $this->getContext() );
00058             $changed = true;
00059         }
00060 
00061         $changes = array();
00062         if ( count( $params['change'] ) ) {
00063             foreach ( $params['change'] as $entry ) {
00064                 $array = explode( '=', $entry, 2 );
00065                 $changes[$array[0]] = isset( $array[1] ) ? $array[1] : null;
00066             }
00067         }
00068         if ( isset( $params['optionname'] ) ) {
00069             $newValue = isset( $params['optionvalue'] ) ? $params['optionvalue'] : null;
00070             $changes[$params['optionname']] = $newValue;
00071         }
00072         if ( !$changed && !count( $changes ) ) {
00073             $this->dieUsage( 'No changes were requested', 'nochanges' );
00074         }
00075 
00076         $prefs = Preferences::getPreferences( $user, $this->getContext() );
00077         $prefsKinds = $user->getOptionKinds( $this->getContext(), $changes );
00078 
00079         foreach ( $changes as $key => $value ) {
00080             switch ( $prefsKinds[$key] ) {
00081                 case 'registered':
00082                     // Regular option.
00083                     $field = HTMLForm::loadInputFromParameters( $key, $prefs[$key] );
00084                     $validation = $field->validate( $value, $user->getOptions() );
00085                     break;
00086                 case 'registered-multiselect':
00087                 case 'registered-checkmatrix':
00088                     // A key for a multiselect or checkmatrix option.
00089                     $validation = true;
00090                     $value = $value !== null ? (bool)$value : null;
00091                     break;
00092                 case 'userjs':
00093                     // Allow non-default preferences prefixed with 'userjs-', to be set by user scripts
00094                     if ( strlen( $key ) > 255 ) {
00095                         $validation = "key too long (no more than 255 bytes allowed)";
00096                     } elseif ( preg_match( "/[^a-zA-Z0-9_-]/", $key ) !== 0 ) {
00097                         $validation = "invalid key (only a-z, A-Z, 0-9, _, - allowed)";
00098                     } else {
00099                         $validation = true;
00100                     }
00101                     break;
00102                 case 'unused':
00103                 default:
00104                     $validation = "not a valid preference";
00105                     break;
00106             }
00107             if ( $validation === true ) {
00108                 $user->setOption( $key, $value );
00109                 $changed = true;
00110             } else {
00111                 $this->setWarning( "Validation error for '$key': $validation" );
00112             }
00113         }
00114 
00115         if ( $changed ) {
00116             // Commit changes
00117             $user->saveSettings();
00118         }
00119 
00120         $this->getResult()->addValue( null, $this->getModuleName(), 'success' );
00121     }
00122 
00123     public function mustBePosted() {
00124         return true;
00125     }
00126 
00127     public function isWriteMode() {
00128         return true;
00129     }
00130 
00131     public function getAllowedParams() {
00132         $optionKinds = User::listOptionKinds();
00133         $optionKinds[] = 'all';
00134 
00135         return array(
00136             'token' => array(
00137                 ApiBase::PARAM_TYPE => 'string',
00138                 ApiBase::PARAM_REQUIRED => true
00139             ),
00140             'reset' => false,
00141             'resetkinds' => array(
00142                 ApiBase::PARAM_TYPE => $optionKinds,
00143                 ApiBase::PARAM_DFLT => 'all',
00144                 ApiBase::PARAM_ISMULTI => true
00145             ),
00146             'change' => array(
00147                 ApiBase::PARAM_ISMULTI => true,
00148             ),
00149             'optionname' => array(
00150                 ApiBase::PARAM_TYPE => 'string',
00151             ),
00152             'optionvalue' => array(
00153                 ApiBase::PARAM_TYPE => 'string',
00154             ),
00155         );
00156     }
00157 
00158     public function getResultProperties() {
00159         return array(
00160             '' => array(
00161                 '*' => array(
00162                     ApiBase::PROP_TYPE => array(
00163                         'success'
00164                     )
00165                 )
00166             )
00167         );
00168     }
00169 
00170     public function getParamDescription() {
00171         return array(
00172             'token' => 'An options token previously obtained through the action=tokens',
00173             'reset' => 'Resets preferences to the site defaults',
00174             'resetkinds' => 'List of types of options to reset when the "reset" option is set',
00175             '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',
00176             'optionname' => 'A name of a option which should have an optionvalue set',
00177             'optionvalue' => 'A value of the option specified by the optionname, can contain pipe characters',
00178         );
00179     }
00180 
00181     public function getDescription() {
00182         return array(
00183             'Change preferences of the current user',
00184             'Only options which are registered in core or in one of installed extensions,',
00185             'or as options with keys prefixed with \'userjs-\' (intended to be used by user scripts), can be set.'
00186         );
00187     }
00188 
00189     public function getPossibleErrors() {
00190         return array_merge( parent::getPossibleErrors(), array(
00191             array( 'code' => 'notloggedin', 'info' => 'Anonymous users cannot change preferences' ),
00192             array( 'code' => 'nochanges', 'info' => 'No changes were requested' ),
00193         ) );
00194     }
00195 
00196     public function needsToken() {
00197         return true;
00198     }
00199 
00200     public function getTokenSalt() {
00201         return '';
00202     }
00203 
00204     public function getHelpUrls() {
00205         return 'https://www.mediawiki.org/wiki/API:Options';
00206     }
00207 
00208     public function getExamples() {
00209         return array(
00210             'api.php?action=options&reset=&token=123ABC',
00211             'api.php?action=options&change=skin=vector|hideminor=1&token=123ABC',
00212             'api.php?action=options&reset=&change=skin=monobook&optionname=nickname&optionvalue=[[User:Beau|Beau]]%20([[User_talk:Beau|talk]])&token=123ABC',
00213         );
00214     }
00215 }