/ src / services / FormService.php
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  }