Files
WooNooW/SINGLE_SOURCE_OF_TRUTH.md
dwindown 4471cd600f feat: Complete markdown syntax refinement and variable protection
 New cleaner syntax implemented:
- [card:type] instead of [card type='type']
- [button:style](url)Text[/button] instead of [button url='...' style='...']
- Standard markdown images: ![alt](url)

 Variable protection from markdown parsing:
- Variables with underscores (e.g., {order_items_table}) now protected
- HTML comment placeholders prevent italic/bold parsing
- All variables render correctly in preview

 Button rendering fixes:
- Buttons work in Visual mode inside cards
- Buttons work in Preview mode
- Button clicks prevented in visual editor
- Proper styling for solid and outline buttons

 Backward compatibility:
- Old syntax still supported
- No breaking changes

 Bug fixes:
- Fixed order_item_table → order_items_table naming
- Fixed button regex to match across newlines
- Added button/image parsing to parseMarkdownBasics
- Prevented button clicks on .button and .button-outline classes

📚 Documentation:
- NEW_MARKDOWN_SYNTAX.md - Complete user guide
- MARKDOWN_SYNTAX_AND_VARIABLES.md - Technical analysis
2025-11-15 20:05:50 +07:00

4.0 KiB

Single Source of Truth - Event Registry

Problem Solved

Previously, events were hardcoded in multiple places:

  • NotificationsController.php - hardcoded 9 events
  • TemplateProvider.php - hardcoded 9 events
  • DefaultTemplates.php - had 15 templates (8 customer + 7 staff)

Result: Mismatches, confusion, missing templates

Solution: EventRegistry

Created /includes/Core/Notifications/EventRegistry.php as the SINGLE SOURCE OF TRUTH.

How It Works

// Get all events
$events = EventRegistry::get_all_events();

// Get by recipient
$staff_events = EventRegistry::get_events_by_recipient('staff');
$customer_events = EventRegistry::get_events_by_recipient('customer');

// Get by category
$order_events = EventRegistry::get_events_by_category('orders');

// Check if exists
if (EventRegistry::event_exists('order_placed', 'staff')) {
    // ...
}

Current Event List

Staff Events (7):

  1. order_placed - New order notification
  2. order_processing - Order confirmed, ready to process
  3. order_shipped - Order shipped
  4. order_completed - Order completed
  5. order_cancelled - Order cancelled
  6. payment_received - Payment confirmed
  7. payment_failed - Payment failed

Customer Events (8):

  1. order_placed - Order placed confirmation
  2. order_processing - Order being processed
  3. order_shipped - Order shipped with tracking
  4. order_completed - Order delivered
  5. order_cancelled - Order cancelled
  6. payment_received - Payment confirmed
  7. payment_failed - Payment failed, retry
  8. new_customer - Welcome email

Total: 15 events (7 staff + 8 customer)

Filter Hook

add_filter('woonoow_notification_events_registry', function($events) {
    // Add custom event
    $events['custom_event'] = [
        'id' => 'custom_event',
        'label' => 'Custom Event',
        'description' => 'My custom notification',
        'category' => 'custom',
        'recipient_type' => 'customer',
        'wc_email' => '',
        'enabled' => true,
    ];
    
    return $events;
});

Components Updated

1. NotificationsController.php

// OLD - Hardcoded
$events = [
    'orders' => [
        ['id' => 'order_placed', ...],
        // ... 100+ lines
    ]
];

// NEW - Uses Registry
$all_events = EventRegistry::get_all_events();
foreach ($all_events as $event) {
    // Group by category
}

2. TemplateProvider.php

// OLD - Hardcoded
$events = [
    'order_placed' => 'staff',
    'order_processing' => 'customer',
    // ...
];

// NEW - Uses Registry
$all_events = EventRegistry::get_all_events();
foreach ($all_events as $event) {
    $event_id = $event['id'];
    $recipient_type = $event['recipient_type'];
    // Generate templates
}

3. DefaultTemplates.php

No changes needed - Already has all 15 templates matching the registry!

Benefits

Single source of truth - One place to add/remove events No hardcoding - All components query the registry Extensible - Filter hook for custom events Type-safe - Consistent event structure No mismatches - Events and templates always aligned Easy maintenance - Add event once, works everywhere

Adding New Events

  1. Add to EventRegistry.php:
'low_stock' => [
    'id' => 'low_stock',
    'label' => __('Low Stock Alert', 'woonoow'),
    'description' => __('When product stock is low', 'woonoow'),
    'category' => 'products',
    'recipient_type' => 'staff',
    'wc_email' => 'low_stock',
    'enabled' => true,
],
  1. Add template to DefaultTemplates.php:
'staff' => [
    // ...
    'low_stock' => self::staff_low_stock(),
],

private static function staff_low_stock() {
    return '[card type="warning"]...';
}
  1. Done! API and UI automatically show the new event.

Testing

After refresh:

  • Events API returns 15 events (7 staff + 8 customer)
  • Templates API returns 15 templates
  • UI shows correct counts
  • All templates load without errors
  • No hardcoded lists anywhere