| 开发者 | easymailing |
|---|---|
| 更新时间 | 2026年6月1日 15:54 |
| 捐献地址: | 去捐款 |
| PHP版本: | 7.1 及以上 |
| WordPress版本: | 7.0 |
| 版权: | GPL 2+ |
| 版权网址: | 版权信息 |
Easymailing is an email marketing platform. You can create and send email newsletters, manage subscribers, and track and analyze results.
You can get help at https://ayuda.easymailing.com.
phone, first_name, and last_name in addition to email, and contacts can be created when at least an email or phone is available.billing_phone when it can be normalized to E.164 using the billing country or a single-country store fallback.TypeError in Api::convertEurToCents() when a product or variation reaches the helper with an empty/non-numeric price (e.g. a simple product without regular_price on save). Under PHP 8+ the previous $eur * 100 raised Unsupported operand types: string * int and put the site into recovery mode. The helper now guards with is_numeric() and casts to float, returning 0 for invalid inputs.CartHooks::getCartItems() to cast $product->get_price() to float before multiplying by the cart item quantity, so an empty price string no longer triggers the same TypeError before reaching convertEurToCents(). Removed the redundant outer intval() since the helper already returns int.SESSION_CART_CUSTOMER_RESOURCE_ID_NAME); on customer mismatch (typical email-change scenario) the previous order_resource_id is discarded so a brand-new cart is created instead of mutating the previous one.input event with debounce removed); it now only fires on change and blur, so a single typed email produces a single AJAX call instead of one per substring (a@b.c, a@b.co, a@b.com...).CartHooks::ajaxTrackCheckoutEmail. Concurrent requests with the same email could read an empty session simultaneously and each create a new cart in Easymailing, leading to duplicated automation entries. A transient-based lock (10s TTL, keyed by email) now serializes parallel requests; only the first creates/updates the cart, the rest return skipped=lock_held.!is_user_logged_in() guard in CartHooks has been removed. Carts are now associated to the Easymailing customer resolved by email (looked up or created on the fly) as soon as an email is available.woocommerce_store_api_cart_update_customer_from_request is now listened to. Block Checkout fires this on every billing field change (including email) after a ~1s debounce, so the Easymailing cart is created as soon as the shopper enters a valid email, without having to wait for country/postcode to be filled in.woocommerce_store_api_checkout_update_order_from_request is also listened to as a secondary trigger, firing on every update of the draft order (wc-checkout-draft) once country/postcode are known, so later address edits keep the Easymailing cart in sync.woocommerce_checkout_update_order_review is now listened to for guest tracking on the Classic Checkout, so entering an email in the form creates the Easymailing cart even before the shopper places the order.CustomerService::resolveByEmail() that looks up a customer in Easymailing by email and creates one if it doesn't exist, used by both the new Block and Classic guest flows.checkout_url sent to Easymailing now embeds the cart contents as a base64 query parameter. When the shopper clicks the recovery link from the abandoned cart email, the new CartRebuildHook decodes the products and re-adds them to the WooCommerce cart, redirecting to the checkout — even from a different device or after the session expired. Preserves em_ch for campaign attribution.easymailing_checkout_script.js (loaded only on checkout pages) observes the email input in both Classic and Block Checkout with a single selector (input[name="billing_email"], #billing_email, .wc-block-components-text-input > #email) and hits admin-ajax.php?action=easymailing_track_checkout_email on change/blur. This captures the email on the first tab-out of the field, without waiting for the Block Checkout internal debounce. Complements the PHP Store API hooks, doesn't replace them.woocommerce_register_additional_checkout_field, available since WC 8.9). The same checkboxes that were rendered on the Classic Checkout via the woocommerce_checkout_fields filter now also appear on the Block Checkout in the "Contact" group, and are persisted into the order/user meta using the existing format so the rest of the plugin (OrderHooks, CustomerService) reads them unchanged.