Generate woocommerce coupon after gravity form submission - php

I want a user to enter their email in a gravity form and after submission they are emailed a unique coupon code that expires after two weeks. I have cobble together code from a few other solutions and I am successful at creating the unique code. But I can't get it to create the coupon in woocommerce.. Not being a PHP master I know I'm missing something obvious.
//* Define options/constants
define( 'ENGWP_FORM_ID', 276 ); // The ID of the form (integer)
define( 'ENGWP_SOURCE_FIELD_ID', 2 ); // The ID of the form field holding the code (integer)
define( 'ENGWP_CODE_LENGTH', 12 ); // Length of code (integer)
define( 'ENGWP_CODE_CHARS', '1234567890QWERTYUIOPASDFGHJKLZXCVBNM' ); // Available character for the code; default 0-9 and uppercase letters (string)
define( 'ENGWP_CODE_PREFIX', '17-' ); // Custom prefix for the code (string); default empty
define( 'ENGWP_DISCOUNT_TYPE', 'percent' ); // 'flat' or 'percent' (string)
define( 'ENGWP_DISCOUNT_AMOUNT', 10 ); // Value of discount (integer); $ if 'type' is 'flat' and % if 'type' is 'percent'
define( 'ENGWP_MAX_USES', 1 ); // Maximum number of uses per customer (integer)
define( 'ENGWP_MIN_PRICE', 0 ); // Minimum price for discount to apply (integer); default none
define( 'ENGWP_PRODUCT_REQS', '' ); // A comma-separated list of product IDs (string) the coupons apply to
define( 'ENGWP_REQS_CONDITION', '' ); // How to apply the discount to those products (string); accepts 'any' (at least one product ID must be in the cart) or 'all' (all products must be in the cart)
define( 'ENGWP_SINGLE_USE', 'use_once' ); // Whether the coupons generated can be used more than once by a single customer; default is set to one-time usage but can be set to false (boolean) for allowing multiple uses
define( 'ENGWP_EXCLUDE_PRODUCTS', '' ); // A comma-separated list of product IDs (string) to exclude from discount-applicability
$start_date = ''; # no date
// $start_date = '01/01/1900'; # static date
// $start_date = date( 'm/d/Y', strtotime("yesterday") );
$exp_date = date( 'm/d/Y', strtotime("+14 days") );
// $exp_date = '01/01/1900'; # static date
// $exp_date = ''; # no date
class GW_Create_Coupon {
public function __construct( $args = array() ) {
// set our default arguments, parse against the provided arguments, and store for use throughout the class
$this->_args = wp_parse_args( $args, array(
'form_id' => false,
'source_field_id' => false,
'plugin' => 'wc',
'amount' => 0,
'type' => '',
'meta' => array()
) );
// do version check in the init to make sure if GF is going to be loaded, it is already loaded
add_action( 'init', array( $this, 'init' ) );
}
public function init() {
// make sure we're running the required minimum version of Gravity Forms
if( ! property_exists( 'GFCommon', 'version' ) || ! version_compare( GFCommon::$version, '1.8', '>=' ) ) {
return;
}
add_action( 'gform_after_submission', array( $this, 'create_coupon' ), 10, 2 );
}
public function create_coupon( $entry, $form ) {
if( ! $this->is_applicable_form( $form ) ) {
return;
}
$coupon_code = rgar( $entry, $this->_args['source_field_id'] );
$amount = $this->_args['amount'];
$type = $this->_args['type'];
$plugin_func = array( $this, sprintf( 'create_coupon_%s', $this->_args['plugin'] ) );
if( is_callable( $plugin_func ) ) {
call_user_func( $plugin_func, $coupon_code, $amount, $type );
}
}
public function create_coupon_wc( $coupon_code, $amount, $type ) {
$coupon = array(
‘post_title’ => $coupon_code,
‘post_content’ => ”,
‘post_status’ => ‘publish’,
‘post_author’ => 1,
‘post_type’ => ‘shop_coupon’
);
$new_coupon_id = wp_insert_post( $coupon );
$meta = wp_parse_args( $this->_args[‘meta’], array(
‘discount_type’ => $type,
‘coupon_amount’ => $amount,
‘individual_use’ => ‘yes’,
‘product_ids’ => ”,
‘exclude_product_ids’ => ”,
‘usage_limit’ => ‘1’,
‘expiry_date’ => ”,
‘apply_before_tax’ => ‘no’,
‘free_shipping’ => ‘no’,
‘exclude_sale_items’ => ‘no’,
‘product_categories’ => ”,
‘exclude_product_categories’ => ”,
‘minimum_amount’ => ”,
‘customer_email’ => ”
) );
foreach( $meta as $meta_key => $meta_value ) {
update_post_meta( $new_coupon_id, $meta_key, $meta_value );
}
}
public function create_coupon_edd( $coupon_code, $amount, $type ) {
if( ! is_callable( 'edd_store_discount' ) ) {
return;
}
$meta = wp_parse_args( $this->_args['meta'], array(
'name' => $coupon_code,
'code' => $coupon_code,
'type' => $type,
'amount' => $amount,
'excluded_products' => array(),
'expiration' => '',
'is_not_global' => false,
'is_single_use' => false,
'max_uses' => '',
'min_price' => '',
'product_condition' => '',
'product_reqs' => array(),
'start' => '',
'uses' => '',
) );
// EDD will set it's own defaults in the edd_store_discount() so let's filter out our own empty defaults (their just here for easier reference)
$meta = array_filter( $meta );
// EDD takes a $details array which has some different keys than the meta, let's map the keys to the expected format
$edd_post_keys = array(
'max_uses' => 'max',
'product_reqs' => 'products',
'excluded_products' => 'excluded-products',
'is_not_global' => 'not_global',
'is_single_use' => 'use_once'
);
foreach( $meta as $key => $value ) {
$mod_key = rgar( $edd_post_keys, $key );
if( $mod_key ) {
$meta[$mod_key] = $value;
}
}
edd_store_discount( $meta );
}
function is_applicable_form( $form ) {
$form_id = isset( $form['id'] ) ? $form['id'] : $form;
return $form_id == $this->_args['form_id'];
}
}
//* Instantiate the class for EDD
new GW_Create_Coupon( array(
'form_id' => ENGWP_FORM_ID,
'source_field_id' => ENGWP_SOURCE_FIELD_ID,
'amount' => ENGWP_DISCOUNT_AMOUNT,
'type' => ENGWP_DISCOUNT_TYPE,
'meta' => array(
'excluded_products' => array( ENGWP_EXCLUDE_PRODUCTS ),
'expiration' => $exp_date,
'is_not_global' => 'not_global',
'is_single_use' => ENGWP_SINGLE_USE,
'max_uses' => ENGWP_MAX_USES,
'min_price' => ENGWP_MIN_PRICE,
'product_condition' => ENGWP_REQS_CONDITION,
'product_reqs' => array( ENGWP_PRODUCT_REQS ),
'start' => $start_date,
)
) );
/**
* Generate the random codes to be used for the EDD discounts
*/
//* Generates and returns the code
add_filter( 'gform_field_value_uuid', 'gw_generate_unique_code' );
function gw_generate_unique_code() {
$length = ENGWP_CODE_LENGTH;
$chars = ENGWP_CODE_CHARS;
$prefix = ENGWP_CODE_PREFIX;
$unique = '';
$chars_length = strlen( $chars )-1;
for( $i = 0 ; $i < $length ; $i++ ) {
$unique .= $chars[ rand( 0, $chars_length ) ];
}
do {
$unique = $prefix . str_shuffle( $unique );
} while ( !gw_check_unique_code( $unique ) );
return $unique;
}
//* Checks to make sure the code generated is unique (not already in use)
function gw_check_unique_code( $unique ) {
global $wpdb;
$table = $wpdb->prefix . 'rg_lead_detail';
$form_id = ENGWP_FORM_ID; // update to the form ID your unique id field belongs to
$field_id = ENGWP_SOURCE_FIELD_ID; // update to the field ID your unique id is being prepopulated in
$result = $wpdb->get_var( "SELECT value FROM $table WHERE form_id = '$form_id' AND field_number = '$field_id' AND value = '$unique'" );
if ( empty ( $result ) ) {
return true;
} else return false;
}

