/** * Changes preferences of the current user. */ public function execute() { $user = $this->getUser(); if ($user->isAnon()) { $this->dieUsage('Anonymous users cannot change preferences', 'notloggedin'); } if (!$user->isAllowed('editmyoptions')) { $this->dieUsage('You don\'t have permission to edit your options', 'permissiondenied'); } $params = $this->extractRequestParams(); $changed = false; if (isset($params['optionvalue']) && !isset($params['optionname'])) { $this->dieUsageMsg(array('missingparam', 'optionname')); } if ($params['reset']) { $user->resetOptions(); $changed = true; } $changes = array(); if (count($params['change'])) { foreach ($params['change'] as $entry) { $array = explode('=', $entry, 2); $changes[$array[0]] = isset($array[1]) ? $array[1] : null; } } if (isset($params['optionname'])) { $newValue = isset($params['optionvalue']) ? $params['optionvalue'] : null; $changes[$params['optionname']] = $newValue; } if (!$changed && !count($changes)) { $this->dieUsage('No changes were requested', 'nochanges'); } $prefs = Preferences::getPreferences($user, $this->getContext()); foreach ($changes as $key => $value) { if (empty($prefs[$key])) { // This is not a default preference and cannot be modified by this API $validation = 'not a valid preference'; } else { $field = HTMLForm::loadInputFromParameters($key, $prefs[$key]); $validation = $field->validate($value, $user->getOptions()); } if ($validation === true) { $user->setGlobalPreference($key, $value); $changed = true; } else { $this->setWarning("Validation error for '{$key}': {$validation}"); } } if ($changed) { // Commit changes $user->saveSettings(); } $this->getResult()->addValue(null, $this->getModuleName(), 'success'); }
/** * @param $user User * @param $context IContextSource * @param $formClass string * @param array $remove array of items to remove * @return HtmlForm */ static function getFormObject( $user, IContextSource $context, $formClass = 'PreferencesForm', array $remove = array() ) { $formDescriptor = Preferences::getPreferences( $user, $context ); if ( count( $remove ) ) { $removeKeys = array_flip( $remove ); $formDescriptor = array_diff_key( $formDescriptor, $removeKeys ); } // Remove type=api preferences. They are not intended for rendering in the form. foreach ( $formDescriptor as $name => $info ) { if ( isset( $info['type'] ) && $info['type'] === 'api' ) { unset( $formDescriptor[$name] ); } } /** * @var $htmlForm PreferencesForm */ $htmlForm = new $formClass( $formDescriptor, $context, 'prefs' ); $htmlForm->setModifiedUser( $user ); $htmlForm->setId( 'mw-prefs-form' ); $htmlForm->setSubmitText( $context->msg( 'saveprefs' )->text() ); # Used message keys: 'accesskey-preferences-save', 'tooltip-preferences-save' $htmlForm->setSubmitTooltip( 'preferences-save' ); $htmlForm->setSubmitID( 'prefsubmit' ); $htmlForm->setSubmitCallback( array( 'Preferences', 'tryFormSubmit' ) ); return $htmlForm; }
/** * Return an associative array mapping preferences keys to the kind of a preference they're * used for. Different kinds are handled differently when setting or reading preferences. * * See User::listOptionKinds for the list of valid option types that can be provided. * * @see User::listOptionKinds * @param IContextSource $context * @param array $options Assoc. array with options keys to check as keys. * Defaults to $this->mOptions. * @return array The key => kind mapping data */ public function getOptionKinds(IContextSource $context, $options = null) { $this->loadOptions(); if ($options === null) { $options = $this->mOptions; } $prefs = Preferences::getPreferences($this, $context); $mapping = array(); // Pull out the "special" options, so they don't get converted as // multiselect or checkmatrix. $specialOptions = array_fill_keys(Preferences::getSaveBlacklist(), true); foreach ($specialOptions as $name => $value) { unset($prefs[$name]); } // Multiselect and checkmatrix options are stored in the database with // one key per option, each having a boolean value. Extract those keys. $multiselectOptions = array(); foreach ($prefs as $name => $info) { if (isset($info['type']) && $info['type'] == 'multiselect' || isset($info['class']) && $info['class'] == 'HTMLMultiSelectField') { $opts = HTMLFormField::flattenOptions($info['options']); $prefix = isset($info['prefix']) ? $info['prefix'] : $name; foreach ($opts as $value) { $multiselectOptions["{$prefix}{$value}"] = true; } unset($prefs[$name]); } } $checkmatrixOptions = array(); foreach ($prefs as $name => $info) { if (isset($info['type']) && $info['type'] == 'checkmatrix' || isset($info['class']) && $info['class'] == 'HTMLCheckMatrix') { $columns = HTMLFormField::flattenOptions($info['columns']); $rows = HTMLFormField::flattenOptions($info['rows']); $prefix = isset($info['prefix']) ? $info['prefix'] : $name; foreach ($columns as $column) { foreach ($rows as $row) { $checkmatrixOptions["{$prefix}{$column}-{$row}"] = true; } } unset($prefs[$name]); } } // $value is ignored foreach ($options as $key => $value) { if (isset($prefs[$key])) { $mapping[$key] = 'registered'; } elseif (isset($multiselectOptions[$key])) { $mapping[$key] = 'registered-multiselect'; } elseif (isset($checkmatrixOptions[$key])) { $mapping[$key] = 'registered-checkmatrix'; } elseif (isset($specialOptions[$key])) { $mapping[$key] = 'special'; } elseif (substr($key, 0, 7) === 'userjs-') { $mapping[$key] = 'userjs'; } else { $mapping[$key] = 'unused'; } } return $mapping; }
/** * Changes preferences of the current user. */ public function execute() { $user = $this->getUser(); if ($user->isAnon()) { $this->dieUsage('Anonymous users cannot change preferences', 'notloggedin'); } if (!$user->isAllowed('editmyoptions')) { $this->dieUsage('You don\'t have permission to edit your options', 'permissiondenied'); } $params = $this->extractRequestParams(); $changed = false; if (isset($params['optionvalue']) && !isset($params['optionname'])) { $this->dieUsageMsg(array('missingparam', 'optionname')); } // Load the user from the master to reduce CAS errors on double post (T95839) if (wfGetLB()->getServerCount() > 1) { $user = User::newFromId($user->getId()); if (!$user->loadFromId(User::READ_EXCLUSIVE)) { $this->dieUsage('Anonymous users cannot change preferences', 'notloggedin'); } } if ($params['reset']) { $user->resetOptions($params['resetkinds'], $this->getContext()); $changed = true; } $changes = array(); if (count($params['change'])) { foreach ($params['change'] as $entry) { $array = explode('=', $entry, 2); $changes[$array[0]] = isset($array[1]) ? $array[1] : null; } } if (isset($params['optionname'])) { $newValue = isset($params['optionvalue']) ? $params['optionvalue'] : null; $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); $htmlForm = null; foreach ($changes as $key => $value) { switch ($prefsKinds[$key]) { case 'registered': // Regular option. if ($htmlForm === null) { // We need a dummy HTMLForm for the validate callback... $htmlForm = new HTMLForm(array(), $this); } $field = HTMLForm::loadInputFromParameters($key, $prefs[$key]); $field->mParent = $htmlForm; $validation = $field->validate($value, $user->getOptions()); break; case 'registered-multiselect': case 'registered-checkmatrix': // A key for a multiselect or checkmatrix option. $validation = true; $value = $value !== null ? (bool) $value : null; 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 'special': $validation = "cannot be set by this module"; 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 ($changed) { // Commit changes $user->saveSettings(); } $this->getResult()->addValue(null, $this->getModuleName(), 'success'); }
/** * @param $user User * @param $formClass string * @return HtmlForm */ static function getFormObject($user, $formClass = 'PreferencesForm') { $formDescriptor = Preferences::getPreferences($user); $htmlForm = new $formClass($formDescriptor, 'prefs'); $htmlForm->setId('mw-prefs-form'); $htmlForm->setSubmitText(wfMsg('saveprefs')); # Used message keys: 'accesskey-preferences-save', 'tooltip-preferences-save' $htmlForm->setSubmitTooltip('preferences-save'); $htmlForm->setTitle(SpecialPage::getTitleFor('Preferences')); $htmlForm->setSubmitID('prefsubmit'); $htmlForm->setSubmitCallback(array('Preferences', 'tryFormSubmit')); return $htmlForm; }
/** * @param $user User * @param $context IContextSource * @param $formClass string * @param $remove Array: array of items to remove * @return HtmlForm */ static function getFormObject($user, IContextSource $context, $formClass = 'PreferencesForm', array $remove = array()) { $formDescriptor = Preferences::getPreferences($user, $context); if (count($remove)) { $removeKeys = array_flip($remove); $formDescriptor = array_diff_key($formDescriptor, $removeKeys); } /** * @var $htmlForm PreferencesForm */ $htmlForm = new $formClass($formDescriptor, $context, 'prefs'); $htmlForm->setModifiedUser($user); $htmlForm->setId('mw-prefs-form'); $htmlForm->setSubmitText($context->msg('saveprefs')->text()); # Used message keys: 'accesskey-preferences-save', 'tooltip-preferences-save' $htmlForm->setSubmitTooltip('preferences-save'); $htmlForm->setSubmitID('prefsubmit'); $htmlForm->setSubmitCallback(array('Preferences', 'tryFormSubmit')); return $htmlForm; }
static function getFormObject($user) { $formDescriptor = Preferences::getPreferences($user); $htmlForm = new PreferencesForm($formDescriptor, 'prefs'); $htmlForm->setSubmitText(wfMsg('saveprefs')); $htmlForm->setTitle(SpecialPage::getTitleFor('Preferences')); $htmlForm->setSubmitID('prefsubmit'); $htmlForm->setSubmitCallback(array('Preferences', 'tryFormSubmit')); return $htmlForm; }
/** * Changes preferences of the current user. */ public function execute() { $user = $this->getUser(); if ($user->isAnon()) { $this->dieUsage('Anonymous users cannot change preferences', 'notloggedin'); } $params = $this->extractRequestParams(); $changed = false; if (isset($params['optionvalue']) && !isset($params['optionname'])) { $this->dieUsageMsg(array('missingparam', 'optionname')); } if ($params['reset']) { $user->resetOptions($params['resetkinds']); $changed = true; } $changes = array(); if (count($params['change'])) { foreach ($params['change'] as $entry) { $array = explode('=', $entry, 2); $changes[$array[0]] = isset($array[1]) ? $array[1] : null; } } if (isset($params['optionname'])) { $newValue = isset($params['optionvalue']) ? $params['optionvalue'] : null; $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': case 'registered-checkmatrix': // A key for a multiselect or checkmatrix option. $validation = true; $value = $value !== null ? (bool) $value : null; 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 ($changed) { // Commit changes $user->saveSettings(); } $this->getResult()->addValue(null, $this->getModuleName(), 'success'); }
/** * Return an associative array mapping preferences keys to the kind of a preference they're * used for. Different kinds are handled differently when setting or reading preferences. * * See User::listOptionKinds for the list of valid option types that can be provided. * * @see User::listOptionKinds * @param $context IContextSource * @param array $options assoc. array with options keys to check as keys. Defaults to $this->mOptions. * @return array the key => kind mapping data */ public function getOptionKinds( IContextSource $context, $options = null ) { $this->loadOptions(); if ( $options === null ) { $options = $this->mOptions; } $prefs = Preferences::getPreferences( $this, $context ); $mapping = array(); // Multiselect and checkmatrix options are stored in the database with // one key per option, each having a boolean value. Extract those keys. $multiselectOptions = array(); foreach ( $prefs as $name => $info ) { if ( ( isset( $info['type'] ) && $info['type'] == 'multiselect' ) || ( isset( $info['class'] ) && $info['class'] == 'HTMLMultiSelectField' ) ) { $opts = HTMLFormField::flattenOptions( $info['options'] ); $prefix = isset( $info['prefix'] ) ? $info['prefix'] : $name; foreach ( $opts as $value ) { $multiselectOptions["$prefix$value"] = true; } unset( $prefs[$name] ); } } $checkmatrixOptions = array(); foreach ( $prefs as $name => $info ) { if ( ( isset( $info['type'] ) && $info['type'] == 'checkmatrix' ) || ( isset( $info['class'] ) && $info['class'] == 'HTMLCheckMatrix' ) ) { $columns = HTMLFormField::flattenOptions( $info['columns'] ); $rows = HTMLFormField::flattenOptions( $info['rows'] ); $prefix = isset( $info['prefix'] ) ? $info['prefix'] : $name; foreach ( $columns as $column ) { foreach ( $rows as $row ) { $checkmatrixOptions["$prefix-$column-$row"] = true; } } unset( $prefs[$name] ); } } // $value is ignored foreach ( $options as $key => $value ) { if ( isset( $prefs[$key] ) ) { $mapping[$key] = 'registered'; } elseif ( isset( $multiselectOptions[$key] ) ) { $mapping[$key] = 'registered-multiselect'; } elseif ( isset( $checkmatrixOptions[$key] ) ) { $mapping[$key] = 'registered-checkmatrix'; } elseif ( substr( $key, 0, 7 ) === 'userjs-' ) { $mapping[$key] = 'userjs'; } else { $mapping[$key] = 'unused'; } } return $mapping; }