Files
nolimit-discounts/includes/class-helpers.php
T

225 lines
5.4 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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' )
);
}
}