Skip to content

Instantly share code, notes, and snippets.

@topdown
Last active January 23, 2017 07:15
Show Gist options
  • Save topdown/23070e48bfed00640bd190edaf6662dc to your computer and use it in GitHub Desktop.
Save topdown/23070e48bfed00640bd190edaf6662dc to your computer and use it in GitHub Desktop.
Working example of WP admin ajax
<?php
/**
* Plugin Name: Ajax Example Plugin
* Plugin URI: https://validwebs.com
* Description: Basic Ajax Example
* Version: 0.0.1
* Author: Jeff Behnke
* Author URI: https://validwebs.com
* License: GPL2
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: wporg
* Domain Path: /languages
*
* @see https://developer.wordpress.org/plugins/the-basics/
* @see https://developer.wordpress.org/plugins/the-basics/header-requirements/
*/
// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
die;
}
/**
* @see https://codex.wordpress.org/Administration_Menus#Sample_Menu_Page
*/
add_action( 'admin_menu', 'my_plugin_menu' );
/**
* Admin menu and load page
*
*/
function my_plugin_menu() {
// Add the new admin menu and page and save the returned hook suffix
add_options_page( 'My Plugin Options', 'My Plugin', 'manage_options', 'my-unique-identifier', 'mt_settings_page' );
}
/**
* Basic settings page
*/
function mt_settings_page() {
//must check that the user has the required capability
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
}
// @ToDo Get your values and add them into the form for first page load
?>
<h2>My Plugin Title</h2>
<p>In the text fields hit enter when done.</p>
<div class="form">
<p><input type="text" id="cf_geo_text" name="cf_geo_text" /></p>
<p><select name="cf_geo_select" id="cf_geo_select">
<option value="0">Select one</option>
<option value="1">One</option>
<option value="2">Two</option>
</select></p>
<p><textarea name="cf_geo_textarea" id="cf_geo_textarea" cols="30" rows="10"></textarea></p>
</div>
</div>
<?php
}
/**
* Plugins are always loaded once activated
* Only allow these actions on this plugins page
*
* @see my_plugin_menu() 'my-unique-identifier'
*/
if ( isset( $_REQUEST['page'] ) && $_REQUEST['page'] == 'my-unique-identifier' ) {
add_action( 'admin_footer', 'cfgeo_settings_javascript' );
}
// Only load our ajax processing in the admin panel
if ( is_admin() ) {
add_action( 'wp_ajax_cfgeo_settings', 'cfgeo_settings_callback' );
}
/**
* The JavaScript / Ajax to handle the form
*
* @see https://codex.wordpress.org/Plugin_API/Action_Reference/wp_ajax_(action)
* @see https://codex.wordpress.org/Function_Reference/check_ajax_referer
*/
function cfgeo_settings_javascript() {
// my-special-string should be changed to something unique
$ajax_nonce = wp_create_nonce( "my-special-string" );
?>
<script type="text/javascript">
(function ($) {
$.fn.run_my_ajax = function () {
var This = $(this),
name = This.attr("name"),
value = This.val(),
data = {};
data['action'] = 'cfgeo_settings';
data[name] = value;
data['security'] = '<?php echo $ajax_nonce; ?>';
console.log(data);
//console.log(ajaxurl);
$.post(ajaxurl, data).done(function (returns) {
if (returns != -1) {
// Success
console.log(returns);
var msg = '';
if (returns == 'true') {
msg = 'Settings were saved.';
} else {
msg = 'Nothing changed';
}
if (msg != '') {
$("<div id='notice' class='updated fade'>" +
"<p>" + msg + "</p>" +
"</div>").insertBefore('.form');
}
$('.updated').delay(2000).hide(1000);
} else {
alert('Something went wrong or nonce failed.');
}
});
};
// Handle your events
$(document).ready(function () {
var body = $('body');
// THIS IS A VERY BAD IDEA Do not do on text forms with ajax queries -> change keyup
// You would be querying the database on every keystroke VERY BAD to do
//$("input[id^='cf_geo_'], select[id^='cf_geo_'], textarea[id^='cf_geo_']").on("change keyup", function () {
// Handle selects with deferals
body.on("change", "select[id^='cf_geo_']", function () {
$(this).run_my_ajax();
});
/**
* You can handel this on enter or via on enter trigger button
*/
// Handle text
body.on('keyup', "input[id^='cf_geo_'], textarea[id^='cf_geo_']", function (e) {
// On Enter key pressed
if (e.keyCode == 13) {
$(this).run_my_ajax();
}
});
});
}(window.jQuery));
</script> <?php
}
/**
* Process the ajax post only after nonce check and sanitizing values
*
*/
function cfgeo_settings_callback() {
// First thing
// This will automatically die if the check fails
// my-special-string should be changed to match the unique key where it was defined
check_ajax_referer( 'my-special-string', 'security' );
//echo json_encode( $_POST );
if ( isset( $_POST['action'] ) && $_POST['action'] == 'cfgeo_settings' ) {
// Do the saving
$front_page_elements = array();
$updates = array();
$status = false;
$text = ( isset( $_POST['cf_geo_text'] ) ) ? sanitize_text_field( $_POST['cf_geo_text'] ) : false;
$select = ( isset( $_POST['cf_geo_select'] ) ) ? esc_attr( $_POST['cf_geo_select'] ) : false;
$textarea = ( isset( $_POST['cf_geo_textarea'] ) ) ? sanitize_textarea_field( $_POST['cf_geo_textarea'] ) : false;
// Do something with your data
// NOTE: if you use your keys dynamically from the form that the Ajax post you need to sanitize those also
if ( $text ) {
$status = update_option( 'cf_geo_text', $text );
}
if ( $select ) {
$status = update_option( 'cf_geo_select', $select );
}
// etc....
// Or build an array and store all setting in one option field which is better for performance
// DO NOT DO THIS --------------------------------------
// foreach ( $_POST as $key => $val ) {
// if ( $key != 'cfgeo_settings' ) {
// // $key should need to be santized if done this way
// update_option( $key, esc_attr( $val ) );
// }
// }
// DO NOT DO THIS --------------------------------------
if ( $status ) {
echo 'true';
} else {
echo 'false';
}
} else {
// If we fail return -1 since that is also what a failed nonce returns
echo - 1;
}
wp_die(); // this is required to terminate immediately and return a proper response
}
// End ajax-test.php
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment