Woocommerce WC_Form_Handler not found - php

I'm newly using classes in my Plugin. Before I've used classes, my Ajax add to cart function worked fine.
Now I'm getting this error:
Uncaught Error: Class 'system\core\WC_Form_Handler' not found
("system\core" is the namespace of my file)
Before I am calling Wc_Form_Handler::add_to_cart_action(); I'm checking if this specific class exists. So if the class wouldn't exist, the class wouldn't be called later...)
I've also taken a look into get_declared_classes(); to make sure that my classes are called after the Wc_Form_Handler.
Does someone have any idea how I can deal with that problem?
namespace system\core;
class Woocommerce{
public function __construct() {
add_action( 'wp_footer', array( __CLASS__, 'ace_product_page_ajax_add_to_cart_js' ) );
add_action( 'wc_ajax_ace_add_to_cart', array( __CLASS__, 'ace_ajax_add_to_cart_handler' ) );
add_action( 'wc_ajax_nopriv_ace_add_to_cart', array( __CLASS__, 'ace_ajax_add_to_cart_handler' ) );
add_action('init', array( __CLASS__, 'remove_add_cart_handler' ),10);
}
* JS for AJAX Add to Cart handling
*/
public static function ace_product_page_ajax_add_to_cart_js() {
?><script type="text/javascript" charset="UTF-8">
jQuery(function($) {
$('form.cart').on('submit', function(e) {
e.preventDefault();
var form = $(this);
form.block({ message: null, overlayCSS: { background: '#fff', opacity: 0.6, "border-radius": "30px", } });
var formData = new FormData(form[0]);
formData.append('add-to-cart', form.find('[name=add-to-cart]').val() );
// Ajax action.
$.ajax({
url: wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'ace_add_to_cart' ),
data: formData,
type: 'POST',
processData: false,
contentType: false,
complete: function( response ) {
response = response.responseJSON;
if ( ! response ) {
return;
}
if ( response.error && response.product_url ) {
window.location = response.product_url;
return;
}
// Redirect to cart option
if ( wc_add_to_cart_params.cart_redirect_after_add === 'yes' ) {
window.location = wc_add_to_cart_params.cart_url;
return;
}
var $thisbutton = form.find('.single_add_to_cart_button'); //
// var $thisbutton = null; // uncomment this if you don't want the 'View cart' button
// Trigger event so themes can refresh other areas.
$( document.body ).trigger( 'added_to_cart', [ response.fragments, response.cart_hash, $thisbutton ] );
// Remove existing notices
$( '.woocommerce-error, .woocommerce-message, .woocommerce-info' ).remove();
// Add new notices
form.closest('.product').before(response.fragments.notices_html)
form.unblock();
}
});
});
});
</script><?php
}
/**
* Add to cart handler.
*/
public static function ace_ajax_add_to_cart_handler() {
if (class_exists('WC_Form_Handler')){
WC_Form_Handler::add_to_cart_action();
WC_AJAX::get_refreshed_fragments();
}
}
public static function remove_add_cart_handler() {
remove_action( 'wp_loaded', array( 'WC_Form_Handler', 'add_to_cart_action' ), 20 );
add_filter( 'wc_add_to_cart_message_html', '__return_false' );
}
}
(edit)
Because the class gets loaded I think that this isn't the problem but could my autoloader be the problem?
spl_autoload_register(function ($class_name) {
$location = __DIR__ . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $class_name) . '.php';
if (file_exists($location)) {
try {
require_once $location;
return;
} catch (Exception $e) {
throw new Exception($e->getMessage());
}
}
});

Alright, I got it! You need to define the WC-Form_Handler class as global.
public static function ace_ajax_add_to_cart_handler() {
if (class_exists('WC_Form_Handler')){
\WC_Form_Handler::add_to_cart_action();
\WC_AJAX::get_refreshed_fragments();
}
}

Related

How can I get my Wordpress plugin to receive data and relay it in an ajax/php request to a remote server that requires authentication?

