├── .gitignore ├── index.php ├── assets ├── index.php └── src │ ├── js │ ├── frontend.js │ ├── shared.js │ ├── plugins │ │ └── lockr.js │ ├── polyfill.js │ └── backend.js │ └── scss │ └── backend.scss ├── data ├── index.php ├── woongkir-state.json └── woongkir-country.json ├── includes ├── index.php ├── couriers │ ├── class-woongkir-courier-ide.php │ ├── class-woongkir-courier-wahana.php │ ├── class-woongkir-courier-ninja.php │ ├── class-woongkir-courier-pandu.php │ ├── class-woongkir-courier-indah.php │ ├── class-woongkir-courier-anteraja.php │ ├── class-woongkir-courier-dse.php │ ├── class-woongkir-courier-jet.php │ ├── class-woongkir-courier-rex.php │ ├── class-woongkir-courier-sicepat.php │ ├── class-woongkir-courier-sap.php │ ├── class-woongkir-courier-idl.php │ ├── class-woongkir-courier-pcp.php │ ├── class-woongkir-courier-jnt.php │ ├── class-woongkir-courier-rpx.php │ ├── class-woongkir-courier-star.php │ ├── class-woongkir-courier-sentral.php │ ├── class-woongkir-courier-tiki.php │ ├── class-woongkir-courier-lion.php │ ├── class-woongkir-courier-jtl.php │ ├── class-woongkir-courier-ncs.php │ ├── class-woongkir-courier-pahala.php │ ├── class-woongkir-courier-expedito.php │ ├── class-woongkir-courier-slis.php │ ├── class-woongkir-courier-jne.php │ └── class-woongkir-courier-pos.php ├── accounts │ ├── class-woongkir-account-starter.php │ ├── class-woongkir-account-basic.php │ └── class-woongkir-account-pro.php ├── classes │ ├── class-woongkir-courier.php │ ├── class-woongkir-account.php │ └── class-woongkir.php └── helpers.php ├── .deepsource.toml ├── .editorconfig ├── .travis.yml ├── .jshintrc ├── composer.json ├── package.json ├── woongkir.php ├── phpcs.xml ├── deploy-wp.sh ├── gulpfile.js ├── README.txt └── composer.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | node_modules/* 4 | assets/js/* 5 | assets/css/* 6 | languages/* 7 | dist/* 8 | vendor/* 9 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | =8.0.0 =<10" 13 | }, 14 | "engineStrict": true, 15 | "devDependencies": { 16 | "browser-sync": "^2.24.4", 17 | "gulp": "^3.9.1", 18 | "gulp-autoprefixer": "^5.0.0", 19 | "gulp-bump": "^3.1.1", 20 | "gulp-clean-css": "^3.9.3", 21 | "gulp-concat": "^2.6.1", 22 | "gulp-if": "^2.0.2", 23 | "gulp-iife": "^0.3.0", 24 | "gulp-notify": "^3.2.0", 25 | "gulp-phpcs": "^2.1.0", 26 | "gulp-plumber": "^1.2.0", 27 | "gulp-rename": "^1.2.2", 28 | "gulp-replace": "^1.0.0", 29 | "gulp-sass": "^4.0.1", 30 | "gulp-sourcemaps": "^2.6.4", 31 | "gulp-uglify": "3.0.0", 32 | "gulp-wp-pot": "^2.2.0", 33 | "gulp-zip": "^4.1.0", 34 | "semver": "^6.3.0", 35 | "yargs": "^11.0.0" 36 | }, 37 | "scripts": { 38 | "start": "./node_modules/.bin/gulp", 39 | "build": "./node_modules/.bin/gulp build", 40 | "bump": "./node_modules/.bin/gulp bump", 41 | "dist": "./node_modules/.bin/gulp dist", 42 | "deploy": "yarn dist && ./deploy-wp.sh" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /data/woongkir-state.json: -------------------------------------------------------------------------------- 1 | [{"id":1,"value":"BA","label":"Bali"},{"id":2,"value":"BB","label":"Bangka Belitung"},{"id":3,"value":"BT","label":"Banten"},{"id":4,"value":"BE","label":"Bengkulu"},{"id":5,"value":"YO","label":"DI Yogyakarta"},{"id":6,"value":"JK","label":"DKI Jakarta"},{"id":7,"value":"GO","label":"Gorontalo"},{"id":8,"value":"JA","label":"Jambi"},{"id":9,"value":"JB","label":"Jawa Barat"},{"id":10,"value":"JT","label":"Jawa Tengah"},{"id":11,"value":"JI","label":"Jawa Timur"},{"id":12,"value":"KB","label":"Kalimantan Barat"},{"id":13,"value":"KS","label":"Kalimantan Selatan"},{"id":14,"value":"KT","label":"Kalimantan Tengah"},{"id":15,"value":"KI","label":"Kalimantan Timur"},{"id":16,"value":"KU","label":"Kalimantan Utara"},{"id":17,"value":"KR","label":"Kepulauan Riau"},{"id":18,"value":"LA","label":"Lampung"},{"id":19,"value":"MA","label":"Maluku"},{"id":20,"value":"MU","label":"Maluku Utara"},{"id":21,"value":"AC","label":"Nanggroe Aceh Darussalam (NAD)"},{"id":22,"value":"NB","label":"Nusa Tenggara Barat (NTB)"},{"id":23,"value":"NT","label":"Nusa Tenggara Timur (NTT)"},{"id":24,"value":"PA","label":"Papua"},{"id":25,"value":"PB","label":"Papua Barat"},{"id":26,"value":"RI","label":"Riau"},{"id":27,"value":"SR","label":"Sulawesi Barat"},{"id":28,"value":"SN","label":"Sulawesi Selatan"},{"id":29,"value":"ST","label":"Sulawesi Tengah"},{"id":30,"value":"SG","label":"Sulawesi Tenggara"},{"id":31,"value":"SA","label":"Sulawesi Utara"},{"id":32,"value":"SB","label":"Sumatera Barat"},{"id":33,"value":"SS","label":"Sumatera Selatan"},{"id":34,"value":"SU","label":"Sumatera Utara"}] 2 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-ide.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_IDE extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.3.8 31 | * 32 | * @var string 33 | */ 34 | public $code = 'ide'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.3.8 40 | * 41 | * @var string 42 | */ 43 | public $label = 'IDexpress Service Solution'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.3.8 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://idexpress.com'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.3.8 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'STD' => 'Standard Service', 64 | ); 65 | } 66 | 67 | /** 68 | * Get courier account for domestic shipping 69 | * 70 | * @since 1.3.8 71 | * 72 | * @return array 73 | */ 74 | public function get_account_domestic() { 75 | return array( 76 | 'pro', 77 | ); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-wahana.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_WAHANA extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'wahana'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'Wahana Express'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://www.wahana.com'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'Normal' => 'Normal Service', 64 | ); 65 | } 66 | 67 | /** 68 | * Get courier account for domestic shipping 69 | * 70 | * @since 1.2.12 71 | * 72 | * @return array 73 | */ 74 | public function get_account_domestic() { 75 | return array( 76 | 'pro', 77 | ); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-ninja.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_NINJA extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'ninja'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'Ninja Xpress'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'https://www.ninjaxpress.co'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'STANDARD' => 'Standard Service', 64 | ); 65 | } 66 | 67 | /** 68 | * Get courier account for domestic shipping 69 | * 70 | * @since 1.2.12 71 | * 72 | * @return array 73 | */ 74 | public function get_account_domestic() { 75 | return array( 76 | 'pro', 77 | ); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-pandu.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_PANDU extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'pandu'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'Pandu Logistics'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://www.pandulogistics.com'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'REG' => 'Regular Package', 64 | ); 65 | } 66 | 67 | /** 68 | * Get courier account for domestic shipping 69 | * 70 | * @since 1.2.12 71 | * 72 | * @return array 73 | */ 74 | public function get_account_domestic() { 75 | return array( 76 | 'pro', 77 | ); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-indah.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_INDAH extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'indah'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'Indah Logistic'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://www.indahonline.com'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'DARAT' => 'Cargo Darat', 64 | 'UDARA' => 'Cargo Udara', 65 | ); 66 | } 67 | 68 | /** 69 | * Get courier account for domestic shipping 70 | * 71 | * @since 1.2.12 72 | * 73 | * @return array 74 | */ 75 | public function get_account_domestic() { 76 | return array( 77 | 'pro', 78 | ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-anteraja.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_ANTERAJA extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'anteraja'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'AnterAja'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://anteraja.id'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'ND' => 'Next Day', 64 | 'REG' => 'Regular', 65 | 'SD' => 'Same Day', 66 | ); 67 | } 68 | 69 | /** 70 | * Get courier account for domestic shipping 71 | * 72 | * @since 1.2.12 73 | * 74 | * @return array 75 | */ 76 | public function get_account_domestic() { 77 | return array( 78 | 'pro', 79 | ); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-dse.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_DSE extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'dse'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = '21 Express'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://21express.co.id'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'ECO' => 'Regular Service', 64 | 'ONS' => 'Over Night Service', 65 | 'SDS' => 'Same Day Service', 66 | ); 67 | } 68 | 69 | /** 70 | * Get courier account for domestic shipping 71 | * 72 | * @since 1.2.12 73 | * 74 | * @return array 75 | */ 76 | public function get_account_domestic() { 77 | return array( 78 | 'pro', 79 | ); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-jet.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_JET extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'jet'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'JET Express'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://www.jetexpress.co.id'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'CRG' => 'Cargo', 64 | 'PRI' => 'Priority', 65 | 'REG' => 'Regular', 66 | 'XPS' => 'Express', 67 | ); 68 | } 69 | 70 | /** 71 | * Get courier account for domestic shipping 72 | * 73 | * @since 1.2.12 74 | * 75 | * @return array 76 | */ 77 | public function get_account_domestic() { 78 | return array( 79 | 'pro', 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-rex.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_REX extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'rex'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'Royal Express Indonesia'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'https://www.rex.co.id'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'EXP' => 'EXPRESS', 64 | 'REG' => 'REGULAR', 65 | 'REX-1' => 'REX-1', 66 | 'REX-10' => 'REX-10', 67 | 'REX-5' => 'REX-5', 68 | ); 69 | } 70 | 71 | /** 72 | * Get courier account for domestic shipping 73 | * 74 | * @since 1.2.12 75 | * 76 | * @return array 77 | */ 78 | public function get_account_domestic() { 79 | return array( 80 | 'pro', 81 | ); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-sicepat.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_SICEPAT extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'sicepat'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'SiCepat Express'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://www.sicepat.com'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'BEST' => 'Besok Sampai Tujuan', 64 | 'GOKIL' => 'Cargo', 65 | 'REG' => 'Layanan Reguler', 66 | 'SIUNT' => 'SiUntung', 67 | ); 68 | } 69 | 70 | /** 71 | * Get courier account for domestic shipping 72 | * 73 | * @since 1.2.12 74 | * 75 | * @return array 76 | */ 77 | public function get_account_domestic() { 78 | return array( 79 | 'pro', 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-sap.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_SAP extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'sap'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'SAP Express'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://sap-express.id'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'CARGO DARAT' => 'REGULAR DARAT', 64 | 'ODS' => 'One Day Service', 65 | 'REG' => 'Regular Service', 66 | 'SDS' => 'Same Day Service', 67 | ); 68 | } 69 | 70 | /** 71 | * Get courier account for domestic shipping 72 | * 73 | * @since 1.2.12 74 | * 75 | * @return array 76 | */ 77 | public function get_account_domestic() { 78 | return array( 79 | 'pro', 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-idl.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_IDL extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'idl'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'Indotama Domestik Lestari'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://www.idlcargo.co.id'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'iCon' => 'EKONOMIS', 64 | 'iONS' => 'OVERNIGHT SERVICES', 65 | 'iREG' => 'REGULAR', 66 | 'iSCF' => 'SPECIAL FLEET', 67 | 'iSDS' => 'SAME DAY SERVICES', 68 | ); 69 | } 70 | 71 | /** 72 | * Get courier account for domestic shipping 73 | * 74 | * @since 1.2.12 75 | * 76 | * @return array 77 | */ 78 | public function get_account_domestic() { 79 | return array( 80 | 'pro', 81 | ); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-pcp.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_PCP extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'pcp'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'PCP'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://www.pcpexpress.com'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'EXIS' => 'Express Ekonomi', 64 | 'GODA' => 'Kargo Darat', 65 | 'HIT' => 'Hari Ini Tiba', 66 | 'JET' => 'Jaminan Esok Tiba', 67 | 'TREX' => 'Titipan Regular Express', 68 | ); 69 | } 70 | 71 | /** 72 | * Get courier account for domestic shipping 73 | * 74 | * @since 1.2.12 75 | * 76 | * @return array 77 | */ 78 | public function get_account_domestic() { 79 | return array( 80 | 'basic', 81 | 'pro', 82 | ); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-jnt.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_JNT extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'jnt'; 35 | 36 | /** 37 | * API Response ID 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $response_code = 'J&T'; 44 | 45 | /** 46 | * Courier Label 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $label = 'J&T Express'; 53 | 54 | /** 55 | * Courier Website 56 | * 57 | * @since 1.2.12 58 | * 59 | * @var string 60 | */ 61 | public $website = 'http://www.jet.co.id'; 62 | 63 | /** 64 | * Get courier services for domestic shipping 65 | * 66 | * @since 1.2.12 67 | * 68 | * @return array 69 | */ 70 | public function get_services_domestic_default() { 71 | return array( 72 | 'EZ' => 'Regular Service', 73 | 'JSD' => 'Same Day Service', 74 | ); 75 | } 76 | 77 | /** 78 | * Get courier account for domestic shipping 79 | * 80 | * @since 1.2.12 81 | * 82 | * @return array 83 | */ 84 | public function get_account_domestic() { 85 | return array( 86 | 'pro', 87 | ); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-rpx.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_RPX extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'rpx'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'RPX'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://www.rpx.co.id'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'MDP' => 'MidDay Package', 64 | 'NDP' => 'Next Day Package', 65 | 'PAS' => 'Paket Ambil Suka-Suka', 66 | 'PSR' => 'PAS Reguler', 67 | 'RGP' => 'Regular Package', 68 | 'SDP' => 'SameDay Package', 69 | ); 70 | } 71 | 72 | /** 73 | * Get courier account for domestic shipping 74 | * 75 | * @since 1.2.12 76 | * 77 | * @return array 78 | */ 79 | public function get_account_domestic() { 80 | return array( 81 | 'basic', 82 | 'pro', 83 | ); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-star.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_STAR extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'star'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'Star Cargo'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://www.starcargo.co.id'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'Dokumen' => 'Dokumen', 64 | 'Express' => 'Express', 65 | 'MOTOR 150 - 250 CC' => 'MOTOR 150 - 250 CC', 66 | 'MOTOR' => 'MOTOR', 67 | 'Reguler' => 'Reguler', 68 | ); 69 | } 70 | 71 | /** 72 | * Get courier account for domestic shipping 73 | * 74 | * @since 1.2.12 75 | * 76 | * @return array 77 | */ 78 | public function get_account_domestic() { 79 | return array( 80 | 'pro', 81 | ); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-sentral.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_SENTRAL extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.3.8 31 | * 32 | * @var string 33 | */ 34 | public $code = 'sentral'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.3.8 40 | * 41 | * @var string 42 | */ 43 | public $label = 'Sentral Cargo'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.3.8 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://sentralcargo.co.id'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.3.8 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'DARAT ELEKTRONIK' => 'DARAT ELEKTRONIK', 64 | 'DARAT NON ELEKTRONIK' => 'DARAT NON ELEKTRONIK', 65 | 'UDARA ELEKTRONIK' => 'UDARA ELEKTRONIK', 66 | 'UDARA NON ELEKTRONIK' => 'UDARA NON ELEKTRONIK', 67 | ); 68 | } 69 | 70 | /** 71 | * Get courier account for domestic shipping 72 | * 73 | * @since 1.3.8 74 | * 75 | * @return array 76 | */ 77 | public function get_account_domestic() { 78 | return array( 79 | 'pro', 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-tiki.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_TIKI extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'tiki'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'TIKI'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://tiki.id'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'ECO' => 'Economy Service', 64 | 'HDS' => 'Holiday Services', 65 | 'ONS' => 'Over Night Service', 66 | 'REG' => 'Regular Service', 67 | 'SDS' => 'Same Day Service', 68 | 'TRC' => 'Trucking Service', 69 | ); 70 | } 71 | 72 | /** 73 | * Get courier account for domestic shipping 74 | * 75 | * @since 1.2.12 76 | * 77 | * @return array 78 | */ 79 | public function get_account_domestic() { 80 | return array( 81 | 'starter', 82 | 'basic', 83 | 'pro', 84 | ); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-lion.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_LION extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'lion'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'Lion Parcel'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://lionparcel.com'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'BIGPACK' => 'Big Package Service', 64 | 'JAGOPACK' => 'Economy Service', 65 | 'JAGOPACK' => 'Economy Service', 66 | 'LANDPACK' => 'Logistic Service', 67 | 'ONEPACK' => 'One Day Service', 68 | 'REGPACK' => 'Regular Service', 69 | ); 70 | } 71 | 72 | /** 73 | * Get courier account for domestic shipping 74 | * 75 | * @since 1.2.12 76 | * 77 | * @return array 78 | */ 79 | public function get_account_domestic() { 80 | return array( 81 | 'pro', 82 | ); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-jtl.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_JTL extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.3.8 31 | * 32 | * @var string 33 | */ 34 | public $code = 'jtl'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.3.8 40 | * 41 | * @var string 42 | */ 43 | public $label = 'JTL Express'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.3.8 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://www.jtlexpress.co.id'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.3.8 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'EXPRESS ECONOMY' => 'Express Economy', 64 | 'EXPRESS STANDART' => 'Express Standart', 65 | 'JTL EXTRA' => 'JTL Extra', 66 | 'JTL HAPPY' => 'JTL Happy', 67 | 'JTLOG' => 'JTLog', 68 | 'NON EXPRESS' => 'Non Express', 69 | ); 70 | } 71 | 72 | /** 73 | * Get courier account for domestic shipping 74 | * 75 | * @since 1.3.8 76 | * 77 | * @return array 78 | */ 79 | public function get_account_domestic() { 80 | return array( 81 | 'pro', 82 | ); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-ncs.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_NCS extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'ncs'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'Nusantara Card Semesta'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://www.ptncs.com'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'DRT' => 'Regular Darat', 64 | 'JMR' => 'Jawa Murah', 65 | 'NFO' => 'Food-One Night Service', 66 | 'NFO' => 'Food-One Night Service', 67 | 'NRS' => 'REGULAR SERVICE', 68 | 'ONS' => 'OVERNIGHT SERVICE', 69 | 'SDS' => 'SAME DAY SERVICE', 70 | ); 71 | } 72 | 73 | /** 74 | * Get courier account for domestic shipping 75 | * 76 | * @since 1.2.12 77 | * 78 | * @return array 79 | */ 80 | public function get_account_domestic() { 81 | return array( 82 | 'pro', 83 | ); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-pahala.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_PAHALA extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'pahala'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'Pahala Express'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://www.pahalaexpress.co.id'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'EXPRESS' => 'Express Service', 64 | 'MOTOR BEBEK' => 'Paket Motor Bebek', 65 | 'MOTOR BESAR' => 'Paket Motor Besar', 66 | 'MOTOR SPORT' => 'Paket Motor Sport', 67 | 'ONS' => 'One Night Service', 68 | 'SDS' => 'Same Day Service', 69 | 'SEPEDA' => 'Paket Sepeda', 70 | ); 71 | } 72 | 73 | /** 74 | * Get courier account for domestic shipping 75 | * 76 | * @since 1.2.12 77 | * 78 | * @return array 79 | */ 80 | public function get_account_domestic() { 81 | return array( 82 | 'pro', 83 | ); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /includes/accounts/class-woongkir-account-starter.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Account_Starter extends Woongkir_Account { 26 | 27 | /** 28 | * Account priority 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var int 33 | */ 34 | public $priority = 1; 35 | 36 | /** 37 | * Account type 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $type = 'starter'; 44 | 45 | /** 46 | * Account label 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $label = 'Starter'; 53 | 54 | /** 55 | * Account API URL 56 | * 57 | * @since 1.2.12 58 | * 59 | * @var string 60 | */ 61 | public $api_url = 'http://api.rajaongkir.com/starter'; 62 | 63 | /** 64 | * Account features 65 | * 66 | * @since 1.2.12 67 | * 68 | * @var array 69 | */ 70 | protected $features = array( 71 | 'subdistrict' => false, 72 | 'multiple_couriers' => false, 73 | 'volumetric' => false, 74 | 'weight_over_30kg' => false, 75 | 'dedicated_server' => false, 76 | ); 77 | 78 | /** 79 | * Parse API request parameters. 80 | * 81 | * @since 1.2.12 82 | * 83 | * @param array $params API request parameters to parse. 84 | * @param string $endpoint API request endpoint. 85 | * 86 | * @return (array|WP_Error) 87 | */ 88 | public function api_request_parser( $params = array(), $endpoint = '' ) { 89 | if ( '/cost' === $endpoint ) { 90 | $this->api_request_params_required = array( 91 | 'origin', 92 | 'destination', 93 | 'weight', 94 | 'courier', 95 | ); 96 | } 97 | 98 | return parent::api_request_parser( $params ); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /woongkir.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_EXPEDITO extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'expedito'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'Expedito'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://www.expedito.co.id'; 53 | 54 | /** 55 | * Get courier services for international shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_international_default() { 62 | return array( 63 | 'ARAMEX Indonesia' => 'ARAMEX Indonesia', 64 | 'CityLink Express' => 'CityLink Express', 65 | 'CityLink' => 'CityLink', 66 | 'DHL JKT' => 'DHL JKT', 67 | 'DHL Singapore' => 'DHL Singapore', 68 | 'DPEX' => 'DPEX', 69 | 'Moon Forwarder' => 'Moon Forwarder', 70 | 'NetworkCourierSG' => 'NetworkCourierSG', 71 | 'SF EXPRESS' => 'SF EXPRESS', 72 | 'SkyNet Worldwide' => 'SkyNet Worldwide', 73 | 'SkySaver by Skynet Worldwide' => 'SkySaver by Skynet Worldwide', 74 | 'TNT | Fedex' => 'TNT | Fedex', 75 | ); 76 | } 77 | 78 | /** 79 | * Get courier account for international shipping 80 | * 81 | * @since 1.2.12 82 | * 83 | * @return array 84 | */ 85 | public function get_account_international() { 86 | return array( 87 | 'pro', 88 | ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-slis.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_SLIS extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'slis'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'Solusi Ekspres'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://www.solusiekspres.com'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'EXPRESS' => 'Express Service', 64 | 'REGULAR' => 'Regular Service', 65 | ); 66 | } 67 | 68 | /** 69 | * Get courier services for international shipping 70 | * 71 | * @since 1.2.12 72 | * 73 | * @return array 74 | */ 75 | public function get_services_international_default() { 76 | return array( 77 | 'PACKAGE' => 'PACKAGE', 78 | 'COSMETIC/FOOD' => 'COSMETIC/FOOD', 79 | ); 80 | } 81 | 82 | /** 83 | * Get courier account for domestic shipping 84 | * 85 | * @since 1.2.12 86 | * 87 | * @return array 88 | */ 89 | public function get_account_domestic() { 90 | return array( 91 | 'pro', 92 | ); 93 | } 94 | 95 | /** 96 | * Get courier account for international shipping 97 | * 98 | * @since 1.2.12 99 | * 100 | * @return array 101 | */ 102 | public function get_account_international() { 103 | return array( 104 | 'pro', 105 | ); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-jne.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_JNE extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'jne'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'JNE'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://www.jne.co.id'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'CTC' => 'City Courier', 64 | 'CTCYES' => 'City Courier YES', 65 | 'OKE' => 'Ongkos Kirim Ekonomis', 66 | 'REG' => 'Layanan Reguler', 67 | 'YES' => 'Yakin Esok Sampai', 68 | ); 69 | } 70 | 71 | /** 72 | * Get courier services for international shipping 73 | * 74 | * @since 1.2.12 75 | * 76 | * @return array 77 | */ 78 | public function get_services_international_default() { 79 | return array( 80 | 'INTL' => 'INTL', 81 | ); 82 | } 83 | 84 | /** 85 | * Get courier account for domestic shipping 86 | * 87 | * @since 1.2.12 88 | * 89 | * @return array 90 | */ 91 | public function get_account_domestic() { 92 | return array( 93 | 'starter', 94 | 'basic', 95 | 'pro', 96 | ); 97 | } 98 | 99 | /** 100 | * Get courier account for international shipping 101 | * 102 | * @since 1.2.12 103 | * 104 | * @return array 105 | */ 106 | public function get_account_international() { 107 | return array( 108 | 'pro', 109 | ); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /includes/accounts/class-woongkir-account-basic.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Account_Basic extends Woongkir_Account { 26 | 27 | /** 28 | * Account priority 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var int 33 | */ 34 | public $priority = 2; 35 | 36 | /** 37 | * Account type 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $type = 'basic'; 44 | 45 | /** 46 | * Account label 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $label = 'Basic'; 53 | 54 | /** 55 | * Account API URL 56 | * 57 | * @since 1.2.12 58 | * 59 | * @var string 60 | */ 61 | public $api_url = 'http://api.rajaongkir.com/basic'; 62 | 63 | /** 64 | * Account features 65 | * 66 | * @since 1.2.12 67 | * 68 | * @var array 69 | */ 70 | protected $features = array( 71 | 'subdistrict' => false, 72 | 'multiple_couriers' => true, 73 | 'volumetric' => false, 74 | 'weight_over_30kg' => false, 75 | 'dedicated_server' => false, 76 | ); 77 | 78 | /** 79 | * Parse API request parameters. 80 | * 81 | * @since 1.2.12 82 | * 83 | * @param array $params API request parameters to parse. 84 | * @param string $endpoint API request endpoint. 85 | * 86 | * @return (array|WP_Error) 87 | */ 88 | public function api_request_parser( $params = array(), $endpoint = '' ) { 89 | if ( '/cost' === $endpoint ) { 90 | $this->api_request_params_required = array( 91 | 'origin', 92 | 'destination', 93 | 'weight', 94 | 'courier', 95 | ); 96 | } elseif ( '/v2/internationalCost' === $endpoint ) { 97 | $this->api_request_params_required = array( 98 | 'origin', 99 | 'destination', 100 | 'weight', 101 | 'courier', 102 | ); 103 | } 104 | 105 | return parent::api_request_parser( $params ); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /phpcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Generally-applicable sniffs for WordPress plugins. 4 | 5 | 6 | . 7 | /vendor/ 8 | /node_modules/ 9 | /tests/ 10 | /dist/ 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /includes/accounts/class-woongkir-account-pro.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Account_Pro extends Woongkir_Account { 26 | 27 | /** 28 | * Account priority 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var int 33 | */ 34 | public $priority = 3; 35 | 36 | /** 37 | * Account type 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $type = 'pro'; 44 | 45 | /** 46 | * Account label 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $label = 'Pro'; 53 | 54 | /** 55 | * Account API URL 56 | * 57 | * @since 1.2.12 58 | * 59 | * @var string 60 | */ 61 | public $api_url = 'http://pro.rajaongkir.com/api'; 62 | 63 | /** 64 | * Account features 65 | * 66 | * @since 1.2.12 67 | * 68 | * @var array 69 | */ 70 | protected $features = array( 71 | 'subdistrict' => true, 72 | 'multiple_couriers' => true, 73 | 'volumetric' => true, 74 | 'weight_over_30kg' => true, 75 | 'dedicated_server' => true, 76 | ); 77 | 78 | /** 79 | * Parse API request parameters. 80 | * 81 | * @since 1.2.12 82 | * 83 | * @param array $params API request parameters to parse. 84 | * @param string $endpoint API request endpoint. 85 | * 86 | * @return (array|WP_Error) 87 | */ 88 | public function api_request_parser( $params = array(), $endpoint = '' ) { 89 | if ( '/cost' === $endpoint ) { 90 | $this->api_request_params_required = array( 91 | 'origin', 92 | 'originType', 93 | 'destination', 94 | 'destinationType', 95 | 'weight', 96 | 'courier', 97 | ); 98 | 99 | $this->api_request_params_optional = array( 100 | 'length', 101 | 'width', 102 | 'height', 103 | 'diameter', 104 | ); 105 | } elseif ( '/v2/internationalCost' === $endpoint ) { 106 | $this->api_request_params_required = array( 107 | 'origin', 108 | 'destination', 109 | 'weight', 110 | 'courier', 111 | ); 112 | 113 | $this->api_request_params_optional = array( 114 | 'length', 115 | 'width', 116 | 'height', 117 | ); 118 | } 119 | 120 | return parent::api_request_parser( $params ); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /includes/couriers/class-woongkir-courier-pos.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class Woongkir_Courier_POS extends Woongkir_Courier { 26 | 27 | /** 28 | * Courier Code 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var string 33 | */ 34 | public $code = 'pos'; 35 | 36 | /** 37 | * Courier Label 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $label = 'POS Indonesia'; 44 | 45 | /** 46 | * Courier Website 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $website = 'http://www.posindonesia.co.id'; 53 | 54 | /** 55 | * Get courier services for domestic shipping 56 | * 57 | * @since 1.2.12 58 | * 59 | * @return array 60 | */ 61 | public function get_services_domestic_default() { 62 | return array( 63 | 'Express Next Day Barang' => 'Express Next Day Barang', 64 | 'Express Next Day Dokumen' => 'Express Next Day Dokumen', 65 | 'Express Sameday Barang' => 'Express Sameday Barang', 66 | 'Express Sameday Dokumen' => 'Express Sameday Dokumen', 67 | 'Kargopos Ritel Train' => 'Kargopos Ritel Train', 68 | 'Kargopos Ritel Udara Dn' => 'Kargopos Ritel Udara Dn', 69 | 'Paket Jumbo Ekonomi' => 'Paket Jumbo Ekonomi', 70 | 'Paket Kilat Khusus' => 'Paket Kilat Khusus', 71 | 'Paketpos Biasa' => 'Paketpos Biasa', 72 | 'Paketpos Dangerous Goods' => 'Paketpos Dangerous Goods', 73 | 'Paketpos Valuable Goods' => 'Paketpos Valuable Goods', 74 | 'Surat Kilat Khusus' => 'Surat Kilat Khusus', 75 | ); 76 | } 77 | 78 | /** 79 | * Get courier services for international shipping 80 | * 81 | * @since 1.2.12 82 | * 83 | * @return array 84 | */ 85 | public function get_services_international_default() { 86 | return array( 87 | 'EMS BARANG' => 'EMS BARANG', 88 | 'ePacket LP APP' => 'ePacket LP APP', 89 | 'PAKETPOS BIASA LN' => 'PAKETPOS BIASA LN', 90 | 'PAKETPOS CEPAT LN' => 'PAKETPOS CEPAT LN', 91 | 'POS EKSPOR' => 'POS EKSPOR', 92 | 'R LN' => 'R LN', 93 | ); 94 | } 95 | 96 | /** 97 | * Get courier account for domestic shipping 98 | * 99 | * @since 1.2.12 100 | * 101 | * @return array 102 | */ 103 | public function get_account_domestic() { 104 | return array( 105 | 'starter', 106 | 'basic', 107 | 'pro', 108 | ); 109 | } 110 | 111 | /** 112 | * Get courier account for international shipping 113 | * 114 | * @since 1.2.12 115 | * 116 | * @return array 117 | */ 118 | public function get_account_international() { 119 | return array( 120 | 'basic', 121 | 'pro', 122 | ); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /assets/src/js/frontend.js: -------------------------------------------------------------------------------- 1 | function woongkirFrontendModifyForm(fieldPrefix) { 2 | var localeData = $.extend(true, {}, woongkir_params.locale.default, woongkir_params.locale.ID); 3 | 4 | $.each(woongkirShared.getFields(), function (fieldSuffix, fieldData) { 5 | var fieldId = fieldPrefix + '_' + fieldSuffix; 6 | var fieldLocale = localeData[fieldSuffix] || {}; 7 | 8 | if ($('#' + fieldId).length < 1 && 'calc_shipping' === fieldPrefix && 'address_2' === fieldSuffix) { 9 | var $postCodeField = $('#' + fieldPrefix + '_postcode_field'); 10 | 11 | if ($postCodeField && $postCodeField.length) { 12 | $postCodeField 13 | .clone() 14 | .attr({ 15 | id: fieldId + '_field', 16 | }) 17 | .insertBefore($postCodeField); 18 | 19 | var placeholder = localeData[fieldSuffix] && localeData[fieldSuffix].placeholder || ''; 20 | 21 | $('#' + fieldId + '_field').find('input').attr({ 22 | id: fieldId, 23 | name: fieldId, 24 | placeholder: placeholder, 25 | 'data-placeholder': placeholder, 26 | value: $('#woongkir_' + fieldPrefix + '_' + fieldSuffix).val(), 27 | }); 28 | } 29 | } 30 | 31 | if ($('#' + fieldId).length < 1) { 32 | return; 33 | } 34 | 35 | if ('address_2' === fieldSuffix && fieldLocale.label) { 36 | $('label[for="' + fieldId + '"]').removeClass('screen-reader-text'); 37 | } 38 | 39 | if (fieldData.onChange) { 40 | $('#' + fieldId).off('change', fieldData.onChange); 41 | } 42 | 43 | var isConvert = true === fieldData.convert || (Array.isArray(fieldData.convert) && fieldData.convert.indexOf(fieldPrefix) !== -1); 44 | 45 | if (!$('#' + fieldId).data('select2') && isConvert) { 46 | woongkirShared.getLocationData(fieldSuffix).then(function (results) { 47 | var options = woongkirShared.filterLocationData(results, fieldPrefix, fieldSuffix, fieldData); 48 | 49 | $('#' + fieldId).selectWoo({ 50 | data: options, 51 | width: '100%', 52 | }); 53 | 54 | if (fieldData.onChange) { 55 | $('#' + fieldId).on('change', fieldData.onChange); 56 | } 57 | }); 58 | } else { 59 | if (fieldData.onChange) { 60 | $('#' + fieldId).on('change', fieldData.onChange); 61 | } 62 | } 63 | }); 64 | } 65 | 66 | function woongkirFrontendRestoreForm(fieldPrefix, countryCode) { 67 | var localeData = $.extend(true, {}, woongkir_params.locale.default, woongkir_params.locale[countryCode]); 68 | 69 | $.each(woongkirShared.getFields(), function (fieldSuffix, fieldData) { 70 | var fieldId = fieldPrefix + '_' + fieldSuffix; 71 | var fieldLocale = localeData[fieldSuffix] || {}; 72 | 73 | if ($('#' + fieldId).length < 1) { 74 | return; 75 | } 76 | 77 | $('#' + fieldId).off('change', fieldData.onChange); 78 | 79 | if (!fieldData.convert) { 80 | return; 81 | } 82 | 83 | if (Array.isArray(fieldData.convert) && fieldData.convert.indexOf(fieldPrefix) === -1) { 84 | return; 85 | } 86 | 87 | if ('address_2' === fieldSuffix && !fieldLocale.label) { 88 | $('label[for="' + fieldId + '"]').addClass('screen-reader-text'); 89 | } 90 | 91 | if ($('#' + fieldId).data('select2')) { 92 | $('#' + fieldId).select2('destroy'); 93 | } 94 | 95 | if ('calc_shipping' === fieldPrefix && 'address_2' === fieldSuffix) { 96 | $('#' + fieldId + '_field').remove(); 97 | } 98 | }); 99 | } 100 | 101 | var woongkirFrontendCountryToStateChangedTimeoutId = {}; 102 | 103 | $(document.body).on('country_to_state_changed', function (event, country, dropdownCountry) { 104 | if ('country_to_state_changed' !== event.type) { 105 | return; 106 | } 107 | 108 | var countryCode = country || $('#calc_shipping_country').val(); 109 | var $selectorCountry = dropdownCountry && dropdownCountry.prevObject ? dropdownCountry.prevObject : $('#calc_shipping_country'); 110 | 111 | if (!$selectorCountry || !$selectorCountry.length) { 112 | return; 113 | } 114 | 115 | var fieldPrefix = $selectorCountry.attr('ID').replace('_country', ''); 116 | 117 | if (woongkirFrontendCountryToStateChangedTimeoutId[fieldPrefix]) { 118 | clearTimeout(woongkirFrontendCountryToStateChangedTimeoutId[fieldPrefix]); 119 | } 120 | 121 | woongkirFrontendCountryToStateChangedTimeoutId[fieldPrefix] = setTimeout(function () { 122 | if ('ID' === countryCode) { 123 | woongkirFrontendModifyForm(fieldPrefix); 124 | } else { 125 | woongkirFrontendRestoreForm(fieldPrefix, countryCode); 126 | } 127 | }, 100); 128 | }); 129 | 130 | -------------------------------------------------------------------------------- /deploy-wp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Note that this does not use pipefail 4 | # because if the grep later doesn't match any deleted files, 5 | # which is likely the majority case, 6 | # it does not exit with a 0, and I only care about the final exit. 7 | # set -eo 8 | 9 | help() { 10 | echo "Usage: ./deploy-wp.sh [ -s | --slug ] Plugin slug. 11 | [ -v | --version ] Plugin version. 12 | [ -d | --dir ] Source files directory. 13 | [ -u | --username ] WP.org username. 14 | [ -p | --password ] WP.org password. 15 | [ -m | --message ] Commit message. 16 | [ -h | --help ]" 17 | exit 2 18 | } 19 | 20 | while [ "$1" ]; do 21 | case "$1" in 22 | -s | --slug) 23 | SLUG="$2" 24 | shift 2 25 | ;; 26 | -v | --version) 27 | VERSION="$2" 28 | shift 2 29 | ;; 30 | -d | --dir) 31 | SVN_SRC_DIR="$2" 32 | shift 2 33 | ;; 34 | -u | --username) 35 | SVN_USERNAME="$2" 36 | shift 2 37 | ;; 38 | -p | --password) 39 | SVN_PASSWORD="$2" 40 | shift 2 41 | ;; 42 | -m | --message) 43 | COMMIT_MSG="$2" 44 | shift 2 45 | ;; 46 | -h | --help) 47 | help 48 | ;; 49 | --) 50 | shift 51 | break 52 | ;; 53 | *) 54 | echo "Unexpected option: $1" 55 | help 56 | ;; 57 | esac 58 | done 59 | 60 | while [[ -z "$SLUG" ]]; do 61 | read -p 'Plugin slug: ' SLUG 62 | done 63 | 64 | while [[ -z "$VERSION" ]]; do 65 | read -p 'Plugin version: ' VERSION 66 | done 67 | 68 | while [ -z "$SVN_SRC_DIR" ] || [ ! -d "$SVN_SRC_DIR" ]; do 69 | read -p 'Source directory: ' SVN_SRC_DIR 70 | 71 | if [ -d "$SVN_SRC_DIR" ]; then 72 | SVN_SRC_DIR=$(cd "$SVN_SRC_DIR"; pwd) 73 | fi 74 | done 75 | 76 | while [[ -z "$SVN_USERNAME" ]]; do 77 | read -p 'SVN username: ' SVN_USERNAME 78 | done 79 | 80 | while [[ -z "$SVN_PASSWORD" ]]; do 81 | read -s -p 'SVN password: ' SVN_PASSWORD 82 | echo 83 | done 84 | 85 | while [[ -z "$COMMIT_MSG" ]]; do 86 | read -e -p "Commit message: " -i "Update to version $VERSION" COMMIT_MSG 87 | done 88 | 89 | SVN_URL="https://plugins.svn.wordpress.org/${SLUG}/" 90 | SVN_LOCAL_DIR="${HOME}/.deploy-wp/plugins/${SLUG}" 91 | 92 | echo "Plugin slug: $SLUG" 93 | echo "Plugin version: $VERSION" 94 | echo "SVN Source directory: $SVN_SRC_DIR" 95 | echo "SVN username: $SVN_USERNAME" 96 | echo "SVN password: *****" 97 | echo "SVN URL: $SVN_URL" 98 | echo "SVN local directory: $SVN_LOCAL_DIR" 99 | echo "Commit message: $COMMIT_MSG" 100 | 101 | # Checkout just trunk and assets for efficiency 102 | # Tagging will be handled on the SVN level 103 | echo "➤ Checking out .org repository..." 104 | svn checkout --depth immediates "$SVN_URL" "$SVN_LOCAL_DIR" 105 | cd "$SVN_LOCAL_DIR" || exit 106 | svn update --set-depth infinity tags 107 | svn update --set-depth infinity trunk 108 | 109 | if [ -d "$SVN_LOCAL_DIR/tags/$VERSION" ]; then 110 | while true; do 111 | read -p "Tags version $VERSION is already exists. Do you want to override? " yn 112 | case $yn in 113 | [Yy]*) break ;; 114 | [Nn]*) exit ;; 115 | *) echo "Please answer yes or no." ;; 116 | esac 117 | done 118 | fi 119 | 120 | echo "➤ Copying files from source directory..." 121 | 122 | # Copy from source directory to /trunk 123 | # The --delete flag will delete anything in destination that no longer exists in source 124 | rsync -rc "$SVN_SRC_DIR/" "$SVN_LOCAL_DIR/trunk/" --delete --delete-excluded 125 | 126 | # Copy tag locally to make this a single commit 127 | echo "➤ Copying tag..." 128 | rsync -rc "$SVN_LOCAL_DIR/trunk/" "$SVN_LOCAL_DIR/tags/$VERSION/" --delete --delete-excluded 129 | 130 | # Add everything and commit to SVN 131 | # The force flag ensures we recurse into subdirectories even if they are already added 132 | # Suppress stdout in favor of svn status later for readability 133 | echo "➤ Staging changes..." 134 | svn add . --force >/dev/null 135 | 136 | # SVN delete all deleted files 137 | # Also suppress stdout here 138 | svn status | grep '^\!' | sed 's/! *//' | xargs -I% svn rm %@ >/dev/null 139 | 140 | if [ -z "$(svn status)" ]; then 141 | echo "✗ Nothing to commit, working tree clean" 142 | exit 1 143 | fi 144 | 145 | if [[ -z "$COMMIT_MSG" ]]; then 146 | COMMIT_MSG="Update to version $VERSION" 147 | fi 148 | 149 | echo "➤ Committing changes..." 150 | svn commit -m "$COMMIT_MSG" --no-auth-cache --non-interactive --username "$SVN_USERNAME" --password "$SVN_PASSWORD" 151 | 152 | echo "✓ Plugin deployed!" 153 | -------------------------------------------------------------------------------- /assets/src/js/shared.js: -------------------------------------------------------------------------------- 1 | var woongkirShared = { 2 | updateCheckoutTimeoutId: null, 3 | renderLocationFields: function (fieldPrefix, fieldSuffixes) { 4 | var dfd = new $.Deferred(); 5 | 6 | var renderCounter = 0; 7 | 8 | $.each(woongkirShared.getFields(), function (fieldSuffix, fieldData) { 9 | if (!fieldSuffixes || fieldSuffixes.indexOf(fieldSuffix) === -1) { 10 | return; 11 | } 12 | 13 | var fieldId = fieldPrefix + '_' + fieldSuffix; 14 | 15 | if (!$('#' + fieldId) || !$('#' + fieldId).length) { 16 | return; 17 | } 18 | 19 | woongkirShared.getLocationData(fieldSuffix).then(function (results) { 20 | var options = woongkirShared.filterLocationData(results, fieldPrefix, fieldSuffix, fieldData); 21 | 22 | var optionSelected = options.find(function (option) { 23 | return option.selected; 24 | }); 25 | 26 | var optionSelectedValue = optionSelected ? optionSelected.id : null; 27 | 28 | $('#' + fieldId).selectWoo({ 29 | data: options, 30 | width: '100%', 31 | }).val(optionSelectedValue); 32 | 33 | renderCounter++; 34 | 35 | if (renderCounter === fieldSuffixes.length) { 36 | dfd.resolve(); 37 | } 38 | }); 39 | }); 40 | 41 | return dfd.promise(); 42 | }, 43 | onChangeFieldState: function (event) { 44 | var fieldPrefix = $(event.target).attr('id').replace('_state', ''); 45 | 46 | woongkirShared.renderLocationFields(fieldPrefix, ['city', 'address_2']).then(function () { 47 | $('#' + fieldPrefix + '_city').trigger('change'); 48 | }); 49 | }, 50 | onChangeFieldCity: function (event) { 51 | var fieldPrefix = $(event.target).attr('id').replace('_city', ''); 52 | 53 | woongkirShared.renderLocationFields(fieldPrefix, ['address_2']).then(function () { 54 | $('#' + fieldPrefix + '_address_2').trigger('change'); 55 | }); 56 | }, 57 | onChangeFieldAddress2: function (event) { 58 | var fieldPrefix = $(event.target).attr('id').replace('_address_2', ''); 59 | var isShipDifferentAddress = $('#ship-to-different-address-checkbox').is(':checked'); 60 | var isCheckout = wc_checkout_params && wc_checkout_params.is_checkout; 61 | 62 | if (!isCheckout) { 63 | return; 64 | } 65 | 66 | if (isShipDifferentAddress && 'billing' === fieldPrefix) { 67 | return; 68 | } 69 | 70 | if (woongkirShared.updateCheckoutTimeoutId) { 71 | clearTimeout(woongkirShared.updateCheckoutTimeoutId); 72 | } 73 | 74 | woongkirShared.updateCheckoutTimeoutId = setTimeout(function () { 75 | $(document.body).trigger('update_checkout'); 76 | }, 200); 77 | }, 78 | getFields: function () { 79 | return { 80 | state: { 81 | onChange: woongkirShared.onChangeFieldState, 82 | convert: false, 83 | restore: false, 84 | }, 85 | city: { 86 | onChange: woongkirShared.onChangeFieldCity, 87 | convert: true, 88 | restore: true, 89 | fieldFilters: ['state'], 90 | }, 91 | address_2: { 92 | onChange: woongkirShared.onChangeFieldAddress2, 93 | convert: true, 94 | restore: true, 95 | fieldFilters: ['state', 'city'], 96 | }, 97 | }; 98 | }, 99 | getLocationDataCountry: function () { 100 | return woongkirShared.getLocationData('country'); 101 | }, 102 | getLocationDataState: function () { 103 | return woongkirShared.getLocationData('state'); 104 | }, 105 | getLocationDataCity: function () { 106 | return woongkirShared.getLocationData('city'); 107 | }, 108 | getLocationDataAddress2: function () { 109 | return woongkirShared.getLocationData('address_2'); 110 | }, 111 | getLocationData: function (locationType) { 112 | var dfd = new $.Deferred(); 113 | var dataKey = woongkir_params.json[locationType].key; 114 | var dataUrl = woongkir_params.json[locationType].url; 115 | 116 | var items = Lockr.get(dataKey); 117 | 118 | if (null === items || typeof items === 'undefined') { 119 | var randomKey = Math.random().toString(36).substring(7); 120 | $.getJSON(dataUrl, { [randomKey]: new Date().getTime() }, function (data) { 121 | data.sort(function (a, b) { 122 | return (a.value > b.value) ? 1 : ((b.value > a.value) ? -1 : 0); 123 | }); 124 | 125 | Lockr.set(dataKey, data); 126 | 127 | dfd.resolve(data); 128 | }); 129 | } else { 130 | dfd.resolve(items); 131 | } 132 | 133 | return dfd.promise(); 134 | }, 135 | filterLocationData: function (results, fieldPrefix, fieldSuffix, fieldData) { 136 | var getLocationDataFilter = []; 137 | 138 | if (fieldData.fieldFilters) { 139 | getLocationDataFilter = fieldData.fieldFilters.filter(function (item) { 140 | return $('#' + fieldPrefix + '_' + item).length > 0; 141 | }).map(function (item) { 142 | return { 143 | key: item, 144 | value: $('#' + fieldPrefix + '_' + item).val(), 145 | }; 146 | }); 147 | } 148 | 149 | return results.filter(function (result) { 150 | if (!getLocationDataFilter || !getLocationDataFilter.length) { 151 | return true; 152 | } 153 | 154 | return getLocationDataFilter.every(function (locationFilter) { 155 | return result[locationFilter.key] === locationFilter.value; 156 | }); 157 | }).map(function (item) { 158 | return { 159 | id: item.value, 160 | text: item.label || item.value, 161 | selected: $('#' + fieldPrefix + '_' + fieldSuffix).val() === item.value, 162 | }; 163 | }); 164 | }, 165 | }; 166 | -------------------------------------------------------------------------------- /assets/src/js/plugins/lockr.js: -------------------------------------------------------------------------------- 1 | (function (root, factory) { 2 | 3 | if (typeof exports !== 'undefined') { 4 | if (typeof module !== 'undefined' && module.exports) { 5 | exports = module.exports = factory(root, exports); 6 | } 7 | } else if (typeof define === 'function' && define.amd) { 8 | define(['exports'], function (exports) { 9 | root.Lockr = factory(root, exports); 10 | }); 11 | } else { 12 | root.Lockr = factory(root, {}); 13 | } 14 | 15 | }(this, function (root, Lockr) { 16 | 'use strict'; 17 | 18 | if (!Array.prototype.indexOf) { 19 | Array.prototype.indexOf = function (elt /*, from*/) { 20 | var len = this.length >>> 0; 21 | 22 | var from = Number(arguments[1]) || 0; 23 | from = (from < 0) 24 | ? Math.ceil(from) 25 | : Math.floor(from); 26 | if (from < 0) 27 | from += len; 28 | 29 | for (; from < len; from++) { 30 | if (from in this && 31 | this[from] === elt) 32 | return from; 33 | } 34 | return -1; 35 | }; 36 | } 37 | 38 | Lockr.prefix = ""; 39 | 40 | Lockr._getPrefixedKey = function (key, options) { 41 | options = options || {}; 42 | 43 | if (options.noPrefix) { 44 | return key; 45 | } else { 46 | return this.prefix + key; 47 | } 48 | 49 | }; 50 | 51 | Lockr.set = function (key, value, options) { 52 | var query_key = this._getPrefixedKey(key, options); 53 | 54 | try { 55 | localStorage.setItem(query_key, JSON.stringify({ "data": value })); 56 | } catch (e) { 57 | if (console) console.warn("Lockr didn't successfully save the '{" + key + ": " + value + "}' pair, because the localStorage is full."); 58 | } 59 | }; 60 | 61 | Lockr.get = function (key, missing, options) { 62 | var query_key = this._getPrefixedKey(key, options), 63 | value; 64 | 65 | try { 66 | value = JSON.parse(localStorage.getItem(query_key)); 67 | } catch (e) { 68 | if (localStorage[query_key]) { 69 | value = { data: localStorage.getItem(query_key) }; 70 | } else { 71 | value = null; 72 | } 73 | } 74 | 75 | if (!value) { 76 | return missing; 77 | } 78 | else if (typeof value === 'object' && typeof value.data !== 'undefined') { 79 | return value.data; 80 | } 81 | }; 82 | 83 | Lockr.sadd = function (key, value, options) { 84 | var query_key = this._getPrefixedKey(key, options), 85 | json; 86 | 87 | var values = Lockr.smembers(key); 88 | 89 | if (values.indexOf(value) > -1) { 90 | return null; 91 | } 92 | 93 | try { 94 | values.push(value); 95 | json = JSON.stringify({ "data": values }); 96 | localStorage.setItem(query_key, json); 97 | } catch (e) { 98 | console.log(e); 99 | if (console) console.warn("Lockr didn't successfully add the " + value + " to " + key + " set, because the localStorage is full."); 100 | } 101 | }; 102 | 103 | Lockr.smembers = function (key, options) { 104 | var query_key = this._getPrefixedKey(key, options), 105 | value; 106 | 107 | try { 108 | value = JSON.parse(localStorage.getItem(query_key)); 109 | } catch (e) { 110 | value = null; 111 | } 112 | 113 | return (value && value.data) ? value.data : []; 114 | }; 115 | 116 | Lockr.sismember = function (key, value, options) { 117 | return Lockr.smembers(key).indexOf(value) > -1; 118 | }; 119 | 120 | Lockr.keys = function () { 121 | var keys = []; 122 | var allKeys = Object.keys(localStorage); 123 | 124 | if (Lockr.prefix.length === 0) { 125 | return allKeys; 126 | } 127 | 128 | allKeys.forEach(function (key) { 129 | if (key.indexOf(Lockr.prefix) !== -1) { 130 | keys.push(key.replace(Lockr.prefix, '')); 131 | } 132 | }); 133 | 134 | return keys; 135 | }; 136 | 137 | Lockr.getAll = function (includeKeys) { 138 | var keys = Lockr.keys(); 139 | 140 | if (includeKeys) { 141 | return keys.reduce(function (accum, key) { 142 | var tempObj = {}; 143 | tempObj[key] = Lockr.get(key); 144 | accum.push(tempObj); 145 | return accum; 146 | }, []); 147 | } 148 | 149 | return keys.map(function (key) { 150 | return Lockr.get(key); 151 | }); 152 | }; 153 | 154 | Lockr.srem = function (key, value, options) { 155 | var query_key = this._getPrefixedKey(key, options), 156 | json, 157 | index; 158 | 159 | var values = Lockr.smembers(key, value); 160 | 161 | index = values.indexOf(value); 162 | 163 | if (index > -1) 164 | values.splice(index, 1); 165 | 166 | json = JSON.stringify({ "data": values }); 167 | 168 | try { 169 | localStorage.setItem(query_key, json); 170 | } catch (e) { 171 | if (console) console.warn("Lockr couldn't remove the " + value + " from the set " + key); 172 | } 173 | }; 174 | 175 | Lockr.rm = function (key) { 176 | var queryKey = this._getPrefixedKey(key); 177 | 178 | localStorage.removeItem(queryKey); 179 | }; 180 | 181 | Lockr.flush = function () { 182 | if (Lockr.prefix.length) { 183 | Lockr.keys().forEach(function (key) { 184 | localStorage.removeItem(Lockr._getPrefixedKey(key)); 185 | }); 186 | } else { 187 | localStorage.clear(); 188 | } 189 | }; 190 | return Lockr; 191 | 192 | })); -------------------------------------------------------------------------------- /assets/src/scss/backend.scss: -------------------------------------------------------------------------------- 1 | $border-color: #ccd0d4; 2 | $bg-color: #f8f8f8; 3 | $bg-color-hover: lighten($bg-color, 1%); 4 | 5 | .wc-modal-shipping-method-settings.wc-modal-shipping-method-settings--woongkir { 6 | th.titledesc { 7 | vertical-align: top; 8 | background-color: $bg-color; 9 | } 10 | 11 | .woongkir { 12 | &-account-features { 13 | table-layout: fixed; 14 | 15 | &-wrap { 16 | margin-top: 10px; 17 | box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.1); 18 | } 19 | 20 | th, 21 | td { 22 | white-space: nowrap; 23 | 24 | &:first-child { 25 | border-left: 1px solid $border-color; 26 | } 27 | 28 | &:last-child { 29 | border-right: 1px solid $border-color; 30 | } 31 | } 32 | 33 | th+th, 34 | th+td, 35 | td+th, 36 | td+td { 37 | border-left: 1px solid $border-color; 38 | } 39 | 40 | thead { 41 | 42 | td, 43 | th { 44 | border-top: 1px solid $border-color; 45 | background-color: $bg-color; 46 | } 47 | 48 | th { 49 | border-bottom: 1px solid $border-color; 50 | 51 | &:first-child { 52 | width: auto !important; 53 | } 54 | 55 | &:not(:first-child) { 56 | text-align: center; 57 | width: 90px; 58 | } 59 | } 60 | } 61 | 62 | tbody { 63 | tr { 64 | &:nth-child(even) { 65 | 66 | td, 67 | th { 68 | background-color: $bg-color; 69 | } 70 | } 71 | 72 | &:hover { 73 | 74 | td, 75 | th { 76 | background-color: $bg-color-hover; 77 | } 78 | } 79 | } 80 | 81 | tr:last-child { 82 | 83 | td, 84 | th { 85 | border-bottom: 1px solid $border-color; 86 | } 87 | } 88 | 89 | td { 90 | text-align: center; 91 | } 92 | 93 | th, 94 | td { 95 | padding: 0.6em 1em; 96 | } 97 | } 98 | 99 | tfoot { 100 | 101 | td, 102 | th { 103 | border-bottom: 1px solid $border-color; 104 | background-color: $bg-color; 105 | } 106 | 107 | td { 108 | text-align: center; 109 | } 110 | } 111 | } 112 | 113 | &-couriers { 114 | margin: 0; 115 | 116 | &-item { 117 | border: 1px solid $border-color; 118 | margin: 0 0 3px 0; 119 | background-color: $bg-color; 120 | 121 | &-info { 122 | position: relative; 123 | height: 40px; 124 | cursor: move; 125 | 126 | &-title { 127 | display: inline-block; 128 | line-height: 40px; 129 | height: 40px; 130 | font-weight: bold; 131 | padding-left: 12px; 132 | } 133 | 134 | &-toggle, 135 | &-link { 136 | position: absolute; 137 | top: 0; 138 | width: 40px; 139 | height: 40px; 140 | border-left: 1px solid $border-color; 141 | text-align: center; 142 | 143 | a { 144 | text-decoration: none; 145 | display: block; 146 | height: 40px; 147 | line-height: 40px; 148 | padding-top: 10px; 149 | 150 | &:hover { 151 | background-color: $bg-color-hover; 152 | } 153 | } 154 | } 155 | 156 | &-toggle { 157 | right: 0; 158 | } 159 | 160 | &-link { 161 | right: 40px; 162 | transition: all 0.2s ease-in-out; 163 | } 164 | } 165 | 166 | &:not(.expanded) { 167 | background-color: #fff; 168 | 169 | &:hover { 170 | background-color: $bg-color-hover; 171 | } 172 | 173 | .woongkir-couriers-item-info-link, 174 | .woongkir-services { 175 | transform: scale(0); 176 | height: 0; 177 | } 178 | } 179 | } 180 | 181 | &--selected { 182 | &:before { 183 | content: " ("; 184 | } 185 | 186 | &::after { 187 | content: " / "; 188 | } 189 | } 190 | 191 | &--available { 192 | &:after { 193 | content: ")"; 194 | } 195 | } 196 | } 197 | 198 | &-services { 199 | transform: scale(1); 200 | background-color: #fff; 201 | transition: all 0.2s ease-in-out; 202 | 203 | &-item { 204 | margin: 0; 205 | padding: 7px 0 7px 36px; 206 | border-top: 1px solid $border-color; 207 | 208 | &:first-child { 209 | border-top: 1px solid $border-color; 210 | } 211 | 212 | &:nth-child(even) { 213 | background-color: $bg-color; 214 | } 215 | 216 | &:hover { 217 | background-color: $bg-color-hover; 218 | } 219 | } 220 | } 221 | 222 | &-tab { 223 | &-container { 224 | border-radius: 0; 225 | margin-bottom: 24px; 226 | } 227 | 228 | &-nav { 229 | display: block; 230 | padding: 0; 231 | margin: 0; 232 | 233 | &:after { 234 | display: block; 235 | clear: both; 236 | content: ""; 237 | } 238 | 239 | li { 240 | float: left; 241 | list-style: none; 242 | text-align: center; 243 | padding: 0; 244 | margin: 0; 245 | display: block; 246 | box-sizing: border-box; 247 | width: 50%; 248 | 249 | border-top: 1px solid $border-color; 250 | border-right: 1px solid $border-color; 251 | border-left: 1px solid $border-color; 252 | 253 | &+li { 254 | border-left: none; 255 | } 256 | 257 | a { 258 | padding: 1em 2em; 259 | display: block; 260 | text-decoration: none; 261 | outline: none; 262 | box-shadow: none; 263 | color: unset; 264 | position: relative; 265 | font-weight: 700; 266 | border-bottom: 1px solid $border-color; 267 | 268 | &.active { 269 | background-color: $bg-color; 270 | border-bottom: 1px solid $bg-color; 271 | } 272 | 273 | &:not(.active) { 274 | opacity: 0.7; 275 | 276 | &:hover { 277 | background-color: $bg-color-hover; 278 | opacity: 1; 279 | } 280 | } 281 | 282 | &:active, 283 | &:focus { 284 | outline: none; 285 | box-shadow: none; 286 | } 287 | } 288 | } 289 | } 290 | 291 | &-content { 292 | display: block; 293 | padding: 1em; 294 | min-height: 100px; 295 | box-sizing: border-box; 296 | border-right: 1px solid $border-color; 297 | border-bottom: 1px solid $border-color; 298 | border-left: 1px solid $border-color; 299 | background-color: $bg-color; 300 | 301 | &:not(.active) { 302 | display: none; 303 | } 304 | } 305 | } 306 | 307 | &-api-key-input { 308 | max-width: calc(100% - 42px); 309 | border-top-right-radius: 0px !important; 310 | border-bottom-right-radius: 0px !important; 311 | } 312 | 313 | &-api-key-view { 314 | border-top-left-radius: 0px !important; 315 | border-bottom-left-radius: 0px !important; 316 | margin-left: -2px; 317 | } 318 | 319 | &-account { 320 | display: flex; 321 | justify-content: space-between; 322 | list-style-type: none; 323 | padding: 0; 324 | 325 | &-item { 326 | flex-grow: 1; 327 | text-align: center; 328 | border: 1px solid #ccd0d4; 329 | padding: 10px; 330 | 331 | &-label { 332 | display: block; 333 | text-decoration: none; 334 | font-weight: bold; 335 | margin-bottom: 6px; 336 | } 337 | } 338 | 339 | &-type { 340 | min-width: unset !important; 341 | width: 16px !important; 342 | height: 16px !important; 343 | } 344 | } 345 | } 346 | } 347 | 348 | /** 349 | * Style for WooCommerce 8.4.0 and later 350 | */ 351 | .wc-shipping-zone-method-fields { 352 | .woongkir { 353 | &-api-key { 354 | &-input { 355 | width: calc(100% - 42px) !important; 356 | } 357 | 358 | &-view { 359 | margin-top: 6px !important; 360 | padding-top: 6px !important; 361 | padding-bottom: 6px !important; 362 | } 363 | } 364 | } 365 | } -------------------------------------------------------------------------------- /data/woongkir-country.json: -------------------------------------------------------------------------------- 1 | [{"id":2,"value":"AF","label":"Afghanistan"},{"id":4,"value":"AL","label":"Albania"},{"id":5,"value":"DZ","label":"Algeria"},{"id":146,"value":"AS","label":"American Samoa"},{"id":189,"value":"AD","label":"Andorra"},{"id":6,"value":"AO","label":"Angola"},{"id":7,"value":"AG","label":"Antigua and Barbuda"},{"id":8,"value":"AR","label":"Argentina"},{"id":190,"value":"AM","label":"Armenia"},{"id":191,"value":"AW","label":"Aruba"},{"id":9,"value":"AU","label":"Australia"},{"id":10,"value":"AT","label":"Austria"},{"id":11,"value":"AZ","label":"Azerbaijan"},{"id":12,"value":"BS","label":"Bahamas"},{"id":13,"value":"BH","label":"Bahrain"},{"id":14,"value":"BD","label":"Bangladesh"},{"id":15,"value":"BB","label":"Barbados"},{"id":192,"value":"BY","label":"Belarus"},{"id":16,"value":"BE","label":"Belgium"},{"id":17,"value":"BZ","label":"Belize"},{"id":18,"value":"BJ","label":"Benin"},{"id":19,"value":"BM","label":"Bermuda"},{"id":20,"value":"BT","label":"Bhutan"},{"id":21,"value":"BO","label":"Bolivia"},{"id":222,"value":"BQ","label":"Bonaire, Saint Eustatius and Saba"},{"id":194,"value":"BA","label":"Bosnia and Herzegovina"},{"id":22,"value":"BW","label":"Botswana"},{"id":23,"value":"BR","label":"Brazil"},{"id":232,"value":"VG","label":"British Virgin Islands"},{"id":24,"value":"BN","label":"Brunei"},{"id":25,"value":"BG","label":"Bulgaria"},{"id":26,"value":"BF","label":"Burkina Faso"},{"id":27,"value":"BI","label":"Burundi"},{"id":28,"value":"KH","label":"Cambodia"},{"id":29,"value":"CM","label":"Cameroon"},{"id":30,"value":"CA","label":"Canada"},{"id":196,"value":"CV","label":"Cape Verde"},{"id":31,"value":"KY","label":"Cayman Islands"},{"id":33,"value":"CF","label":"Central African Republic"},{"id":34,"value":"TD","label":"Chad"},{"id":35,"value":"CL","label":"Chile"},{"id":36,"value":"CN","label":"China"},{"id":37,"value":"CO","label":"Colombia"},{"id":38,"value":"KM","label":"Comoros"},{"id":39,"value":"CG","label":"Congo (Brazzaville)"},{"id":235,"value":"CD","label":"Congo (Kinshasa)"},{"id":40,"value":"CK","label":"Cook Islands"},{"id":41,"value":"CR","label":"Costa Rica"},{"id":198,"value":"HR","label":"Croatia"},{"id":43,"value":"CU","label":"Cuba"},{"id":44,"value":"CY","label":"Cyprus"},{"id":45,"value":"CZ","label":"Czech Republic"},{"id":47,"value":"DK","label":"Denmark"},{"id":48,"value":"DJ","label":"Djibouti"},{"id":49,"value":"DM","label":"Dominica"},{"id":50,"value":"DO","label":"Dominican Republic"},{"id":51,"value":"EC","label":"Ecuador"},{"id":52,"value":"EG","label":"Egypt"},{"id":53,"value":"SV","label":"El Salvador"},{"id":54,"value":"GQ","label":"Equatorial Guinea"},{"id":55,"value":"ER","label":"Eritrea"},{"id":200,"value":"EE","label":"Estonia"},{"id":56,"value":"ET","label":"Ethiopia"},{"id":202,"value":"FK","label":"Falkland Islands"},{"id":57,"value":"FO","label":"Faroe Islands"},{"id":58,"value":"FJ","label":"Fiji"},{"id":59,"value":"FI","label":"Finland"},{"id":61,"value":"FR","label":"France"},{"id":62,"value":"GF","label":"French Guiana"},{"id":63,"value":"PF","label":"French Polynesia"},{"id":64,"value":"GA","label":"Gabon"},{"id":65,"value":"GM","label":"Gambia"},{"id":203,"value":"GE","label":"Georgia"},{"id":66,"value":"DE","label":"Germany"},{"id":67,"value":"GH","label":"Ghana"},{"id":68,"value":"GI","label":"Gibraltar"},{"id":70,"value":"GR","label":"Greece"},{"id":71,"value":"GL","label":"Greenland"},{"id":72,"value":"GD","label":"Grenada"},{"id":73,"value":"GP","label":"Guadeloupe"},{"id":74,"value":"GU","label":"Guam"},{"id":75,"value":"GT","label":"Guatemala"},{"id":204,"value":"GG","label":"Guernsey"},{"id":76,"value":"GN","label":"Guinea"},{"id":77,"value":"GW","label":"Guinea-Bissau"},{"id":78,"value":"GY","label":"Guyana"},{"id":79,"value":"HT","label":"Haiti"},{"id":80,"value":"HN","label":"Honduras"},{"id":81,"value":"HK","label":"Hong Kong"},{"id":82,"value":"HU","label":"Hungary"},{"id":83,"value":"IS","label":"Iceland"},{"id":84,"value":"IN","label":"India"},{"id":0,"value":"ID","label":"Indonesia"},{"id":85,"value":"IR","label":"Iran"},{"id":86,"value":"IQ","label":"Iraq"},{"id":87,"value":"IE","label":"Ireland"},{"id":88,"value":"IL","label":"Israel"},{"id":89,"value":"IT","label":"Italy"},{"id":42,"value":"CI","label":"Ivory Coast"},{"id":90,"value":"JM","label":"Jamaica"},{"id":91,"value":"JP","label":"Japan"},{"id":205,"value":"JE","label":"Jersey"},{"id":92,"value":"JO","label":"Jordan"},{"id":93,"value":"KZ","label":"Kazakhstan"},{"id":94,"value":"KE","label":"Kenya"},{"id":95,"value":"KI","label":"Kiribati"},{"id":97,"value":"KW","label":"Kuwait"},{"id":206,"value":"KG","label":"Kyrgyzstan"},{"id":98,"value":"LA","label":"Laos"},{"id":207,"value":"LV","label":"Latvia"},{"id":99,"value":"LB","label":"Lebanon"},{"id":100,"value":"LS","label":"Lesotho"},{"id":101,"value":"LR","label":"Liberia"},{"id":102,"value":"LY","label":"Libya"},{"id":208,"value":"LI","label":"Liechtenstein"},{"id":209,"value":"LT","label":"Lithuania"},{"id":103,"value":"LU","label":"Luxembourg"},{"id":104,"value":"MO","label":"Macao S.A.R., China"},{"id":60,"value":"MK","label":"Macedonia"},{"id":105,"value":"MG","label":"Madagascar"},{"id":107,"value":"MW","label":"Malawi"},{"id":108,"value":"MY","label":"Malaysia"},{"id":109,"value":"MV","label":"Maldives"},{"id":110,"value":"ML","label":"Mali"},{"id":111,"value":"MT","label":"Malta"},{"id":113,"value":"MQ","label":"Martinique"},{"id":114,"value":"MR","label":"Mauritania"},{"id":115,"value":"MU","label":"Mauritius"},{"id":116,"value":"MX","label":"Mexico"},{"id":210,"value":"MD","label":"Moldova"},{"id":211,"value":"MC","label":"Monaco"},{"id":117,"value":"MN","label":"Mongolia"},{"id":212,"value":"ME","label":"Montenegro"},{"id":118,"value":"MS","label":"Montserrat"},{"id":119,"value":"MA","label":"Morocco"},{"id":120,"value":"MZ","label":"Mozambique"},{"id":121,"value":"MM","label":"Myanmar"},{"id":122,"value":"NA","label":"Namibia"},{"id":123,"value":"NR","label":"Nauru"},{"id":124,"value":"NP","label":"Nepal"},{"id":125,"value":"NL","label":"Netherlands"},{"id":127,"value":"NC","label":"New Caledonia"},{"id":128,"value":"NZ","label":"New Zealand"},{"id":129,"value":"NI","label":"Nicaragua"},{"id":130,"value":"NE","label":"Niger"},{"id":131,"value":"NG","label":"Nigeria"},{"id":214,"value":"NU","label":"Niue"},{"id":96,"value":"KP","label":"North Korea"},{"id":112,"value":"MP","label":"Northern Mariana Islands"},{"id":132,"value":"NO","label":"Norway"},{"id":133,"value":"OM","label":"Oman"},{"id":134,"value":"PK","label":"Pakistan"},{"id":135,"value":"PA","label":"Panama"},{"id":136,"value":"PG","label":"Papua New Guinea"},{"id":137,"value":"PY","label":"Paraguay"},{"id":138,"value":"PE","label":"Peru"},{"id":139,"value":"PH","label":"Philippines"},{"id":140,"value":"PL","label":"Poland"},{"id":141,"value":"PT","label":"Portugal"},{"id":215,"value":"PR","label":"Puerto Rico"},{"id":142,"value":"QA","label":"Qatar"},{"id":216,"value":"RE","label":"Reunion"},{"id":143,"value":"RO","label":"Romania"},{"id":144,"value":"RU","label":"Russia"},{"id":145,"value":"RW","label":"Rwanda"},{"id":221,"value":"BL","label":"Saint Barthélemy"},{"id":158,"value":"SH","label":"Saint Helena"},{"id":223,"value":"KN","label":"Saint Kitts and Nevis"},{"id":224,"value":"LC","label":"Saint Lucia"},{"id":225,"value":"SX","label":"Saint Martin (Dutch part)"},{"id":226,"value":"VC","label":"Saint Vincent and the Grenadines"},{"id":185,"value":"WS","label":"Samoa"},{"id":147,"value":"SA","label":"Saudi Arabia"},{"id":149,"value":"SN","label":"Senegal"},{"id":218,"value":"RS","label":"Serbia"},{"id":150,"value":"SC","label":"Seychelles"},{"id":151,"value":"SL","label":"Sierra Leone"},{"id":152,"value":"SG","label":"Singapore"},{"id":153,"value":"SK","label":"Slovakia"},{"id":219,"value":"SI","label":"Slovenia"},{"id":154,"value":"SB","label":"Solomon Islands"},{"id":220,"value":"SO","label":"Somalia"},{"id":155,"value":"ZA","label":"South Africa"},{"id":46,"value":"KR","label":"South Korea"},{"id":156,"value":"ES","label":"Spain"},{"id":157,"value":"LK","label":"Sri Lanka"},{"id":159,"value":"SD","label":"Sudan"},{"id":160,"value":"SR","label":"Suriname"},{"id":161,"value":"SZ","label":"Swaziland"},{"id":162,"value":"SE","label":"Sweden"},{"id":163,"value":"CH","label":"Switzerland"},{"id":164,"value":"SY","label":"Syria"},{"id":165,"value":"TW","label":"Taiwan"},{"id":228,"value":"TJ","label":"Tajikistan"},{"id":166,"value":"TZ","label":"Tanzania"},{"id":167,"value":"TH","label":"Thailand"},{"id":168,"value":"TL","label":"Timor-Leste"},{"id":169,"value":"TG","label":"Togo"},{"id":170,"value":"TO","label":"Tonga"},{"id":172,"value":"TT","label":"Trinidad and Tobago"},{"id":173,"value":"TN","label":"Tunisia"},{"id":174,"value":"TR","label":"Turkey"},{"id":229,"value":"TM","label":"Turkmenistan"},{"id":175,"value":"TC","label":"Turks and Caicos Islands"},{"id":176,"value":"TV","label":"Tuvalu"},{"id":177,"value":"UG","label":"Uganda"},{"id":230,"value":"UA","label":"Ukraine"},{"id":178,"value":"AE","label":"United Arab Emirates"},{"id":69,"value":"GB","label":"United Kingdom (UK)"},{"id":179,"value":"US","label":"United States (US)"},{"id":233,"value":"VI","label":"United States (US) Virgin Islands"},{"id":180,"value":"UY","label":"Uruguay"},{"id":231,"value":"UZ","label":"Uzbekistan"},{"id":181,"value":"VU","label":"Vanuatu"},{"id":182,"value":"VA","label":"Vatican"},{"id":183,"value":"VE","label":"Venezuela"},{"id":184,"value":"VN","label":"Vietnam"},{"id":186,"value":"YE","label":"Yemen"},{"id":187,"value":"ZM","label":"Zambia"},{"id":188,"value":"ZW","label":"Zimbabwe"}] 2 | -------------------------------------------------------------------------------- /includes/classes/class-woongkir-courier.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | abstract class Woongkir_Courier { 26 | 27 | /** 28 | * Courier priority 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var int 33 | */ 34 | public $priority = 0; 35 | 36 | /** 37 | * Courier Code 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $code = ''; 44 | 45 | /** 46 | * API Response ID 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $response_code = ''; 53 | 54 | /** 55 | * Courier Label 56 | * 57 | * @since 1.2.12 58 | * 59 | * @var string 60 | */ 61 | public $label = ''; 62 | 63 | /** 64 | * Courier Website 65 | * 66 | * @since 1.2.12 67 | * 68 | * @var string 69 | */ 70 | public $website = ''; 71 | 72 | /** 73 | * Get courier priority 74 | * 75 | * @since 1.2.12 76 | * 77 | * @return int 78 | */ 79 | public function get_priority() { 80 | return $this->priority; 81 | } 82 | 83 | /** 84 | * Get courier code 85 | * 86 | * @since 1.2.12 87 | * 88 | * @return string 89 | */ 90 | public function get_code() { 91 | return $this->code; 92 | } 93 | 94 | /** 95 | * Get courier API response ID 96 | * 97 | * @since 1.2.12 98 | * 99 | * @return string 100 | */ 101 | public function get_response_code() { 102 | return $this->response_code ? $this->response_code : $this->code; 103 | } 104 | 105 | /** 106 | * Get courier label 107 | * 108 | * @since 1.2.12 109 | * 110 | * @return string 111 | */ 112 | public function get_label() { 113 | return $this->label; 114 | } 115 | 116 | /** 117 | * Get courier website 118 | * 119 | * @since 1.2.12 120 | * 121 | * @return string 122 | */ 123 | public function get_website() { 124 | return $this->website; 125 | } 126 | 127 | /** 128 | * Get courier services 129 | * 130 | * @since 1.3.0 131 | * 132 | * @param string $zone Shipping zone. 133 | * 134 | * @return array 135 | */ 136 | public function get_services( $zone ) { 137 | if ( 'domestic' === $zone ) { 138 | return $this->get_services_domestic(); 139 | } 140 | 141 | if ( 'international' === $zone ) { 142 | return $this->get_services_international(); 143 | } 144 | 145 | return array(); 146 | } 147 | 148 | /** 149 | * Get default courier services 150 | * 151 | * @since 1.3.0 152 | * 153 | * @param string $zone Shipping zone. 154 | * 155 | * @return array 156 | */ 157 | public function get_services_default( $zone ) { 158 | if ( 'domestic' === $zone ) { 159 | return $this->get_services_domestic_default(); 160 | } 161 | 162 | if ( 'international' === $zone ) { 163 | return $this->get_services_international_default(); 164 | } 165 | 166 | return array(); 167 | } 168 | 169 | /** 170 | * Get courier services for domestic shipping 171 | * 172 | * @since 1.2.12 173 | * 174 | * @return array 175 | */ 176 | public function get_services_domestic() { 177 | $default_data = $this->get_services_domestic_default(); 178 | 179 | if ( ! $default_data ) { 180 | return array(); 181 | } 182 | 183 | $data_key = $this->get_services_data_key( 'domestic' ); 184 | $saved_data = get_option( $data_key ); 185 | 186 | if ( false === $saved_data ) { 187 | update_option( $data_key, $default_data, true ); 188 | } else { 189 | return $saved_data; 190 | } 191 | 192 | return $default_data; 193 | } 194 | 195 | /** 196 | * Get default courier services for domestic shipping 197 | * 198 | * @since 1.3.0 199 | * 200 | * @return array 201 | */ 202 | public function get_services_domestic_default() { 203 | return array(); 204 | } 205 | 206 | /** 207 | * Get courier services for international shipping 208 | * 209 | * @since 1.2.12 210 | * 211 | * @return array 212 | */ 213 | public function get_services_international() { 214 | $default_data = $this->get_services_international_default(); 215 | 216 | if ( ! $default_data ) { 217 | return array(); 218 | } 219 | 220 | $data_key = $this->get_services_data_key( 'international' ); 221 | $saved_data = get_option( $data_key ); 222 | 223 | if ( false === $saved_data ) { 224 | update_option( $data_key, $default_data, true ); 225 | } else { 226 | return $saved_data; 227 | } 228 | 229 | return $default_data; 230 | } 231 | 232 | /** 233 | * Get default courier services for international shipping 234 | * 235 | * @since 1.3.0 236 | * 237 | * @return array 238 | */ 239 | public function get_services_international_default() { 240 | return array(); 241 | } 242 | 243 | /** 244 | * Add new service 245 | * 246 | * @since 1.3.0 247 | * 248 | * @param string $id Service ID. 249 | * @param string $label Service label. 250 | * @param string $zone Shipping zone. 251 | * 252 | * @return bool 253 | */ 254 | public function add_service( $id, $label, $zone ) { 255 | $services = $this->get_services( $zone ); 256 | 257 | if ( isset( $services[ $id ] ) ) { 258 | return; 259 | } 260 | 261 | if ( ! $label ) { 262 | $label = $id; 263 | } 264 | 265 | $services[ $id ] = $label; 266 | 267 | return update_option( $this->get_services_data_key( $zone ), $services, true ); 268 | } 269 | 270 | /** 271 | * Update service 272 | * 273 | * @since 1.3.0 274 | * 275 | * @param string $id Service ID. 276 | * @param string $label Service label. 277 | * @param string $zone Shipping zone. 278 | * 279 | * @return bool 280 | */ 281 | public function update_service( $id, $label, $zone ) { 282 | $services = $this->get_services( $zone ); 283 | 284 | if ( ! isset( $services[ $id ] ) ) { 285 | return; 286 | } 287 | 288 | $services[ $id ] = $label; 289 | 290 | return update_option( $this->get_services_data_key( $zone ), $services, true ); 291 | } 292 | 293 | /** 294 | * Delete service 295 | * 296 | * @since 1.3.0 297 | * 298 | * @param string $id Service ID. 299 | * @param string $zone Shipping zone. 300 | * 301 | * @return bool 302 | */ 303 | public function delete_service( $id, $zone ) { 304 | $services = $this->get_services( $zone ); 305 | 306 | if ( ! isset( $services[ $id ] ) ) { 307 | return; 308 | } 309 | 310 | unset( $services[ $id ] ); 311 | 312 | return update_option( $this->get_services_data_key( $zone ), $services, true ); 313 | } 314 | 315 | /** 316 | * Get courier services data option name 317 | * 318 | * @since 1.3.0 319 | * 320 | * @param string $zone Shipping zone. 321 | * 322 | * @return string 323 | */ 324 | public function get_services_data_key( $zone ) { 325 | return sprintf( 'woongkir_couriers_data_%s_%s', $zone, $this->get_code() ); 326 | } 327 | 328 | /** 329 | * Get courier account for domestic shipping 330 | * 331 | * @since 1.2.12 332 | * 333 | * @return array 334 | */ 335 | public function get_account_domestic() { 336 | return array(); 337 | } 338 | 339 | /** 340 | * Get courier account for international shipping 341 | * 342 | * @since 1.2.12 343 | * 344 | * @return array 345 | */ 346 | public function get_account_international() { 347 | return array(); 348 | } 349 | 350 | /** 351 | * Get courier account for international shipping 352 | * 353 | * @since 1.2.12 354 | * 355 | * @param {string} $zone Zone ID. 356 | * 357 | * @return array 358 | */ 359 | public function get_account_by_zone( $zone ) { 360 | if ( 'domestic' === $zone ) { 361 | return $this->get_account_domestic(); 362 | } 363 | 364 | if ( 'international' === $zone ) { 365 | return $this->get_account_international(); 366 | } 367 | 368 | return array(); 369 | } 370 | 371 | /** 372 | * Populate properties as array 373 | * 374 | * @since 1.2.12 375 | * 376 | * @param string $zone Couriers zone: domestic, international, all. 377 | * 378 | * @return array 379 | */ 380 | public function to_array( $zone = 'all' ) { 381 | if ( 'domestic' === $zone ) { 382 | return array( 383 | 'priority' => $this->get_priority(), 384 | 'code' => $this->get_code(), 385 | 'response_code' => $this->get_response_code(), 386 | 'label' => $this->get_label(), 387 | 'website' => $this->get_website(), 388 | 'services' => $this->get_services_domestic(), 389 | 'account' => $this->get_account_domestic(), 390 | ); 391 | } 392 | 393 | if ( 'international' === $zone ) { 394 | return array( 395 | 'priority' => $this->get_priority(), 396 | 'code' => $this->get_code(), 397 | 'response_code' => $this->get_response_code(), 398 | 'label' => $this->get_label(), 399 | 'website' => $this->get_website(), 400 | 'services' => $this->get_services_international(), 401 | 'account' => $this->get_account_international(), 402 | ); 403 | } 404 | 405 | return array( 406 | 'priority' => $this->get_priority(), 407 | 'code' => $this->get_code(), 408 | 'response_code' => $this->get_response_code(), 409 | 'label' => $this->get_label(), 410 | 'website' => $this->get_website(), 411 | 'services_domestic' => $this->get_services_domestic(), 412 | 'services_international' => $this->get_services_international(), 413 | 'account_domestic' => $this->get_account_domestic(), 414 | 'account_international' => $this->get_account_international(), 415 | ); 416 | } 417 | } 418 | -------------------------------------------------------------------------------- /assets/src/js/polyfill.js: -------------------------------------------------------------------------------- 1 | // https://tc39.github.io/ecma262/#sec-array.prototype.find 2 | if (!Array.prototype.find) { 3 | Object.defineProperty(Array.prototype, 'find', { 4 | value: function (predicate) { 5 | // 1. Let O be ? ToObject(this value). 6 | if (this == null) { 7 | throw TypeError('"this" is null or not defined'); 8 | } 9 | 10 | var o = Object(this); 11 | 12 | // 2. Let len be ? ToLength(? Get(O, "length")). 13 | var len = o.length >>> 0; 14 | 15 | // 3. If IsCallable(predicate) is false, throw a TypeError exception. 16 | if (typeof predicate !== 'function') { 17 | throw TypeError('predicate must be a function'); 18 | } 19 | 20 | 21 | // 4. If thisArg was supplied, let T be thisArg; else let T be undefined. 22 | var thisArg = arguments[1]; 23 | 24 | // 5. Let k be 0. 25 | var k = 0; 26 | 27 | // 6. Repeat, while k < len 28 | while (k < len) { 29 | // a. Let Pk be ! ToString(k). 30 | // b. Let kValue be ? Get(O, Pk). 31 | // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)). 32 | // d. If testResult is true, return kValue. 33 | var kValue = o[k]; 34 | if (predicate.call(thisArg, kValue, k, o)) { 35 | return kValue; 36 | } 37 | // e. Increase k by 1. 38 | k++; 39 | } 40 | 41 | // 7. Return undefined. 42 | return undefined; 43 | }, 44 | configurable: true, 45 | writable: true 46 | }); 47 | } 48 | 49 | if (!Array.prototype.filter) { 50 | Array.prototype.filter = function (func, thisArg) { 51 | 'use strict'; 52 | if (!((typeof func === 'Function' || typeof func === 'function') && this)) 53 | throw new TypeError(); 54 | 55 | var len = this.length >>> 0, 56 | res = new Array(len), // preallocate array 57 | t = this, c = 0, i = -1; 58 | 59 | var kValue; 60 | if (thisArg === undefined) { 61 | while (++i !== len) { 62 | // checks to see if the key was set 63 | if (i in this) { 64 | kValue = t[i]; // in case t is changed in callback 65 | if (func(t[i], i, t)) { 66 | res[c++] = kValue; 67 | } 68 | } 69 | } 70 | } 71 | else { 72 | while (++i !== len) { 73 | // checks to see if the key was set 74 | if (i in this) { 75 | kValue = t[i]; 76 | if (func.call(thisArg, t[i], i, t)) { 77 | res[c++] = kValue; 78 | } 79 | } 80 | } 81 | } 82 | 83 | res.length = c; // shrink down array to proper size 84 | return res; 85 | }; 86 | } 87 | 88 | if (!Array.prototype.every) { 89 | Array.prototype.every = function (callbackfn, thisArg) { 90 | 'use strict'; 91 | var T, k; 92 | 93 | if (this == null) { 94 | throw new TypeError('this is null or not defined'); 95 | } 96 | 97 | // 1. Let O be the result of calling ToObject passing the this 98 | // value as the argument. 99 | var O = Object(this); 100 | 101 | // 2. Let lenValue be the result of calling the Get internal method 102 | // of O with the argument "length". 103 | // 3. Let len be ToUint32(lenValue). 104 | var len = O.length >>> 0; 105 | 106 | // 4. If IsCallable(callbackfn) is false, throw a TypeError exception. 107 | if (typeof callbackfn !== 'function' && Object.prototype.toString.call(callbackfn) !== '[object Function]') { 108 | throw new TypeError(); 109 | } 110 | 111 | // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. 112 | if (arguments.length > 1) { 113 | T = thisArg; 114 | } 115 | 116 | // 6. Let k be 0. 117 | k = 0; 118 | 119 | // 7. Repeat, while k < len 120 | while (k < len) { 121 | 122 | var kValue; 123 | 124 | // a. Let Pk be ToString(k). 125 | // This is implicit for LHS operands of the in operator 126 | // b. Let kPresent be the result of calling the HasProperty internal 127 | // method of O with argument Pk. 128 | // This step can be combined with c 129 | // c. If kPresent is true, then 130 | if (k in O) { 131 | var testResult; 132 | // i. Let kValue be the result of calling the Get internal method 133 | // of O with argument Pk. 134 | kValue = O[k]; 135 | 136 | // ii. Let testResult be the result of calling the Call internal method 137 | // of callbackfn with T as the this value if T is not undefined 138 | // else is the result of calling callbackfn 139 | // and argument list containing kValue, k, and O. 140 | if (T) testResult = callbackfn.call(T, kValue, k, O); 141 | else testResult = callbackfn(kValue, k, O) 142 | 143 | // iii. If ToBoolean(testResult) is false, return false. 144 | if (!testResult) { 145 | return false; 146 | } 147 | } 148 | k++; 149 | } 150 | return true; 151 | }; 152 | } 153 | 154 | // Production steps of ECMA-262, Edition 5, 15.4.4.19 155 | // Reference: https://es5.github.io/#x15.4.4.19 156 | if (!Array.prototype.map) { 157 | 158 | Array.prototype.map = function (callback/*, thisArg*/) { 159 | 160 | var T, A, k; 161 | 162 | if (this == null) { 163 | throw new TypeError('this is null or not defined'); 164 | } 165 | 166 | // 1. Let O be the result of calling ToObject passing the |this| 167 | // value as the argument. 168 | var O = Object(this); 169 | 170 | // 2. Let lenValue be the result of calling the Get internal 171 | // method of O with the argument "length". 172 | // 3. Let len be ToUint32(lenValue). 173 | var len = O.length >>> 0; 174 | 175 | // 4. If IsCallable(callback) is false, throw a TypeError exception. 176 | // See: https://es5.github.com/#x9.11 177 | if (typeof callback !== 'function') { 178 | throw new TypeError(callback + ' is not a function'); 179 | } 180 | 181 | // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. 182 | if (arguments.length > 1) { 183 | T = arguments[1]; 184 | } 185 | 186 | // 6. Let A be a new array created as if by the expression new Array(len) 187 | // where Array is the standard built-in constructor with that name and 188 | // len is the value of len. 189 | A = new Array(len); 190 | 191 | // 7. Let k be 0 192 | k = 0; 193 | 194 | // 8. Repeat, while k < len 195 | while (k < len) { 196 | 197 | var kValue, mappedValue; 198 | 199 | // a. Let Pk be ToString(k). 200 | // This is implicit for LHS operands of the in operator 201 | // b. Let kPresent be the result of calling the HasProperty internal 202 | // method of O with argument Pk. 203 | // This step can be combined with c 204 | // c. If kPresent is true, then 205 | if (k in O) { 206 | 207 | // i. Let kValue be the result of calling the Get internal 208 | // method of O with argument Pk. 209 | kValue = O[k]; 210 | 211 | // ii. Let mappedValue be the result of calling the Call internal 212 | // method of callback with T as the this value and argument 213 | // list containing kValue, k, and O. 214 | mappedValue = callback.call(T, kValue, k, O); 215 | 216 | // iii. Call the DefineOwnProperty internal method of A with arguments 217 | // Pk, Property Descriptor 218 | // { Value: mappedValue, 219 | // Writable: true, 220 | // Enumerable: true, 221 | // Configurable: true }, 222 | // and false. 223 | 224 | // In browsers that support Object.defineProperty, use the following: 225 | // Object.defineProperty(A, k, { 226 | // value: mappedValue, 227 | // writable: true, 228 | // enumerable: true, 229 | // configurable: true 230 | // }); 231 | 232 | // For best browser support, use the following: 233 | A[k] = mappedValue; 234 | } 235 | // d. Increase k by 1. 236 | k++; 237 | } 238 | 239 | // 9. return A 240 | return A; 241 | }; 242 | } 243 | 244 | // Production steps of ECMA-262, Edition 5, 15.4.4.18 245 | // Reference: https://es5.github.io/#x15.4.4.18 246 | 247 | if (!Array.prototype['forEach']) { 248 | 249 | Array.prototype.forEach = function (callback, thisArg) { 250 | 251 | if (this == null) { throw new TypeError('Array.prototype.forEach called on null or undefined'); } 252 | 253 | var T, k; 254 | // 1. Let O be the result of calling toObject() passing the 255 | // |this| value as the argument. 256 | var O = Object(this); 257 | 258 | // 2. Let lenValue be the result of calling the Get() internal 259 | // method of O with the argument "length". 260 | // 3. Let len be toUint32(lenValue). 261 | var len = O.length >>> 0; 262 | 263 | // 4. If isCallable(callback) is false, throw a TypeError exception. 264 | // See: https://es5.github.com/#x9.11 265 | if (typeof callback !== "function") { throw new TypeError(callback + ' is not a function'); } 266 | 267 | // 5. If thisArg was supplied, let T be thisArg; else let 268 | // T be undefined. 269 | if (arguments.length > 1) { T = thisArg; } 270 | 271 | // 6. Let k be 0 272 | k = 0; 273 | 274 | // 7. Repeat, while k < len 275 | while (k < len) { 276 | 277 | var kValue; 278 | 279 | // a. Let Pk be ToString(k). 280 | // This is implicit for LHS operands of the in operator 281 | // b. Let kPresent be the result of calling the HasProperty 282 | // internal method of O with argument Pk. 283 | // This step can be combined with c 284 | // c. If kPresent is true, then 285 | if (k in O) { 286 | 287 | // i. Let kValue be the result of calling the Get internal 288 | // method of O with argument Pk. 289 | kValue = O[k]; 290 | 291 | // ii. Call the Call internal method of callback with T as 292 | // the this value and argument list containing kValue, k, and O. 293 | callback.call(T, kValue, k, O); 294 | } 295 | // d. Increase k by 1. 296 | k++; 297 | } 298 | // 8. return undefined 299 | }; 300 | } 301 | 302 | // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys 303 | if (!Object.keys) { 304 | Object.keys = (function () { 305 | 'use strict'; 306 | var hasOwnProperty = Object.prototype.hasOwnProperty, 307 | hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'), 308 | dontEnums = [ 309 | 'toString', 310 | 'toLocaleString', 311 | 'valueOf', 312 | 'hasOwnProperty', 313 | 'isPrototypeOf', 314 | 'propertyIsEnumerable', 315 | 'constructor' 316 | ], 317 | dontEnumsLength = dontEnums.length; 318 | 319 | return function (obj) { 320 | if (typeof obj !== 'function' && (typeof obj !== 'object' || obj === null)) { 321 | throw new TypeError('Object.keys called on non-object'); 322 | } 323 | 324 | var result = [], prop, i; 325 | 326 | for (prop in obj) { 327 | if (hasOwnProperty.call(obj, prop)) { 328 | result.push(prop); 329 | } 330 | } 331 | 332 | if (hasDontEnumBug) { 333 | for (i = 0; i < dontEnumsLength; i++) { 334 | if (hasOwnProperty.call(obj, dontEnums[i])) { 335 | result.push(dontEnums[i]); 336 | } 337 | } 338 | } 339 | return result; 340 | }; 341 | }()); 342 | } 343 | -------------------------------------------------------------------------------- /includes/classes/class-woongkir-account.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | abstract class Woongkir_Account { 26 | 27 | /** 28 | * Account priority 29 | * 30 | * @since 1.2.12 31 | * 32 | * @var int 33 | */ 34 | public $priority = 0; 35 | 36 | /** 37 | * Account type 38 | * 39 | * @since 1.2.12 40 | * 41 | * @var string 42 | */ 43 | public $type = ''; 44 | 45 | /** 46 | * Account label 47 | * 48 | * @since 1.2.12 49 | * 50 | * @var string 51 | */ 52 | public $label = ''; 53 | 54 | /** 55 | * Account API URL 56 | * 57 | * @since 1.2.12 58 | * 59 | * @var string 60 | */ 61 | public $api_url = ''; 62 | 63 | /** 64 | * Account features 65 | * 66 | * @since 1.2.12 67 | * 68 | * @var array 69 | */ 70 | protected $features = array( 71 | 'multiple_couriers' => false, 72 | 'subdistrict' => false, 73 | 'volumetric' => false, 74 | 'weight_over_30kg' => false, 75 | 'dedicated_server' => false, 76 | ); 77 | 78 | /** 79 | * Allowed API Request parameters 80 | * 81 | * @since 1.2.12 82 | * 83 | * @var array 84 | */ 85 | protected $api_request_params = array( 86 | 'origin' => array( 87 | 'type' => 'string', 88 | 'validate_type' => 'is_string', 89 | ), 90 | 'originType' => array( 91 | 'type' => 'string', 92 | 'validate_type' => 'is_string', 93 | ), 94 | 'destination' => array( 95 | 'type' => 'string', 96 | 'validate_type' => 'is_string', 97 | ), 98 | 'destinationType' => array( 99 | 'type' => 'string', 100 | 'validate_type' => 'is_string', 101 | ), 102 | 'weight' => array( 103 | 'type' => 'numeric', 104 | 'validate_type' => 'is_numeric', 105 | ), 106 | 'courier' => array( 107 | 'type' => 'array', 108 | 'validate_type' => 'is_array', 109 | ), 110 | 'length' => array( 111 | 'type' => 'numeric', 112 | 'validate_type' => 'is_numeric', 113 | ), 114 | 'width' => array( 115 | 'type' => 'numeric', 116 | 'validate_type' => 'is_numeric', 117 | ), 118 | 'height' => array( 119 | 'type' => 'numeric', 120 | 'validate_type' => 'is_numeric', 121 | ), 122 | 'diameter' => array( 123 | 'type' => 'numeric', 124 | 'validate_type' => 'is_numeric', 125 | ), 126 | ); 127 | 128 | /** 129 | * Required API Request parameters 130 | * 131 | * @since 1.2.12 132 | * 133 | * @var array 134 | */ 135 | protected $api_request_params_required = array(); 136 | 137 | /** 138 | * Optionals API Request parameters 139 | * 140 | * @since 1.2.12 141 | * 142 | * @var array 143 | */ 144 | protected $api_request_params_optional = array(); 145 | 146 | /** 147 | * Get account priority 148 | * 149 | * @since 1.2.12 150 | * 151 | * @return int 152 | */ 153 | public function get_priority() { 154 | return $this->priority; 155 | } 156 | 157 | /** 158 | * Get account type 159 | * 160 | * @since 1.2.12 161 | * 162 | * @return string 163 | */ 164 | public function get_type() { 165 | return $this->type; 166 | } 167 | 168 | /** 169 | * Get account label 170 | * 171 | * @since 1.2.12 172 | * 173 | * @return string 174 | */ 175 | public function get_label() { 176 | return $this->label; 177 | } 178 | 179 | /** 180 | * Get account API URL 181 | * 182 | * @since 1.2.12 183 | * 184 | * @return string 185 | */ 186 | public function get_api_url() { 187 | return $this->api_url; 188 | } 189 | 190 | /** 191 | * Get account features 192 | * 193 | * @since 1.2.12 194 | * 195 | * @return array 196 | */ 197 | public function get_features() { 198 | return $this->features; 199 | } 200 | 201 | /** 202 | * Get account features label. 203 | * 204 | * @since 1.3 205 | * 206 | * @return array 207 | */ 208 | public static function get_features_label() { 209 | return array( 210 | 'multiple_couriers' => __( 'Multiple Shipping Couriers', 'woongkir' ), 211 | 'subdistrict' => __( 'Calculate Subdistrict Level', 'woongkir' ), 212 | 'volumetric' => __( 'Calculate Volumetric', 'woongkir' ), 213 | 'weight_over_30kg' => __( 'Calculate Weight Over 30kg', 'woongkir' ), 214 | 'dedicated_server' => __( 'Dedicated API Server', 'woongkir' ), 215 | ); 216 | } 217 | 218 | /** 219 | * Check is feature enabled 220 | * 221 | * @since 1.2.12 222 | * 223 | * @param string $feature_key Feature key. 224 | * 225 | * @return bool 226 | */ 227 | public function feature_enable( $feature_key ) { 228 | return isset( $this->features[ $feature_key ] ) ? $this->features[ $feature_key ] : false; 229 | } 230 | 231 | /** 232 | * Check is feature enabled 233 | * 234 | * @since 1.2.12 235 | * 236 | * @param string $feature_key Feature key. 237 | * 238 | * @return bool 239 | */ 240 | public function can_do( $feature_key ) { 241 | return $this->feature_enable( $feature_key ); 242 | } 243 | 244 | /** 245 | * Parse API request parameters. 246 | * 247 | * @since 1.2.12 248 | * 249 | * @param array $params API request parameters to parse. 250 | * 251 | * @throws Exception Error message. 252 | * 253 | * @return (array|WP_Error) 254 | */ 255 | public function api_request_parser( $params = array() ) { 256 | try { 257 | $parsed = array(); 258 | 259 | foreach ( $this->api_request_params as $allowed_key => $allowed ) { 260 | if ( ! in_array( $allowed_key, $this->api_request_params_required, true ) && ! in_array( $allowed_key, $this->api_request_params_optional, true ) ) { 261 | continue; 262 | } 263 | 264 | $value = isset( $params[ $allowed_key ] ) ? $params[ $allowed_key ] : null; 265 | $has_value = is_numeric( $value ) || is_string( $value ) || is_integer( $value ) ? strlen( $value ) : $value; 266 | 267 | if ( in_array( $allowed_key, $this->api_request_params_required, true ) && ! $has_value ) { 268 | // translators: %s API request parameter key. 269 | throw new Exception( sprintf( __( 'Required API request parameter is empty: %s.', 'woongkir' ), $allowed_key ) ); 270 | } 271 | 272 | if ( ! is_null( $value ) && isset( $allowed['validate_type'] ) && is_callable( $allowed['validate_type'] ) && ! call_user_func( $allowed['validate_type'], $value ) ) { 273 | // translators: %1$s API request parameter key, %2$s Expected data type, %1$s Passed data type. 274 | throw new Exception( sprintf( __( 'Invalid API request parameter data type: %1$s. Passed %2$s instead %3$s', 'woongkir' ), $allowed_key, gettype( $value ), $allowed['type'] ) ); 275 | } 276 | 277 | $value_modifier_callback = array( $this, 'api_request_param_' . $allowed_key . '_value_modifier' ); 278 | if ( is_callable( $value_modifier_callback ) ) { 279 | $value = call_user_func( $value_modifier_callback, $value ); 280 | } 281 | 282 | if ( is_wp_error( $value ) ) { 283 | throw new Exception( $value->get_error_message() ); 284 | } 285 | 286 | if ( ! is_null( $value ) ) { 287 | $parsed[ $allowed_key ] = $value; 288 | } 289 | } 290 | 291 | if ( empty( $parsed ) ) { 292 | throw new Exception( __( 'API request parameters is empty.', 'woongkir' ) ); 293 | } 294 | 295 | return $parsed; 296 | } catch ( Exception $e ) { 297 | return new WP_Error( 'invalid_request_params', $e->getMessage() ); 298 | } 299 | } 300 | 301 | /** 302 | * API Request parameter value modifier and validator: weight 303 | * 304 | * @since 1.2.12 305 | * 306 | * @param string $value weight parameter value. 307 | * 308 | * @return (float|int|double) 309 | */ 310 | protected function api_request_param_weight_value_modifier( $value ) { 311 | if ( ! $this->feature_enable( 'weight_over_30kg' ) && $value > 30000 ) { 312 | return new WP_Error( 'invalid_api_request_param_weight_value', __( 'Account type not support weight over 30 kg.', 'woongkir' ) ); 313 | } 314 | 315 | return $value; 316 | } 317 | 318 | /** 319 | * API Request parameter value modifier and validator: originType 320 | * 321 | * @since 1.2.12 322 | * 323 | * @param string $value originType parameter value. 324 | * 325 | * @return string 326 | */ 327 | protected function api_request_param_originType_value_modifier( $value ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid 328 | if ( ! $this->feature_enable( 'subdistrict' ) && 'subdistrict' === $value ) { 329 | return new WP_Error( 'invalid_api_request_param_originType_value', __( 'Account type not support subdistrict origin.', 'woongkir' ) ); 330 | } 331 | 332 | return $value; 333 | } 334 | 335 | /** 336 | * API Request parameter value modifier and validator: destinationType 337 | * 338 | * @since 1.2.12 339 | * 340 | * @param string $value destinationType parameter value. 341 | * 342 | * @return string 343 | */ 344 | protected function api_request_param_destinationType_value_modifier( $value ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid 345 | if ( ! $this->feature_enable( 'subdistrict' ) && 'subdistrict' === $value ) { 346 | return new WP_Error( 'invalid_api_request_param_destinationType_value', __( 'Account type not support subdistrict destination.', 'woongkir' ) ); 347 | } 348 | 349 | return $value; 350 | } 351 | 352 | /** 353 | * API Request parameter value modifier and validator: courier 354 | * 355 | * @since 1.2.12 356 | * 357 | * @param array $value courier parameter value. 358 | * 359 | * @return string 360 | */ 361 | protected function api_request_param_courier_value_modifier( $value ) { 362 | if ( ! $this->feature_enable( 'multiple_couriers' ) && count( $value ) > 1 ) { 363 | return new WP_Error( 'invalid_api_request_param_courier_value', __( 'Account type not support multiple couriers.', 'woongkir' ) ); 364 | } 365 | 366 | return implode( ':', $value ); 367 | } 368 | 369 | /** 370 | * Populate properties as array 371 | * 372 | * @since 1.2.12 373 | * 374 | * @return array 375 | */ 376 | public function to_array() { 377 | return array_merge( 378 | array( 379 | 'priority' => $this->get_priority(), 380 | 'type' => $this->get_type(), 381 | 'label' => $this->get_label(), 382 | 'api_url' => $this->get_api_url(), 383 | ), 384 | $this->get_features() 385 | ); 386 | } 387 | } 388 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Import modules 3 | */ 4 | const packageJSON = require('./package.json'); 5 | const semver = require('semver'); 6 | const argv = require('yargs').argv; 7 | const browserSync = require('browser-sync').create(); 8 | 9 | const gulp = require('gulp'); 10 | const gulpAutoprefixer = require('gulp-autoprefixer'); 11 | const gulpCleanCSS = require('gulp-clean-css'); 12 | const gulpConcat = require('gulp-concat'); 13 | const gulpIf = require('gulp-if'); 14 | const gulpIife = require('gulp-iife'); 15 | const gulpNotify = require('gulp-notify'); 16 | const gulpPhpcs = require('gulp-phpcs'); 17 | const gulpPlumber = require('gulp-plumber'); 18 | const gulpRename = require('gulp-rename'); 19 | const gulpReplace = require('gulp-replace'); 20 | const gulpSass = require('gulp-sass'); 21 | const gulpSourcemaps = require('gulp-sourcemaps'); 22 | const gulpUglify = require('gulp-uglify'); 23 | const gulpWpPot = require('gulp-wp-pot'); 24 | 25 | /** 26 | * Local variables 27 | */ 28 | const prefix = 'woongkir'; 29 | const project = 'Woongkir'; 30 | 31 | const assets = [ 32 | { 33 | type: 'scripts', 34 | target: 'backend', 35 | sources: [ 36 | 'polyfill.js', 37 | 'shared.js', 38 | 'backend.js', 39 | ], 40 | targetDir: 'assets/js/', 41 | sourcesDir: 'assets/src/js/', 42 | isPrefixed: true, 43 | isIife: true, 44 | isSourceMap: false, 45 | }, 46 | { 47 | type: 'scripts', 48 | target: 'frontend', 49 | sources: [ 50 | 'polyfill.js', 51 | 'shared.js', 52 | 'frontend.js', 53 | ], 54 | targetDir: 'assets/js/', 55 | sourcesDir: 'assets/src/js/', 56 | isPrefixed: true, 57 | isIife: true, 58 | isSourceMap: false, 59 | }, 60 | { 61 | type: 'scripts', 62 | target: 'lockr', 63 | sources: [ 64 | 'plugins/lockr.js', 65 | ], 66 | targetDir: 'assets/js/', 67 | sourcesDir: 'assets/src/js/', 68 | isPrefixed: false, 69 | isIife: false, 70 | isSourceMap: false, 71 | }, 72 | { 73 | type: 'styles', 74 | target: 'backend', 75 | sources: [ 76 | 'backend.scss', 77 | ], 78 | targetDir: 'assets/css/', 79 | sourcesDir: 'assets/src/scss/', 80 | isPrefixed: true, 81 | isSourceMap: false, 82 | }, 83 | { 84 | type: 'php', 85 | target: 'php', 86 | sources: [ 87 | '*.php', 88 | '**/*.php', 89 | '!vendor/', 90 | '!vendor/**', 91 | '!dist/', 92 | '!dist/**', 93 | '!node_modules/', 94 | '!node_modules/**', 95 | '!index.php', 96 | '!**/index.php', 97 | ], 98 | }, 99 | ]; 100 | 101 | /** 102 | * Custom error handler 103 | */ 104 | const errorHandler = function () { 105 | return gulpPlumber(function (err) { 106 | gulpNotify.onError({ 107 | title: 'Gulp error in ' + err.plugin, 108 | message: err.toString() 109 | })(err); 110 | }); 111 | }; 112 | 113 | /** 114 | * Script task handler 115 | */ 116 | const scriptsHandler = function (asset, isMinify) { 117 | const srcParam = asset.sources.map(function (sources) { 118 | const sourcesDir = asset.sourcesDir || ''; 119 | return sourcesDir + sources; 120 | }); 121 | 122 | return gulp.src(srcParam) 123 | .pipe(errorHandler()) 124 | .pipe(gulpConcat(asset.target + '.js')) 125 | .pipe(gulpIf(asset.isIife, gulpIife({ 126 | useStrict: true, 127 | trimCode: true, 128 | prependSemicolon: false, 129 | bindThis: false, 130 | params: ['$', 'wc_checkout_params'], 131 | args: ['jQuery', 'window.wc_checkout_params'] 132 | }))) 133 | .pipe(gulpIf(asset.isPrefixed, gulpRename({ 134 | prefix: prefix + '-', 135 | }))) 136 | .pipe(gulp.dest(asset.targetDir)) 137 | .pipe(gulpIf(isMinify, gulpRename({ 138 | suffix: '.min', 139 | }))) 140 | .pipe(gulpIf(asset.isSourceMap, gulpSourcemaps.init())) 141 | .pipe(gulpIf(isMinify, gulpUglify())) 142 | .pipe(gulpIf(asset.isSourceMap, gulpSourcemaps.write())) 143 | .pipe(gulpIf(isMinify, gulp.dest(asset.targetDir))); 144 | } 145 | 146 | /** 147 | * Style task handler 148 | */ 149 | const stylesHandler = function (asset, isMinify) { 150 | const srcParam = asset.sources.map(function (sourcesFile) { 151 | const sourcesDir = asset.sourcesDir || ''; 152 | return sourcesDir + sourcesFile; 153 | }); 154 | 155 | return gulp.src(srcParam) 156 | .pipe(errorHandler()) 157 | .pipe(gulpIf(asset.isSourceMap, gulpSourcemaps.init())) 158 | .pipe(gulpSass().on('error', gulpSass.logError)) 159 | .pipe(gulpAutoprefixer( 160 | 'last 2 version', 161 | '> 1%', 162 | 'safari 5', 163 | 'ie 8', 164 | 'ie 9', 165 | 'opera 12.1', 166 | 'ios 6', 167 | 'android 4')) 168 | .pipe(gulpIf(asset.isPrefixed, gulpRename({ 169 | prefix: prefix + '-', 170 | }))) 171 | .pipe(gulp.dest(asset.targetDir)) 172 | .pipe(gulpIf(isMinify, gulpRename({ 173 | suffix: '.min', 174 | }))) 175 | .pipe(gulpIf(isMinify, gulpCleanCSS({ 176 | compatibility: 'ie8', 177 | }))) 178 | .pipe(gulpIf(asset.isSourceMap, gulpSourcemaps.write())) 179 | .pipe(gulpIf(isMinify, gulp.dest(asset.targetDir))) 180 | .pipe(gulpIf(!isMinify, browserSync.stream())); 181 | } 182 | 183 | /** 184 | * PHPCS tasks handler 185 | */ 186 | const phpcsHandler = function (asset) { 187 | const srcParam = asset.sources.map(function (sourcesFile) { 188 | const sourcesDir = asset.sourcesDir || ''; 189 | return sourcesDir + sourcesFile; 190 | }); 191 | 192 | const config = Object.assign({}, asset.config, { 193 | bin: 'vendor/bin/phpcs', 194 | standard: 'phpcs.xml', 195 | warningSeverity: 0, 196 | }); 197 | 198 | return gulp.src(srcParam) 199 | .pipe(errorHandler()) 200 | .pipe(gulpPhpcs(config)) 201 | .pipe(gulpPhpcs.reporter('log')); 202 | } 203 | 204 | /** 205 | * Internationalization task handler 206 | */ 207 | const i18nHandler = function (asset) { 208 | const srcParam = asset.sources.map(function (sourcesFile) { 209 | const sourcesDir = asset.sourcesDir || ''; 210 | return sourcesDir + sourcesFile; 211 | }); 212 | 213 | const config = Object.assign({}, asset.config, { 214 | domain: prefix, 215 | package: project, 216 | }); 217 | 218 | return gulp.src(srcParam) 219 | .pipe(gulpWpPot(config)) 220 | .pipe(gulp.dest('languages/' + config.domain + '.pot')); 221 | } 222 | 223 | /** 224 | * Build tasks list 225 | */ 226 | const tasksListBuild = []; 227 | 228 | assets.forEach(function (asset) { 229 | /** 230 | * Minify Scripts Task 231 | */ 232 | if (asset.type === 'scripts') { 233 | const taskName = asset.target + '-scripts-minify'; 234 | 235 | gulp.task(taskName, function () { 236 | return scriptsHandler(asset, true); 237 | }); 238 | 239 | tasksListBuild.push(taskName); 240 | } 241 | 242 | /** 243 | * Minify Styles Task 244 | */ 245 | if (asset.type === 'styles') { 246 | const taskName = asset.target + '-styles-minify'; 247 | 248 | gulp.task(taskName, function () { 249 | return stylesHandler(asset, true); 250 | }); 251 | 252 | tasksListBuild.push(taskName); 253 | } 254 | 255 | /** 256 | * Internationalization Task 257 | */ 258 | if (asset.type === 'php') { 259 | const taskName = asset.target + '-i18n'; 260 | 261 | gulp.task(taskName, function () { 262 | return i18nHandler(asset); 263 | }); 264 | 265 | tasksListBuild.push(taskName); 266 | } 267 | }); 268 | 269 | /** 270 | * Build task 271 | */ 272 | gulp.task('build', tasksListBuild); 273 | 274 | /** 275 | * Default tasks list 276 | */ 277 | const tasksListDefault = []; 278 | 279 | assets.forEach(function (asset) { 280 | /** 281 | * Scripts Task 282 | */ 283 | if (asset.type === 'scripts') { 284 | const taskName = asset.target + '-scripts'; 285 | 286 | gulp.task(taskName, function () { 287 | return scriptsHandler(asset); 288 | }); 289 | 290 | tasksListDefault.push(taskName); 291 | } 292 | 293 | /** 294 | * Styles Task 295 | */ 296 | if (asset.type === 'styles') { 297 | const taskName = asset.target + '-styles'; 298 | 299 | gulp.task(taskName, function () { 300 | return stylesHandler(asset, false); 301 | }); 302 | 303 | tasksListDefault.push(taskName); 304 | } 305 | 306 | /** 307 | * PHPCS Task 308 | */ 309 | if (asset.type === 'php') { 310 | const taskName = asset.target + '-phpcs'; 311 | 312 | gulp.task(taskName, function () { 313 | return phpcsHandler(asset); 314 | }); 315 | 316 | tasksListDefault.push(taskName); 317 | } 318 | }); 319 | 320 | 321 | /** 322 | * Default task 323 | */ 324 | gulp.task('default', tasksListDefault, function () { 325 | if (argv.hasOwnProperty('proxy')) { 326 | browserSync.init({ 327 | proxy: argv.proxy 328 | }); 329 | } 330 | 331 | assets.forEach(function (asset) { 332 | /** 333 | * Watch styles sources files 334 | */ 335 | if (asset.type === 'styles') { 336 | const watchStylesSrc = asset.sources.map(function (sourcesFile) { 337 | const sourcesDir = asset.sourcesDir || ''; 338 | return sourcesDir + sourcesFile; 339 | }); 340 | 341 | gulp.watch(watchStylesSrc, [asset.target + '-styles']); 342 | } 343 | 344 | /** 345 | * Watch scripts sources files 346 | */ 347 | if (asset.type === 'scripts') { 348 | const watchScriptsSrc = asset.sources.map(function (sourcesFile) { 349 | const sourcesDir = asset.sourcesDir || ''; 350 | return sourcesDir + sourcesFile; 351 | }); 352 | 353 | gulp.watch(watchScriptsSrc, [asset.target + '-scripts']).on('change', function () { 354 | if (argv.hasOwnProperty('proxy')) { 355 | browserSync.reload(); 356 | } 357 | }); 358 | } 359 | 360 | /** 361 | * Watch php sources files 362 | */ 363 | if (asset.type === 'php') { 364 | const watchSrc = asset.sources.map(function (sourcesFile) { 365 | const sourcesDir = asset.sourcesDir || ''; 366 | return sourcesDir + sourcesFile; 367 | }); 368 | 369 | gulp.watch(watchSrc, [asset.target + '-phpcs']).on('change', function () { 370 | if (argv.hasOwnProperty('proxy')) { 371 | browserSync.reload(); 372 | } 373 | }); 374 | } 375 | }); 376 | }); 377 | 378 | gulp.task('bump', function () { 379 | const versionCurrent = packageJSON.version; 380 | const versionBump = semver.inc(packageJSON.version, (argv.semver || 'patch')); 381 | 382 | const assets = [ 383 | { 384 | src: ['./includes/**/*.php'], 385 | dest: './includes/', 386 | search: /\@since(\s+)\?\?/g, 387 | replaceWith: `@since$1${versionBump}`, 388 | }, 389 | { 390 | src: ['./woongkir.php'], 391 | dest: './', 392 | search: `* Version: ${versionCurrent}`, 393 | replaceWith: `* Version: ${versionBump}`, 394 | }, 395 | { 396 | src: ['./README.txt'], 397 | dest: './', 398 | search: `Stable tag: ${versionCurrent}`, 399 | replaceWith: `Stable tag: ${versionBump}`, 400 | }, 401 | { 402 | src: ['./package.json'], 403 | dest: './', 404 | search: `"version": "${versionCurrent}"`, 405 | replaceWith: `"version": "${versionBump}"`, 406 | }, 407 | ]; 408 | 409 | assets.forEach(function (asset) { 410 | gulp.src(asset.src) 411 | .pipe(gulpReplace(asset.search, asset.replaceWith)) 412 | .pipe(gulp.dest(asset.dest)); 413 | }); 414 | }); 415 | 416 | // Export task 417 | gulp.task('dist', ['build'], function () { 418 | gulp.src([ 419 | './**', 420 | '!tests/', 421 | '!bin/', 422 | '!vendor/', 423 | '!dist/', 424 | '!node_modules/', 425 | '!assets/src/', 426 | '!tests/**', 427 | '!bin/**', 428 | '!vendor/**', 429 | '!dist/**', 430 | '!node_modules/**', 431 | '!assets/src/**', 432 | '!gulpfile.js', 433 | '!package-lock.json', 434 | '!package.json', 435 | '!composer.lock', 436 | '!composer.json', 437 | '!yarn.lock', 438 | '!phpcs.xml', 439 | '!phpunit.xml', 440 | '!deploy-wp.sh', 441 | ]) 442 | .pipe(gulp.dest('./dist')); 443 | }); 444 | -------------------------------------------------------------------------------- /includes/helpers.php: -------------------------------------------------------------------------------- 1 | errors ) && $wp_filesystem->errors->get_error_code() ) ) { 94 | throw new Exception( 'WordPress Filesystem Abstraction classes is not available', 1 ); 95 | } 96 | 97 | if ( ! $wp_filesystem->exists( $file_path ) ) { 98 | throw new Exception( 'JSON file is not exists or unreadable', 1 ); 99 | } 100 | 101 | $json = $wp_filesystem->get_contents( $file_path ); 102 | } catch ( Exception $e ) { 103 | // Get JSON data by HTTP if the WP_Filesystem API procedure failed. 104 | $json = wp_remote_retrieve_body( wp_remote_get( esc_url_raw( $file_url ) ) ); 105 | } 106 | 107 | if ( ! $json ) { 108 | return false; 109 | } 110 | 111 | $json_data = json_decode( $json, true ); 112 | $json_error = json_last_error_msg(); 113 | 114 | if ( ! $json_data || ( $json_error && 'no error' !== strtolower( $json_error ) ) ) { 115 | return false; 116 | } 117 | 118 | // Search JSON data by associative array. Return the match row or false if not found. 119 | if ( $search ) { 120 | foreach ( $json_data as $row ) { 121 | if ( array_intersect_assoc( $search, $row ) === $search ) { 122 | return $row; 123 | } 124 | } 125 | 126 | return false; 127 | } 128 | 129 | return $json_data; 130 | } 131 | endif; 132 | 133 | if ( ! function_exists( 'woongkir_scripts_params' ) ) : 134 | /** 135 | * Get localized scripts parameters. 136 | * 137 | * @since 1.2.11 138 | * 139 | * @param array $params Custom localized scripts parameters. 140 | * 141 | * @return array 142 | */ 143 | function woongkir_scripts_params( $params = array() ) { 144 | $json_version = str_replace( '.', '_', woongkir_get_plugin_data( 'Version' ) ); 145 | $json_keys = array( 'country', 'state', 'city', 'address_2' ); 146 | $json_data = array(); 147 | 148 | foreach ( $json_keys as $json_key ) { 149 | $json_data[ $json_key ] = array( 150 | 'url' => WOONGKIR_URL . woongkir_get_json_path( $json_key ), 151 | 'key' => 'woongkir_data_' . $json_key . '_v_' . $json_version, 152 | ); 153 | } 154 | 155 | return wp_parse_args( 156 | $params, 157 | array( 158 | 'json' => $json_data, 159 | 'locale' => WC()->countries->get_country_locale(), 160 | ) 161 | ); 162 | } 163 | endif; 164 | 165 | if ( ! function_exists( 'woongkir_sort_by_priority' ) ) : 166 | /** 167 | * Sort data by priority 168 | * 169 | * @param array $a Item to compare. 170 | * @param array $b Item to compare. 171 | * 172 | * @return int 173 | */ 174 | function woongkir_sort_by_priority( $a, $b ) { 175 | $a_priority = 0; 176 | 177 | if ( is_object( $a ) && is_callable( array( $a, 'get_priority' ) ) ) { 178 | $a_priority = $a->get_priority(); 179 | } elseif ( isset( $a['priority'] ) ) { 180 | $a_priority = $a['priority']; 181 | } 182 | 183 | $b_priority = 0; 184 | 185 | if ( is_object( $b ) && is_callable( array( $b, 'get_priority' ) ) ) { 186 | $b_priority = $b->get_priority(); 187 | } elseif ( isset( $b['priority'] ) ) { 188 | $b_priority = $b['priority']; 189 | } 190 | 191 | return strcasecmp( $a_priority, $b_priority ); 192 | } 193 | endif; 194 | 195 | if ( ! function_exists( 'woongkir_is_dev' ) ) : 196 | /** 197 | * Check is in development environment. 198 | * 199 | * @since 1.2.11 200 | * 201 | * @return bool 202 | */ 203 | function woongkir_is_dev() { 204 | if ( defined( 'WOONGKIR_DEV' ) && WOONGKIR_DEV ) { 205 | return true; 206 | } 207 | 208 | if ( function_exists( 'getenv' ) && getenv( 'WOONGKIR_DEV' ) ) { 209 | return true; 210 | } 211 | 212 | return false; 213 | } 214 | endif; 215 | 216 | if ( ! function_exists( 'woongkir_get_plugin_data' ) ) : 217 | /** 218 | * Get plugin data 219 | * 220 | * @since 1.2.13 221 | * 222 | * @param string $selected Selected data key. 223 | * @param string $selected_default Selected data key default value. 224 | * @param bool $markup If the returned data should have HTML markup applied. 225 | * @param bool $translate If the returned data should be translated. 226 | * 227 | * @return (string|array) 228 | */ 229 | function woongkir_get_plugin_data( $selected = null, $selected_default = '', $markup = false, $translate = true ) { 230 | static $plugin_data; 231 | 232 | if ( ! function_exists( 'get_plugin_data' ) ) { 233 | require_once ABSPATH . 'wp-admin/includes/plugin.php'; 234 | } 235 | 236 | if ( is_null( $plugin_data ) ) { 237 | $plugin_data = get_plugin_data( WOONGKIR_FILE, $markup, $translate ); 238 | } 239 | 240 | if ( ! is_null( $selected ) ) { 241 | return isset( $plugin_data[ $selected ] ) ? $plugin_data[ $selected ] : $selected_default; 242 | } 243 | 244 | return $plugin_data; 245 | } 246 | endif; 247 | 248 | if ( ! function_exists( 'woongkir_instances' ) ) : 249 | /** 250 | * Get shipping method instances 251 | * 252 | * @since 1.3.0 253 | * 254 | * @param bool $enabled_only Filter to includes only enabled instances. 255 | * @return array 256 | */ 257 | function woongkir_instances( $enabled_only = true ) { 258 | $instances = array(); 259 | 260 | $zone_data_store = new WC_Shipping_Zone_Data_Store(); 261 | 262 | $shipping_methods = $zone_data_store->get_methods( '0', $enabled_only ); 263 | 264 | if ( $shipping_methods ) { 265 | foreach ( $shipping_methods as $shipping_method ) { 266 | if ( WOONGKIR_METHOD_ID !== $shipping_method->method_id ) { 267 | continue; 268 | } 269 | 270 | $instances[] = array( 271 | 'zone_id' => 0, 272 | 'method_id' => $shipping_method->method_id, 273 | 'instance_id' => $shipping_method->instance_id, 274 | ); 275 | } 276 | } 277 | 278 | $zones = WC_Shipping_Zones::get_zones(); 279 | 280 | if ( ! empty( $zones ) ) { 281 | foreach ( $zones as $zone ) { 282 | $shipping_methods = $zone_data_store->get_methods( $zone['id'], $enabled_only ); 283 | if ( $shipping_methods ) { 284 | foreach ( $shipping_methods as $shipping_method ) { 285 | if ( WOONGKIR_METHOD_ID !== $shipping_method->method_id ) { 286 | continue; 287 | } 288 | 289 | $instances[] = array( 290 | 'zone_id' => 0, 291 | 'method_id' => $shipping_method->method_id, 292 | 'instance_id' => $shipping_method->instance_id, 293 | ); 294 | } 295 | } 296 | } 297 | } 298 | 299 | return apply_filters( 'woongkir_instances', $instances ); 300 | } 301 | endif; 302 | 303 | if ( ! function_exists( 'woongkir_is_enable_cache' ) ) : 304 | /** 305 | * Check wether api response should be cached 306 | * 307 | * @return boolean 308 | */ 309 | function woongkir_is_enable_cache() { 310 | return defined( 'WOONGKIR_ENABLE_CACHE' ) ? WOONGKIR_ENABLE_CACHE : true; 311 | } 312 | endif; 313 | 314 | if ( ! function_exists( 'woongkir_parse_etd' ) ) : 315 | /** 316 | * Parse API response ETD data. 317 | * 318 | * @since 1.3 319 | * 320 | * @param string $etd API response ETD data. 321 | * 322 | * @return string 323 | */ 324 | function woongkir_parse_etd( $etd ) { 325 | if ( ! $etd ) { 326 | return ''; 327 | } 328 | 329 | $etd = strtolower( $etd ); 330 | $etd = preg_replace( '/([0-9]+) - ([0-9]+)/', '$1-$2', $etd ); 331 | $etd = str_replace( '1-1', '1', $etd ); 332 | $etd = str_replace( '0-0', '0', $etd ); 333 | 334 | if ( false !== strpos( $etd, 'jam' ) ) { 335 | $etd = trim( str_replace( 'jam', '', $etd ) ); 336 | 337 | // translators: %s is number of hours. 338 | $etd = is_numeric( $etd ) && intval( $etd ) === 1 ? __( '1 hour', 'woongkir' ) : sprintf( __( '%s hours', 'woongkir' ), $etd ); 339 | } else { 340 | $etd = trim( str_replace( 'hari', '', $etd ) ); 341 | 342 | // translators: %s is number of days. 343 | $etd = is_numeric( $etd ) && intval( $etd ) === 1 ? __( '1 day', 'woongkir' ) : sprintf( __( '%s days', 'woongkir' ), $etd ); 344 | } 345 | 346 | return $etd; 347 | } 348 | endif; 349 | 350 | if ( ! function_exists( 'woongkir_custom_address_fields' ) ) : 351 | /** 352 | * Get custom address fields data. 353 | * 354 | * @since 1.3 355 | * 356 | * @return array 357 | */ 358 | function woongkir_custom_address_fields() { 359 | $custom_address_fields = array( 360 | 'state' => array( 361 | 'label' => __( 'Province', 'woongkir' ), 362 | 'placeholder' => __( 'Province', 'woongkir' ), 363 | 'priority' => 41, 364 | ), 365 | 'city' => array( 366 | 'label' => __( 'Town / City', 'woongkir' ), 367 | 'placeholder' => __( 'Town / City', 'woongkir' ), 368 | 'priority' => 42, 369 | ), 370 | 'address_2' => array( 371 | 'label' => __( 'Subdistrict', 'woongkir' ), 372 | 'placeholder' => __( 'Subdistrict', 'woongkir' ), 373 | 'priority' => 43, 374 | ), 375 | ); 376 | 377 | return apply_filters( 'woongkir_custom_address_fields', $custom_address_fields ); 378 | } 379 | endif; 380 | -------------------------------------------------------------------------------- /assets/src/js/backend.js: -------------------------------------------------------------------------------- 1 | var openSettingsModalTimeout; 2 | 3 | function woongkirBackendGetUrlParams(url) { 4 | var params = {}; 5 | var parser = document.createElement('a'); 6 | 7 | parser.href = url; 8 | 9 | var query = parser.search.substring(1); 10 | var vars = query.split('&'); 11 | 12 | for (var i = 0; i < vars.length; i++) { 13 | var pair = vars[i].split('='); 14 | 15 | if (pair.length === 2) { 16 | params[pair[0]] = decodeURIComponent(pair[1]); 17 | } 18 | } 19 | 20 | return params; 21 | }; 22 | 23 | function woongkirBackendOpenSettingsModal() { 24 | var urlParams = woongkirBackendGetUrlParams(window.location.search); 25 | 26 | if (!urlParams.woongkir_settings) { 27 | return; 28 | } 29 | 30 | if (openSettingsModalTimeout) { 31 | clearTimeout(openSettingsModalTimeout); 32 | } 33 | 34 | openSettingsModalTimeout = setTimeout(function () { 35 | var methodsMatch = $(document).find('.wc-shipping-zone-method-type').filter(function () { 36 | return $(this).text() === woongkir_params.method_title; 37 | }); 38 | 39 | if (methodsMatch.length) { 40 | $(methodsMatch).closest('tr').find('.row-actions .wc-shipping-zone-method-settings').trigger('click'); 41 | } else { 42 | $('.wc-shipping-zone-add-method').trigger('click'); 43 | $('select[name="add_method_id"]').val(woongkir_params.method_id).trigger('change'); 44 | } 45 | }, 500); 46 | } 47 | 48 | function woongkirBackendRenderOriginLocations() { 49 | var fieldPrefix = 'woocommerce_woongkir_origin_location'; 50 | 51 | var localeData = $.extend(true, {}, woongkir_params.locale.default, woongkir_params.locale.ID); 52 | 53 | $.each(woongkirShared.getFields(), function (fieldSuffix, fieldData) { 54 | var $field = $('#' + fieldPrefix + '_' + fieldSuffix); 55 | 56 | if (!$field || !$field.length) { 57 | return; 58 | } 59 | 60 | $field.off('change', fieldData.onChange); 61 | 62 | woongkirShared.getLocationData(fieldSuffix).then(function (results) { 63 | var options = woongkirShared.filterLocationData(results, fieldPrefix, fieldSuffix, fieldData); 64 | var placeholder = localeData[fieldSuffix] && localeData[fieldSuffix].placeholder || ''; 65 | 66 | $field.attr({ 67 | placeholder: placeholder, 68 | }).data({ 69 | placeholder: placeholder, 70 | }).selectWoo({ 71 | data: options, 72 | width: '100%', 73 | }); 74 | 75 | $field.on('change', fieldData.onChange); 76 | }); 77 | }); 78 | } 79 | 80 | function woongkirBackendToggleApiKeyVisibility() { 81 | $('#woocommerce_woongkir_api_key_toggle').remove(); 82 | 83 | $("#woocommerce_woongkir_api_key").each(function () { 84 | $(this).after(''); 85 | }); 86 | 87 | $('#woocommerce_woongkir_api_key_toggle').off('click'); 88 | 89 | $('#woocommerce_woongkir_api_key_toggle').on('click', function (event) { 90 | event.preventDefault(); 91 | 92 | var fieldType = $("#woocommerce_woongkir_api_key").attr('type'); 93 | 94 | if ('password' === fieldType) { 95 | $("#woocommerce_woongkir_api_key").attr('type', 'text'); 96 | } else { 97 | $("#woocommerce_woongkir_api_key").attr('type', 'password'); 98 | } 99 | 100 | $(this).find('span').toggleClass('dashicons-visibility dashicons-hidden'); 101 | }); 102 | } 103 | 104 | function woongkirBackendInitCouriersSortable() { 105 | $(".woongkir-couriers").sortable({ 106 | axis: 'y', 107 | cursor: 'move', 108 | }); 109 | } 110 | 111 | function woongkirBackendHandleChangeAccountType(event) { 112 | var $accountType = $(event.target); 113 | 114 | if (!$accountType.is(':checked')) { 115 | return; 116 | } 117 | 118 | var accounts = $accountType.data('accounts'); 119 | var accountType = $accountType.val(); 120 | var accountSelected = accountType && accounts[accountType]; 121 | 122 | if (!accountSelected) { 123 | return; 124 | } 125 | 126 | // Toggle volumetric converter fields 127 | var $volumetricCalculator = $('#woocommerce_woongkir_volumetric_calculator'); 128 | 129 | if (accountSelected.volumetric) { 130 | if ($volumetricCalculator.closest('tr').length) { 131 | $volumetricCalculator.closest('tr').show(); 132 | } else { 133 | $("label[for='woocommerce_woongkir_volumetric_calculator']").show().next('fieldset').show(); 134 | } 135 | } else { 136 | $volumetricCalculator.prop('checked', false); 137 | 138 | if ($volumetricCalculator.closest('tr').length) { 139 | $volumetricCalculator.closest('tr').hide(); 140 | } else { 141 | $("label[for='woocommerce_woongkir_volumetric_calculator']").hide().next('fieldset').hide(); 142 | } 143 | } 144 | 145 | $volumetricCalculator.trigger('change'); 146 | 147 | var couriers = $accountType.data('couriers'); 148 | 149 | $.each(couriers, function (zoneId, zoneData) { 150 | var zoneCouriers = []; 151 | 152 | $.each(zoneData, function (courierId, courierData) { 153 | if (courierData.account && courierData.account.indexOf(accountType) !== -1) { 154 | zoneCouriers.push(courierId); 155 | } 156 | }); 157 | 158 | $('#woongkir-couriers-' + zoneId).find('.woongkir-couriers-item').each(function () { 159 | if (zoneCouriers.length && zoneCouriers.indexOf($(this).data('id')) !== -1) { 160 | $(this).show(); 161 | } else { 162 | $(this).hide().find('.woongkir-service--bulk').prop('checked', false).trigger('change'); 163 | } 164 | }); 165 | }); 166 | 167 | if (!accountSelected.multiple_couriers) { 168 | $.each(couriers, function (zoneId) { 169 | var $firstCheckBox = $('#woongkir-couriers-' + zoneId).find('.woongkir-service--single:checked').first(); 170 | 171 | if ($firstCheckBox && $firstCheckBox.length) { 172 | var $firstCheckBoxBulk = $firstCheckBox.closest('.woongkir-couriers-item').find('.woongkir-service--bulk'); 173 | 174 | if ($firstCheckBoxBulk && $firstCheckBoxBulk.length) { 175 | $('#woongkir-couriers-' + zoneId).find('.woongkir-service--bulk').not($firstCheckBoxBulk).prop('checked', false).trigger('change'); 176 | } 177 | } 178 | }); 179 | } 180 | } 181 | 182 | function woongkirBackendHandleChangeVolumetricCalculator(event) { 183 | var $volumetricDivider = $('#woocommerce_woongkir_volumetric_divider'); 184 | 185 | if ($(event.target).is(':checked')) { 186 | if ($volumetricDivider.closest('tr').length) { 187 | $volumetricDivider.closest('tr').show(); 188 | } else { 189 | $("label[for='woocommerce_woongkir_volumetric_divider']").show().next('fieldset').show(); 190 | } 191 | } else { 192 | if ($volumetricDivider.closest('tr').length) { 193 | $volumetricDivider.closest('tr').hide(); 194 | } else { 195 | $("label[for='woocommerce_woongkir_volumetric_divider']").hide().next('fieldset').hide(); 196 | } 197 | } 198 | } 199 | 200 | function woongkirBackendToggleCourierServices(event) { 201 | event.preventDefault(); 202 | 203 | $(event.currentTarget) 204 | .find('.dashicons') 205 | .toggleClass('dashicons-admin-generic dashicons-arrow-up-alt2') 206 | .closest('.woongkir-couriers-item') 207 | .toggleClass('expanded'); 208 | 209 | } 210 | 211 | function woongkirBackendSelectServicesBulk(event) { 212 | var $checkboxBulk = $(event.target); 213 | var $couriers = $checkboxBulk.closest('.woongkir-couriers'); 214 | var $courierItem = $checkboxBulk.closest('.woongkir-couriers-item'); 215 | 216 | var $accountType = $('.woongkir-account-type:checked'); 217 | var accounts = $accountType.data('accounts'); 218 | var accountType = $accountType.val(); 219 | var accountSelected = accountType && accounts[accountType]; 220 | 221 | var isChecked = $checkboxBulk.is(':checked'); 222 | 223 | $courierItem.find('.woongkir-service--single').prop('checked', isChecked).trigger('change'); 224 | 225 | if (isChecked && !accountSelected.multiple_couriers) { 226 | $couriers.find('.woongkir-couriers-item').not($courierItem).each(function () { 227 | $(this).find('.woongkir-service--bulk:checked').prop('checked', false).trigger('change'); 228 | $(this).find('.woongkir-service--single:checked').prop('checked', false).trigger('change'); 229 | }); 230 | } 231 | } 232 | 233 | function woongkirBackendSelectServicesSingle(event) { 234 | var $checkbox = $(event.target); 235 | var $couriers = $checkbox.closest('.woongkir-couriers'); 236 | var $courierItem = $checkbox.closest('.woongkir-couriers-item'); 237 | var $accountType = $('.woongkir-account-type:checked'); 238 | var accounts = $accountType.data('accounts'); 239 | var accountType = $accountType.val(); 240 | var accountSelected = accountType && accounts[accountType]; 241 | 242 | var courierItemsSelected = $courierItem.find('.woongkir-service--single:checked').length; 243 | var courierItemsAvailable = $courierItem.find('.woongkir-service--single').length; 244 | 245 | $courierItem.find('.woongkir-couriers--selected').text(courierItemsSelected); 246 | $courierItem.find('.woongkir-couriers--available').text(courierItemsAvailable); 247 | 248 | var checkCheckboxBulk = courierItemsSelected > 0; 249 | var selectorCheckboxBulk = checkCheckboxBulk ? '.woongkir-service--bulk:not(:checked)' : '.woongkir-service--bulk:checked'; 250 | 251 | $courierItem.find(selectorCheckboxBulk).prop('checked', checkCheckboxBulk); 252 | 253 | if ($checkbox.is(':checked') && !accountSelected.multiple_couriers) { 254 | $couriers.find('.woongkir-couriers-item').not($courierItem).each(function () { 255 | $(this).find('.woongkir-service--single:checked').prop('checked', false).trigger('change'); 256 | }); 257 | } 258 | } 259 | 260 | function woongkirBackendHandleClickTabNav(event) { 261 | event.preventDefault(); 262 | var $link = $(event.target); 263 | var target = $link.attr('href'); 264 | var $target = $(target); 265 | 266 | if (!$target || !$target.length) { 267 | return; 268 | } 269 | 270 | $('.woongkir-tab-nav-item').each(function () { 271 | if ($(this).is($link)) { 272 | $(this).addClass('active'); 273 | } else { 274 | $(this).removeClass('active'); 275 | } 276 | }); 277 | 278 | $('.woongkir-tab-content').each(function () { 279 | if ($(this).is(target)) { 280 | $(this).addClass('active'); 281 | } else { 282 | $(this).removeClass('active'); 283 | } 284 | }); 285 | } 286 | 287 | function woongkirBackendHandleWcBackboneModalLoaded(event, target) { 288 | if (!event || 'wc-modal-shipping-method-settings' !== target || 1 > $('.' + target).find('[name^="woocommerce_woongkir_"]').length) { 289 | return; 290 | } 291 | 292 | $('.' + target).addClass('wc-modal-shipping-method-settings--woongkir'); 293 | 294 | woongkirBackendRenderOriginLocations(); 295 | woongkirBackendInitCouriersSortable(); 296 | woongkirBackendToggleApiKeyVisibility(); 297 | 298 | $(document.body).off('change', '.woongkir-account-type', woongkirBackendHandleChangeAccountType); 299 | $(document.body).on('change', '.woongkir-account-type', woongkirBackendHandleChangeAccountType); 300 | $(document.body).find('.woongkir-account-type').trigger('change'); 301 | 302 | $(document.body).off('change', '#woocommerce_woongkir_volumetric_calculator', woongkirBackendHandleChangeVolumetricCalculator); 303 | $(document.body).on('change', '#woocommerce_woongkir_volumetric_calculator', woongkirBackendHandleChangeVolumetricCalculator); 304 | $(document.body).find('#woocommerce_woongkir_volumetric_calculator').trigger('change'); 305 | 306 | $(document.body).off('click', '.woongkir-couriers-toggle', woongkirBackendToggleCourierServices); 307 | $(document.body).on('click', '.woongkir-couriers-toggle', woongkirBackendToggleCourierServices); 308 | 309 | $(document.body).off('change', '.woongkir-service--bulk', woongkirBackendSelectServicesBulk); 310 | $(document.body).on('change', '.woongkir-service--bulk', woongkirBackendSelectServicesBulk); 311 | 312 | $(document.body).off('change', '.woongkir-service--single', woongkirBackendSelectServicesSingle); 313 | $(document.body).on('change', '.woongkir-service--single', woongkirBackendSelectServicesSingle); 314 | 315 | $(document.body).off('click', '.woongkir-tab-nav-item', woongkirBackendHandleClickTabNav); 316 | $(document.body).on('click', '.woongkir-tab-nav-item', woongkirBackendHandleClickTabNav); 317 | $(document.body).find('.woongkir-tab-nav-item').first().trigger('click'); 318 | } 319 | 320 | $(document.body).on('wc_backbone_modal_loaded', woongkirBackendHandleWcBackboneModalLoaded); 321 | $(document).ready(woongkirBackendOpenSettingsModal); 322 | -------------------------------------------------------------------------------- /includes/classes/class-woongkir.php: -------------------------------------------------------------------------------- 1 | 33 | */ 34 | class Woongkir { 35 | 36 | 37 | /** 38 | * Shipping base country 39 | * 40 | * @var string 41 | */ 42 | private $base_country = 'ID'; 43 | 44 | /** 45 | * Hold an instance of the class 46 | * 47 | * @var Woongkir 48 | */ 49 | private static $instance = null; 50 | 51 | /** 52 | * The object is created from within the class itself 53 | * only if the class has no instance. 54 | * 55 | * @return Woongkir 56 | */ 57 | public static function get_instance() { 58 | if ( null === self::$instance ) { 59 | self::$instance = new Woongkir(); 60 | } 61 | 62 | return self::$instance; 63 | } 64 | 65 | /** 66 | * Constructor 67 | * 68 | * @since 1.0.0 69 | * 70 | * @return void 71 | */ 72 | public function __construct() { 73 | // Hook to load plugin textdomain. 74 | add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) ); 75 | 76 | // Hook to add plugin action links. 77 | add_action( 'plugin_action_links_' . plugin_basename( WOONGKIR_FILE ), array( $this, 'plugin_action_links' ) ); 78 | 79 | // Hook to register the shipping method. 80 | add_filter( 'woocommerce_shipping_methods', array( $this, 'register_shipping_method' ) ); 81 | 82 | // Hook to enqueue scripts & styles assets in backend area. 83 | add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_backend_assets' ), 999 ); 84 | 85 | // Hook to enqueue scripts & styles assets in frontend area. 86 | add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_frontend_assets' ), 999 ); 87 | 88 | // Hook to check if this shipping method is available for current order. 89 | add_filter( 'woocommerce_shipping_' . WOONGKIR_METHOD_ID . '_is_available', array( $this, 'check_is_available' ), 10, 2 ); 90 | 91 | // Hook to modify the default country selections after a country is chosen. 92 | add_filter( 'woocommerce_get_country_locale', array( $this, 'get_country_locale' ) ); 93 | 94 | // Hook to woocommerce_cart_shipping_packages to inject field address_2. 95 | add_filter( 'woocommerce_cart_shipping_packages', array( $this, 'inject_cart_shipping_packages' ), 10 ); 96 | 97 | // Hook to print hidden element for the hidden address 2 field after the shipping calculator form. 98 | add_action( 'woocommerce_after_shipping_calculator', array( $this, 'after_shipping_calculator' ) ); 99 | 100 | // Hook to enable city field in the shipping calculator form. 101 | add_filter( 'woocommerce_shipping_calculator_enable_city', array( $this, 'shipping_calculator_enable_city' ), 10 ); 102 | 103 | // Hook to declare compatibility with the High-Performance Order Storage. 104 | add_action( 105 | 'before_woocommerce_init', 106 | function() { 107 | if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) { 108 | \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', WOONGKIR_FILE, true ); 109 | } 110 | } 111 | ); 112 | 113 | // Hook to declare incompatibility with the Cart and Checkout Blocks. 114 | add_action( 115 | 'before_woocommerce_init', 116 | function() { 117 | if ( class_exists( '\Automattic\WooCommerce\Utilities\FeaturesUtil' ) ) { 118 | \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', WOONGKIR_FILE, false ); 119 | } 120 | } 121 | ); 122 | } 123 | 124 | /** 125 | * Check if this method available 126 | * 127 | * @since 1.0.0 128 | * @param boolean $available Current status is available. 129 | * @param array $package Current order package data. 130 | * @return bool 131 | */ 132 | public function check_is_available( $available, $package ) { 133 | if ( WC()->countries->get_base_country() !== $this->base_country ) { 134 | return false; 135 | } 136 | 137 | if ( empty( $package ) || empty( $package['contents'] ) || empty( $package['destination'] ) ) { 138 | return false; 139 | } 140 | 141 | return $available; 142 | } 143 | 144 | /** 145 | * Load plugin textdomain. 146 | * 147 | * @since 1.0.0 148 | */ 149 | public function load_textdomain() { 150 | load_plugin_textdomain( 'woongkir', false, basename( WOONGKIR_PATH ) . '/languages' ); 151 | } 152 | 153 | /** 154 | * Add plugin action links. 155 | * 156 | * Add a link to the settings page on the plugins.php page. 157 | * 158 | * @since 1.1.3 159 | * 160 | * @param array $links List of existing plugin action links. 161 | * @return array List of modified plugin action links. 162 | */ 163 | public function plugin_action_links( $links ) { 164 | $zone_id = 0; 165 | 166 | if ( ! class_exists( 'WC_Shipping_Zones' ) ) { 167 | return $links; 168 | } 169 | 170 | foreach ( WC_Shipping_Zones::get_zones() as $zone ) { 171 | if ( empty( $zone['shipping_methods'] ) || empty( $zone['zone_id'] ) ) { 172 | continue; 173 | } 174 | 175 | foreach ( $zone['shipping_methods'] as $zone_shipping_method ) { 176 | if ( $zone_shipping_method instanceof Woongkir ) { 177 | $zone_id = $zone['zone_id']; 178 | break; 179 | } 180 | } 181 | 182 | if ( $zone_id ) { 183 | break; 184 | } 185 | } 186 | 187 | $links = array_merge( 188 | array( 189 | '' . __( 'Settings', 'woongkir' ) . '', 200 | ), 201 | $links 202 | ); 203 | 204 | return $links; 205 | } 206 | 207 | /** 208 | * Enqueue backend scripts. 209 | * 210 | * @since 1.0.0 211 | * @param string $hook Passed screen ID in admin area. 212 | */ 213 | public function enqueue_backend_assets( $hook = null ) { 214 | if ( ! is_admin() ) { 215 | return; 216 | } 217 | 218 | $is_dev_env = woongkir_is_dev(); 219 | 220 | if ( 'woocommerce_page_wc-settings' === $hook ) { 221 | // Define the styles URL. 222 | $css_url = WOONGKIR_URL . 'assets/css/woongkir-backend.min.css'; 223 | if ( $is_dev_env ) { 224 | $css_url = add_query_arg( array( 't' => time() ), str_replace( '.min', '', $css_url ) ); 225 | } 226 | 227 | // Enqueue admin styles. 228 | wp_enqueue_style( 229 | 'woongkir-backend', // Give the script a unique ID. 230 | $css_url, // Define the path to the JS file. 231 | array(), // Define dependencies. 232 | woongkir_get_plugin_data( 'Version' ), // Define a version (optional). 233 | false // Specify whether to put in footer (leave this false). 234 | ); 235 | 236 | // Register lockr.js scripts. 237 | $lockr_url = WOONGKIR_URL . 'assets/js/lockr.min.js'; 238 | if ( $is_dev_env ) { 239 | $lockr_url = add_query_arg( array( 't' => time() ), str_replace( '.min', '', $lockr_url ) ); 240 | } 241 | 242 | wp_register_script( 243 | 'lockr.js', // Give the script a unique ID. 244 | $lockr_url, // Define the path to the JS file. 245 | array( 'jquery' ), // Define dependencies. 246 | woongkir_get_plugin_data( 'Version' ), // Define a version (optional). 247 | true // Specify whether to put in footer (leave this true). 248 | ); 249 | 250 | // Define the scripts URL. 251 | $js_url = WOONGKIR_URL . 'assets/js/woongkir-backend.min.js'; 252 | if ( $is_dev_env ) { 253 | $js_url = add_query_arg( array( 't' => time() ), str_replace( '.min', '', $js_url ) ); 254 | } 255 | 256 | wp_enqueue_script( 257 | 'woongkir-backend', // Give the script a unique ID. 258 | $js_url, // Define the path to the JS file. 259 | array( 'jquery', 'accordion', 'wp-util', 'selectWoo', 'lockr.js' ), // Define dependencies. 260 | woongkir_get_plugin_data( 'Version' ), // Define a version (optional). 261 | true // Specify whether to put in footer (leave this true). 262 | ); 263 | 264 | wp_localize_script( 265 | 'woongkir-backend', 266 | 'woongkir_params', 267 | woongkir_scripts_params( 268 | array( 269 | 'method_id' => WOONGKIR_METHOD_ID, 270 | 'method_title' => woongkir_get_plugin_data( 'Name' ), 271 | ) 272 | ) 273 | ); 274 | } 275 | } 276 | 277 | /** 278 | * Enqueue frontend scripts. 279 | * 280 | * @since 1.0.0 281 | */ 282 | public function enqueue_frontend_assets() { 283 | if ( is_admin() || ! woongkir_instances() ) { 284 | return; 285 | } 286 | 287 | $is_enqueue_assets = apply_filters( 'woongkir_enqueue_frontend_assets', ( is_cart() || is_checkout() || is_account_page() ) ); 288 | 289 | if ( ! $is_enqueue_assets ) { 290 | return; 291 | } 292 | 293 | $is_dev_env = woongkir_is_dev(); 294 | 295 | // Register lockr.js scripts. 296 | $lockr_url = WOONGKIR_URL . 'assets/js/lockr.min.js'; 297 | if ( $is_dev_env ) { 298 | $lockr_url = add_query_arg( array( 't' => time() ), str_replace( '.min', '', $lockr_url ) ); 299 | } 300 | 301 | wp_register_script( 302 | 'lockr.js', // Give the script a unique ID. 303 | $lockr_url, // Define the path to the JS file. 304 | array(), // Define dependencies. 305 | woongkir_get_plugin_data( 'Version' ), // Define a version (optional). 306 | true // Specify whether to put in footer (leave this true). 307 | ); 308 | 309 | // Enqueue main scripts. 310 | $js_url = WOONGKIR_URL . 'assets/js/woongkir-frontend.min.js'; 311 | if ( $is_dev_env ) { 312 | $js_url = add_query_arg( array( 't' => time() ), str_replace( '.min', '', $js_url ) ); 313 | } 314 | 315 | wp_enqueue_script( 316 | 'woongkir-frontend', // Give the script a unique ID. 317 | $js_url, // Define the path to the JS file. 318 | array( 'jquery', 'wp-util', 'selectWoo', 'lockr.js' ), // Define dependencies. 319 | woongkir_get_plugin_data( 'Version' ), // Define a version (optional). 320 | true // Specify whether to put in footer (leave this true). 321 | ); 322 | 323 | wp_localize_script( 'woongkir-frontend', 'woongkir_params', woongkir_scripts_params() ); 324 | } 325 | 326 | /** 327 | * Modify the default country selections after a country is chosen. 328 | * 329 | * @since 1.3 330 | * 331 | * @param array $locale Default locale data. 332 | * 333 | * @return array 334 | */ 335 | public function get_country_locale( $locale ) { 336 | if ( ! woongkir_instances() || ! isset( $locale['ID'] ) ) { 337 | return $locale; 338 | } 339 | 340 | $custom_fields = woongkir_custom_address_fields(); 341 | 342 | foreach ( $custom_fields as $key => $value ) { 343 | if ( isset( $locale['ID'][ $key ] ) ) { 344 | $locale['ID'][ $key ] = array_merge( $locale['ID'][ $key ], $value ); 345 | } else { 346 | $locale['ID'][ $key ] = $value; 347 | } 348 | } 349 | 350 | return $locale; 351 | } 352 | 353 | /** 354 | * Inject cart packages to calculate shipping for address 2 field. 355 | * 356 | * @since 1.1.4 357 | * @param array $packages Current cart contents packages. 358 | * @return array 359 | */ 360 | public function inject_cart_shipping_packages( $packages ) { 361 | if ( ! woongkir_instances() ) { 362 | return $packages; 363 | } 364 | 365 | $nonce_action = 'woocommerce-shipping-calculator'; 366 | $nonce_name = 'woocommerce-shipping-calculator-nonce'; 367 | $address_2_field = 'calc_shipping_address_2'; 368 | 369 | if ( isset( $_POST[ $nonce_name ], $_POST[ $address_2_field ] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST[ $nonce_name ] ) ), $nonce_action ) ) { 370 | $address_2 = sanitize_text_field( wp_unslash( $_POST[ $address_2_field ] ) ); 371 | 372 | if ( empty( $address_2 ) ) { 373 | return $packages; 374 | } 375 | 376 | foreach ( array_keys( $packages ) as $key ) { 377 | WC()->customer->set_billing_address_2( $address_2 ); 378 | WC()->customer->set_shipping_address_2( $address_2 ); 379 | $packages[ $key ]['destination']['address_2'] = $address_2; 380 | } 381 | } 382 | 383 | return $packages; 384 | } 385 | 386 | /** 387 | * Hook to enable city field in the shipping calculator form. 388 | * 389 | * @since 1.3.2 390 | * 391 | * @param bool $is_enable Current status is city enabled. 392 | * 393 | * @return bool 394 | */ 395 | public function shipping_calculator_enable_city( $is_enable ) { 396 | if ( ! woongkir_instances() ) { 397 | return $is_enable; 398 | } 399 | 400 | return true; 401 | } 402 | 403 | /** 404 | * Print hidden element for the hidden address 2 field value 405 | * in shipping calculator form. 406 | * 407 | * @since 1.2.4 408 | * @return void 409 | */ 410 | public function after_shipping_calculator() { 411 | if ( ! woongkir_instances() ) { 412 | return; 413 | } 414 | 415 | $enable_address_2 = apply_filters( 'woocommerce_shipping_calculator_enable_address_2', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound 416 | 417 | if ( ! $enable_address_2 ) { 418 | return; 419 | } 420 | 421 | $address_2 = WC()->cart->get_customer()->get_shipping_address_2(); 422 | ?> 423 | 424 | Add New 77 | 1. Choose upload 78 | 1. Upload the plugin zip file, the plugin will now be installed 79 | 1. After the installation has finished, click the ‘activate plugin’ link 80 | 81 | == Frequently Asked Questions == 82 | 83 | = I see the message "There are no shipping methods available" in the cart/checkout page, what should I do? = 84 | 85 | I have no clue what is happening on your server during the WooCommerce doing the shipping calculation, and there are too many possibilities to guess that can cause the shipping method not available. To find out the causes and the solutions, please switch to “ON” for the WooCommerce Shipping Debug Mode setting. Then open your cart/checkout page. You will see a very informative and self-explanatory debug info printed on the cart/checkout page. Please note that this debug info only visible for users that already logged-in/authenticated as an administrator. You must include this debug info in case you are going to create a support ticket related to this issue. 86 | 87 | [Click here](https://fast.wistia.net/embed/iframe/9c9008dxnr) for how to switch WooCommerce Shipping Debug Mode. 88 | 89 | = How to switch WooCommerce Shipping Debug Mode setting? = 90 | 91 | [Click here](https://fast.wistia.net/embed/iframe/9c9008dxnr) for how to switch WooCommerce Shipping Debug Mode setting. 92 | 93 | = I see there is no city or subdistrict dropdown field in the checkout form or shipping calculator form, what should I do? = 94 | 95 | The main cause of this issue is because you are using a theme or plugin that modifying the standard WooCommerce form structure. There is no way to fix this at the moment except you deactivate the theme or plugin that modifying the standard WooCommerce form structure. You may also need to check out the Browser's developer tools console to check if there is a JavaScript error/conflict. You must include this debug info in case you are going to create a support ticket related to this issue. 96 | 97 | = How to set the plugin settings? = 98 | 99 | You can set up the plugin setting from the WooCommerce Shipping Zones settings panel. Please [click here](https://fast.wistia.net/embed/iframe/95yiocro6p) for the video tutorial on how to set up the WooCommerce Shipping Zones. 100 | 101 | = I got an error related with the API Key setting, what should I do? = 102 | 103 | The error printed in there is coming from the RajaOngkir.com API server. Please check your account by login to RajaOngkir.com. 104 | 105 | = Where can I get support or report a bug? = 106 | 107 | You can create a support ticket at plugin support forum: 108 | 109 | * [Plugin Support Forum](https://wordpress.org/plugins/woongkir) 110 | 111 | = Can I contribute to developing this plugin? = 112 | 113 | I always welcome and encourage contributions to this plugin. Please visit the plugin GitHub repository: 114 | 115 | * [Plugin GitHub Repository](https://github.com/sofyansitorus/Woongkir) 116 | 117 | == Screenshots == 118 | 1. Settings panel: General Options 119 | 2. Settings panel: Domestic Shipping Options 120 | 3. Settings panel: International Shipping Options 121 | 4. Shipping Calculator Preview: Domestic Shipping 122 | 5. Shipping Calculator Preview: International Shipping 123 | 124 | == Changelog == 125 | 126 | = 1.3.12 = 127 | 128 | * Fix - Fix incorrect plugin file when declaring incompatibility with the Cart and Checkout Blocks. 129 | 130 | = 1.3.11 = 131 | 132 | * Fix - Declare incompatibility with the Cart and Checkout Blocks. 133 | 134 | = 1.3.10 = 135 | 136 | * Fix - Fixed broken in setting modal in WooCommerce 8.4.0 or later. 137 | 138 | = 1.3.9 = 139 | 140 | * Fix - Fixed compatibility with High-Performance Order Storage. 141 | 142 | = 1.3.8 = 143 | 144 | * Added new courier: IDexpress Service Solution (IDE). 145 | * Added new courier: JTL Express (JTL). 146 | * Added new courier: Sentral Cargo (SENTRAL). 147 | * Updated courier services list: Expedito (EXPEDITO). 148 | * Updated courier services list: Lion Parcel (LION). 149 | * Updated courier services list: Nusantara Card Semesta (NCS). 150 | * Updated courier services list: POS Indonesia (POS). 151 | * Updated courier services list: Royal Express Indonesia (REX). 152 | * Updated courier services list: SAP Express (SAP). 153 | * Updated courier services list: SiCepat Express (SICEPAT). 154 | 155 | = 1.3.7 = 156 | 157 | * Improved API requests by enabling retry on failed requests. 158 | 159 | = 1.3.6 = 160 | 161 | * Fix origin sub-district with the same name but having different city causing incorrect origin info. 162 | 163 | = 1.3.5 = 164 | 165 | * Fixed manual sort couriers list not works in admin settings panel. 166 | 167 | = 1.3.4 = 168 | 169 | * Added new courier: AnterAja. 170 | * Fixed update_checkout event not triggered when shipping destination forced to billing address. 171 | 172 | = 1.3.3 = 173 | 174 | * Enabled JSON local data versioning to prevent outdated local data after update. 175 | * Improved UI/UX admin settings area. 176 | 177 | = 1.3.2 = 178 | 179 | * Fixed PHP fatal error after upgrade. 180 | 181 | = 1.3.1 = 182 | 183 | * Added new filter hook: woongkir_api_key_hardcoded. 184 | * Fixed subdistrict filed attributes not rendered properly 185 | 186 | = 1.3 = 187 | 188 | * Fixed performance issue when many couriers is enabled. 189 | * Fixed unwanted JSON data loaded on first visit. 190 | * Fixed checkout fields label and priority. 191 | * Improved UI/UX admin settings area. 192 | 193 | = 1.2.16 = 194 | 195 | * Fixed incorrect ETA value parsing when started with 1. 196 | 197 | = 1.2.15 = 198 | 199 | * Tweaked calculate shipping form. 200 | * Enabled auto-update couriers list. 201 | * Removed send log functionality. 202 | * Added option to sort shipping results by name and cost in descending order. 203 | * Improved couriers list setting UI/UX. 204 | * Fixed selected services counter not work properly for the Basic account type. 205 | 206 | = 1.2.14 = 207 | 208 | * Added Sort Shipping settings. 209 | * Fixed internationalization text for ETA label. 210 | 211 | = 1.2.13 = 212 | 213 | * Fixed real-time API Key setting validation. 214 | * Added API response error to debug info. 215 | * Updated version compatibility. 216 | 217 | = 1.2.12 = 218 | 219 | * Improved UI/UX in the admin area for mobile devices. 220 | * Refactored codebase to make it modular for easy to extend. 221 | * Introduced new filters: woongkir_api_request_post_pre, woongkir_api_request_get_pre, woongkir_shipping_results, woongkir_shipping_origin_info, woongkir_shipping_destination_info, woongkir_shipping_dimension_weight. 222 | 223 | = 1.2.11 = 224 | 225 | * Fixed bug to calculate volumetrically. 226 | * Added new couriers: 21 Express, Nusantara Card Semesta, Lion Parcel, Ninja Xpress, Indotama Domestik Lestari, Royal Express Indonesia, Indah Logistic. 227 | * Updated existing couriers. 228 | 229 | = 1.2.10 = 230 | 231 | * Fixed fail to parse the API response in some cases. 232 | 233 | = 1.2.9 = 234 | 235 | * Improvement - Enabled Volumetric Converter 236 | * Improvement - Added new hooks: woocommerce_woongkir_shipping_origin_info, woocommerce_woongkir_shipping_destination_info 237 | * Fix - Fixed bug when calculating cost 1 courier only in starter account 238 | 239 | = 1.2.7 = 240 | 241 | * Fix - Fixed duplicate postcode field in checkout form when using custom form structure 242 | * Fix - Fixed timeout issue when many couriers selected 243 | * Fix - Removed Cahaya Logistic Domestic Courier (Not supported by RajaOngkir anymore) 244 | * Fix - Removed TIKI International Courier (Not supported by RajaOngkir temporarily) 245 | * Improvement - Enabled to sort couriers list 246 | * Improvement - Enabled logger for API response error 247 | 248 | = 1.2.6 = 249 | 250 | * Fix - Fixed corrupted file during the build process 251 | 252 | = 1.2.5 = 253 | 254 | * Fix - Fixed checkout form not updated on fields change 255 | * Improvements - Improved backend form 256 | 257 | = 1.2.4 = 258 | 259 | * Fix - Fixed City and subdistrict dropdown field now appear in my account address fields 260 | * Fix - Fixed Fixed Subdistrict selected value always empty in the shipping calculator form 261 | * Improvements - Improved backend form 262 | 263 | = 1.2.3 = 264 | 265 | * Bug Fix - Compatibility issue with WooCommerce 3.5 266 | 267 | = 1.2.2 = 268 | 269 | * Bug Fix - Empty JS File. 270 | 271 | = 1.2.1 = 272 | 273 | * Improvements - Added 5 new domestic couriers: Solusi Ekspres, Wahana Prestasi Logistik, Cahaya Ekspress Logistik, Pahala Kencana Express, SAP Express Courier 274 | 275 | = 1.2 = 276 | 277 | * Feature - Enabled subdistrict field in shipping rate calculator form. 278 | * Fix - Plugin is not detected in WordPress multisite. 279 | 280 | = 1.1.4 = 281 | 282 | * Improvements - Add a new setting field for base weight. 283 | * Improvements - Add a logo for couriers in setting panel. 284 | * Fix - Bug in getting destination info. 285 | * Fix - Bug in getting weight info. 286 | 287 | = 1.1.3 = 288 | 289 | * Improvements - Add the "Settings" link on the plugins.php page. 290 | 291 | = 1.1.2 = 292 | 293 | * Fix - The couriers are not displayed if the product weight and dimensions are empty. 294 | * Improvements - Store local storage data at first load only. 295 | 296 | = 1.1.1 = 297 | 298 | * Fix - Prevent request to API server if the destination address is not complete. 299 | * Improvements - Set timeout parameter for remote request: 10 seconds. 300 | 301 | = 1.1.0 = 302 | 303 | * Feature - Add new domestic shipping couriers: STAR, SICEPAT, JET, PANDU, J&T. 304 | * Feature - Add new international shipping couriers: TIKI, SLIS, EXPEDITO. 305 | * Improvements - Tweak settings panel. 306 | * Improvements - Tweak estimated time of arrival label. 307 | 308 | = 1.0.0 = 309 | 310 | * Feature - Support multiple couriers for domestic shipping: JNE, TIKI, POS, PCP, RPX. 311 | * Feature - Support multiple couriers for international shipping: JNE, POS. 312 | * Feature - Support shipping rates calculation from and to subdistrict location for domestic shipping. 313 | * Feature - Support shipping rates calculation based on dimensions and weight. 314 | * Feature - Enable or disable any of the shipping services provided by each courier. 315 | * Feature - Show or hide the estimated time of arrival. 316 | * Feature - Real-time currency conversion to IDR for international shipping cost courier that uses USD. 317 | * Feature - Real-time API Key validation on settings update. 318 | 319 | == Upgrade Notice == 320 | 321 | = 1.2.16 = 322 | This version includes bug fixes. Upgrade immediately is always recommended. 323 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "344140836b66b510bf57f0521fdb4646", 8 | "packages": [], 9 | "packages-dev": [ 10 | { 11 | "name": "dealerdirect/phpcodesniffer-composer-installer", 12 | "version": "v0.7.1", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", 16 | "reference": "fe390591e0241955f22eb9ba327d137e501c771c" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/fe390591e0241955f22eb9ba327d137e501c771c", 21 | "reference": "fe390591e0241955f22eb9ba327d137e501c771c", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "composer-plugin-api": "^1.0 || ^2.0", 26 | "php": ">=5.3", 27 | "squizlabs/php_codesniffer": "^2.0 || ^3.0 || ^4.0" 28 | }, 29 | "require-dev": { 30 | "composer/composer": "*", 31 | "phpcompatibility/php-compatibility": "^9.0", 32 | "sensiolabs/security-checker": "^4.1.0" 33 | }, 34 | "type": "composer-plugin", 35 | "extra": { 36 | "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" 37 | }, 38 | "autoload": { 39 | "psr-4": { 40 | "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" 41 | } 42 | }, 43 | "notification-url": "https://packagist.org/downloads/", 44 | "license": [ 45 | "MIT" 46 | ], 47 | "authors": [ 48 | { 49 | "name": "Franck Nijhof", 50 | "email": "franck.nijhof@dealerdirect.com", 51 | "homepage": "http://www.frenck.nl", 52 | "role": "Developer / IT Manager" 53 | } 54 | ], 55 | "description": "PHP_CodeSniffer Standards Composer Installer Plugin", 56 | "homepage": "http://www.dealerdirect.com", 57 | "keywords": [ 58 | "PHPCodeSniffer", 59 | "PHP_CodeSniffer", 60 | "code quality", 61 | "codesniffer", 62 | "composer", 63 | "installer", 64 | "phpcs", 65 | "plugin", 66 | "qa", 67 | "quality", 68 | "standard", 69 | "standards", 70 | "style guide", 71 | "stylecheck", 72 | "tests" 73 | ], 74 | "support": { 75 | "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", 76 | "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" 77 | }, 78 | "time": "2020-12-07T18:04:37+00:00" 79 | }, 80 | { 81 | "name": "phpcompatibility/php-compatibility", 82 | "version": "9.3.5", 83 | "source": { 84 | "type": "git", 85 | "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", 86 | "reference": "9fb324479acf6f39452e0655d2429cc0d3914243" 87 | }, 88 | "dist": { 89 | "type": "zip", 90 | "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243", 91 | "reference": "9fb324479acf6f39452e0655d2429cc0d3914243", 92 | "shasum": "" 93 | }, 94 | "require": { 95 | "php": ">=5.3", 96 | "squizlabs/php_codesniffer": "^2.3 || ^3.0.2" 97 | }, 98 | "conflict": { 99 | "squizlabs/php_codesniffer": "2.6.2" 100 | }, 101 | "require-dev": { 102 | "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0" 103 | }, 104 | "suggest": { 105 | "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", 106 | "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." 107 | }, 108 | "type": "phpcodesniffer-standard", 109 | "notification-url": "https://packagist.org/downloads/", 110 | "license": [ 111 | "LGPL-3.0-or-later" 112 | ], 113 | "authors": [ 114 | { 115 | "name": "Wim Godden", 116 | "homepage": "https://github.com/wimg", 117 | "role": "lead" 118 | }, 119 | { 120 | "name": "Juliette Reinders Folmer", 121 | "homepage": "https://github.com/jrfnl", 122 | "role": "lead" 123 | }, 124 | { 125 | "name": "Contributors", 126 | "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" 127 | } 128 | ], 129 | "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.", 130 | "homepage": "http://techblog.wimgodden.be/tag/codesniffer/", 131 | "keywords": [ 132 | "compatibility", 133 | "phpcs", 134 | "standards" 135 | ], 136 | "support": { 137 | "issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues", 138 | "source": "https://github.com/PHPCompatibility/PHPCompatibility" 139 | }, 140 | "time": "2019-12-27T09:44:58+00:00" 141 | }, 142 | { 143 | "name": "phpcompatibility/phpcompatibility-paragonie", 144 | "version": "1.3.1", 145 | "source": { 146 | "type": "git", 147 | "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git", 148 | "reference": "ddabec839cc003651f2ce695c938686d1086cf43" 149 | }, 150 | "dist": { 151 | "type": "zip", 152 | "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/ddabec839cc003651f2ce695c938686d1086cf43", 153 | "reference": "ddabec839cc003651f2ce695c938686d1086cf43", 154 | "shasum": "" 155 | }, 156 | "require": { 157 | "phpcompatibility/php-compatibility": "^9.0" 158 | }, 159 | "require-dev": { 160 | "dealerdirect/phpcodesniffer-composer-installer": "^0.7", 161 | "paragonie/random_compat": "dev-master", 162 | "paragonie/sodium_compat": "dev-master" 163 | }, 164 | "suggest": { 165 | "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", 166 | "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." 167 | }, 168 | "type": "phpcodesniffer-standard", 169 | "notification-url": "https://packagist.org/downloads/", 170 | "license": [ 171 | "LGPL-3.0-or-later" 172 | ], 173 | "authors": [ 174 | { 175 | "name": "Wim Godden", 176 | "role": "lead" 177 | }, 178 | { 179 | "name": "Juliette Reinders Folmer", 180 | "role": "lead" 181 | } 182 | ], 183 | "description": "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.", 184 | "homepage": "http://phpcompatibility.com/", 185 | "keywords": [ 186 | "compatibility", 187 | "paragonie", 188 | "phpcs", 189 | "polyfill", 190 | "standards" 191 | ], 192 | "support": { 193 | "issues": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/issues", 194 | "source": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie" 195 | }, 196 | "time": "2021-02-15T10:24:51+00:00" 197 | }, 198 | { 199 | "name": "phpcompatibility/phpcompatibility-wp", 200 | "version": "2.1.1", 201 | "source": { 202 | "type": "git", 203 | "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", 204 | "reference": "b7dc0cd7a8f767ccac5e7637550ea1c50a67b09e" 205 | }, 206 | "dist": { 207 | "type": "zip", 208 | "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/b7dc0cd7a8f767ccac5e7637550ea1c50a67b09e", 209 | "reference": "b7dc0cd7a8f767ccac5e7637550ea1c50a67b09e", 210 | "shasum": "" 211 | }, 212 | "require": { 213 | "phpcompatibility/php-compatibility": "^9.0", 214 | "phpcompatibility/phpcompatibility-paragonie": "^1.0" 215 | }, 216 | "require-dev": { 217 | "dealerdirect/phpcodesniffer-composer-installer": "^0.7" 218 | }, 219 | "suggest": { 220 | "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", 221 | "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." 222 | }, 223 | "type": "phpcodesniffer-standard", 224 | "notification-url": "https://packagist.org/downloads/", 225 | "license": [ 226 | "LGPL-3.0-or-later" 227 | ], 228 | "authors": [ 229 | { 230 | "name": "Wim Godden", 231 | "role": "lead" 232 | }, 233 | { 234 | "name": "Juliette Reinders Folmer", 235 | "role": "lead" 236 | } 237 | ], 238 | "description": "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.", 239 | "homepage": "http://phpcompatibility.com/", 240 | "keywords": [ 241 | "compatibility", 242 | "phpcs", 243 | "standards", 244 | "wordpress" 245 | ], 246 | "support": { 247 | "issues": "https://github.com/PHPCompatibility/PHPCompatibilityWP/issues", 248 | "source": "https://github.com/PHPCompatibility/PHPCompatibilityWP" 249 | }, 250 | "time": "2021-02-15T12:58:46+00:00" 251 | }, 252 | { 253 | "name": "sirbrillig/phpcs-variable-analysis", 254 | "version": "v2.10.2", 255 | "source": { 256 | "type": "git", 257 | "url": "https://github.com/sirbrillig/phpcs-variable-analysis.git", 258 | "reference": "0775e0c683badad52c03b11c2cd86a9fdecb937a" 259 | }, 260 | "dist": { 261 | "type": "zip", 262 | "url": "https://api.github.com/repos/sirbrillig/phpcs-variable-analysis/zipball/0775e0c683badad52c03b11c2cd86a9fdecb937a", 263 | "reference": "0775e0c683badad52c03b11c2cd86a9fdecb937a", 264 | "shasum": "" 265 | }, 266 | "require": { 267 | "php": ">=5.4.0", 268 | "squizlabs/php_codesniffer": "^3.5" 269 | }, 270 | "require-dev": { 271 | "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", 272 | "limedeck/phpunit-detailed-printer": "^3.1 || ^4.0 || ^5.0", 273 | "phpstan/phpstan": "^0.11.8", 274 | "phpunit/phpunit": "^5.0 || ^6.5 || ^7.0 || ^8.0", 275 | "sirbrillig/phpcs-import-detection": "^1.1" 276 | }, 277 | "type": "phpcodesniffer-standard", 278 | "autoload": { 279 | "psr-4": { 280 | "VariableAnalysis\\": "VariableAnalysis/" 281 | } 282 | }, 283 | "notification-url": "https://packagist.org/downloads/", 284 | "license": [ 285 | "BSD-2-Clause" 286 | ], 287 | "authors": [ 288 | { 289 | "name": "Sam Graham", 290 | "email": "php-codesniffer-variableanalysis@illusori.co.uk" 291 | }, 292 | { 293 | "name": "Payton Swick", 294 | "email": "payton@foolord.com" 295 | } 296 | ], 297 | "description": "A PHPCS sniff to detect problems with variables.", 298 | "support": { 299 | "issues": "https://github.com/sirbrillig/phpcs-variable-analysis/issues", 300 | "source": "https://github.com/sirbrillig/phpcs-variable-analysis", 301 | "wiki": "https://github.com/sirbrillig/phpcs-variable-analysis/wiki" 302 | }, 303 | "time": "2021-01-08T16:31:05+00:00" 304 | }, 305 | { 306 | "name": "squizlabs/php_codesniffer", 307 | "version": "3.5.8", 308 | "source": { 309 | "type": "git", 310 | "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", 311 | "reference": "9d583721a7157ee997f235f327de038e7ea6dac4" 312 | }, 313 | "dist": { 314 | "type": "zip", 315 | "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/9d583721a7157ee997f235f327de038e7ea6dac4", 316 | "reference": "9d583721a7157ee997f235f327de038e7ea6dac4", 317 | "shasum": "" 318 | }, 319 | "require": { 320 | "ext-simplexml": "*", 321 | "ext-tokenizer": "*", 322 | "ext-xmlwriter": "*", 323 | "php": ">=5.4.0" 324 | }, 325 | "require-dev": { 326 | "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" 327 | }, 328 | "bin": [ 329 | "bin/phpcs", 330 | "bin/phpcbf" 331 | ], 332 | "type": "library", 333 | "extra": { 334 | "branch-alias": { 335 | "dev-master": "3.x-dev" 336 | } 337 | }, 338 | "notification-url": "https://packagist.org/downloads/", 339 | "license": [ 340 | "BSD-3-Clause" 341 | ], 342 | "authors": [ 343 | { 344 | "name": "Greg Sherwood", 345 | "role": "lead" 346 | } 347 | ], 348 | "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", 349 | "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", 350 | "keywords": [ 351 | "phpcs", 352 | "standards" 353 | ], 354 | "support": { 355 | "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", 356 | "source": "https://github.com/squizlabs/PHP_CodeSniffer", 357 | "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" 358 | }, 359 | "time": "2020-10-23T02:01:07+00:00" 360 | }, 361 | { 362 | "name": "wp-coding-standards/wpcs", 363 | "version": "2.3.0", 364 | "source": { 365 | "type": "git", 366 | "url": "https://github.com/WordPress/WordPress-Coding-Standards.git", 367 | "reference": "7da1894633f168fe244afc6de00d141f27517b62" 368 | }, 369 | "dist": { 370 | "type": "zip", 371 | "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/7da1894633f168fe244afc6de00d141f27517b62", 372 | "reference": "7da1894633f168fe244afc6de00d141f27517b62", 373 | "shasum": "" 374 | }, 375 | "require": { 376 | "php": ">=5.4", 377 | "squizlabs/php_codesniffer": "^3.3.1" 378 | }, 379 | "require-dev": { 380 | "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || ^0.6", 381 | "phpcompatibility/php-compatibility": "^9.0", 382 | "phpcsstandards/phpcsdevtools": "^1.0", 383 | "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" 384 | }, 385 | "suggest": { 386 | "dealerdirect/phpcodesniffer-composer-installer": "^0.6 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically." 387 | }, 388 | "type": "phpcodesniffer-standard", 389 | "notification-url": "https://packagist.org/downloads/", 390 | "license": [ 391 | "MIT" 392 | ], 393 | "authors": [ 394 | { 395 | "name": "Contributors", 396 | "homepage": "https://github.com/WordPress/WordPress-Coding-Standards/graphs/contributors" 397 | } 398 | ], 399 | "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions", 400 | "keywords": [ 401 | "phpcs", 402 | "standards", 403 | "wordpress" 404 | ], 405 | "support": { 406 | "issues": "https://github.com/WordPress/WordPress-Coding-Standards/issues", 407 | "source": "https://github.com/WordPress/WordPress-Coding-Standards", 408 | "wiki": "https://github.com/WordPress/WordPress-Coding-Standards/wiki" 409 | }, 410 | "time": "2020-05-13T23:57:56+00:00" 411 | } 412 | ], 413 | "aliases": [], 414 | "minimum-stability": "stable", 415 | "stability-flags": [], 416 | "prefer-stable": false, 417 | "prefer-lowest": false, 418 | "platform": [], 419 | "platform-dev": [], 420 | "platform-overrides": { 421 | "php": "5.6" 422 | }, 423 | "plugin-api-version": "2.0.0" 424 | } 425 | --------------------------------------------------------------------------------