diff --git a/admin/DashboardController.php b/admin/DashboardController.php index 9692bd6..5333c88 100644 --- a/admin/DashboardController.php +++ b/admin/DashboardController.php @@ -332,26 +332,26 @@ HTML; private static function typeLabel(string $field, string $type): string { if ($field === 'statuses') { - $cls = match ($type) { - 'sent' => 'badge-blue', - 'delivered' => 'badge-green', - 'read' => 'badge-teal', - 'failed' => 'badge-red', - default => 'badge-gray', - }; + switch ($type) { + case 'sent': $cls = 'badge-blue'; break; + case 'delivered': $cls = 'badge-green'; break; + case 'read': $cls = 'badge-teal'; break; + case 'failed': $cls = 'badge-red'; break; + default: $cls = 'badge-gray'; break; + } return '' . self::h($type) . ''; } - return match ($type) { - 'text' => 'πŸ’¬ Texto', - 'image' => 'πŸ–ΌοΈ Imagen', - 'audio' => '🎡 Audio', - 'video' => 'πŸŽ₯ Video', - 'document' => 'πŸ“„ Documento', - 'location' => 'πŸ“ UbicaciΓ³n', - 'interactive' => 'πŸ”˜ Interactivo', - 'button' => 'πŸ”² BotΓ³n', - default => self::h($type), - }; + switch ($type) { + case 'text': return '💬 Texto'; + case 'image': return '📷 Imagen'; + case 'audio': return '🎵 Audio'; + case 'video': return '🎬 Video'; + case 'document': return '📄 Documento'; + case 'location': return '📍 Ubicación'; + case 'interactive': return '🔘 Interactivo'; + case 'button': return '🔲 Botón'; + default: return self::h($type); + } } // ─── Render ─────────────────────────────────────────────────────────────── diff --git a/admin/v1/WpWebhook.php b/admin/v1/WpWebhook.php index 0fcef40..0f1c9fa 100644 --- a/admin/v1/WpWebhook.php +++ b/admin/v1/WpWebhook.php @@ -92,11 +92,13 @@ class WpWebhook $field = $change['field'] ?? ''; $value = $change['value'] ?? []; - match ($field) { - 'messages', 'conversations' => self::handleMessages($value), - 'statuses' => self::handleStatuses($value), - default => self::log('INFO', "Campo no manejado: $field"), - }; + if ($field === 'messages' || $field === 'conversations') { + self::handleMessages($value); + } elseif ($field === 'statuses') { + self::handleStatuses($value); + } else { + self::log('INFO', "Campo no manejado: $field"); + } } } @@ -140,19 +142,19 @@ class WpWebhook 'display_phone' => $displayPhone, ]; - match ($type) { - 'text' => self::handleText($msg, $context), - 'image' => self::handleMedia($msg, $context, 'image'), - 'audio' => self::handleMedia($msg, $context, 'audio'), - 'video' => self::handleMedia($msg, $context, 'video'), - 'document' => self::handleMedia($msg, $context, 'document'), - 'sticker' => self::handleMedia($msg, $context, 'sticker'), - 'location' => self::handleLocation($msg, $context), - 'interactive' => self::handleInteractive($msg, $context), - 'button' => self::handleButton($msg, $context), - 'reaction' => self::handleReaction($msg, $context), - default => self::log('INFO', "Tipo de mensaje no manejado: $type | from=$from"), - }; + switch ($type) { + case 'text': self::handleText($msg, $context); break; + case 'image': self::handleMedia($msg, $context, 'image'); break; + case 'audio': self::handleMedia($msg, $context, 'audio'); break; + case 'video': self::handleMedia($msg, $context, 'video'); break; + case 'document': self::handleMedia($msg, $context, 'document'); break; + case 'sticker': self::handleMedia($msg, $context, 'sticker'); break; + case 'location': self::handleLocation($msg, $context); break; + case 'interactive': self::handleInteractive($msg, $context); break; + case 'button': self::handleButton($msg, $context); break; + case 'reaction': self::handleReaction($msg, $context); break; + default: self::log('INFO', "Tipo de mensaje no manejado: $type | from=$from"); break; + } } // Estados que pueden venir dentro del mismo field 'messages' @@ -198,11 +200,13 @@ class WpWebhook private static function handleInteractive(array $msg, array $ctx): void { $iType = $msg['interactive']['type'] ?? ''; - $reply = match ($iType) { - 'button_reply' => $msg['interactive']['button_reply'] ?? [], - 'list_reply' => $msg['interactive']['list_reply'] ?? [], - default => [], - }; + if ($iType === 'button_reply') { + $reply = $msg['interactive']['button_reply'] ?? []; + } elseif ($iType === 'list_reply') { + $reply = $msg['interactive']['list_reply'] ?? []; + } else { + $reply = []; + } $preview = $iType . ': ' . json_encode($reply); self::log('MSG', "[INTERACTIVE/$iType] {$ctx['from']} | reply=" . json_encode($reply)); self::saveWebhookLog('messages', $ctx['from'], $ctx['name'], 'interactive', $preview); @@ -262,7 +266,7 @@ class WpWebhook } $sigHeader = $_SERVER['HTTP_X_HUB_SIGNATURE_256'] ?? ''; - if (!str_starts_with($sigHeader, 'sha256=')) { + if (strpos($sigHeader, 'sha256=') !== 0) { self::respond(401, ['error' => 'Firma ausente']); } @@ -366,7 +370,7 @@ class WpWebhook } } - private static function respond(int $code, array $body): never + private static function respond(int $code, array $body): void { http_response_code($code); header('Content-Type: application/json; charset=utf-8'); diff --git a/config/env.php b/config/env.php index cf1cb2b..9865bc7 100644 --- a/config/env.php +++ b/config/env.php @@ -15,10 +15,10 @@ declare(strict_types=1); foreach ($lines as $line) { $line = trim($line); // Ignorar comentarios - if ($line === '' || str_starts_with($line, '#')) { + if ($line === '' || strpos($line, '#') === 0) { continue; } - if (!str_contains($line, '=')) { + if (strpos($line, '=') === false) { continue; } [$key, $value] = explode('=', $line, 2); @@ -32,7 +32,7 @@ declare(strict_types=1); } })(); -function env(string $key, mixed $default = null): mixed +function env(string $key, $default = null) { return $_ENV[$key] ?? getenv($key) ?: $default; } diff --git a/index.php b/index.php index c0e13b4..2dd3a3c 100644 --- a/index.php +++ b/index.php @@ -5,13 +5,13 @@ $base = ''; if (file_exists(__DIR__ . '/.env')) { foreach (file(__DIR__ . '/.env') as $line) { $line = trim($line); - if (str_starts_with($line, 'APP_BASE=')) { + if (strpos($line, 'APP_BASE=') === 0) { $base = rtrim(trim(explode('=', $line, 2)[1]), '/'); break; } } } -if ($base !== '' && str_starts_with($_SERVER['REQUEST_URI'], $base)) { +if ($base !== '' && strpos($_SERVER['REQUEST_URI'], $base) === 0) { $_SERVER['REQUEST_URI'] = substr($_SERVER['REQUEST_URI'], strlen($base)) ?: '/'; } require_once __DIR__ . '/public/index.php'; diff --git a/middleware/Auth.php b/middleware/Auth.php index 6e6b1d2..7a41ccf 100644 --- a/middleware/Auth.php +++ b/middleware/Auth.php @@ -19,7 +19,7 @@ class Auth ?? $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ?? ''; - if (!str_starts_with($header, 'Bearer ')) { + if (strpos($header, 'Bearer ') !== 0) { self::abort(401, 'Token de autorizaciΓ³n requerido.'); } @@ -78,7 +78,7 @@ class Auth return base64_decode(strtr($data, '-_', '+/')); } - private static function abort(int $code, string $message): never + private static function abort(int $code, string $message): void { http_response_code($code); header('Content-Type: application/json; charset=utf-8');