# 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
