Run SQL prepared statement in custom PHP function - php

I wrote the following function to create a woocommerce product with PHP in wordpress and delete it if it already exists upon add/update custom post type.
Everything is working fine if i pressed the "update" button twice in the post page, as if i should run the code twice. Can anyone help me out.
function create_tour_product($post, $ID){
if(get_post_type( $post ) == 'tour'){
global $wpdb;
$tourprice =get_post_meta( get_the_ID(), 'tour_price', true );
$tourdiscountprice =get_post_meta( get_the_ID(), 'tour_discount_price', true );
$tourname =get_the_title();
$postimgid =get_the_ID();
$sqlstatement = $wpdb->prepare("DELETE p FROM $wpdb->posts p join $wpdb->postmeta pm on p.ID = pm.post_id WHERE p.post_type = %s and p.post_title= %s",'product',$tourname);
$wpdb->query($sqlstatement);
$new_product = array(
'post_author' => $user_id,
'post_content' => '',
'post_status' => "publish",
'post_title' => $tourname,
'post_parent' => '',
'post_type' => "product",
);
$new_product = wp_insert_post( $new_product, $wp_error );
if($new_product){
$attach_id = get_post_thumbnail_id($postimgid);
set_post_thumbnail($new_product, $attach_id);
$tour_id = $new_product;
}
wp_set_object_terms( $new_product, 'Tours', 'product_cat' );
wp_set_object_terms( $new_product, 'simple', 'product_type');
update_post_meta( $new_product, '_visibility', 'visible' );
update_post_meta( $new_product, '_stock_status', 'instock');
update_post_meta( $new_product, 'total_sales', '0');
update_post_meta( $new_product, '_downloadable', 'no');
update_post_meta( $new_product, '_virtual', 'yes');
update_post_meta( $new_product, '_regular_price', $tourprice );
update_post_meta( $new_product, '_sale_price', $tourdiscountprice );
update_post_meta( $new_product, '_purchase_note', "" );
update_post_meta( $new_product, '_featured', "no" );
update_post_meta( $new_product, '_sku', "");
update_post_meta( $new_product, '_product_attributes', array());
update_post_meta( $new_product, '_price', $tourprice );
update_post_meta( $new_product, '_manage_stock', "no" );
update_post_meta( $new_product, '_backorders', "no" );
}
}
add_action('edit_post', 'create_tour_product',10,2);

I ended up with adding another action (Edit & Save) to update the product.
add_action('edit_post', 'create_tour_product',10,2);
add_action('save_post', 'create_tour_product',10,2);

Related

Functions not running on plugin_activation hook

