Writing Plugins (for WP & WPMU)

All of our children have a blog on one of our WPMU installs. One of them asked Andrea if we could add a facebook plugin so she could follow her facebook stream from her blog. The plugin that Andrea found that she thought would do the trick was the Facebook Dashboard Widget.

After Andrea installed the plugin, our daughter tried it out and found that the options page would not save any settings. I’ve fixed that issue in a few WP plugins in the last few months. It is a fairly straight forward process:

Search through the plugin code and look for functions being added to the the admin_menu hook. In this plugin it was around line 640:

add_action('admin_menu', 'fdw_menus');

Now, I needed to find the fdw_menus function. In this case, it was right above the hook:

function fdw_menus() {
if (current_user_can('manage_options')) {
if (function_exists('add_options_page')) {
add_options_page(__('Facebook Dashboard Widget', 'fdw'), __('Facebook Dashboard Widget', 'fdw'), 8, __FILE__, 'fdw_options');
}
}
}

What I was looking for in that function was the function name that WP/WPMU calls for the admin page. In this case it’s fdw_options. That function can be found at about line 385. The first few lines are

function fdw_options() {
global $fdw;
?>
<div class="wrap">
<form method="post" action="options.php" style="margin-bottom: 60px;">
<h2><?php echo __('Facebook Dashboard Widget Options', 'fdw') ?></h2>
<?php wp_nonce_field('update-options') ?>

There are two changes that I made in this code. I commented out the call to wp_nonce_field (It’s okay to completely remove it because the settings_field that I mention next adds its own wp_nonce_field). And, I added a call to settings_fields passing the name of the option page function as a parameter:

function fdw_options() {
global $fdw;
?>
<div class="wrap">
<form method="post" action="options.php" style="margin-bottom: 60px;">
<?php settings_fields('fdw_options'); ?>
<h2><?php echo __('Facebook Dashboard Widget Options', 'fdw') ?></h2>
<?php //wp_nonce_field('update-options') ?>

There’s another change that needs to be made. For this part, I looked through the form HTML of the options page for hidden element called page_options. I found it at about line 590:

What I needed from this is the comma separated list that is the page_options’ value (fdw_showupdates, fdw_updatesfeed, …). I used that list in a new function that I added to the bottom of the plugin:

function fdw_whitelist($options) {
$added = array( 'fdw_options' => array( 'fdw_showupdates',
'fdw_updatesfeed',
'fdw_updatesmax',
'fdw_updatesheight',
'fdw_updatesnewheight',
'fdw_updateswidth',
'fdw_shownotifications',
'fdw_notificationsfeed',
'fdw_notificationsmax',
'fdw_notificationsheight',
'fdw_notificationsnewheight',
'fdw_notificationswidth',
'fdw_showposted',
'fdw_postedfeed',
'fdw_postedmax',
'fdw_postedheight',
'fdw_postednewheight',
'fdw_postedwidth', )
);
$options = add_option_whitelist( $added, $options );
return $options;
}

The $options parameter to the function is an array where the array key of each element is the name of the option page that the element applies to. The form in this plugin is fdw_options. The value of the array element is an array of option fields on the option page. So, I just converted the comma separated list into an array of values. The call to add_option_whitelist merges the $options parameter and the array I just created.

The last thing to do is hook my function into WP/WPMU. The filter for this is whitelist_options

add_filter('whitelist_options', 'fdw_whitelist');

After those changes the plugin works in both WordPress and WordPress MU (only tested with 2.8.X).

Comments

  1. Hi Ron

    Nice article. :)

    I’m the author of the Facebook Dashboard Widget, and fixing it to work with WPMU is something I’ve been promising people for a while – but as with most things, lack of free time has got into the way.

    If you’ve managed to get it working, I’d love to integrate these fixes into the plugin for the next release – I’ll be sure to give you a credit when I do.

    If you’re happy to do it, would it be possible to email ,e a copy of the new plugin code? It’d be useful to be able to see the changes in a diff viewer.

    Thanks for potentially saving me a lot of time :)

    - Chris

    • Hi Chris,

      Thanks for letting me know. I have a second post that I hope to get to tomorrow where I turn the options into an array so that it only adds one row to the options table.

      Ron

  2. This is a nice article.

    It would have been nicer if you explained WHY you do the things you do.

    I am trying to make the plugin “WP-PhotoContest” MU-compatible, and of course that plugin looks different from the FWD plugin.

    • The brief answer is that the security is stricter in MU than in WP. You need to make those changes to have the options whitelisted to the security in MU. If options are not whitelisted, MU won’t save them.

  3. Wow, you are a god! However, I am SO OUTSIDE my abilities, its not even funny. I am trying to get a plugin called logo-slideshow working in WPMU. (See http://www.iwebix.de/logo-slideshow-wordpress-plugin/)

    It hasn’t been updated by the author in a really long time and the author hasn’t responded to my Email request.

    This seems like a really straightforward little plugin but for the life of me, I can’t figure out how to make it work in MU.

    Any help /hints you can give would be most appreciated. If you know of a good programmer that I can throw this at or of an alternative solution that *is* working with WPMU, I would be most appreciative.

    Thank you!