Changeset 3221460
- Timestamp:
- 01/13/2025 09:39:32 AM (13 months ago)
- Location:
- boxo-return
- Files:
-
- 12 added
- 22 edited
- 1 copied
-
tags/0.0.29 (copied) (copied from boxo-return/trunk)
-
tags/0.0.29/admin/admin.php (modified) (4 diffs)
-
tags/0.0.29/admin/order.php (modified) (3 diffs)
-
tags/0.0.29/admin/product-picker.js (modified) (1 diff)
-
tags/0.0.29/admin/product-picker.php (modified) (4 diffs)
-
tags/0.0.29/admin/settings.php (modified) (13 diffs)
-
tags/0.0.29/boxo-return.php (modified) (2 diffs)
-
tags/0.0.29/checkout/checkout.js (modified) (11 diffs)
-
tags/0.0.29/checkout/checkout.php (modified) (5 diffs)
-
tags/0.0.29/includes/api.php (modified) (7 diffs)
-
tags/0.0.29/includes/options.php (modified) (6 diffs)
-
tags/0.0.29/languages (added)
-
tags/0.0.29/languages/boxo-return-nl.po (added)
-
tags/0.0.29/languages/boxo-return-nl_BE.mo (added)
-
tags/0.0.29/languages/boxo-return-nl_NL.mo (added)
-
tags/0.0.29/languages/boxo-return-nl_NL_formal.mo (added)
-
tags/0.0.29/languages/boxo-return.pot (added)
-
tags/0.0.29/readme.txt (modified) (2 diffs)
-
trunk/admin/admin.php (modified) (4 diffs)
-
trunk/admin/order.php (modified) (3 diffs)
-
trunk/admin/product-picker.js (modified) (1 diff)
-
trunk/admin/product-picker.php (modified) (4 diffs)
-
trunk/admin/settings.php (modified) (13 diffs)
-
trunk/boxo-return.php (modified) (2 diffs)
-
trunk/checkout/checkout.js (modified) (11 diffs)
-
trunk/checkout/checkout.php (modified) (5 diffs)
-
trunk/includes/api.php (modified) (7 diffs)
-
trunk/includes/options.php (modified) (6 diffs)
-
trunk/languages (added)
-
trunk/languages/boxo-return-nl.po (added)
-
trunk/languages/boxo-return-nl_BE.mo (added)
-
trunk/languages/boxo-return-nl_NL.mo (added)
-
trunk/languages/boxo-return-nl_NL_formal.mo (added)
-
trunk/languages/boxo-return.pot (added)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
boxo-return/tags/0.0.29/admin/admin.php
r3208611 r3221460 19 19 20 20 add_menu_page( 21 'B oxoReturn',22 'B oxoReturn',21 'BOXO Return', 22 'BOXO Return', 23 23 'manage_options', 24 24 'boxo-return', … … 34 34 35 35 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'); 37 37 } 38 38 settings_errors('boxo_messages'); … … 46 46 settings_fields('boxo'); 47 47 do_settings_sections('boxo'); 48 submit_button( 'Save');48 submit_button(esc_html__('Save', 'boxo-return')); 49 49 echo <<<HTML 50 50 </form> … … 56 56 $url = admin_url('admin.php?page=boxo-return'); 57 57 $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>', 59 59 ); 60 60 return array_merge($action_links, $links); -
boxo-return/tags/0.0.29/admin/order.php
r3212861 r3221460 19 19 public static function show_order_meta($order) { 20 20 $packaging = $order->get_meta('boxo_packaging', true); 21 $title_safe = esc_html__('Packaging', 'boxo-return'); 21 22 22 23 if ( … … 25 26 ) { 26 27 $heart_icon_safe = file_get_contents(WP_PLUGIN_DIR . '/boxo-return/icons/heart.svg'); 28 $packaging_safe = esc_html__('Reusable packaging', 'boxo-return'); 27 29 echo <<<HTML 28 <h3> Verpakking</h3><br>30 <h3>$title_safe</h3><br> 29 31 <div class="boxo_packaging-info"> 30 32 <span class="boxo_packaging-icon">$heart_icon_safe</span> 31 Herbruikbare verzendverpakking33 $packaging_safe 32 34 </div> 33 35 HTML; … … 39 41 || $packaging === 'false' // Added for backwards compatibility, can be removed at a later moment. 40 42 ) { 43 $packaging_safe = esc_html__('Disposable packaging', 'boxo-return'); 41 44 echo <<<HTML 42 <h3> Verpakking</h3><br>43 Eenmalige verzendverpakking45 <h3>$title_safe</h3><br> 46 $packaging_safe 44 47 HTML; 45 48 return; 46 49 } 47 50 48 // If the order was placed when B oxoReturn was not active, do not echo anything.51 // If the order was placed when BOXO Return was not active, do not echo anything. 49 52 } 50 53 } -
boxo-return/tags/0.0.29/admin/product-picker.js
r3208611 r3221460 39 39 const res = await fetch(ajaxUrl + '?' + params.toString()) 40 40 if (!res.ok) { 41 console.error('[B oxoReturn] Search products: ' + res.status + ' ' + res.statusText)41 console.error('[BOXO Return] Search products: ' + res.status + ' ' + res.statusText) 42 42 this.searchResults = [] 43 43 return -
boxo-return/tags/0.0.29/admin/product-picker.php
r3208611 r3221460 42 42 $ajax_url_safe = esc_js(admin_url('admin-ajax.php')); 43 43 $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'); 44 48 45 49 return <<<HTML … … 51 55 <div class="bxpp_search"> 52 56 <label class="bxpp_search-input-container"> 53 Add a product:57 $search_label_safe 54 58 <input 55 59 type="search" 56 60 aria-autocomplete="list" 57 61 aria-controls="bxpp_$name_safe-search-results" 58 placeholder=" Product title"62 placeholder="$search_placeholder_safe" 59 63 x-model.debounce.300="keyword" 60 64 > … … 73 77 </template> 74 78 <template x-if="!hasSearchResults()"> 75 <li class="bxpp_search-result"> No products found.</li>79 <li class="bxpp_search-result">$no_results_safe</li> 76 80 </template> 77 81 </ul> … … 91 95 x-on:click="handleRemoveProductClick(product.id)" 92 96 > 93 Remove97 $remove_safe; 94 98 </button> 95 99 </td> -
boxo-return/tags/0.0.29/admin/settings.php
r3212861 r3221460 28 28 add_settings_section( 29 29 'section', 30 'Settings',30 __('Settings', 'boxo-return'), 31 31 'Boxo_Settings::add_section_header', 32 32 'boxo' … … 35 35 add_settings_field( 36 36 'api_key', 37 'API Key',37 __('API Key', 'boxo-return'), 38 38 'Boxo_Settings::add_api_key_field', 39 39 'boxo', … … 47 47 add_settings_field( 48 48 'deposit_cents', 49 'Deposit amount in cents',49 __('Deposit amount in cents', 'boxo-return'), 50 50 'Boxo_Settings::add_deposit_cents_field', 51 51 'boxo', … … 59 59 add_settings_field( 60 60 'disposable_fee_enabled', 61 'Disposable packaging fee',61 __('Disposable packaging fee', 'boxo-return'), 62 62 'Boxo_Settings::add_disposable_fee_enabled_field', 63 63 'boxo', … … 70 70 71 71 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', 79 79 'class' => 'boxo_row', 80 80 ] … … 83 83 add_settings_field( 84 84 'info_url', 85 'URL to information page (optional)',85 __('URL to information page (optional)', 'boxo-return'), 86 86 'Boxo_Settings::add_info_url_field', 87 87 'boxo', … … 95 95 add_settings_field( 96 96 'product_allow_mode', 97 'Availability',97 __('Allowed in reusable packaging', 'boxo-return'), 98 98 'Boxo_Settings::add_product_allow_mode_field', 99 99 'boxo', … … 125 125 public static function add_api_key_field() { 126 126 $value_safe = esc_attr(Boxo_Options::api_key()); 127 $description_safe = esc_html__('Enter the API key provided by BOXO Return.', 'boxo-return'); 127 128 // The actual API key needs to be present in this input, so that it will not be cleared from storage on save. 128 129 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> 130 139 HTML; 131 140 } … … 140 149 public static function add_disposable_fee_enabled_field() { 141 150 $enabled = Boxo_Options::disposable_fee_enabled(); 151 $enabled_safe = $enabled ? 'true' : 'false'; 142 152 $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'); 144 155 $fee_safe = esc_attr(Boxo_Options::disposable_fee_cents()); 156 $cents_label_safe = esc_html__('Fee in cents:', 'boxo-return'); 145 157 echo <<<HTML 146 158 <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> 157 173 <!-- Using x-show instead of x-if, so that invisible settings are not cleared on save. --> 158 174 <label x-show="enabled" x-cloak> 159 Fee in cents:175 $cents_label_safe 160 176 <input 161 177 name="boxo_options[disposable_fee_cents]" … … 170 186 } 171 187 172 public static function add_default_packaging_field() { 188 public static function add_selection_mode_field() { 189 $selection_mode = Boxo_Options::selection_mode(); 173 190 $default_packaging = Boxo_Options::default_packaging(); 174 191 192 $choice_safe = Boxo_Options::SELECTION_MODE_CHOICE; 193 $force_reusable_safe = Boxo_Options::SELECTION_MODE_FORCE_REUSABLE; 175 194 $reusable_safe = Boxo_Options::DEFAULT_PACKAGING_REUSABLE; 176 195 $disposable_safe = Boxo_Options::DEFAULT_PACKAGING_DISPOSABLE; 177 196 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' : ''; 178 199 $reusable_selected_attb_safe = $default_packaging == Boxo_Options::DEFAULT_PACKAGING_REUSABLE ? 'selected' : ''; 179 200 $disposable_selected_attb_safe = $default_packaging == Boxo_Options::DEFAULT_PACKAGING_DISPOSABLE ? 'selected' : ''; 180 201 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> 190 228 HTML; 191 229 } … … 193 231 public static function add_info_url_field() { 194 232 $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> 197 244 HTML; 198 245 } … … 208 255 $all_except_excluded_selected_attb_safe = $allow_mode == Boxo_Options::PRODUCT_ALLOW_MODE_ALL_EXCEPT_EXCLUDED ? 'selected' : ''; 209 256 $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'); 210 261 211 262 $allow_mode_safe = esc_js($allow_mode); … … 228 279 class="regular-text" 229 280 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> 233 284 </select> 234 285 <!-- 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 2 2 /* 3 3 * Plugin Name: BOXO Return 4 * Version: 0.0.2 64 * Version: 0.0.29 5 5 * Description: Allows customers to select reusable packaging during checkout. 6 * Author: B oxo6 * Author: BOXO 7 7 * Author URI: https://www.boxo.nu 8 * Developer: B oxo8 * Developer: BOXO 9 9 * Developer URI: https://www.boxo.nu 10 10 * License: GPLv2 11 11 * License URI: https://www.gnu.org/licenses/gpl-2.0.html 12 12 * Requires Plugins: woocommerce 13 * Text Domain: boxo-return 14 * Domain Path: /languages 13 15 */ 14 16 … … 35 37 } 36 38 }); 39 40 add_action('init', 'boxo_load_textdomain'); 41 42 function 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 3 3 const serverData = document.getElementById('boxo-data') 4 4 if (!(serverData instanceof HTMLDivElement)) { 5 throw new Error('[B oxoReturn] Could not get server data')5 throw new Error('[BOXO Return] Could not get server data') 6 6 } 7 7 8 8 const boxoAvailableUrl = serverData.getAttribute('data-boxo-available-url') 9 9 if (!boxoAvailableUrl) { 10 throw new Error('[B oxoReturn] Could not get Boxo available URL')10 throw new Error('[BOXO Return] Could not get Boxo available URL') 11 11 } 12 12 … … 29 29 const container = document.getElementById('boxo_container') 30 30 if (!(container instanceof HTMLTableRowElement)) { 31 throw Error('[B oxoReturn] Could not get container')31 throw Error('[BOXO Return] Could not get container') 32 32 } 33 33 … … 43 43 const inputsContainer = document.getElementById('boxo_inputs_container') 44 44 if (!(inputsContainer instanceof HTMLDivElement)) { 45 throw new Error('[B oxoReturn] Could not get inputs container')45 throw new Error('[BOXO Return] Could not get inputs container') 46 46 } 47 47 48 48 const inputsTemplate = document.getElementById('boxo_inputs_template') 49 49 if (!(inputsTemplate instanceof HTMLTemplateElement)) { 50 throw new Error('[B oxoReturn] Could not get inputs template')50 throw new Error('[BOXO Return] Could not get inputs template') 51 51 } 52 52 … … 58 58 const container = document.getElementById('boxo_container') 59 59 if (!(container instanceof HTMLTableRowElement)) { 60 throw Error('[B oxoReturn] Could not get container')60 throw Error('[BOXO Return] Could not get container') 61 61 } 62 62 … … 67 67 const inputsContainer = document.getElementById('boxo_inputs_container') 68 68 if (!(inputsContainer instanceof HTMLDivElement)) { 69 throw new Error('[B oxoReturn] Could not get inputs container')69 throw new Error('[BOXO Return] Could not get inputs container') 70 70 } 71 71 … … 85 85 const selectedInput = document.querySelector(`[name=boxo_packaging][value=${state.selection}]`) 86 86 if (!(selectedInput instanceof HTMLInputElement)) { 87 throw new Error('[B oxoReturn] Could not find selected input')87 throw new Error('[BOXO Return] Could not find selected input') 88 88 } 89 89 selectedInput.checked = true … … 101 101 const res = await fetch(url.toString()) 102 102 if (!res.ok) { 103 console.error(`[B oxoReturn] ${res.status} ${res.statusText}`)103 console.error(`[BOXO Return] ${res.status} ${res.statusText}`) 104 104 return false 105 105 } … … 107 107 const available = (await res.json()).available 108 108 if (typeof available !== 'boolean') { 109 console.error('[B oxoReturn] Unexpected response')109 console.error('[BOXO Return] Unexpected response') 110 110 return false 111 111 } … … 113 113 return available 114 114 } catch (err) { 115 console.error('[B oxoReturn]', err)115 console.error('[BOXO Return]', err) 116 116 return false 117 117 } … … 148 148 : document.getElementById('billing_postcode') 149 149 if (!(postalCodeInput instanceof HTMLInputElement)) { 150 console.error('[B oxoReturn] Could not get postal code input')150 console.error('[BOXO Return] Could not get postal code input') 151 151 return 152 152 } … … 187 187 document.body.dispatchEvent(new Event('update_checkout')) 188 188 189 console.info('[B oxoReturn] Ready')189 console.info('[BOXO Return] Ready') 190 190 } 191 191 -
boxo-return/tags/0.0.29/checkout/checkout.php
r3218341 r3221460 43 43 44 44 $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 47 45 $shop_country_safe = esc_attr(WC()->countries->get_base_country()); 48 46 $reusable_checked_attr_safe = esc_attr(Boxo_Options::default_packaging() === 'reusable' ? 'checked' : ''); 49 47 $disposable_checked_attr_safe = esc_attr(Boxo_Options::default_packaging() === 'disposable' ? 'checked' : ''); 50 48 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'); 58 91 // The HTML for the input elements is based on the HTML for standard shipping inputs in WooCommerce. 59 92 // A hidden input shows whether Boxo is available so that validation can run accordingly. … … 61 94 <div id="boxo-data" data-boxo-available-url="$boxo_available_url_safe" data-shop-country="$shop_country_safe" style="display: none;"></div> 62 95 <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"> 65 98 <div id="boxo_inputs_container"></div> 66 99 <template id="boxo_inputs_template"> 67 100 <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 100 102 </template> 101 103 </td> 102 104 </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 103 136 HTML; 104 137 } … … 123 156 if ($post_data['boxo_packaging'] === 'reusable') { 124 157 WC()->cart->add_fee( 125 'Statiegeld',158 __('Deposit', 'boxo-return'), 126 159 Boxo_Options::deposit_cents() / 100, 127 160 false // Deposit is not taxable. … … 131 164 if (Boxo_Options::disposable_fee_enabled()) { 132 165 WC()->cart->add_fee( 133 'Eenmalige verpakking',166 __('Disposable packaging', 'boxo-return'), 134 167 Boxo_Options::disposable_fee_cents() / 100, 135 168 true // Disposable fee is taxable. … … 156 189 157 190 if (!isset($post_data['boxo_packaging'])) { 158 wc_add_notice(esc_html__('Select eer een verzendverpakking.'), 'error');191 wc_add_notice(esc_html__('Select a packaging option.', 'boxo-return'), 'error'); 159 192 } 160 193 } -
boxo-return/tags/0.0.29/includes/api.php
r3203659 r3221460 40 40 foreach ($cart_contents as $item) { 41 41 if (in_array($item['product_id'], $excluded)) { 42 error_log('[BOXO Return] Product not allowed: ' . $item['product_id']); 42 43 return ['available' => false]; 43 44 } … … 50 51 foreach ($cart_contents as $item) { 51 52 if (!in_array($item['product_id'], $included)) { 53 error_log('[BOXO Return] Product not allowed: ' . $item['product_id']); 52 54 return ['available' => false]; 53 55 } … … 72 74 73 75 if (is_wp_error($boxo_res)) { 74 error_log('[B oxoReturn] 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)); 75 77 $res = rest_ensure_response('Internal server error'); 76 78 $res->set_status(500); … … 80 82 if ($boxo_res['response']['code'] !== 200) { 81 83 error_log(implode(" ", [ 82 '[B oxoReturn] Error:',84 '[BOXO Return] Error:', 83 85 $url, 84 86 $boxo_res['response']['code'], … … 95 97 $available = $body->available; 96 98 if (!is_bool($available)) { 97 error_log('[B oxoReturn] Unexpected response: ' . wp_json_encode($boxo_res));99 error_log('[BOXO Return] Unexpected response: ' . wp_json_encode($boxo_res)); 98 100 $res = rest_ensure_response('Internal server error'); 99 101 $res->set_status(500); … … 102 104 103 105 if ($available) { 106 error_log('[BOXO Return] Available'); 104 107 return ['available' => true]; 105 108 } 109 error_log('[BOXO Return] Not available'); 106 110 return ['available' => false]; 107 111 } … … 113 117 } 114 118 115 // B oxoReturn base url can be overwritten when using wp-env119 // BOXO Return base url can be overwritten when using wp-env 116 120 $boxo_api = new Boxo_Api(defined('BOXO_RETURN_BASE_URL') ? BOXO_RETURN_BASE_URL : 'https://api.boxo.nu'); 117 121 -
boxo-return/tags/0.0.29/includes/options.php
r3212861 r3221460 10 10 public const PRODUCT_ALLOW_MODE_ALL_EXCEPT_EXCLUDED = 'all_except_excluded'; 11 11 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'; 12 14 public const DEFAULT_PACKAGING_REUSABLE = 'reusable'; 13 15 public const DEFAULT_PACKAGING_DISPOSABLE = 'disposable'; … … 18 20 'disposable_fee_enabled' => false, 19 21 'disposable_fee_cents' => 25, 22 'selection_mode' => self::SELECTION_MODE_CHOICE, 20 23 'default_packaging' => self::DEFAULT_PACKAGING_REUSABLE, 21 24 'info_url' => '', … … 34 37 35 38 /** 36 * @return string API key for B oxoReturn API.39 * @return string API key for BOXO Return API. 37 40 */ 38 41 public static function api_key() { … … 62 65 63 66 /** 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 /** 64 87 * @return string URL of an optional information page. 65 88 */ … … 69 92 70 93 /** 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. 73 99 */ 74 100 public static function product_allow_mode() { … … 89 115 return self::option("included_product_ids"); 90 116 } 91 92 /**93 * @return string Default packaging selected in checkout.94 */95 public static function default_packaging() {96 return self::option("default_packaging");97 }98 117 } 99 118 } -
boxo-return/tags/0.0.29/readme.txt
r3218341 r3221460 4 4 Requires at least: 4.7 5 5 Tested up to: 6.5.3 6 Stable tag: 0.0.2 66 Stable tag: 0.0.29 7 7 Requires PHP: 7.0 8 8 License: GPLv2 or later … … 26 26 27 27 == Changelog == 28 29 = 0.0.28 = 30 Add Dutch translations to settings page. 31 32 = 0.0.28 = 33 Add instructions to settings page. 34 35 = 0.0.27 = 36 Add option to always use reusable packaging when possible, instead of showing a selection menu at checkout. 28 37 29 38 = 0.0.26 = -
boxo-return/trunk/admin/admin.php
r3208611 r3221460 19 19 20 20 add_menu_page( 21 'B oxoReturn',22 'B oxoReturn',21 'BOXO Return', 22 'BOXO Return', 23 23 'manage_options', 24 24 'boxo-return', … … 34 34 35 35 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'); 37 37 } 38 38 settings_errors('boxo_messages'); … … 46 46 settings_fields('boxo'); 47 47 do_settings_sections('boxo'); 48 submit_button( 'Save');48 submit_button(esc_html__('Save', 'boxo-return')); 49 49 echo <<<HTML 50 50 </form> … … 56 56 $url = admin_url('admin.php?page=boxo-return'); 57 57 $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>', 59 59 ); 60 60 return array_merge($action_links, $links); -
boxo-return/trunk/admin/order.php
r3212861 r3221460 19 19 public static function show_order_meta($order) { 20 20 $packaging = $order->get_meta('boxo_packaging', true); 21 $title_safe = esc_html__('Packaging', 'boxo-return'); 21 22 22 23 if ( … … 25 26 ) { 26 27 $heart_icon_safe = file_get_contents(WP_PLUGIN_DIR . '/boxo-return/icons/heart.svg'); 28 $packaging_safe = esc_html__('Reusable packaging', 'boxo-return'); 27 29 echo <<<HTML 28 <h3> Verpakking</h3><br>30 <h3>$title_safe</h3><br> 29 31 <div class="boxo_packaging-info"> 30 32 <span class="boxo_packaging-icon">$heart_icon_safe</span> 31 Herbruikbare verzendverpakking33 $packaging_safe 32 34 </div> 33 35 HTML; … … 39 41 || $packaging === 'false' // Added for backwards compatibility, can be removed at a later moment. 40 42 ) { 43 $packaging_safe = esc_html__('Disposable packaging', 'boxo-return'); 41 44 echo <<<HTML 42 <h3> Verpakking</h3><br>43 Eenmalige verzendverpakking45 <h3>$title_safe</h3><br> 46 $packaging_safe 44 47 HTML; 45 48 return; 46 49 } 47 50 48 // If the order was placed when B oxoReturn was not active, do not echo anything.51 // If the order was placed when BOXO Return was not active, do not echo anything. 49 52 } 50 53 } -
boxo-return/trunk/admin/product-picker.js
r3208611 r3221460 39 39 const res = await fetch(ajaxUrl + '?' + params.toString()) 40 40 if (!res.ok) { 41 console.error('[B oxoReturn] Search products: ' + res.status + ' ' + res.statusText)41 console.error('[BOXO Return] Search products: ' + res.status + ' ' + res.statusText) 42 42 this.searchResults = [] 43 43 return -
boxo-return/trunk/admin/product-picker.php
r3208611 r3221460 42 42 $ajax_url_safe = esc_js(admin_url('admin-ajax.php')); 43 43 $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'); 44 48 45 49 return <<<HTML … … 51 55 <div class="bxpp_search"> 52 56 <label class="bxpp_search-input-container"> 53 Add a product:57 $search_label_safe 54 58 <input 55 59 type="search" 56 60 aria-autocomplete="list" 57 61 aria-controls="bxpp_$name_safe-search-results" 58 placeholder=" Product title"62 placeholder="$search_placeholder_safe" 59 63 x-model.debounce.300="keyword" 60 64 > … … 73 77 </template> 74 78 <template x-if="!hasSearchResults()"> 75 <li class="bxpp_search-result"> No products found.</li>79 <li class="bxpp_search-result">$no_results_safe</li> 76 80 </template> 77 81 </ul> … … 91 95 x-on:click="handleRemoveProductClick(product.id)" 92 96 > 93 Remove97 $remove_safe; 94 98 </button> 95 99 </td> -
boxo-return/trunk/admin/settings.php
r3212861 r3221460 28 28 add_settings_section( 29 29 'section', 30 'Settings',30 __('Settings', 'boxo-return'), 31 31 'Boxo_Settings::add_section_header', 32 32 'boxo' … … 35 35 add_settings_field( 36 36 'api_key', 37 'API Key',37 __('API Key', 'boxo-return'), 38 38 'Boxo_Settings::add_api_key_field', 39 39 'boxo', … … 47 47 add_settings_field( 48 48 'deposit_cents', 49 'Deposit amount in cents',49 __('Deposit amount in cents', 'boxo-return'), 50 50 'Boxo_Settings::add_deposit_cents_field', 51 51 'boxo', … … 59 59 add_settings_field( 60 60 'disposable_fee_enabled', 61 'Disposable packaging fee',61 __('Disposable packaging fee', 'boxo-return'), 62 62 'Boxo_Settings::add_disposable_fee_enabled_field', 63 63 'boxo', … … 70 70 71 71 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', 79 79 'class' => 'boxo_row', 80 80 ] … … 83 83 add_settings_field( 84 84 'info_url', 85 'URL to information page (optional)',85 __('URL to information page (optional)', 'boxo-return'), 86 86 'Boxo_Settings::add_info_url_field', 87 87 'boxo', … … 95 95 add_settings_field( 96 96 'product_allow_mode', 97 'Availability',97 __('Allowed in reusable packaging', 'boxo-return'), 98 98 'Boxo_Settings::add_product_allow_mode_field', 99 99 'boxo', … … 125 125 public static function add_api_key_field() { 126 126 $value_safe = esc_attr(Boxo_Options::api_key()); 127 $description_safe = esc_html__('Enter the API key provided by BOXO Return.', 'boxo-return'); 127 128 // The actual API key needs to be present in this input, so that it will not be cleared from storage on save. 128 129 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> 130 139 HTML; 131 140 } … … 140 149 public static function add_disposable_fee_enabled_field() { 141 150 $enabled = Boxo_Options::disposable_fee_enabled(); 151 $enabled_safe = $enabled ? 'true' : 'false'; 142 152 $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'); 144 155 $fee_safe = esc_attr(Boxo_Options::disposable_fee_cents()); 156 $cents_label_safe = esc_html__('Fee in cents:', 'boxo-return'); 145 157 echo <<<HTML 146 158 <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> 157 173 <!-- Using x-show instead of x-if, so that invisible settings are not cleared on save. --> 158 174 <label x-show="enabled" x-cloak> 159 Fee in cents:175 $cents_label_safe 160 176 <input 161 177 name="boxo_options[disposable_fee_cents]" … … 170 186 } 171 187 172 public static function add_default_packaging_field() { 188 public static function add_selection_mode_field() { 189 $selection_mode = Boxo_Options::selection_mode(); 173 190 $default_packaging = Boxo_Options::default_packaging(); 174 191 192 $choice_safe = Boxo_Options::SELECTION_MODE_CHOICE; 193 $force_reusable_safe = Boxo_Options::SELECTION_MODE_FORCE_REUSABLE; 175 194 $reusable_safe = Boxo_Options::DEFAULT_PACKAGING_REUSABLE; 176 195 $disposable_safe = Boxo_Options::DEFAULT_PACKAGING_DISPOSABLE; 177 196 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' : ''; 178 199 $reusable_selected_attb_safe = $default_packaging == Boxo_Options::DEFAULT_PACKAGING_REUSABLE ? 'selected' : ''; 179 200 $disposable_selected_attb_safe = $default_packaging == Boxo_Options::DEFAULT_PACKAGING_DISPOSABLE ? 'selected' : ''; 180 201 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> 190 228 HTML; 191 229 } … … 193 231 public static function add_info_url_field() { 194 232 $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> 197 244 HTML; 198 245 } … … 208 255 $all_except_excluded_selected_attb_safe = $allow_mode == Boxo_Options::PRODUCT_ALLOW_MODE_ALL_EXCEPT_EXCLUDED ? 'selected' : ''; 209 256 $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'); 210 261 211 262 $allow_mode_safe = esc_js($allow_mode); … … 228 279 class="regular-text" 229 280 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> 233 284 </select> 234 285 <!-- Using x-show instead of x-if, so that invisible settings are not cleared on save. --> -
boxo-return/trunk/boxo-return.php
r3218341 r3221460 2 2 /* 3 3 * Plugin Name: BOXO Return 4 * Version: 0.0.2 64 * Version: 0.0.29 5 5 * Description: Allows customers to select reusable packaging during checkout. 6 * Author: B oxo6 * Author: BOXO 7 7 * Author URI: https://www.boxo.nu 8 * Developer: B oxo8 * Developer: BOXO 9 9 * Developer URI: https://www.boxo.nu 10 10 * License: GPLv2 11 11 * License URI: https://www.gnu.org/licenses/gpl-2.0.html 12 12 * Requires Plugins: woocommerce 13 * Text Domain: boxo-return 14 * Domain Path: /languages 13 15 */ 14 16 … … 35 37 } 36 38 }); 39 40 add_action('init', 'boxo_load_textdomain'); 41 42 function boxo_load_textdomain() { 43 load_plugin_textdomain('boxo-return', false, dirname(plugin_basename(__FILE__)) . '/languages'); 44 } -
boxo-return/trunk/checkout/checkout.js
r3212861 r3221460 3 3 const serverData = document.getElementById('boxo-data') 4 4 if (!(serverData instanceof HTMLDivElement)) { 5 throw new Error('[B oxoReturn] Could not get server data')5 throw new Error('[BOXO Return] Could not get server data') 6 6 } 7 7 8 8 const boxoAvailableUrl = serverData.getAttribute('data-boxo-available-url') 9 9 if (!boxoAvailableUrl) { 10 throw new Error('[B oxoReturn] Could not get Boxo available URL')10 throw new Error('[BOXO Return] Could not get Boxo available URL') 11 11 } 12 12 … … 29 29 const container = document.getElementById('boxo_container') 30 30 if (!(container instanceof HTMLTableRowElement)) { 31 throw Error('[B oxoReturn] Could not get container')31 throw Error('[BOXO Return] Could not get container') 32 32 } 33 33 … … 43 43 const inputsContainer = document.getElementById('boxo_inputs_container') 44 44 if (!(inputsContainer instanceof HTMLDivElement)) { 45 throw new Error('[B oxoReturn] Could not get inputs container')45 throw new Error('[BOXO Return] Could not get inputs container') 46 46 } 47 47 48 48 const inputsTemplate = document.getElementById('boxo_inputs_template') 49 49 if (!(inputsTemplate instanceof HTMLTemplateElement)) { 50 throw new Error('[B oxoReturn] Could not get inputs template')50 throw new Error('[BOXO Return] Could not get inputs template') 51 51 } 52 52 … … 58 58 const container = document.getElementById('boxo_container') 59 59 if (!(container instanceof HTMLTableRowElement)) { 60 throw Error('[B oxoReturn] Could not get container')60 throw Error('[BOXO Return] Could not get container') 61 61 } 62 62 … … 67 67 const inputsContainer = document.getElementById('boxo_inputs_container') 68 68 if (!(inputsContainer instanceof HTMLDivElement)) { 69 throw new Error('[B oxoReturn] Could not get inputs container')69 throw new Error('[BOXO Return] Could not get inputs container') 70 70 } 71 71 … … 85 85 const selectedInput = document.querySelector(`[name=boxo_packaging][value=${state.selection}]`) 86 86 if (!(selectedInput instanceof HTMLInputElement)) { 87 throw new Error('[B oxoReturn] Could not find selected input')87 throw new Error('[BOXO Return] Could not find selected input') 88 88 } 89 89 selectedInput.checked = true … … 101 101 const res = await fetch(url.toString()) 102 102 if (!res.ok) { 103 console.error(`[B oxoReturn] ${res.status} ${res.statusText}`)103 console.error(`[BOXO Return] ${res.status} ${res.statusText}`) 104 104 return false 105 105 } … … 107 107 const available = (await res.json()).available 108 108 if (typeof available !== 'boolean') { 109 console.error('[B oxoReturn] Unexpected response')109 console.error('[BOXO Return] Unexpected response') 110 110 return false 111 111 } … … 113 113 return available 114 114 } catch (err) { 115 console.error('[B oxoReturn]', err)115 console.error('[BOXO Return]', err) 116 116 return false 117 117 } … … 148 148 : document.getElementById('billing_postcode') 149 149 if (!(postalCodeInput instanceof HTMLInputElement)) { 150 console.error('[B oxoReturn] Could not get postal code input')150 console.error('[BOXO Return] Could not get postal code input') 151 151 return 152 152 } … … 187 187 document.body.dispatchEvent(new Event('update_checkout')) 188 188 189 console.info('[B oxoReturn] Ready')189 console.info('[BOXO Return] Ready') 190 190 } 191 191 -
boxo-return/trunk/checkout/checkout.php
r3218341 r3221460 43 43 44 44 $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 47 45 $shop_country_safe = esc_attr(WC()->countries->get_base_country()); 48 46 $reusable_checked_attr_safe = esc_attr(Boxo_Options::default_packaging() === 'reusable' ? 'checked' : ''); 49 47 $disposable_checked_attr_safe = esc_attr(Boxo_Options::default_packaging() === 'disposable' ? 'checked' : ''); 50 48 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'); 58 91 // The HTML for the input elements is based on the HTML for standard shipping inputs in WooCommerce. 59 92 // A hidden input shows whether Boxo is available so that validation can run accordingly. … … 61 94 <div id="boxo-data" data-boxo-available-url="$boxo_available_url_safe" data-shop-country="$shop_country_safe" style="display: none;"></div> 62 95 <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"> 65 98 <div id="boxo_inputs_container"></div> 66 99 <template id="boxo_inputs_template"> 67 100 <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 100 102 </template> 101 103 </td> 102 104 </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 103 136 HTML; 104 137 } … … 123 156 if ($post_data['boxo_packaging'] === 'reusable') { 124 157 WC()->cart->add_fee( 125 'Statiegeld',158 __('Deposit', 'boxo-return'), 126 159 Boxo_Options::deposit_cents() / 100, 127 160 false // Deposit is not taxable. … … 131 164 if (Boxo_Options::disposable_fee_enabled()) { 132 165 WC()->cart->add_fee( 133 'Eenmalige verpakking',166 __('Disposable packaging', 'boxo-return'), 134 167 Boxo_Options::disposable_fee_cents() / 100, 135 168 true // Disposable fee is taxable. … … 156 189 157 190 if (!isset($post_data['boxo_packaging'])) { 158 wc_add_notice(esc_html__('Select eer een verzendverpakking.'), 'error');191 wc_add_notice(esc_html__('Select a packaging option.', 'boxo-return'), 'error'); 159 192 } 160 193 } -
boxo-return/trunk/includes/api.php
r3203659 r3221460 40 40 foreach ($cart_contents as $item) { 41 41 if (in_array($item['product_id'], $excluded)) { 42 error_log('[BOXO Return] Product not allowed: ' . $item['product_id']); 42 43 return ['available' => false]; 43 44 } … … 50 51 foreach ($cart_contents as $item) { 51 52 if (!in_array($item['product_id'], $included)) { 53 error_log('[BOXO Return] Product not allowed: ' . $item['product_id']); 52 54 return ['available' => false]; 53 55 } … … 72 74 73 75 if (is_wp_error($boxo_res)) { 74 error_log('[B oxoReturn] 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)); 75 77 $res = rest_ensure_response('Internal server error'); 76 78 $res->set_status(500); … … 80 82 if ($boxo_res['response']['code'] !== 200) { 81 83 error_log(implode(" ", [ 82 '[B oxoReturn] Error:',84 '[BOXO Return] Error:', 83 85 $url, 84 86 $boxo_res['response']['code'], … … 95 97 $available = $body->available; 96 98 if (!is_bool($available)) { 97 error_log('[B oxoReturn] Unexpected response: ' . wp_json_encode($boxo_res));99 error_log('[BOXO Return] Unexpected response: ' . wp_json_encode($boxo_res)); 98 100 $res = rest_ensure_response('Internal server error'); 99 101 $res->set_status(500); … … 102 104 103 105 if ($available) { 106 error_log('[BOXO Return] Available'); 104 107 return ['available' => true]; 105 108 } 109 error_log('[BOXO Return] Not available'); 106 110 return ['available' => false]; 107 111 } … … 113 117 } 114 118 115 // B oxoReturn base url can be overwritten when using wp-env119 // BOXO Return base url can be overwritten when using wp-env 116 120 $boxo_api = new Boxo_Api(defined('BOXO_RETURN_BASE_URL') ? BOXO_RETURN_BASE_URL : 'https://api.boxo.nu'); 117 121 -
boxo-return/trunk/includes/options.php
r3212861 r3221460 10 10 public const PRODUCT_ALLOW_MODE_ALL_EXCEPT_EXCLUDED = 'all_except_excluded'; 11 11 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'; 12 14 public const DEFAULT_PACKAGING_REUSABLE = 'reusable'; 13 15 public const DEFAULT_PACKAGING_DISPOSABLE = 'disposable'; … … 18 20 'disposable_fee_enabled' => false, 19 21 'disposable_fee_cents' => 25, 22 'selection_mode' => self::SELECTION_MODE_CHOICE, 20 23 'default_packaging' => self::DEFAULT_PACKAGING_REUSABLE, 21 24 'info_url' => '', … … 34 37 35 38 /** 36 * @return string API key for B oxoReturn API.39 * @return string API key for BOXO Return API. 37 40 */ 38 41 public static function api_key() { … … 62 65 63 66 /** 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 /** 64 87 * @return string URL of an optional information page. 65 88 */ … … 69 92 70 93 /** 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. 73 99 */ 74 100 public static function product_allow_mode() { … … 89 115 return self::option("included_product_ids"); 90 116 } 91 92 /**93 * @return string Default packaging selected in checkout.94 */95 public static function default_packaging() {96 return self::option("default_packaging");97 }98 117 } 99 118 } -
boxo-return/trunk/readme.txt
r3218341 r3221460 4 4 Requires at least: 4.7 5 5 Tested up to: 6.5.3 6 Stable tag: 0.0.2 66 Stable tag: 0.0.29 7 7 Requires PHP: 7.0 8 8 License: GPLv2 or later … … 26 26 27 27 == Changelog == 28 29 = 0.0.28 = 30 Add Dutch translations to settings page. 31 32 = 0.0.28 = 33 Add instructions to settings page. 34 35 = 0.0.27 = 36 Add option to always use reusable packaging when possible, instead of showing a selection menu at checkout. 28 37 29 38 = 0.0.26 =
Note: See TracChangeset
for help on using the changeset viewer.