WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have been using settings API for my plugins for some time and it used to work well. Now it is broken and I can not figure out why. Apparently, the option validation function is not even called. Form data is properly sent and received, though. (Both figured out by echo resp print_r debugging.)

I boiled down a (hopefully) minimal yet runnable example that retains both features of what I do and structure of how I do it:


Plugin Name: My Plugin
Plugin URI: http://wordpress.org/extend/plugins/myplugin/
Description: Example plugin.
Version: 1.0
Author: Your Name
Author URI: http://your.site
License: GPL2


class MyPlugin extends Plugin {

  function __construct() {
    parent::__construct(array('name' => 'myplugin',
                              'prettyName' => 'My Plugin',
                              'mainFile' => __FILE__));

  function activate() {
    if ( !get_option($this->name) ) {
      $options = array( 'test' => 'testwert' );
      add_option($this->name, $options);

  function deactivate() {}

  function options_validate($input) {
    $options = get_option($this->name);

    $options['test'] = empty($input['test']) ? $options['test'] : $input['test'];

    return $options;

  function setup_settings() {

new MyPlugin();


if ( !class_exists('Plugin') ) {

abstract class Plugin {
  protected $name;
  protected $prettyName;
  protected $mainFile;
  private $hasOptions = true;
  protected $options;

  function __construct($props, $hasOptions = true) {
    $this->name = $props['name'];
    $this->prettyName = $props['prettyName'];
    $this->mainFile = $props['mainFile'];
    $this->hasOptions = $hasOptions;

    if ( $hasOptions ) {
      if ( is_admin() ) {
        // Register Options Page
        add_action('admin_menu', array(&$this, 'admin_menu_init'));
        // Register settings
        add_action('admin_init', array(&$this, 'setup_settings'));

      $this->options = get_option($this->name);

    register_activation_hook($this->mainFile, array(&$this, 'activate'));
    register_deactivation_hook($this->mainFile, array(&$this, 'deactivate'));

  function admin_menu_init() {
    add_options_page($this->prettyName.' -- Options', $this->prettyName, 'manage_options', basename($this->mainFile), array(&$this, 'options_page'));

  abstract function options_validate($input);

  function setup_settings() {
    register_setting($this->name, $this->name, array(&$this, 'options_validate'));

  function options_page() { ?>
    <div class="wrap">
      <h2><?php echo $this->prettyName; ?> &ndash; Settings</h2>
      <form action="" method="post">
        <?php submit_button(); ?>
        <?php settings_fields($this->name); ?>
        <?php do_settings_sections($this->name); ?>
        <?php submit_button(); ?>
    </div> <?php

  abstract function activate();

  abstract function deactivate();




class MyPluginCallbacks {
  private $name = null;
  private $options = null;

  function __construct($name, $options) {
    $this->name = $name;
    $this->options = $options;

  function general_text() {
    echo 'A simple options page demonstration';

  function test() {
    echo "<input id='sanitisation' name='{$this->name}[test]' type='text' value='{$this->options['test']}'/>\n";
    echo "<br /><small>A simple test value.</small>";

$callbacks = new MyPluginCallbacks($this->name, $this->options);

add_settings_section('general', 'General', array(&$callbacks, 'general_text'), $this->name);
add_settings_field('test', 'Test Value:', array(&$callbacks, 'test'), $this->name, 'general');


Can be reproduced on WP 3.3 and the latest build via beta test plugin. There are no visible debug messages (WP_DEBUG is enabled).

Edit: Something that changed is the options page. It used to be options.php but that did no longer work. Now it is options-general.php.

share|improve this question
up vote 0 down vote accepted
<form action="" method="post">

should be

<form action="options.php" method="post">

Must have overcompensated for something there.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.