I am trying to create 8 Woo products programmatically via wp_insert_post only the first time the plugin is activated. Functions insert_SB1() to insert_SB8() contain the individual product data. Function insert_SB1() has been shown as an example. Adding just one of these products by something only like this without any activation hook / option checking does the job:
$my_post = array(
'post_title' => 'SB: 0 - 60',
'post_status' => 'publish',
'post_type' => 'product'
);
$post_id = wp_insert_post( $my_post );
wp_set_object_terms( $post_id, 'Skates', 'product_cat' );
wp_set_object_terms( $post_id, 'simple', 'product_type');
update_post_meta( $post_id, '_stock_status', 'instock');
But trying to add all 8 products on activation hook and after checking if an option exist is not working. I have used the admin_notices hook to run the insert_SB1-8 functions below because the init hook created duplicates when I was test adding just one product out of the activation hook.
This is in my main plugin file:
// Activate important functions
include( plugin_dir_path(__FILE__) . '/includes/activation.php');
register_activation_hook( __FILE__, 'activate_core_functions' );
The file activation.php contains the function activate_core_functions.
function activate_core_functions() {
if ( get_option('my_plugin_activated') ) {
add_action('admin_notices', 'insert_SB1');
add_action('admin_notices', 'insert_SB2');
add_action('admin_notices', 'insert_SB3');
add_action('admin_notices', 'insert_SB4');
add_action('admin_notices', 'insert_SB5');
add_action('admin_notices', 'insert_SB6');
add_action('admin_notices', 'insert_SB7');
add_action('admin_notices', 'insert_SB8');
function insert_SB1() {
$my_post = array(
'post_title' => 'SB: 0 - 60',
'post_status' => 'publish',
'post_type' => 'product'
);
$post_id = wp_insert_post( $my_post );
wp_set_object_terms( $post_id, 'Skates', 'product_cat' );
wp_set_object_terms( $post_id, 'simple', 'product_type');
update_post_meta( $post_id, '_stock_status', 'instock');
// Meta values
update_post_meta( $post_id, 'sections', 3);
// Materials related
update_post_meta( $post_id, 'bpl', 672);
update_post_meta( $post_id, '1pp', 2);
update_post_meta( $post_id, 'plf', 132);
update_post_meta( $post_id, 'bnp', 152);
update_post_meta( $post_id, 'sb', 152);
update_post_meta( $post_id, 'cs', 218);
update_post_meta( $post_id, 'spl1', 578);
update_post_meta( $post_id, 'spl2', 0);
update_post_meta( $post_id, 'spl3', 0);
update_post_meta( $post_id, 'bwt', 60);
update_post_meta( $post_id, '6hh', 18);
update_post_meta( $post_id, '611hh', 30);
update_post_meta( $post_id, 'cp', 0);
update_post_meta( $post_id, 'abpl', 175);
update_post_meta( $post_id, 'ab', 1);
add_costs_meta($post_id);
}
// Rest of the functions till insert_SB8() are similar below with different product names
function insert_SB2() {...
}
function insert_SB3() {...
}
function insert_SB4() {...
}
function insert_SB5() {...
}
function insert_SB6() {...
}
function insert_SB7() {...
}
function insert_SB8() {...
}
add_costs_meta($post_id){
// Costs Related meta vals
update_post_meta( $post_id, 'psc', 1.75);
update_post_meta( $post_id, 'pmhc', 45);
update_post_meta( $post_id, 'osc', 1.75);
update_post_meta( $post_id, 'oabc', 295);
update_post_meta( $post_id, 'mbc', 1.75);
update_post_meta( $post_id, 'mbcp', 0.20);
update_post_meta( $post_id, 'wc', 45);
update_post_meta( $post_id, 'ihsc', 75);
}
}
update_option('my_plugin_activated', time());
}
I can say that the function activate_core_functions is firing properly as the option my_plugin_activated does get created in the DB.
Any help would be appreciated, I really worked hard on these, but to no avail.
Ok I got it working. So I removed these action hooks:
add_action('admin_notices', 'insert_SB1');
add_action('admin_notices', 'insert_SB2');
add_action('admin_notices', 'insert_SB3');
add_action('admin_notices', 'insert_SB4');
add_action('admin_notices', 'insert_SB5');
add_action('admin_notices', 'insert_SB6');
add_action('admin_notices', 'insert_SB7');
add_action('admin_notices', 'insert_SB8');
and instead manually executed the function at the end like so:
insert_SB1();
insert_SB2();
insert_SB3();
insert_SB4();
insert_SB5();
insert_SB6();
insert_SB7();
insert_SB8();

WP_insert_term creating duplicate categories during WooCommerce product import

