WooCommerce: how to check user authorization via REST API - php

In my store there is an iframe in which products are placed. Iframe has the ability to save the selected product configuration, but only authorized users can do this.Thus, need to check whether the token has entered under login or not. Wordpress provides the function is_user_logged_in () but it does not suit me.My question is this: is there a way to do the same through the REST API?

https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/
The WP REST ajax call itself by default doesn't carry over the cookie. You can follow the above ref, using this way:
In PHP:
<?php
wp_localize_script( 'wp-api', 'wpApiSettings', array(
'root' => esc_url_raw( rest_url() ),
'nonce' => wp_create_nonce( 'wp_rest' )
) );
In JS:
$.ajax( {
url: wpApiSettings.root + 'wp/v2/posts/1',
method: 'POST',
beforeSend: function ( xhr ) {
xhr.setRequestHeader( 'X-WP-Nonce', wpApiSettings.nonce );
},
data:{
'title' : 'Hello Moon'
}
} ).done( function ( response ) {
console.log( response );
} );
WP will automatically setup the user in REST with that. And you can use is_user_logged_in() now.

Related

Ajax post request results with 400 error in wordpress

I'm currently developing a plugin. In the plugin's main.php file, I have the following code to do an ajax post request:
main.php
<?php
add_action( 'admin_footer', 'first_ajax' );
function first_ajax() { ?>
<script type="text/javascript">
jQuery(document).ready(function($) {
$('#mybutton').click(function(){
$.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'POST',
data: {
action : 'second_ajax'
},
success: function(response) {
console.log("successful");
},
error: function(err) {
console.log(err);
}
});
});
});
</script>
<?php } ?>
But on the browser console, I see an error object.
Screenshot 1
Screenshot 2
I wrote this function taking as reference: https://codex.wordpress.org/AJAX_in_Plugins.
Any help is appreciated.
You're calling javascript from a php function tho your javascript is "raw" and not wrapped in a php variable. We're also missing a bunch of information in regard to the ajax action function (the php part which is supposed to answer to the request).
An ajax request need two things to be able to work properly.
The javascript call to action function and the backend php action function.
It a standard to use anonymous php functions as action functions.
Ajax action functions hooks are prepended with a wp_ajax_{$action} for public function (non-logged-in users) and wp_ajax_nopriv_{$action} for logged-in users. A logged-in user won't be able to use a public ajax function same goes for non-logged-in users.
The {$action} part is set in your javascript call to action function.
It is standard to pass a nonce as well as the ajax admin url through the localize_script() function. Localizing data only works if the script has already been registered.
An example of registering/enqueuing a script and localizing varaibles: functions.php
<?php
wp_enqueue_script( 'my-ajax-script', trailingslashit( get_template_directory_uri() ) . 'assets/js/my-ajax-script.js', array(), wp_get_theme()->version, true );
wp_localize_script( 'my-ajax-script', 'localize', array(
'_ajax_url' => admin_url( 'admin-ajax.php' ),
'_ajax_nonce' => wp_create_nonce( '_ajax_nonce' ),
) );
(The Object's name localize and variables _ajax_url and _ajax_nonce used in wp_localize_script() are just a personal preference).
A basic javascrip ajax call to action function looks like this: my-ajax-script.js
$( '#selector' ).click( function ( event ) {
$.ajax( {
type: 'POST',
url: localize._ajax_url,
context: this,
data: {
_ajax_nonce: localize._ajax_nonce,
action: '_wpso_73933867', //where this match {$action} from wp_ajax_{$action} in our php action function.
},
success: function ( response ) {
console.log( response );
//...
},
} );
} );
Where we use are localized variables: localize._ajax_url and localize._ajax_nonce (best practices).
A basic php ajax action function looks like this: functions.php
<?php
add_action( 'wp_ajax__wpso_73933867', function () {
if ( check_ajax_referer( '_ajax_nonce' ) ) {
//...
wp_send_json_success();
} else {
//...
wp_send_json_error();
};
wp_die();
} );
If the function is intended to be use by a non-logged-in user wp_ajax_nopriv should be prepended instead of wp_ajax_. Vice versa. If both case are supposed to be used, the function should be doubled.

Nonce has not been verifed - Woocommerce problem

I have problem with nonce,
I have ajax calls that download cost and dates from API, recently I made change to posts, they are not wordpress posts that "pretend" to be a products, they are now products from woocommerce.
Old posts have no problems with veryfing nonce, new ones can't verify nonces. I really didn't change anything besides making Woocommerce.php that use my product.twig instead of making products using gutenberg.
Here's my jsData:
declare const jsData: { ajaxUrl: string; nonce: string; post_id: number; google_api_key: string; theme_uri: string }
Here's ajax call:
async addToCart(dateStart: DateTime, dateEnd: DateTime) {
const formData = new FormData()
formData.append('nonce', jsData.nonce)
formData.append('action', 'addToCart')
formData.append('product_id', `${jsData.post_id}`)
formData.append('booked_date_start', dateStart.format('YYYY-MM-DD'))
formData.append('booked_date_end', dateEnd.format('YYYY-MM-DD'))
return callAjax({
method: 'POST',
body: formData,
}).then(res => res.json())
}
This is my assets.php where I create nonce and i transfer it to js bundle
$nonce = wp_create_nonce('ajax');
// type in jsData.d.ts
$transferDatas = [
'ajaxUrl' => admin_url('admin-ajax.php?data-nonce="' . $nonce . '"'),
'nonce' => $nonce,
'post_id' => get_the_ID(),
'theme_uri' => get_stylesheet_directory_uri(),
'google_api_key' => get_field('google_api_key', 'options'),
];
wp_localize_script('bundle-js', 'jsData', $transferDatas);
And this is how I try to verify nonce
if (wp_verify_nonce($_POST['nonce'], 'ajax')) ...
I tried to change post to REQUEST, and I added action which register session on init like below in my functions.php
function register_my_session()
{
if( !session_id() )
{
session_start();
}
}
Do you have any ideas what can I change to make those nonces verifed like on old posts (that are still up and work - new ones doesnt work)?

Wordpress Admin Ajax 400 (Bad Request)

I have used Wordpress Admin Ajax and the console shows that 400 (Bad Request)
jQuery('#submitid').click(function(e){
e.preventDefault();
//var newCustomerForm = jQuery(this).serialize();
jQuery.ajax({
type: "POST",
url: "wp-admin/admin-ajax.php",
data: {status: 'status', name: 'name'},
success:function(data){
jQuery("#result").html(data);
}
});
});
The Wordpress AJAX process has some basic points that should be followed if you want it to work correctly:
1.In functions.php add the action you'd like to call from the frontend:
function logged_in_action_name() {
// your action if user is logged in
}
function not_logged_in_action_name() {
// your action if user is NOT logged in
}
add_action( 'wp_ajax_logged_in_action_name', 'logged_in_action_name' );
add_action( 'wp_ajax_nopriv_not_logged_in_action_name', 'not_logged_in_action_name' );
2.Register the localization object in functions.php
// Register the script
wp_register_script( 'some_handle', 'path/to/myscript.js' );
// Localize the script with new data
$some_object = array(
'ajax_url' => admin_url( 'admin-ajax.php' )
);
wp_localize_script( 'some_handle', 'ajax_object', $some_object );
// Enqueued script with localized data.
wp_enqueue_script( 'some_handle' );
3.Create the AJAX request on the frontend
// source: https://codex.wordpress.org/AJAX_in_Plugins
var data = {
'action': 'not_logged_in_action_name',
'whatever': 1234
};
jQuery.post( ajax_object.ajax_url, data, function( response ) {
console.log( response );
}
All Wordpress Ajax call must have action param which points to hook wp_ajax_{action_param} or wp_ajax_nopriv_{action_param} and from there you jump to function from that hooks.
From Codex:
add_action( 'wp_ajax_my_action', 'my_action' );
add_action( 'wp_ajax_nopriv_my_action', 'my_action' );
function my_action() {
$status = $_POST['status'];
}
first you shouldn't write the url by yourself. You could use the localize function to add the url to your javascript file:
wp_enqueue_script('myHandle','pathToJS');
wp_localize_script(
'myHandle',
'ajax_obj',
array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) )
);
After this you can use ajax_obj.ajax_url within your script to receive the url.
Second, did you implement the correct hook?
// Only accessible by logged in users
add_action( 'wp_ajax_my_action', 'my_action_callback' );
// Accessible by all visitors
add_action( 'wp_ajax_nopriv_my_action', 'my_action_callback' );
Best Regards

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');.

