How do I get the value of a variable inside another - php

I'm trying to get the $pi1 and $pi2 variable values inside of the add_custom_price function, but nothing seems to be working.
I have looked at setting variables to be accessible from function classes but I'm not sure I understand how to access them correctly.
add_filter( 'gform_confirmation', array(gravity_pi,custom_confirmation), 10, 4 );
class gravity_pi {
public $pi1;
public $pi2;
public function custom_confirmation( $confirmation, $form, $entry, $ajax, $product_id, $pi1, $pi2 ) {
if( $form['id'] == '2' ) {
$post = get_post( $entry['post_id'] );
$this->pi1 = rgar( $entry, '20' );
$this->pi2 = rgar( $entry, '21' );
$exclude_list = array("pi24","pi64","pi65","pi66","pi67","pi68","pi69","pi70","pi71","pi72","pi73","pi74","pi75","pi76","pi77","pi78","pi79","pi80","pi81","pi82");
if(!in_array($this->pi1, $exclude_list) && !empty($this->pi1)){
$target_product_id = '86';
$pid1 = '86';
}else{
$pid1 = preg_replace("/[^0-9,.]/", "", $this->pi1 );
}
if(!in_array($pi2, $exclude_list) && !empty($this->pi2)){
$target_product_id = '87';
$pid2 = '87';
}else{
$pid2 = preg_replace("/[^0-9,.]/", "", $this->pi2);
}
$product_ids = ''.$pid1.','.$pid2.'';
$url = 'https://*****.com/cart/?add-to-cart='.$product_ids.'';
$confirmation = array( 'redirect' => $url );
}
return $confirmation;
}
public function add_custom_price( $cart_object, $entry,$form, $field, $input_id ) {
foreach ( $cart_object->cart_contents as $key => $value ) {
if( 86 == $value['data']->id ) {
$value['data']->set_price( $this->pi1 );
}
if( 87 == $value['data']->id ) {
$value['data']->set_price( $this->pi2 );
}
}
}
}
add_action( 'woocommerce_before_calculate_totals', array(gravity_pi,add_custom_price));

You need to use $this to get/set any property in the class.
// set pi1 property value
$this->pi1 = 10;
//print/get property value
echo $this->pi1;

When you're setting the class properties (pi1 & pi2) you need to reference them in the same way you access them. Ex.
<?php
...
$this->pi1 = rgar($entry, '20');
Change all references (except where you declare them) of $pid1 to $this->pid1. Do this for $pid2 too.
Check this video out - https://www.youtube.com/watch?v=4c4nP7GLL1c

Related

Dynamically added custom fields not displayed on WooCommerce email notifications