I've been racking my brain for a few days on this issue and can't figure out why my code to import is creating duplicate product categories.
Problem: I am pulling in about 30,000 products from the third party API in JSON format it is then is inserted into a custom database, from which I pull each product's data and format for importing into WooCommerce, these processes are working fine the problem comes when I am inserting the category terms. When categories are inserted using wp_insert_term some categories are duplicated but have a different URL slug.
ie...
— Ranges, Cooktops & Ovens
— — Range Hoods & Downdraft Ventilation (slug: range-hoods-downdraft-ventilation )
— — Range Hoods & Downdraft Ventilation (slug: range-hoods-downdraft-ventilation-ranges-cooktops-ovens)
The child category gets duplicated but with a different slug.
This is the Category array I'm looping through to create the hierarchical category paths:
"categoryPath":[{"id":"cat00000","name":"Company Name"},{"id":"abcat0900000","name":"Appliances"},{"id":"abcat0904000","name":"Ranges, Cooktops & Ovens"},{"id":"abcat0904002","name":"Range Hoods & Downdraft Ventilation"}]
Here is my single product import code the relevant category portion in at the bottom starting with $categoryPath, just wanted to give some context of what Im doing:
$result= $wpdb->get_var( "SELECT `results_array`
FROM $table_name
WHERE `arr_serialize2` = $textProductSku
AND `update_type` = 'create'
");
$final_product_formate_arrays = json_decode($result, true);
$post = array(
'post_title' => $final_product_formate_arrays['parent_or_simple_product']['title'],
'post_content' => $final_product_formate_arrays['parent_or_simple_product']['longDescription'],
'post_excerpt' => isset( $final_product_formate_arrays['parent_or_simple_product']['shortDescription']) ? $final_product_formate_arrays['parent_or_simple_product']['shortDescription'] : '' ,
'post_status' => "publish",
'post_parent' => '',
'post_type' => "product",
);
$post_id = wp_insert_post( $post );
if (!$post_id)
{
return false;
}
update_post_meta($post_id,'_complete_product_data',json_encode($final_product_formate_arrays));
update_post_meta($post_id, '_sku', $final_product_formate_arrays['parent_or_simple_product']['sku']);
update_post_meta( $post_id, '_visibility', 'visible' );
if($final_product_formate_arrays['parent_or_simple_product']['inStoreAvailability'] > 0)
{
update_post_meta( $post_id, '_manage_stock', "yes" );
update_post_meta( $post_id, '_stock', $final_product_formate_arrays['parent_or_simple_product']['stockQuantity'] );
update_post_meta( $post_id, '_stock_status', 'instock');
} elseif($final_product_formate_arrays['is_variation']){
update_post_meta( $post_id, '_manage_stock', "no" );
update_post_meta( $post_id, '_stock_status', 'instock');
} else {
update_post_meta( $post_id, '_manage_stock', "yes" );
update_post_meta( $post_id, '_stock_status', 'outofstock');
update_post_meta( $post_id, '_stock', 0 );
}
update_post_meta( $post_id, '_regular_price', $final_product_formate_arrays['parent_or_simple_product']['regularPrice'] );
update_post_meta( $post_id, '_sale_price', $final_product_formate_arrays['parent_or_simple_product']['salePrice'] );
update_post_meta( $post_id, '_price', $final_product_formate_arrays['parent_or_simple_product']['salePrice'] );
update_post_meta( $post_id, '_weight', $final_product_formate_arrays['parent_or_simple_product']['weight'] );
update_post_meta( $post_id, '_length', $final_product_formate_arrays['parent_or_simple_product']['depth'] );
update_post_meta( $post_id, '_width', $final_product_formate_arrays['parent_or_simple_product']['width'] );
update_post_meta( $post_id, '_height', $final_product_formate_arrays['parent_or_simple_product']['height'] );
update_post_meta( $post_id, '_wc_average_rating', $final_product_formate_arrays['parent_or_simple_product']['reviewAverage'] );
**$categoryPath = $final_product_formate_arrays['parent_or_simple_product']['categoryPath'];
if(!empty($categoryPath))
{
$parent_id='';
foreach ($categoryPath as $key => $value) {
if($key!=0) {
$new_str = str_replace( array( ',', '&' ), '-', $value['name'] );
$new_str = sanitize_title( $new_str );
$parent_term = term_exists( $parent_id, 'product_cat' ); // array is returned if taxonomy is given
if( isset( $parent_term )) {
$parent_id = $parent_term['term_id']; // get numeric term id
} else{
$parent_id = 0;
}
$term = wp_insert_term( $value['name'], 'product_cat', [
'description'=> $value['name'],
'parent' => intval( $parent_id ),
'slug' => $new_str,
]
);
if( is_wp_error( $term ) && isset( $term->error_data['term_exists'] ) )
{
$term_id = isset( $term->error_data['term_exists'] ) ? $term->error_data['term_exists'] :'';
$term_error = $term->get_error_message();
$term_error .="\n";
error_log($term_error, 3, $pluginlog);
} else if ( !is_wp_error( $term ) ) {
$new_term_id = isset( $term['term_id']) ? $term['term_id'] : '';
$term_id = $new_term_id;
}
$term_id = intval($term_id);
$parent_id = !empty($term_id)?$term_id:'';
wp_set_post_terms($post_id, $term_id, 'product_cat');**
// wp_set_object_terms($post_id, $term_id, 'product_cat');
} else {
continue;
}
}
}

Use woocomerce functions inside my php script file

I see many examples of use of woocomerce library, but no one of them include any libraries.
This is an example:
$post = array(
'post_author' => $user_id,
'post_content' => '',
'post_status' => "publish",
'post_title' => $product->part_num,
'post_parent' => '',
'post_type' => "product",
);
//Create post
$post_id = wp_insert_post( $post, $wp_error );
if($post_id){
$attach_id = get_post_meta($product->parent_id, "_thumbnail_id", true);
add_post_meta($post_id, '_thumbnail_id', $attach_id);
}
wp_set_object_terms( $post_id, 'Races', 'product_cat' );
wp_set_object_terms( $post_id, 'simple', 'product_type');
update_post_meta( $post_id, '_visibility', 'visible' );
update_post_meta( $post_id, '_stock_status', 'instock');
update_post_meta( $post_id, 'total_sales', '0');
update_post_meta( $post_id, '_downloadable', 'yes');
update_post_meta( $post_id, '_virtual', 'yes');
update_post_meta( $post_id, '_regular_price', "1" );
update_post_meta( $post_id, '_sale_price', "1" );
update_post_meta( $post_id, '_purchase_note', "" );
update_post_meta( $post_id, '_featured', "no" );
update_post_meta( $post_id, '_weight', "" );
update_post_meta( $post_id, '_length', "" );
update_post_meta( $post_id, '_width', "" );
update_post_meta( $post_id, '_height', "" );
update_post_meta( $post_id, '_sku', "");
update_post_meta( $post_id, '_product_attributes', array());
update_post_meta( $post_id, '_sale_price_dates_from', "" );
update_post_meta( $post_id, '_sale_price_dates_to', "" );
update_post_meta( $post_id, '_price', "1" );
update_post_meta( $post_id, '_sold_individually', "" );
update_post_meta( $post_id, '_manage_stock', "no" );
update_post_meta( $post_id, '_backorders', "no" );
update_post_meta( $post_id, '_stock', "" );
// file paths will be stored in an array keyed off md5(file path)
$downdloadArray =array('name'=>"Test", 'file' => $uploadDIR['baseurl']."/video/".$video);
$file_path =md5($uploadDIR['baseurl']."/video/".$video);
$_file_paths[ $file_path ] = $downdloadArray;
// grant permission to any newly added files on any existing orders for this product
// do_action( 'woocommerce_process_product_file_download_paths', $post_id, 0, $downdloadArray );
update_post_meta( $post_id, '_downloadable_files', $_file_paths);
update_post_meta( $post_id, '_download_limit', '');
update_post_meta( $post_id, '_download_expiry', '');
update_post_meta( $post_id, '_download_type', '');
update_post_meta( $post_id, '_product_image_gallery', '');
Where they put this code so there is no:
Fatal error: Uncaught Error: Call to undefined function
Is the only way is to include the library in the script?
I think you are trying to make a plugin for woo-commerce. If yes then here is an example of making a simple woo-commerce plugin
You need to check first if woo-commerce plugin is activated or not. To do that in your main plugin file write this code.
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
// code for woocommerce goes here
}
Here is the full demo code you should use in your plugin file
<?php
/**
* Plugin Name: Demo URL button for Woocommerce
*/
/**
* Check if WooCommerce is active
**/
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
include 'functions.php';
}
You can check a demo plugin for woo-commerce here https://github.com/prappo/woocommerce-add-demo-link-button
I hope it will help you.

