How to get post id in Ajax callback in Wordpress - javascript

I use the Add to cart Ajax callback, but I miss how I can get the post Id there.
MY GOAL: I want to use the add_filter only on a specific page.
PHP in functions.php
add_filter( 'woocommerce_add_cart_item_data', 'iconic_add_engraving_text_to_cart_item' , 10, 3 );
function iconic_add_engraving_text_to_cart_item( $cart_item_data, $product_id, $variation_id ) {
global $post;
if ( $post->ID === 54214 ) {
$engraving_text = 'test';
$cart_item_data['iconic-engraving'] = $engraving_text;
return $cart_item_data;
} else {
return $cart_item_data;
}
}
This is NOT WORKING because $post is NULL (because of the Ajax woocommerce_add_cart_item_data hook).
So I tried the following code in the JS to get the post id in JS (working).
function get_current_page_id() {
var page_body = $('body.page');
var id = 0;
if(page_body) {
var classList = page_body.attr('class').split(/\s+/);
$.each(classList, function(index, item) {
if (item.indexOf('page-id') >= 0) {
var item_arr = item.split('-');
id = item_arr[item_arr.length -1];
return false;
}
});
}
return id;
}
Now, how can I handover the id to my Ajax Callback to work with it?
Any advice?
EDIT:
I forgot to tell that I am planning to use the add to cart action on other pages but not a single product page.
For that, I am using a third party plugin which gives me the button for my desired product, so I am not using default $product or $post Object (like in single product pages).

I have finally found a solution for this "simple" problem. I can work with a session:
add_action( 'wp_head', 'set_session' );
add_filter( 'woocommerce_add_cart_item_data', 'iconic_add_engraving_text_to_cart_item' , 10, 3 );
function set_session() {
session_start();
// add post id
global $post;
$post_id = $post->ID;
$_SESSION['post_id'] = $post_id;
}
function iconic_add_engraving_text_to_cart_item( $cart_item_data, $product_id, $variation_id ) {
session_start();
if( $_SESSION['post_id'] == 54214 ) {
$engraving_text = 'test';
$cart_item_data['iconic-engraving'] = $engraving_text;
return $cart_item_data;
} else {
return $cart_item_data;
}
}

Related

Trigger Js function onclick

I am using wordpress and have a function like this, how to redirect to the corresponding url only happens onclick, for now the "en" language page is automatically redirecting after the page load, but the "zh-hant" redirecting after click, anyone can help me to check the code?
Thanks.
add_action( 'wp_head', 'redirect_after_booking' );
function redirect_after_booking() {
if ( in_category('teachers') ) {
if(ICL_LANGUAGE_CODE=='en'){
?>
<script>
window.beforeConfirmedBooking = function() {
window.location.href = "https://aaa.com";
};
</script>
<?php
}
if(ICL_LANGUAGE_CODE=='zh-hant'){
?>
<script>
window.beforeConfirmedBooking = function() {
window.location.href = "https://aaa.com/zh-hant";
};
</script>
<?php
}
}
}
You should be doing all of it in one function itself
add_action( 'wp_head', 'redirect_after_booking' );
function redirect_after_booking() {
if ( in_category('teachers') ) {
$url_endpoint = '';
if(ICL_LANGUAGE_CODE=='en'){
} else if (ICL_LANGUAGE_CODE=='zh-hans') {
$url_endpoint = '/zh-hans';
}else if (ICL_LANGUAGE_CODE=='zh-hant') {
$url_endpoint = '/zh-hant';
}
?>
<script>
window.beforeConfirmedBooking = function() {
window.location.href = "https://aaa.com<?php echo $url_endpoint; ?>";
};
const btn = document.querySelector('.el-button .el-button--primary .redirect-link');
btn.addEventListener('click', beforeConfirmedBooking);
</script>
<?php
}
}
You can also do it just using php and no js at all
add_action( 'wp_head', 'redirect_after_booking' );
function redirect_after_booking() {
if ( in_category('teachers') ) {
$url_endpoint = '';
if(ICL_LANGUAGE_CODE=='en'){
} else if (ICL_LANGUAGE_CODE=='zh-hans') {
$url_endpoint = '/zh-hans';
}else if (ICL_LANGUAGE_CODE=='zh-hant') {
$url_endpoint = '/zh-hant';
}
}
}
// The following will redirect you to where ever you want
header('Location: https://aaa.com' . $url_endpoint);
/* Make sure that code below does not get executed when we redirect. */
One method would be to do the below using a switch statement.
This allows for easy growth and in the event you end up with a LOT of languages easy to just repeat and falls back to the site URL in the event there isn't a match.
add_action( 'wp_head', 'redirect_after_booking' );
function redirect_after_booking() {
if ( in_category('teachers') ) {
switch (CL_LANGUAGE_CODE) {
case 'zh-hant':
wp_redirect( trailingslashit( get_site_url() ) . CL_LANGUAGE_CODE );
exit;
break;
default:
wp_redirect( get_site_url() );
exit;
}
}
}

