Hello I have been trying to create a woocommerce booking by code, I have managed to create a booking and add it to the user's cart. The problem is that I cannot set the booking's price. I have tried multiple solutions such as these:
add_filter('woocommerce_add_cart_item', 'tsc_booking_woocommerce_add_cart_item', 99, 1);
function tsc_booking_woocommerce_add_cart_item($cart_item)
{
try {
session_start();
if (!empty($cart_item['booking']) && isset($cart_item['booking']
['_cost']) && '' !== $cart_item['booking']['_cost']) {
$cart_item['data']->set_price(100);
$cart_item['custom_price'] = 100;
}
return $cart_item;
} catch (Exception $e) {
throw $e;
}
}
add_filter('woocommerce_get_cart_item_from_session', 'tsc_booking_woocommerce_get_cart_item_from_session', 99, 3);
function tsc_booking_woocommerce_get_cart_item_from_session($woo_data, $values, $key)
{
if (!isset($woo_data['custom_price']) || empty($woo_data['custom_price'])) {
return $woo_data;
}
$woo_data['data']->set_price($woo_data['custom_price']);
return $woo_data;
}
add_filter('woocommerce_bookings_calculated_booking_cost', 'tsc_booking_woocommerce_bookings_calculated_booking_cost', 99, 3);
function tsc_booking_woocommerce_bookings_calculated_booking_cost($booking_cost, $booking, $posted)
{
try {
return 100;
} catch (Exception $e) {
throw $e;
}
}
But they don't seem to work.
The documented solution would be to use the "woocommerce_before_calculate_totals" hook but it is not working.
I have debugged the code and all the function are being invoked and no there does not seem to be any errors.
add_action('woocommerce_before_calculate_totals', 'tsc_booking_woocommerce_before_calculate_totals', 1000, 1);
function tsc_booking_woocommerce_before_calculate_totals($cart)
{
if (is_admin() && !defined('DOING_AJAX'))
return;
if (did_action('woocommerce_before_calculate_totals') >= 2)
return;
foreach ($cart->get_cart() as $cart_item) {
$cart_item['data']->set_price(100);
}
}
I am pretty sure this worked for a normal WC_Product is there something else to do for a Booking product?
Thanks,
I got it...
Just in case anyone gets an headache like the one I just got.
The reason the price was reset to 0 in the cart was because of another plugin "Woocommerce Membership". The product had a discount price of 100€ for members and because I was using a testing price of 100€... the two would add up to 0. I guess the membership plugin has a lower priority when setting the product price.
Related
Here is a screenshot:
I want to catch a specific page template and show meta box according the specific page template. I have tried to with it:
$pageTemplate = get_post_meta($post->ID, '_wp_page_template', true);
but is not working.
Add the following code to functions.php:
add_filter('template_include', 'var_template_include', 1000);
function var_template_include($t) {
$GLOBALS['current_theme_template'] = basename($t);
return $t;
}
function get_current_template() {
if (isset($GLOBALS['current_theme_template'])) {
return $GLOBALS['current_theme_template'];
} else {
return false;
}
}
You'll then be able to do the following:
$pageTemplate = get_current_template();
I am trying to pre select a value within a select field in my contact from on the contact page from another page by passing a query string ?request=call-back. I am using Ninja Forms and the values that I have in my select field are: email-us, call-back
I have tried the following:
add_filter( 'ninja_forms_render_default_value', 'my_ninja_forms_pre_populate', 10, 3 );
function my_ninja_forms_pre_populate( $default_value, $field_type, $field_settings ){
if( 'request' == $field_settings[ 'key' ] ){
$default_value = $_GET['request'];
}
return $default_value;
}
I would like the select field to have call-back already selected.
I didnt need to use the filter that I was attempting. I changed the key value under administration within the ninja form builder and I made sure that none of the values were pre selected.
This drove me mad... but finally I've got a solution:
// register custom get parameter (to use it with get_query_var() for safety reasons)
function add_get_val() {
global $wp;
$wp->add_query_var('request');
}
add_action('init', 'add_get_val');
add_filter('ninja_forms_localize_field_listselect', function ($field) {
if (get_query_var('request')) {
$request = get_query_var('request');
$optionExists = FALSE;
// check if field exists
foreach ($field['settings']['options'] as $option) {
if ($option['value'] === $request) {
$optionExists = TRUE;
break;
}
}
if ($optionExists) {
foreach ($field['settings']['options'] as $key => $option) {
// deselect all fields
$field['settings']['options'][$key]['selected'] = 0;
// select parameter
if ($option['value'] === $request) {
$field['settings']['options'][$key]['selected'] = 1;
}
}
}
}
return $field;
});
I am trying to take the price in the filter woocommerce_update_order_review_fragments, but failing to understand where it resides
add_filter('woocommerce_update_order_review_fragments', 'price_bottom_checkout');
function price_bottom_checkout($arr) {
$price = ? // how to get it over here?
$price_txt = '<span class="total-pay">'.$price.'</span>';
$arr['.total-pay'] = $price;
return $arr;
}
Managed to find out how. Needed to see the session cart which is updated on every cart refresh via ajax.
add_filter('woocommerce_update_order_review_fragments', 'price_bottom_checkout');
function price_bottom_checkout($arr) {
global $woocommerce;
$the_total = '';
foreach ($woocommerce->cart->cart_contents as $cart_item) {
$the_total = $cart_item['line_total'];
break;
}
$price_txt = '<span class="total-pay">'.wc_price($the_total).'</span>';
$arr['.total-pay'] = $price_txt;
return $arr;
}
I would like to add a select field in admin/post-new.php.
This select field will be populated with JSON data (from a GET URL).
^ This point is solved. In your function.php:
function acf_load_colors_field_choices($field) {
$field['choices'] = [];
$choices = json_decode(file_get_contents('http://127.0.0.1/json/colors'), true);
if (is_array($choices)) {
foreach ($choices as $choice) {
$field['choices'][$choice] = $choice;
}
}
return $field;
}
add_filter('acf/load_field/name=colors', 'acf_load_colors_field_choices');
Once the page is ready to be published, I would like to catch POST data to send them to another URL.
How to catch those data?
In functions.php, to catch POST data:
function on_save_post_articles($post_id) {
var_dump($post_id);
var_dump($_POST);
exit;
}
add_action('save_post', 'on_save_post_articles');
Solved!
For all users I need to conditionally block access to nodes of type 'message'. The only way users should be able to view these message nodes is by successfully submitting a form.
I've started like this:
function mymodule_node_access($node, $op, $account) {
if ($op == 'view' && $node->type == 'message') {
return NODE_ACCESS_DENY;
}
}
However, I want to allow view access to individual nodes of this type upon successful submission of form:
function form_submit($form, &$form_state) {
// some logic here
$form_state['redirect'] = 'node/255';
}
so node 255 is of type 'message', and I want to 'lift' the NODE_ACCESS_DENY for this particular node and this user (+ in most cases this will be an anonymous user)
Any suggestions on different ways to accomplish this?
The only way you can do that is to set a value in the form submission handler that is then checked by hook_node_access(); you could use a Drupal variable, or a value saved in a database table.
You need to store the user ID of the user that accessed the form, and the node ID of every node for which such form has been submitted.
Supposing you use a Drupal variable, you could use code similar to the following one:
function mymodule_form_submit($form, &$form_state) {
global $user;
$message_nid = 255;
$values = variable_get('access_nid', array());
if (isset($values[$user->uid])) {
if (!isset($values[$user->uid][$message_nid])) {
$values[$user->uid][$message_nid] = $message_nid;
}
}
else {
$values[$user->uid] = array($message_nid => $message_nid);
}
variable_set('access_nid', $values);
$form_state['redirect'] = 'node/' . $message_nid;
}
function mymodule_node_access($node, $op, $account) {
$result = NODE_ACCESS_IGNORE;
if ($op == 'view' && $node->type == 'message') {
$values = variable_get('access_nid', array());
if (!empty($values[$account->uid]) {
if (isset($values[$account->uid][$node->nid])) {
unset($values[$account->uid][$node->nid]);
$result = NODE_ACCESS_ALLOW;
}
else {
$result = NODE_ACCESS_DENY;
}
}
else {
$result = NODE_ACCESS_DENY;
}
}
variable_set('access_nid', $values);
return $result;
}
To notice that this code allows a user to access a node only once; if the user would try to access the same node the second time, the user would get an "access denied" error. If that is not desired, then the second function should be re-written as follows:
function mymodule_node_access($node, $op, $account) {
if ($op == 'view' && $node->type == 'message') {
$values = variable_get('access_nid', array());
if (!empty($values[$account->uid]) {
if (isset($values[$account->uid][$node->nid])) {
return NODE_ACCESS_ALLOW;
}
return NODE_ACCESS_DENY;
}
}
else {
$result = NODE_ACCESS_DENY;
}
}
return NODE_ACCESS_IGNORE;
}
I used a Drupal variable to write simple code; using a Drupal variable, in this case, should be done if the users that can create nodes of that content type are few; if there are many users who can create those nodes, then using a database table is better.
Also when using Drupal variables, Drupal is using a database table; the difference is that the content of that database table is always loaded in memory. If you need to store many data, you should not use Drupal variables.
Modified solution to use $_SESSION as I'm working mostly with anonymous users:
function mymodule_form_submit($form, &$form_state) {
$message_nid = 255;
if (!isset($_SESSION['node_access'])) {
$_SESSION['node_access'] = array();
}
if (!isset($_SESSION['node_access']['nid'])) {
$_SESSION['node_access']['nid'] = $message_nid;
}
$form_state['redirect'] = 'node/' . $message_nid;
}
function mymodule_node_access($node, $op, $account) {
$node_access = NODE_ACCESS_IGNORE;
if ($op == 'view' && $node->type == 'message') {
if (isset($_SESSION['node_access'] && !empty($_SESSION['node_access'])) {
if ($node->nid == $_SESSION['node_access']['nid']) {
unset($_SESSION['node_access']['nid']);
$node_access = NODE_ACCESS_ALLOW ;
} else {
unset($_SESSION['node_access']['nid']);
$node_access = NODE_ACCESS_DENY;
}
} else {
$node_access = NODE_ACCESS_DENY;
}
}
return $node_access;
}