When developing a large application in WordPress one option is to implement it as a theme rather than a series of plugins. When the project has multiple developers, a challenge then is how to provide each developer their own environment. If the site is standalone then each developer can have their own local WP instance. But what about the database? If different developers are adding records to different databases how are they merged.
Anyway, in my scenario there's a simpler approach. Let each developer have their own copy of the theme within the themes folder. The only requirement then is to be able to allow each user to choose or to be allocated a specific theme. This is really easy to do.
The main function is the one that reacts to the 'wp_loaded' action. The action function looks to see what theme template folder is defined in user meta for the user and returns it. Otherwise it returns a default theme folder.
The rest of the code adds a dropdown of the available themes to the user profile page and saves the the selection if/when the profile is updated.
<?php
/*
Plugin Name: User switch theme
Description: Swap the theme based on the user.
Version: 0.1
Author: Bill Seddon
Author URI: https://github.com/bseddon
License: GPL v3
*/
/**
* Replace the theme with one from user meta data if one exists.
* The plugins_loaded action is called before any theme work occurs
*/
add_action('plugins_loaded', function()
{
$user = wp_get_current_user();
if ( ! isset( $user ) || $user->ID == 0 ) return;
// Get the 'theme' user meta data value
$theme = get_user_meta( $user->ID, 'theme', true );
if ( ! empty( $theme ) )
{
error_log( "wp_loaded: $theme" );
// Replace the theme with the one from the user meta data
add_filter('template', function($template) use ($theme) {
return $theme;
});
// Replace the stylesheet with the one from the user meta data
add_filter('stylesheet', function($stylesheet) use ($theme) {
return $theme;
});
}
});
/**
* Present a drop down list of themes to the user.
* @param object $user The user object currently being edited.
*/
function edit_user_template_name( $user )
{
// If there is no user, there is no theme to add
if ( $user == "add-new-user" || ! current_user_can( 'administrator' ))
{
return;
}
?>
<h3><?php _e( 'Set personal thene' ); ?></h3>
<table class="form-table">
<tr>
<th><label for="theme"><?php _e( 'Testing theme to use' ); ?></label></th>
<td>
<?php
// Get the user's theme
$theme = get_user_meta( $user->ID, 'theme', true );
// Get the current theme
// Can't use the 'current_theme' as it's always the theme of person reviewing the user profile
if ( empty( $theme ) )
{
// Use the option save in appearance->themes as the default
$theme = get_option( 'template', false );
}
// Get the list of themes
$themes = wp_get_themes();
// Create a drop down list of themes
$theme_list = "<select name='theme' id='theme'>";
foreach ( $themes as $theme_name => $theme_data )
{
$theme_list .= "<option value='$theme_name' " . selected( $theme_name, $theme, false ) . ">$theme_name</option>";
}
$theme_list .= "</select>";
echo $theme_list;
?>
</td>
</tr>
</table>
<?php
}
add_action( 'show_user_profile', 'edit_user_template_name' );
add_action( 'edit_user_profile', 'edit_user_template_name' );
add_action( 'user_new_form', 'edit_user_template_name' );
/**
* Save the selected theme for the user.
* @param int $user_id The ID of the user to save the terms for.
*/
function save_user_template_name( $user_id )
{
/* Make sure the current user can edit the user and assign terms before proceeding. */
if ( !current_user_can( 'edit_user', $user_id ) )
return false;
$theme = $_POST['theme'];
if ( ! empty( $theme ) && $theme != "fwsbi" )
{
update_user_meta( $user_id, 'theme', $theme );
}
else
{
delete_user_meta( $user_id, 'theme' );
}
}
add_action( 'personal_options_update', 'save_user_template_name' );
add_action( 'edit_user_profile_update', 'save_user_template_name' );
add_action( 'user_register', 'save_user_template_name' );
?>