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