Skip to content

Instantly share code, notes, and snippets.

@stracker-phil
Last active October 21, 2022 11:12

Revisions

  1. stracker-phil revised this gist Oct 21, 2022. 1 changed file with 54 additions and 39 deletions.
    93 changes: 54 additions & 39 deletions edd-generate-discount.php
    Original file line number Diff line number Diff line change
    @@ -42,45 +42,8 @@ function generate_discount(
    $exp_date = '';
    }

    $pattern = preg_replace( '/[^a-zA-Z0-9_\-.*#+^?]/', '*', $pattern );
    if ( strlen( $pattern ) < 6 ) {
    $pattern = substr( $pattern . '******', 0, 6 );
    }

    $pattern_len = strlen( $pattern );
    $num_chars = '0123456789';
    $lower_chars = 'abcdefghijklmnopqrstuvwxyz';
    $upper_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $letter_chars = $lower_chars . $upper_chars;
    $hex_chars = 'ABCDEF0123456789';
    $all_chars = $num_chars . $upper_chars;

    do {
    $coupon_code = '';
    for ( $i = 0; $i < $pattern_len; $i ++ ) {
    $char = $pattern[ $i ];

    if ( '*' === $char ) {
    $pool = $all_chars;
    } elseif ( '^' === $char ) {
    $pool = $hex_chars;
    } elseif ( '?' === $char ) {
    $pool = $letter_chars;
    } elseif ( '.' === $char ) {
    $pool = $lower_chars;
    } elseif ( '#' === $char ) {
    $pool = $upper_chars;
    } elseif ( '+' === $char ) {
    $pool = $num_chars;
    } else {
    $pool = false;
    }

    if ( $pool ) {
    $char = $pool[ wp_rand( 0, strlen( $pool ) - 1 ) ];
    }
    $coupon_code .= $char;
    }
    $coupon_code = generate_coupon_code( $pattern );

    $exists = edd_get_discount_by_code( $coupon_code );
    } while ( $exists );
    @@ -127,4 +90,56 @@ function generate_discount(
    edd_store_discount( $meta );

    return $coupon_code;
    }
    }


    /**
    * Generates a random coupon code.
    *
    * @param string $pattern The pattern - @see generate_discount() for details.
    * @param int $min_length Minimum length of the code.
    *
    * @return string The random coupon code.
    */
    function generate_coupon_code( $pattern, $min_length = 6 ) {
    $pattern = preg_replace( '/[^a-zA-Z0-9_\-.*#+^?]/', '*', $pattern );
    while ( strlen( $pattern ) < 6 ) {
    $pattern .= '*';
    }

    $pattern_len = strlen( $pattern );
    $num_chars = '0123456789';
    $lower_chars = 'abcdefghijklmnopqrstuvwxyz';
    $upper_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $letter_chars = $lower_chars . $upper_chars;
    $hex_chars = 'ABCDEF0123456789';
    $all_chars = $num_chars . $upper_chars;

    $coupon_code = '';
    for ( $i = 0; $i < $pattern_len; $i ++ ) {
    $char = $pattern[ $i ];

    if ( '*' === $char ) {
    $pool = $all_chars;
    } elseif ( '^' === $char ) {
    $pool = $hex_chars;
    } elseif ( '?' === $char ) {
    $pool = $letter_chars;
    } elseif ( '.' === $char ) {
    $pool = $lower_chars;
    } elseif ( '#' === $char ) {
    $pool = $upper_chars;
    } elseif ( '+' === $char ) {
    $pool = $num_chars;
    } else {
    $pool = false;
    }

    if ( $pool ) {
    $char = $pool[ wp_rand( 0, strlen( $pool ) - 1 ) ];
    }
    $coupon_code .= $char;
    }

    return $coupon_code;
    }
  2. stracker-phil created this gist Oct 21, 2022.
    130 changes: 130 additions & 0 deletions edd-generate-discount.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,130 @@
    <?php
    /**
    * Generate a random discount code that matches the given criteria.
    *
    * Samples:
    * - generate_discount( 10, 'percent', '+7days', 'HI-^^^^' );
    * - generate_discount( 5, 'flat', '', '********' );
    *
    * @param int $amount The discount code value.
    * @param string $type The type, either [flat|percent].
    * @param string $expires A (relative) date string like "+7days", or empty for
    * no expiration.
    * @param string $pattern A string that describes the length/pattern of the code.
    * "*" is replaced with a random uppercase letter or digit.
    * "?" is replaced with a random uppercase/lowercase letter.
    * "." is replaced with a random lowercase letter.
    * "#" is replaced with a random uppercase letter.
    * "^" is replaced with a random uppercase hexadecimal digit.
    * "+" is replaced with a random digit.
    * @param string $name Optional, internal coupon name.
    *
    * @return string The newly generated code.
    */
    function generate_discount(
    int $amount = 10,
    string $type = 'flat',
    string $expires = '',
    string $pattern = '^^^^-^^^^',
    string $name = ''
    ) : string {
    if ( ! is_callable( 'edd_store_discount' ) ) {
    return '';
    }

    if ( $expires ) {
    if ( is_numeric( $expires ) ) {
    $exp_date = gmdate( 'm/d/Y', $expires );
    } else {
    $exp_date = gmdate( 'm/d/Y', strtotime( $expires ) );
    }
    } else {
    $exp_date = '';
    }

    $pattern = preg_replace( '/[^a-zA-Z0-9_\-.*#+^?]/', '*', $pattern );
    if ( strlen( $pattern ) < 6 ) {
    $pattern = substr( $pattern . '******', 0, 6 );
    }

    $pattern_len = strlen( $pattern );
    $num_chars = '0123456789';
    $lower_chars = 'abcdefghijklmnopqrstuvwxyz';
    $upper_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $letter_chars = $lower_chars . $upper_chars;
    $hex_chars = 'ABCDEF0123456789';
    $all_chars = $num_chars . $upper_chars;

    do {
    $coupon_code = '';
    for ( $i = 0; $i < $pattern_len; $i ++ ) {
    $char = $pattern[ $i ];

    if ( '*' === $char ) {
    $pool = $all_chars;
    } elseif ( '^' === $char ) {
    $pool = $hex_chars;
    } elseif ( '?' === $char ) {
    $pool = $letter_chars;
    } elseif ( '.' === $char ) {
    $pool = $lower_chars;
    } elseif ( '#' === $char ) {
    $pool = $upper_chars;
    } elseif ( '+' === $char ) {
    $pool = $num_chars;
    } else {
    $pool = false;
    }

    if ( $pool ) {
    $char = $pool[ wp_rand( 0, strlen( $pool ) - 1 ) ];
    }
    $coupon_code .= $char;
    }

    $exists = edd_get_discount_by_code( $coupon_code );
    } while ( $exists );

    $meta = [
    'name' => $name ? $name : $coupon_code,
    'code' => $coupon_code,
    'type' => $type,
    'amount' => $amount,
    'excluded_products' => [],
    'expiration' => $exp_date,
    'is_not_global' => false,
    'is_single_use' => true,
    'max_uses' => '1',
    'min_price' => '',
    'product_condition' => '',
    'product_reqs' => [],
    'start' => '',
    'uses' => '',
    ];

    // EDD will set its own defaults in the edd_store_discount() so let's filter out
    // empty defaults. We just keep them 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 = [
    '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 = $edd_post_keys[ $key ];

    if ( $mod_key ) {
    $meta[ $mod_key ] = $value;
    }
    }

    edd_store_discount( $meta );

    return $coupon_code;
    }