(bug 35885) remove api version string and parameter
[lhc/web/wiklou.git] / includes / api / ApiOptions.php
index 4398eb0..6ed324c 100644 (file)
@@ -47,34 +47,73 @@ class ApiOptions extends ApiBase {
                }
 
                $params = $this->extractRequestParams();
-               $changes = 0;
+               $changed = false;
 
                if ( isset( $params['optionvalue'] ) && !isset( $params['optionname'] ) ) {
                        $this->dieUsageMsg( array( 'missingparam', 'optionname' ) );
                }
 
                if ( $params['reset'] ) {
-                       $user->resetOptions();
-                       $changes++;
+                       $user->resetOptions( 'all' );
+                       $changed = true;
                }
+
+               $changes = array();
                if ( count( $params['change'] ) ) {
                        foreach ( $params['change'] as $entry ) {
                                $array = explode( '=', $entry, 2 );
-                               $user->setOption( $array[0], isset( $array[1] ) ? $array[1] : null );
-                               $changes++;
+                               $changes[$array[0]] = isset( $array[1] ) ? $array[1] : null;
                        }
                }
                if ( isset( $params['optionname'] ) ) {
                        $newValue = isset( $params['optionvalue'] ) ? $params['optionvalue'] : null;
-                       $user->setOption( $params['optionname'], $newValue );
-                       $changes++;
+                       $changes[$params['optionname']] = $newValue;
+               }
+               if ( !$changed && !count( $changes ) ) {
+                       $this->dieUsage( 'No changes were requested', 'nochanges' );
+               }
+
+               $prefs = Preferences::getPreferences( $user, $this->getContext() );
+               $prefsKinds = $user->getOptionKinds( $this->getContext(), $changes );
+
+               foreach ( $changes as $key => $value ) {
+                       switch ( $prefsKinds[$key] ) {
+                               case 'registered':
+                                       // Regular option.
+                                       $field = HTMLForm::loadInputFromParameters( $key, $prefs[$key] );
+                                       $validation = $field->validate( $value, $user->getOptions() );
+                                       break;
+                               case 'registered-multiselect':
+                                       // A key for a multiselect option.
+                                       $validation = true;
+                                       $value = (bool)$value;
+                                       break;
+                               case 'userjs':
+                                       // Allow non-default preferences prefixed with 'userjs-', to be set by user scripts
+                                       if ( strlen( $key ) > 255 ) {
+                                               $validation = "key too long (no more than 255 bytes allowed)";
+                                       } elseif ( preg_match( "/[^a-zA-Z0-9_-]/", $key ) !== 0 ) {
+                                               $validation = "invalid key (only a-z, A-Z, 0-9, _, - allowed)";
+                                       } else {
+                                               $validation = true;
+                                       }
+                                       break;
+                               case 'unused':
+                               default:
+                                       $validation = "not a valid preference";
+                                       break;
+                       }
+                       if ( $validation === true ) {
+                               $user->setOption( $key, $value );
+                               $changed = true;
+                       } else {
+                               $this->setWarning( "Validation error for '$key': $validation" );
+                       }
                }
 
-               if ( $changes ) {
+               if ( $changed ) {
                        // Commit changes
                        $user->saveSettings();
-               } else {
-                       $this->dieUsage( 'No changes were requested', 'nochanges' );
                }
 
                $this->getResult()->addValue( null, $this->getModuleName(), 'success' );
@@ -130,7 +169,11 @@ class ApiOptions extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Change preferences of the current user';
+               return array(
+                       'Change preferences of the current user',
+                       'Only options which are registered in core or in one of installed extensions,',
+                       'or as options with keys prefixed with \'userjs-\' (intended to be used by user scripts), can be set.'
+               );
        }
 
        public function getPossibleErrors() {
@@ -159,8 +202,4 @@ class ApiOptions extends ApiBase {
                        'api.php?action=options&reset=&change=skin=monobook&optionname=nickname&optionvalue=[[User:Beau|Beau]]%20([[User_talk:Beau|talk]])&token=123ABC',
                );
        }
-
-       public function getVersion() {
-               return __CLASS__ . ': $Id$';
-       }
 }