I have a different kind of scenario then the typical custom fields (I suppose). I am not getting custom values (fields) from user in the form rather I have an implementation which adds:
ColorName
Size
City
These are from a custom product flow which adds custom attributes to the cart, here is how I am doing that:
add_action('wp_ajax_wdm_add_user_custom_data_options', 'wdm_add_user_custom_data_options_callback');
add_action('wp_ajax_nopriv_wdm_add_user_custom_data_options', 'wdm_add_user_custom_data_options_callback');
function wdm_add_user_custom_data_options_callback()
{
// print_r($_POST);
$productIDM = $_POST['product_id'];
// case swith
switch ($productIDM) {
case "Ace Dura Silk":
$productID = 3254;
break;
case "Ace Matt Finish":
$productID = 3232;
break;
case "Ace Plastic Emulsion":
$productID = 3276;
break;
case "Ace Weather Defender":
$productID = 2991;
break;
case "Overall Plasticoat":
$productID = 3112;
break;
}
$colorname = $_POST['colorname'];
$cityname = $_POST['cityname'];
$size = $_POST['size'];
$price = $_POST['price'];
global $woocommerce;
$woocommerce->cart->add_to_cart( $productID, 1 );
// die();
// echo 'I am in...';
$result = array(
'status' => true
);
echo json_encode($result);
}
add_filter('woocommerce_add_cart_item_data','wdm_add_item_data',1,10);
function wdm_add_item_data($cart_item_data, $product_id) {
global $woocommerce;
$new_value = array();
$new_value['_custom_options'] = $_POST['custom_options'];
if(empty($cart_item_data)) {
return $new_value;
} else {
return array_merge($cart_item_data, $new_value);
}
}
add_filter('woocommerce_get_cart_item_from_session', 'wdm_get_cart_items_from_session', 1, 3 );
function wdm_get_cart_items_from_session($item,$values,$key) {
if (array_key_exists( '_custom_options', $values ) ) {
$item['_custom_options'] = $values['_custom_options'];
}
return $item;
}
add_filter('woocommerce_cart_item_name','add_usr_custom_session',1,3);
function add_usr_custom_session($product_name, $values, $cart_item_key ) {
$return_string = $product_name . "<div class='cart_subitems_custom'><br /><small>".$values['_custom_options']['colorname']."</small><br /><small>".$values['_custom_options']['cityname']."</small><br /><small>".$values['_custom_options']['size']."</small></div>" ; //. "<br />" . print_r($values['_custom_options']);
return $return_string;
}
add_action('woocommerce_add_order_item_meta','wdm_add_values_to_order_item_meta',1,2);
function wdm_add_values_to_order_item_meta($item_id, $values) {
global $woocommerce,$wpdb;
wc_add_order_item_meta($item_id,'_colorname',$values['_custom_options']['colorname']);
wc_add_order_item_meta($item_id,'_cityname',$values['_custom_options']['cityname']);
wc_add_order_item_meta($item_id,'_size',$values['_custom_options']['size']);
}
add_action( 'woocommerce_before_calculate_totals', 'update_custom_price', 1, 1 );
function update_custom_price( $cart_object ) {
foreach ( $cart_object->cart_contents as $cart_item_key => $value ) {
// Version 2.x
//$value['data']->price = $value['_custom_options']['custom_price'];
// Version 3.x / 4.x
if($value['_custom_options']['price'] == null){
echo"";
}else{
$value['data']->set_price($value['_custom_options']['price']);
}
}
}
I am getting these custom values almost everywhere except Email Notification.
Here is what normal product order edit shows:
Here is how I am getting the custom product in order edit page:
I have tried all the solution I can possibly find (filter & action hooks) but nothing works for me.
I have tried first answer from this:
add_action( 'woocommerce_checkout_create_order_line_item', 'custom_checkout_create_order_line_item', 20, 4 );
function custom_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
if( isset( $values['colorname'] ) )
$item->add_meta_data( __('DCM Shade'), $values['_colorname'] );
}
Also the common method I found everywhere:
function custom_woocommerce_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
// Get meta
$color = $order->get_meta( 'colorname', true );
// NOT empty
if( ! empty( $color ) ) {
$fields['colorname'] = array(
'label' => __( 'Shade' ),
'value' => $color,
);
}
// Get (other) meta
$shipping_email = $order->get_meta( '_cityname', true );
// NOT empty
if ( ! empty( $shipping_email ) ) {
$fields['_cityname'] = array(
'label' => __( 'City' ),
'value' => $shipping_email,
);
}
return $fields;
}
add_filter( 'woocommerce_email_order_meta_fields', 'custom_woocommerce_email_order_meta_fields', 10, 3 );
But I can't get the custom fields.
What am I doing wrong can please anyone please guide me.

Woocommerce custom add to cart with unique id

I am not that proficient at coding so please bear with me.
I have this custom add to cart code:
public static function add_to_cart( $params, $uid ) {
$data = self::get_calc_data($uid);
foreach ($data as $calc_id => $calc_data) {
$product_id = isset($calc_data['woo_info']['product_id']) ? $calc_data['woo_info']['product_id'] : null;
if ( $product_id && intval($product_id) === intval($params['woo_info']['product_id']) ) {
$meta = [
'product_id' => $product_id,
'item_name' => isset($calc_data['item_name']) ? $calc_data['item_name'] : '',
];
if(!empty($calc_data['descriptions']) && is_array($calc_data['descriptions'])) {
foreach ($calc_data['descriptions'] as $calc_item) {
if ( $calc_item['hidden'] === true ){
continue;
}
if ( strpos($calc_item['alias'], 'datePicker_field_id_') !== false ) {
$val = $calc_item['converted'] ? ' ('. $calc_item['converted'] . ') ' . $calc_item['value'] : $calc_item['value'];
}else{
$labels = isset($calc_item['extra']) ? $calc_item['extra']: '';
if ( (strpos($calc_item['alias'], 'radio_field_id_') !== false
|| strpos($calc_item['alias'], 'dropDown_field_id_') !== false)
&& key_exists('options', $calc_item) ) {
$labels = CCBWooCheckout::getLabels($calc_item['options']);
}
if ( strpos($calc_item['alias'], 'multi_range_field_id_') !== false
&& key_exists('options', $calc_item) && count($calc_item['options']) > 0 ) {
$labels = key_exists('label', $calc_item['options'][0]) ?
$calc_item['options'][0]['label']: '';
}
$val = isset($labels) ? $labels . ' ' . $calc_item['converted'] : $calc_item['converted'];
}
$meta['calc_data'][$calc_item['label']] = $val;
}
}
/** add totals data */
if( !empty($calc_data['ccb_total_and_label']) && is_array($calc_data['ccb_total_and_label']) ) {
$meta['ccb_total'] = $calc_data['ccb_total_and_label']['total'];
}
WC()->cart->add_to_cart($product_id, 1, '', array(), array('ccb_calculator' => $meta));
}
}
}
It adds simple item from a plugin into Woocommerce Cart. I am trying to add a unique ID for every added item so that I can add multiples of the same item and they would show as unique items in the cart.
I was trying to create the unique ID with
public static function add_custom_cart_item_data( $cart_item_data, $cart_item_key ) {
$cart_item_data[custom_data]['unique_key'] = md5( microtime().rand() );
return $cart_item_data;
}
and then use the $cart_item_data; changing the 'product_id' => $product_id, to 'product_id' => $cart_item_data, but sadly this doesn't seem to work. What am I doing wrong?
Really appreciate all your help!

