- Add ModuleRegistry for managing built-in modules (newsletter, wishlist, affiliate, subscription, licensing) - Add ModulesController REST API for module enable/disable - Create Modules settings page with category grouping and toggle controls - Integrate module checks across admin-spa and customer-spa - Add useModules hook for both SPAs to check module status - Hide newsletter from footer builder when module disabled - Hide wishlist features when module disabled (product cards, account menu, wishlist page) - Protect wishlist API endpoints with module checks - Auto-update navigation tree when modules toggled - Clean up obsolete documentation files - Add comprehensive documentation: - MODULE_SYSTEM_IMPLEMENTATION.md - MODULE_INTEGRATION_SUMMARY.md - ADDON_MODULE_INTEGRATION.md (proposal) - ADDON_MODULE_DESIGN_DECISIONS.md (design doc) - FEATURE_ROADMAP.md - SHIPPING_INTEGRATION.md Module system provides: - Centralized enable/disable for all features - Automatic navigation updates - Frontend/backend integration - Foundation for addon-module unification
399 lines
9.5 KiB
Markdown
399 lines
9.5 KiB
Markdown
# Module Management System - Implementation Guide
|
|
|
|
**Status**: ✅ Complete
|
|
**Date**: December 26, 2025
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
Centralized module management system that allows enabling/disabling features to improve performance and reduce clutter.
|
|
|
|
---
|
|
|
|
## Architecture
|
|
|
|
### Backend Components
|
|
|
|
#### 1. ModuleRegistry (`includes/Core/ModuleRegistry.php`)
|
|
Central registry for all modules with enable/disable functionality.
|
|
|
|
**Methods**:
|
|
- `get_all_modules()` - Get all registered modules
|
|
- `get_enabled_modules()` - Get list of enabled module IDs
|
|
- `is_enabled($module_id)` - Check if a module is enabled
|
|
- `enable($module_id)` - Enable a module
|
|
- `disable($module_id)` - Disable a module
|
|
|
|
**Storage**: `woonoow_enabled_modules` option (array of enabled module IDs)
|
|
|
|
#### 2. ModulesController (`includes/Api/ModulesController.php`)
|
|
REST API endpoints for module management.
|
|
|
|
**Endpoints**:
|
|
- `GET /woonoow/v1/modules` - Get all modules with status (admin only)
|
|
- `POST /woonoow/v1/modules/toggle` - Toggle module on/off (admin only)
|
|
- `GET /woonoow/v1/modules/enabled` - Get enabled modules (public, cached)
|
|
|
|
#### 3. Navigation Integration
|
|
Added "Modules" to Settings menu in `NavigationRegistry.php`.
|
|
|
|
---
|
|
|
|
### Frontend Components
|
|
|
|
#### 1. Settings Page (`admin-spa/src/routes/Settings/Modules.tsx`)
|
|
React component for managing modules.
|
|
|
|
**Features**:
|
|
- Grouped by category (Marketing, Customers, Products)
|
|
- Toggle switches for each module
|
|
- Module descriptions and feature lists
|
|
- Real-time enable/disable with API integration
|
|
|
|
#### 2. useModules Hook
|
|
Custom React hook for checking module status.
|
|
|
|
**Files**:
|
|
- `admin-spa/src/hooks/useModules.ts`
|
|
- `customer-spa/src/hooks/useModules.ts`
|
|
|
|
**Usage**:
|
|
```tsx
|
|
import { useModules } from '@/hooks/useModules';
|
|
|
|
function MyComponent() {
|
|
const { isEnabled, enabledModules, isLoading } = useModules();
|
|
|
|
if (!isEnabled('wishlist')) {
|
|
return null; // Hide feature if module disabled
|
|
}
|
|
|
|
return <WishlistButton />;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Registered Modules
|
|
|
|
### 1. Newsletter & Campaigns
|
|
- **ID**: `newsletter`
|
|
- **Category**: Marketing
|
|
- **Default**: Enabled
|
|
- **Features**: Subscriber management, email campaigns, scheduling
|
|
|
|
### 2. Customer Wishlist
|
|
- **ID**: `wishlist`
|
|
- **Category**: Customers
|
|
- **Default**: Enabled
|
|
- **Features**: Save products, wishlist page, sharing
|
|
|
|
### 3. Affiliate Program
|
|
- **ID**: `affiliate`
|
|
- **Category**: Marketing
|
|
- **Default**: Disabled
|
|
- **Features**: Referral tracking, commissions, dashboard, payouts
|
|
|
|
### 4. Product Subscriptions
|
|
- **ID**: `subscription`
|
|
- **Category**: Products
|
|
- **Default**: Disabled
|
|
- **Features**: Recurring billing, subscription management, renewals, trials
|
|
|
|
### 5. Software Licensing
|
|
- **ID**: `licensing`
|
|
- **Category**: Products
|
|
- **Default**: Disabled
|
|
- **Features**: License keys, activation management, validation API, expiry
|
|
|
|
---
|
|
|
|
## Integration Examples
|
|
|
|
### Example 1: Hide Wishlist Heart Icon (Frontend)
|
|
|
|
**File**: `customer-spa/src/pages/Product/index.tsx`
|
|
|
|
```tsx
|
|
import { useModules } from '@/hooks/useModules';
|
|
|
|
export default function ProductPage() {
|
|
const { isEnabled } = useModules();
|
|
|
|
return (
|
|
<div>
|
|
{/* Only show wishlist button if module enabled */}
|
|
{isEnabled('wishlist') && (
|
|
<button onClick={addToWishlist}>
|
|
<Heart />
|
|
</button>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Example 2: Hide Newsletter Menu (Backend)
|
|
|
|
**File**: `includes/Compat/NavigationRegistry.php`
|
|
|
|
```php
|
|
use WooNooW\Core\ModuleRegistry;
|
|
|
|
private static function get_base_tree(): array {
|
|
$tree = [
|
|
// ... other sections
|
|
[
|
|
'key' => 'marketing',
|
|
'label' => __('Marketing', 'woonoow'),
|
|
'path' => '/marketing',
|
|
'icon' => 'mail',
|
|
'children' => [],
|
|
],
|
|
];
|
|
|
|
// Only add newsletter if module enabled
|
|
if (ModuleRegistry::is_enabled('newsletter')) {
|
|
$tree[4]['children'][] = [
|
|
'label' => __('Newsletter', 'woonoow'),
|
|
'mode' => 'spa',
|
|
'path' => '/marketing/newsletter'
|
|
];
|
|
}
|
|
|
|
return $tree;
|
|
}
|
|
```
|
|
|
|
### Example 3: Conditional Settings Display (Admin)
|
|
|
|
**File**: `admin-spa/src/routes/Settings/Customers.tsx`
|
|
|
|
```tsx
|
|
import { useModules } from '@/hooks/useModules';
|
|
|
|
export default function CustomersSettings() {
|
|
const { isEnabled } = useModules();
|
|
|
|
return (
|
|
<div>
|
|
{/* Only show wishlist settings if module enabled */}
|
|
{isEnabled('wishlist') && (
|
|
<SettingsCard title="Wishlist Settings">
|
|
<WishlistOptions />
|
|
</SettingsCard>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Example 4: Backend Feature Check (PHP)
|
|
|
|
**File**: `includes/Api/SomeController.php`
|
|
|
|
```php
|
|
use WooNooW\Core\ModuleRegistry;
|
|
|
|
public function some_endpoint($request) {
|
|
// Check if module enabled before processing
|
|
if (!ModuleRegistry::is_enabled('wishlist')) {
|
|
return new WP_Error(
|
|
'module_disabled',
|
|
__('Wishlist module is disabled', 'woonoow'),
|
|
['status' => 403]
|
|
);
|
|
}
|
|
|
|
// Process wishlist request
|
|
// ...
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Performance Considerations
|
|
|
|
### Caching
|
|
- Frontend: Module status cached for 5 minutes via React Query
|
|
- Backend: Module list stored in `wp_options` (no transients needed)
|
|
|
|
### Optimization
|
|
- Public endpoint (`/modules/enabled`) returns only enabled module IDs
|
|
- No authentication required for checking module status
|
|
- Minimal payload (~100 bytes)
|
|
|
|
---
|
|
|
|
## Adding New Modules
|
|
|
|
### 1. Register Module (Backend)
|
|
|
|
Edit `includes/Core/ModuleRegistry.php`:
|
|
|
|
```php
|
|
'my_module' => [
|
|
'id' => 'my_module',
|
|
'label' => __('My Module', 'woonoow'),
|
|
'description' => __('Description of my module', 'woonoow'),
|
|
'category' => 'marketing', // or 'customers', 'products'
|
|
'icon' => 'icon-name', // lucide icon name
|
|
'default_enabled' => false,
|
|
'features' => [
|
|
__('Feature 1', 'woonoow'),
|
|
__('Feature 2', 'woonoow'),
|
|
],
|
|
],
|
|
```
|
|
|
|
### 2. Integrate Module Checks
|
|
|
|
**Frontend**:
|
|
```tsx
|
|
const { isEnabled } = useModules();
|
|
if (!isEnabled('my_module')) return null;
|
|
```
|
|
|
|
**Backend**:
|
|
```php
|
|
if (!ModuleRegistry::is_enabled('my_module')) {
|
|
return;
|
|
}
|
|
```
|
|
|
|
### 3. Update Navigation (Optional)
|
|
|
|
If module adds menu items, conditionally add them in `NavigationRegistry.php`.
|
|
|
|
---
|
|
|
|
## Testing Checklist
|
|
|
|
### Backend Tests
|
|
- ✅ Module registry returns all modules
|
|
- ✅ Enable/disable module updates option
|
|
- ✅ `is_enabled()` returns correct status
|
|
- ✅ API endpoints require admin permission
|
|
- ✅ Public endpoint works without auth
|
|
|
|
### Frontend Tests
|
|
- ✅ Modules page displays all modules
|
|
- ✅ Toggle switches work
|
|
- ✅ Changes persist after page reload
|
|
- ✅ `useModules` hook returns correct status
|
|
- ✅ Features hide when module disabled
|
|
|
|
### Integration Tests
|
|
- ✅ Wishlist heart icon hidden when module off
|
|
- ✅ Newsletter menu hidden when module off
|
|
- ✅ Settings sections hidden when module off
|
|
- ✅ API endpoints return 403 when module off
|
|
|
|
---
|
|
|
|
## Migration Notes
|
|
|
|
### First Time Setup
|
|
On first load, modules use `default_enabled` values:
|
|
- Newsletter: Enabled
|
|
- Wishlist: Enabled
|
|
- Affiliate: Disabled
|
|
- Subscription: Disabled
|
|
- Licensing: Disabled
|
|
|
|
### Existing Installations
|
|
No migration needed. System automatically initializes with defaults on first access.
|
|
|
|
---
|
|
|
|
## Hooks & Filters
|
|
|
|
### Actions
|
|
- `woonoow/module/enabled` - Fired when module is enabled
|
|
- Param: `$module_id` (string)
|
|
- `woonoow/module/disabled` - Fired when module is disabled
|
|
- Param: `$module_id` (string)
|
|
|
|
### Filters
|
|
- `woonoow/modules/registry` - Modify module registry
|
|
- Param: `$modules` (array)
|
|
- Return: Modified modules array
|
|
|
|
**Example**:
|
|
```php
|
|
add_filter('woonoow/modules/registry', function($modules) {
|
|
$modules['custom_module'] = [
|
|
'id' => 'custom_module',
|
|
'label' => 'Custom Module',
|
|
// ... other properties
|
|
];
|
|
return $modules;
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Module Toggle Not Working
|
|
1. Check admin permissions (`manage_options`)
|
|
2. Clear browser cache
|
|
3. Check browser console for API errors
|
|
4. Verify REST API is accessible
|
|
|
|
### Module Status Not Updating
|
|
1. Clear React Query cache (refresh page)
|
|
2. Check `woonoow_enabled_modules` option in database
|
|
3. Verify API endpoint returns correct data
|
|
|
|
### Features Still Showing When Disabled
|
|
1. Ensure `useModules()` hook is used
|
|
2. Check component conditional rendering
|
|
3. Verify module ID matches registry
|
|
4. Clear navigation cache if menu items persist
|
|
|
|
---
|
|
|
|
## Future Enhancements
|
|
|
|
### Phase 2
|
|
- Module dependencies (e.g., Affiliate requires Newsletter)
|
|
- Module settings page (configure module-specific options)
|
|
- Bulk enable/disable
|
|
- Import/export module configuration
|
|
|
|
### Phase 3
|
|
- Module marketplace (install third-party modules)
|
|
- Module updates and versioning
|
|
- Module analytics (usage tracking)
|
|
- Module recommendations based on store type
|
|
|
|
---
|
|
|
|
## Files Created/Modified
|
|
|
|
### New Files
|
|
- `includes/Core/ModuleRegistry.php`
|
|
- `includes/Api/ModulesController.php`
|
|
- `admin-spa/src/routes/Settings/Modules.tsx`
|
|
- `admin-spa/src/hooks/useModules.ts`
|
|
- `customer-spa/src/hooks/useModules.ts`
|
|
- `MODULE_SYSTEM_IMPLEMENTATION.md` (this file)
|
|
|
|
### Modified Files
|
|
- `includes/Api/Routes.php` - Registered ModulesController
|
|
- `includes/Compat/NavigationRegistry.php` - Added Modules to Settings menu
|
|
- `admin-spa/src/App.tsx` - Added Modules route
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
✅ **Backend**: ModuleRegistry + API endpoints complete
|
|
✅ **Frontend**: Settings page + useModules hook complete
|
|
✅ **Integration**: Navigation menu + example integrations documented
|
|
✅ **Testing**: Ready for testing
|
|
|
|
**Next Steps**: Test module enable/disable functionality and integrate checks into existing features (wishlist, newsletter, etc.)
|