Wordpress AJAX not calling PHP function - php

I've tried a bunch of different things but I just cannot get AJAX with Wordpress to work. I clearly don't get something but I do not know what it is. The PHP function works fine since I have tested it, it just seemingly isnt getting through to the JS. The idea is that when someone clicks the #subscribe-btn div its updates that users meta, nothing overly sophisticated. Any help on why this isnt working would be great.
This is in my theme's functions.php:
function add_admin_ajax()
{
wp_localize_script( 'add_ajax', 'functionAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
wp_enqueue_script( 'add_ajax', get_template_directory_uri().'/assets/js/onLoad.js', 'jquery', true);
}
add_action('template_redirect', 'add_admin_ajax');
add_action( 'wp_ajax_subscribe_cat', 'subscribe_cat' );
add_action( 'wp_ajax_nopriv_subscribe_cat', 'subscribe_cat' );
function subscribe_cat()
{
global $current_user;
if(is_user_logged_in())
{
get_currentuserinfo();
$userid = $current_user->ID;
$catsub = get_category(get_query_var('cat'));
$cat_id = $catsub->cat_ID;
$subs = get_user_meta($userid, 'user_subscriptions', true);
if(empty($subs))
{
$subs = array();
}
if(!in_array($cat_id, $subs))
{
$subs[] = $cat_id;
update_user_meta($userid, 'user_subscriptions', $subs);
//echo json_encode($subs);
}
}
die();
}
And then the jQuery:
$(document).on("click", "#subscribe-btn", function (e) {
//e.preventDefault();
$('#subscribe-btn').fadeOut(300);
$.ajax({
url: ajaxurl,
data: {action: "subscribe_cat"},
success: function() {
alert("Yay!")
},
error: function() {
alert("BOo!")
}
}); // end ajax call
});
I'm not getting either the success or error message. The div does fade out though that is something i guess. Any help here? Thanks!
EDIT:
I just changed the action identifier in add_action from subscribe to subscribe_cat and changed the ajax url from functionAjax.ajaxurl to simply ajaxurl. Now its responding. However I get the success alert twice, which I do not understand, and it doesn't seem its actually triggering the PHP function, or at least not properly, since I'm not getting the results I get when I simply call the function in PHP whithout ajax. Any ideas here?

One thing for sure you need to do is change the way your action is setup in the WordPress themes functions.php file.
I think this is an issue: wp_ajax_subscribe
This:
add_action( 'wp_ajax_subscribe', 'subscribe_cat' );
add_action( 'wp_ajax_nopriv_subscribe', 'subscribe_cat' );
should be:
add_action( 'wp_ajax_subscribe_cat', 'subscribe_cat' );
add_action( 'wp_ajax_nopriv_subscribe_cat', 'subscribe_cat' );
The action you set in your javascript needs to match the ending of the first parameter in your wordpress add_action call.
The WordPress documentation

You should pass page info such as query_var as "data" with your ajax function.
frontend page
<?php
$catsub = get_category(get_query_var('cat'));
$cat_id = $catsub->cat_ID;
?>
<script>
$(document).on("click", "#subscribe-btn", function (e) {
e.preventDefault();
$('#subscribe-btn').fadeOut(300);
$.ajax({
url: ajaxurl,
data: {
action: "subscribe_cat",
catid: "<?php echo $cat_id;?>"
},
success: function(response) {
console.log(response);
},
error: function() {
alert("BOo!")
}
}); // end ajax call
});
</script>
Also in your ajax function you had a condition that will always evaluate to false.
functions.php
add_action( 'wp_ajax_subscribe_cat', 'subscribe_cat' );
add_action( 'wp_ajax_nopriv_subscribe_cat', 'subscribe_cat' );
function subscribe_cat(){
//changed here!!
$cat_id = $_POST['catid'];
if(!$cat_id){
echo 'cat_id is missing';
exit;
} elseif(!is_user_logged_in()) {
echo 'Not logged in!';
exit;
}
$userid = get_current_user_id();
$subs = get_user_meta($userid, 'user_subscriptions', true);
if(empty($subs))
$subs = array();
$subs[] = $cat_id;
update_user_meta($userid, 'user_subscriptions', $subs);
echo json_encode($subs);
exit;
}

Related

Converting Javascript data to PHP using ajax in wordpress plugin development

I'm building my first wordpress plugin and I'm having trouble converting a Javascript array of objects into PHP so I can use the data to create individual tables in the wp-admin user area.
Before i actually include the object, i thought i'd try with just a single variable.
Firstly, i included the wp-admin/admin-ajax.php url in wp_localize_script to use in my Javascript file.
function addition_js_script() {
wp_enqueue_script(
'dynamic-maths-addition-js',
DYNAMIC_MATHS_URL . 'includes/shortcodes/addition/addition.js',
['jquery'],
time(),
true
);
wp_localize_script( 'dynamic-maths-addition-js', 'php_data', array(
'user_addition_skill' => get_user_meta( wp_get_current_user()->ID, 'addition-skill-level', true ),
'ajaxurl' => admin_url( 'admin-ajax.php' )
));
}
if (shortcode_exists( 'addition_quiz' ) ){
add_action( 'wp_enqueue_scripts', 'addition_js_script', 100 );
add_action( 'wp_enqueue_scripts', 'addition_css_script', 100 );
}
Then, in addition.js:
jQuery(document).ready(function($){
let numTest = '75';
jQuery.ajax({
url: php_data.ajaxurl,
data: {
'action': 'php_test',
'php_test': numTest
},
success: function(data){
console.log('happy');
}
});
});
Then in my backend menu.php file:
function retrieve_test_number(){
if (isset($_REQUEST)){
$num = $_REQUEST['php_test'];
echo 'This is our JS variable: ' . $num;
}
die();
}
add_action('wp_ajax_php_test_num', 'retrieve_test_number');
Like this, it displays "This is our JS variable: " but no number displays.
And even when I try return this function with the variable $num, and i try echo it out in a tag further down the page, i can't get the variable to display. Forgive me for any ignorance, my php skills are terrible.
Change add_action('wp_ajax_php_test_num', 'retrieve_test_number'); to add_action('wp_ajax_php_test', 'retrieve_test_number');. check below code.
HTML
<p id="num"></p>
Javascript
jQuery(document).ready(function($){
let numTest = '75';
jQuery.ajax({
url: php_data.ajaxurl,
data: {
'action': 'php_test',
'php_test': numTest
},
success: function(data){
console.log('happy');
$('#num').html(data);
}
});
});
PHP
function retrieve_test_number(){
if (isset($_REQUEST)){
$num = $_REQUEST['php_test'];
echo 'This is our JS variable: ' . $num;
}
die();
}
add_action('wp_ajax_php_test', 'retrieve_test_number');
add_action( 'wp_ajax_nopriv_php_test', 'retrieve_test_number' );
Tested and works.

How to pass php variable to wordpress AJAX handler

Struggling to pass through some php variables into my ajax handler function in functions.php
Example provided below doesn't work, probably has something to do with the hooks but I can't find any info on how to do this:
/*Unsubscribe*/
$test_variable = "derp";
function user_unsubscribe($test_variable){
echo json_encode($test_variable);
wp_die();
};
add_action('wp_ajax_user_unsubscribe', 'user_unsubscribe');
add_action('wp_ajax_nopriv_user_unsubscribe', 'user_unsubscribe');
Solved it with this solution: can I pass arguments to my function through add_action?
Working code solution is:
/*Unsubscribe*/
$test_variable = "derp";
function user_unsubscribe($test_variable){
echo json_encode($test_variable);
wp_die();
};
add_action('wp_ajax_user_unsubscribe', function() use ($test_variable){
user_unsubscribe($test_variable);
});
add_action('wp_ajax_nopriv_user_unsubscribe', function() use ($test_variable){
user_unsubscribe($test_variable);
});
You can pass that PHP variable in ajax data. Please check below files in which I had send the "test_variable" Value to Ajax Function from jQuery.
Jquery File Code
jQuery(document).ready(function($) {
$('#btn').on('click',function(){
$.ajax({
data: {action: 'get_listing_names','test': global.test_variable},
type: 'post',
url: global.ajax,
success: function(data) {
console.log(data);
}
});
});
});
Functions.php file Code.
<?php
/**
* Enqueue scripts and styles.
*
* #since 1.0.0
*/
function ja_global_enqueues() {
wp_enqueue_script(
'global',
get_template_directory_uri() . '/js/global.js',
array( 'jquery' ),
'1.0.0',
true
);
wp_localize_script(
'global',
'global',
array(
'ajax' => admin_url( 'admin-ajax.php' ),
'test_variable' => 'Test Value',
)
);
}
add_action( 'wp_enqueue_scripts', 'ja_global_enqueues' );
add_action('wp_ajax_nopriv_get_listing_names', 'ajax_listings');
add_action('wp_ajax_get_listing_names', 'ajax_listings');
function ajax_listings() {
$test_variable = $_POST['test_variable'];
wp_send_json_success( $test_variable );
}
The prefered way to pass variables to ajax is to add them to the request and read them from $_GET or $_POST official documentation
If you need other variables you'll either have to use globals or call a extra function.
favorite
Struggling to pass through some php variables into my ajax handler function in functions.php
Example provided below doesn't work, probably has something to do with the hooks but I can't find any info on how to do this:
function user_unsubscribe(){
$test_variable = get_test_variable();
echo json_encode($test_variable);
wp_die();
};
add_action('wp_ajax_user_unsubscribe', 'user_unsubscribe');
add_action('wp_ajax_nopriv_user_unsubscribe', 'user_unsubscribe');
function get_test_variable() {
// here get/fetch your variable;
/*Unsubscribe*/
$test_variable = "derp";
return $test_variable;
}

Passing variable from Ajax to PHP in WordPress plugin

I am developing a WordPress plugin and I am trying to pass a variable from ajax to a php file. Both files are inside my plugin folder. The js file is running but when I fire the ajax function, it seems that is not sending a post.
Plugin structure:
-plugin folder
--ajax.js
--folder/example.php
This is my ajax.js
// using jQuery ajax
// send the text with PHP
$.ajax({
type: "POST",
url: "/absoluteurlpluginfolder/folder/example.php",
data: {
'action': 'my_action',
'whatever': 1234
},
// dataType: "text",
success: function(data){
console.log('Connection success.');
// console.log(data);
}
});
And this is my example.php
add_action( 'wp_ajax_my_action', 'my_action' );
function my_action() {
global $wpdb; // this is how you get access to the database
$whatever = intval( $_POST['whatever'] );
$whatever += 10;
alert($whatever);
wp_die(); // this is required to terminate immediately and return a proper response
}
I have two problems:
I cannot see that example.php is receiving anything
How could I use a relative URL to connect with my PHP file? When I try such as 'url: "folder/example.php",' it seems that it starts with "http://localhost/my-wp-project/wp-admin/" and not in my plugin folder, and fails.
I think that the main problem was that I need to add "wp_enqueue_script" and "wp_localize_script". However, I am working in the development of a TinyMCE plugin inside WordPress.
That means that although the JS file is already include, it is not working when I add "wp_enqueue_script" and "wp_localize_script". Why? I do not know but the strange thing is that I made it working with another line.
wp_register_script( 'linked-plugin-script', null);
I have tried with different versions, and the minimum necessary to work is this one above. I can put the URL, version, jquery dependency and false or true. All of them work.
So at the end this is my code and is working.
This is the plugin.php
// Include the JS for TinyMCE
function linked_tinymce_plugin( $plugin_array ) {
$plugin_array['linked'] = plugins_url( '/public/js/tinymce/plugins/linked/plugin.js',__FILE__ );
return $plugin_array;
}
// Add the button key for address via JS
function linked_tinymce_button( $buttons ) {
array_push( $buttons, 'linked_button_key' );
return $buttons;
}
// Enqueue the plugin to manage data via AJAX
add_action( 'admin_enqueue_scripts', 'my_enqueue' );
function my_enqueue() {
wp_register_script( 'linked-plugin-script', null);
wp_enqueue_script( 'linked-plugin-script');
// in JavaScript, object properties are accessed as ajax_object.ajax_url, ajax_object.we_value
wp_localize_script( 'linked-plugin-script', 'ajax_object', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'whatever' => '' )
);
}
// Same handler function...
add_action( 'wp_ajax_my_action', 'my_action' );
function my_action() {
global $wpdb;
$whatever = strtoupper($_POST['whatever']);
echo $whatever;
wp_die();
}
And this is the plugin of TinyMCE in JavaScript
// JavaScript file for TinyMCE Linked Plugin
//
//
//
( function() {
tinymce.PluginManager.add( 'linked', function( editor, url ) {
// Add a button that opens a window
editor.addButton( 'linked_button_key', {
// Button name and icon
text: 'Semantic Notation',
icon: false,
// Button fnctionality
onclick: function() {
// get raw text to variable content
var content = tinymce.activeEditor.getContent({format: 'text'});
// using jQuery ajax
// send the text to textrazor API with PHP
$.ajax({
type: 'POST',
url: ajax_object.ajax_url,
data: { 'action': 'my_action',
'whatever': ajax_object.whatever = content
},
beforeSend: function() {
console.log('before send..');
},
success: function(response){
console.log('Success the result is '+response);
}
});
} // onclick function
} ); // TinyMCE button
} ); // tinymce.PluginManager
} )(); // function
Have you seen this page? This is the best tutorial. But you have missed a few things:
You should set global js variable with wp_localize_script() function. Like
wp_localize_script( 'ajax-script', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'we_value' => 1234 ) );
Replace your url in JS to ajax_object.ajax_url.
IF you wanna work ajax with wp_ajax hooks - you should send all your requests do wp-admin/admin-ajax.php. You can get this url by admin_url('admin-ajax.php');.