load php function on ajax success

I'm looking for a way to call a php function if an ajax request is successful.
Basic setup code:
wp_register_script( 'theme-follow-me-ajax', ... );
wp_localize_script('theme-follow-me-ajax', 'ajax_setting', array(
'ajax_url' => admin_url('admin-ajax.php'),
'ajax_follow_error' => $this->km_follow_me_error(),
....
));
wp_enqueue_script( 'theme-follow-me-ajax' );
Content to display the error, which should be customizable
public function km_follow_me_error() {
$content = esc_html__( 'An error happened. We\'re unable to complete your request.', 'theme' );
echo apply_filters( 'theme_hook_follow_me_error_message', $content );
}
Ajax call:
$.ajax( {
url : ajax_setting.ajax_url,
type : 'post',
data: {
action : 'km_ajax_follow_me',
security : ajax_setting.ajax_nonce,
...
},
success: function( data ) {
$('.km-follow-me').html( ajax_setting.ajax_follow_success ).hide().fadeIn( 'slow' );
//console.log( ajax_setting.ajax_follow_success );
},
} )
WP wp_ajax_ function
public function addon_ajax_follow_me() {
check_ajax_referer( 'km-ajax-create-nonce', 'security' );
... update user meta ...
wp_die();
}
$this->loader->add_action( 'wp_ajax_km_ajax_follow_me', $plugin_public, 'addon_ajax_follow_me' );
In console I get the null message, so it's not grabbing the km_follow_me_error function.
Is there a better way?
You're doing it incorrectly. A PHP function cannot be called/accessed from Javascript the way you're trying to do. You have two options to call that function on your AJAX success.
Create/register another AJAX function in WordPress, maybe named as ajax_follow_success and call it in success of the previous AJAX call.
Identify in your first function WordPress AJAX function i.e. addon_ajax_follow_me whether it's a success or failure and call the next function there.

Categories