WooCommerce Products attribute overwrites over older attributes when saved

I am trying to create product attribute on user input, but whenever i send the request the attribute gets created but it overrides the previous attributes linked to the product.
public static function create_variable_product(){
$variant_data = wp_clean(isset($_POST['data']) ? wp_unslash($_POST['data']) : '');
$product_id = wp_clean(isset($_POST['product_id']) ? wp_unslash($_POST['product_id']) : '');
$variant_data = json_decode($variant_data);
$product = wc_get_product($product_id);
if($product->has_child() == false){
$product = new WC_Product_Variable($product_id);
}
$attribute = self::create_product_attribute($product,$variant_data);
wp_send_json($attribute);
}
public static function create_product_attribute($product,$variant_data){
$id = [];
for($i=0; $i<count($variant_data); $i++){
$attribute = new WC_Product_Attribute();
$attribute->set_id(0);
foreach($variant_data[$i] as $key => $value){
if($key == 'attribute_name'){
$attribute->set_name($value);
}
if($key == 'options'){
$attribute->set_options($value);
}
}
$attribute->set_position( 1 );
$attribute->set_visible( 1 );
$attribute->set_variation( 1 );
$attribute->is_taxonomy(0);
$product->set_attributes(array($attribute));
array_push($id,$product->save());
}
return $id;
}
The data being passed to $_POST['data'] is:
[{
attribute_name: 'Color',
options: ['red','yellow','blue']
}]
There are some mistakes in your code. Try the following instead (untested):
public static function create_variable_product(){
$data = wp_clean(isset($_POST['data'] ? wp_unslash($_POST['data']) : '');
$product_id = wp_clean(isset($_POST['product_id']) ? wp_clean( wp_unslash($_POST['product_id']) ) : '');
$product = wc_get_product($product_id);
if( is_a($product, 'WC_Product') && ! $product->is_type('variable') && isset($_POST['data']) ){
$product = new WC_Product_Variable($product_id);
}
$attribute = self::create_product_attribute($product, $data);
$product->save()
wp_send_json($attribute);
}
public static function create_product_attribute( $product, $data ) {
$attributes = $product->get_attributes();
$attribute = new WC_Product_Attribute();
foreach($variant_data[$i] as $key => $values){
if( $key === 'attribute_name'){
$attribute->set_name($values);
} elseif( $key === 'options' ){
$attribute->set_options($values);
}
}
$attribute->set_position( 1 );
$attribute->set_visible( 1 );
$attribute->set_variation( 1 );
$attribute->is_taxonomy(0);
$attributes[$attribute->get_name()] = $attribute;
$product->set_attributes($attributes);
}
It should better work.

Using ACF number field as price for WooCommerce custom product type

I've seen online that you can add all Custom Post Types to a WooCommerce cart as long as the CPT has a price field. The only issue is that you have to tell WooCommerce what CPT field contains the price.
Afterwords you can easily create an add-to-cart url like this:
https://yourdomain.com/?add-to-cart=XXX (XXX being the Custom Post Type post ID)
Why is this handy?
I have an online menu (just to inform my guest what we serve) but because of Corona we have to close our doors so I want these dishes to be ordered online.
The code should be something like this but the CPT is not added to cart:
add_filter('woocommerce_get_price', 'yl_get_dish_price', 20,2);
function yl_get_dish_price($price,$post) {
if ($post->post->post_type === 'dish') {
$price = get_field('price', $post->ID);
}
return $price;
}
UPDATE
I took this answer from here https://stackoverflow.com/a/60320662/10291365
class YL_Dish_Product extends WC_Product {
protected $post_type = 'dish';
public function get_type() {
return 'dish';
}
public function __construct( $product = 0 ) {
$this->supports[] = 'ajax_add_to_cart';
parent::__construct( $product );
}
// maybe overwrite other functions from WC_Product
}
class YL_Data_Store_CPT extends WC_Product_Data_Store_CPT {
public function read( &$product ) { // this is required
$product->set_defaults();
$post_object = get_post( $product->get_id() );
if ( ! $product->get_id() || ! $post_object || 'dish' !== $post_object->post_type ) {
throw new Exception( __( 'Invalid product.', 'woocommerce' ) );
}
$product->set_props(
array(
'name' => $post_object->post_title,
'slug' => $post_object->post_name,
'date_created' => 0 < $post_object->post_date_gmt ? wc_string_to_timestamp( $post_object->post_date_gmt ) : null,
'date_modified' => 0 < $post_object->post_modified_gmt ? wc_string_to_timestamp( $post_object->post_modified_gmt ) : null,
'status' => $post_object->post_status,
'description' => $post_object->post_content,
'short_description' => $post_object->post_excerpt,
'parent_id' => $post_object->post_parent,
'menu_order' => $post_object->menu_order,
'reviews_allowed' => 'open' === $post_object->comment_status,
)
);
$this->read_attributes( $product );
$this->read_downloads( $product );
$this->read_visibility( $product );
$this->read_product_data( $product );
$this->read_extra_data( $product );
$product->set_object_read( true );
}
// maybe overwrite other functions from WC_Product_Data_Store_CPT
}
class YL_WC_Order_Item_Product extends WC_Order_Item_Product {
public function set_product_id( $value ) {
if ( $value > 0 && 'dish' !== get_post_type( absint( $value ) ) ) {
$this->error( 'order_item_product_invalid_product_id', __( 'Invalid product ID', 'woocommerce' ) );
}
$this->set_prop( 'product_id', absint( $value ) );
}
}
function YL_woocommerce_data_stores( $stores ) {
// the search is made for product-$post_type so note the required 'product-' in key name
$stores['product-dish'] = 'YL_Data_Store_CPT';
return $stores;
}
add_filter( 'woocommerce_data_stores', 'YL_woocommerce_data_stores' , 11, 1 );
function YL_woo_product_class( $class_name , $product_type , $product_id ) {
if ($product_type == 'dish')
$class_name = 'YL_Dish_Product';
return $class_name;
}
add_filter('woocommerce_product_class','YL_woo_product_class',25,3 );
function my_woocommerce_product_get_price( $price, $product ) {
if ($product->get_type() == 'dish' ) {
$price = 10; // or get price how ever you see fit
}
return $price;
}
add_filter('woocommerce_get_price','my_woocommerce_product_get_price',20,2);
add_filter('woocommerce_product_get_price', 'my_woocommerce_product_get_price', 10, 2 );
// required function for allowing posty_type to be added; maybe not the best but it works
function YL_woo_product_type($false,$product_id) {
if ($false === false) { // don't know why, but this is how woo does it
global $post;
// maybe redo it someday?!
if (is_object($post) && !empty($post)) { // post is set
if ($post->post_type == 'dish' && $post->ID == $product_id)
return 'dish';
else {
$product = get_post( $product_id );
if (is_object($product) && !is_wp_error($product)) { // post not set but it's a dish
if ($product->post_type == 'dish')
return 'dish';
} // end if
}
} else if(wp_doing_ajax()) { // has post set (usefull when adding using ajax)
$product_post = get_post( $product_id );
if ($product_post->post_type == 'dish')
return 'dish';
} else {
$product = get_post( $product_id );
if (is_object($product) && !is_wp_error($product)) { // post not set but it's a dish
if ($product->post_type == 'dish')
return 'dish';
} // end if
} // end if // end if
} // end if
return false;
}
add_filter('woocommerce_product_type_query','YL_woo_product_type',12,2 );
function YL_woocommerce_checkout_create_order_line_item_object($item, $cart_item_key, $values, $order) {
$product = $values['data'];
if ($product->get_type() == 'dish') {
return new YL_WC_Order_Item_Product();
} // end if
return $item ;
}
add_filter( 'woocommerce_checkout_create_order_line_item_object', 'YL_woocommerce_checkout_create_order_line_item_object', 20, 4 );
function cod_woocommerce_checkout_create_order_line_item($item,$cart_item_key,$values,$order) {
if ($values['data']->get_type() == 'dish') {
$item->update_meta_data( '_dish', 'yes' ); // add a way to recognize custom post type in ordered items
return;
} // end if
}
add_action( 'woocommerce_checkout_create_order_line_item', 'cod_woocommerce_checkout_create_order_line_item', 20, 4 );
function YL_woocommerce_get_order_item_classname($classname, $item_type, $id) {
global $wpdb;
$is_IA = $wpdb->get_var("SELECT meta_value FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id = {$id} AND meta_key = '_dish'");
if ('yes' === $is_IA) { // load the new class if the item is our custom post
$classname = 'YL_WC_Order_Item_Product';
} // end if
return $classname;
}
add_filter( 'woocommerce_get_order_item_classname', 'YL_woocommerce_get_order_item_classname', 20, 3 );
The above code does add a CPT to your cart (GREAT!!) but the price is always set to 10,00
So the code below doesn't give the right price :(
add_filter('woocommerce_get_price', 'yl_get_dish_price', 20,2);
function yl_get_dish_price($price,$post) {
if ($post->post->post_type === 'dish') {
$price = get_field('price', $post->ID);
}
return $price;
}
Any idea?
Since WooCommerce 3, the hook woocommerce_get_price is obsolete and deprecated… It's replaced by the following composite hook:
add_filter( 'woocommerce_product_get_price', 'yl_get_dish_price', 20, 2 );
add_filter( 'woocommerce_product_get_regular_price', 'yl_get_dish_price', 20, 2 );
function yl_get_dish_price( $price, $product ) {
if ( $product->is_type('dish') ) {
$price = get_field( 'price', $product->get_id() );
}
return $price;
}
It could and should better work.

Wordpress sortable column by IP address

I have been able to add a sortable column to my Wordpress userpage that displays the users last know IP address.
The problem I seem to be having is getting the column to sort by the IP's numbers and not the usernames alphabetically.
I feel im missing something simple and could use another set of eyes.
<?php
class Register_IP_Multisite {
public function __construct() {
add_action( 'init', array( &$this, 'init' ) );
}
public function init() {
add_action( 'user_register', array( $this,'log_ip') );
add_action( 'edit_user_profile', array( $this,'edit_user_profile') );
add_action( 'manage_users_custom_column', array( $this,'columns'), 10, 3);
add_filter( 'manage_users_sortable_columns', array( $this ,'users_sortable_columns_wsp') );
add_filter( 'request', array( $this ,'users_orderby_column_wsp') );
add_filter( 'plugin_row_meta', array( $this ,'donate_link'), 10, 2 );
if ( is_multisite() ) {
add_filter('wpmu_users_columns', array( $this ,'column_header_signup_ip'));
} else {
add_filter('manage_users_columns', array( $this ,'column_header_signup_ip'));
}
}
public function log_ip($user_id){
$ip = $_SERVER['REMOTE_ADDR']; //Get the IP of the person registering
update_user_meta($user_id, 'signup_ip', $ip); //Add user metadata to the usermeta table
}
public function edit_user_profile() {
$user_id = (int) $_GET['user_id'];
?>
<h3><?php _e('Signup IP Address', 'register-ip-mutisite'); ?></h3>
<p style="text-indent:15px;"><?php
$ip_address = get_user_meta($user_id, 'signup_ip', true);
echo $ip_address;
?></p>
<?php
}
public function column_header_signup_ip($column_headers) {
$column_headers['signup_ip'] = __('IP Address', 'register-ip-multisite');
return $column_headers;
}
public function users_sortable_columns_wsp($column_headers) {
$customwsp = array(
// meta column id => sortby value used in query
'signup_ip' => 'user_ip_address',
);
return wp_parse_args($customwsp, $column_headers);
}
public function users_orderby_column_wsp( $varswsp ) {
if ( isset( $varswsp['orderby'] ) && 'signup_ip' == $varswsp['orderby'] ) {
$varswsp = array_merge( $varswsp, array(
'meta_key' => 'signup_ip',
'orderby' => 'meta_value'
) );
}
return $varswsp;
}
public function columns($value, $column_name, $user_id) {
global $modewsp;
$modewsp = empty( $_REQUEST['mode'] ) ? 'list' : $_REQUEST['mode'];
if ( $column_name == 'signup_ip' ) {
$ip = get_user_meta($user_id, 'signup_ip', true);
if ($ip != ""){
$theip = $ip;
if ( has_filter('ripm_show_ip') ) {
$theip = apply_filters('ripm_show_ip', $theip);
}
return $theip;
} else {
$theip = '<em>'.__('None Recorded', 'register-ip-multisite').'</em>';
return $theip;
}
}
$user_ip_address = strtotime(get_date_from_gmt($user->signup_ip));
return $value;
}
}
new Register_IP_Multisite();

Categories