Wordpress show Edit and Delete buttons only if post's author

My wordpress site uses post submissions (actually, CPTs) from site members. When displaying the CPT post, I'd like buttons to appear for Edit and Delete when the author is viewing the post, and not appear if any other member views the post.
I've researched code and plugins, but all seem to only apply to the author role, not the specific author themselves.
Is there a way to use PHP function/shortcode, Javascript, or some combination of the two, to add this functionality?
Here is the code for the disable edit and delete button. I've tested the code and it's working fine from my side.
FOR THE EDIT BUTTON LINK ONLY
function prefix_remove_get_edit_post_link( $link ) {
global $post;
$current_user = get_current_user_id();
$author_id = get_post_field ('post_author', $post_id);
if($author_id == $current_user) {
return $link;
}
return null;
}
add_filter('get_edit_post_link', 'prefix_remove_get_edit_post_link');
FOR THE DELETE BUTTON LINK ONLY
function prefix_remove_get_delete_post_link( $link ) {
global $post;
$current_user = get_current_user_id();
$author_id = get_post_field ('post_author', $post_id);
if($author_id == $current_user) {
return $link;
}
return null;
}
add_filter('get_delete_post_link', 'prefix_remove_get_delete_post_link');
FOR THE HIDE BUTTONS EDIT AND DELETE
add_filter( 'post_row_actions', 'remove_row_actions', 10, 1 );
function remove_row_actions( $actions )
{
global $post;
$current_user = get_current_user_id();
$author_id = get_post_field ('post_author', $post_id);
if($author_id != $current_user) {
if( get_post_type() === 'post' ){
unset( $actions['edit'] );
unset( $actions['trash'] );
unset( $actions['inline hide-if-no-js'] );
}
}
return $actions;
}

PHP Function that executes a JS - Woocommerce