Create a WooCommerce product with the same name when a custom post type is published

I have a custom post type called Event which I want to sell through woocommerce. So what I want, when I create a Event post, it automatically creates a product under woocommerce with the same name. Is it possible?
I tried the following code found in Create a Woocommerce product when post is created
add_action( 'save_event', 'auto_create_product_from_post', 100, 2 );
function auto_create_product_from_post($id, $post){
$post_id = wp_insert_post( array(
//'post_title' => 'Adams Product',
'post_title' => $post.post_title,
'post_content' => $post.post_title,
'post_status' => 'publish',
'post_type' => "product",
) );
wp_set_object_terms( $post_id, 'simple', 'product_type' );
update_post_meta( $post_id, '_visibility', 'visible' );
update_post_meta( $post_id, '_stock_status', 'instock');
update_post_meta( $post_id, 'total_sales', '0' );
update_post_meta( $post_id, '_downloadable', 'no' );
update_post_meta( $post_id, '_virtual', 'yes' );
update_post_meta( $post_id, '_regular_price', '' );
update_post_meta( $post_id, '_sale_price', '' );
update_post_meta( $post_id, '_purchase_note', '' );
update_post_meta( $post_id, '_featured', 'no' );
update_post_meta( $post_id, '_weight', '' );
update_post_meta( $post_id, '_length', '' );
update_post_meta( $post_id, '_width', '' );
update_post_meta( $post_id, '_height', '' );
update_post_meta( $post_id, '_sku', '' );
update_post_meta( $post_id, '_product_attributes', array() );
update_post_meta( $post_id, '_sale_price_dates_from', '' );
update_post_meta( $post_id, '_sale_price_dates_to', '' );
update_post_meta( $post_id, '_price', '' );
update_post_meta( $post_id, '_sold_individually', '' );
update_post_meta( $post_id, '_manage_stock', 'no' );
update_post_meta( $post_id, '_backorders', 'no' );
update_post_meta( $post_id, '_stock', '' );
}
But the above code gives me Recoverable fatal error: Object of class WP_Post could not be converted to string error. I changed the action hook to publish_event but my website has gone in to a infinite loop and still creating a lots of products even after I removed the code.
The wrong part is $post.post_title… $post is a WP_Post object so use -> in $post->post_title, to get the post title as . is used for string concatenation in PHP.
So in your code:
$product = wp_insert_post( array(
//'post_title' => 'Adams Product',
'post_title' => $post->post_title, // <=== HERE
'post_content' => $post->post_content, // <=== Changed
'post_status' => 'publish',
'post_type' => "product",
) );
This will solve your issue.
A better way: Since WooCommerce 3, you could use CRUD Objects like:
add_action( 'save_event', 'auto_create_product_from_post', 100, 2 );
function auto_create_product_from_post($id, $post){
// Create an empty instance of the WC_Product
$product = new WC_Product_Simple(); // <=== Simple product
$product->set_name( $post->post_title );
$product->set_status( $post->post_status );
$product->set_description( $post->post_content ); // (optional)
$product->set_short_description( $post->post_excerpt ); // (optional)
// You can use any available WC_Product methods to set other properties
// see: https://docs.woocommerce.com/wc-apidocs/class-WC_Product.html
$product->save(); // Save (publish) new product
}
Code goes in functions.php file of your active child theme (or active theme). Tested and work.

