Files
WooNooW/HOOKS_REGISTRY.md
dwindown 232059e928 feat: Complete Dashboard API Integration with Analytics Controller
 Features:
- Implemented API integration for all 7 dashboard pages
- Added Analytics REST API controller with 7 endpoints
- Full loading and error states with retry functionality
- Seamless dummy data toggle for development

📊 Dashboard Pages:
- Customers Analytics (complete)
- Revenue Analytics (complete)
- Orders Analytics (complete)
- Products Analytics (complete)
- Coupons Analytics (complete)
- Taxes Analytics (complete)
- Dashboard Overview (complete)

🔌 Backend:
- Created AnalyticsController.php with REST endpoints
- All endpoints return 501 (Not Implemented) for now
- Ready for HPOS-based implementation
- Proper permission checks

🎨 Frontend:
- useAnalytics hook for data fetching
- React Query caching
- ErrorCard with retry functionality
- TypeScript type safety
- Zero build errors

📝 Documentation:
- DASHBOARD_API_IMPLEMENTATION.md guide
- Backend implementation roadmap
- Testing strategy

🔧 Build:
- All pages compile successfully
- Production-ready with dummy data fallback
- Zero TypeScript errors
2025-11-04 11:19:00 +07:00

722 lines
18 KiB
Markdown

