225 lines
5.4 KiB
PHP
225 lines
5.4 KiB
PHP
<?php
|
||
/**
|
||
* Utility functions.
|
||
*
|
||
* @package WC_Email_Discount_Manager
|
||
*/
|
||
|
||
if ( ! defined( 'ABSPATH' ) ) {
|
||
exit;
|
||
}
|
||
|
||
/**
|
||
* Static helper methods shared between admin and frontend.
|
||
*/
|
||
class WC_EDM_Helpers {
|
||
|
||
/**
|
||
* Find the best matching email assignment for an email address.
|
||
*
|
||
* Match priority:
|
||
* 1. Exact email match ([email protected])
|
||
* 2. Domain match (@company.com)
|
||
* 3. Partial match (john)
|
||
*
|
||
* @param string $email Email address.
|
||
* @return object|null Matching row from the emails table, or null.
|
||
*/
|
||
public static function find_email_match( $email ) {
|
||
$email = strtolower( trim( (string) $email ) );
|
||
|
||
if ( '' === $email || ! is_email( $email ) ) {
|
||
return null;
|
||
}
|
||
|
||
$assignments = WC_EDM_DB::get_active_emails();
|
||
|
||
if ( empty( $assignments ) ) {
|
||
return null;
|
||
}
|
||
|
||
$domain_match = null;
|
||
$partial_match = null;
|
||
|
||
foreach ( $assignments as $assignment ) {
|
||
$pattern = strtolower( trim( $assignment->email_pattern ) );
|
||
|
||
if ( '' === $pattern ) {
|
||
continue;
|
||
}
|
||
|
||
// 1. Exact match wins immediately.
|
||
if ( $pattern === $email ) {
|
||
return $assignment;
|
||
}
|
||
|
||
// 2. Domain match: pattern starts with '@'.
|
||
if ( null === $domain_match && 0 === strpos( $pattern, '@' ) ) {
|
||
if ( substr( $email, -strlen( $pattern ) ) === $pattern ) {
|
||
$domain_match = $assignment;
|
||
}
|
||
continue;
|
||
}
|
||
|
||
// 3. Partial match: pattern occurs anywhere in the email.
|
||
if ( null === $partial_match && false === strpos( $pattern, '@' ) && false !== strpos( $email, $pattern ) ) {
|
||
$partial_match = $assignment;
|
||
}
|
||
}
|
||
|
||
if ( $domain_match ) {
|
||
return $domain_match;
|
||
}
|
||
|
||
return $partial_match;
|
||
}
|
||
|
||
/**
|
||
* Get all product categories.
|
||
*
|
||
* @return WP_Term[]
|
||
*/
|
||
public static function get_product_categories() {
|
||
$terms = get_terms(
|
||
array(
|
||
'taxonomy' => 'product_cat',
|
||
'hide_empty' => false,
|
||
'orderby' => 'name',
|
||
'order' => 'ASC',
|
||
)
|
||
);
|
||
|
||
return is_wp_error( $terms ) ? array() : $terms;
|
||
}
|
||
|
||
/**
|
||
* Get every shipping method instance across all zones (including "Rest of the world").
|
||
*
|
||
* @return array Map of method key ("flat_rate:3") => array{ label, zone, method }.
|
||
*/
|
||
public static function get_all_shipping_methods() {
|
||
$methods = array();
|
||
|
||
if ( ! class_exists( 'WC_Shipping_Zones' ) ) {
|
||
return $methods;
|
||
}
|
||
|
||
$zones = WC_Shipping_Zones::get_zones();
|
||
|
||
// Zone 0 = "Locations not covered by your other zones".
|
||
$rest_of_world = new WC_Shipping_Zone( 0 );
|
||
$zones[] = array(
|
||
'zone_name' => $rest_of_world->get_zone_name(),
|
||
'shipping_methods' => $rest_of_world->get_shipping_methods(),
|
||
);
|
||
|
||
foreach ( $zones as $zone ) {
|
||
$zone_name = $zone['zone_name'];
|
||
|
||
foreach ( $zone['shipping_methods'] as $method ) {
|
||
$key = $method->id . ':' . $method->get_instance_id();
|
||
|
||
$methods[ $key ] = array(
|
||
'key' => $key,
|
||
'label' => $method->get_title(),
|
||
'zone' => $zone_name,
|
||
'method' => $method->id,
|
||
);
|
||
}
|
||
}
|
||
|
||
return $methods;
|
||
}
|
||
|
||
/**
|
||
* Get all published WooCommerce coupon codes.
|
||
*
|
||
* @return string[]
|
||
*/
|
||
public static function get_coupon_codes() {
|
||
$posts = get_posts(
|
||
array(
|
||
'post_type' => 'shop_coupon',
|
||
'post_status' => 'publish',
|
||
'posts_per_page' => 500,
|
||
'orderby' => 'title',
|
||
'order' => 'ASC',
|
||
)
|
||
);
|
||
|
||
$codes = array();
|
||
|
||
foreach ( $posts as $post ) {
|
||
$codes[] = wc_format_coupon_code( $post->post_title );
|
||
}
|
||
|
||
return array_values( array_unique( $codes ) );
|
||
}
|
||
|
||
/**
|
||
* Get a human-readable description of an email assignment's target.
|
||
*
|
||
* @param object $assignment Row from the emails table.
|
||
* @return string
|
||
*/
|
||
public static function describe_assignment( $assignment ) {
|
||
$extra = ! empty( $assignment->free_shipping )
|
||
? ' + ' . __( 'free shipping', 'wc-email-discount' )
|
||
: '';
|
||
|
||
return self::describe_assignment_type( $assignment ) . $extra;
|
||
}
|
||
|
||
/**
|
||
* Describe the discount part of an assignment (without extras).
|
||
*
|
||
* @param object $assignment Row from the emails table.
|
||
* @return string
|
||
*/
|
||
private static function describe_assignment_type( $assignment ) {
|
||
switch ( $assignment->assignment_type ) {
|
||
case 'group':
|
||
$group = $assignment->group_id ? WC_EDM_DB::get_group( (int) $assignment->group_id ) : null;
|
||
if ( $group ) {
|
||
/* translators: 1: group name, 2: discount percent */
|
||
return sprintf( __( '%1$s (%2$s%%)', 'wc-email-discount' ), $group->name, wc_format_localized_decimal( $group->discount_percent ) );
|
||
}
|
||
return __( 'Group missing', 'wc-email-discount' );
|
||
|
||
case 'coupon':
|
||
/* translators: %s: coupon code */
|
||
return sprintf( __( 'Coupon: %s', 'wc-email-discount' ), $assignment->coupon_code );
|
||
|
||
case 'custom':
|
||
/* translators: %s: discount percent */
|
||
return sprintf( __( '%s%% off entire cart', 'wc-email-discount' ), wc_format_localized_decimal( $assignment->custom_discount ) );
|
||
}
|
||
|
||
return '';
|
||
}
|
||
|
||
/**
|
||
* Sanitize a discount percent value into the 0–100 range.
|
||
*
|
||
* @param mixed $value Raw value.
|
||
* @return float
|
||
*/
|
||
public static function sanitize_percent( $value ) {
|
||
$value = (float) wc_format_decimal( wp_unslash( $value ) );
|
||
return max( 0, min( 100, $value ) );
|
||
}
|
||
|
||
/**
|
||
* Build an admin URL for the plugin page.
|
||
*
|
||
* @param array $args Extra query args (tab, action, id, ...).
|
||
* @return string
|
||
*/
|
||
public static function admin_url( $args = array() ) {
|
||
return add_query_arg(
|
||
array_merge( array( 'page' => 'wc-email-discounts' ), $args ),
|
||
admin_url( 'admin.php' )
|
||
);
|
||
}
|
||
}
|