I have a JS function that I am trying to execute via my functions.php from within my child theme. This is my first time utilizing PHP so I apologize if my code is poor.
My goal is to try to change the page_title to what has been selected in a dropdown filter. After this is working I then plan to add the category_name to the end of the .innerHTML. This will only occur in the event that a drop down has been selected. In the event it hasn't been then just the category will display via how woocommerce handles it natively.
var machineEl = document.getElementsByClassName('woof_select_pa_machine').firstChild;
var machineValue = machineEl.value;
machineEl.addEventListener('change', function dynamic_page_title() {
if (machineValue != 'Product Machine') {
document.getElementsByClassName('woocommerce-products-header__title').innerHTML = machineValue;
}
});
This is the first script I try to execute in the function.php.
<?php
echo '<script type="text/javascript">',
'dynamic_page_title_js();',
'</script>';
?>
Alternatively I was trying to use the following to accomplish the same thing but with the intention to limiting to only certain pages. Though not sure if I will need this in the end. I used this set of code per another thread I found.
<?php
add_action ( 'wp_enqueue_scripts', 'dynamic_page_title_php');
function dynamic_page_title_php() {
//$wp_query->get_queried_object()->cat_name;
global $page_title;
if( is_page() || is_single() )
{
switch($page_title->title_name ) // post_name is the post slug which is more consistent for matching to here
{
case 'shop':
wp_enqueue_script('shop', get_template_directory_uri() . '/js/dynamic_page_title_js.js', array('jquery'), '', false);
break;
}
}
}
?>
Here is the html of the class I am trying to overwrite.
<h1 class="woocommerce-products-header__title page-title">Sample Page</h1>
I decided to take this a different route and break the issue apart. I used a js function to update page_title on filter select. Then I used code provided in another thread (Woocommerce: How to show Product Attribute name on title when in a category page and "filtering" products via '?pa_attribute=' on address bar) to handle the attribute portion from within my function.php file. The php function handles the page on load replacing shop with the attribute name, in this case the machine type. The js updates this attribute and adds the category on filter select.
There is still some work to be done on the functions.php to add the category name to the page_title when the user navigates to a category via the nav bar. I have posted a new question on how to resolve this last part (Woocommerce: How to show Product Attribute name and Category name on title) but by utilizing both these independently it is more or less accomplishing what I intended.
Also, the JS I am currently executing within the woof-woocommerece-product-filter plugin. It is written within the JS after Ajax is done section. But I do plan to move this in to its own file and call the function only from a organizational aspect.
PHP
add_filter( 'woocommerce_page_title', 'custom_woocommerce_page_title', 15, 2 );
function custom_woocommerce_page_title( $page_title ) {
if ( is_archive() ) {
$exists_attr = false;
foreach ( $_GET as $index => $value ) {
if ( substr( $index, 0, 3 ) === 'pa_' ) {
$attr_id = wc_attribute_taxonomy_id_by_name( $index );
if ( $attr_id === 0 && $cat_id ) {
continue;
}
if ( ! $exists_attr /* && ! $exists_cat */) {
$exists_attr = true;
$page_title .= ' ';
} else {
$page_title .= ' ';
}
$term = get_term_by( 'slug', esc_html( $value ), $index );
$page_title = $term->name;
}
}
}
return $page_title;
}
JS
(function() {
var machineEl = document.getElementsByClassName('woof_select woof_select_pa_machine')[0];
var processEl = document.getElementsByClassName('woof_select woof_select_pa_processing')[0];
var optionMachine = machineEl.querySelector("option[selected='selected']");
var optionProcess = processEl.querySelector("option[selected='selected']");
var machineValue = optionMachine.innerHTML;
var processValue = optionProcess.innerHTML;
var result = document.getElementsByClassName('woocommerce-products-header__title page-title')[0];
if (machineValue != 'Product Machine' && processValue != 'Product Processing') {
result.innerHTML = machineValue + " " + processValue;
}
else if (machineValue != 'Product Machine') {
result.innerHTML = machineValue;
}
else if (processValue != 'Product Processing') {
result.innerHTML = processValue;
}
})()
Once I have the category posting the to page_title I will update this answer.