I have written a Wordpress plugin which places several buttons inside a metabox on the post-edit page. I'd go to example.com/wp-admin/post.php?post=number1&action=edit. I want my Wordpress hook to receive an AJAX call, and in turn makes a request to a remote server (one which requires authentication that the WP user shouldn't have to enter), then returns the result to the Wordpress user.
My code for the form with the data I want to send is two custom HTML elements' entered data. They are:
class MyFormData extends HTMLElement{
constructor() {
super();
}
connectedCallback(){
const li = document.createElement('li');
const newDat = document.createElement('input');
newDat.setAttribute('type','text');
newDat.setAttribute('name',`title box`);
newDat.setAttribute('placeholder',`Test Data`);
const deleteButton = document.createElement('button');
deleteButton.setAttribute('type','button');
deleteButton.innerHTML = "-";
deleteButton.addEventListener("click",function(){
li.parentNode.remove();
});
li.appendChild(newDat);
li.appendChild(deleteButton);
this.appendChild(li);
}
}
customElements.define('form-data',MyFormData);
and
class DurationMenu extends HTMLElement{
constructor(){
super();
}
connectedCallback(){
const amount = document.createElement('input');
amount.setAttribute('id','selectedTime');
amount.setAttribute('type','number');
amount.setAttribute('step',5)
amount.setAttribute('name','duration');
amount.setAttribute('min',5);
amount.setAttribute('max',60);
amount.setAttribute('value',15);
this.appendChild(amount)
}
}
customElements.define('duration-choice', DurationMenu);
Both of these custom elements show up in the metabox. I have a custom element for the submit button:
import ModelObject from './model/modelobject.js'
var theJson;
var data;
import {CO} from './Controller/controllerobject.js';
export var c = new ModelObject();
import {grabDataForSending} from './Controller/wordpressrelay.js';
export class SubmitAndCreate extends HTMLElement{
constructor(){
super();
}
connectedCallback(){
var data;
const submitbutton = document.createElement('button');
submitbutton.setAttribute('type','submit');
submitbutton.setAttribute('id','submitButton');
submitbutton.innerHTML = "Begin ";
submitbutton.addEventListener('click',this.myFunc.bind(this));
submitbutton.addEventListener('click',()=>{
document.getElementById('selectedTime').value = 15;
var dataset = document.getElementById("dataset").children;
for(var i = 0; i < dataset.length; i++){
document.getElementById("dataset").children[i].children[0].childNodes[0].value = '';
}
});
submitbutton.addEventListener('click',(event)=>{
CO.updateModelData();
event.preventDefault();
})
submitbutton.addEventListener('click',(event)=>{
grabExperimentForSending();
})
this.appendChild(submitbutton);
}
gatherData(){
//var enteredURL = document.getElementsByName('URL box')[0].value;
var dataAmount = document.getElementById('dataset').children.length;
var experTime = document.getElementById('selectedTime').value;
var dataObject = {
experimentDuration : experTime,
myData: {}
}
var individualDatum = [];
for (var i = 0; i < dataAmount; i++){
individualDatum[i] = {
dataset: document.getElementById("dataset").children[i].children[0].childNodes[0].value
}
}
dataObject.myData = individualDatum;
var dataObjectJSON = JSON.stringify(dataObject,null,2);
theJson = dataObjectJSON;
return theJson;
}
}
export {theJson, CO};
customElements.define('submit-button', SubmitAndCreate)
I want to grab the data one enters in both, and submit it to an external site that normally requires a password and username to login to from outside Wordpress. I want to submit it as JSon. How can I do this with Ajax and php?
My php so far is:
//for admin-ajax
add_action( 'admin_enqueue_scripts', 'my_enqueue' );
function my_enqueue($hook) {
if( 'index.php' != $hook ) {
return;
}
wp_enqueue_script( 'ajax-script', plugins_url( '/wp-content/plugins/my-plugin/js/Controller/ajaxdata.js', __FILE__ ), array('jquery') );
wp_localize_script( 'ajax-script', 'ajax_object',
array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'c' => c ) ); //c has the data that I need to send to the remote site's server
}
//relevant to admin-ajax
add_action( 'wp_ajax_CBAjax', 'CBAjax' );
//relevant to admin-ajax
function CBAjax() {
error_log(print_r($_REQUEST));
if ( isset($_REQUEST) ) {
$exper = $_REQUEST['experdata'];
error_log(print_r($exper,true));
echo "The exper is " . $exper;
}
$body = array(
'dur' => $exper['experimentDuration'],
'buckets'=> $experdata['myData']
);
$response = wp_remote_post( $url = "https://subdomain.example.com:8080/api/v1/data", array(
'body' => $body,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode( "login#example.com" . ':' . "password!" ),
),
) );
if($response){
error_log(print_r($response,true));
error_log("PING");
}
$respcode = wp_remote_retrieve_response_code($response);
error_log(print_r($respcode,true));
$ajax['remote_code'] = $response['response']['code'];
echo json_encode( $ajax );
error_log(print_r($ajax,true));
wp_die();
}
in the creation of the metabox, I have:
add_action( 'admin_enqueue_scripts', 'my_enqueue' );
add_action( 'wp_ajax_CBAjax', 'CBAjax' );
This is how I proxy the data from the button to the admin-ajax.php page:
import {c} from '../submitbutton.js';
function grabExperimentForSending(){
$.ajax({
url: "admin-ajax.php",
type: "POST",
data: c ,
success: function (response, statusCode) {
console.log(c.exps[0]);
console.log(`statusCode is ${statusCode}`);
console.log(`data is ${data}`);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(`jqXHR is ${jqXHR}, textStatus is ${textStatus}, errorThrown is ${errorThrown}`);
console.log(c.exps[0]);
}
});
}
and from there, it goes to ajaxdata.js
import {c} from './wordpressrelay.js';
function my_action_javascript(){
$('#submitButton').click( function(){
var data = { //model
'action': 'CBAjax',
'experdata': ajax_object.c
}
jQuery.post(ajax_object.ajax_url, data, function(response) {
console.log('Got this from the server: ' + response);
console.log(data.experdata);
console.log(`data[experdata] is ${data['experdata']}`);
});
});
}
export {my_action_javascript,c};
export {grabExperimentForSending,c};
I want to send that data, exp (a Json) to the remote site.
You will need to trigger an ajax request, for example when button click, to your ajax handler.
$('#my-submit-button').click(function(){
var data = {
'action': 'cbAjax',
'experdata': c.exps[0]
};
// from php generate your ajaxurl from admin_url( 'admin-ajax.php' );
jQuery.post(ajaxurl, data, function(response) {
// ajax response if any
});
});
Simply log something in your ajax handler to see if a request is sent after click the button. This is to verify your ajax handler is reachable.

