Files

225 lines
5.4 KiB
PHP
Raw Permalink Normal View History

<?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 (john@example.com)
* 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' )
);
}
}