You can use WC_Coupon to generate a coupon code. try the below code.
add_action( 'gform_after_submission', array( $this, 'create_coupon' ), 10, 2 );
public function create_coupon( $entry, $form ){
$coupon_code = rgar( $entry, $this->_args['source_field_id'] );
$date_expires = date('Y-m-d', strtotime('+14 days'));
$discount_type = 'fixed_cart'; // 'store_credit' doesn't exist
$coupon = new WC_Coupon();
$coupon->set_code($coupon_code);
//the coupon discount type can be 'fixed_cart', 'percent' or 'fixed_product', defaults to 'fixed_cart'
$coupon->set_discount_type($discount_type);
//the discount amount, defaults to zero
$coupon->set_amount($amount );
$coupon->set_date_expires( $date_expires );
//save the coupon
$coupon->save();
}

Related

Implementing Rawg Api wordpress not working

I try to implement the Rawg.io API to my Wordpress Functions.php File but it doesn't work, i tried my code with another API and it is working fine, i think it has something to do with the API link Page='.$current_page.'
as you can see i created an custom post type to add the games to.
i also created custom fields with the right field keys.
My Report.txt file keeps returning current page = 1
function register_game_cpt() {
register_post_type( 'game', array(
'label' => 'Games',
'public' => true,
'capability_type' => 'post',
'supports' => array('title', 'editor', 'thumbnail'),
'taxonomies' => array('recordings', 'category', 'whatever', 'post_tag'),
));
}
add_action( 'init', 'register_game_cpt' );
// if ( ! wp_next_scheduled( 'update_game_list' ) ) {
// wp_schedule_event( time(), 'weekly', 'update_game_list' );
// }
add_action( 'update_game_list', 'get_games_from_api' );
add_action( 'wp_ajax_nopriv_get_games_from_api', 'get_games_from_api' );
add_action( 'wp_ajax_get_games_from_api', 'get_games_from_api' );
function get_games_from_api() {
$file = get_stylesheet_directory() . '/report.txt';
$current_page = ( ! empty( $_POST['current_page'] ) ) ? $_POST['current_page'] : 1;
$games = [];
// Should return an array of objects
$results = wp_remote_retrieve_body(wp_remote_get('https://api.rawg.io/api/games?key=/////////////////////&page='.$current_page.'&page_size=40'));
file_put_contents($file, "Current Page: " . $current_page. "\n\n", FILE_APPEND);
// turn it into a PHP array from JSON string
$results = json_decode( $results );
// Either the API is down or something else spooky happened. Just be done.
if( ! is_array( $results ) || empty( $results ) ){
return false;
}
$games[] = $results;
foreach( $games[0] as $game ){
$game_slug = sanitize_title( $game->name . '-' . $game->id );
$existing_game = get_page_by_path( $game_slug, 'OBJECT', 'game' );
if( $existing_game === null ){
$inserted_game = wp_insert_post( [
'post_name' => $game_slug,
'post_title' => $game_slug,
'post_type' => 'game',
'post_status' => 'publish'
] );
if( is_wp_error( $inserted_game ) || $inserted_game === 0 ) {
die('Could not insert game: ' . $game_slug);
error_log( 'Could not insert game: ' . $game_slug );
continue;
}
// add meta fields
$fillable = [
'field_62684fc72d524' => 'count',
'field_6266cb41982d3' => 'name',
'field_6266cb4c982d4' => 'publishers',
'field_6266cb54982d5' => 'genres',
'field_6266cb64012e9' => 'platforms',
'field_6266cb722ebe8' => 'dates',
'field_626850012d525' => 'results',
];
foreach( $fillable as $key => $name ) {
update_field( $key, $game->$name, $inserted_game );
}
} else {
$existing_game_id = $existing_game->ID;
$exisiting_game_timestamp = get_field('updated_at', $existing_game_id);
if( $game->updated_at >= $exisiting_game_timestamp ){
$fillable = [
'field_62684fc72d524' => 'count',
'field_6266cb41982d3' => 'name',
'field_6266cb4c982d4' => 'publishers',
'field_6266cb54982d5' => 'genres',
'field_6266cb64012e9' => 'platforms',
'field_6266cb722ebe8' => 'dates',
'field_626850012d525' => 'results',
];
foreach( $fillable as $key => $name ){
update_field( $name, $game->$name, $existing_game_id);
}
}
}
}
$current_page = $current_page + 1;
wp_remote_post( admin_url('admin-ajax.php?action=get_games_from_api'), [
'blocking' => false,
'sslverify' => false, // we are sending this to ourselves, so trust it.
'body' => [
'current_page' => $current_page
]
] );
}