wordpress Ajax call to php function doesn't work

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. Always get a result on admin-ajax.php 0
public function enqueue_scripts() {
wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/jquery-3.3.1-public.js', array( 'jquery' ), "3.3.1", false );
wp_enqueue_script( 'ajax-script', plugin_dir_url( __FILE__ ). 'js/wp-public.js', __FILE__, array() , $this->version, true);
wp_localize_script( 'ajax-script', 'ajax_object',
array(
'ajax_url' => admin_url( 'admin-ajax.php')
)
);
}
wp-public.js
$(document).ready(function()
{
$(".like-btn, .dislike-btn").click(function()
{
var id = this.id; // Getting Button id
var split_id = id.split("_");
var text = split_id[0];
var postid = split_id[1]; // postid
// Finding click type
var type = 0;
if(text == "like-btn") {
type = 1;
}else {
type = 0;
}
// AJAX Request
$.ajax(
{
url: ajax_object.ajax_url,
type: 'post',
data: {
'action': 'my_action',
postid: postid,
type: type
},
dataType: 'json',
success: function(data) {
$("#likes_"+postid).text(data.likes); // setting likes
$("#unlikes_"+postid).text(data.unlikes); // setting unlikes
$("#msg_"+postid).text(data.msg); // setting messages
if (data.likes || data.unlikes > "") {
if(type == 1) {
$("#like-btn_"+postid).css("color", "#0757fe");
$("#dislike-btn_"+postid).css("color", "#8e8e8e");
}
if(type == 0) {
$("#dislike-btn_"+postid).css("color", "#f1476e");
$("#like-btn_"+postid).css("color", "#8e8e8e");
}
}
}
}
);
}
);
}
);
included class
class Wp_Ahb_Content {
public function __construct( ) {
add_action('wp_ajax_my_action','my_action');
add_action('wp_ajax_nopriv_my_action','my_action');
}
function my_action() {
global $wpdb;
$whatever = $_POST['postid'] ;
echo "postid".$whatever;
}
Variables were sent successfully without reply
Screenshots
[ajax response][1]
[ajax_object][2]
[1]: https://i.stack.imgur.com/KlmJ7.jpg
[2]: https://i.stack.imgur.com/TO5i9.jpg
My_action function is not running
JUST Delete add_action from __construct () and add them to loader
add_action ('wp_ajax_my_action', 'my_action');
add_action ('wp_ajax_nopriv_my_action', 'my_action');
And I became as follows: ON private function define_public_hooks()
$this-> loader-> add_action ("wp_ajax_my_action", $ plugin_public, "ajax_object");
 
$this-> loader-> add_action ("wp_ajax_nopriv_my_action", $ plugin_public, "ajax_object");
It became operational
I just wanted to clarify, because I found a lot of questions
regarding the Wordpress Plugin Boilerplate

WooCommerce add a custom fee using ajax to cart totals on checkout page

I am trying make it when user changes the Shipping address select dropdown it dynamically add a fee to cart totals using ajax.I could able to to get the value but when select a another state it wont update the totals.
My ajax request:
jQuery(document).ready(function () {
jQuery('#shipping_state').change(function () {
var data = {
action: 'woocommerce_custom_fee',
security: wc_checkout_params.update_order_review_nonce,
add_order_fee: 'state',
post_data: jQuery('form.checkout').serialize()
};
jQuery.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: data,
success: function (code) {
var result = '';
result = jQuery.parseJSON(code);
if (result.result === 'success') {
jQuery('body').trigger('update_checkout');
}
},
dataType: 'html'
});
return false;
});
})
And in functions.php
add_action('woocommerce_cart_calculate_fees', 'woo_add_cart_fee');
function woo_add_cart_fee() {
global $woocommerce;
$destsuburb = $woocommerce->customer->get_shipping_state();
/*Then I use $destsuburb as a variable to API and get a shipping cost returning $shipping_cost*/
$woocommerce->cart->add_fee('Shipping and Handling:', $shipping_cost);
}
I am getting different Shipping cost according to the State,but its not changing the front end value through add_fee()
Finally I found a solution using a session variable to store the Ajax value and add_fee()
My ajax request:
jQuery(document).ready(function () {
jQuery('#State').click(function () {
if (jQuery('#ship-to-different-address-checkbox').is(':checked')) {
var state = jQuery('#shipping_state').val();
var post_code = jQuery('#shipping_postcode').val();
} else {
var state = jQuery('#billing_state').val();
var post_code = jQuery('#billing_postcode').val();
}
console.log(state + post_code);
var data = {
action: 'woocommerce_apply_state',
security: wc_checkout_params.apply_state_nonce,
state: state,
post_code: post_code
};
jQuery.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: data,
success: function (code) {
console.log(code);
// jQuery('.woocommerce-error, .woocommerce-message').remove();
if (code === '0') {
// $form.before(code);
jQuery('body').trigger('update_checkout');
}
},
dataType: 'html'
});
return false;
});
});
And in functions.php
wp_enqueue_script('neemo_state', get_template_directory_uri() . '/js/state_test.js', array('jquery'));
wp_localize_script('neemo_state', 'wc_checkout_params', array('ajaxurl' => admin_url('admin-ajax.php')));
add_action('wp_ajax_woocommerce_apply_state', 'calculate', 10);
add_action('wp_ajax_nopriv_woocommerce_apply_state', 'calculate', 10);
function calculate() {
if (isset($_POST['state'])) {
global $woocommerce;
$weight = WC()->cart->cart_contents_weight;
$state = $_POST['state'];
if ($state === "VIC") {
$val = 1;
} else {
$val = 2;
}
session_start();
$_SESSION['val'] = $val;
}
}
add_action('woocommerce_cart_calculate_fees', 'woo_add_cart_fee');
function woo_add_cart_fee() {
session_start();
$extracost = $_SESSION['val'];
WC()->cart->add_fee('Shipping & Handling:', $extracost);
}
I had to code for accepting donation just before checkout and adding that donation amount to the cart as a fee - and to provide flexibility for user to change the donation amount any number of times before proceeding to pay. I used the following code and it worked so well. I had Donation amount and a donateNow button - <input type="button" id="donateNowBtn" value="Donate Now!"
code in function.php
add_action( 'wp_footer', 'woocommerce_click_donate_button', 80 );
function woocommerce_click_donate_button() {
if (is_checkout()) {
?>
<script type="text/javascript">
jQuery( document ).ready(function( $ ) {
$('#donateNowBtn').click(function(){
jQuery('body').trigger('update_checkout');
});
});
</script>
<?php
}
}
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );
function woo_add_cart_fee( $cart ){
if ( ! $_POST || ( is_admin() && ! is_ajax() ) ) {
return;
}
if ( isset( $_POST['post_data'] ) ) {
parse_str( $_POST['post_data'], $post_data );
} else {
$post_data = $_POST; // fallback for final checkout (non-ajax)
}
if (isset($post_data['donation_amount'])) {
$donation_amount = $post_data['donation_amount'] ;
WC()->cart->add_fee( 'Donation Amount', $donation_amount );
}
}