Get woocommerce product ID by product name

I am working on a custom function to create a woocommerce product programmatically when user click a button on the post contact form. The below is the code i am using to create the product, but yet i am stuck to add this product to the cart via code since i can not manage to get the product id within the function code. Need your help to tell me how to get the product id to add it to the cart.
function contactform7_before_send_mail( $tour_to_product ) {
$tour_to_product = WPCF7_Submission::get_instance();
if ( $tour_to_product ) {
$formData = $tour_to_product->get_posted_data();
}
$tourprice =$formData['tour-price'];
$tourdiscountprice =$formData['tour-discount-price'];
$tourname =$formData['tour-name'];
$noadults =$formData['no-adult'];
$nochild =$formData['no-child'];
if(!empty($formData['tour-discount-price']))
{
$finalprice =$formData['tour-discount-price'];
} else {
$finalprice =$formData['tour-price'];
}
$post = array(
'post_author' => $user_id,
'post_content' => '',
'post_status' => "publish",
'post_title' => $tourname,
'post_parent' => '',
'post_type' => "product",
);
//Create post
$post_id = wp_insert_post( $post, $wp_error );
if($post_id){
global $tour_id;
$attach_id = get_post_meta($product->parent_id, "_thumbnail_id", true);
add_post_meta($post_id, '_thumbnail_id', $attach_id);
// i am trying here to get the product id
$tour_id = get_post_meta($product->id());
}
wp_set_object_terms( $post_id, 'Tours', 'product_cat' );
wp_set_object_terms( $post_id, 'simple', 'product_type');
update_post_meta( $post_id, '_visibility', 'visible' );
update_post_meta( $post_id, '_stock_status', 'instock');
update_post_meta( $post_id, 'total_sales', '0');
update_post_meta( $post_id, '_downloadable', 'no');
update_post_meta( $post_id, '_virtual', 'yes');
update_post_meta( $post_id, '_regular_price', $tourprice );
update_post_meta( $post_id, '_sale_price', $tourdiscountprice );
update_post_meta( $post_id, '_purchase_note', "" );
update_post_meta( $post_id, '_featured', "no" );
update_post_meta( $post_id, '_sku', "");
update_post_meta( $post_id, '_product_attributes', array());
update_post_meta( $post_id, '_sale_price_dates_from', "" );
update_post_meta( $post_id, '_sale_price_dates_to', "" );
update_post_meta( $post_id, '_price', $tourprice );
update_post_meta( $post_id, '_sold_individually', "" );
update_post_meta( $post_id, '_manage_stock', "no" );
update_post_meta( $post_id, '_backorders', "no" );
update_post_meta( $post_id, '_stock', "" );
// i am trying to output the product id for testing
echo "<script type='text/javascript'>alert('$tour_id')</script>";
}
remove_all_filters ('wpcf7_before_send_mail');
add_action( 'wpcf7_before_send_mail', 'contactform7_before_send_mail' );
That's right. The code line below contains the id of the last post added.
$post_id = wp_insert_post( $post, $wp_error ); //<== ID

Categories