Check if Mollie payment is paid

I have been stuck on this for weeks now so I'm dropping my question here, hopefully someone can help me. I have a website where people can sell their car. You buy an advertisement and you can upload your vehicle. I have integrated Mollie Payment API so people can pay with iDeal, but it doesn't seem to read the payment status.
When the payment has been successful, my system doesn't give out an advertisement. How can I check if the payment has been successful and then automatically give out an advertisement if the order has been paid?
This is the code that processes the payments:
<?php
namespace AutoListingsFrontend;
require_once __DIR__ . "/../mollie-api-php/vendor/autoload.php";
require_once __DIR__ . "/../mollie-api-php/examples/functions.php";
class Checkout {
/**
* Hold our entire Purchase data
*/
public $purchase_data = array();
public function __construct() {
add_action( 'init', array( $this, 'process_purchase' ) );
add_action( 'auto_listings_mark_as_pending', array( $this, 'pending_payment' ) );
add_action( 'auto_listings_send_to_gateway', array( $this, 'send_to_gateway' ) );
add_action( 'auto_listings_payment_successful', array( $this, 'payment_successful' ), 10, 2 );
add_action( 'auto_listings_insert_payment_note', array( $this, 'insert_payment_note' ), 10, 2 );
add_action( 'auto_listings_update_payment_status', array( $this, 'update_payment_status' ), 10, 2 );
//add_action( 'auto_listings_gateway_paypal', 'auto_listings_process_paypal_purchase' );
}
public function sanitize_post_data() {
// simple sanitizing
foreach ( $_POST as $key => $value ) {
$key = str_replace( 'auto-listings-', '', $key );
if( $key == 'user-id' ) {
$sanitized[ $key ] = absint( $value );
} else {
$sanitized[ $key ] = sanitize_text_field( $value );
}
}
return $sanitized;
}
/**
* Process Purchase Form
*
* Handles the purchase form process.
*/
public function process_purchase() {
do_action( 'auto_listings_pre_process_purchase' );
// Check if there is $_POST
if ( empty( $_POST ) ) return false;
if ( ! isset( $_POST['auto-listings-gateway'] ) || empty( $_POST['auto-listings-gateway'] ) )
return false;
if ( ! isset( $_POST['auto-listings-package'] ) || empty( $_POST['auto-listings-package'] ) )
return false;
if ( ! isset( $_POST['auto-listings-user-id'] ) || empty( $_POST['auto-listings-user-id'] ) )
return false;
$data = $this->sanitize_post_data();
// Verify there is a user_ID
if ( $data['user-id'] > 0 ) {
// Get the logged in user data
$user = get_userdata( $data['user-id'] );
// Verify data
if ( ! $user ) {
return false;
}
}
// Setup user information
$user_info = array(
'id' => $user->ID,
'email' => $user->user_email,
'first_name' => $user->first_name,
'last_name' => $user->last_name,
);
// Setup package information
$package_info = auto_listings_get_package( $data['package'] );
// Set up the unique purchase key.
$key = strtolower( md5( $user_info['id'] . date( 'Y-m-d H:i:s' ) . uniqid( 'auto', true ) ) );
// Setup purchase information
$purchase_data = array(
'package' => stripslashes_deep( $package_info ),
'purchase_key' => $key,
'user' => stripslashes_deep( $user_info ),
'date' => date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ),
'gateway' => $data['gateway'],
);
// If the total amount in the cart is 0, send to the manual gateway.
if ( ! $purchase_data['package']['price'] ) {
$purchase_data['gateway'] = 'manual';
}
// Allow the purchase data to be modified before it is sent to the gateway
$this->purchase_data = apply_filters(
'auto_listings_purchase_data_before_gateway',
$purchase_data,
$data
);
// Send info to create the pending payment
// Send info to the gateway for payment processing
do_action( 'auto_listings_mark_as_pending' );
do_action( 'auto_listings_send_to_gateway' );
}
/**
* Sends all the payment data to the specified gateway.
*/
public function send_to_gateway() {
$this->purchase_data['gateway_nonce'] = wp_create_nonce( 'auto-listings-gateway' );
// $gateway must match the ID used when registering the gateway
do_action( 'auto_listings_gateway_' . $this->purchase_data['gateway'], $this->purchase_data );
}
/**
* Insert Pending Payment
*
* #param array $payment_data Payment data to process
* #return int|bool Payment ID if payment is inserted, false otherwise
*/
public function pending_payment() {
if ( empty( $this->purchase_data ) ) {
return false;
}
$payment_title = $this->purchase_data['user']['email'];
if ( $purchase_data['gateway'] = 'ideal' ) {
/*
* Initialize the Mollie API library with your API key.
*w
* See: https://www.mollie.com/dashboard/developers/api-keys
*/
$mollie = new \Mollie\Api\MollieApiClient();
$mollie->setApiKey("MOLLIE_APIKEY"); // change to LIVE key when done
$packages = auto_listings_get_packages();
foreach ( $packages as $package_id => $package ){
$orderId = $payment->id;
$prijs = '';
if(isset($_POST["auto-listings-purchase"])) {
$package_id = $_POST['auto-listings-package'];
if($package_id == "3769") {
$prijs = "10.00";
} elseif ($package_id == "3767") {
$prijs = "40.00";
} else {
echo "Something went wrong. Please contact our staff via: info#vagplace.nl.";
}
}
// Create Mollie payment
$payment = $mollie->payments->create([
"amount" => [
"currency" => "EUR",
"value" => $prijs,
],
"description" => "VAGplace order: ".$orderId,
"redirectUrl" => "https://vagplace.nl/mijn-autos/?payment=success&gateway=ideal&order_id=".$orderId,
"webhookUrl" => "https://vagplace.nl/mollie-webhook",
"method" => \Mollie\Api\Types\PaymentMethod::IDEAL,
"metadata" => [
"order_id" => $orderId,
],
]);
database_write($orderId, $payment->status);
/*
* Send the customer off to complete the payment.
* This request should always be a GET, thus we enforce 303 http response code
*/
header("Location: " . $payment->getCheckoutUrl(), true, 303);
}
}
$payment_post = array(
'post_title' => $payment_title,
'post_status' => 'pending',
'post_date' => $this->purchase_data['date'],
'post_type' => 'package-payment',
'post_content' => '',
'meta_input' => array(
'_al_payment_data' => stripslashes_deep( $this->purchase_data ),
'_al_payment_package_status' => 'pending',
'_al_payment_user_id' => $this->purchase_data['user']['id'],
),
);
$payment_id = wp_insert_post( $payment_post );
if ( ! empty( $payment_id ) ) {
$this->purchase_data['payment_id'] = $payment_id;
}
// Return false if no payment was inserted
return false;
}
/**
* Add a note to a payment
*
* #param int $payment_id The payment ID to store a note for
* #param string $note The note to store
* #return int The new note ID
*/
public function insert_payment_note( $payment_id = 0, $note = '' ) {
if ( empty( $payment_id ) )
return false;
$existing_data = get_post_meta( $payment_id, '_al_payment_data', true );
do_action( 'auto_listings_pre_insert_payment_note', $payment_id, $note );
$commentdata = array(
'comment_post_ID' => $payment_id, // to which post the comment will show up
'comment_author' => '', //fixed value - can be dynamic
'comment_author_email' => $existing_data['user']['email'], //fixed value - can be dynamic
'comment_author_url' => '', //fixed value - can be dynamic
'comment_content' => $note['heading'] . ' - ' . $note['content'], //fixed value - can be dynamic
'comment_type' => '', //empty for regular comments, 'pingback' for pingbacks, 'trackback' for trackbacks
'comment_parent' => 0, //0 if it's not a reply to another comment; if it's a reply, mention the parent comment ID here
'user_id' => get_current_user_id() ? get_current_user_id() : 1, //passing current user ID or any predefined as per the demand
);
//Insert new comment and get the comment ID
$note_id = wp_new_comment( $commentdata );
return $note_id;
}
/**
* Updates a payment status.
*
* #param int $payment_id Payment ID
* #param string $new_status New Payment Status (default: publish)
* #return bool If the payment was successfully updated
*/
public function update_payment_status( $payment_id = 0, $new_status = 'publish' ) {
if ( empty( $payment_id ) ) {
return false;
}
if ( empty( $data ) ) {
return false;
}
//Trying to verify payment
//$payment = $mollie->payments->get($payment->id);
$payment = $mollie->payments->get($_POST["id"]);
$orderId = $payment->metadata->order_id;
if ($payment->isPaid())
{
echo "Payment received.";
}
$post_arr = array(
'ID' => $payment_id,
'post_status' => $new_status,
);
$updated = wp_update_post( $post_arr );
return $updated;
}
/**
* What to do when a payment completes successfully
*
* #param array $data payment success data, sent from gateway
* #return bool If the payment was successfully updated
*/
public function payment_successful( $data ) {
$start_time = current_time( 'timestamp', $gmt = 0 );
$end_time = null;
if( $data['package_id']['duration'] > 0 ) {
$end_time = strtotime( '+' . $data['package_id']['duration'] . ' days', date( 'Y-m-d H:i:s', $start_time ) );
}
update_post_meta( $data['payment_id'], '_al_payment_package_time_start', $start_time );
update_post_meta( $data['payment_id'], '_al_payment_package_time_end', $end_time );
update_post_meta( $data['payment_id'], '_al_payment_package_status', 'active' );
update_post_meta( $data['payment_id'], '_al_payment_package_listings', $data['package_id']['listings'] );
update_post_meta( $data['payment_id'], '_al_payment_package_listings_used', '0' );
}
}
Solved. I used the Mollie Webhook to check the status of the payment: https://github.com/mollie/mollie-api-php/blob/master/examples/payments/webhook.php.