wordpress search form autocomplete

I am attempting to add auto complete search function in Wordpress, I have the code but auto complete does not trigger when i start typing in the search field, anybody can guide me in the right direction?
//php
add_action( 'init', 'casino_autocomplete_init' );
function casino_autocomplete_init() {
// Register our jQuery UI style and our custom javascript file
wp_enqueue_style('mycasino-jquery-ui','http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css');
wp_enqueue_script( 'my_acsearch', get_template_directory_uri() . '/js/myacsearch.js', array('jquery','jquery-ui-autocomplete'),null,true);
wp_localize_script( 'my_acsearch', 'MyAcSearch', array('url' => admin_url( 'admin-ajax.php' )));
// Function to fire whenever search form is displayed
add_action( 'get_search_form', 'mycasino_autocomplete_search_form' );
// Functions to deal with the AJAX request - one for logged in users, the other for non-logged in users.
add_action( 'wp_ajax_casino_autocompletesearch', 'mycasino_autocomplete_suggestions' );
add_action( 'wp_ajax_nopriv_casino_autocompletesearch', 'mycasino_autocomplete_suggestions' );
}
function mycasino_autocomplete_search_form(){
wp_enqueue_script( 'my_acsearch' );
wp_enqueue_style( 'mycasino-jquery-ui' );
}
function mycasino_autocomplete_suggestions(){
// custom post type
function filter_search($query) {
if ($query->is_search) {
$query->set('post_type', array('custom_post', 'events'));
};
return $query;
};
add_filter('pre_get_posts', 'filter_search');
// Query for suggestions
$posts = get_posts( array(
's' =>$_REQUEST['term'],
) );
// Initialise suggestions array
$suggestions=array();
global $post;
foreach ($posts as $post): setup_postdata($post);
// Initialise suggestion array
$suggestion = array();
$suggestion['label'] = esc_html($post->post_title);
$suggestion['link'] = get_permalink();
// Add suggestion to suggestions array
$suggestions[]= $suggestion;
endforeach;
// JSON encode and echo
$response = $_GET["callback"] . "(" . json_encode($suggestions) . ")";
echo $response;
// Don't forget to exit!
exit;
}
// jquery
jQuery(document).ready(function ($){
var acs_action = "casino_autocompletesearch";
$("#s").autocomplete({
source: function(req, response){
$.getJSON(MyAcSearch.url+"?callback=?&action="+acs_action, req, response);
},
select: function(event, ui) {
window.location.href=ui.item.link;
},
minLength: 3,
});
});
Please make sure you're using get_search_form() for calls and not get_search_query() you can check this inside the themes php file where the search field has been created. The above code can only be used by themes that uses get_search_form()

