diff --git a/README.md b/README.md
index aec3158..1ddd100 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,12 @@
# WooCommerce Indonesia Shipping v2
+> This plugin requires PRO License from RajaOngkir.com. We are not affiliated with them in any way.
+
![](https://raw.github.com/hrsetyono/cdn/master/woocommerce-indo-shipping/ongkir-banner.jpg)
Ultimate *Ongkos Kirim* Plugin for major Indonesian Shipping courier.
-This plugin requires PRO License purchase from RajaOngkir.com. We are not affiliated with RajaOngkir in any way.
-
-This plugin is free and provided as is. We are not responsible for any damage caused by bugs. If you found a bug, please submit it [here](https://github.com/hrsetyono/woocommerce-indo-shipping/issues).
+This plugin is free and provided as is. If you found a bug, please submit it [here](https://github.com/hrsetyono/woocommerce-indo-shipping/issues).
**Supported Couriers:**
diff --git a/dist/ongkir-public.css b/dist/ongkir-public.css
index 59cb260..89c9aed 100644
--- a/dist/ongkir-public.css
+++ b/dist/ongkir-public.css
@@ -1 +1 @@
-.select2-container{width:100% !important}.ongkir-form-row-hidden{display:none !important}
+.select2-container{width:100% !important}.ongkir-form-row-hidden{display:none !important}form.has-ongkir-dropdown #billing_city_field,form.has-ongkir-dropdown #shipping_city_field{display:none !important}form:not(.has-ongkir-dropdown) #_billing_city_field,form:not(.has-ongkir-dropdown) #_shipping_city_field,form:not(.has-ongkir-dropdown) #_billing_district_field,form:not(.has-ongkir-dropdown) #_shipping_district_field{display:none !important}
diff --git a/dist/ongkir-public.js b/dist/ongkir-public.js
index 79976c8..4c2bc2d 100644
--- a/dist/ongkir-public.js
+++ b/dist/ongkir-public.js
@@ -1 +1 @@
-!function(t){var i={};function e(n){if(i[n])return i[n].exports;var o=i[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,e),o.l=!0,o.exports}e.m=t,e.c=i,e.d=function(t,i,n){e.o(t,i)||Object.defineProperty(t,i,{enumerable:!0,get:n})},e.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},e.t=function(t,i){if(1&i&&(t=e(t)),8&i)return t;if(4&i&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(e.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&i&&"string"!=typeof t)for(var o in t)e.d(n,o,function(i){return t[i]}.bind(null,o));return n},e.n=function(t){var i=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(i,"a",i),i},e.o=function(t,i){return Object.prototype.hasOwnProperty.call(t,i)},e.p="",e(e.s=3)}([function(t,i,e){},,,function(t,i,e){"use strict";e.r(i);e(0);const n=ongkirLocalize.ONGKIR_API;var o={get(t){return window.fetch(`${n}${t}`,{method:"GET",headers:{Accept:"application/json"}}).then(this.handleError).then(this.handleContentType).catch(this.throwError)},post(t,i){return window.fetch(`${n}${t}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(i)}).then(this.handleError).then(this.handleContentType).catch(this.throwError)},handleError:t=>t.ok?t:Promise.reject(t.statusText),handleContentType(t){const i=t.headers.get("content-type");return i&&i.includes("application/json")?t.json():Promise.reject("Oops, we haven't got JSON!")},throwError(t){throw new Error(t)}};const l=jQuery,r={init(){this.isFirstRun=!0;document.querySelector("body").classList.contains("woocommerce-checkout")&&(l(document).on("change","#billing_country, #shipping_country",this.toggleCityField.bind(this)),l(document).on("change","#billing_state, #shipping_state",this.populateCitiesDropdown.bind(this)),this.createFields(),l(document).on("change","#_billing_city, #_shipping_city",this.populateDistrictsDropdown.bind(this)),l(document).on("change","#_billing_district, #_shipping_district",this.fillCityField.bind(this)))},createFields(){document.querySelectorAll("#billing_city, #shipping_city").forEach(async t=>{const i="billing_city"===t.getAttribute("id")?"billing":"shipping",e=t.closest(".woocommerce-billing-fields, .woocommerce-shipping-fields"),n=t.closest("#billing_city_field, #shipping_city_field");let r=e.querySelector("#billing_state, #shipping_state").value;r=r||"0";let c=t.value.match(/\[(\d+)\]/);c=c?c[1]:"0";const s=await o.get(`/fields/${i}/${r}/${c}`);l(n).after(s),l("#billing_country, #shipping_country").trigger("change")})},toggleCityField(t){const i=t.currentTarget.closest(".woocommerce-billing-fields, .woocommerce-shipping-fields"),e=i.querySelector("#billing_city_field, #shipping_city_field"),n=i.querySelector("#_billing_city_field, #_shipping_city_field"),o=i.querySelector("#_billing_district_field, #_shipping_district_field");"ID"===t.currentTarget.value?(e.style.display="none",n&&(n.style.display="block"),o&&(o.style.display="block")):(e.style.display="block",n&&(n.style.display="none"),o&&(o.style.display="none"))},async populateCitiesDropdown(t){const i=l(t.currentTarget).val()||"0",e=l(t.currentTarget).closest(".woocommerce-billing-fields, .woocommerce-shipping-fields");if(!this.isFirstRun){e.find("#billing_city_field, #shipping_city_field").find("input").val("")}const n=e.find("#_billing_city_field select, #_shipping_city_field select");n.html("");e.find("#_billing_district_field select, #_shipping_district_field select").html("");const r=await o.get("/cities/"+i);let c="";Object.keys(r).forEach(t=>{c+=``}),n.html(c),this.isFirstRun=!1},async populateDistrictsDropdown(t){const i=l(t.currentTarget).val(),e=l(t.currentTarget).closest(".woocommerce-billing-fields, .woocommerce-shipping-fields"),n=e.find("#billing_state, #shipping_state").val(),r=e.find("#_billing_district_field select, #_shipping_district_field select");r.html("");const c=await o.get(`/districts/${n}/${i}`);let s="";Object.keys(c).forEach(t=>{s+=``}),r.html(s)},fillCityField(t){const i=l(t.currentTarget),e=i.closest(".woocommerce-billing-fields, .woocommerce-shipping-fields").find("#billing_city, #shipping_city");e.val(i.val()),e.trigger("keydown")}};document.addEventListener("DOMContentLoaded",(function(){r.init()})),window.addEventListener("load",(function(){}))}]);
\ No newline at end of file
+!function(t){var e={};function i(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,i),o.l=!0,o.exports}i.m=t,i.c=e,i.d=function(t,e,n){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)i.d(n,o,function(e){return t[e]}.bind(null,o));return n},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=3)}([function(t,e,i){},,,function(t,e,i){"use strict";i.r(e);i(0);const{baseURL:n}=ongkirLocalize;var o={get(t){return window.fetch(`${n}${t}`,{method:"GET",headers:{Accept:"application/json"}}).then(this.handleError).then(this.handleContentType).catch(this.throwError)},post(t,e){return window.fetch(`${n}${t}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)}).then(this.handleError).then(this.handleContentType).catch(this.throwError)},handleError:t=>t.ok?t:Promise.reject(t.statusText),handleContentType(t){const e=t.headers.get("content-type");return e&&e.includes("application/json")?t.json():Promise.reject("Oops, we haven't got JSON!")},throwError(t){throw new Error(t)}};const r=jQuery,l={isFirstRun:!0,init(){document.querySelector("body").classList.contains("woocommerce-checkout")&&(r(document).on("change","#billing_country, #shipping_country",this.toggleCityField.bind(this)),r(document).on("change","#billing_state, #shipping_state",this.populateCitiesDropdown.bind(this)),this.createFields(),r(document).on("change","#_billing_city, #_shipping_city",this.populateDistrictsDropdown.bind(this)),r(document).on("change","#_billing_district, #_shipping_district",this.fillCityField.bind(this)))},createFields(){document.querySelectorAll("#billing_city, #shipping_city").forEach(async t=>{const e="billing_city"===t.getAttribute("id")?"billing":"shipping",i=t.closest(".woocommerce-billing-fields, .woocommerce-shipping-fields"),n=t.closest("#billing_city_field, #shipping_city_field");let l=i.querySelector("#billing_state, #shipping_state").value;l=l||"0";let c=t.value.match(/\[(\d+)\]/);c=c?c[1]:"0";const s=await o.get(`/fields/${e}/${l}/${c}`);r(n).after(s)}),this.toggleCityField({currentTarget:document.querySelector("#billing_country, #shipping_country")})},toggleCityField(t){const e=t.currentTarget.closest("form");"ID"===t.currentTarget.value?e.classList.add("has-ongkir-dropdown"):e.classList.remove("has-ongkir-dropdown")},async populateCitiesDropdown(t){const e=r(t.currentTarget).val()||"0",i=r(t.currentTarget).closest(".woocommerce-billing-fields, .woocommerce-shipping-fields"),n=i.find("#billing_city_field, #shipping_city_field");this.isFirstRun||n.find("input").val("");const l=i.find("#_billing_city_field select, #_shipping_city_field select");l.html("");i.find("#_billing_district_field select, #_shipping_district_field select").html("");const c=await o.get("/cities/"+e);let s="";Object.keys(c).forEach(t=>{s+=``}),l.html(s),l.trigger("change"),this.isFirstRun=!1},async populateDistrictsDropdown(t){const e=r(t.currentTarget).val(),i=r(t.currentTarget).closest(".woocommerce-billing-fields, .woocommerce-shipping-fields"),n=i.find("#billing_state, #shipping_state").val();if(!n)return;const l=i.find("#_billing_district_field select, #_shipping_district_field select");l.html("");const c=await o.get(`/districts/${n}/${e}`);let s="";Object.keys(c).forEach(t=>{s+=``}),l.html(s)},fillCityField(t){const e=r(t.currentTarget),i=e.closest(".woocommerce-billing-fields, .woocommerce-shipping-fields").find("#billing_city, #shipping_city");i.val(e.val()),i.trigger("keydown")}};document.addEventListener("DOMContentLoaded",(function(){l.init()})),window.addEventListener("load",(function(){}))}]);
\ No newline at end of file
diff --git a/includes/ongkir-api.php b/includes/ongkir-api.php
index 1b955c9..63619ae 100644
--- a/includes/ongkir-api.php
+++ b/includes/ongkir-api.php
@@ -68,7 +68,7 @@ function get_cities_api($params) {
*/
function get_districts_api($params) {
$prov_id = Ongkir_Data::get_province_id($params['prov_code']);
- $cities = Ongkir_Data::get_cities($prov_id, true);
+ $cities = Ongkir_Data::get_cities($prov_id);
$city = $cities[$params['city_id']] ?? null;
// abort if city not found
@@ -91,43 +91,32 @@ function get_districts_api($params) {
* @return array
*/
function get_fields_api($params) {
+ $city_id = 0;
+ $field_value = '';
+
// Convert District ID to City ID
if ($params['district_id'] != '0') {
$prov_id = Ongkir_Data::get_province_id($params['prov_code']);
- $cities = Ongkir_Data::get_cities($prov_id, true);
+ $cities = Ongkir_Data::get_cities($prov_id);
- foreach ($cities as $city_id => $c) {
- foreach ($c['districts'] as $district_id => $name) {
+ foreach ($cities as $id => $c) {
+ foreach ($c['districts'] as $dist_id => $dist_name) {
// find district that has the same ID as the one passed on
- if ($params['district_id'] == $district_id) {
- $params['city_id'] = $city_id;
+ if ($params['district_id'] == $dist_id) {
+ $city_id = $id;
+ $field_value = $c['city_name'] . ", {$dist_name} [{$dist_id}]";
break;
}
}
+
+ if ($city_id > 0) {
+ break;
+ }
}
- } else {
- $params['city_id'] = '0';
}
- $cities_field = $this->_get_cities_field($params['type'], $params['prov_code']);
- $districts_field = $this->_get_districts_field($params['type'], $params['prov_code'], $params['city_id']);
-
- // add selected attribute
- if (isset($params['city_id'])) {
- $cities_field = preg_replace(
- '/(_city_field[\s\S]+)(\"' . $params['city_id'] . '\"\s)(\>)([\s\S]+\/p>)/Ui',
- '$1$2selected$3$4',
- $cities_field
- );
- }
-
- if ($params['district_id'] != '0') {
- $districts_field = preg_replace(
- '/(_district_field[\s\S]+)(' . $params['district_id'] . '\]\"\s)(\>)([\s\S]+\/p>)/Ui',
- '$1$2selected$3$4',
- $districts_field
- );
- }
+ $cities_field = $this->_get_cities_field($params['type'], $params['prov_code'], $city_id);
+ $districts_field = $this->_get_districts_field($params['type'], $params['prov_code'], $city_id, $field_value);
return $cities_field . $districts_field;
}
@@ -139,18 +128,18 @@ function get_fields_api($params) {
*
* @return array - Currently only has one item: 'field' which contains the HTML form field.
*/
- private function _get_cities_field($type, $prov_code = '0') {
+ private function _get_cities_field($type, $prov_code = '0', $city_id = 0) {
$field = '';
// if code is 0, show empty placeholder dropdown
if ($prov_code == '0') {
- $field = woocommerce_form_field( "_{$type}_city", [
+ $field = woocommerce_form_field("_{$type}_city", [
'type' => 'select',
'label' => __('City', 'woocommerce'),
'options' => [0 => __('Pilih Provinsi terlebih dahulu...')],
'return' => true,
'required' => true,
- ] );
+ ]);
}
// else
else {
@@ -162,7 +151,7 @@ private function _get_cities_field($type, $prov_code = '0') {
'options' => $cities,
'return' => true,
'required' => true,
- ] );
+ ], $city_id);
}
return $field;
@@ -176,12 +165,13 @@ private function _get_cities_field($type, $prov_code = '0') {
private function _get_districts_field(
$type,
$prov_code,
- $city_id = '0'
+ $city_id = 0,
+ $field_value = ''
) {
$field = '';
// If city ID is empty, show placeholder
- if ($city_id == '0') {
+ if ($city_id === 0) {
$field = woocommerce_form_field("_{$type}_district", [
'type' => 'select',
'label' => __('Kecamatan'),
@@ -203,7 +193,7 @@ private function _get_districts_field(
'options' => $districts,
'return' => true,
'required' => true
- ]);
+ ], $field_value);
}
return $field;
diff --git a/includes/ongkir-data.php b/includes/ongkir-data.php
index 88d7a79..c21ed81 100644
--- a/includes/ongkir-data.php
+++ b/includes/ongkir-data.php
@@ -15,7 +15,7 @@ static function get_cities($prov_id, $raw = false) {
}
// if exists, scan for duplicate city name
- if($data) {
+ if ($data) {
$data = self::_prefix_dupe_city_name($prov_id, $data);
return $data;
} else {
diff --git a/includes/rajaongkir.php b/includes/rajaongkir.php
index 59e8f42..208fc41 100644
--- a/includes/rajaongkir.php
+++ b/includes/rajaongkir.php
@@ -7,7 +7,7 @@
*/
class RajaOngkir {
private $api_key;
- private $base_url;
+ private $base_url = 'https://pro.rajaongkir.com/api';
function __construct($key = null) {
// set API key
@@ -18,15 +18,6 @@ function __construct($key = null) {
$cached_license = get_transient('wcis_license');
$this->api_key = $cached_license['key'];
}
-
- // set base URL
- $urls = [
- 'starter' => 'https://api.rajaongkir.com/starter',
- 'pro' => 'https://pro.rajaongkir.com/api',
- ];
-
- $license_type = 'pro';
- $this->base_url = $urls[$license_type];
}
diff --git a/public/assets/api.js b/public/assets/api.js
index 6362b97..3594963 100644
--- a/public/assets/api.js
+++ b/public/assets/api.js
@@ -5,12 +5,15 @@
* api.get(url).then((result) => { .. });
* api.post(url, data).then((result) => { ... });
*/
-const baseURL = ongkirLocalize.ONGKIR_API;
+const { baseURL } = ongkirLocalize;
+
const api = {
get(endpoint) {
return window.fetch(`${baseURL}${endpoint}`, {
method: 'GET',
- headers: { Accept: 'application/json' },
+ headers: {
+ Accept: 'application/json',
+ },
})
.then(this.handleError)
.then(this.handleContentType)
diff --git a/public/assets/public.js b/public/assets/public.js
index 308428c..eb7402e 100644
--- a/public/assets/public.js
+++ b/public/assets/public.js
@@ -4,10 +4,9 @@ import api from './api';
const $ = jQuery;
const checkoutFields = {
- init() {
- // fix the weird WooCommerce interaction where it initially trigger 'change' on State field
- this.isFirstRun = true;
+ isFirstRun: true, // fix the weird WooCommerce interaction where it initially trigger 'change' on State field
+ init() {
const $body = document.querySelector('body');
// abort if not in Checkout page
@@ -45,9 +44,10 @@ const checkoutFields = {
// get custom fields and append it after the City field
const result = await api.get(`/fields/${type}/${provCode}/${districtID}`);
$($wrapper).after(result);
+ });
- // hide the custom field if country not ID
- $('#billing_country, #shipping_country').trigger('change');
+ this.toggleCityField({
+ currentTarget: document.querySelector('#billing_country, #shipping_country'),
});
},
@@ -55,34 +55,13 @@ const checkoutFields = {
* Show or Hide the original City field depending on the Country selected
*/
toggleCityField(e) {
- const $wrapper = e.currentTarget.closest('.woocommerce-billing-fields, .woocommerce-shipping-fields');
- const $ogCityField = $wrapper.querySelector('#billing_city_field, #shipping_city_field');
+ const $form = e.currentTarget.closest('form');
- // the custom dropdown
- const $citiesField = $wrapper.querySelector('#_billing_city_field, #_shipping_city_field');
- const $districtsField = $wrapper.querySelector('#_billing_district_field, #_shipping_district_field');
-
- // If country is ID, hide the original City field
+ // If country is ID, add a class to hide the original city field
if (e.currentTarget.value === 'ID') {
- $ogCityField.style.display = 'none';
-
- if ($citiesField) {
- $citiesField.style.display = 'block';
- }
-
- if ($districtsField) {
- $districtsField.style.display = 'block';
- }
- } else { // Else, hide the dropdown and show the original field
- $ogCityField.style.display = 'block';
-
- if ($citiesField) {
- $citiesField.style.display = 'none';
- }
-
- if ($districtsField) {
- $districtsField.style.display = 'none';
- }
+ $form.classList.add('has-ongkir-dropdown');
+ } else {
+ $form.classList.remove('has-ongkir-dropdown');
}
},
@@ -95,9 +74,10 @@ const checkoutFields = {
const provCode = $(e.currentTarget).val() || '0';
const $wrapper = $(e.currentTarget).closest('.woocommerce-billing-fields, .woocommerce-shipping-fields');
+ const $ogCityField = $wrapper.find('#billing_city_field, #shipping_city_field');
+
// if not first run, empty out the city field
if (!this.isFirstRun) {
- const $ogCityField = $wrapper.find('#billing_city_field, #shipping_city_field');
$ogCityField.find('input').val('');
}
@@ -111,12 +91,15 @@ const checkoutFields = {
const result = await api.get(`/cities/${provCode}`);
+ // Create the `;
});
$citiesSelect.html(options);
+ $citiesSelect.trigger('change');
this.isFirstRun = false;
},
@@ -130,6 +113,9 @@ const checkoutFields = {
const $wrapper = $(e.currentTarget).closest('.woocommerce-billing-fields, .woocommerce-shipping-fields');
const provCode = $wrapper.find('#billing_state, #shipping_state').val();
+ // Abort if province not selected
+ if (!provCode) { return; }
+
// add 'Loading' message to district field
const $districtsSelect = $wrapper.find('#_billing_district_field select, #_shipping_district_field select');
$districtsSelect.html('');
diff --git a/public/assets/public.sass b/public/assets/public.sass
index 71429ef..ac1cee3 100644
--- a/public/assets/public.sass
+++ b/public/assets/public.sass
@@ -2,4 +2,16 @@
width: 100% !important
.ongkir-form-row-hidden
- display: none !important
\ No newline at end of file
+ display: none !important
+
+form.has-ongkir-dropdown
+ #billing_city_field,
+ #shipping_city_field
+ display: none !important
+
+form:not(.has-ongkir-dropdown)
+ #_billing_city_field,
+ #_shipping_city_field,
+ #_billing_district_field,
+ #_shipping_district_field
+ display: none !important
\ No newline at end of file
diff --git a/public/index.php b/public/index.php
index 7d44d82..a772ce4 100644
--- a/public/index.php
+++ b/public/index.php
@@ -35,7 +35,7 @@ function enqueue_assets() {
wp_enqueue_script('ongkir_script', ONGKIR_FILE . '/dist/ongkir-public.js', ONGKIR_VERSION, true);
wp_localize_script('ongkir_script', 'ongkirLocalize', [
- 'ONGKIR_API' => ONGKIR_API,
+ 'baseURL' => ONGKIR_API,
]);
}
}
diff --git a/public/ongkir-hooks.php b/public/ongkir-hooks.php
index 23f79c1..9f2eafd 100644
--- a/public/ongkir-hooks.php
+++ b/public/ongkir-hooks.php
@@ -61,7 +61,7 @@ function on_update_shipping_address($packages) {
// look for district ID in city field
preg_match('/\[(\d+)\]/', $packages[0]['destination']['city'], $matches);
if (count($matches)) {
- $packages[0]['destination']['destination_id'] = $matches[1];
+ $packages[0]['destination']['destination_id'] = sanitize_text_field($matches[1]);
}
return $packages;
@@ -76,8 +76,8 @@ function on_update_shipping_address($packages) {
*/
private function _clean_city_field($city_raw) {
preg_match('/[\w\s,]+/', $city_raw, $city);
-
- return trim($city[0]);
+ $city = sanitize_text_field(trim($city[0]));
+ return $city;
}
}
diff --git a/woocommerce-ongkir.php b/woocommerce-ongkir.php
index 550d362..09e066f 100644
--- a/woocommerce-ongkir.php
+++ b/woocommerce-ongkir.php
@@ -3,7 +3,7 @@
* Plugin Name: WooCommerce Ongkir Indonesia
* Plugin URI: http://github.com/hrsetyono/woocommerce-ongkir
* Description: Calculate shipping cost for Indonesian couriers like JNE, J&T, TIKI, POS, etc. Requires RajaOngkir PRO License.
- * Version: 2.2.0
+ * Version: 2.3.0
* Author: Pixel Studio
* Author URI: https://pixelstudio.id/
* License: GPL-3.0+
@@ -18,7 +18,7 @@
return;
}
-define('ONGKIR_VERSION', '2.2.1');
+define('ONGKIR_VERSION', '2.3.0');
define('ONGKIR_FILE', plugins_url('', __FILE__));
define('ONGKIR_DIR', __DIR__);
define('ONGKIR_NAMESPACE', 'ongkir/v1');