L A T T I S B O I S
lattis-bois

Model de HTML à Inclure dans le site : ctiouest.fr/claustra-bois-lattis

EXEMPLE DANS L'IFRAME CI-DESSOUS: Voir sans iframe

CODE PHP


<?php
//13-02-2026
/*
Lecture d'une page externe, cache local + fallback si indisponible
- Récupère https://facon-lattis.ctiouest.pro/include_ctiouest.php
- Sauvegarde en local
- Si le contenu distant change => met à jour le cache
- Si lecture distante impossible => affiche le cache
- Affiche le contenu (distant ou cache)
*/

$url = "https://facon-lattis.ctiouest.pro/include_ctiouest.php";

/* Emplacement cache (dans le même dossier que ce fichier) */
$cache_dir  = __DIR__ . "/cache_ext";
$cache_file = $cache_dir . "/include_ctiouest.cache.html";
$meta_file  = $cache_dir . "/include_ctiouest.cache.meta.json";

/* Crée le dossier si besoin */
if (!is_dir($cache_dir)) {
    @mkdir($cache_dir, 0755, true);
}

/* Lire un fichier local proprement */
function read_local_file($path) {
    if (!is_file($path)) return "";
    $c = @file_get_contents($path);
    if ($c === false) return "";
    return $c;
}

/* Écrire atomiquement (évite fichier partiel) */
function write_atomic($path, $content) {
    $dir = dirname($path);
    if (!is_dir($dir)) return false;

    $tmp = $path . ".tmp_" . uniqid("", true);
    $ok = @file_put_contents($tmp, $content, LOCK_EX);
    if ($ok === false) {
        @unlink($tmp);
        return false;
    }
    if (!@rename($tmp, $path)) {
        @unlink($tmp);
        return false;
    }
    return true;
}

/* Récupérer distant via cURL (robuste) */
function fetch_remote($url) {
    if (!function_exists("curl_init")) {
        return array("ok" => false, "status" => 0, "body" => "", "err" => "cURL non disponible");
    }

    $ch = curl_init();
    curl_setopt_array($ch, array(
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_MAXREDIRS => 5,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_TIMEOUT => 10,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_SSL_VERIFYHOST => 2,
        CURLOPT_USERAGENT => "CTI-Ouest CacheFetcher/1.0",
        CURLOPT_HTTPHEADER => array(
            "Accept: text/html, */*;q=0.8",
            "Cache-Control: no-cache",
            "Pragma: no-cache"
        ),
    ));

    $body = curl_exec($ch);
    $err  = curl_error($ch);
    $code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($body === false || $body === null) {
        return array("ok" => false, "status" => $code, "body" => "", "err" => $err);
    }

    // On considère OK uniquement si 200
    if ($code !== 200) {
        return array("ok" => false, "status" => $code, "body" => (string)$body, "err" => "HTTP $code");
    }

    return array("ok" => true, "status" => $code, "body" => (string)$body, "err" => "");
}

/* Charge cache actuel */
$cached_body = read_local_file($cache_file);
$cached_hash = $cached_body !== "" ? hash("sha256", $cached_body) : "";

$meta = array();
$meta_json = read_local_file($meta_file);
if ($meta_json !== "") {
    $tmp = json_decode($meta_json, true);
    if (is_array($tmp)) $meta = $tmp;
}

/* Tente lecture distante */
$remote = fetch_remote($url);

$final_body = "";
$source = "cache"; // ou "remote"
$updated = false;

if ($remote["ok"]) {
    $remote_body = $remote["body"];

    // Si vide => on traite comme erreur (option)
    if ($remote_body === "") {
        // fallback cache
        if ($cached_body !== "") {
            $final_body = $cached_body;
            $source = "cache";
        } else {
            $final_body = "<!-- contenu distant vide et pas de cache -->";
            $source = "none";
        }
    } else {
        $remote_hash = hash("sha256", $remote_body);

        // Mise à jour seulement si différent ou cache absent
        if ($remote_hash !== $cached_hash) {
            $ok1 = write_atomic($cache_file, $remote_body);

            $meta = array(
                "url" => $url,
                "updated_at" => date("c"),
                "sha256" => $remote_hash,
                "http_status" => $remote["status"]
            );
            $ok2 = write_atomic($meta_file, json_encode($meta, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));

            $updated = ($ok1 && $ok2);
            // Même si l'écriture rate, on peut afficher le distant
        }

        $final_body = $remote_body;
        $source = "remote";
    }
} else {
    // Impossible de lire => on utilise la sauvegarde
    if ($cached_body !== "") {
        $final_body = $cached_body;
        $source = "cache";
    } else {
        $final_body = "<!-- impossible de lire $url et aucun cache local -->";
        $source = "none";
    }
}


/* Debug (à commenter en prod) */
/*
echo "<!-- source=$source updated=".($updated?1:0)." status=".$remote["status"]." err=".htmlspecialchars($remote["err"])." -->\n";
*/

echo $final_body;
 ?>