Wordpress: how to call a plugin function with an ajax call?

I'm writing a Wordpress MU plugin, it includes a link with each post and I want to use ajax to call one of the plugin functions when the user clicks on this link, and then dynamically update the link-text with output from that function.
I'm stuck with the ajax query. I've got this complicated, clearly hack-ish, way to do it, but it is not quite working. What is the 'correct' or 'wordpress' way to include ajax functionality in a plugin?
(My current hack code is below. When I click the generate link I don't get the same output I get in the wp page as when I go directly to sample-ajax.php in my browser.)
I've got my code[1] set up as follows:
mu-plugins/sample.php:
<?php
/*
Plugin Name: Sample Plugin
*/
if (!class_exists("SamplePlugin")) {
class SamplePlugin {
function SamplePlugin() {}
function addHeaderCode() {
echo '<link type="text/css" rel="stylesheet" href="'.get_bloginfo('wpurl').
'/wp-content/mu-plugins/sample/sample.css" />\n';
wp_enqueue_script('sample-ajax', get_bloginfo('wpurl') .
'/wp-content/mu-plugins/sample/sample-ajax.js.php',
array('jquery'), '1.0');
}
// adds the link to post content.
function addLink($content = '') {
$content .= "<span class='foobar clicked'><a href='#'>click</a></span>";
return $content;
}
function doAjax() { //
echo "<a href='#'>AJAX!</a>";
}
}
}
if (class_exists("SamplePlugin")) {
$sample_plugin = new SamplePlugin();
}
if (isset($sample_plugin)) {
add_action('wp_head',array(&$sample_plugin,'addHeaderCode'),1);
add_filter('the_content', array(&$sample_plugin, 'addLink'));
}
mu-plugins/sample/sample-ajax.js.php:
<?php
if (!function_exists('add_action')) {
require_once("../../../wp-config.php");
}
?>
jQuery(document).ready(function(){
jQuery(".foobar").bind("click", function() {
var aref = this;
jQuery(this).toggleClass('clicked');
jQuery.ajax({
url: "http://mysite/wp-content/mu-plugins/sample/sample-ajax.php",
success: function(value) {
jQuery(aref).html(value);
}
});
});
});
mu-plugins/sample/sample-ajax.php:
<?php
if (!function_exists('add_action')) {
require_once("../../../wp-config.php");
}
if (isset($sample_plugin)) {
$sample_plugin->doAjax();
} else {
echo "unset";
}
?>
[1] Note: The following tutorial got me this far, but I'm stumped at this point.
http://www.devlounge.net/articles/using-ajax-with-your-wordpress-plugin
TheDeadMedic is not quite right. WordPress has built in AJAX capabilities. Send your ajax request to /wp-admin/admin-ajax.php using POST with the argument 'action':
jQuery(document).ready(function(){
jQuery(".foobar").bind("click", function() {
jQuery(this).toggleClass('clicked');
jQuery.ajax({
type:'POST',
data:{action:'my_unique_action'},
url: "http://mysite/wp-admin/admin-ajax.php",
success: function(value) {
jQuery(this).html(value);
}
});
});
});
Then hook it in the plugin like this if you only want it to work for logged in users:
add_action('wp_ajax_my_unique_action',array($sample_plugin,'doAjax'));
or hook it like this to work only for non-logged in users:
add_action('wp_ajax_nopriv_my_unique_action',array($sample_plugin,'doAjax'));
Use both if you want it to work for everybody.
admin-ajax.php uses some action names already, so make sure you look through the file and don't use the same action names, or else you'll accidentally try to do things like delete comments, etc.
EDIT
Sorry, I didn't quite understand the question. I thought you were asking how to do an ajax request. Anyway, two things I'd try:
First, have your function echo just the word AJAX without the a tag. Next, try changing your ajax call so it has both a success and a complete callback:
jQuery(document).ready(function(){
jQuery(".foobar").bind("click", function() {
var val = '';
jQuery(this).toggleClass('clicked');
jQuery.ajax({
type:'POST',
data:{action:'my_unique_action'},
url: "http://mysite/wp-admin/admin-ajax.php",
success: function(value) {
val = value;
},
complete: function(){
jQuery(this).html(val);
}
});
});
});
WordPress environment
First of all, in order to achieve this task, it's recommended to register then enqueue a jQuery script that will push the request to the server. These operations will be hooked in wp_enqueue_scripts action hook. In the same hook you should put wp_localize_script that it's used to include arbitrary Javascript. By this way there will be a JS object available in front end. This object carries on the correct url to be used by the jQuery handle.
Please take a look to:
wp_register_script(); function
wp_enqueue_scripts hook
wp_enqueue_script(); function
wp_localize_script(); function
File: functions.php 1/2
add_action( 'wp_enqueue_scripts', 'so_enqueue_scripts' );
function so_enqueue_scripts(){
wp_register_script( 'ajaxHandle', get_template_directory() . 'PATH TO YOUR JS FILE', array(), false, true );
wp_enqueue_script( 'ajaxHandle' );
wp_localize_script( 'ajaxHandle', 'ajax_object', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}
File: jquery.ajax.js
This file makes the ajax call.
jQuery(document).ready( function($){
//Some event will trigger the ajax call, you can push whatever data to the server, simply passing it to the "data" object in ajax call
$.ajax({
url: ajax_object.ajaxurl, // this is the object instantiated in wp_localize_script function
type: 'POST',
data:{
action: 'myaction', // this is the function in your functions.php that will be triggered
name: 'John',
age: '38'
},
success: function( data ){
//Do something with the result from server
console.log( data );
}
});
});
File: functions.php 2/2
Finally on your functions.php file there should be the function triggered by your ajax call.
Remember the suffixes:
wp_ajax ( allow the function only for registered users or admin panel operations )
wp_ajax_nopriv ( allow the function for no privilege users )
These suffixes plus the action compose the name of your action:
wp_ajax_myaction or wp_ajax_nopriv_myaction
add_action( 'wp_ajax_myaction', 'so_wp_ajax_function' );
add_action( 'wp_ajax_nopriv_myaction', 'so_wp_ajax_function' );
function so_wp_ajax_function(){
//DO whatever you want with data posted
//To send back a response you have to echo the result!
echo $_POST['name'];
echo $_POST['age'];
wp_die(); // ajax call must die to avoid trailing 0 in your response
}
Hope it helps!
Let me know if something is not clear.
Just to add an information.
If you want to receive an object from a php class method function :
js file
jQuery(document).ready(function(){
jQuery(".foobar").bind("click", function() {
var data = {
'action': 'getAllOptionsByAjax',
'arg1': 'val1',
'arg2': $(this).val()
};
jQuery.post( ajaxurl, data, function(response) {
var jsonObj = JSON.parse( response );
});
});
php file
public static function getAllOptionsByAjax(){
global $wpdb;
// Start query string
$query_string = "SELECT * FROM wp_your_table WHERE col1='" . $_POST['arg1'] . "' AND col2 = '" . $_POST['arg2'] . "' ";
// Return results
$a_options = $wpdb->get_results( $query_string, ARRAY_A );
$f_options = array();
$f_options[null] = __( 'Please select an item', 'my_domain' );
foreach ($a_options as $option){
$f_options [$option['id']] = $option['name'];
}
$json = json_encode( $f_options );
echo $json;
wp_die();
}

Categories