HomeController.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. <?php
  2. /**
  3. * Classe HomeController
  4. *
  5. * Gère les actions liées à la page d'accueil.
  6. */
  7. if (!class_exists('HomeController')) {
  8. class HomeController
  9. {
  10. /**
  11. * Affiche la page d'accueil.
  12. */
  13. public static function index()
  14. {
  15. $data = [
  16. 'title' => 'Bienvenue dans l\'application',
  17. 'content' => 'Ceci est le contenu principal de la page d\'accueil.',
  18. 'loaded_map' => null,
  19. 'map_data' => null
  20. ];
  21. // Vérifier si une carte doit être chargée
  22. if (isset($_GET['load']) && is_numeric($_GET['load'])) {
  23. $mapId = (int) $_GET['load'];
  24. $map = MapModel::findMap($mapId);
  25. if ($map) {
  26. $data['loaded_map'] = $map;
  27. $data['map_data'] = [
  28. 'id' => $mapId,
  29. 'name' => $map->getName(),
  30. 'width' => $map->getWidth(),
  31. 'height' => $map->getHeight(),
  32. 'created_at' => $map->getCreatedAt(),
  33. 'updated_at' => $map->getUpdatedAt(),
  34. 'statistics' => $map->getStatistics()
  35. ];
  36. $data['title'] = $map->getName() . ' - Map Generator';
  37. } else {
  38. $data['load_error'] = 'Carte non trouvée (ID: ' . $mapId . '). Vérifiez que l\'ID est correct.';
  39. }
  40. }
  41. Renderer::render('home', $data);
  42. }
  43. /**
  44. * Affiche le formulaire de création d'un nouveau projet.
  45. */
  46. public static function newProject()
  47. {
  48. $data = [
  49. 'title' => 'Nouveau projet - Map Generator',
  50. 'page' => 'new_project'
  51. ];
  52. // Découvrir les templates disponibles
  53. require_once __DIR__ . '/../Models/Templates/TemplateFactory.php';
  54. $templates = TemplateFactory::listAvailable();
  55. $data['templates'] = $templates;
  56. Renderer::render('projects/new', $data);
  57. }
  58. /**
  59. * Crée un nouveau projet (endpoint POST)
  60. * Accepte form POST classique ou JSON
  61. */
  62. public static function createProject()
  63. {
  64. if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
  65. http_response_code(405);
  66. echo json_encode(['success' => false, 'message' => 'Méthode non autorisée']);
  67. return;
  68. }
  69. $contentType = $_SERVER['CONTENT_TYPE'] ?? '';
  70. if (strpos($contentType, 'application/json') !== false) {
  71. $raw = file_get_contents('php://input');
  72. $input = json_decode($raw, true) ?: [];
  73. } else {
  74. $input = $_POST;
  75. }
  76. $name = isset($input['name']) ? trim($input['name']) : '';
  77. $description = $input['description'] ?? null;
  78. $template = $input['template'] ?? null;
  79. if (!$name) {
  80. http_response_code(400);
  81. echo json_encode(['success' => false, 'message' => 'Le nom est requis']);
  82. return;
  83. }
  84. // Si un radius est envoyé, créer la map via radius
  85. $radius = isset($input['radius']) ? (int) $input['radius'] : null;
  86. $map = null;
  87. if ($radius && $radius > 0) {
  88. $map = Map::fromRadius($name, $radius);
  89. } else {
  90. // Fallback: utiliser width/height
  91. $width = isset($input['width']) ? (int) $input['width'] : 10;
  92. $height = isset($input['height']) ? (int) $input['height'] : 10;
  93. $map = new Map($name, $width, $height);
  94. }
  95. // Appliquer le template si fourni (ou template neutre par défaut)
  96. require_once __DIR__ . '/../Models/Templates/TemplateFactory.php';
  97. $templateClass = TemplateFactory::get($template);
  98. if (class_exists($templateClass) && method_exists($templateClass, 'applyTemplate')) {
  99. $templateClass::applyTemplate($map);
  100. }
  101. $created = MapModel::create($map, $description, $template, $radius);
  102. // Détecter AJAX
  103. $isAjax = false;
  104. $xrw = $_SERVER['HTTP_X_REQUESTED_WITH'] ?? '';
  105. if (strtolower($xrw) === 'xmlhttprequest' || strpos($contentType, 'application/json') !== false) {
  106. $isAjax = true;
  107. }
  108. if ($created) {
  109. if ($isAjax) {
  110. echo json_encode(['success' => true, 'id' => $created]);
  111. } else {
  112. header('Location: /projects');
  113. }
  114. } else {
  115. if ($isAjax) {
  116. http_response_code(500);
  117. echo json_encode(['success' => false, 'message' => 'Erreur lors de la création']);
  118. } else {
  119. header('Location: /projects');
  120. }
  121. }
  122. }
  123. /**
  124. * Affiche la liste des projets (cartes) disponibles.
  125. */
  126. public static function projects()
  127. {
  128. // Récupérer la liste des cartes depuis la base de données
  129. $maps = MapModel::paginate(1, 20)['data']; // Récupérer les 20 premières cartes
  130. // Récupérer les statistiques globales
  131. $stats = MapModel::getGlobalStats();
  132. $data = [
  133. 'title' => 'Mes projets - Map Generator',
  134. 'page' => 'projects',
  135. 'maps' => $maps,
  136. 'stats' => $stats
  137. ];
  138. Renderer::render('projects/index', $data);
  139. }
  140. /**
  141. * Affiche le formulaire d'édition pour une carte existante
  142. * @param int $id
  143. */
  144. public static function editProject(int $id)
  145. {
  146. // Charger la map via MapModel
  147. $map = MapModel::findMap($id);
  148. if (!$map) {
  149. http_response_code(404);
  150. echo 'Carte non trouvée';
  151. return;
  152. }
  153. // Préparer les données de la view
  154. require_once __DIR__ . '/../Models/Templates/TemplateFactory.php';
  155. $templates = TemplateFactory::listAvailable();
  156. // Récupérer la row brute pour extraire les métadonnées JSON
  157. $rawRow = null;
  158. try {
  159. $rawRow = MapModel::getRowById($id);
  160. } catch (Throwable $e) {
  161. $rawRow = null;
  162. }
  163. $templateId = null;
  164. $radiusVal = null;
  165. if (!empty($rawRow['data'])) {
  166. $decoded = is_string($rawRow['data']) ? json_decode($rawRow['data'], true) : $rawRow['data'];
  167. if (is_array($decoded)) {
  168. $templateId = $decoded['template'] ?? null;
  169. $radiusVal = isset($decoded['radius']) ? (int)$decoded['radius'] : null;
  170. }
  171. }
  172. $data = [
  173. 'title' => 'Édition de la carte - ' . $map->getName(),
  174. 'page' => 'projects_edit',
  175. 'map' => $map,
  176. 'templates' => $templates,
  177. 'templateId' => $templateId,
  178. 'radiusVal' => $radiusVal,
  179. 'mapId' => $id,
  180. 'mapDescription' => $rawRow['description'] ?? ''
  181. ];
  182. Renderer::render('projects/edit', $data);
  183. }
  184. /**
  185. * Traite la mise à jour d'une carte (POST)
  186. */
  187. public static function updateProject()
  188. {
  189. if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
  190. http_response_code(405);
  191. echo json_encode(['success' => false, 'message' => 'Méthode non autorisée']);
  192. return;
  193. }
  194. $input = $_POST;
  195. $id = isset($input['id']) ? (int)$input['id'] : null;
  196. if (!$id) {
  197. http_response_code(400);
  198. echo json_encode(['success' => false, 'message' => 'ID manquant']);
  199. return;
  200. }
  201. $name = isset($input['name']) ? trim($input['name']) : '';
  202. $description = $input['description'] ?? null;
  203. $template = $input['template'] ?? null;
  204. $radius = isset($input['radius']) ? (int)$input['radius'] : null;
  205. $existing = MapModel::findMap($id);
  206. if (!$existing) {
  207. http_response_code(404);
  208. echo json_encode(['success' => false, 'message' => 'Carte non trouvée']);
  209. return;
  210. }
  211. // Par défaut, préserver le contenu existant
  212. $map = $existing;
  213. // Récupérer la row brute pour comparer le radius existant
  214. $existingRow = MapModel::getRowById($id);
  215. $existingRadius = null;
  216. if (!empty($existingRow['data'])) {
  217. $decoded = is_string($existingRow['data']) ? json_decode($existingRow['data'], true) : $existingRow['data'];
  218. if (is_array($decoded) && isset($decoded['radius'])) {
  219. $existingRadius = (int)$decoded['radius'];
  220. }
  221. }
  222. // Si l'utilisateur a fourni un radius et qu'il est différent de l'existant, reconstruire la map
  223. if ($radius && $radius > 0 && $radius !== $existingRadius) {
  224. $map = Map::fromRadius($name ?: $existing->getName(), $radius);
  225. } else {
  226. // Ne pas reconstruire : mettre à jour seulement le nom si fourni
  227. if (!empty($name)) {
  228. $map->setName($name);
  229. }
  230. }
  231. // Appliquer le template si fourni
  232. require_once __DIR__ . '/../Models/Templates/TemplateFactory.php';
  233. $templateClass = TemplateFactory::get($template);
  234. if (class_exists($templateClass) && method_exists($templateClass, 'applyTemplate')) {
  235. $templateClass::applyTemplate($map);
  236. }
  237. // Mettre à jour
  238. $ok = MapModel::update($id, $map, $description, $template, $radius);
  239. if ($ok) {
  240. header('Location: /projects');
  241. } else {
  242. http_response_code(500);
  243. echo 'Erreur lors de la mise à jour';
  244. }
  245. }
  246. /**
  247. * Supprime une carte (endpoint POST)
  248. * Accepte JSON (AJAX) ou form POST standard.
  249. */
  250. public static function deleteProject()
  251. {
  252. // Méthode attendue: POST
  253. if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
  254. http_response_code(405);
  255. echo json_encode(['success' => false, 'message' => 'Méthode non autorisée']);
  256. return;
  257. }
  258. // Lire input JSON si présent
  259. $input = [];
  260. $contentType = $_SERVER['CONTENT_TYPE'] ?? '';
  261. if (strpos($contentType, 'application/json') !== false) {
  262. $raw = file_get_contents('php://input');
  263. $input = json_decode($raw, true) ?: [];
  264. } else {
  265. $input = $_POST;
  266. }
  267. $id = isset($input['id']) ? (int) $input['id'] : null;
  268. if (!$id) {
  269. http_response_code(400);
  270. echo json_encode(['success' => false, 'message' => 'ID manquant']);
  271. return;
  272. }
  273. // Vérifier existence
  274. if (!MapModel::exists($id)) {
  275. http_response_code(404);
  276. echo json_encode(['success' => false, 'message' => 'Carte non trouvée']);
  277. return;
  278. }
  279. $deleted = MapModel::delete($id);
  280. // Détecter si la requête est AJAX
  281. $isAjax = false;
  282. $xrw = $_SERVER['HTTP_X_REQUESTED_WITH'] ?? '';
  283. if (strtolower($xrw) === 'xmlhttprequest' || strpos($contentType, 'application/json') !== false) {
  284. $isAjax = true;
  285. }
  286. if ($isAjax) {
  287. if ($deleted) {
  288. echo json_encode(['success' => true]);
  289. } else {
  290. http_response_code(500);
  291. echo json_encode(['success' => false, 'message' => 'Erreur lors de la suppression']);
  292. }
  293. return;
  294. }
  295. // Pour les requêtes classiques (form POST), utiliser les messages flash en session avant redirection
  296. if (session_status() === PHP_SESSION_NONE) {
  297. session_start();
  298. }
  299. if ($deleted) {
  300. $_SESSION['flash'][] = ['type' => 'success', 'message' => 'La carte a été supprimée avec succès.'];
  301. } else {
  302. $_SESSION['flash'][] = ['type' => 'error', 'message' => 'Une erreur est survenue lors de la suppression de la carte.'];
  303. }
  304. header('Location: /projects');
  305. return;
  306. }
  307. }
  308. }