How to set Wooommerce default featured category images as product featured imaged based on category?

Im after some help, I want to be able to replace all my product featured images with the default product category image that I have set.
I have found a plug in that does the reverse however Im not sure what changes will need to be made to reverse it?
Would anyone be able to help?
The original plugin author said the below when I asked
'That should be possible, although I'm not aware of any links off the top of my head. A function called "woocommerce_template_loop_product_thumbnail" is hooked in the "woocommerce_before_shop_loop_item_title" action that you could remove and replace, similar to how my plugin works. The function essentially just calls the "woocommerce_get_product_thumbnail" function found here which looks simple enough to muck about with!'
namespace GazChap;
class WC_Category_Product_Thumbnails {
private $shuffle = true;
private $recurse_category_ids = true;
private $limit = 20; // number of most recent products to fetch when shuffle is true, lower means faster
/**
* WC_Category_Product_Thumbnails constructor.
* Sets a default limit (to -1, i.e. all posts) if none already set and then replaces WC actions with ours
*/
public function __construct() {
add_action( 'plugins_loaded', array( $this, 'replace_wc_actions' ) );
if ( !$this->limit ) $this->limit = -1;
}
/**
* Removes the action that puts the thumbnail before the subcategory title, and replaces it with our version
*/
public function replace_wc_actions() {
remove_action( 'woocommerce_before_subcategory_title', 'woocommerce_subcategory_thumbnail', 10 );
add_action( 'woocommerce_before_subcategory_title', array( $this, 'auto_subcategory_thumbnail' ) );
add_filter( 'woocommerce_get_sections_products', array( $this, 'add_setting_section' ) );
add_filter( 'woocommerce_get_settings_products', array( $this, 'add_settings_to_section' ), 10, 2 );
}
/**
* The function that does all the donkey work.
* #param \WP_Term $category - the category that we're dealing with
*/
public function auto_subcategory_thumbnail( $category ) {
// does this category already have a thumbnail defined? if so, use that instead
if ( get_term_meta( $category->term_id, 'thumbnail_id', true ) ) {
woocommerce_subcategory_thumbnail( $category );
return;
}
// get a list of category IDs inside this category (so we're fetching products from all subcategories, not just the top level one)
if ( $this->recurse_category_ids ) {
$category_ids = $this->get_sub_category_ids( $category );
} else {
$category_ids = array( $category->term_id );
}
$query_args = array(
'posts_per_page' => $this->shuffle ? $this->limit : 1,
'post_status' => 'publish',
'post_type' => 'product',
'meta_query' => array(
array(
'key' => '_thumbnail_id',
'value' => '',
'compare' => '!=',
),
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $category_ids,
'operator' => 'IN',
),
),
);
$products = get_posts( $query_args );
if ( $products ) {
$image_size = 'shop_thumbnail';
if ( get_option('gazchap-wc-category-product-thumbnails_category-size') ) {
$image_size = get_option('gazchap-wc-category-product-thumbnails_category-size');
}
echo get_the_post_thumbnail( $products[ array_rand( $products ) ]->ID, $image_size );
} else {
// show the default placeholder category image if there's no products inside this one
woocommerce_subcategory_thumbnail( $category );
}
}
/**
* Recursive function to fetch a list of child category IDs for the one passed
*
* #param \WP_Term $start - the category to start from
* #param array $results - this just stores the results as they're being built up
*
* #return array - an array of term IDs for each product_cat inside the original one
*/
private function get_sub_category_ids( $start, $results = array() ) {
if ( !is_array( $results ) ) $results = array();
$results[] = $start->term_id;
$cats = get_terms( array( 'taxonomy' => 'product_cat', 'hide_empty' => false, 'parent' => $start->term_id ) );
if ( is_array( $cats ) ) {
foreach( $cats as $cat ) {
$results = $this->get_sub_category_ids( $cat, $results );
}
}
return $results;
}
function add_setting_section( $sections ) {
$sections['gazchap-wc-category-thumbnails'] = __( 'Auto Category Thumbnails', 'gazchap-wc-category-product-thumbnails' );
return $sections;
}
function add_settings_to_section( $settings, $current_section ) {
/**
* Check the current section is what we want
**/
if ( $current_section == 'gazchap-wc-category-thumbnails' ) {
$new_settings = array();
// Add Title to the Settings
$new_settings[] = array( 'name' => __( 'Auto Category Thumbnails Settings', 'gazchap-wc-category-product-thumbnails' ), 'type' => 'title', 'desc' => __( 'The following options are used to configure GazChap\'s Auto Category Thumbnails', 'text-domain' ), 'id' => 'gazchap-wc-category-thumbnails' );
$temp = $this->_get_all_image_sizes();
$image_sizes = array();
foreach( $temp as $image_size => $image_spec_array ) {
$image_spec = "";
$image_spec .= ($image_spec_array['width'] > 0) ? $image_spec_array['width'] : 'auto';
$image_spec .= ' x ';
$image_spec .= ($image_spec_array['height'] > 0) ? $image_spec_array['height'] : 'auto';
if ( $image_spec_array['crop'] ) {
$image_spec .= ", cropped";
}
$image_sizes[ $image_size ] = $image_size . " (" . $image_spec . ")";
}
// Add first checkbox option
$new_settings[] = array(
'name' => __( 'Thumbnail Size', 'text-domain' ),
'desc_tip' => __( 'Choose the image size to use for the thumbnails', 'gazchap-wc-category-thumbnails' ),
'id' => 'gazchap-wc-category-product-thumbnails_category-size',
'type' => 'select',
'options' => $image_sizes,
'desc' => __( 'Choose the image size to use for the thumbnails', 'gazchap-wc-category-thumbnails' ),
);
$new_settings[] = array( 'type' => 'sectionend', 'id' => 'gazchap-wc-category-thumbnails' );
return $new_settings;
/**
* If not, return the standard settings
**/
} else {
return $settings;
}
}
private function _get_all_image_sizes() {
global $_wp_additional_image_sizes;
$default_image_sizes = get_intermediate_image_sizes();
foreach ( $default_image_sizes as $size ) {
$image_sizes[ $size ][ 'width' ] = intval( get_option( "{$size}_size_w" ) );
$image_sizes[ $size ][ 'height' ] = intval( get_option( "{$size}_size_h" ) );
$image_sizes[ $size ][ 'crop' ] = get_option( "{$size}_crop" ) ? get_option( "{$size}_crop" ) : false;
}
if ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) ) {
$image_sizes = array_merge( $image_sizes, $_wp_additional_image_sizes );
}
return $image_sizes;
}
}
new WC_Category_Product_Thumbnails();
If anyone can help it would be most appreciated or be able to provide another way how to achieve this!

