Settings > Shipping > Maple Parcel, once per store. * instance(): the modal for each shipping zone the method is added to. * * Three field types are our own and are drawn and saved by CustomFields: * bbmmp_secret (never printed back), bbmmp_services (the services table) and * bbmmp_test_button. */ declare(strict_types=1); namespace BlueBrainMedia\MapleParcel\Settings; use BlueBrainMedia\MapleParcel\Shipping\ParcelBuilder; defined( 'ABSPATH' ) || exit; final class Fields { /** Where merchants make the app whose key and secret go in the settings. */ public const PORTAL_URL = 'https://developer-developpeur.canadapost-postescanada.ca/devportal-portaildesdeveloppeurs/'; /** @return array> */ public static function global(): array { /** * The store-wide settings, in WooCommerce settings-API format. Fields * added here are saved with the others and read with Settings::raw(). * * @param array> $fields */ $fields = apply_filters( 'bbmmp_global_fields', self::storeFields() ); return is_array( $fields ) ? $fields : self::storeFields(); } /** @return array> */ private static function storeFields(): array { $weight = (string) get_option( 'woocommerce_weight_unit', 'kg' ); $length = (string) get_option( 'woocommerce_dimension_unit', 'cm' ); return array( 'connection_title' => array( 'title' => __( 'Canada Post connection', 'maple-parcel' ), 'type' => 'title', 'description' => sprintf( /* translators: %s: link to Canada Post's Developer Portal. */ __( 'Maple Parcel uses your own app from Canada Post\'s %s. Create an app there, subscribe it to the Rating API, and copy its key and secret below. The Test app returns sample prices and never bills; the Production app returns your real prices.', 'maple-parcel' ), '' . esc_html__( 'Developer Portal', 'maple-parcel' ) . '' ) . '
' . esc_html__( 'Only keys from the new Developer Portal work.', 'maple-parcel' ) . ' ' . esc_html__( 'A username and password from Canada Post\'s old developer program (the one used by most older plugins) will not connect.', 'maple-parcel' ), ), 'environment' => array( 'title' => __( 'Environment', 'maple-parcel' ), 'type' => 'select', 'class' => 'wc-enhanced-select', 'default' => 'test', 'options' => array( 'test' => __( 'Test (sample prices)', 'maple-parcel' ), 'production' => __( 'Production (your real prices)', 'maple-parcel' ), ), ), 'test_client_id' => array( 'title' => __( 'Test app key', 'maple-parcel' ), 'type' => 'text', 'default' => '', 'custom_attributes' => array( 'autocomplete' => 'off' ), 'description' => __( 'From your Test app in the new Developer Portal. Not a username from the old developer program.', 'maple-parcel' ), ), 'test_client_secret' => array( 'title' => __( 'Test app secret', 'maple-parcel' ), 'type' => 'bbmmp_secret', 'default' => '', ), 'production_client_id' => array( 'title' => __( 'Production app key', 'maple-parcel' ), 'type' => 'text', 'default' => '', 'custom_attributes' => array( 'autocomplete' => 'off' ), 'description' => __( 'From your Production app in the new Developer Portal. Not a username from the old developer program.', 'maple-parcel' ), ), 'production_client_secret' => array( 'title' => __( 'Production app secret', 'maple-parcel' ), 'type' => 'bbmmp_secret', 'default' => '', ), 'test_connection' => array( 'title' => __( 'Check the connection', 'maple-parcel' ), 'type' => 'bbmmp_test_button', 'description' => __( 'Signs in with the saved key and secret for the chosen environment, and asks for one sample rate. Save your changes first.', 'maple-parcel' ), ), 'account_title' => array( 'title' => __( 'Your Canada Post account', 'maple-parcel' ), 'type' => 'title', ), 'customer_number' => array( 'title' => __( 'Customer number', 'maple-parcel' ), 'type' => 'text', 'default' => '', 'description' => __( 'Up to 10 digits, from your Canada Post business account. Needed for your own (commercial) prices; without it, counter prices are shown.', 'maple-parcel' ), 'custom_attributes' => array( 'inputmode' => 'numeric', 'pattern' => '\d{1,10}', ), ), 'contract_id' => array( 'title' => __( 'Contract number', 'maple-parcel' ), 'type' => 'text', 'default' => '', 'description' => __( 'Only for commercial contract customers. Leave it blank if you are a Solutions for Small Business member: Canada Post refuses a contract number from those accounts.', 'maple-parcel' ), ), 'quote_type' => array( 'title' => __( 'Prices', 'maple-parcel' ), 'type' => 'select', 'class' => 'wc-enhanced-select', 'default' => Settings::QUOTE_COMMERCIAL, 'options' => array( Settings::QUOTE_COMMERCIAL => __( 'My account\'s prices (commercial)', 'maple-parcel' ), Settings::QUOTE_COUNTER => __( 'Post office counter prices', 'maple-parcel' ), ), ), 'origin_postal_code' => array( 'title' => __( 'Ship-from postal code', 'maple-parcel' ), 'type' => 'text', 'default' => '', 'description' => __( 'Where parcels are mailed from, for example V2S 6X1.', 'maple-parcel' ), ), 'rates_title' => array( 'title' => __( 'Rates', 'maple-parcel' ), 'type' => 'title', ), 'tax_mode' => array( 'title' => __( 'Price to charge', 'maple-parcel' ), 'type' => 'select', 'class' => 'wc-enhanced-select', 'default' => 'base', 'options' => array( 'base' => __( 'Before tax (WooCommerce adds tax on shipping)', 'maple-parcel' ), 'due' => __( 'Canada Post\'s price including tax', 'maple-parcel' ), ), 'description' => __( 'Choose "Before tax" if WooCommerce charges tax on shipping in your store, so the tax is not charged twice.', 'maple-parcel' ), ), 'cache_minutes' => array( 'title' => __( 'Remember rates for (minutes)', 'maple-parcel' ), 'type' => 'number', 'default' => '60', 'description' => __( 'The same parcel to the same place is not asked for again within this time. 0 asks every time.', 'maple-parcel' ), 'custom_attributes' => array( 'min' => '0', 'step' => '1', ), ), 'parcels_title' => array( 'title' => __( 'Parcels', 'maple-parcel' ), 'type' => 'title', ), 'packing' => array( 'title' => __( 'Packing', 'maple-parcel' ), 'type' => 'select', 'class' => 'wc-enhanced-select', 'default' => ParcelBuilder::WHOLE_CART, 'options' => array( ParcelBuilder::WHOLE_CART => __( 'Whole cart in one box (more boxes over 30 kg)', 'maple-parcel' ), ParcelBuilder::PER_ITEM => __( 'Each item in its own box', 'maple-parcel' ), ), ), 'default_weight' => array( /* translators: %s: the store's weight unit, e.g. kg. */ 'title' => sprintf( __( 'Default weight (%s)', 'maple-parcel' ), $weight ), 'type' => 'decimal', 'default' => wc_format_decimal( wc_get_weight( 0.5, $weight, 'kg' ), 3, true ), 'description' => __( 'Used for products with no weight.', 'maple-parcel' ), 'custom_attributes' => array( 'min' => '0' ), ), /* translators: %s: the store's dimension unit, e.g. cm. */ 'default_length' => self::side( __( 'Default box length (%s)', 'maple-parcel' ), $length, 20.0 ), /* translators: %s: the store's dimension unit, e.g. cm. */ 'default_width' => self::side( __( 'Default box width (%s)', 'maple-parcel' ), $length, 15.0 ), /* translators: %s: the store's dimension unit, e.g. cm. */ 'default_height' => self::side( __( 'Default box height (%s)', 'maple-parcel' ), $length, 10.0 ), 'debug' => array( 'title' => __( 'Debug log', 'maple-parcel' ), 'type' => 'checkbox', 'label' => __( 'Log every request and answer', 'maple-parcel' ), 'default' => 'no', 'description' => __( 'Written to WooCommerce > Status > Logs under "maple-parcel". Keys, secrets and sign-in tokens are never logged. Errors are logged either way.', 'maple-parcel' ), ), ); } /** @return array> */ public static function instance(): array { /** * The settings in each shipping zone's modal, in WooCommerce * settings-API format. Fields added here are saved with the zone and * read with the method's get_option(). * * @param array> $fields */ $fields = apply_filters( 'bbmmp_instance_fields', self::zoneFields() ); return is_array( $fields ) ? $fields : self::zoneFields(); } /** @return array> */ private static function zoneFields(): array { return array( 'title' => array( 'title' => __( 'Name', 'maple-parcel' ), 'type' => 'text', 'default' => __( 'Canada Post', 'maple-parcel' ), 'description' => __( 'Shown in this zone\'s list of shipping methods. Customers see the service names instead.', 'maple-parcel' ), 'desc_tip' => true, ), 'services' => array( 'title' => __( 'Services', 'maple-parcel' ), 'type' => 'bbmmp_services', 'description' => __( 'Tick the services to offer in this zone. Only those that suit the address are shown. Type a name to rename a service at checkout.', 'maple-parcel' ), ), 'delivery_time' => array( 'title' => __( 'Delivery estimate', 'maple-parcel' ), 'type' => 'checkbox', 'label' => __( 'Show Canada Post\'s delivery estimate under each rate', 'maple-parcel' ), 'default' => 'yes', ), 'free_shipping_min' => array( 'title' => __( 'Free shipping over', 'maple-parcel' ), 'type' => 'price', 'default' => '', 'placeholder' => __( 'Off', 'maple-parcel' ), 'description' => __( 'When the items in the cart come to this amount or more (before tax), the cheapest service is free. Leave blank to switch this off.', 'maple-parcel' ), 'desc_tip' => true, ), 'coverage' => array( 'title' => __( 'Coverage', 'maple-parcel' ), 'type' => 'checkbox', 'label' => __( 'Include coverage for the value of the items (priced into the rate)', 'maple-parcel' ), 'default' => 'no', ), 'signature' => array( 'title' => __( 'Signature', 'maple-parcel' ), 'type' => 'checkbox', 'label' => __( 'Ask for a signature on delivery (priced into the rate)', 'maple-parcel' ), 'default' => 'no', ), 'fallback_cost' => array( 'title' => __( 'Fallback rate', 'maple-parcel' ), 'type' => 'price', 'default' => '', 'placeholder' => __( 'None', 'maple-parcel' ), 'description' => __( 'Charged when Canada Post cannot be reached, so the customer can still check out. Leave blank to offer no Canada Post option at those times.', 'maple-parcel' ), 'desc_tip' => true, ), 'fallback_label' => array( 'title' => __( 'Fallback rate name', 'maple-parcel' ), 'type' => 'text', 'default' => __( 'Shipping', 'maple-parcel' ), ), 'tax_status' => array( 'title' => __( 'Tax status', 'maple-parcel' ), 'type' => 'select', 'class' => 'wc-enhanced-select', 'default' => 'taxable', 'options' => array( 'taxable' => __( 'Taxable', 'maple-parcel' ), 'none' => _x( 'None', 'Tax status', 'maple-parcel' ), ), ), ); } /** @return array Saved-value defaults for global(). */ public static function globalDefaults(): array { $defaults = array(); foreach ( self::global() as $key => $field ) { if ( array_key_exists( 'default', $field ) ) { $defaults[ $key ] = $field['default']; } } return $defaults; } /** @return array */ private static function side( string $title, string $unit, float $cm ): array { return array( 'title' => sprintf( $title, $unit ), 'type' => 'decimal', 'default' => wc_format_decimal( wc_get_dimension( $cm, $unit, 'cm' ), 1, true ), 'custom_attributes' => array( 'min' => '0' ), ); } }