FormService.php
1 <?php 2 3 namespace ButA2SaeS3\services; 4 5 use ButA2SaeS3\utils\HttpUtils; 6 7 class FormService 8 { 9 public static function handleFormSubmission( 10 callable $validator, 11 callable $processor, 12 string $successMessage, 13 string $currentPage, 14 string $prefix = '' 15 ): void { 16 if (!HttpUtils::isPost()) { 17 return; 18 } 19 20 $formData = self::sanitizeFormData($_POST); 21 $validationResult = $validator($formData); 22 23 if ($validationResult->isValid()) { 24 try { 25 $processor($validationResult->value()); 26 self::setSuccessMessage($successMessage, $prefix); 27 header("Location: " . self::withRedirectSuccess($currentPage, $prefix)); 28 } catch (\Throwable $e) { 29 self::setFormState($formData, ['_form' => $e->getMessage()], $prefix); 30 header("Location: " . self::withoutQuerySuccess($currentPage)); 31 } 32 exit(); 33 } 34 35 self::setFormState($formData, $validationResult->messages(), $prefix); 36 header("Location: " . self::withoutQuerySuccess($currentPage)); 37 exit(); 38 } 39 40 public static function restoreFormData(string $prefix = ''): array 41 { 42 $dataKey = self::key('form_data', $prefix); 43 $errorsKey = self::key('form_errors', $prefix); 44 45 $data = $_SESSION[$dataKey] ?? []; 46 $errors = $_SESSION[$errorsKey] ?? []; 47 48 unset($_SESSION[$dataKey], $_SESSION[$errorsKey]); 49 50 return ['data' => $data, 'errors' => $errors]; 51 } 52 53 public static function getSuccessMessage(string $prefix = ''): ?string 54 { 55 if (!isset($_GET['success']) || $_GET['success'] !== '1') { 56 return null; 57 } 58 59 if ($prefix !== '' && (($_GET['success_form'] ?? '') !== $prefix)) { 60 return null; 61 } 62 63 $key = self::key('success_message', $prefix); 64 $message = $_SESSION[$key] ?? null; 65 unset($_SESSION[$key]); 66 return $message; 67 } 68 69 public static function getErrorMessage(string $prefix = ''): ?string 70 { 71 $key = self::key('error_message', $prefix); 72 $message = $_SESSION[$key] ?? null; 73 unset($_SESSION[$key]); 74 return $message; 75 } 76 77 public static function setSuccessMessage(string $message, string $prefix = ''): void 78 { 79 $_SESSION[self::key('success_message', $prefix)] = $message; 80 } 81 82 public static function setErrorMessage(string $message, string $prefix = ''): void 83 { 84 $_SESSION[self::key('error_message', $prefix)] = $message; 85 } 86 87 private static function setFormState(array $data, array $errors, string $prefix = ''): void 88 { 89 $_SESSION[self::key('form_data', $prefix)] = $data; 90 $_SESSION[self::key('form_errors', $prefix)] = $errors; 91 } 92 93 private static function key(string $baseKey, string $prefix): string 94 { 95 if ($prefix === '') { 96 return $baseKey; 97 } 98 return $baseKey . '__' . $prefix; 99 } 100 101 private static function withRedirectSuccess(string $url, string $prefix = ''): string 102 { 103 return self::withQuery($url, [ 104 'success' => '1', 105 'success_form' => $prefix !== '' ? $prefix : null 106 ]); 107 } 108 109 private static function withoutQuerySuccess(string $url): string 110 { 111 [$base, $fragment] = array_pad(explode('#', $url, 2), 2, null); 112 return $fragment !== null ? ($base . '#' . $fragment) : $base; 113 } 114 115 private static function withQuery(string $url, array $params): string 116 { 117 [$base, $fragment] = array_pad(explode('#', $url, 2), 2, null); 118 $baseParts = explode('?', $base, 2); 119 $path = $baseParts[0]; 120 $existingQuery = $baseParts[1] ?? ''; 121 122 $queryParams = []; 123 if ($existingQuery !== '') { 124 parse_str($existingQuery, $queryParams); 125 } 126 127 foreach ($params as $k => $v) { 128 if ($v === null) { 129 unset($queryParams[$k]); 130 continue; 131 } 132 $queryParams[$k] = $v; 133 } 134 135 $query = http_build_query($queryParams); 136 $out = $query !== '' ? ($path . '?' . $query) : $path; 137 return $fragment !== null ? ($out . '#' . $fragment) : $out; 138 } 139 140 private static function sanitizeFormData(array $data): array 141 { 142 return array_map(function ($value) { 143 return is_string($value) ? trim($value) : $value; 144 }, $data); 145 } 146 }