TwilioProvider::class, '360dialog' => Dialog360Provider::class, ]; /** * Provider instances cache */ protected static array $instances = []; /** * Create provider for a restaurant * * @param int $restaurantId * @return WhatsappProviderInterface|null */ public static function forRestaurant(int $restaurantId): ?WhatsappProviderInterface { // Check cache $cacheKey = "restaurant_{$restaurantId}"; if (isset(self::$instances[$cacheKey])) { return self::$instances[$cacheKey]; } // Get provider type from config $providerType = self::getProviderType($restaurantId); //ray('ProviderType:' . $providerType); if (!$providerType) { return null; } /*if ($providerType == 'twilio' && defined('ALEXR_PRO_PLUGIN_DIR')) { ray('Cargando Twilio'); require_once ALEXR_PRO_PLUGIN_DIR . 'vendors/twilio/vendor/autoload.php'; } else { return null; }*/ // Create provider $provider = self::create($providerType, $restaurantId); if ($provider) { self::$instances[$cacheKey] = $provider; } return $provider; } /** * Create a specific provider type * * @param string $providerType * @param int $restaurantId * @return WhatsappProviderInterface|null */ public static function create(string $providerType, int $restaurantId): ?WhatsappProviderInterface { $providerType = strtolower($providerType); if (!isset(self::$providers[$providerType])) { return null; } $providerClass = self::$providers[$providerType]; return new $providerClass($restaurantId); } /** * Get provider type from configuration * * @param int $restaurantId * @return string|null */ public static function getProviderType(int $restaurantId): ?string { $config = WhatsappConfig::where('restaurant_id', $restaurantId)->first(); if (!$config) { return null; } $configData = $config->config ?? []; // Check for explicit provider setting if (!empty($configData['provider'])) { return strtolower($configData['provider']); } // Auto-detect based on configured credentials // Check Twilio first (legacy support) if (!empty($configData['twilio_sid']) && !empty($configData['twilio_token'])) { return 'twilio'; } // Check 360dialog if (!empty($configData['dialog360_api_key'])) { return '360dialog'; } return null; } /** * Register a custom provider * * @param string $name Provider name * @param string $class Provider class (must implement WhatsappProviderInterface) * @throws \InvalidArgumentException */ public static function register(string $name, string $class): void { if (!class_exists($class)) { throw new \InvalidArgumentException("Provider class {$class} does not exist"); } if (!in_array(WhatsappProviderInterface::class, class_implements($class))) { throw new \InvalidArgumentException("Provider class {$class} must implement WhatsappProviderInterface"); } self::$providers[strtolower($name)] = $class; } /** * Get all registered providers * * @return array */ public static function getRegisteredProviders(): array { return array_keys(self::$providers); } /** * Check if a provider type is registered * * @param string $providerType * @return bool */ public static function isRegistered(string $providerType): bool { return isset(self::$providers[strtolower($providerType)]); } /** * Clear the instance cache * * @param int|null $restaurantId Clear specific restaurant or all */ public static function clearCache(?int $restaurantId = null): void { if ($restaurantId) { unset(self::$instances["restaurant_{$restaurantId}"]); } else { self::$instances = []; } } /** * Find restaurant by phone number * * @param string $phone * @return int|null Restaurant ID or null */ public static function findRestaurantByPhone(string $phone): ?int { $phone = preg_replace('/[^0-9+]/', '', $phone); $phone = ltrim($phone, '+'); $configs = WhatsappConfig::all(); foreach ($configs as $config) { $configData = $config->config ?? []; // Check Twilio phone $twilioPhone = $configData['twilio_phone'] ?? ''; $twilioPhone = preg_replace('/[^0-9+]/', '', $twilioPhone); $twilioPhone = ltrim($twilioPhone, '+'); if ($twilioPhone && $twilioPhone === $phone) { return $config->restaurant_id; } // Check 360dialog phone $dialogPhone = $configData['dialog360_phone_number'] ?? ''; $dialogPhone = preg_replace('/[^0-9+]/', '', $dialogPhone); $dialogPhone = ltrim($dialogPhone, '+'); if ($dialogPhone && $dialogPhone === $phone) { return $config->restaurant_id; } } return null; } /** * Get provider info for display * * @return array */ public static function getProviderInfo(): array { return [ 'twilio' => [ 'name' => 'Twilio', 'description' => 'Twilio WhatsApp Business API', 'config_fields' => [ 'twilio_sid' => [ 'label' => 'Account SID', 'type' => 'text', 'required' => true, ], 'twilio_token' => [ 'label' => 'Auth Token', 'type' => 'password', 'required' => true, ], 'twilio_phone' => [ 'label' => 'WhatsApp Phone Number', 'type' => 'text', 'required' => true, 'placeholder' => '+1234567890', ], ], ], '360dialog' => [ 'name' => '360dialog', 'description' => '360dialog WhatsApp Cloud API', 'config_fields' => [ 'dialog360_api_key' => [ 'label' => 'API Key', 'type' => 'password', 'required' => true, ], 'dialog360_phone_number' => [ 'label' => 'WhatsApp Phone Number', 'type' => 'text', 'required' => true, 'placeholder' => '+1234567890', ], 'dialog360_phone_number_id' => [ 'label' => 'Phone Number ID', 'type' => 'text', 'required' => false, ], 'dialog360_webhook_verify_token' => [ 'label' => 'Webhook Verify Token', 'type' => 'text', 'required' => false, ], 'dialog360_app_secret' => [ 'label' => 'App Secret (for webhook validation)', 'type' => 'password', 'required' => false, ], ], ], ]; } }