## Point 1: Addon Bridge Pattern ✅ Created ADDON_BRIDGE_PATTERN.md documenting: - WooNooW Core = Zero addon dependencies - Bridge snippet pattern for Rajaongkir compatibility - Proper addon development approach - Hook system usage **Key Decision:** - ❌ No Rajaongkir integration in core - ✅ Provide bridge snippets for compatibility - ✅ Encourage proper WooNooW addons - ✅ Keep core clean and maintainable --- ## Point 2: Calculation Efficiency Audit 🚨 CRITICAL Created CALCULATION_EFFICIENCY_AUDIT.md revealing: **BLOATED Implementation Found:** - 2 separate API calls (/shipping/calculate + /orders/preview) - Cart initialized TWICE - Shipping calculated TWICE - Taxes calculated TWICE - ~1000ms total time **Recommended Solution:** - Single /orders/calculate endpoint - ONE cart initialization - ONE calculation - ~300ms total time (70% faster!) - 50% fewer requests - 50% less server load **This is exactly what we discussed at the beginning:** > "WooCommerce is bloated because of separate requests. We need efficient flow that handles everything at once." **Current implementation repeats WooCommerce's mistake!** **Status:** ❌ NOT IMPLEMENTED YET **Priority:** 🚨 CRITICAL **Impact:** 🔥 HIGH - Performance bottleneck --- ## Point 3: Settings Placement Strategy ✅ Created SETTINGS_PLACEMENT_STRATEGY.md proposing: **No separate "WooNooW Settings" page.** Instead: - Store Logo → WooCommerce > Settings > General - Order Format → WooCommerce > Settings > Orders - Product Settings → WooCommerce > Settings > Products - UI Settings → WooCommerce > Settings > Admin UI (new tab) **Benefits:** - Contextual placement - Familiar to users - No clutter - Seamless integration - Feels native to WooCommerce **Philosophy:** WooNooW should feel like a native part of WooCommerce, not a separate plugin. --- ## Summary **Point 1:** ✅ Documented addon bridge pattern **Point 2:** 🚨 CRITICAL - Current calculation is bloated, needs refactoring **Point 3:** ✅ Settings placement strategy documented **Next Action Required:** Implement unified /orders/calculate endpoint to fix performance bottleneck.
326 lines
8.4 KiB
Markdown
326 lines
8.4 KiB
Markdown
# Addon Bridge Pattern - Rajaongkir Example
|
|
|
|
## Philosophy
|
|
|
|
**WooNooW Core = Zero Addon Dependencies**
|
|
|
|
We don't integrate specific addons into WooNooW core. Instead, we provide:
|
|
1. **Hook system** for addons to extend functionality
|
|
2. **Bridge snippets** for compatibility with existing plugins
|
|
3. **Addon development guide** for building proper WooNooW addons
|
|
|
|
---
|
|
|
|
## Problem: Rajaongkir Plugin
|
|
|
|
Rajaongkir is a WooCommerce plugin that:
|
|
- Removes standard address fields (city, state)
|
|
- Adds custom destination dropdown
|
|
- Stores data in WooCommerce session
|
|
- Works on WooCommerce checkout page
|
|
|
|
**It doesn't work with WooNooW OrderForm because:**
|
|
- OrderForm uses standard WooCommerce fields
|
|
- Rajaongkir expects session-based destination
|
|
- No destination = No shipping calculation
|
|
|
|
---
|
|
|
|
## Solution: Bridge Snippet (Not Core Integration!)
|
|
|
|
### Option A: Standalone Bridge Plugin
|
|
|
|
Create a tiny bridge plugin that makes Rajaongkir work with WooNooW:
|
|
|
|
```php
|
|
<?php
|
|
/**
|
|
* Plugin Name: WooNooW Rajaongkir Bridge
|
|
* Description: Makes Rajaongkir plugin work with WooNooW OrderForm
|
|
* Version: 1.0.0
|
|
* Requires: WooNooW, Rajaongkir Official
|
|
*/
|
|
|
|
// Hook into WooNooW's shipping calculation
|
|
add_filter('woonoow_before_shipping_calculate', function($shipping_data) {
|
|
// If Indonesia and has city, convert to Rajaongkir destination
|
|
if ($shipping_data['country'] === 'ID' && !empty($shipping_data['city'])) {
|
|
// Search Rajaongkir API for destination
|
|
$api = Cekongkir_API::get_instance();
|
|
$results = $api->search_destination_api($shipping_data['city']);
|
|
|
|
if (!empty($results[0])) {
|
|
// Set Rajaongkir session data
|
|
WC()->session->set('selected_destination_id', $results[0]['id']);
|
|
WC()->session->set('selected_destination_label', $results[0]['text']);
|
|
}
|
|
}
|
|
|
|
return $shipping_data;
|
|
});
|
|
|
|
// Add Rajaongkir destination field to OrderForm via hook system
|
|
add_action('wp_enqueue_scripts', function() {
|
|
if (!is_admin()) return;
|
|
|
|
wp_enqueue_script(
|
|
'woonoow-rajaongkir-bridge',
|
|
plugin_dir_url(__FILE__) . 'dist/bridge.js',
|
|
['woonoow-admin'],
|
|
'1.0.0',
|
|
true
|
|
);
|
|
});
|
|
```
|
|
|
|
**Frontend (bridge.js):**
|
|
|
|
```typescript
|
|
import { addonLoader, addFilter } from '@woonoow/hooks';
|
|
|
|
addonLoader.register({
|
|
id: 'rajaongkir-bridge',
|
|
name: 'Rajaongkir Bridge',
|
|
version: '1.0.0',
|
|
init: () => {
|
|
// Add destination search field after shipping address
|
|
addFilter('woonoow_order_form_after_shipping', (content, formData, setFormData) => {
|
|
// Only for Indonesia
|
|
if (formData.shipping?.country !== 'ID') return content;
|
|
|
|
return (
|
|
<>
|
|
{content}
|
|
<div className="border rounded-lg p-4 mt-4">
|
|
<h3 className="font-medium mb-3">📍 Shipping Destination</h3>
|
|
<RajaongkirDestinationSearch
|
|
value={formData.shipping?.destination_id}
|
|
onChange={(id, label) => {
|
|
setFormData({
|
|
...formData,
|
|
shipping: {
|
|
...formData.shipping,
|
|
destination_id: id,
|
|
destination_label: label,
|
|
}
|
|
});
|
|
}}
|
|
/>
|
|
</div>
|
|
</>
|
|
);
|
|
});
|
|
}
|
|
});
|
|
```
|
|
|
|
### Option B: Code Snippet (No Plugin)
|
|
|
|
For users who don't want a separate plugin, provide a code snippet:
|
|
|
|
```php
|
|
// Add to theme's functions.php or custom plugin
|
|
|
|
// Bridge Rajaongkir with WooNooW
|
|
add_filter('woonoow_shipping_data', function($data) {
|
|
if ($data['country'] === 'ID' && !empty($data['city'])) {
|
|
// Auto-search and set destination
|
|
$api = Cekongkir_API::get_instance();
|
|
$results = $api->search_destination_api($data['city']);
|
|
if (!empty($results[0])) {
|
|
WC()->session->set('selected_destination_id', $results[0]['id']);
|
|
}
|
|
}
|
|
return $data;
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
## Proper Solution: Build WooNooW Addon
|
|
|
|
Instead of bridging Rajaongkir, build a proper WooNooW addon:
|
|
|
|
**WooNooW Indonesia Shipping Addon**
|
|
|
|
```php
|
|
<?php
|
|
/**
|
|
* Plugin Name: WooNooW Indonesia Shipping
|
|
* Description: Indonesia shipping with Rajaongkir API
|
|
* Version: 1.0.0
|
|
* Requires: WooNooW 1.0.0+
|
|
*/
|
|
|
|
// Register addon
|
|
add_filter('woonoow/addon_registry', function($addons) {
|
|
$addons['indonesia-shipping'] = [
|
|
'id' => 'indonesia-shipping',
|
|
'name' => 'Indonesia Shipping',
|
|
'version' => '1.0.0',
|
|
'spa_bundle' => plugin_dir_url(__FILE__) . 'dist/addon.js',
|
|
'dependencies' => ['woocommerce' => '8.0'],
|
|
];
|
|
return $addons;
|
|
});
|
|
|
|
// Add API endpoints
|
|
add_action('rest_api_init', function() {
|
|
register_rest_route('woonoow/v1', '/indonesia/search-destination', [
|
|
'methods' => 'GET',
|
|
'callback' => function($req) {
|
|
$query = $req->get_param('query');
|
|
$api = new RajaongkirAPI(get_option('rajaongkir_api_key'));
|
|
return $api->searchDestination($query);
|
|
},
|
|
]);
|
|
|
|
register_rest_route('woonoow/v1', '/indonesia/calculate-shipping', [
|
|
'methods' => 'POST',
|
|
'callback' => function($req) {
|
|
$origin = $req->get_param('origin');
|
|
$destination = $req->get_param('destination');
|
|
$weight = $req->get_param('weight');
|
|
|
|
$api = new RajaongkirAPI(get_option('rajaongkir_api_key'));
|
|
return $api->calculateShipping($origin, $destination, $weight);
|
|
},
|
|
]);
|
|
});
|
|
```
|
|
|
|
**Frontend:**
|
|
|
|
```typescript
|
|
// dist/addon.ts
|
|
|
|
import { addonLoader, addFilter } from '@woonoow/hooks';
|
|
import { DestinationSearch } from './components/DestinationSearch';
|
|
|
|
addonLoader.register({
|
|
id: 'indonesia-shipping',
|
|
name: 'Indonesia Shipping',
|
|
version: '1.0.0',
|
|
init: () => {
|
|
// Add destination field
|
|
addFilter('woonoow_order_form_after_shipping', (content, formData, setFormData) => {
|
|
if (formData.shipping?.country !== 'ID') return content;
|
|
|
|
return (
|
|
<>
|
|
{content}
|
|
<DestinationSearch
|
|
value={formData.shipping?.destination_id}
|
|
onChange={(id, label) => {
|
|
setFormData({
|
|
...formData,
|
|
shipping: { ...formData.shipping, destination_id: id, destination_label: label }
|
|
});
|
|
}}
|
|
/>
|
|
</>
|
|
);
|
|
});
|
|
|
|
// Add validation
|
|
addFilter('woonoow_order_form_validation', (errors, formData) => {
|
|
if (formData.shipping?.country === 'ID' && !formData.shipping?.destination_id) {
|
|
errors.destination = 'Please select shipping destination';
|
|
}
|
|
return errors;
|
|
});
|
|
}
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
## Comparison
|
|
|
|
### Bridge Snippet (Quick Fix)
|
|
✅ Works immediately
|
|
✅ No new plugin needed
|
|
✅ Minimal code
|
|
❌ Depends on Rajaongkir plugin
|
|
❌ Limited features
|
|
❌ Not ideal UX
|
|
|
|
### Proper WooNooW Addon (Best Practice)
|
|
✅ Native WooNooW integration
|
|
✅ Better UX
|
|
✅ More features
|
|
✅ Independent of Rajaongkir plugin
|
|
✅ Can use any shipping API
|
|
❌ More development effort
|
|
❌ Separate plugin to maintain
|
|
|
|
---
|
|
|
|
## Recommendation
|
|
|
|
**For WooNooW Core:**
|
|
- ❌ Don't integrate Rajaongkir
|
|
- ✅ Provide hook system
|
|
- ✅ Document bridge pattern
|
|
- ✅ Provide code snippets
|
|
|
|
**For Users:**
|
|
- **Quick fix:** Use bridge snippet
|
|
- **Best practice:** Build proper addon or use community addon
|
|
|
|
**For Community:**
|
|
- Build "WooNooW Indonesia Shipping" addon
|
|
- Publish on WordPress.org
|
|
- Support Rajaongkir, Biteship, and other Indonesian shipping APIs
|
|
|
|
---
|
|
|
|
## Hook Points Needed in WooNooW Core
|
|
|
|
To support addons like this, WooNooW core should provide:
|
|
|
|
```php
|
|
// Before shipping calculation
|
|
apply_filters('woonoow_before_shipping_calculate', $shipping_data);
|
|
|
|
// After shipping calculation
|
|
apply_filters('woonoow_after_shipping_calculate', $rates, $shipping_data);
|
|
|
|
// Modify shipping data
|
|
apply_filters('woonoow_shipping_data', $data);
|
|
```
|
|
|
|
```typescript
|
|
// Frontend hooks
|
|
'woonoow_order_form_after_shipping'
|
|
'woonoow_order_form_shipping_fields'
|
|
'woonoow_order_form_validation'
|
|
'woonoow_order_form_submit'
|
|
```
|
|
|
|
**These hooks already exist in our addon system!**
|
|
|
|
---
|
|
|
|
## Conclusion
|
|
|
|
**WooNooW Core = Zero addon dependencies**
|
|
|
|
Instead of integrating Rajaongkir into core:
|
|
1. Provide hook system ✅ (Already done)
|
|
2. Document bridge pattern ✅ (This document)
|
|
3. Encourage community addons ✅
|
|
|
|
This keeps WooNooW core:
|
|
- Clean
|
|
- Maintainable
|
|
- Flexible
|
|
- Extensible
|
|
|
|
Users can choose:
|
|
- Bridge snippet (quick fix)
|
|
- Proper addon (best practice)
|
|
- Build their own
|
|
|
|
**No bloat in core!**
|