# WooNooW Hooks & Filters Registry
**Version:** 1.0.0
**Last Updated:** 2025-10-28
**Status:** Production Ready
---
## 📋 Table of Contents
1. [Hook Naming Convention](#hook-naming-convention)
2. [Addon System Hooks](#addon-system-hooks)
3. [Navigation Hooks](#navigation-hooks)
4. [Route Hooks](#route-hooks)
5. [Content Injection Hooks](#content-injection-hooks)
6. [Asset Hooks](#asset-hooks)
7. [Future Hooks](#future-hooks)
8. [Hook Tree Structure](#hook-tree-structure)
---
## Hook Naming Convention
All WooNooW hooks follow this structure:
```
woonoow/{category}/{action}[/{subcategory}]
```
**Rules:**
1. Always prefix with `woonoow/`
2. Use lowercase with underscores
3. Use singular nouns for registries (`addon_registry`, not `addons_registry`)
4. Use hierarchical structure for nested items (`nav_tree/products/children`)
5. Use descriptive names that indicate purpose
---
## Addon System Hooks
### `woonoow/addon_registry`
**Type:** Filter
**Priority:** 20 (runs on `plugins_loaded`)
**File:** `includes/Compat/AddonRegistry.php`
**Purpose:** Register addon metadata with WooNooW
**Parameters:**
- `$addons` (array) - Array of addon configurations
**Returns:** array
**Example:**
```php
add_filter('woonoow/addon_registry', function($addons) {
$addons['my-addon'] = [
'id' => 'my-addon',
'name' => 'My Addon',
'version' => '1.0.0',
'author' => 'Author Name',
'description' => 'Addon description',
'spa_bundle' => plugin_dir_url(__FILE__) . 'dist/addon.js',
'dependencies' => ['woocommerce' => '8.0'],
];
return $addons;
});
```
**Schema:**
```typescript
{
id: string; // Required: Unique identifier
name: string; // Required: Display name
version: string; // Required: Semantic version
author?: string; // Optional: Author name
description?: string; // Optional: Short description
spa_bundle?: string; // Optional: Main JS bundle URL
dependencies?: { // Optional: Plugin dependencies
[plugin: string]: string; // plugin => min version
};
}
```
---
## Navigation Hooks
### `woonoow/nav_tree`
**Type:** Filter
**Priority:** 30 (runs on `plugins_loaded`)
**File:** `includes/Compat/NavigationRegistry.php`
**Purpose:** Modify the entire navigation tree
**Parameters:**
- `$tree` (array) - Array of main navigation nodes
**Returns:** array
**Example:**
```php
add_filter('woonoow/nav_tree', function($tree) {
$tree[] = [
'key' => 'subscriptions',
'label' => __('Subscriptions', 'my-addon'),
'path' => '/subscriptions',
'icon' => 'repeat', // lucide icon name
'children' => [
[
'label' => __('All Subscriptions', 'my-addon'),
'mode' => 'spa',
'path' => '/subscriptions',
],
[
'label' => __('New', 'my-addon'),
'mode' => 'spa',
'path' => '/subscriptions/new',
],
],
];
return $tree;
});
```
**Schema:**
```typescript
{
key: string; // Required: Unique key
label: string; // Required: Display label (i18n)
path: string; // Required: Route path
icon?: string; // Optional: Lucide icon name
children?: SubItem[]; // Optional: Submenu items
}
```
---
### `woonoow/nav_tree/{key}/children`
**Type:** Filter
**Priority:** 30 (runs on `plugins_loaded`)
**File:** `includes/Compat/NavigationRegistry.php`
**Purpose:** Inject items into specific section's submenu
**Available Keys:**
- `dashboard` - Dashboard section
- `orders` - Orders section (no children by design)
- `products` - Products section
- `coupons` - Coupons section
- `customers` - Customers section
- `settings` - Settings section
- *Any custom section key added by addons*
**Parameters:**
- `$children` (array) - Array of submenu items
**Returns:** array
**Example:**
```php
// Add "Bundles" to Products menu
add_filter('woonoow/nav_tree/products/children', function($children) {
$children[] = [
'label' => __('Bundles', 'my-addon'),
'mode' => 'spa',
'path' => '/products/bundles',
];
return $children;
});
// Add "Reports" to Dashboard menu
add_filter('woonoow/nav_tree/dashboard/children', function($children) {
$children[] = [
'label' => __('Custom Reports', 'my-addon'),
'mode' => 'spa',
'path' => '/reports',
];
return $children;
});
```
**Schema:**
```typescript
{
label: string; // Required: Display label (i18n)
mode: 'spa' | 'bridge'; // Required: Render mode
path?: string; // Required for SPA mode
href?: string; // Required for bridge mode
exact?: boolean; // Optional: Exact path match
}
```
---
## Route Hooks
### `woonoow/spa_routes`
**Type:** Filter
**Priority:** 25 (runs on `plugins_loaded`)
**File:** `includes/Compat/RouteRegistry.php`
**Purpose:** Register SPA routes for addon pages
**Parameters:**
- `$routes` (array) - Array of route configurations
**Returns:** array
**Example:**
```php
add_filter('woonoow/spa_routes', function($routes) {
$base_url = plugin_dir_url(__FILE__) . 'dist/';
$routes[] = [
'path' => '/subscriptions',
'component_url' => $base_url . 'SubscriptionsList.js',
'capability' => 'manage_woocommerce',
'title' => __('Subscriptions', 'my-addon'),
];
$routes[] = [
'path' => '/subscriptions/:id',
'component_url' => $base_url . 'SubscriptionDetail.js',
'capability' => 'manage_woocommerce',
'title' => __('Subscription Detail', 'my-addon'),
];
return $routes;
});
```
**Schema:**
```typescript
{
path: string; // Required: Route path (must start with /)
component_url: string; // Required: URL to React component JS
capability?: string; // Optional: WordPress capability (default: manage_woocommerce)
title?: string; // Optional: Page title
exact?: boolean; // Optional: Exact path match (default: false)
props?: object; // Optional: Props to pass to component
}
```
---
## Content Injection Hooks
### `woonoow/dashboard/widgets` (Future)
**Type:** Filter
**Priority:** TBD
**File:** `includes/Compat/WidgetRegistry.php` (planned)
**Purpose:** Add widgets to dashboard
**Status:** 📋 Planned
**Example:**
```php
add_filter('woonoow/dashboard/widgets', function($widgets) {
$widgets[] = [
'id' => 'subscription-stats',
'title' => __('Active Subscriptions', 'my-addon'),
'component_url' => plugin_dir_url(__FILE__) . 'dist/SubscriptionWidget.js',
'position' => 'top-right',
'size' => 'medium',
];
return $widgets;
});
```
---
### `woonoow/order/detail/panels` (Future)
**Type:** Filter
**Priority:** TBD
**File:** `includes/Compat/WidgetRegistry.php` (planned)
**Purpose:** Add panels to order detail page
**Status:** 📋 Planned
**Example:**
```php
add_filter('woonoow/order/detail/panels', function($panels, $order_id) {
if (wcs_order_contains_subscription($order_id)) {
$panels[] = [
'id' => 'subscription-info',
'title' => __('Subscription', 'my-addon'),
'content' => render_subscription_panel($order_id),
];
}
return $panels;
}, 10, 2);
```
---
### `woonoow/orders/toolbar_actions` (Future)
**Type:** Filter
**Priority:** TBD
**File:** TBD
**Purpose:** Add actions to orders list toolbar
**Status:** 📋 Planned
**Example:**
```php
add_filter('woonoow/orders/toolbar_actions', function($actions) {
$actions[] = [
'label' => __('Export to CSV', 'my-addon'),
'callback' => 'my_addon_export_orders',
'icon' => 'download',
];
return $actions;
});
```
---
## Payment & Shipping Hooks
### `woonoow/payment_gateway_channels`
**Type:** Filter
**Priority:** 10-30
**File:** `includes/Api/OrdersController.php`, `includes/Compat/PaymentChannels.php`
**Purpose:** Detect and expose payment gateway channels (e.g., bank accounts)
**Parameters:**
- `$channels` (array) - Array of channel configurations
- `$gateway_id` (string) - Gateway ID
- `$gateway` (object) - Gateway instance
**Returns:** array
**Example:**
```php
add_filter('woonoow/payment_gateway_channels', function($channels, $gateway_id, $gateway) {
if ($gateway_id === 'stripe') {
$accounts = get_option('stripe_connected_accounts', []);
foreach ($accounts as $account) {
$channels[] = [
'id' => 'stripe_' . $account['id'],
'title' => $account['name'],
'meta' => $account,
];
}
}
return $channels;
}, 30, 3);
```
**Built-in Handlers:**
- **BACS Detection** (Priority 10) - Automatically detects bank transfer accounts
- **Custom Channels** (Priority 20) - Placeholder for third-party integrations
**Schema:**
```typescript
{
id: string; // Required: Unique channel ID
title: string; // Required: Display name
meta?: any; // Optional: Additional channel data
}
```
**Use Case:**
When a payment gateway has multiple accounts or channels (e.g., multiple bank accounts for BACS), this filter allows them to be exposed as separate options in the order form.
---
## Asset Hooks
### `woonoow/admin_is_dev`
**Type:** Filter
**Priority:** N/A
**File:** `includes/Admin/Assets.php`
**Purpose:** Force dev/prod mode for admin assets
**Parameters:**
- `$is_dev` (bool) - Whether dev mode is enabled
**Returns:** bool
**Example:**
```php
// Force dev mode
add_filter('woonoow/admin_is_dev', '__return_true');
// Force prod mode
add_filter('woonoow/admin_is_dev', '__return_false');
```
---
### `woonoow/admin_dev_server`
**Type:** Filter
**Priority:** N/A
**File:** `includes/Admin/Assets.php`
**Purpose:** Change dev server URL
**Parameters:**
- `$url` (string) - Dev server URL
**Returns:** string
**Example:**
```php
add_filter('woonoow/admin_dev_server', function($url) {
return 'http://localhost:3000';
});
```
---
## Future Hooks
### Planned for Future Releases
#### Product Module
- `woonoow/product/types` - Register custom product types
- `woonoow/product/fields` - Add custom product fields
- `woonoow/product/detail/tabs` - Add tabs to product detail
#### Customer Module
- `woonoow/customer/fields` - Add custom customer fields
- `woonoow/customer/detail/panels` - Add panels to customer detail
#### Settings Module
- `woonoow/settings/tabs` - Add custom settings tabs
- `woonoow/settings/sections` - Add settings sections
#### Email Module
- `woonoow/email/templates` - Register custom email templates
- `woonoow/email/variables` - Add email template variables
#### Reports Module
- `woonoow/reports/types` - Register custom report types
- `woonoow/reports/widgets` - Add report widgets
---
## Hook Tree Structure
```
woonoow/
├── addon_registry ✅ ACTIVE (Priority: 20)
│ └── Purpose: Register addon metadata
├── spa_routes ✅ ACTIVE (Priority: 25)
│ └── Purpose: Register SPA routes
├── nav_tree ✅ ACTIVE (Priority: 30)
│ ├── Purpose: Modify navigation tree
│ └── {section_key}/
│ └── children ✅ ACTIVE (Priority: 30)
│ └── Purpose: Inject submenu items
├── payment_gateway_channels ✅ ACTIVE (Priority: 10-30)
│ └── Purpose: Detect payment gateway channels
├── dashboard/
│ └── widgets 📋 PLANNED
│ └── Purpose: Add dashboard widgets
├── order/
│ └── detail/
│ └── panels 📋 PLANNED
│ └── Purpose: Add order detail panels
├── orders/
│ └── toolbar_actions 📋 PLANNED
│ └── Purpose: Add toolbar actions
├── product/
│ ├── types 📋 PLANNED
│ ├── fields 📋 PLANNED
│ └── detail/
│ └── tabs 📋 PLANNED
├── customer/
│ ├── fields 📋 PLANNED
│ └── detail/
│ └── panels 📋 PLANNED
├── settings/
│ ├── tabs 📋 PLANNED
│ └── sections 📋 PLANNED
├── email/
│ ├── templates 📋 PLANNED
│ └── variables 📋 PLANNED
├── reports/
│ ├── types 📋 PLANNED
│ └── widgets 📋 PLANNED
└── admin_is_dev ✅ ACTIVE
└── Purpose: Force dev/prod mode
```
---
## Hook Priority Guidelines
**Standard Priorities:**
- **10** - Early hooks (before WooNooW)
- **20** - AddonRegistry (collect addon metadata)
- **25** - RouteRegistry (collect routes)
- **30** - NavigationRegistry (build nav tree)
- **40** - Late hooks (after WooNooW)
- **50+** - Very late hooks
**Why This Order:**
1. AddonRegistry runs first to validate dependencies
2. RouteRegistry runs next to register routes
3. NavigationRegistry runs last to build complete tree
**Custom Hook Priorities:**
- Use **15** to run before AddonRegistry
- Use **22** to run between Addon and Route
- Use **27** to run between Route and Navigation
- Use **35** to run after all registries
---
## Hook Usage Examples
### Complete Addon Integration
```php
<?php
/**
* Plugin Name: WooNooW Complete Addon
* Description: Shows all hook usage
*/
// 1. Register addon (Priority: 20)
add_filter('woonoow/addon_registry', function($addons) {
$addons['complete-addon'] = [
'id' => 'complete-addon',
'name' => 'Complete Addon',
'version' => '1.0.0',
'dependencies' => ['woocommerce' => '8.0'],
];
return $addons;
});
// 2. Register routes (Priority: 25)
add_filter('woonoow/spa_routes', function($routes) {
$routes[] = [
'path' => '/complete',
'component_url' => plugin_dir_url(__FILE__) . 'dist/Complete.js',
'capability' => 'manage_woocommerce',
];
return $routes;
});
// 3. Add main menu (Priority: 30)
add_filter('woonoow/nav_tree', function($tree) {
$tree[] = [
'key' => 'complete',
'label' => 'Complete',
'path' => '/complete',
'icon' => 'puzzle',
'children' => [],
];
return $tree;
});
// 4. Inject into existing menu (Priority: 30)
add_filter('woonoow/nav_tree/products/children', function($children) {
$children[] = [
'label' => 'Custom Products',
'mode' => 'spa',
'path' => '/complete/products',
];
return $children;
});
```
---
## Best Practices
### ✅ DO:
1. **Use Correct Priority**
```php
add_filter('woonoow/addon_registry', $callback, 20);
```
2. **Return Modified Data**
```php
add_filter('woonoow/nav_tree', function($tree) {
$tree[] = ['key' => 'my-item', ...];
return $tree; // ✅ Always return
});
```
3. **Validate Data**
```php
add_filter('woonoow/spa_routes', function($routes) {
if (!empty($my_route['path'])) {
$routes[] = $my_route;
}
return $routes;
});
```
4. **Use i18n**
```php
'label' => __('My Label', 'my-addon')
```
5. **Check Dependencies**
```php
if (class_exists('WooCommerce')) {
add_filter('woonoow/addon_registry', ...);
}
```
### ❌ DON'T:
1. **Don't Forget to Return**
```php
// ❌ Bad
add_filter('woonoow/nav_tree', function($tree) {
$tree[] = ['key' => 'my-item', ...];
// Missing return!
});
```
2. **Don't Use Wrong Hook Name**
```php
// ❌ Bad
add_filter('woonoow_addon_registry', ...); // Wrong separator
add_filter('addon_registry', ...); // Missing prefix
```
3. **Don't Modify Core Items**
```php
// ❌ Bad
add_filter('woonoow/nav_tree', function($tree) {
unset($tree[0]); // Don't remove core items
return $tree;
});
```
4. **Don't Use Generic Keys**
```php
// ❌ Bad
'key' => 'item' // Too generic
// ✅ Good
'key' => 'my-addon-subscriptions'
```
---
## Testing Hooks
### Check Hook Registration
```javascript
// Browser console
console.log('Addons:', window.WNW_ADDONS);
console.log('Routes:', window.WNW_ADDON_ROUTES);
console.log('Nav Tree:', window.WNW_NAV_TREE);
```
### Debug Hook Execution
```php
// Add debug logging
add_filter('woonoow/addon_registry', function($addons) {
error_log('WooNooW: Addon registry filter fired');
error_log('WooNooW: Current addons: ' . print_r($addons, true));
$addons['my-addon'] = [...];
error_log('WooNooW: After adding my addon: ' . print_r($addons, true));
return $addons;
});
```
### Flush Caches
```php
// Flush all WooNooW caches
do_action('woonoow_flush_caches');
// Or manually
delete_option('wnw_addon_registry');
delete_option('wnw_spa_routes');
delete_option('wnw_nav_tree');
```
---
## Support & Resources
**Documentation:**
- `ADDON_INJECTION_GUIDE.md` - Complete developer guide
- `PROJECT_SOP.md` - Development standards
- `ADDONS_ADMIN_UI_REQUIREMENTS.md` - Requirements & status
**Code References:**
- `includes/Compat/AddonRegistry.php` - Addon registration
- `includes/Compat/RouteRegistry.php` - Route management
- `includes/Compat/NavigationRegistry.php` - Navigation building
---
**End of Registry**
**Version:** 1.0.0
**Last Updated:** 2025-10-28
**Status:** ✅ Production Ready