Ajax call in wordpress not working for subscriber user in front site

i have simple wordpress form to add data in custom table in wordpress using Ajax
my jquery code(Ajax code )
jQuery.ajax(ajax_object.ajax_url, {
type: "POST",
data: data,
cache: false,
success: function (response) {
alert(response);
},
error: function (error) {
if (typeof console === "object") {
console.log(error);
}
},
complete: function () {
}
});
my php code to save data
if(!class_exists('bookly_appo_Ajax'))
{
class bookly_appo_Ajax
{
public function __construct()
{
add_action('init', array(&$this, 'init'));
}
public function init()
{
add_action( 'wp_enqueue_scripts', 'enqueue_ajax_booklyapp' );
function enqueue_ajax_booklyapp($hook) {
wp_enqueue_script('ajax-script-booklyapp', plugins_url( '/ajax.js?v='.rand(), __FILE__ ), array('jquery'));
wp_localize_script('ajax-script-booklyapp', 'ajax_object',
array(
'ajax_url' => admin_url('admin-ajax.php')
)
);
}
add_action('wp_ajax_add_category_bookly', 'add_category_bookly_callback');
add_action('wp_ajax_nopriv_add_category_bookly', 'add_category_bookly_callback');
function add_category_bookly_callback() {
$storeid=$_REQUEST['storeid'];
$rows = $wpdb->insert(
$table_category, array(
'store_id' => $storeid,
)
);
$lastid = $wpdb->insert_id;
}
}
}
}
my question is
when login with admin user my ajax work fine but when login with other
user(subscriber user) of my site it's give error "Opps!You do not
have sufficient perissions to access this page"
which type of
accessibility provide to subscriber to used admin-ajax.php file
My guess would be you're not defining the action for privileged and non-priviliged users. Do you have both
add_action( 'wp_ajax_ACTION', 'bookly_appo_Ajax' );
add_action( 'wp_ajax_nopriv_ACTION', 'bookly_appo_Ajax' );
In your php? wp_ajax_nopriv_ACTION is probably what you're missing.

