Plugin Directory

Changeset 3221460


Ignore:
Timestamp:
01/13/2025 09:39:32 AM (13 months ago)
Author:
boxodev
Message:

Update to version 0.0.29 from GitHub

Location:
boxo-return
Files:
12 added
22 edited
1 copied

Legend:

Unmodified
Added
Removed
  • boxo-return/tags/0.0.29/admin/admin.php

    r3208611 r3221460  
    1919
    2020            add_menu_page(
    21                 'Boxo Return',
    22                 'Boxo Return',
     21                'BOXO Return',
     22                'BOXO Return',
    2323                'manage_options',
    2424                'boxo-return',
     
    3434
    3535            if (isset($_GET['settings-updated'])) {
    36                 add_settings_error('boxo_messages', 'settings_updated', 'Settings saved', 'updated');
     36                add_settings_error('boxo_messages', 'settings_updated', esc_html__('Settings saved', 'boxo-return'), 'updated');
    3737            }
    3838            settings_errors('boxo_messages');
     
    4646            settings_fields('boxo');
    4747            do_settings_sections('boxo');
    48             submit_button('Save');
     48            submit_button(esc_html__('Save', 'boxo-return'));
    4949            echo <<<HTML
    5050                </form>
     
    5656            $url = admin_url('admin.php?page=boxo-return');
    5757            $action_links = array(
    58                 'settings' => '<a href="' . esc_url($url) . '">Settings</a>',
     58                'settings' => '<a href="' . esc_url($url) . '">' . esc_html__('Settings', 'boxo-return') . '</a>',
    5959            );
    6060            return array_merge($action_links, $links);
  • boxo-return/tags/0.0.29/admin/order.php

    r3212861 r3221460  
    1919        public static function show_order_meta($order) {
    2020            $packaging = $order->get_meta('boxo_packaging', true);
     21            $title_safe = esc_html__('Packaging', 'boxo-return');
    2122
    2223            if (
     
    2526            ) {
    2627                $heart_icon_safe = file_get_contents(WP_PLUGIN_DIR . '/boxo-return/icons/heart.svg');
     28                $packaging_safe = esc_html__('Reusable packaging', 'boxo-return');
    2729                echo <<<HTML
    28                 <h3>Verpakking</h3><br>
     30                <h3>$title_safe</h3><br>
    2931                <div class="boxo_packaging-info">
    3032                    <span class="boxo_packaging-icon">$heart_icon_safe</span>
    31                     Herbruikbare verzendverpakking
     33                    $packaging_safe
    3234                </div>
    3335                HTML;
     
    3941                || $packaging === 'false' // Added for backwards compatibility, can be removed at a later moment.
    4042            ) {
     43                $packaging_safe = esc_html__('Disposable packaging', 'boxo-return');
    4144                echo <<<HTML
    42                 <h3>Verpakking</h3><br>
    43                 Eenmalige verzendverpakking
     45                <h3>$title_safe</h3><br>
     46                $packaging_safe
    4447                HTML;
    4548                return;
    4649            }
    4750
    48             // If the order was placed when Boxo Return was not active, do not echo anything.
     51            // If the order was placed when BOXO Return was not active, do not echo anything.
    4952        }
    5053    }
  • boxo-return/tags/0.0.29/admin/product-picker.js

    r3208611 r3221460  
    3939      const res = await fetch(ajaxUrl + '?' + params.toString())
    4040      if (!res.ok) {
    41         console.error('[Boxo Return] Search products: ' + res.status + ' ' + res.statusText)
     41        console.error('[BOXO Return] Search products: ' + res.status + ' ' + res.statusText)
    4242        this.searchResults = []
    4343        return
  • boxo-return/tags/0.0.29/admin/product-picker.php

    r3208611 r3221460  
    4242            $ajax_url_safe = esc_js(admin_url('admin-ajax.php'));
    4343            $nonce_safe = esc_js(wp_create_nonce('boxo'));
     44            $search_label_safe = esc_html__('Add a product:', 'boxo-return');
     45            $search_placeholder_safe = esc_attr__('Product name', 'boxo-return');
     46            $no_results_safe = esc_html__('No products found.', 'boxo-return');
     47            $remove_safe = esc_html__('Remove', 'boxo-return');
    4448
    4549            return <<<HTML
     
    5155                <div class="bxpp_search">
    5256                    <label class="bxpp_search-input-container">
    53                     Add a product:
     57                    $search_label_safe
    5458                    <input
    5559                        type="search"
    5660                        aria-autocomplete="list"
    5761                        aria-controls="bxpp_$name_safe-search-results"
    58                         placeholder="Product title"
     62                        placeholder="$search_placeholder_safe"
    5963                        x-model.debounce.300="keyword"
    6064                    >
     
    7377                        </template>
    7478                        <template x-if="!hasSearchResults()">
    75                             <li class="bxpp_search-result">No products found.</li>
     79                            <li class="bxpp_search-result">$no_results_safe</li>
    7680                        </template>
    7781                    </ul>
     
    9195                                        x-on:click="handleRemoveProductClick(product.id)"
    9296                                    >
    93                                         Remove
     97                                    $remove_safe;
    9498                                    </button>
    9599                                </td>
  • boxo-return/tags/0.0.29/admin/settings.php

    r3212861 r3221460  
    2828            add_settings_section(
    2929                'section',
    30                 'Settings',
     30                __('Settings', 'boxo-return'),
    3131                'Boxo_Settings::add_section_header',
    3232                'boxo'
     
    3535            add_settings_field(
    3636                'api_key',
    37                 'API Key',
     37                __('API Key', 'boxo-return'),
    3838                'Boxo_Settings::add_api_key_field',
    3939                'boxo',
     
    4747            add_settings_field(
    4848                'deposit_cents',
    49                 'Deposit amount in cents',
     49                __('Deposit amount in cents', 'boxo-return'),
    5050                'Boxo_Settings::add_deposit_cents_field',
    5151                'boxo',
     
    5959            add_settings_field(
    6060                'disposable_fee_enabled',
    61                 'Disposable packaging fee',
     61                __('Disposable packaging fee', 'boxo-return'),
    6262                'Boxo_Settings::add_disposable_fee_enabled_field',
    6363                'boxo',
     
    7070
    7171            add_settings_field(
    72                 'default_packaging',
    73                 'Default packaging',
    74                 'Boxo_Settings::add_default_packaging_field',
    75                 'boxo',
    76                 'section',
    77                 [
    78                     'label_for' => 'boxo_default-packaging-select',
     72                'selection_mode',
     73                __('Packaging selection', 'boxo-return'),
     74                'Boxo_Settings::add_selection_mode_field',
     75                'boxo',
     76                'section',
     77                [
     78                    'label_for' => 'boxo_selection-mode-select',
    7979                    'class' => 'boxo_row',
    8080                ]
     
    8383            add_settings_field(
    8484                'info_url',
    85                 'URL to information page (optional)',
     85                __('URL to information page (optional)', 'boxo-return'),
    8686                'Boxo_Settings::add_info_url_field',
    8787                'boxo',
     
    9595            add_settings_field(
    9696                'product_allow_mode',
    97                 'Availability',
     97                __('Allowed in reusable packaging', 'boxo-return'),
    9898                'Boxo_Settings::add_product_allow_mode_field',
    9999                'boxo',
     
    125125        public static function add_api_key_field() {
    126126            $value_safe = esc_attr(Boxo_Options::api_key());
     127            $description_safe = esc_html__('Enter the API key provided by BOXO Return.', 'boxo-return');
    127128            // The actual API key needs to be present in this input, so that it will not be cleared from storage on save.
    128129            echo <<<HTML
    129             <input id="boxo_api-key-input" class="regular-text" name="boxo_options[api_key]" type="password" value="$value_safe">
     130            <input
     131                id="boxo_api-key-input"
     132                class="regular-text"
     133                name="boxo_options[api_key]"
     134                type="password"
     135                value="$value_safe"
     136                aria-describedby="boxo_api-key-description"
     137            >
     138            <p class="description" id="boxo_api-key-description">$description_safe</p>
    130139            HTML;
    131140        }
     
    140149        public static function add_disposable_fee_enabled_field() {
    141150            $enabled = Boxo_Options::disposable_fee_enabled();
     151            $enabled_safe = $enabled ? 'true' : 'false';
    142152            $checked_attb_safe = $enabled ? 'checked' : '';
    143             $enabled_safe = $enabled ? 'true' : 'false';
     153            $label_safe = esc_html__('Enable disposable packaging fee', 'boxo-return');
     154            $description_safe = esc_html__('If enabled, a fee is charged when the customer does not select reusable packaging.', 'boxo-return');
    144155            $fee_safe = esc_attr(Boxo_Options::disposable_fee_cents());
     156            $cents_label_safe = esc_html__('Fee in cents:', 'boxo-return');
    145157            echo <<<HTML
    146158            <div class="boxo_settings-field" x-data="{enabled: $enabled_safe}">
    147                 <label>
    148                     <input
    149                         id="boxo_disposable-fee-enabled-input"
    150                         name="boxo_options[disposable_fee_enabled]"
    151                         type="checkbox"
    152                         $checked_attb_safe
    153                         x-model="enabled"
    154                     >
    155                     Charge fee for disposable packaging
    156                 </label>
     159                <div>
     160                    <label>
     161                        <input
     162                            id="boxo_disposable-fee-enabled-input"
     163                            name="boxo_options[disposable_fee_enabled]"
     164                            type="checkbox"
     165                            $checked_attb_safe
     166                            x-model="enabled"
     167                            aria-describedby="boxo_disposable-fee-enabled-description"
     168                        >
     169                        $label_safe
     170                    </label>
     171                    <p class="description" id="boxo_disposable-fee-enabled-description">$description_safe</p>
     172                </div>
    157173                <!-- Using x-show instead of x-if, so that invisible settings are not cleared on save. -->
    158174                <label x-show="enabled" x-cloak>
    159                     Fee in cents:
     175                $cents_label_safe
    160176                    <input
    161177                        name="boxo_options[disposable_fee_cents]"
     
    170186        }
    171187
    172         public static function add_default_packaging_field() {
     188        public static function add_selection_mode_field() {
     189            $selection_mode = Boxo_Options::selection_mode();
    173190            $default_packaging = Boxo_Options::default_packaging();
    174191
     192            $choice_safe = Boxo_Options::SELECTION_MODE_CHOICE;
     193            $force_reusable_safe = Boxo_Options::SELECTION_MODE_FORCE_REUSABLE;
    175194            $reusable_safe = Boxo_Options::DEFAULT_PACKAGING_REUSABLE;
    176195            $disposable_safe = Boxo_Options::DEFAULT_PACKAGING_DISPOSABLE;
    177196
     197            $choice_selected_attb_safe = $selection_mode == Boxo_Options::SELECTION_MODE_CHOICE ? 'selected' : '';
     198            $force_reusable_selected_attb_safe = $selection_mode == Boxo_Options::SELECTION_MODE_FORCE_REUSABLE ? 'selected' : '';
    178199            $reusable_selected_attb_safe = $default_packaging == Boxo_Options::DEFAULT_PACKAGING_REUSABLE ? 'selected' : '';
    179200            $disposable_selected_attb_safe = $default_packaging == Boxo_Options::DEFAULT_PACKAGING_DISPOSABLE ? 'selected' : '';
    180201
    181             echo <<<HTML
    182                 <select
    183                     id="boxo_default-packaging-select"
    184                     name="boxo_options[default_packaging]"
    185                     class="regular-text"
    186                     >
    187                     <option value="$reusable_safe" $reusable_selected_attb_safe>Reusable packaging</option>
    188                     <option value="$disposable_safe" $disposable_selected_attb_safe>Disposable packaging</option>
    189                 </select>
     202            $default_packaging_label_safe = esc_html__('Default selection:', 'boxo-return');
     203            $choice_label_safe = esc_html__('Customer chooses packaging', 'boxo-return');
     204            $force_reusable_label_safe = esc_html__('Always use reusable packaging when possible', 'boxo-return');
     205            $reusable_label_safe = esc_html__('Reusable packaging', 'boxo-return');
     206            $disposable_label_safe = esc_html__('Disposable packaging', 'boxo-return');
     207
     208            echo <<<HTML
     209                <div class="boxo_settings-field" x-data="{selectionMode: '$selection_mode'}">
     210                    <select
     211                        id="boxo_selection-mode-select"
     212                        name="boxo_options[selection_mode]"
     213                        class="regular-text"
     214                        x-model="selectionMode"
     215                        >
     216                        <option value="$choice_safe" $choice_selected_attb_safe>$choice_label_safe</option>
     217                        <option value="$force_reusable_safe" $force_reusable_selected_attb_safe>$force_reusable_label_safe</option>
     218                    </select>
     219                    <!-- Using x-show instead of x-if, so that invisible settings are not cleared on save. -->
     220                    <label x-show="selectionMode === 'choice'" x-cloak>
     221                    $default_packaging_label_safe
     222                        <select name="boxo_options[default_packaging]" class="regular-text">
     223                            <option value="$reusable_safe" $reusable_selected_attb_safe>$reusable_label_safe</option>
     224                            <option value="$disposable_safe" $disposable_selected_attb_safe>$disposable_label_safe</option>
     225                        </select>
     226                    </label>
     227                </div>
    190228            HTML;
    191229        }
     
    193231        public static function add_info_url_field() {
    194232            $value_safe = esc_attr(Boxo_Options::info_url());
    195             echo <<<HTML
    196             <input id="boxo_info-url-input" class="regular-text" name="boxo_options[info_url]" type="url" value="$value_safe">
     233            $description_safe = esc_html__('Will open in a new tab when the customer clicks the information button. Defaults to BOXO Return homepage.', 'boxo-return');
     234            echo <<<HTML
     235            <input
     236                id="boxo_info-url-input"
     237                class="regular-text"
     238                name="boxo_options[info_url]"
     239                type="url"
     240                value="$value_safe"
     241                aria-describedby="boxo_info-url-description"
     242            >
     243            <p class="description" id="boxo_info-url-description">$description_safe</p>
    197244            HTML;
    198245        }
     
    208255            $all_except_excluded_selected_attb_safe = $allow_mode == Boxo_Options::PRODUCT_ALLOW_MODE_ALL_EXCEPT_EXCLUDED ? 'selected' : '';
    209256            $included_only_selected_attb_safe = $allow_mode == Boxo_Options::PRODUCT_ALLOW_MODE_INCLUDED_ONLY ? 'selected' : '';
     257
     258            $all_label_safe = esc_html__('All products', 'boxo-return');
     259            $all_except_excluded_label_safe = esc_html__('All products except:', 'boxo-return');
     260            $included_only_label_safe = esc_html__('Only these products:', 'boxo-return');
    210261
    211262            $allow_mode_safe = esc_js($allow_mode);
     
    228279                    class="regular-text"
    229280                    x-model="allowMode">
    230                     <option value="$all_safe" $all_selected_attb_safe>All products</option>
    231                     <option value="$all_except_excluded_safe" $all_except_excluded_selected_attb_safe>All products except:</option>
    232                     <option value="$included_only_safe" $included_only_selected_attb_safe>Only these products:</option>
     281                    <option value="$all_safe" $all_selected_attb_safe>$all_label_safe</option>
     282                    <option value="$all_except_excluded_safe" $all_except_excluded_selected_attb_safe>$all_except_excluded_label_safe</option>
     283                    <option value="$included_only_safe" $included_only_selected_attb_safe>$included_only_label_safe</option>
    233284                </select>
    234285                <!-- Using x-show instead of x-if, so that invisible settings are not cleared on save. -->
  • boxo-return/tags/0.0.29/boxo-return.php

    r3218341 r3221460  
    22/*
    33* Plugin Name: BOXO Return
    4 * Version: 0.0.26
     4* Version: 0.0.29
    55* Description: Allows customers to select reusable packaging during checkout.
    6 * Author: Boxo
     6* Author: BOXO
    77* Author URI: https://www.boxo.nu
    8 * Developer: Boxo
     8* Developer: BOXO
    99* Developer URI: https://www.boxo.nu
    1010* License: GPLv2
    1111* License URI: https://www.gnu.org/licenses/gpl-2.0.html
    1212* Requires Plugins: woocommerce
     13* Text Domain: boxo-return
     14* Domain Path: /languages
    1315*/
    1416
     
    3537    }
    3638});
     39
     40add_action('init', 'boxo_load_textdomain');
     41
     42function boxo_load_textdomain() {
     43    load_plugin_textdomain('boxo-return', false, dirname(plugin_basename(__FILE__)) . '/languages');
     44}
  • boxo-return/tags/0.0.29/checkout/checkout.js

    r3212861 r3221460  
    33const serverData = document.getElementById('boxo-data')
    44if (!(serverData instanceof HTMLDivElement)) {
    5   throw new Error('[Boxo Return] Could not get server data')
     5  throw new Error('[BOXO Return] Could not get server data')
    66}
    77
    88const boxoAvailableUrl = serverData.getAttribute('data-boxo-available-url')
    99if (!boxoAvailableUrl) {
    10   throw new Error('[Boxo Return] Could not get Boxo available URL')
     10  throw new Error('[BOXO Return] Could not get Boxo available URL')
    1111}
    1212
     
    2929  const container = document.getElementById('boxo_container')
    3030  if (!(container instanceof HTMLTableRowElement)) {
    31     throw Error('[Boxo Return] Could not get container')
     31    throw Error('[BOXO Return] Could not get container')
    3232  }
    3333
     
    4343  const inputsContainer = document.getElementById('boxo_inputs_container')
    4444  if (!(inputsContainer instanceof HTMLDivElement)) {
    45     throw new Error('[Boxo Return] Could not get inputs container')
     45    throw new Error('[BOXO Return] Could not get inputs container')
    4646  }
    4747
    4848  const inputsTemplate = document.getElementById('boxo_inputs_template')
    4949  if (!(inputsTemplate instanceof HTMLTemplateElement)) {
    50     throw new Error('[Boxo Return] Could not get inputs template')
     50    throw new Error('[BOXO Return] Could not get inputs template')
    5151  }
    5252
     
    5858  const container = document.getElementById('boxo_container')
    5959  if (!(container instanceof HTMLTableRowElement)) {
    60     throw Error('[Boxo Return] Could not get container')
     60    throw Error('[BOXO Return] Could not get container')
    6161  }
    6262
     
    6767  const inputsContainer = document.getElementById('boxo_inputs_container')
    6868  if (!(inputsContainer instanceof HTMLDivElement)) {
    69     throw new Error('[Boxo Return] Could not get inputs container')
     69    throw new Error('[BOXO Return] Could not get inputs container')
    7070  }
    7171
     
    8585  const selectedInput = document.querySelector(`[name=boxo_packaging][value=${state.selection}]`)
    8686  if (!(selectedInput instanceof HTMLInputElement)) {
    87     throw new Error('[Boxo Return] Could not find selected input')
     87    throw new Error('[BOXO Return] Could not find selected input')
    8888  }
    8989  selectedInput.checked = true
     
    101101    const res = await fetch(url.toString())
    102102    if (!res.ok) {
    103       console.error(`[Boxo Return] ${res.status} ${res.statusText}`)
     103      console.error(`[BOXO Return] ${res.status} ${res.statusText}`)
    104104      return false
    105105    }
     
    107107    const available = (await res.json()).available
    108108    if (typeof available !== 'boolean') {
    109       console.error('[Boxo Return] Unexpected response')
     109      console.error('[BOXO Return] Unexpected response')
    110110      return false
    111111    }
     
    113113    return available
    114114  } catch (err) {
    115     console.error('[Boxo Return]', err)
     115    console.error('[BOXO Return]', err)
    116116    return false
    117117  }
     
    148148    : document.getElementById('billing_postcode')
    149149  if (!(postalCodeInput instanceof HTMLInputElement)) {
    150     console.error('[Boxo Return] Could not get postal code input')
     150    console.error('[BOXO Return] Could not get postal code input')
    151151    return
    152152  }
     
    187187  document.body.dispatchEvent(new Event('update_checkout'))
    188188
    189   console.info('[Boxo Return] Ready')
     189  console.info('[BOXO Return] Ready')
    190190}
    191191
  • boxo-return/tags/0.0.29/checkout/checkout.php

    r3218341 r3221460  
    4343
    4444            $boxo_available_url_safe = esc_url(rest_url('boxo/available'));
    45             $info_url_safe = esc_url(Boxo_Options::info_url() ?: self::DEFAULT_INFO_URL);
    46 
    4745            $shop_country_safe = esc_attr(WC()->countries->get_base_country());
    4846            $reusable_checked_attr_safe = esc_attr(Boxo_Options::default_packaging() === 'reusable' ? 'checked' : '');
    4947            $disposable_checked_attr_safe = esc_attr(Boxo_Options::default_packaging() === 'disposable' ? 'checked' : '');
    5048
    51             $heart_icon_safe = file_get_contents(WP_PLUGIN_DIR . '/boxo-return/icons/heart.svg');
    52             $info_icon_safe = file_get_contents(WP_PLUGIN_DIR . '/boxo-return/icons/info.svg');
    53             $trash_icon_safe = file_get_contents(WP_PLUGIN_DIR . '/boxo-return/icons/trash.svg');
    54 
    55             $deposit_formatted_safe = esc_html('(€' . number_format(Boxo_Options::deposit_cents() / 100, 2, ',', '.') . ' statiegeld)');
    56             $disposable_fee_formatted_safe = Boxo_Options::disposable_fee_enabled() ? esc_html('(€' . number_format(Boxo_Options::disposable_fee_cents() / 100, 2, ',', '.') . ')') : '';
    57 
     49            $reusable_label = self::reusable_label();
     50            $disposable_label = self::disposable_label();
     51
     52            $options = Boxo_Options::selection_mode() === Boxo_Options::SELECTION_MODE_FORCE_REUSABLE ?
     53                <<<HTML
     54                $reusable_label
     55                <input name="boxo_packaging" value="reusable" hidden />
     56                HTML
     57                :
     58                <<<HTML
     59                <ul id="shipping_method" class="woocommerce-shipping-methods">
     60                    <li>
     61                        <input
     62                            id="boxo_packaging_reusable"
     63                            name="boxo_packaging"
     64                            class="shipping_method"
     65                            type="radio"
     66                            value="reusable"
     67                            $reusable_checked_attr_safe
     68                        />
     69                        <label for="boxo_packaging_reusable">
     70                            $reusable_label
     71                        </label>
     72                    </li>
     73                    <li>
     74                        <input
     75                            id="boxo_packaging_disposable"
     76                            name="boxo_packaging"
     77                            class="shipping_method"
     78                            type="radio"
     79                            value="disposable"
     80                            $disposable_checked_attr_safe
     81                        />
     82                        <label for="boxo_packaging_disposable">
     83                        $disposable_label
     84                        </label>
     85                    </li>
     86                </ul>
     87                HTML;
     88
     89            $title_safe_html = esc_html__('Packaging', 'boxo-return');
     90            $title_safe_attr = esc_attr__('Packaging', 'boxo-return');
    5891            // The HTML for the input elements is based on the HTML for standard shipping inputs in WooCommerce.
    5992            // A hidden input shows whether Boxo is available so that validation can run accordingly.
     
    6194            <div id="boxo-data" data-boxo-available-url="$boxo_available_url_safe" data-shop-country="$shop_country_safe" style="display: none;"></div>
    6295            <tr id="boxo_container" class="woocommerce-shipping-totals shipping">
    63                 <th>Verzendverpakking</th>
    64                 <td data-title="Verzendverpakking">
     96                <th>$title_safe_html</th>
     97                <td data-title="$title_safe_attr">
    6598                    <div id="boxo_inputs_container"></div>
    6699                    <template id="boxo_inputs_template">
    67100                        <input type="hidden" name="boxo_available" value="true">
    68                         <ul id="shipping_method" class="woocommerce-shipping-methods">
    69                             <li>
    70                                 <input type="radio" name="boxo_packaging" id="boxo_packaging_reusable" value="reusable" class="shipping_method" $reusable_checked_attr_safe />
    71                                 <label for="boxo_packaging_reusable">
    72                                     Herbruikbaar
    73                                     <span class="boxo_option_icon">$heart_icon_safe</span>
    74                                     $deposit_formatted_safe
    75                                     <a class="boxo_info_container" href="$info_url_safe" target="_blank">
    76                                         <span class="boxo_info_icon">$info_icon_safe</span>
    77                                         <div class="boxo_info_tooltip">
    78                                             We versturen je bestelling in een herbruikbare verzendverpakking. Lever de verpakking in bij een inleverpunt en ontvang direct je statiegeld terug.
    79                                             Klik voor meer informatie.
    80                                         </div>
    81                                     </a>
    82                                 </label>
    83                             </li>
    84                             <li>
    85                                 <input
    86                                     type="radio"
    87                                     name="boxo_packaging"
    88                                     id="boxo_packaging_disposable"
    89                                     value="disposable"
    90                                     class="shipping_method"
    91                                     $disposable_checked_attr_safe
    92                                 />
    93                                 <label for="boxo_packaging_disposable">
    94                                     Eenmalig
    95                                     <span class="boxo_option_icon">$trash_icon_safe</span>
    96                                     $disposable_fee_formatted_safe
    97                                 </label>
    98                             </li>
    99                         </ul>
     101                        $options
    100102                    </template>
    101103                </td>
    102104            </tr>
     105            HTML;
     106        }
     107
     108        private static function reusable_label() {
     109            $deposit_formatted_safe = esc_html('(€' . number_format(Boxo_Options::deposit_cents() / 100, 2, ',', '.') . ' ' . esc_html__('deposit', 'boxo-return') . ')');
     110            $heart_icon_safe = file_get_contents(WP_PLUGIN_DIR . '/boxo-return/icons/heart.svg');
     111            $reusable_safe = esc_html__('Reusable', 'boxo-return');
     112            $info_url_safe = esc_url(Boxo_Options::info_url() ?: self::DEFAULT_INFO_URL);
     113            $info_icon_safe = file_get_contents(WP_PLUGIN_DIR . '/boxo-return/icons/info.svg');
     114            $info_safe = esc_html__('We\'ll send your order in reusable packaging. Return the packaging at a return point to get your deposit back right away. Click for more information.', 'boxo-return');
     115
     116            return <<<HTML
     117            $reusable_safe
     118            <span class="boxo_option_icon">$heart_icon_safe</span>
     119            $deposit_formatted_safe
     120            <a class="boxo_info_container" href="$info_url_safe" target="_blank">
     121                <span class="boxo_info_icon">$info_icon_safe</span>
     122                <div class="boxo_info_tooltip">$info_safe</div>
     123            </a>
     124            HTML;
     125        }
     126
     127        private static function disposable_label() {
     128            $disposable_fee_formatted_safe = Boxo_Options::disposable_fee_enabled() ? esc_html('(€' . number_format(Boxo_Options::disposable_fee_cents() / 100, 2, ',', '.') . ')') : '';
     129            $trash_icon_safe = file_get_contents(WP_PLUGIN_DIR . '/boxo-return/icons/trash.svg');
     130            $disposable_safe = esc_html__('Disposable', 'boxo-return');
     131
     132            return <<<HTML
     133            $disposable_safe
     134            <span class="boxo_option_icon">$trash_icon_safe</span>
     135            $disposable_fee_formatted_safe
    103136            HTML;
    104137        }
     
    123156            if ($post_data['boxo_packaging'] === 'reusable') {
    124157                WC()->cart->add_fee(
    125                     'Statiegeld',
     158                    __('Deposit', 'boxo-return'),
    126159                    Boxo_Options::deposit_cents() / 100,
    127160                    false // Deposit is not taxable.
     
    131164            if (Boxo_Options::disposable_fee_enabled()) {
    132165                WC()->cart->add_fee(
    133                     'Eenmalige verpakking',
     166                    __('Disposable packaging', 'boxo-return'),
    134167                    Boxo_Options::disposable_fee_cents() / 100,
    135168                    true // Disposable fee is taxable.
     
    156189
    157190            if (!isset($post_data['boxo_packaging'])) {
    158                 wc_add_notice(esc_html__('Selecteer een verzendverpakking.'), 'error');
     191                wc_add_notice(esc_html__('Select a packaging option.', 'boxo-return'), 'error');
    159192            }
    160193        }
  • boxo-return/tags/0.0.29/includes/api.php

    r3203659 r3221460  
    4040                foreach ($cart_contents as $item) {
    4141                    if (in_array($item['product_id'], $excluded)) {
     42                        error_log('[BOXO Return] Product not allowed: ' . $item['product_id']);
    4243                        return ['available' => false];
    4344                    }
     
    5051                foreach ($cart_contents as $item) {
    5152                    if (!in_array($item['product_id'], $included)) {
     53                        error_log('[BOXO Return] Product not allowed: ' . $item['product_id']);
    5254                        return ['available' => false];
    5355                    }
     
    7274
    7375            if (is_wp_error($boxo_res)) {
    74                 error_log('[Boxo Return] wp_remote_get error: ' . wp_json_encode($boxo_res->errors));
     76                error_log('[BOXO Return] wp_remote_get error: ' . wp_json_encode($boxo_res->errors));
    7577                $res = rest_ensure_response('Internal server error');
    7678                $res->set_status(500);
     
    8082            if ($boxo_res['response']['code'] !== 200) {
    8183                error_log(implode(" ", [
    82                     '[Boxo Return] Error:',
     84                    '[BOXO Return] Error:',
    8385                    $url,
    8486                    $boxo_res['response']['code'],
     
    9597            $available = $body->available;
    9698            if (!is_bool($available)) {
    97                 error_log('[Boxo Return] Unexpected response: ' . wp_json_encode($boxo_res));
     99                error_log('[BOXO Return] Unexpected response: ' . wp_json_encode($boxo_res));
    98100                $res = rest_ensure_response('Internal server error');
    99101                $res->set_status(500);
     
    102104
    103105            if ($available) {
     106                error_log('[BOXO Return] Available');
    104107                return ['available' => true];
    105108            }
     109            error_log('[BOXO Return] Not available');
    106110            return ['available' => false];
    107111        }
     
    113117}
    114118
    115 // Boxo Return base url can be overwritten when using wp-env
     119// BOXO Return base url can be overwritten when using wp-env
    116120$boxo_api = new Boxo_Api(defined('BOXO_RETURN_BASE_URL') ? BOXO_RETURN_BASE_URL : 'https://api.boxo.nu');
    117121
  • boxo-return/tags/0.0.29/includes/options.php

    r3212861 r3221460  
    1010        public const PRODUCT_ALLOW_MODE_ALL_EXCEPT_EXCLUDED = 'all_except_excluded';
    1111        public const PRODUCT_ALLOW_MODE_INCLUDED_ONLY = 'included_only';
     12        public const SELECTION_MODE_CHOICE = 'choice';
     13        public const SELECTION_MODE_FORCE_REUSABLE = 'force_reusable';
    1214        public const DEFAULT_PACKAGING_REUSABLE = 'reusable';
    1315        public const DEFAULT_PACKAGING_DISPOSABLE = 'disposable';
     
    1820            'disposable_fee_enabled' => false,
    1921            'disposable_fee_cents' => 25,
     22            'selection_mode' => self::SELECTION_MODE_CHOICE,
    2023            'default_packaging' => self::DEFAULT_PACKAGING_REUSABLE,
    2124            'info_url' => '',
     
    3437
    3538        /**
    36          * @return string API key for Boxo Return API.
     39         * @return string API key for BOXO Return API.
    3740         */
    3841        public static function api_key() {
     
    6265
    6366        /**
     67         * @return string How the packaging will be selected.
     68         * One of the following constants: 
     69         * - SELECTION_MODE_CHOICE: customer can choose between reusable and disposable packaging.
     70         * - SELECTION_MODE_FORCE_REUSABLE: reusable packaging will be selected if available.
     71         */
     72        public static function selection_mode() {
     73            return self::option("selection_mode");
     74        }
     75
     76        /**
     77         * @return string Default packaging selected in checkout.
     78         * One of the following constants: 
     79         * - DEFAULT_PACKAGING_REUSABLE: reusable packaging is selected by default.
     80         * - DEFAULT_PACKAGING_DISPOSABLE: disposable packaging is selected by default.
     81         */
     82        public static function default_packaging() {
     83            return self::option("default_packaging");
     84        }
     85
     86        /**
    6487         * @return string URL of an optional information page.
    6588         */
     
    6992
    7093        /**
    71          * @return string Decides which products are allowed in Boxo packaging.
    72          * Boxo packaging will only be offered if all products in cart are allowed.
     94         * @return string Decides which products are allowed in reusable packaging.
     95         * One of the following constants: 
     96         * - PRODUCT_ALLOW_MODE_ALL: all products are allowed.
     97         * - PRODUCT_ALLOW_MODE_ALL_EXCEPT_EXCLUDED: reusable packaging is not allowed if the order contains one or more excluded products.
     98         * - PRODUCT_ALLOW_MODE_INCLUDED_ONLY: reusable packaging is only allowed if all products in the order are in the included products list.
    7399         */
    74100        public static function product_allow_mode() {
     
    89115            return self::option("included_product_ids");
    90116        }
    91 
    92         /**
    93          * @return string Default packaging selected in checkout.
    94          */
    95         public static function default_packaging() {
    96             return self::option("default_packaging");
    97         }
    98117    }
    99118}
  • boxo-return/tags/0.0.29/readme.txt

    r3218341 r3221460  
    44Requires at least: 4.7
    55Tested up to: 6.5.3
    6 Stable tag: 0.0.26
     6Stable tag: 0.0.29
    77Requires PHP: 7.0
    88License: GPLv2 or later
     
    2626
    2727== Changelog ==
     28
     29= 0.0.28 =
     30Add Dutch translations to settings page.
     31
     32= 0.0.28 =
     33Add instructions to settings page.
     34
     35= 0.0.27 =
     36Add option to always use reusable packaging when possible, instead of showing a selection menu at checkout.
    2837
    2938= 0.0.26 =
  • boxo-return/trunk/admin/admin.php

    r3208611 r3221460  
    1919
    2020            add_menu_page(
    21                 'Boxo Return',
    22                 'Boxo Return',
     21                'BOXO Return',
     22                'BOXO Return',
    2323                'manage_options',
    2424                'boxo-return',
     
    3434
    3535            if (isset($_GET['settings-updated'])) {
    36                 add_settings_error('boxo_messages', 'settings_updated', 'Settings saved', 'updated');
     36                add_settings_error('boxo_messages', 'settings_updated', esc_html__('Settings saved', 'boxo-return'), 'updated');
    3737            }
    3838            settings_errors('boxo_messages');
     
    4646            settings_fields('boxo');
    4747            do_settings_sections('boxo');
    48             submit_button('Save');
     48            submit_button(esc_html__('Save', 'boxo-return'));
    4949            echo <<<HTML
    5050                </form>
     
    5656            $url = admin_url('admin.php?page=boxo-return');
    5757            $action_links = array(
    58                 'settings' => '<a href="' . esc_url($url) . '">Settings</a>',
     58                'settings' => '<a href="' . esc_url($url) . '">' . esc_html__('Settings', 'boxo-return') . '</a>',
    5959            );
    6060            return array_merge($action_links, $links);
  • boxo-return/trunk/admin/order.php

    r3212861 r3221460  
    1919        public static function show_order_meta($order) {
    2020            $packaging = $order->get_meta('boxo_packaging', true);
     21            $title_safe = esc_html__('Packaging', 'boxo-return');
    2122
    2223            if (
     
    2526            ) {
    2627                $heart_icon_safe = file_get_contents(WP_PLUGIN_DIR . '/boxo-return/icons/heart.svg');
     28                $packaging_safe = esc_html__('Reusable packaging', 'boxo-return');
    2729                echo <<<HTML
    28                 <h3>Verpakking</h3><br>
     30                <h3>$title_safe</h3><br>
    2931                <div class="boxo_packaging-info">
    3032                    <span class="boxo_packaging-icon">$heart_icon_safe</span>
    31                     Herbruikbare verzendverpakking
     33                    $packaging_safe
    3234                </div>
    3335                HTML;
     
    3941                || $packaging === 'false' // Added for backwards compatibility, can be removed at a later moment.
    4042            ) {
     43                $packaging_safe = esc_html__('Disposable packaging', 'boxo-return');
    4144                echo <<<HTML
    42                 <h3>Verpakking</h3><br>
    43                 Eenmalige verzendverpakking
     45                <h3>$title_safe</h3><br>
     46                $packaging_safe
    4447                HTML;
    4548                return;
    4649            }
    4750
    48             // If the order was placed when Boxo Return was not active, do not echo anything.
     51            // If the order was placed when BOXO Return was not active, do not echo anything.
    4952        }
    5053    }
  • boxo-return/trunk/admin/product-picker.js

    r3208611 r3221460  
    3939      const res = await fetch(ajaxUrl + '?' + params.toString())
    4040      if (!res.ok) {
    41         console.error('[Boxo Return] Search products: ' + res.status + ' ' + res.statusText)
     41        console.error('[BOXO Return] Search products: ' + res.status + ' ' + res.statusText)
    4242        this.searchResults = []
    4343        return
  • boxo-return/trunk/admin/product-picker.php

    r3208611 r3221460  
    4242            $ajax_url_safe = esc_js(admin_url('admin-ajax.php'));
    4343            $nonce_safe = esc_js(wp_create_nonce('boxo'));
     44            $search_label_safe = esc_html__('Add a product:', 'boxo-return');
     45            $search_placeholder_safe = esc_attr__('Product name', 'boxo-return');
     46            $no_results_safe = esc_html__('No products found.', 'boxo-return');
     47            $remove_safe = esc_html__('Remove', 'boxo-return');
    4448
    4549            return <<<HTML
     
    5155                <div class="bxpp_search">
    5256                    <label class="bxpp_search-input-container">
    53                     Add a product:
     57                    $search_label_safe
    5458                    <input
    5559                        type="search"
    5660                        aria-autocomplete="list"
    5761                        aria-controls="bxpp_$name_safe-search-results"
    58                         placeholder="Product title"
     62                        placeholder="$search_placeholder_safe"
    5963                        x-model.debounce.300="keyword"
    6064                    >
     
    7377                        </template>
    7478                        <template x-if="!hasSearchResults()">
    75                             <li class="bxpp_search-result">No products found.</li>
     79                            <li class="bxpp_search-result">$no_results_safe</li>
    7680                        </template>
    7781                    </ul>
     
    9195                                        x-on:click="handleRemoveProductClick(product.id)"
    9296                                    >
    93                                         Remove
     97                                    $remove_safe;
    9498                                    </button>
    9599                                </td>
  • boxo-return/trunk/admin/settings.php

    r3212861 r3221460  
    2828            add_settings_section(
    2929                'section',
    30                 'Settings',
     30                __('Settings', 'boxo-return'),
    3131                'Boxo_Settings::add_section_header',
    3232                'boxo'
     
    3535            add_settings_field(
    3636                'api_key',
    37                 'API Key',
     37                __('API Key', 'boxo-return'),
    3838                'Boxo_Settings::add_api_key_field',
    3939                'boxo',
     
    4747            add_settings_field(
    4848                'deposit_cents',
    49                 'Deposit amount in cents',
     49                __('Deposit amount in cents', 'boxo-return'),
    5050                'Boxo_Settings::add_deposit_cents_field',
    5151                'boxo',
     
    5959            add_settings_field(
    6060                'disposable_fee_enabled',
    61                 'Disposable packaging fee',
     61                __('Disposable packaging fee', 'boxo-return'),
    6262                'Boxo_Settings::add_disposable_fee_enabled_field',
    6363                'boxo',
     
    7070
    7171            add_settings_field(
    72                 'default_packaging',
    73                 'Default packaging',
    74                 'Boxo_Settings::add_default_packaging_field',
    75                 'boxo',
    76                 'section',
    77                 [
    78                     'label_for' => 'boxo_default-packaging-select',
     72                'selection_mode',
     73                __('Packaging selection', 'boxo-return'),
     74                'Boxo_Settings::add_selection_mode_field',
     75                'boxo',
     76                'section',
     77                [
     78                    'label_for' => 'boxo_selection-mode-select',
    7979                    'class' => 'boxo_row',
    8080                ]
     
    8383            add_settings_field(
    8484                'info_url',
    85                 'URL to information page (optional)',
     85                __('URL to information page (optional)', 'boxo-return'),
    8686                'Boxo_Settings::add_info_url_field',
    8787                'boxo',
     
    9595            add_settings_field(
    9696                'product_allow_mode',
    97                 'Availability',
     97                __('Allowed in reusable packaging', 'boxo-return'),
    9898                'Boxo_Settings::add_product_allow_mode_field',
    9999                'boxo',
     
    125125        public static function add_api_key_field() {
    126126            $value_safe = esc_attr(Boxo_Options::api_key());
     127            $description_safe = esc_html__('Enter the API key provided by BOXO Return.', 'boxo-return');
    127128            // The actual API key needs to be present in this input, so that it will not be cleared from storage on save.
    128129            echo <<<HTML
    129             <input id="boxo_api-key-input" class="regular-text" name="boxo_options[api_key]" type="password" value="$value_safe">
     130            <input
     131                id="boxo_api-key-input"
     132                class="regular-text"
     133                name="boxo_options[api_key]"
     134                type="password"
     135                value="$value_safe"
     136                aria-describedby="boxo_api-key-description"
     137            >
     138            <p class="description" id="boxo_api-key-description">$description_safe</p>
    130139            HTML;
    131140        }
     
    140149        public static function add_disposable_fee_enabled_field() {
    141150            $enabled = Boxo_Options::disposable_fee_enabled();
     151            $enabled_safe = $enabled ? 'true' : 'false';
    142152            $checked_attb_safe = $enabled ? 'checked' : '';
    143             $enabled_safe = $enabled ? 'true' : 'false';
     153            $label_safe = esc_html__('Enable disposable packaging fee', 'boxo-return');
     154            $description_safe = esc_html__('If enabled, a fee is charged when the customer does not select reusable packaging.', 'boxo-return');
    144155            $fee_safe = esc_attr(Boxo_Options::disposable_fee_cents());
     156            $cents_label_safe = esc_html__('Fee in cents:', 'boxo-return');
    145157            echo <<<HTML
    146158            <div class="boxo_settings-field" x-data="{enabled: $enabled_safe}">
    147                 <label>
    148                     <input
    149                         id="boxo_disposable-fee-enabled-input"
    150                         name="boxo_options[disposable_fee_enabled]"
    151                         type="checkbox"
    152                         $checked_attb_safe
    153                         x-model="enabled"
    154                     >
    155                     Charge fee for disposable packaging
    156                 </label>
     159                <div>
     160                    <label>
     161                        <input
     162                            id="boxo_disposable-fee-enabled-input"
     163                            name="boxo_options[disposable_fee_enabled]"
     164                            type="checkbox"
     165                            $checked_attb_safe
     166                            x-model="enabled"
     167                            aria-describedby="boxo_disposable-fee-enabled-description"
     168                        >
     169                        $label_safe
     170                    </label>
     171                    <p class="description" id="boxo_disposable-fee-enabled-description">$description_safe</p>
     172                </div>
    157173                <!-- Using x-show instead of x-if, so that invisible settings are not cleared on save. -->
    158174                <label x-show="enabled" x-cloak>
    159                     Fee in cents:
     175                $cents_label_safe
    160176                    <input
    161177                        name="boxo_options[disposable_fee_cents]"
     
    170186        }
    171187
    172         public static function add_default_packaging_field() {
     188        public static function add_selection_mode_field() {
     189            $selection_mode = Boxo_Options::selection_mode();
    173190            $default_packaging = Boxo_Options::default_packaging();
    174191
     192            $choice_safe = Boxo_Options::SELECTION_MODE_CHOICE;
     193            $force_reusable_safe = Boxo_Options::SELECTION_MODE_FORCE_REUSABLE;
    175194            $reusable_safe = Boxo_Options::DEFAULT_PACKAGING_REUSABLE;
    176195            $disposable_safe = Boxo_Options::DEFAULT_PACKAGING_DISPOSABLE;
    177196
     197            $choice_selected_attb_safe = $selection_mode == Boxo_Options::SELECTION_MODE_CHOICE ? 'selected' : '';
     198            $force_reusable_selected_attb_safe = $selection_mode == Boxo_Options::SELECTION_MODE_FORCE_REUSABLE ? 'selected' : '';
    178199            $reusable_selected_attb_safe = $default_packaging == Boxo_Options::DEFAULT_PACKAGING_REUSABLE ? 'selected' : '';
    179200            $disposable_selected_attb_safe = $default_packaging == Boxo_Options::DEFAULT_PACKAGING_DISPOSABLE ? 'selected' : '';
    180201
    181             echo <<<HTML
    182                 <select
    183                     id="boxo_default-packaging-select"
    184                     name="boxo_options[default_packaging]"
    185                     class="regular-text"
    186                     >
    187                     <option value="$reusable_safe" $reusable_selected_attb_safe>Reusable packaging</option>
    188                     <option value="$disposable_safe" $disposable_selected_attb_safe>Disposable packaging</option>
    189                 </select>
     202            $default_packaging_label_safe = esc_html__('Default selection:', 'boxo-return');
     203            $choice_label_safe = esc_html__('Customer chooses packaging', 'boxo-return');
     204            $force_reusable_label_safe = esc_html__('Always use reusable packaging when possible', 'boxo-return');
     205            $reusable_label_safe = esc_html__('Reusable packaging', 'boxo-return');
     206            $disposable_label_safe = esc_html__('Disposable packaging', 'boxo-return');
     207
     208            echo <<<HTML
     209                <div class="boxo_settings-field" x-data="{selectionMode: '$selection_mode'}">
     210                    <select
     211                        id="boxo_selection-mode-select"
     212                        name="boxo_options[selection_mode]"
     213                        class="regular-text"
     214                        x-model="selectionMode"
     215                        >
     216                        <option value="$choice_safe" $choice_selected_attb_safe>$choice_label_safe</option>
     217                        <option value="$force_reusable_safe" $force_reusable_selected_attb_safe>$force_reusable_label_safe</option>
     218                    </select>
     219                    <!-- Using x-show instead of x-if, so that invisible settings are not cleared on save. -->
     220                    <label x-show="selectionMode === 'choice'" x-cloak>
     221                    $default_packaging_label_safe
     222                        <select name="boxo_options[default_packaging]" class="regular-text">
     223                            <option value="$reusable_safe" $reusable_selected_attb_safe>$reusable_label_safe</option>
     224                            <option value="$disposable_safe" $disposable_selected_attb_safe>$disposable_label_safe</option>
     225                        </select>
     226                    </label>
     227                </div>
    190228            HTML;
    191229        }
     
    193231        public static function add_info_url_field() {
    194232            $value_safe = esc_attr(Boxo_Options::info_url());
    195             echo <<<HTML
    196             <input id="boxo_info-url-input" class="regular-text" name="boxo_options[info_url]" type="url" value="$value_safe">
     233            $description_safe = esc_html__('Will open in a new tab when the customer clicks the information button. Defaults to BOXO Return homepage.', 'boxo-return');
     234            echo <<<HTML
     235            <input
     236                id="boxo_info-url-input"
     237                class="regular-text"
     238                name="boxo_options[info_url]"
     239                type="url"
     240                value="$value_safe"
     241                aria-describedby="boxo_info-url-description"
     242            >
     243            <p class="description" id="boxo_info-url-description">$description_safe</p>
    197244            HTML;
    198245        }
     
    208255            $all_except_excluded_selected_attb_safe = $allow_mode == Boxo_Options::PRODUCT_ALLOW_MODE_ALL_EXCEPT_EXCLUDED ? 'selected' : '';
    209256            $included_only_selected_attb_safe = $allow_mode == Boxo_Options::PRODUCT_ALLOW_MODE_INCLUDED_ONLY ? 'selected' : '';
     257
     258            $all_label_safe = esc_html__('All products', 'boxo-return');
     259            $all_except_excluded_label_safe = esc_html__('All products except:', 'boxo-return');
     260            $included_only_label_safe = esc_html__('Only these products:', 'boxo-return');
    210261
    211262            $allow_mode_safe = esc_js($allow_mode);
     
    228279                    class="regular-text"
    229280                    x-model="allowMode">
    230                     <option value="$all_safe" $all_selected_attb_safe>All products</option>
    231                     <option value="$all_except_excluded_safe" $all_except_excluded_selected_attb_safe>All products except:</option>
    232                     <option value="$included_only_safe" $included_only_selected_attb_safe>Only these products:</option>
     281                    <option value="$all_safe" $all_selected_attb_safe>$all_label_safe</option>
     282                    <option value="$all_except_excluded_safe" $all_except_excluded_selected_attb_safe>$all_except_excluded_label_safe</option>
     283                    <option value="$included_only_safe" $included_only_selected_attb_safe>$included_only_label_safe</option>
    233284                </select>
    234285                <!-- Using x-show instead of x-if, so that invisible settings are not cleared on save. -->
  • boxo-return/trunk/boxo-return.php

    r3218341 r3221460  
    22/*
    33* Plugin Name: BOXO Return
    4 * Version: 0.0.26
     4* Version: 0.0.29
    55* Description: Allows customers to select reusable packaging during checkout.
    6 * Author: Boxo
     6* Author: BOXO
    77* Author URI: https://www.boxo.nu
    8 * Developer: Boxo
     8* Developer: BOXO
    99* Developer URI: https://www.boxo.nu
    1010* License: GPLv2
    1111* License URI: https://www.gnu.org/licenses/gpl-2.0.html
    1212* Requires Plugins: woocommerce
     13* Text Domain: boxo-return
     14* Domain Path: /languages
    1315*/
    1416
     
    3537    }
    3638});
     39
     40add_action('init', 'boxo_load_textdomain');
     41
     42function boxo_load_textdomain() {
     43    load_plugin_textdomain('boxo-return', false, dirname(plugin_basename(__FILE__)) . '/languages');
     44}
  • boxo-return/trunk/checkout/checkout.js

    r3212861 r3221460  
    33const serverData = document.getElementById('boxo-data')
    44if (!(serverData instanceof HTMLDivElement)) {
    5   throw new Error('[Boxo Return] Could not get server data')
     5  throw new Error('[BOXO Return] Could not get server data')
    66}
    77
    88const boxoAvailableUrl = serverData.getAttribute('data-boxo-available-url')
    99if (!boxoAvailableUrl) {
    10   throw new Error('[Boxo Return] Could not get Boxo available URL')
     10  throw new Error('[BOXO Return] Could not get Boxo available URL')
    1111}
    1212
     
    2929  const container = document.getElementById('boxo_container')
    3030  if (!(container instanceof HTMLTableRowElement)) {
    31     throw Error('[Boxo Return] Could not get container')
     31    throw Error('[BOXO Return] Could not get container')
    3232  }
    3333
     
    4343  const inputsContainer = document.getElementById('boxo_inputs_container')
    4444  if (!(inputsContainer instanceof HTMLDivElement)) {
    45     throw new Error('[Boxo Return] Could not get inputs container')
     45    throw new Error('[BOXO Return] Could not get inputs container')
    4646  }
    4747
    4848  const inputsTemplate = document.getElementById('boxo_inputs_template')
    4949  if (!(inputsTemplate instanceof HTMLTemplateElement)) {
    50     throw new Error('[Boxo Return] Could not get inputs template')
     50    throw new Error('[BOXO Return] Could not get inputs template')
    5151  }
    5252
     
    5858  const container = document.getElementById('boxo_container')
    5959  if (!(container instanceof HTMLTableRowElement)) {
    60     throw Error('[Boxo Return] Could not get container')
     60    throw Error('[BOXO Return] Could not get container')
    6161  }
    6262
     
    6767  const inputsContainer = document.getElementById('boxo_inputs_container')
    6868  if (!(inputsContainer instanceof HTMLDivElement)) {
    69     throw new Error('[Boxo Return] Could not get inputs container')
     69    throw new Error('[BOXO Return] Could not get inputs container')
    7070  }
    7171
     
    8585  const selectedInput = document.querySelector(`[name=boxo_packaging][value=${state.selection}]`)
    8686  if (!(selectedInput instanceof HTMLInputElement)) {
    87     throw new Error('[Boxo Return] Could not find selected input')
     87    throw new Error('[BOXO Return] Could not find selected input')
    8888  }
    8989  selectedInput.checked = true
     
    101101    const res = await fetch(url.toString())
    102102    if (!res.ok) {
    103       console.error(`[Boxo Return] ${res.status} ${res.statusText}`)
     103      console.error(`[BOXO Return] ${res.status} ${res.statusText}`)
    104104      return false
    105105    }
     
    107107    const available = (await res.json()).available
    108108    if (typeof available !== 'boolean') {
    109       console.error('[Boxo Return] Unexpected response')
     109      console.error('[BOXO Return] Unexpected response')
    110110      return false
    111111    }
     
    113113    return available
    114114  } catch (err) {
    115     console.error('[Boxo Return]', err)
     115    console.error('[BOXO Return]', err)
    116116    return false
    117117  }
     
    148148    : document.getElementById('billing_postcode')
    149149  if (!(postalCodeInput instanceof HTMLInputElement)) {
    150     console.error('[Boxo Return] Could not get postal code input')
     150    console.error('[BOXO Return] Could not get postal code input')
    151151    return
    152152  }
     
    187187  document.body.dispatchEvent(new Event('update_checkout'))
    188188
    189   console.info('[Boxo Return] Ready')
     189  console.info('[BOXO Return] Ready')
    190190}
    191191
  • boxo-return/trunk/checkout/checkout.php

    r3218341 r3221460  
    4343
    4444            $boxo_available_url_safe = esc_url(rest_url('boxo/available'));
    45             $info_url_safe = esc_url(Boxo_Options::info_url() ?: self::DEFAULT_INFO_URL);
    46 
    4745            $shop_country_safe = esc_attr(WC()->countries->get_base_country());
    4846            $reusable_checked_attr_safe = esc_attr(Boxo_Options::default_packaging() === 'reusable' ? 'checked' : '');
    4947            $disposable_checked_attr_safe = esc_attr(Boxo_Options::default_packaging() === 'disposable' ? 'checked' : '');
    5048
    51             $heart_icon_safe = file_get_contents(WP_PLUGIN_DIR . '/boxo-return/icons/heart.svg');
    52             $info_icon_safe = file_get_contents(WP_PLUGIN_DIR . '/boxo-return/icons/info.svg');
    53             $trash_icon_safe = file_get_contents(WP_PLUGIN_DIR . '/boxo-return/icons/trash.svg');
    54 
    55             $deposit_formatted_safe = esc_html('(€' . number_format(Boxo_Options::deposit_cents() / 100, 2, ',', '.') . ' statiegeld)');
    56             $disposable_fee_formatted_safe = Boxo_Options::disposable_fee_enabled() ? esc_html('(€' . number_format(Boxo_Options::disposable_fee_cents() / 100, 2, ',', '.') . ')') : '';
    57 
     49            $reusable_label = self::reusable_label();
     50            $disposable_label = self::disposable_label();
     51
     52            $options = Boxo_Options::selection_mode() === Boxo_Options::SELECTION_MODE_FORCE_REUSABLE ?
     53                <<<HTML
     54                $reusable_label
     55                <input name="boxo_packaging" value="reusable" hidden />
     56                HTML
     57                :
     58                <<<HTML
     59                <ul id="shipping_method" class="woocommerce-shipping-methods">
     60                    <li>
     61                        <input
     62                            id="boxo_packaging_reusable"
     63                            name="boxo_packaging"
     64                            class="shipping_method"
     65                            type="radio"
     66                            value="reusable"
     67                            $reusable_checked_attr_safe
     68                        />
     69                        <label for="boxo_packaging_reusable">
     70                            $reusable_label
     71                        </label>
     72                    </li>
     73                    <li>
     74                        <input
     75                            id="boxo_packaging_disposable"
     76                            name="boxo_packaging"
     77                            class="shipping_method"
     78                            type="radio"
     79                            value="disposable"
     80                            $disposable_checked_attr_safe
     81                        />
     82                        <label for="boxo_packaging_disposable">
     83                        $disposable_label
     84                        </label>
     85                    </li>
     86                </ul>
     87                HTML;
     88
     89            $title_safe_html = esc_html__('Packaging', 'boxo-return');
     90            $title_safe_attr = esc_attr__('Packaging', 'boxo-return');
    5891            // The HTML for the input elements is based on the HTML for standard shipping inputs in WooCommerce.
    5992            // A hidden input shows whether Boxo is available so that validation can run accordingly.
     
    6194            <div id="boxo-data" data-boxo-available-url="$boxo_available_url_safe" data-shop-country="$shop_country_safe" style="display: none;"></div>
    6295            <tr id="boxo_container" class="woocommerce-shipping-totals shipping">
    63                 <th>Verzendverpakking</th>
    64                 <td data-title="Verzendverpakking">
     96                <th>$title_safe_html</th>
     97                <td data-title="$title_safe_attr">
    6598                    <div id="boxo_inputs_container"></div>
    6699                    <template id="boxo_inputs_template">
    67100                        <input type="hidden" name="boxo_available" value="true">
    68                         <ul id="shipping_method" class="woocommerce-shipping-methods">
    69                             <li>
    70                                 <input type="radio" name="boxo_packaging" id="boxo_packaging_reusable" value="reusable" class="shipping_method" $reusable_checked_attr_safe />
    71                                 <label for="boxo_packaging_reusable">
    72                                     Herbruikbaar
    73                                     <span class="boxo_option_icon">$heart_icon_safe</span>
    74                                     $deposit_formatted_safe
    75                                     <a class="boxo_info_container" href="$info_url_safe" target="_blank">
    76                                         <span class="boxo_info_icon">$info_icon_safe</span>
    77                                         <div class="boxo_info_tooltip">
    78                                             We versturen je bestelling in een herbruikbare verzendverpakking. Lever de verpakking in bij een inleverpunt en ontvang direct je statiegeld terug.
    79                                             Klik voor meer informatie.
    80                                         </div>
    81                                     </a>
    82                                 </label>
    83                             </li>
    84                             <li>
    85                                 <input
    86                                     type="radio"
    87                                     name="boxo_packaging"
    88                                     id="boxo_packaging_disposable"
    89                                     value="disposable"
    90                                     class="shipping_method"
    91                                     $disposable_checked_attr_safe
    92                                 />
    93                                 <label for="boxo_packaging_disposable">
    94                                     Eenmalig
    95                                     <span class="boxo_option_icon">$trash_icon_safe</span>
    96                                     $disposable_fee_formatted_safe
    97                                 </label>
    98                             </li>
    99                         </ul>
     101                        $options
    100102                    </template>
    101103                </td>
    102104            </tr>
     105            HTML;
     106        }
     107
     108        private static function reusable_label() {
     109            $deposit_formatted_safe = esc_html('(€' . number_format(Boxo_Options::deposit_cents() / 100, 2, ',', '.') . ' ' . esc_html__('deposit', 'boxo-return') . ')');
     110            $heart_icon_safe = file_get_contents(WP_PLUGIN_DIR . '/boxo-return/icons/heart.svg');
     111            $reusable_safe = esc_html__('Reusable', 'boxo-return');
     112            $info_url_safe = esc_url(Boxo_Options::info_url() ?: self::DEFAULT_INFO_URL);
     113            $info_icon_safe = file_get_contents(WP_PLUGIN_DIR . '/boxo-return/icons/info.svg');
     114            $info_safe = esc_html__('We\'ll send your order in reusable packaging. Return the packaging at a return point to get your deposit back right away. Click for more information.', 'boxo-return');
     115
     116            return <<<HTML
     117            $reusable_safe
     118            <span class="boxo_option_icon">$heart_icon_safe</span>
     119            $deposit_formatted_safe
     120            <a class="boxo_info_container" href="$info_url_safe" target="_blank">
     121                <span class="boxo_info_icon">$info_icon_safe</span>
     122                <div class="boxo_info_tooltip">$info_safe</div>
     123            </a>
     124            HTML;
     125        }
     126
     127        private static function disposable_label() {
     128            $disposable_fee_formatted_safe = Boxo_Options::disposable_fee_enabled() ? esc_html('(€' . number_format(Boxo_Options::disposable_fee_cents() / 100, 2, ',', '.') . ')') : '';
     129            $trash_icon_safe = file_get_contents(WP_PLUGIN_DIR . '/boxo-return/icons/trash.svg');
     130            $disposable_safe = esc_html__('Disposable', 'boxo-return');
     131
     132            return <<<HTML
     133            $disposable_safe
     134            <span class="boxo_option_icon">$trash_icon_safe</span>
     135            $disposable_fee_formatted_safe
    103136            HTML;
    104137        }
     
    123156            if ($post_data['boxo_packaging'] === 'reusable') {
    124157                WC()->cart->add_fee(
    125                     'Statiegeld',
     158                    __('Deposit', 'boxo-return'),
    126159                    Boxo_Options::deposit_cents() / 100,
    127160                    false // Deposit is not taxable.
     
    131164            if (Boxo_Options::disposable_fee_enabled()) {
    132165                WC()->cart->add_fee(
    133                     'Eenmalige verpakking',
     166                    __('Disposable packaging', 'boxo-return'),
    134167                    Boxo_Options::disposable_fee_cents() / 100,
    135168                    true // Disposable fee is taxable.
     
    156189
    157190            if (!isset($post_data['boxo_packaging'])) {
    158                 wc_add_notice(esc_html__('Selecteer een verzendverpakking.'), 'error');
     191                wc_add_notice(esc_html__('Select a packaging option.', 'boxo-return'), 'error');
    159192            }
    160193        }
  • boxo-return/trunk/includes/api.php

    r3203659 r3221460  
    4040                foreach ($cart_contents as $item) {
    4141                    if (in_array($item['product_id'], $excluded)) {
     42                        error_log('[BOXO Return] Product not allowed: ' . $item['product_id']);
    4243                        return ['available' => false];
    4344                    }
     
    5051                foreach ($cart_contents as $item) {
    5152                    if (!in_array($item['product_id'], $included)) {
     53                        error_log('[BOXO Return] Product not allowed: ' . $item['product_id']);
    5254                        return ['available' => false];
    5355                    }
     
    7274
    7375            if (is_wp_error($boxo_res)) {
    74                 error_log('[Boxo Return] wp_remote_get error: ' . wp_json_encode($boxo_res->errors));
     76                error_log('[BOXO Return] wp_remote_get error: ' . wp_json_encode($boxo_res->errors));
    7577                $res = rest_ensure_response('Internal server error');
    7678                $res->set_status(500);
     
    8082            if ($boxo_res['response']['code'] !== 200) {
    8183                error_log(implode(" ", [
    82                     '[Boxo Return] Error:',
     84                    '[BOXO Return] Error:',
    8385                    $url,
    8486                    $boxo_res['response']['code'],
     
    9597            $available = $body->available;
    9698            if (!is_bool($available)) {
    97                 error_log('[Boxo Return] Unexpected response: ' . wp_json_encode($boxo_res));
     99                error_log('[BOXO Return] Unexpected response: ' . wp_json_encode($boxo_res));
    98100                $res = rest_ensure_response('Internal server error');
    99101                $res->set_status(500);
     
    102104
    103105            if ($available) {
     106                error_log('[BOXO Return] Available');
    104107                return ['available' => true];
    105108            }
     109            error_log('[BOXO Return] Not available');
    106110            return ['available' => false];
    107111        }
     
    113117}
    114118
    115 // Boxo Return base url can be overwritten when using wp-env
     119// BOXO Return base url can be overwritten when using wp-env
    116120$boxo_api = new Boxo_Api(defined('BOXO_RETURN_BASE_URL') ? BOXO_RETURN_BASE_URL : 'https://api.boxo.nu');
    117121
  • boxo-return/trunk/includes/options.php

    r3212861 r3221460  
    1010        public const PRODUCT_ALLOW_MODE_ALL_EXCEPT_EXCLUDED = 'all_except_excluded';
    1111        public const PRODUCT_ALLOW_MODE_INCLUDED_ONLY = 'included_only';
     12        public const SELECTION_MODE_CHOICE = 'choice';
     13        public const SELECTION_MODE_FORCE_REUSABLE = 'force_reusable';
    1214        public const DEFAULT_PACKAGING_REUSABLE = 'reusable';
    1315        public const DEFAULT_PACKAGING_DISPOSABLE = 'disposable';
     
    1820            'disposable_fee_enabled' => false,
    1921            'disposable_fee_cents' => 25,
     22            'selection_mode' => self::SELECTION_MODE_CHOICE,
    2023            'default_packaging' => self::DEFAULT_PACKAGING_REUSABLE,
    2124            'info_url' => '',
     
    3437
    3538        /**
    36          * @return string API key for Boxo Return API.
     39         * @return string API key for BOXO Return API.
    3740         */
    3841        public static function api_key() {
     
    6265
    6366        /**
     67         * @return string How the packaging will be selected.
     68         * One of the following constants: 
     69         * - SELECTION_MODE_CHOICE: customer can choose between reusable and disposable packaging.
     70         * - SELECTION_MODE_FORCE_REUSABLE: reusable packaging will be selected if available.
     71         */
     72        public static function selection_mode() {
     73            return self::option("selection_mode");
     74        }
     75
     76        /**
     77         * @return string Default packaging selected in checkout.
     78         * One of the following constants: 
     79         * - DEFAULT_PACKAGING_REUSABLE: reusable packaging is selected by default.
     80         * - DEFAULT_PACKAGING_DISPOSABLE: disposable packaging is selected by default.
     81         */
     82        public static function default_packaging() {
     83            return self::option("default_packaging");
     84        }
     85
     86        /**
    6487         * @return string URL of an optional information page.
    6588         */
     
    6992
    7093        /**
    71          * @return string Decides which products are allowed in Boxo packaging.
    72          * Boxo packaging will only be offered if all products in cart are allowed.
     94         * @return string Decides which products are allowed in reusable packaging.
     95         * One of the following constants: 
     96         * - PRODUCT_ALLOW_MODE_ALL: all products are allowed.
     97         * - PRODUCT_ALLOW_MODE_ALL_EXCEPT_EXCLUDED: reusable packaging is not allowed if the order contains one or more excluded products.
     98         * - PRODUCT_ALLOW_MODE_INCLUDED_ONLY: reusable packaging is only allowed if all products in the order are in the included products list.
    7399         */
    74100        public static function product_allow_mode() {
     
    89115            return self::option("included_product_ids");
    90116        }
    91 
    92         /**
    93          * @return string Default packaging selected in checkout.
    94          */
    95         public static function default_packaging() {
    96             return self::option("default_packaging");
    97         }
    98117    }
    99118}
  • boxo-return/trunk/readme.txt

    r3218341 r3221460  
    44Requires at least: 4.7
    55Tested up to: 6.5.3
    6 Stable tag: 0.0.26
     6Stable tag: 0.0.29
    77Requires PHP: 7.0
    88License: GPLv2 or later
     
    2626
    2727== Changelog ==
     28
     29= 0.0.28 =
     30Add Dutch translations to settings page.
     31
     32= 0.0.28 =
     33Add instructions to settings page.
     34
     35= 0.0.27 =
     36Add option to always use reusable packaging when possible, instead of showing a selection menu at checkout.
    2837
    2938= 0.0.26 =
Note: See TracChangeset for help on using the changeset viewer.