(populate dropdown in contact form 7 getting this error - Warning: array_keys() expects parameter 1 to be array, null given in

Ok where to start, I will try and explain as much as I can.
I am using wordpress with contact form 7 and I am trying to populate 3 dropdown items on the contact form, I found some code that I was able to use with no problem but the problem with this was that it was getting the information from a excel file, the file is now to big and will not run on my website anymore so I would like to get the information from my database now.
I have made a table in my database "vehicle_information" with 3 columns "vehicle_type", "vehicle_make", vehicle_model"
I have code in my functions.php and code in my footer to be able to use the cf7 shortcodes.
Code from funtions.php
function ajax_cf7_populate_values() {
//MySQLi information
$db_host = '***';
$db_username = '***';
$db_password = '***';
$vehicles_makes_models = array();
//connect to mysqli database (Host/Username/Password)
$connection = mysqli_connect($db_host, $db_username, $db_password) or die('Error ' . mysqli_error());
//select MySQLi dabatase table
$vehicles_makes_models = mysqli_select_db($connection, 'vehicle_information') or die('Error ' . mysqli_error());
$sql = mysqli_query($connection, 'SELECT * FROM vehicle_type');
while($row = mysqli_fetch_array($sql)) {
$vehicles_makes_models[$row[0]][$row[1]][] = $row[2]; }
}
// setup the initial array that will be returned to the the client side script as a JSON object.
$return_array = array(
'vehicles' => array_keys($vehicles_makes_models),
'makes' => array(),
'models' => array(),
'current_vehicle' => false,
'current_make' => false
);
// collect the posted values from the submitted form
$vehicle = key_exists('vehicle', $_POST) ? $_POST['vehicle'] : false;
$make = key_exists('make', $_POST) ? $_POST['make'] : false;
$model = key_exists('model', $_POST) ? $_POST['model'] : false;
// populate the $return_array with the necessary values
if ($vehicle) {
$return_array['current_vehicle'] = $vehicle;
$return_array['makes'] = array_keys($vehicles_makes_models[$vehicle]);
if ($make) {
$return_array['current_make'] = $make;
$return_array['models'] = $vehicles_makes_models[$vehicle][$make];
if ($model) {
$return_array['current_model'] = $model;
}
}
}
// encode the $return_array as a JSON object and echo it
echo json_encode($return_array);
wp_die();
// These action hooks are needed to tell WordPress that the cf7_populate_values() function needs to be called
// if a script is POSTing the action : 'cf7_populate_values'
add_action( 'wp_ajax_cf7_populate_values', 'ajax_cf7_populate_values' );
add_action( 'wp_ajax_nopriv_cf7_populate_values', 'ajax_cf7_populate_values' );
Code from my footer
<script>
(function($) {
// create references to the 3 dropdown fields for later use.
var $vehicles_dd = $('[name="vehicles"]');
var $makes_dd = $('[name="makes"]');
var $models_dd = $('[name="models"]');
// run the populate_fields function, and additionally run it every time a value changes
populate_fields();
$('select').change(function() {
populate_fields();
});
function populate_fields() {
var data = {
// action needs to match the action hook part after wp_ajax_nopriv_ and wp_ajax_ in the server side script.
'action' : 'cf7_populate_values',
// pass all the currently selected values to the server side script.
'vehicle' : $vehicles_dd.val(),
'make' : $makes_dd.val(),
'model' : $models_dd.val()
};
// call the server side script, and on completion, update all dropdown lists with the received values.
$.post('<?php echo admin_url( 'admin-ajax.php' ) ?>', data, function(response) {
all_values = response;
$vehicles_dd.html('').append($('<option>').text(' -- choose vehicle -- '));
$makes_dd.html('').append($('<option>').text(' -- choose make -- '));
$models_dd.html('').append($('<option>').text(' -- choose model -- '));
$.each(all_values.vehicles, function() {
$option = $("<option>").text(this).val(this);
if (all_values.current_vehicle == this) {
$option.attr('selected','selected');
}
$vehicles_dd.append($option);
});
$.each(all_values.makes, function() {
$option = $("<option>").text(this).val(this);
if (all_values.current_make == this) {
$option.attr('selected','selected');
}
$makes_dd.append($option);
});
$.each(all_values.models, function() {
$option = $("<option>").text(this).val(this);
if (all_values.current_model == this) {
$option.attr('selected','selected');
}
$models_dd.append($option);
});
},'json');
}
})( jQuery );
The problem is I am still learning and this is the first time I have had to use this funtion.
and I am getting an error on my website
Warning: array_keys() expects parameter 1 to be array, null given in /customers/4/0/0/motobid.co.uk/httpd.www/wp-content/themes/storevilla-child/functions.php on line 38 {"vehicles":null,"makes":[],"models":[],"current_vehicle":false,"current_make":false}
any help would be very greatful.
Just like to say code was supplied by BDMW.
Where you use the method array_keys(), instead of:
$return_array['makes'] = array_keys($vehicles_makes_models[$vehicle]);
Try this:
$return_array['makes'] = ! empty($vehicles_makes_models[$vehicle]) ? array_keys($vehicles_makes_models[$vehicle]) : [];
From what I've read, the array_keys() has been an issue depending on php versions. Hope this helps!

Create a redirect based on applied coupon in WooCommerce order received page

Here is the flow:
Customer adds product to cart.
Customer adds coupon "smile" at checkout.
When customer places order the function will run before the Order
Details page loads. Function will check for "smile" coupon and if it
has been applied it redirects to a new page where they will be
offered additional products for free. If not, then it continues on
as normal.
I have been referencing two solutions I found through a Google search similar to parts of my problem. Individually I get them to work but together I cannot seem to get them to work correctly.
Here is my code:
add_action( 'woocommerce_thankyou' , 'sq_checkout_custom_redirect' );
function sq_checkout_custom_redirect($order_id) {
global $woocommerce;
$order = new WC_Order( $order_id );
$coupon_id = 'smile';
$applied_coupon = $woocommerce->cart->applied_coupons;
$url = 'https://site.mysite.org/score-you-win/';
if( $applied_coupon[0] === $coupon_id ) {
echo "<script type=\"text/javascript\">window.location.replace('".$url."');</script>";
} else {
echo '<h3 style="font-size:200px; z-index:30000; color:#000 !important;">Coupon not applied</h3>';
}
}
No matter what coupon I apply I get the message "Coupon not applied." and no redirect happens.
The two solutions that I am referencing are:
Find applied coupon_id in cart
Redirect with JS
This code runs successfully:
add_action( 'woocommerce_thankyou', function ($order_id){
$order = new WC_Order( $order_id );
$coupon_id = "smile";
$url = 'https://site.mysite.org/score-you-win/';
if ($order->status != 'failed') {
echo "<script type=\"text/javascript\">window.location.replace('".$url."');</script>";
}
});
And this runs successfully:
function product_checkout_custom_content() {
global $woocommerce;
$coupon_id = 'smile';
$applied_coupon = $woocommerce->cart->applied_coupons;
if( $applied_coupon[0] === $coupon_id ) {
echo '<span style="font-size:200px; z-index:30000; color:#red !important;">We are happy you bought this product =)</span> ';
} else {
echo '<h3 style="font-size:200px; z-index:30000; color:#000 !important;">Coupon not applied</h3>';
}
}
add_action( 'woocommerce_thankyou' , 'sq_checkout_custom_redirect' );
Updated: In woocommerce "Order Received" page (thankyou), there is no more WC_Cart object available. Instead you need to target the WC_Order object this way:
add_action( 'woocommerce_thankyou', 'thankyou_custom_redirect', 20, 1 );
function thankyou_custom_redirect( $order_id ) {
// Your settings below:
$coupon_id = 'smile';
$url = 'https://site.mysite.org/score-you-win/';
// Get an instance of the WC_order object
$order = wc_get_order($order_id);
$found = false;
// Loop through the order coupon items
foreach( $order->get_items('coupon') as $coupon_item ){
if( $coupon_item->get_code() == strtolower($coupon_id) ){
$found = true; // Coupon is found
break; // We stop the loop
}
}
if( $found )
echo "<script type=\"text/javascript\">window.location.replace('".$url."');</script>";
else
echo '<h3 style="font-size:200px; z-index:30000; color:#000 !important;">Coupon not applied</h3>';
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Categories