code for split button in tinymce not working in wordpress 3.9 version?

I have code for php file as under
class TinyMCE_Buttons {
function __construct() {
add_action( 'init', array(&$this,'init') );
}
function init() {
if ( ! current_user_can('edit_posts') && ! current_user_can('edit_pages') )
return;
if ( get_user_option('rich_editing') == 'true' ) {
add_filter( 'mce_external_plugins', array(&$this, 'add_plugin') );
add_filter( 'mce_buttons', array(&$this,'register_button') );
}
}
function add_plugin($plugin_array) {
$plugin_array['shortcodes'] = SHORTCODES_PLUGIN_URL.'/js/tinymce.js';
return $plugin_array;
}
function register_button($buttons) {
array_push($buttons, "shortcodes_button");
return $buttons;
}
}
$shortcode = new TinyMCE_Buttons;
this is my .js file
(function() {
tinymce.create('tinymce.plugins.ShortcodeMce', {
init : function(ed, url){
tinymce.plugins.ShortcodeMce.theurl = url;
},
createControl : function(btn, e) {
if ( btn == "shortcodes_button" ) {
var a = this;
var btn = e.createSplitButton('symple_button', {
title: "Insert Shortcode",
image: tinymce.plugins.ShortcodeMce.theurl +"/shortcodes.png",
icons: false,
});
btn.onRenderMenu.add(function (c, b) {
b.add({title : 'Shortcodes', 'class' : 'mceMenuItemTitle'}).setDisabled(1);
// Columns
c = b.addMenu({title:"Columns"});
// add more menu and cloase file
Its not worked in tinymce4.x version also not gives any error.
any solution accepted.
The init and createControl callbacks are no longer called for the Plugin object.
Secondly, you need to call the addButton function on the Editor object.
A proposed solution could work like this (taking code from your post above):
(function() {
tinymce.create('tinymce.plugins.ShortcodeMce', function (editor, url) {
tinymce.plugins.ShortcodeMce.theurl = url;
var btn = editor.addButton('symple_button', {
type: "splitbutton",
title: "Insert Shortcode",
image: tinymce.plugins.ShortcodeMce.theurl +"/shortcodes.png",
icons: false,
menu: [
{ title: "Shortcodes", classes: "mceMenuItemTitle", disabled: true }
]
});
Here's the reference of the Button interface in TinyMCE API 4.x: http://www.tinymce.com/wiki.php/api4:class.tinymce.ui.Button

Categories