Last active
February 17, 2024 22:58
-
-
Save devinsays/9e6030dec131366d2eadca4174f82d57 to your computer and use it in GitHub Desktop.
WP CLI script for generating coupon copies
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Generate coupon copies from an existing coupon. | |
* Replaces UNQCODE with a unique generated coupon code. | |
* | |
* For more information about this script: | |
* https://devpress.com/wp-cli-script-to-duplicate-woocommerce-coupons/ | |
* | |
* wp eval-file coupon-generator.php | |
*/ | |
// Quick explainer of script. | |
WP_CLI::log( "\nThis script generates copies of an existing coupon code." ); | |
WP_CLI::log( "If 'UNQCODE' is in the coupon code, it will be replaced with a unique code.\n" ); | |
$code = devpress_ask( 'Coupon code to duplicate:' ); | |
// Get the coupon ID to copy. | |
$coupon_id = wc_get_coupon_id_by_code( $code ); | |
if ( ! $coupon_id ) { | |
WP_CLI::error( 'Coupon code not found.' ); | |
exit; | |
} | |
WP_CLI::success( "Coupon ID $coupon_id found." ); | |
// Get number of coupons to generate. | |
WP_CLI::log( '' ); | |
$count = (int) devpress_ask( 'How coupons would you like to generate:' ); | |
if ( ! $count || $count < 1 ) { | |
WP_CLI::error( 'Must enter a number value 1 or higher.' ); | |
exit; | |
} | |
WP_CLI::log( '' ); | |
if ( $count > 100 ) { | |
WP_CLI::log( '' ); | |
WP_CLI::confirm( "Are you sure you want to generate $count coupons?" ); | |
} | |
// Log file to write to. | |
$log_file = $code . '-generated-' . current_time( 'timestamp' ) . '.csv'; | |
// Output for CLI table. | |
$output = []; | |
for ( $i = 1; $i <= $count; $i++ ) { | |
$duplicate = devpress_generate_duplicate_coupon( $coupon_id ); | |
if ( ! $duplicate ) { | |
WP_CLI::error( "Coupon $i of $count failed to generate." ); | |
exit; | |
} | |
WP_CLI::success( "$i/$count: {$duplicate->get_code()}" ); | |
$url = get_site_url() . '/' . $duplicate->get_meta( '_wc_url_coupons_unique_url' ); | |
$output[] = [ | |
'code' => $duplicate->get_code(), | |
'url' => $url, | |
]; | |
devpress_write_file( | |
$log_file, | |
[ $duplicate->get_code(), $url ] | |
); | |
} | |
// Output table of all generated coupons. | |
WP_CLI::log( '' ); | |
WP_CLI\Utils\format_items( 'table', $output, [ 'code', 'url' ] ); | |
WP_CLI::log( '' ); | |
WP_CLI::success( "$count coupons generated." ); | |
WP_CLI::log( "Log file: $log_file" ); | |
WP_CLI::log( '' ); | |
/** | |
* Generates a duplicate coupon. | |
* | |
* Based on `product_duplicate` in: | |
* woocommerce/includes/admin/class-wc-admin-duplicate-product.php | |
* | |
* @param int $id Original coupon ID. | |
* @return WC_Coupon $duplicate New coupon object. | |
*/ | |
function devpress_generate_duplicate_coupon( $id ) { | |
$original = new WC_Coupon( $id ); | |
$duplicate = clone $original; | |
// Reset ID and date properties. | |
$duplicate->set_id( 0 ); | |
$duplicate->set_date_created( null ); | |
// Updates the coupon code. | |
$code = $original->get_code(); | |
$generated_key = devpress_generate_unique_coupon_key( $code ); | |
$new_code = $generated_key; | |
if ( stripos( $code, 'UNQCODE' ) !== false ) { | |
$new_code = str_ireplace( 'UNQCODE', $generated_key, $code ); | |
} | |
$duplicate->set_code( $new_code ); | |
// Replace URL. | |
$url_meta_key = '_wc_url_coupons_unique_url'; | |
$url = $original->get_meta( $url_meta_key ); | |
if ( stripos( $url, 'UNQCODE' ) !== false ) { | |
// Assume code in the URL is the same pattern. | |
$new_url = str_ireplace( 'UNQCODE', $generated_key, $url ); | |
$duplicate->update_meta_data( $url_meta_key, $new_url ); | |
} | |
$duplicate->save(); | |
// Update the active coupons option, hook into \WC_URL_Coupons. | |
if ( class_exists( 'WC_URL_Coupons' ) ) { | |
$options = [ | |
'coupon_id' => $duplicate->get_id(), | |
'unique_url' => $duplicate->get_meta( $url_meta_key ), | |
'url_prefix' => '', | |
'redirect_page' => $duplicate->get_meta( '_wc_url_coupons_redirect_page' ), | |
'redirect_page_type' => $duplicate->get_meta( '_wc_url_coupons_redirect_page_type' ), | |
'product_ids' => $duplicate->get_meta( '_wc_url_coupons_product_ids' ), | |
'defer_apply' => $duplicate->get_meta( '_wc_url_coupons_defer_apply' ), | |
]; | |
$coupons_admin = \WC_URL_Coupons::instance()->get_admin_instance(); | |
$coupons_admin->update_coupons( $options ); | |
} | |
return $duplicate; | |
} | |
/** | |
* Generates a unique coupon code. | |
* | |
* @param string $code Existing coupon code. | |
* @return string $generated_key | |
*/ | |
function devpress_generate_unique_coupon_key( $code ) { | |
// Loops until a unique coupon code is generated. | |
while ( true ) { | |
$generated_key = devpress_generate_coupon_key(); | |
$new_code = $generated_key; | |
if ( stripos( $code, 'UNQCODE' ) !== false ) { | |
$new_code = str_ireplace( 'UNQCODE', $generated_key, $code ); | |
} | |
// Check if code already exists before returning. | |
$coupon_id = wc_get_coupon_id_by_code( $new_code ); | |
if ( ! $coupon_id ) { | |
return $generated_key; | |
} | |
} | |
} | |
/** | |
* Generates a random key string for unique coupons. | |
* | |
* Doesn't use ambiguous characters like: 0 o i l 1. | |
* | |
* @param int $length | |
* @return string | |
*/ | |
function devpress_generate_coupon_key( $length = 7 ) { | |
$chars = 'abcdefghjkmnpqrstuvwxyz23456789'; | |
$coupon_key = ''; | |
$chars_length = strlen( $chars ); | |
for ( $i = 0; $i < $length; $i++ ) { | |
$coupon_key .= substr( $chars, wp_rand( 0, $chars_length - 1 ), 1 ); | |
} | |
return $coupon_key; | |
} | |
/** | |
* Ask a question and returns the user's input. | |
* | |
* @param string $question | |
* @param bool $case_sensitive | |
* | |
* @return string | |
*/ | |
function devpress_ask( $question, $case_sensitive = false ) { | |
fwrite( STDOUT, trim( $question ) . ' ' ); | |
$answer = trim( fgets( STDIN ) ); | |
$answer = $case_sensitive ? $answer : strtolower( $answer ); | |
return $answer; | |
} | |
/** | |
* Writes output to a csv file. | |
* | |
* @param string $file_name | |
* @param array $output | |
*/ | |
function devpress_write_file( $file_name, $output ) { | |
$file_resource = fopen( $file_name, 'a' ); | |
fputcsv( $file_resource, $output ); | |
fclose( $file_resource ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment