diff options
| author | Murilo Ijanc <[email protected]> | 2026-07-26 16:41:48 -0300 |
|---|---|---|
| committer | Murilo Ijanc <[email protected]> | 2026-07-26 16:47:14 -0300 |
| commit | 535dbda6b48171f8115b455e54790de94d97d42a (patch) | |
| tree | 5c0410011e61a883bdf063ee612875a637fb1d22 /includes/class-cepis-woo-assets.php | |
| download | woocommerce-0.1.0.tar.gz | |
Initial importv0.1.0
Diffstat (limited to 'includes/class-cepis-woo-assets.php')
| -rw-r--r-- | includes/class-cepis-woo-assets.php | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/includes/class-cepis-woo-assets.php b/includes/class-cepis-woo-assets.php new file mode 100644 index 0000000..def6fe2 --- /dev/null +++ b/includes/class-cepis-woo-assets.php @@ -0,0 +1,183 @@ +<?php +/** + * What gets loaded on the checkout page, and with what configuration. + * + * @package CepisWooCommerce + */ + +declare(strict_types=1); + +defined( 'ABSPATH' ) || exit; + +/** + * Detects which of WooCommerce's two checkouts is on screen and loads the + * matching integration. + * + * They are not variations of one another. The classic checkout is a server + * rendered form, so the widget can own the fields directly. The Cart/Checkout + * Blocks are React, the fields are controlled inputs, and writing to them from + * outside is at best ignored on the next render — so there the plugin never + * touches the DOM and drives the `wc/store/cart` data store instead. + */ +final class Cepis_Woo_Assets { + + /** + * Script handle for the vendored widget. + */ + private const WIDGET = 'cepis-autofill'; + + /** + * Hook the enqueue. + */ + public static function init(): void { + add_action( 'wp_enqueue_scripts', array( self::class, 'enqueue' ) ); + } + + /** + * Load the widget plus whichever integration this checkout needs. + */ + public static function enqueue(): void { + $checkout = self::checkout_type(); + + if ( '' === $checkout || ! Cepis_Woo_Options::enabled() ) { + return; + } + + wp_register_script( + self::WIDGET, + CEPIS_WOO_URL . 'assets/js/cepis-autofill.min.js', + array(), + CEPIS_WOO_VERSION, + true + ); + + $handle = 'cepis-woocommerce-' . $checkout; + $dependencies = 'blocks' === $checkout + ? array( self::WIDGET, 'wp-data', 'wc-blocks-data-store' ) + : array( self::WIDGET, 'jquery' ); + + wp_enqueue_script( + $handle, + CEPIS_WOO_URL . 'assets/js/cepis-woocommerce-' . $checkout . '.js', + $dependencies, + CEPIS_WOO_VERSION, + true + ); + + wp_add_inline_script( + $handle, + 'window.cepisWooCommerce = ' . wp_json_encode( self::config( $checkout ), JSON_HEX_TAG | JSON_HEX_AMP ) . ';', + 'before' + ); + } + + /** + * Which checkout is being rendered. + * + * @return string `blocks`, `classic`, or an empty string when this is not a + * checkout the plugin should touch. + */ + private static function checkout_type(): string { + if ( ! function_exists( 'is_checkout' ) || ! is_checkout() ) { + return ''; + } + + if ( function_exists( 'is_order_received_page' ) && is_order_received_page() ) { + return ''; + } + + $post = get_post(); + + return ( $post instanceof WP_Post && has_block( 'woocommerce/checkout', $post ) ) ? 'blocks' : 'classic'; + } + + /** + * Everything the browser needs, in one object. + * + * @param string $checkout Either `blocks` or `classic`. + * + * @return array<string, mixed> + */ + private static function config( string $checkout ): array { + return array( + 'baseUrl' => 'proxy' === Cepis_Woo_Options::mode() + ? Cepis_Woo_Rest::base_url() + : Cepis_Woo_Options::base_url(), + 'overwrite' => Cepis_Woo_Options::overwrite(), + 'focusNumero' => Cepis_Woo_Options::focus_number(), + 'debounceMs' => 250, + 'timeoutMs' => 8000, + 'messages' => Cepis_Woo_Messages::all(), + 'fields' => 'blocks' === $checkout ? self::blocks_fields() : self::classic_fields(), + ); + } + + /** + * CSS selectors for the classic checkout, per address section. + * + * `billing_number` and `billing_neighborhood` are not WooCommerce fields — + * they come from the "Brazilian Market on WooCommerce" plugin, which is the + * de-facto way a Brazilian store gets a house-number and a neighbourhood + * box. A selector that matches nothing is skipped, so listing them costs + * nothing on a store that does not have them. + * + * There is deliberately no fallback onto `address_2` for the neighbourhood: + * in WooCommerce that field means "apartment, suite, unit", and putting a + * neighbourhood there produces a wrong address on the shipping label. + * + * @return array<string, array<string, string>> + */ + private static function classic_fields(): array { + $fields = array(); + + foreach ( array( 'billing', 'shipping' ) as $section ) { + $fields[ $section ] = array( + 'cep' => '#' . $section . '_postcode', + 'logradouro' => '#' . $section . '_address_1', + 'bairro' => '#' . $section . '_neighborhood', + 'localidade' => '#' . $section . '_city', + 'uf' => '#' . $section . '_state', + 'numero' => '#' . $section . '_number', + ); + } + + /** + * Filters the field selectors used on the classic checkout. + * + * Keys are the API's own field names; values are CSS selectors. A theme + * or one-page-checkout plugin that renames the fields hooks in here. + * + * @param array<string, array<string, string>> $fields Selectors per address section. + */ + return (array) apply_filters( 'cepis_woocommerce_classic_fields', $fields ); + } + + /** + * Store API address keys for the Cart/Checkout Blocks. + * + * The block checkout has no house-number and no neighbourhood field, and no + * plugin currently adds one: "Brazilian Market on WooCommerce" only extends + * the classic form. A store that registers its own with + * `woocommerce_register_additional_checkout_field()` can map it here, using + * the namespaced key the Store API exposes it under. + * + * @return array<string, string> + */ + private static function blocks_fields(): array { + $fields = array( + 'logradouro' => 'address_1', + 'localidade' => 'city', + 'uf' => 'state', + ); + + /** + * Filters the Store API address keys written on the block checkout. + * + * Keys are the API's own field names; values are keys of the address + * object in the `wc/store/cart` data store. + * + * @param array<string, string> $fields Address keys per API field. + */ + return (array) apply_filters( 'cepis_woocommerce_blocks_fields', $fields ); + } +} |