[ 'id' => 'newsletter', 'label' => __('Newsletter & Campaigns', 'woonoow'), 'description' => __('Email newsletter subscription and campaign management', 'woonoow'), 'category' => 'marketing', 'icon' => 'mail', 'default_enabled' => true, 'has_settings' => true, 'features' => [ __('Subscriber management', 'woonoow'), __('Email campaigns', 'woonoow'), __('Campaign scheduling', 'woonoow'), ], ], 'wishlist' => [ 'id' => 'wishlist', 'label' => __('Customer Wishlist', 'woonoow'), 'description' => __('Allow customers to save products for later', 'woonoow'), 'category' => 'customers', 'icon' => 'heart', 'default_enabled' => true, 'has_settings' => true, 'features' => [ __('Save products to wishlist', 'woonoow'), __('Wishlist page', 'woonoow'), __('Share wishlist', 'woonoow'), ], ], 'affiliate' => [ 'id' => 'affiliate', 'label' => __('Affiliate Program', 'woonoow'), 'description' => __('Referral tracking and commission management', 'woonoow'), 'category' => 'marketing', 'icon' => 'users', 'default_enabled' => false, 'features' => [ __('Referral tracking', 'woonoow'), __('Commission management', 'woonoow'), __('Affiliate dashboard', 'woonoow'), __('Payout system', 'woonoow'), ], ], 'subscription' => [ 'id' => 'subscription', 'label' => __('Product Subscriptions', 'woonoow'), 'description' => __('Recurring product subscriptions with flexible billing', 'woonoow'), 'category' => 'products', 'icon' => 'refresh-cw', 'default_enabled' => false, 'has_settings' => true, 'features' => [ __('Recurring billing', 'woonoow'), __('Subscription management', 'woonoow'), __('Automatic renewals', 'woonoow'), __('Trial periods', 'woonoow'), ], ], 'licensing' => [ 'id' => 'licensing', 'label' => __('Software Licensing', 'woonoow'), 'description' => __('License key generation and validation for digital products', 'woonoow'), 'category' => 'products', 'icon' => 'key', 'default_enabled' => false, 'has_settings' => true, 'features' => [ __('License key generation', 'woonoow'), __('Activation management', 'woonoow'), __('Validation API', 'woonoow'), __('Expiry management', 'woonoow'), ], ], ]; return $modules; } /** * Get addon modules from AddonRegistry * * @return array */ private static function get_addon_modules() { $addons = apply_filters('woonoow/addon_registry', []); $modules = []; foreach ($addons as $addon_id => $addon) { $modules[$addon_id] = [ 'id' => $addon_id, 'label' => $addon['name'] ?? ucfirst($addon_id), 'description' => $addon['description'] ?? '', 'category' => $addon['category'] ?? 'other', 'icon' => $addon['icon'] ?? 'puzzle', 'default_enabled' => false, 'features' => $addon['features'] ?? [], 'is_addon' => true, 'version' => $addon['version'] ?? '1.0.0', 'author' => $addon['author'] ?? '', 'has_settings' => !empty($addon['has_settings']), 'settings_component' => $addon['settings_component'] ?? null, ]; } return $modules; } /** * Get all modules (built-in + addons) * * @return array */ public static function get_all_modules() { $builtin = self::get_builtin_modules(); $addons = self::get_addon_modules(); return array_merge($builtin, $addons); } /** * Get categories dynamically from registered modules * * @return array Associative array of category_id => label */ public static function get_categories() { $all_modules = self::get_all_modules(); $categories = []; // Extract unique categories from modules foreach ($all_modules as $module) { $cat = $module['category'] ?? 'other'; if (!isset($categories[$cat])) { $categories[$cat] = self::get_category_label($cat); } } // Sort by predefined order $order = ['marketing', 'customers', 'products', 'shipping', 'payments', 'analytics', 'other']; uksort($categories, function ($a, $b) use ($order) { $pos_a = array_search($a, $order); $pos_b = array_search($b, $order); if ($pos_a === false) $pos_a = 999; if ($pos_b === false) $pos_b = 999; return $pos_a - $pos_b; }); return $categories; } /** * Get human-readable label for category * * @param string $category Category ID * @return string */ private static function get_category_label($category) { $labels = [ 'marketing' => __('Marketing & Sales', 'woonoow'), 'customers' => __('Customer Experience', 'woonoow'), 'products' => __('Products & Inventory', 'woonoow'), 'shipping' => __('Shipping & Fulfillment', 'woonoow'), 'payments' => __('Payments & Checkout', 'woonoow'), 'analytics' => __('Analytics & Reports', 'woonoow'), 'other' => __('Other Extensions', 'woonoow'), ]; return $labels[$category] ?? ucfirst($category); } /** * Group modules by category * * @return array */ public static function get_grouped_modules() { $all_modules = self::get_all_modules(); $grouped = []; foreach ($all_modules as $module) { $cat = $module['category'] ?? 'other'; if (!isset($grouped[$cat])) { $grouped[$cat] = []; } $grouped[$cat][] = $module; } return $grouped; } /** * Get enabled modules * * @return array */ public static function get_enabled_modules() { $enabled = get_option('woonoow_enabled_modules', null); // First time - use defaults if ($enabled === null) { $modules = self::get_all_modules(); $enabled = []; foreach ($modules as $module) { if ($module['default_enabled']) { $enabled[] = $module['id']; } } update_option('woonoow_enabled_modules', $enabled); } return $enabled; } /** * Check if a module is enabled * * @param string $module_id * @return bool */ public static function is_enabled($module_id) { $enabled = self::get_enabled_modules(); return in_array($module_id, $enabled); } /** * Enable a module * * @param string $module_id * @return bool */ public static function enable($module_id) { $modules = self::get_all_modules(); if (!isset($modules[$module_id])) { return false; } $enabled = self::get_enabled_modules(); if (!in_array($module_id, $enabled)) { $enabled[] = $module_id; update_option('woonoow_enabled_modules', $enabled); // Clear navigation cache when module is toggled if (class_exists('\WooNooW\Compat\NavigationRegistry')) { \WooNooW\Compat\NavigationRegistry::flush(); } do_action('woonoow/module/enabled', $module_id); return true; } return false; } /** * Disable a module * * @param string $module_id * @return bool */ public static function disable($module_id) { $enabled = self::get_enabled_modules(); if (in_array($module_id, $enabled)) { $enabled = array_diff($enabled, [$module_id]); update_option('woonoow_enabled_modules', array_values($enabled)); // Clear navigation cache when module is toggled if (class_exists('\WooNooW\Compat\NavigationRegistry')) { \WooNooW\Compat\NavigationRegistry::flush(); } do_action('woonoow/module/disabled', $module_id); return true; } return false; } /** * Get modules by category * * @param string $category * @return array */ public static function get_by_category($category) { $modules = self::get_all_modules(); $enabled = self::get_enabled_modules(); $result = []; foreach ($modules as $module) { if ($module['category'] === $category) { $module['enabled'] = in_array($module['id'], $enabled); $result[] = $module; } } return $result; } /** * Get all modules with enabled status * * @return array */ public static function get_all_with_status() { $modules = self::get_all_modules(); $enabled = self::get_enabled_modules(); foreach ($modules as $id => &$module) { $module['enabled'] = in_array($id, $enabled); } return $modules; } /** * Get module settings * * @param string $module_id * @return array */ public static function get_settings($module_id) { $settings = get_option("woonoow_module_{$module_id}_settings", []); // Apply defaults from schema if available $schema = apply_filters('woonoow/module_settings_schema', []); if (isset($schema[$module_id])) { $defaults = self::get_schema_defaults($schema[$module_id]); $settings = wp_parse_args($settings, $defaults); } return $settings; } /** * Get default values from schema * * @param array $schema * @return array */ private static function get_schema_defaults($schema) { $defaults = []; foreach ($schema as $key => $field) { if (isset($field['default'])) { $defaults[$key] = $field['default']; } } return $defaults; } }