Skip to content

Instantly share code, notes, and snippets.

@dalethedeveloper
Created December 13, 2011 23:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dalethedeveloper/1474525 to your computer and use it in GitHub Desktop.
Save dalethedeveloper/1474525 to your computer and use it in GitHub Desktop.
Generic WP Plugin Admin Menu Implementation - with AJAX!
<?php
/*
Plugin Name: Generic Menu
Plugin URI: http://example.com/
Description: Move things
Author: dalethedeveloper
Version: 0.1
*/
new myadmin_generic();
class myadmin_generic {
protected $nonce_string = 'myadmin_generic_nonce_string';
protected $ajax_slug = 'myadmin';
/**
* Sitewide plugin defaults
*/
public static $option_defaults = array(
'generic_opt_bool' => 'no',
'generic_opt_num' => '1',
'generic_opt_text' => '',
);
public function __construct() {
add_action('admin_menu', array($this, 'admin_menus'));
add_action('wp_ajax_'.$this->ajax_slug, array($this,'ajax_handler'));
add_action('admin_head',array($this,'ajax_script'));
}
/**
* Register Admin page and filtering
*/
public function admin_menus() {
// Example Settings Page, Editors and up
add_menu_page(
'Generic Settings Menu',
'Generic Menu',
'edit_posts',
'myadmin',
array($this,'show_admin_page')
);
// Example Administrator Only Subpage
add_submenu_page(
'myadmin',
'Admin Settings',
'Admin Setings',
'activate_plugins',
'myadmin_page',
array($this,'show_admin_subpage')
);
}
/**
* Handle AJAX calls to and fro, assuming jQuery is doing the hard work.
*/
public function ajax_handler() {
check_ajax_referer($this->nonce_string,'security');
// $this->save_settings(true);
$response = array('message' => $_POST['generic_opt_text']);
header('Content-Type: application/json');
exit( json_encode($response) );
}
/**
* Output javascript with noncing for AJAX requests
*/
public function ajax_script() {
$nonce = wp_create_nonce($this->nonce_string);
echo <<<JS
<script type="text/javascript">
jQuery(document).ready(function($) {
$('form[name="myadmin_opts"]').delegate('input.button-primary.ajax','click',function(){
var input = $(this).closest('form').serialize(),
parent = $(this).parent(),
loading = $('.ajax-feedback',parent);
if( loading.css('visibility') !== 'visible' ) {
$('div.updated',parent).remove();
loading.css('visibility','visible');
$.ajax({
type: 'POST',
url: ajaxurl,
data: input + '&action={$this->ajax_slug}&security={$nonce}',
dataType: 'json',
timeout : 30000,
success: function(data, textStatus, jqXHR) {
if( data ) {
if( data.message )
$('<div class="updated"><p><strong>' + data.message + '</strong></p></div>').appendTo( parent ).delay(1000).fadeOut();
if( data.error )
$('<div class="updated"><p><strong>Error: ' + data.error + '</strong></p></div>').appendTo( parent ).delay(1000).fadeOut();
if( data.reload )
window.location.reload();
}
},
complete: function(jqXHR, textStatus) {
loading.css('visibility','hidden');
if( textStatus !== 'success' )
$('<div class="updated"><p><strong>Unable to completed that action, please try again.</strong></p></div>').appendTo( parent );
}
});
}
return false;
});
});
</script>
JS;
}
/**
* Save $_POST options on posting
*
* @return bool TRUE on saved, FALSE on not saved
*/
public function save_settings($not_ajax = true) {
if( $_POST and !empty($_POST['myadmin_form_nonce']) and wp_verify_nonce( $_POST['myadmin_form_nonce'],$this->nonce_string ) ) {
foreach( array_keys(self::$option_defaults) as $option ) {
if( isset($_POST[$option]) )
update_option($option,$_POST[$option]);
}
if( $not_ajax )
echo '<div class="updated"><p><strong>Settings Saved.</strong></p></div>';
return true;
}
return false;
}
/**
* Output an admin form wrapping our interior options panes
*/
public function output_form( $content ) {
$nonceid = wp_create_nonce($this->nonce_string);
echo <<<HTML
<div class="wrap">
<form name="myadmin_opts" method="post" action="">
{$content}
<input type="hidden" name="myadmin_form_nonce" id="myadmin_form_nonce" value="{$nonceid}" />
</form>
</div>
HTML;
}
/**
* Quick check for permissions, for URL tomfoolery
*
* @param type $cap Capability
*/
public function check_perm($cap) {
if( !current_user_can($cap) ) {
$msg = <<<MSG
<div class="wrap">
<h2>Permission Denied</h2>
<p>
You do not have permission to change these settings. Please contact your site administrator.
</p>
</div>
MSG;
wp_die($msg);
}
}
/**
* Settings page for Generic Admin
*/
public function show_admin_page() {
$this->check_perm('manage_options');
$this->save_settings();
// Load Options
$opt_text = get_option('generic_opt_text');
$opt_bool = get_option('generic_opt_bool','no');
$opt_bool_yes = ($opt_bool == 'yes') ? 'checked="checked" ' : '';
$opt_bool_no = ($opt_bool == 'no') ? 'checked="checked" ' : '';
$opt_num = (int) get_option('generic_opt_num','1');
$opt_num_select = '<select name="generic_opt_num" id="generic_opt_num">';
for($i=1;$i<=5;$i++) {
$opt_num_select .= '<option '.($opt_num==$i?'selected="selected"':'').">$i</option>";
}
$opt_num_select .= '</select>';
$body = <<<HTML
<h2>Admin Menu Title</h2>
<h3>Subtitle</h3>
<p>
A pleasant description of our Options.
</p>
<table class="form-table">
<tr valign="top">
<th scope="row">Text Option</th>
<td>
<input type="text" name="generic_opt_text" id="generic_opt_text" value="{$opt_text}"/>
</td>
</tr>
<tr valign="top">
<th scope="row">Numeric Dropdown Option</th>
<td>
{$opt_num_select}
</td>
</tr>
<tr valign="top">
<th scope="row">Boolean Radio Option</th>
<td>
<input type="radio" name="generic_opt_bool" value="yes" {$opt_bool_yes} /> Yes <br/>
<input type="radio" name="generic_opt_bool" value="no" {$opt_bool_no} /> No
</td>
</tr>
</table>
<p class="submit">
<input type="submit" name="Submit" class="button-primary" value="Save Changes" />
</p>
HTML;
$this->output_form($body);
}
public function show_admin_subpage() {
$this->check_perm('manage_options');
$this->save_settings();
$loading_img = esc_url( admin_url( 'images/wpspin_light.gif' ) );
$body = <<<HTML
<h2>Admin Settings</h2>
<h3>With bonus AJAX Calls!</h3>
<p>
Data is passed from the form below back to the class via jQuery.
</p>
<table class="form-table">
<tr valign="top">
<th scope="row">Post this data back via AJAX:</th>
<td>
<input type="text" name="generic_opt_text" id="generic_opt_text" value="Form input."/>
</td>
</tr>
</table>
<p class="submit">
<input type="submit" name="Submit" class="button-primary ajax" value="Save Changes" />
<img src="{$loading_img}" class="ajax-feedback" title="" alt="" />
</p>
HTML;
$this->output_form($body);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment