Version qui gère mieux les écritures concurentes dans le cache

This commit is contained in:
leosw committed 2026-10-20 17:10:43 +02:00
1 parent 117e4935f5
commit cf36496e0f
1 file changed
+163 -153
+163 -153
View File
@@ -34,34 +34,34 @@ switch ($controller->splitted_url[1]) {
foreach ($definition as $key => $label) { foreach ($definition as $key => $label) {
if (isset($_POST[$key])) { if (isset($_POST[$key])) {
$value = $_POST[$key]; $value = $_POST[$key];
if (str_starts_with($key, 'b_')) { if (str_starts_with($key, 'b_')) {
if ($value === "0" || $value === "1" || $value === "2") { if ($value === "0" || $value === "1" || $value === "2") {
$params[$key] = intval($value); $params[$key] = intval($value);
} else { } else {
$params[$key] = -1; // non renseigné $params[$key] = -1; // non renseigné
} }
}
elseif (str_starts_with($key, 'n_')) {
$params[$key] = is_numeric($value) ? (0 + $value) : null;
}
elseif (str_starts_with($key, 't_') || str_starts_with($key, 'l_')) {
$params[$key] = trim($value);
}
else {
$params[$key] = $value;
} }
elseif (str_starts_with($key, 'n_')) {
$params[$key] = is_numeric($value) ? (0 + $value) : null;
}
elseif (str_starts_with($key, 't_') || str_starts_with($key, 'l_')) {
$params[$key] = trim($value);
}
else {
$params[$key] = $value;
}
} else { } else {
// Champ absent → booléen = -1 (non renseigné) // Champ absent → booléen = -1 (non renseigné)
if (str_starts_with($key, 'b_')) { if (str_starts_with($key, 'b_')) {
$params[$key] = -1; $params[$key] = -1;
} else { } else {
$params[$key] = null; $params[$key] = null;
} }
} }
} }
$poi->parameters = json_encode($params, JSON_UNESCAPED_UNICODE); $poi->parameters = json_encode($params, JSON_UNESCAPED_UNICODE);
@@ -114,83 +114,93 @@ switch ($controller->splitted_url[1]) {
break; break;
case "api_bbox": case "api_bbox":
// API JSON pour la liste des POIs (carte). // API JSON pour la liste des POIs (carte).
header("Content-Type: application/json; charset=utf-8"); header("Content-Type: application/json; charset=utf-8");
$north = (float)$_GET['north']; $north = (float)$_GET['north'];
$south = (float)$_GET['south']; $south = (float)$_GET['south'];
$east = (float)$_GET['east']; $east = (float)$_GET['east'];
$west = (float)$_GET['west']; $west = (float)$_GET['west'];
$pois = new Kabano\Pois(); $pois = new Kabano\Pois();
$pois->listPoisBBOX( $pois->listPoisBBOX(
$north, $north,
$south, $south,
$east, $east,
$west, $west,
$user->rankIsHigher("premium") ? 1 : 0); $user->rankIsHigher("premium") ? 1 : 0);
$out = []; $out = [];
foreach ($pois->objs as $poi) { foreach ($pois->objs as $poi) {
$out[] = [ $out[] = [
"id" => $poi->content_id, "id" => $poi->content_id,
"name" => $poi->name, "name" => $poi->name,
"lat" => floatval($poi->lat), "lat" => floatval($poi->lat),
"lon" => floatval($poi->lon), "lon" => floatval($poi->lon),
"type" => $poi->poi_type, "type" => $poi->poi_type,
"permalink" => $poi->permalink "permalink" => $poi->permalink
]; ];
} }
echo json_encode($out, JSON_UNESCAPED_UNICODE); echo json_encode($out, JSON_UNESCAPED_UNICODE);
break; break;
case "tile": case "tile":
$z = intval($controller->splitted_url[2]); $z = intval($controller->splitted_url[2]);
$x = intval($controller->splitted_url[3]); $x = intval($controller->splitted_url[3]);
$y = intval(str_replace(".pbf", "", $controller->splitted_url[4])); $y = intval(str_replace(".pbf", "", $controller->splitted_url[4]));
$cacheRoot = $config['public_folder'].'/cache/tiles'; $cacheRoot = $config['public_folder'] . '/cache/tiles';
$cacheDir = $cacheRoot . '/' . $z . '/' . $x; $cacheDir = $cacheRoot . '/' . $z . '/' . $x;
$cacheFile = $cacheDir . '/' . $y . '.pbf'; $cacheFile = $cacheDir . '/' . $y . '.pbf';
// Cache hit // Cache hit
if (is_file($cacheFile)) { if (is_file($cacheFile)) {
header('Content-Type: application/x-protobuf'); header('Content-Type: application/x-protobuf');
header('Cache-Control: public, max-age=31536000, immutable'); header('Cache-Control: public, max-age=31536000, immutable');
header('X-Cache: HIT'); header('X-Cache: HIT');
readfile($cacheFile); readfile($cacheFile);
exit; exit;
} }
// Cache miss : on génère une fois // Création du dossier si nécessaire
$pois = new Kabano\Pois(); if (!is_dir($cacheDir)) {
if (!@mkdir($cacheDir, 0777, true) && !is_dir($cacheDir)) {
http_response_code(500);
exit('Tile cache directory not writable');
}
}
try { if (!is_writable($cacheDir)) {
$tile = $pois->getVectorTile($z, $x, $y); http_response_code(500);
} catch (Exception $e) { exit('Tile cache directory is not writable');
http_response_code(500); }
echo 'Tile generation failed: ' . $e->getMessage();
exit;
}
if (!is_dir($cacheDir)) { $pois = new Kabano\Pois();
mkdir($cacheDir, 0777, true);
}
$tmp = $cacheFile . '.tmp'; try {
file_put_contents($tmp, $tile); $tile = $pois->getVectorTile($z, $x, $y);
} catch (Exception $e) {
http_response_code(500);
echo 'Tile generation failed: ' . $e->getMessage();
exit;
}
if (file_exists($tmp)) { $tmp = $cacheDir . '/' . uniqid('tile_', true) . '.pbf.tmp';
rename($tmp, $cacheFile);
}
header('Content-Type: application/x-protobuf'); if (file_put_contents($tmp, $tile) === false) {
header('Cache-Control: public, max-age=31536000, immutable'); http_response_code(500);
header('X-Cache: MISS'); exit('Unable to write tile cache');
echo $tile; }
break;
rename($tmp, $cacheFile);
header('Content-Type: application/x-protobuf');
header('Cache-Control: public, max-age=31536000, immutable');
header('X-Cache: MISS');
echo $tile;
break;
default: default:
// Affichage / édition / suppression d’un POI // Affichage / édition / suppression d’un POI
@@ -224,34 +234,34 @@ switch ($controller->splitted_url[1]) {
foreach ($definition as $key => $label) { foreach ($definition as $key => $label) {
if (isset($_POST[$key])) { if (isset($_POST[$key])) {
$value = $_POST[$key]; $value = $_POST[$key];
if (str_starts_with($key, 'b_')) { if (str_starts_with($key, 'b_')) {
if ($value === "0" || $value === "1" || $value === "2") { if ($value === "0" || $value === "1" || $value === "2") {
$params[$key] = intval($value); $params[$key] = intval($value);
} else { } else {
$params[$key] = -1; $params[$key] = -1;
} }
}
elseif (str_starts_with($key, 'n_')) {
$params[$key] = is_numeric($value) ? (0 + $value) : null;
}
elseif (str_starts_with($key, 't_') || str_starts_with($key, 'l_')) {
$params[$key] = trim($value);
}
else {
$params[$key] = $value;
} }
elseif (str_starts_with($key, 'n_')) {
$params[$key] = is_numeric($value) ? (0 + $value) : null;
}
elseif (str_starts_with($key, 't_') || str_starts_with($key, 'l_')) {
$params[$key] = trim($value);
}
else {
$params[$key] = $value;
}
} else { } else {
// Champ absent → booléen = -1 (non renseigné) // Champ absent → booléen = -1 (non renseigné)
if (str_starts_with($key, 'b_')) { if (str_starts_with($key, 'b_')) {
$params[$key] = -1; $params[$key] = -1;
} else { } else {
$params[$key] = null; $params[$key] = null;
} }
} }
} }
$poi->parameters = json_encode($params, JSON_UNESCAPED_UNICODE); $poi->parameters = json_encode($params, JSON_UNESCAPED_UNICODE);
@@ -292,64 +302,64 @@ switch ($controller->splitted_url[1]) {
if (!empty($_FILES['photo']['tmp_name'])) { if (!empty($_FILES['photo']['tmp_name'])) {
$tmp = $_FILES['photo']['tmp_name']; $tmp = $_FILES['photo']['tmp_name'];
$info = getimagesize($tmp); $info = getimagesize($tmp);
if ($info === false) { if ($info === false) {
die("Fichier non valide"); die("Fichier non valide");
} }
$mime = $info['mime']; $mime = $info['mime'];
switch ($mime) { switch ($mime) {
case 'image/jpeg': case 'image/jpeg':
$src = imagecreatefromjpeg($tmp); $src = imagecreatefromjpeg($tmp);
break; break;
case 'image/png': case 'image/png':
$src = imagecreatefrompng($tmp); $src = imagecreatefrompng($tmp);
break; break;
case 'image/webp': case 'image/webp':
$src = imagecreatefromwebp($tmp); $src = imagecreatefromwebp($tmp);
break; break;
default: default:
die("Format non supporté"); die("Format non supporté");
} }
$width = imagesx($src); $width = imagesx($src);
$height = imagesy($src); $height = imagesy($src);
// Taille max // Taille max
$max = 1500; $max = 1500;
$ratio = min($max / $width, $max / $height, 1); $ratio = min($max / $width, $max / $height, 1);
$newWidth = (int)($width * $ratio); $newWidth = (int)($width * $ratio);
$newHeight = (int)($height * $ratio); $newHeight = (int)($height * $ratio);
$dst = imagecreatetruecolor($newWidth, $newHeight); $dst = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height); imagecopyresampled($dst, $src, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
// --- Watermark --- // --- Watermark ---
$watermarkPath = $config['medias_folder'] . '/watermark.png'; $watermarkPath = $config['medias_folder'] . '/watermark.png';
if (file_exists($watermarkPath)) { if (file_exists($watermarkPath)) {
$wm = imagecreatefrompng($watermarkPath); $wm = imagecreatefrompng($watermarkPath);
imagealphablending($wm, true); imagealphablending($wm, true);
imagesavealpha($wm, true); imagesavealpha($wm, true);
$wmWidth = imagesx($wm); $wmWidth = imagesx($wm);
$wmHeight = imagesy($wm); $wmHeight = imagesy($wm);
$x = $newWidth - $wmWidth - 20; $x = $newWidth - $wmWidth - 20;
$y = 20; $y = 20;
// Fusion // Fusion
imagecopy($dst, $wm, $x, $y, 0, 0, $wmWidth, $wmHeight); imagecopy($dst, $wm, $x, $y, 0, 0, $wmWidth, $wmHeight);
} }
$filename = uniqid('comment_') . '.jpg'; $filename = uniqid('comment_') . '.jpg';
$destination = $config['medias_folder'] . 'comment_photos/' . $filename; $destination = $config['medias_folder'] . 'comment_photos/' . $filename;
imagejpeg($dst, $destination, 70); imagejpeg($dst, $destination, 70);
$Comment->photo = $filename; $Comment->photo = $filename;
} }
$Comment->insert(); $Comment->insert();