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

18 KiB

WooNooW Hooks & Filters Registry

Version: 1.0.0
Last Updated: 2025-10-28
Status: Production Ready


📋 Table of Contents

  1. Hook Naming Convention
  2. Addon System Hooks
  3. Navigation Hooks
  4. Route Hooks
  5. Content Injection Hooks
  6. Asset Hooks
  7. Future Hooks
  8. 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:

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:

{
  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:

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:

{
  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:

// 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:

{
  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:

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:

{
  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:

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:

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:

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:

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:

{
  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:

// 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:

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
/**
 * 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

    add_filter('woonoow/addon_registry', $callback, 20);
    
  2. Return Modified Data

    add_filter('woonoow/nav_tree', function($tree) {
        $tree[] = ['key' => 'my-item', ...];
        return $tree; // ✅ Always return
    });
    
  3. Validate Data

    add_filter('woonoow/spa_routes', function($routes) {
        if (!empty($my_route['path'])) {
            $routes[] = $my_route;
        }
        return $routes;
    });
    
  4. Use i18n

    'label' => __('My Label', 'my-addon')
    
  5. Check Dependencies

    if (class_exists('WooCommerce')) {
        add_filter('woonoow/addon_registry', ...);
    }
    

DON'T:

  1. Don't Forget to Return

    // ❌ Bad
    add_filter('woonoow/nav_tree', function($tree) {
        $tree[] = ['key' => 'my-item', ...];
        // Missing return!
    });
    
  2. Don't Use Wrong Hook Name

    // ❌ Bad
    add_filter('woonoow_addon_registry', ...); // Wrong separator
    add_filter('addon_registry', ...);         // Missing prefix
    
  3. Don't Modify Core Items

    // ❌ Bad
    add_filter('woonoow/nav_tree', function($tree) {
        unset($tree[0]); // Don't remove core items
        return $tree;
    });
    
  4. Don't Use Generic Keys

    // ❌ Bad
    'key' => 'item' // Too generic
    
    // ✅ Good
    'key' => 'my-addon-subscriptions'
    

Testing Hooks

Check Hook Registration

// 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

// 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

// 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