Plugin Directory

Changeset 3489826


Ignore:
Timestamp:
03/24/2026 10:00:22 AM (11 days ago)
Author:
bookpodplugin1
Message:

Updating to version 2.1.7

Location:
bookpod-author-tools/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • bookpod-author-tools/trunk/bookpod-author-tools.php

    r3485558 r3489826  
    33 * Plugin Name: BookPod Author Tools
    44 * Description: A plugin for managing books and orders through Bookpod.
    5  * Version:     2.1.6
     5 * Version:     2.1.7
    66 * Author:      Rachel Stern
    77 * Text Domain: bookpod-author-tools
  • bookpod-author-tools/trunk/bpat-checkout-logic.js

    r3485558 r3489826  
    409409    // ==========================
    410410    function getSelectedBookpodMethod() {
    411       // 1. Classic checkout — custom BookPod method select
    412       var $methodSelect = $('select[name="bpat_bookpod_shipping_method"]');
    413       if ($methodSelect.length) return $methodSelect.val() || "";
    414 
    415       // 2. Classic checkout — WooCommerce shipping rate radio buttons
     411      // 1. Classic checkout — WooCommerce shipping rate radio buttons
    416412      var $classicRate = $('input[name^="shipping_method"]:checked');
    417413      if ($classicRate.length) {
     
    423419      }
    424420
    425       // 3. Blocks checkout — WooCommerce shipping rate radio buttons
     421      // 2. Blocks checkout — WooCommerce shipping rate radio buttons
    426422      var $checkedRate = $('.wc-block-components-shipping-rates-control input[type="radio"]:checked');
    427423      if ($checkedRate.length) {
     
    459455      lastBookpodMethod = method;
    460456
    461       // Your original behavior
     457      // Hide WC standard address fields when home delivery is selected —
     458      // custom fields (bpat_street_name etc.) replace them.
     459      // Also remove validate-required so WooCommerce doesn't block checkout
     460      // because the hidden field is empty.
    462461      if (method === "home") {
    463         $wcAddress1.hide();
    464         $wcAddress2.hide();
     462        $wcAddress1.hide().removeClass("validate-required");
     463        $wcAddress2.hide().removeClass("validate-required");
     464        $wcAddress1.find("input").prop("required", false);
    465465      } else {
    466         $wcAddress1.show();
     466        $wcAddress1.show().addClass("validate-required");
    467467        $wcAddress2.show();
     468        $wcAddress1.find("input").prop("required", true);
    468469      }
    469470
     
    485486        else fetchPoints();
    486487      }
     488
    487489    }
    488490
     
    515517    });
    516518
    517     // ✅ Classic checkout: update visibility immediately when the custom BookPod method select changes
    518     // Also sync to the WooCommerce shipping rate radio so WooCommerce recalculates the order total.
    519     $(document.body).on("change", 'select[name="bpat_bookpod_shipping_method"]', function () {
    520       syncBlockBookpodMethod();
    521       updateVisibility();
    522 
    523       var selectedMethod = $(this).val();
    524       if (!selectedMethod) return;
    525 
    526       var suffix = selectedMethod === "pickup_point" ? "pickup_point" : "home";
    527       var $rates = $('input[name^="shipping_method"]');
    528       var triggered = false;
    529 
    530       $rates.each(function () {
    531         var rateVal = String($(this).val() || "");
    532         if (rateVal.indexOf("bpat_bookpod") !== -1 && rateVal.indexOf(suffix) !== -1) {
    533           if (!$(this).prop("checked")) {
    534             $(this).prop("checked", true);
    535             // Fire the native change event — WooCommerce's checkout.js already listens for
    536             // 'change' on input[name^="shipping_method"] and calls update_order_review() from there.
    537             $(this).trigger("change");
    538           }
    539           triggered = true;
    540           return false; // break
    541         }
    542       });
    543 
    544       // If no BookPod WC rate radio exists (shipping zone not configured), trigger update_checkout
    545       // directly so woocommerce_checkout_update_order_review saves the method and
    546       // woocommerce_cart_calculate_fees adds the correct shipping cost as a fee.
    547       if (!triggered) {
    548         $(document.body).trigger("update_checkout");
    549       }
    550     });
    551 
    552     // ✅ Classic checkout: when WooCommerce shipping rate radio changes, sync to custom select
     519    // ✅ Classic checkout: when WooCommerce BookPod shipping rate radio changes, update visibility.
    553520    $(document.body).on("change", 'input[name^="shipping_method"]', function () {
    554521      var val = String($(this).val() || "");
    555       var $sel = $('select[name="bpat_bookpod_shipping_method"]');
    556       if (!$sel.length) return;
    557522      if (val.indexOf("bpat_bookpod") !== -1) {
    558         var method = val.indexOf("pickup_point") !== -1 ? "pickup_point" : "home";
    559         if ($sel.val() !== method) {
    560           $sel.val(method).trigger("change");
    561         }
     523        syncBlockBookpodMethod();
     524        updateVisibility();
    562525      }
    563526    });
  • bookpod-author-tools/trunk/bpat-order.php

    r3485558 r3489826  
    179179            );
    180180        } else {
    181             $items_for_bookpod[] = array(
     181            $is_digital = bpat_product_is_digital( $product_id, $variation_id );
     182            $item_data  = array(
    182183                'type'     => 'book',
    183184                'bookid'   => (string) $bookpod_id,
    184185                'quantity' => $qty,
    185186            );
     187            if ( $is_digital ) {
     188                $item_data['format'] = 'epub';
     189            }
     190            $items_for_bookpod[] = $item_data;
    186191        }
    187192    }
     
    10211026}
    10221027
     1028/**
     1029 * Returns true only when the store has manually added the BookPod WC shipping
     1030 * method to at least one shipping zone (including the "Rest of World" zone).
     1031 * Result is cached per request via a static variable.
     1032 */
     1033function bpat_has_bookpod_shipping_in_zones() {
     1034    static $result = null;
     1035    if ( null !== $result ) {
     1036        return $result;
     1037    }
     1038
     1039    $zones   = WC_Shipping_Zones::get_zones();
     1040    $zones[] = array( 'zone_id' => 0 ); // Rest of World zone
     1041
     1042    foreach ( $zones as $zone_data ) {
     1043        $zone = new WC_Shipping_Zone( $zone_data['zone_id'] );
     1044        foreach ( $zone->get_shipping_methods( true ) as $method ) {
     1045            if ( 'bpat_bookpod' === $method->id ) {
     1046                $result = true;
     1047                return $result;
     1048            }
     1049        }
     1050    }
     1051
     1052    $result = false;
     1053    return $result;
     1054}
     1055
    10231056function bpat_inject_bookpod_checkout_fields( $fields ) {
    1024     if ( ! bpat_cart_has_only_physical_bookpod_items() ) {
     1057    if ( ! bpat_cart_has_only_physical_bookpod_items() || ! bpat_has_bookpod_shipping_in_zones() ) {
    10251058        return $fields;
    10261059    }
     
    10291062    $fields['billing']['billing_phone']['label'] = __( 'Phone', 'bookpod-author-tools' );
    10301063
    1031     $fields['billing']['bpat_bookpod_shipping_method'] = array(
    1032         'type' => 'select',
    1033         'label' => __( 'BookPod Shipping Method', 'bookpod-author-tools' ),
    1034         'required' => true,
    1035         'options' => array(
    1036             ''             => __( 'Select Shipping Method', 'bookpod-author-tools' ),
    1037             'home'         => __( 'Home Delivery', 'bookpod-author-tools' ) . ' — ₪29',
    1038             'pickup_point' => __( 'Pickup Point (Locker/Shop)', 'bookpod-author-tools' ) . ' — ₪18',
    1039         ),
    1040         'class' => array( 'form-row-wide' ),
    1041         'priority' => 25,
    1042     );
     1064    // Shipping method (home / pickup_point) is now chosen via the standard
     1065    // WooCommerce shipping rate radios — no custom select needed here.
    10431066
    10441067    $fields['billing']['bpat_street_name'] = array(
     
    11171140
    11181141function bpat_inject_bookpod_block_checkout_fields( $fields ) {
     1142    if ( ! bpat_has_bookpod_shipping_in_zones() ) {
     1143        return $fields;
     1144    }
     1145
    11191146    $fields['billing']['bpat_street_name'] = array(
    11201147        'label'    => __( 'Street Name', 'bookpod-author-tools' ),
     
    13601387
    13611388    // If a BookPod WC shipping rate is already selected, it handles the cost — don't double-count.
     1389    // bpat_filter_package_rates_for_bookpod() syncs chosen_shipping_methods to a BookPod rate
     1390    // during the same calculate_totals() call, so this check is reliable.
    13621391    $chosen = WC()->session ? (array) WC()->session->get( 'chosen_shipping_methods', array() ) : array();
    13631392    foreach ( $chosen as $chosen_method ) {
     
    13831412        return;
    13841413    }
     1414
     1415    // Derive the chosen BookPod method from the standard WC shipping_method POST field.
    13851416    // phpcs:ignore WordPress.Security.NonceVerification.Missing
    1386     $shipping_method = isset( $_POST['bpat_bookpod_shipping_method'] ) ? sanitize_text_field( wp_unslash( $_POST['bpat_bookpod_shipping_method'] ) ) : '';
    1387 
    1388     if ( empty($shipping_method) ) {
    1389          wc_add_notice( __( 'Please select a shipping method for BookPod book.', 'bookpod-author-tools' ), 'error' );
     1417    $raw_methods     = isset( $_POST['shipping_method'] ) ? (array) $_POST['shipping_method'] : array();
     1418    $shipping_method = '';
     1419    foreach ( $raw_methods as $m ) {
     1420        $m = sanitize_text_field( wp_unslash( $m ) );
     1421        if ( false !== strpos( $m, 'bpat_bookpod' ) ) {
     1422            $shipping_method = ( false !== strpos( $m, 'pickup_point' ) ) ? 'pickup_point' : 'home';
     1423            break;
     1424        }
     1425    }
     1426
     1427    // If no BookPod rate was chosen WooCommerce itself will block submission.
     1428    if ( empty( $shipping_method ) ) {
     1429        return;
    13901430    }
    13911431
     
    15181558    }
    15191559
     1560    // Derive the BookPod shipping method from the chosen WC rate (home / pickup_point).
     1561    // phpcs:ignore WordPress.Security.NonceVerification.Missing
     1562    $raw_methods    = isset( $_POST['shipping_method'] ) ? (array) $_POST['shipping_method'] : array();
     1563    $bookpod_method = '';
     1564    foreach ( $raw_methods as $m ) {
     1565        $m = sanitize_text_field( wp_unslash( $m ) );
     1566        if ( false !== strpos( $m, 'bpat_bookpod' ) ) {
     1567            $bookpod_method = ( false !== strpos( $m, 'pickup_point' ) ) ? 'pickup_point' : 'home';
     1568            break;
     1569        }
     1570    }
     1571    if ( ! empty( $bookpod_method ) ) {
     1572        update_post_meta( $order_id, '_bpat_bookpod_shipping_method', $bookpod_method );
     1573    }
     1574
    15201575    $fields = [
    1521         'bpat_bookpod_shipping_method',
    15221576        'bpat_street_name',
    15231577        'bpat_building_number',
  • bookpod-author-tools/trunk/bpat-woocommerce-shipping.php

    r3475827 r3489826  
    9898    return $methods;
    9999}
     100
     101/**
     102 * When the cart contains only physical BookPod items AND the store has
     103 * manually configured the BookPod WC shipping method in a zone, keep only
     104 * the BookPod rates so the customer is not asked to pick twice.
     105 *
     106 * If BookPod is NOT configured as a WC shipping method we do not interfere —
     107 * the store's own rates are returned unchanged and BookPod fulfillment happens
     108 * silently via the API (bpat_add_bookpod_shipping_fee handles the cost).
     109 */
     110add_filter( 'woocommerce_package_rates', 'bpat_filter_package_rates_for_bookpod', 10, 2 );
     111
     112function bpat_filter_package_rates_for_bookpod( $rates, $package ) {
     113    if ( ! function_exists( 'bpat_cart_has_only_physical_bookpod_items' ) || ! bpat_cart_has_only_physical_bookpod_items() ) {
     114        return $rates;
     115    }
     116
     117    $bookpod_rates = array_filter(
     118        $rates,
     119        function ( $rate_id ) {
     120            return false !== strpos( $rate_id, 'bpat_bookpod' );
     121        },
     122        ARRAY_FILTER_USE_KEY
     123    );
     124
     125    // BookPod WC method is NOT configured in any zone — leave rates untouched.
     126    if ( empty( $bookpod_rates ) ) {
     127        return $rates;
     128    }
     129
     130    // BookPod WC rates exist — keep only them so the customer picks once.
     131    // Also sync chosen_shipping_methods in the session right now so that
     132    // bpat_add_bookpod_shipping_fee() (which runs immediately after in the same
     133    // calculate_totals() call) sees a BookPod rate as the chosen method and
     134    // skips adding a fee on top of the WC rate cost.
     135    if ( WC()->session ) {
     136        $chosen    = (array) WC()->session->get( 'chosen_shipping_methods', array() );
     137        $first_key = null;
     138        foreach ( $bookpod_rates as $k => $_ ) {
     139            $first_key = $k;
     140            break;
     141        }
     142        $changed = false;
     143        foreach ( $chosen as $i => $method ) {
     144            if ( false === strpos( (string) $method, 'bpat_bookpod' ) ) {
     145                $chosen[ $i ] = $first_key;
     146                $changed      = true;
     147            }
     148        }
     149        if ( $changed ) {
     150            WC()->session->set( 'chosen_shipping_methods', $chosen );
     151        }
     152    }
     153
     154    return $bookpod_rates;
     155}
Note: See TracChangeset for help on using the changeset viewer.