prepare(" INSERT INTO owners (name, address, phone, email, username, password_hash) VALUES (?, ?, ?, ?, ?, ?) "); $stmt->execute([ $_POST['name'], $_POST['address'], $_POST['phone'], $_POST['email'], $_POST['username'], password_hash($_POST['password'], PASSWORD_DEFAULT) ]); $_SESSION['owner_id'] = $db->lastInsertId(); redirect('edit'); } catch (PDOException $e) { $error = "Nom d'utilisateur déjà pris."; $action = 'register'; } } /* ---------- CONNEXION ---------- */ if ($action === 'do_login' && $_SERVER['REQUEST_METHOD'] === 'POST') { $stmt = $db->prepare("SELECT * FROM owners WHERE username=?"); $stmt->execute([$_POST['username']]); $owner = $stmt->fetch(PDO::FETCH_ASSOC); if ($owner && password_verify($_POST['password'], $owner['password_hash'])) { $_SESSION['owner_id'] = $owner['id']; redirect('edit'); } else { $error = "Identifiants incorrects."; $action = 'login'; } } /* ---------- DÉCONNEXION ---------- */ if ($action === 'logout') { session_destroy(); redirect('home'); } /* ---------- SAUVEGARDE MATERIEL (prix numérique + prix libre) ---------- */ if ($action === 'save_item' && $_SERVER['REQUEST_METHOD'] === 'POST' && is_logged()) { // Prix numérique obligatoire $price = floatval($_POST['price']); if ($price <= 0) { $error = "Le prix doit être un nombre positif."; $action = 'edit'; } // Prix libre ? $price_free = isset($_POST['price_free']) ? "free" : ""; $price_value = $price_free ? "$price|free" : "$price"; // Upload photo $photo = null; if (!empty($_FILES['photo']['name'])) { $photo = time() . "_" . basename($_FILES['photo']['name']); move_uploaded_file($_FILES['photo']['tmp_name'], "uploads/" . $photo); } // UPDATE if (!empty($_POST['id'])) { if ($photo) { $stmt = $db->prepare("UPDATE items SET name=?, price=?, description=?, photo=?, category=? WHERE id=? AND owner_id=?"); $stmt->execute([ $_POST['name'], $price_value, $_POST['description'], $photo, $_POST['category'], $_POST['id'], $_SESSION['owner_id'] ]); } else { $stmt = $db->prepare("UPDATE items SET name=?, price=?, description=?, category=? WHERE id=? AND owner_id=?"); $stmt->execute([ $_POST['name'], $price_value, $_POST['description'], $_POST['category'], $_POST['id'], $_SESSION['owner_id'] ]); } // INSERT } else { $stmt = $db->prepare("INSERT INTO items (name, price, description, photo, owner_id, category) VALUES (?, ?, ?, ?, ?, ?)"); $stmt->execute([ $_POST['name'], $price_value, $_POST['description'], $photo, $_SESSION['owner_id'], $_POST['category'] ]); } redirect('edit'); } /* ---------- SUPPRESSION MATERIEL ---------- */ if ($action === 'delete_item' && is_logged()) { $stmt = $db->prepare("DELETE FROM items WHERE id=? AND owner_id=?"); $stmt->execute([$_GET['id'], $_SESSION['owner_id']]); redirect('edit'); } /* ---------- GENERATION STATISTIQUES ---------- */ if ($action === 'admin_generate_stats') { // Sécurité : seul toi (ID=1) if (!isset($_SESSION['owner_id']) || $_SESSION['owner_id'] != 1) { echo "

Accès refusé.

"; exit; } // Emplacement du rapport généré $report = __DIR__ . "/stats.html"; // Récupérer tous les logs gzip $gz_files = glob('/var/log/nginx/materiel.kabano.org-access.log*.gz'); // Construire la commande $cmd = "/bin/bash -c '("; // 1. Logs compressés if (!empty($gz_files)) { $cmd .= "zcat " . implode(' ', array_map('escapeshellarg', $gz_files)) . " ; "; } // 2. Log d’hier if (file_exists('/var/log/nginx/materiel.kabano.org-access.log.1')) { $cmd .= "cat /var/log/nginx/materiel.kabano.org-access.log.1 ; "; } // 3. Log du jour $cmd .= "cat /var/log/nginx/materiel.kabano.org-access.log"; $cmd .= ") | goaccess --log-format=COMBINED --no-progress -o " . escapeshellarg($report) . " -' 2>&1"; // Exécuter $output = shell_exec($cmd); // Vérifier si le fichier a été généré if (!file_exists($report)) { echo "

Erreur lors de la génération du rapport

"; echo "
$output
"; exit; } // Redirection vers le rapport header("Location: stats.html"); exit; } /* ---------- SUPPRESSION PHOTO MATERIEL ---------- */ if ($action === 'delete_photo' && is_logged()) { // Récupérer le matériel $stmt = $db->prepare("SELECT photo FROM items WHERE id=? AND owner_id=?"); $stmt->execute([$_GET['id'], $_SESSION['owner_id']]); $item = $stmt->fetch(PDO::FETCH_ASSOC); if ($item && !empty($item['photo'])) { $file = "uploads/" . $item['photo']; if (file_exists($file)) { unlink($file); } // Mettre la colonne photo à NULL $stmt = $db->prepare("UPDATE items SET photo=NULL WHERE id=? AND owner_id=?"); $stmt->execute([$_GET['id'], $_SESSION['owner_id']]); } redirect('edit_item&id=' . $_GET['id']); } /* ---------- MODIFICATION PROFIL ---------- */ if ($action === 'save_profile' && $_SERVER['REQUEST_METHOD'] === 'POST' && is_logged()) { $params = [ $_POST['name'], $_POST['address'], $_POST['phone'], $_POST['email'], $_POST['username'] ]; $sql = "UPDATE owners SET name=?, address=?, phone=?, email=?, username=?"; if (!empty($_POST['password'])) { $sql .= ", password_hash=?"; $params[] = password_hash($_POST['password'], PASSWORD_DEFAULT); } $sql .= " WHERE id=?"; $params[] = $_SESSION['owner_id']; $stmt = $db->prepare($sql); $stmt->execute($params); $success = "Profil mis à jour."; $action = 'profile'; } ?> Location de matériel

Matériel partagé à Durban-sur-Arize Blason de Durban-sur-Arize


Personnaliser les indications de prix libre selon mon revenu mensuel : €/mois
L'objectif du site est de mettre en relation des emprunteur·ses et loueur·ses avec des propriétaires de matériel. Des tarifs peuvent être indiqués, ils restent avant tout indicatifs afin d’éviter les malaises et de poser une base aux discussions. L’essentiel est de privilégier la discussion, la confiance, les arrangements et l'entraide. L'idée n'est pas de faire une grande publicité pour cet outil de partage, mais de le garder à petite échelle, localement, autour de valeurs de solidarité et de proximité. N'hésitez pas à être le plus clair possible dès le début sur les issues d'une casse.
Rechercher un matériel :
query(" SELECT items.*, owners.name AS owner_name, owners.phone, owners.address, owners.email FROM items JOIN owners ON owners.id = items.owner_id ORDER BY items.category COLLATE NOCASE ASC, items.name COLLATE NOCASE ASC ")->fetchAll(PDO::FETCH_ASSOC); foreach ($items as $item) { // Décodage du prix $price_raw = $item['price'] ?? ''; $price_parts = explode('|', $price_raw); $price_value = floatval($price_parts[0]); $price_free = isset($price_parts[1]) && $price_parts[1] === 'free'; $search_text = strtolower( ($item['name'] ?? '') . ' ' . ($item['description'] ?? '') ); echo "
"; echo "
"; // Photo if (!empty($item['photo'])) { echo "Photo"; } else { echo "
🛠️
"; } echo "
"; echo "

" . htmlspecialchars($item['name'] ?? '') . "

"; echo "

Catégorie : " . htmlspecialchars($item['category']) . "

"; // Prix echo "

"; echo "Prix : {$price_value} € / jour"; if ($price_free) echo " (prix libre)"; echo "

"; // Description echo "

" . nl2br(htmlspecialchars($item['description'] ?? '')) . "

"; // Propriétaire echo "
"; echo "Propriétaire : " . htmlspecialchars($item['owner_name'] ?? '') . "
"; // Adresse $addr = urlencode($item['address'] ?? ''); echo htmlspecialchars($item['address'] ?? '')."
"; // Téléphone → tel: echo "" . htmlspecialchars($item['phone'] ?? '') . "
"; // Email → mailto: echo "" . htmlspecialchars($item['email'] ?? '') . ""; echo "
"; // owner-block echo "
"; // tool-info echo "
"; // tool-row echo "
"; } } /* ============================================================ VUE : CONNEXION ============================================================ */ if ($action === 'login') { echo "

Connexion

"; if (!empty($error)) echo "

$error

"; ?>
Inscription"; if (!empty($error)) echo "

$error

"; ?>
Toutes les coordonnées indiquées ici seront affichées publiquement.

query("SELECT id, name, email FROM owners ORDER BY id ASC")->fetchAll(PDO::FETCH_ASSOC); ?>

Administration — Utilisateurs

ID Nom Email

Statistiques

🔄 Générer le rapport GoAccess

prepare("SELECT * FROM owners WHERE id=?"); $stmt->execute([$_SESSION['owner_id']]); $owner = $stmt->fetch(PDO::FETCH_ASSOC); echo "

Mon profil

"; if (!empty($success)) echo "

$success

"; ?>
Toutes les coordonnées indiquées ici seront affichées publiquement.

prepare("SELECT * FROM items WHERE id=? AND owner_id=?"); $stmt->execute([$_GET['id'], $_SESSION['owner_id']]); $item = $stmt->fetch(PDO::FETCH_ASSOC); if (!$item) { echo "

Matériel introuvable.

"; } else { // Décodage du prix $price_raw = $item['price'] ?? ''; $price_parts = explode('|', $price_raw); $price_value = floatval($price_parts[0]); $price_free = isset($price_parts[1]) && $price_parts[1] === 'free'; echo "

Modifier le matériel

"; ?>

Le prix libre conseillé sera ajusté selon le revenu de l’utilisateur. Prix saisi pour le revenu médian de 1900€.



Supprimer la photo
🛠️


Mes matériels"; ?>

➕ Ajouter un matériel

prepare("SELECT * FROM items WHERE owner_id=? ORDER BY category COLLATE NOCASE ASC, name COLLATE NOCASE ASC "); $stmt->execute([$_SESSION['owner_id']]); $items = $stmt->fetchAll(PDO::FETCH_ASSOC); echo "

Mes matériels existants

"; foreach ($items as $item) { // Décodage du prix $price_raw = $item['price'] ?? ''; $price_parts = explode('|', $price_raw); $price_value = floatval($price_parts[0]); $price_free = isset($price_parts[1]) && $price_parts[1] === 'free'; echo "
"; echo "
"; // Photo if (!empty($item['photo'])) { echo "Photo"; } else { echo "
🛠️
"; } echo "
"; echo "

" . htmlspecialchars($item['name'] ?? '') . "

"; echo "

Catégorie : " . htmlspecialchars($item['category']) . "

"; echo "

Prix : {$price_value} € / jour"; if ($price_free) echo " (prix libre)"; echo "

"; echo "

" . nl2br(htmlspecialchars($item['description'] ?? '')) . "

"; echo ""; echo "
"; // tool-info echo "
"; // tool-row echo "
"; } } ?>