Setting the product type as a variable subscription in WooCommerce

I'm learning Woocommerce and I've managed to create a product programmatically. Currently, the product is being set as a variable product image
However, this needs to be a variable subscription. How should I do so? Tried looking in the wc_product class etc... Even though that replacing:
$product = new WC_Product_Variable( $product_id );
with
$product = new WC_Subscription_Variable( $product_id );
would work... It didn't obviously... So I'll try looking for an answer, but maybe if you knew what to do, then that would be amazing :)
My code:
create_product_variation( array(
'author' => '', // optional
'title' => $oVehicle['koeretoej']['titel'],
'excerpt' => 'The product short description…',
'regular_price' => '0', // product regular price
'sale_price' => '', // product sale price (optional)
'stock' => '1', // Set a minimal stock quantity
'image_id' => '', // optional
'gallery_ids' => array(), // optional
'sku' => '', // optional
'tax_class' => '', // optional
'weight' => '', // optional
// For NEW attributes/values use NAMES (not slugs)
'attributes' => array(
'Perioder' => array( '1 Uge', '2 Uger', '3 Uger', '4 Uger', '2 Måneder',),
// 'Attribute 2' => array( 'Value 1', 'Value 2', 'Value 3' ),
),
) );
}
}
$response['existingvehicles'] = $existingvehicles;
$response['$iProductID'] = $product;
$response['vehicles'] = $vehicles;
$response['aVehicles'] = $_POST['aVehicles'];
$response['bSucces'] = true;
echo json_encode($response);
wp_die();
}
function save_product_attribute_from_name( $name, $label='', $set=true ){
if( ! function_exists ('get_attribute_id_from_name') ) return;
global $wpdb;
$label = $label == '' ? ucfirst($name) : $label;
$attribute_id = get_attribute_id_from_name( $name );
if( empty($attribute_id) ){
$attribute_id = NULL;
} else {
$set = false;
}
$args = array(
'attribute_id' => $attribute_id,
'attribute_name' => $name,
'attribute_label' => $label,
'attribute_type' => 'select',
'attribute_orderby' => 'menu_order',
'attribute_public' => 0,
);
if( empty($attribute_id) ) {
$wpdb->insert( "{$wpdb->prefix}woocommerce_attribute_taxonomies", $args );
set_transient( 'wc_attribute_taxonomies', false );
}
if( $set ){
$attributes = wc_get_attribute_taxonomies();
$args['attribute_id'] = get_attribute_id_from_name( $name );
$attributes[] = (object) $args;
//print_r($attributes);
set_transient( 'wc_attribute_taxonomies', $attributes );
} else {
return;
}
}
/**
* Get the product attribute ID from the name.
*
* #since 3.0.0
* #param string $name | The name (slug).
*/
function get_attribute_id_from_name( $name ){
global $wpdb;
$attribute_id = $wpdb->get_col("SELECT attribute_id
FROM {$wpdb->prefix}woocommerce_attribute_taxonomies
WHERE attribute_name LIKE '$name'");
return reset($attribute_id);
}
/**
* Create a new variable product (with new attributes if they are).
* (Needed functions:
*
* #since 3.0.0
* #param array $data | The data to insert in the product.
*/
function create_product_variation( $data ){
if( ! function_exists ('save_product_attribute_from_name') ) return;
$postname = sanitize_title( $data['title'] );
$author = empty( $data['author'] ) ? '1' : $data['author'];
$post_data = array(
'post_author' => $author,
'post_name' => $postname,
'post_title' => $data['title'],
'post_content' => $data['content'],
'post_excerpt' => $data['excerpt'],
'post_status' => 'publish',
'ping_status' => 'closed',
'post_type' => 'product',
'guid' => home_url( '/product/'.$postname.'/' ),
);
// Creating the product (post data)
$product_id = wp_insert_post( $post_data );
// Get an instance of the WC_Product_Variable object and save it
$product = new WC_Product_Variable( $product_id );
$product->save();
## ---------------------- Other optional data ---------------------- ##
## (see WC_Product and WC_Product_Variable setters methods)
// THE PRICES (No prices yet as we need to create product variations)
// IMAGES GALLERY
if( ! empty( $data['gallery_ids'] ) && count( $data['gallery_ids'] ) > 0 )
$product->set_gallery_image_ids( $data['gallery_ids'] );
// SKU
if( ! empty( $data['sku'] ) )
$product->set_sku( $data['sku'] );
// STOCK (stock will be managed in variations)
$product->set_stock_quantity( $data['stock'] ); // Set a minimal stock quantity
$product->set_manage_stock(true);
$product->set_stock_status('');
// Tax class
if( empty( $data['tax_class'] ) )
$product->set_tax_class( $data['tax_class'] );
// WEIGHT
if( ! empty($data['weight']) )
$product->set_weight(''); // weight (reseting)
else
$product->set_weight($data['weight']);
$product->validate_props(); // Check validation
## ---------------------- VARIATION ATTRIBUTES ---------------------- ##
$product_attributes = array();
foreach( $data['attributes'] as $key => $terms ){
$taxonomy = wc_attribute_taxonomy_name($key); // The taxonomy slug
$attr_label = ucfirst($key); // attribute label name
$attr_name = ( wc_sanitize_taxonomy_name($key)); // attribute slug
// NEW Attributes: Register and save them
if( ! taxonomy_exists( $taxonomy ) )
save_product_attribute_from_name( $attr_name, $attr_label );
$product_attributes[$taxonomy] = array (
'name' => $taxonomy,
'value' => '',
'position' => '',
'is_visible' => 1,
'is_variation' => 1,
'is_taxonomy' => 1
);
foreach( $terms as $value ){
$term_name = ucfirst($value);
$term_slug = sanitize_title($value);
// Check if the Term name exist and if not we create it.
if( ! term_exists( $value, $taxonomy ) )
wp_insert_term( $term_name, $taxonomy, array('slug' => $term_slug ) ); // Create the term
// Set attribute values
wp_set_post_terms( $product_id, $term_name, $taxonomy, true );
}
}
update_post_meta( $product_id, '_product_attributes', $product_attributes );
// $product->set_attributes(array( $taxonomy => $terms[0] ));
$product->save(); // Save the data
}
Replacing this:
$product = new WC_Product_Variable( $product_id );
with this
$product = new WC_Product_Variable_Subscription( $product_id );
did the job

Force a shipping method when a valid coupon is applied in Woocommerce

Using Woocommerce, I want to force a shipping method when a certain valid coupon is applied at the cart/checkout phase.
Below my code. It extends WC_Shipping_Method, gets the whole woocommerce coupon list, let admin to select one or more, save them and then, when a costumer applies one of those chosen coupons checking out, forces to use only one this shipping method.
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
/* Custom LocalPickup Class */
class WC_Shipping_LocalPickUp_On_Coupon extends WC_Shipping_Method {
public $requires = '';
public function __construct( $instance_id = 0 ) {
$this->id = 'localpickup_on_coupon';
$this->instance_id = absint( $instance_id );
$this->method_title = __( 'Pickup with Coupon', 'Valeo' );
$this->method_description = __( 'Pickup with Coupon', 'Valeo' );
$this->supports = array(
'shipping-zones',
'instance-settings',
'instance-settings-modal',
);
/*Getting Coupon List */
$args = array(
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'asc',
'post_type' => 'shop_coupon',
'post_status' => 'publish',
);
$coupons = get_posts( $args );
$this->list = [];
foreach($coupons as $item){
$this->list[$item->post_name] = $item->post_title;
}
$this->init();
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
public function init() {
$this->init_form_fields();
$this->init_settings();
$this->title = $this->get_option( 'title' );
$this->requires = $this->get_option( 'requires' );
}
public function init_form_fields() {
$this->instance_form_fields = array(
'title' => array(
'title' => __( 'Title', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
'default' => $this->method_title,
'desc_tip' => true,
),
'requires' => array(
'title' => __( 'Il ritiro in sede richiede...', 'Valeo' ),
'type' => 'multiselect',
'class' => 'valeo_multiselect',
'default' => '',
'options' => $this->list
),
);
}
public function is_available( $package ) {
$has_coupon = false;
$coupons = WC()->cart->get_coupons();
if(!empty($coupons)) {
$couponKey = array_keys($coupons)[0];
if ( in_array( $couponKey, $this->requires ) ) {
if ( $coupons ) {
foreach ( $coupons as $code => $coupon ) {
if ( $coupon->is_valid() ) {
$has_coupon = true;
break;
}
}
}
}
}
return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', $has_coupon, $package, $this );
}
public function calculate_shipping( $package = array() ) {
$rate = array(
'id' => $this->get_rate_id(),
'label' => $this->title,
'cost' => 0,
'taxes' => 0,
'package' => $package,
);
$this->add_rate($rate);
do_action( 'woocommerce_' . $this->id . '_shipping_add_rate', $this, $rate );
}
}
add_filter( 'woocommerce_shipping_methods', 'register_devso_method' );
function register_devso_method( $methods ) {
$methods[ 'localpickup_on_coupon' ] = 'WC_Shipping_LocalPickUp_On_Coupon';
return $methods;
}
}
Here the filter that checks if customer has inserted the chosen coupon/s and (in a "bad" way) removes all woocommerce package rates but the one I declared in the class.
function filter_woocommerce_package_rates( $array ) {
$check = FALSE;
foreach($array as $index => $value){
if(strpos($index, 'localpickup_on_coupon') !== false) { $check = TRUE; }
}
if($check){
foreach($array as $index => $value){
if(!(strpos($index, 'localpickup_on_coupon') !== false)) { unset($array[$index]); }
}
}
return $array;
};
// add the filter
add_filter( 'woocommerce_package_rates', 'filter_woocommerce_package_rates', 10, 1 );
Is there a better way to do this?

Categories