This commit is contained in:
2026-01-21 10:29:37 +01:00
parent dda63d9711
commit 7f7dff32d9
17 changed files with 1885 additions and 521 deletions
+337 -183
View File
@@ -1,42 +1,72 @@
<?php
// Forza la visualizzazione degli errori
// teacher_profile.php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
include('include/headscript.php');
// Importa la libreria QR Code
// QR Code library
require_once __DIR__ . '/../../vendor/autoload.php';
use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\Writer\PngWriter;
// Connessione al database
$dbHandler = DBHandlerSelect::getInstance();
$pdo = $dbHandler->getConnection();
// ID dell'utente loggato (assumiamo sia definito)
if (!isset($iduserlogin)) {
die("Errore: ID utente non definito.");
}
// Recupera i dati dell'insegnante
$stmt = $pdo->prepare("
SELECT t.*, u.first_name, u.last_name, u.email
FROM auth_users u
LEFT JOIN teachers t ON t.user_id = u.id
WHERE u.id = ?
");
$stmt->execute([$iduserlogin]);
$teacher = $stmt->fetch();
$teacher_id = (int)($_GET['id'] ?? 0);
$is_owner_view = ($teacher_id > 0); // se arrivi da teacher_list.php con ?id=...
if (!$teacher) {
die("Errore: Utente non trovato.");
if ($teacher_id > 0) {
// === OWNER VIEW: carica teacher per teachers.id SOLO se l'owner ha diritto ===
$stmt = $pdo->prepare("
SELECT
t.*,
u.first_name, u.last_name, u.email
FROM teachers t
JOIN auth_users u ON t.user_id = u.id
JOIN teacher_schools ts ON ts.teacher_id = t.id
JOIN schools s ON s.id = ts.school_id
WHERE t.id = ?
AND s.owner_id = ?
LIMIT 1
");
$stmt->execute([$teacher_id, $iduserlogin]);
$teacher = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$teacher) {
die("Errore: insegnante non trovata o non hai permessi.");
}
} else {
// === TEACHER SELF VIEW: carica il profilo dell'utente loggato ===
$stmt = $pdo->prepare("
SELECT
t.*,
u.first_name, u.last_name, u.email
FROM auth_users u
LEFT JOIN teachers t ON t.user_id = u.id
WHERE u.id = ?
LIMIT 1
");
$stmt->execute([$iduserlogin]);
$teacher = $stmt->fetch(PDO::FETCH_ASSOC);
}
// Determina se è un nuovo insegnante
$is_new = !isset($teacher['id']);
$is_new = empty($teacher['id']); // ok così
if ($teacher_id > 0) {
$is_new = false; // owner sta editando una teacher esistente
}
if ($is_new) {
$teacher = [
'id' => null,
@@ -49,267 +79,351 @@ if ($is_new) {
'status' => 'active',
'created_at' => '',
'updated_at' => '',
'first_name' => $teacher['first_name'],
'last_name' => $teacher['last_name'],
'email' => $teacher['email']
'first_name' => '',
'last_name' => '',
'email' => ''
];
}
// Funzione per generare un codice univoco
function generateUniqueCode($pdo, $length = 16)
{
do {
$code = bin2hex(random_bytes($length / 2));
$stmt = $pdo->prepare("SELECT COUNT(*) FROM teachers WHERE unique_code = ?");
$stmt->execute([$code]);
$count = $stmt->fetchColumn();
} while ($count > 0);
} while ($stmt->fetchColumn() > 0);
return $code;
}
// Generazione del QR Code
$qr_code_path = null;
if (!$is_new) {
try {
$unique_code = $teacher['unique_code'];
if (empty($unique_code)) {
throw new Exception("Errore: unique_code è vuoto.");
function writeQrPng($text, $filename, $size = 150, $margin = 10)
{
// ✅ nella tua versione il costruttore vuole il testo
$qrCode = new \Endroid\QrCode\QrCode($text);
// size: alcune versioni hanno setSize(), altre setModuleSize()
if (method_exists($qrCode, 'setSize')) {
$qrCode->setSize($size);
} elseif (method_exists($qrCode, 'setModuleSize')) {
$module = max(3, (int)round($size / 25)); // mapping semplice
$qrCode->setModuleSize($module);
}
// margin: alcune versioni setMargin(), altre setPadding()
if (method_exists($qrCode, 'setMargin')) {
$qrCode->setMargin($margin);
} elseif (method_exists($qrCode, 'setPadding')) {
$qrCode->setPadding($margin);
}
$writer = new \Endroid\QrCode\Writer\PngWriter();
if (method_exists($writer, 'writeFile')) {
$writer->writeFile($qrCode, $filename);
} else {
$result = $writer->write($qrCode);
if (is_object($result) && method_exists($result, 'saveToFile')) {
$result->saveToFile($filename);
} else {
file_put_contents($filename, (string)$result);
}
$base_dir = __DIR__ . '/../../public/userarea/phototeachers/qrcodes/';
$qr_code_filename = "{$base_dir}{$iduserlogin}-{$unique_code}.png";
$qr_code_path = "phototeachers/qrcodes/{$iduserlogin}-{$unique_code}.png";
if (!file_exists($qr_code_filename)) {
if (!is_dir($base_dir)) {
mkdir($base_dir, 0755, true) or die("Errore: Impossibile creare la directory.");
}
if (!is_writable($base_dir)) {
die("Errore: La directory non è scrivibile.");
}
$builder = new Builder();
$result = $builder->build(
writer: new PngWriter(),
data: $unique_code,
size: 150,
margin: 10
);
$result->saveToFile($qr_code_filename);
}
} catch (Exception $e) {
$error = "Errore generazione QR Code: " . $e->getMessage();
error_log($error);
}
}
// Gestione del form
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$first_name = $_POST['first_name'];
$last_name = $_POST['last_name'];
$phone = $_POST['phone'] ?? null;
$description = $_POST['description'] ?? null;
$specializations = $_POST['specializations'] ?? null;
$status = $_POST['status'] === 'active' ? 'active' : 'inactive';
// Gestione del caricamento della foto
$profile_picture = $teacher['profile_picture'];
if (isset($_FILES['profile_picture']) && $_FILES['profile_picture']['error'] === UPLOAD_ERR_OK) {
$file = $_FILES['profile_picture'];
$timestamp = time();
$original_name = basename($file['name']);
$extension = strtolower(pathinfo($original_name, PATHINFO_EXTENSION));
$allowed_extensions = ['jpg', 'jpeg', 'png', 'gif'];
if (in_array($extension, $allowed_extensions)) {
$new_filename = "phototeachers/{$iduserlogin}-{$timestamp}-{$original_name}";
if (move_uploaded_file($file['tmp_name'], $new_filename)) {
$profile_picture = $new_filename;
if ($teacher['profile_picture'] && file_exists($teacher['profile_picture']) && !$is_new) {
unlink($teacher['profile_picture']);
}
} else {
$error = "Errore durante il caricamento della foto.";
}
} else {
$error = "Estensione del file non consentita. Usa JPG, JPEG, PNG o GIF.";
$qr_code_path = null;
if (!$is_new && !empty($teacher['unique_code'])) {
try {
$unique_code = $teacher['unique_code'];
$base_dir = __DIR__ . '/../../public/phototeachers/qrcodes/';
$qr_filename = "{$base_dir}{$iduserlogin}-{$unique_code}.png";
$qr_code_path = "phototeachers/qrcodes/{$iduserlogin}-{$unique_code}.png";
if (!file_exists($qr_filename)) {
if (!is_dir($base_dir)) mkdir($base_dir, 0755, true);
writeQrPng($unique_code, $qr_filename, 150, 10);
}
} catch (Exception $e) {
error_log("Errore QR: " . $e->getMessage());
}
}
$success_message = $error = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// ✅ target: se owner sta editando una teacher (?id=..), salva su QUELLA teacher
$target_user_id = ($teacher_id > 0) ? (int)$teacher['user_id'] : (int)$iduserlogin;
$target_teacher_id = ($teacher_id > 0) ? (int)$teacher['id'] : (int)($teacher['id'] ?? 0);
$first_name = trim($_POST['first_name'] ?? '');
$last_name = trim($_POST['last_name'] ?? '');
$phone = trim($_POST['phone'] ?? '');
$description = trim($_POST['description'] ?? '');
$specializations = trim($_POST['specializations'] ?? '');
$status = ($_POST['status'] ?? 'active') === 'active' ? 'active' : 'inactive';
$target_user_id = ($teacher_id > 0) ? (int)$teacher['user_id'] : (int)$iduserlogin;
// Aggiorna auth_users
$stmt = $pdo->prepare("UPDATE auth_users SET first_name = ?, last_name = ? WHERE id = ?");
$stmt->execute([$first_name, $last_name, $iduserlogin]);
$stmt->execute([$first_name, $last_name, $target_user_id]);
$profile_picture = $teacher['profile_picture'] ?? '';
if (!empty($_FILES['profile_picture']['name']) && $_FILES['profile_picture']['error'] === UPLOAD_ERR_OK) {
$ext = strtolower(pathinfo($_FILES['profile_picture']['name'], PATHINFO_EXTENSION));
if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif'])) {
$new_name = "phototeachers/{$target_user_id}-" . time() . "-profile.$ext";
if (move_uploaded_file($_FILES['profile_picture']['tmp_name'], $new_name)) {
if ($profile_picture && file_exists($profile_picture) && !$is_new) @unlink($profile_picture);
$profile_picture = $new_name;
} else $error = "Errore caricamento foto.";
} else $error = "Solo JPG, PNG, GIF ammessi.";
}
if ($is_new) {
$unique_code = generateUniqueCode($pdo);
$stmt = $pdo->prepare("
INSERT INTO teachers (user_id, unique_code, phone, description, specializations, profile_picture, status)
INSERT INTO teachers
(user_id, unique_code, phone, description, specializations, profile_picture, status)
VALUES (?, ?, ?, ?, ?, ?, ?)
");
$success = $stmt->execute([$iduserlogin, $unique_code, $phone, $description, $specializations, $profile_picture, $status]);
$success = $stmt->execute([$target_user_id, $unique_code, $phone ?: null, $description, $specializations, $profile_picture, $status]);
if ($success) {
$success_message = "Insegnante creato con successo!";
$stmt = $pdo->prepare("
SELECT t.*, u.first_name, u.last_name, u.email
FROM auth_users u
LEFT JOIN teachers t ON t.user_id = u.id
WHERE u.id = ?
");
$success_message = "Profilo creato!";
$stmt = $pdo->prepare("SELECT t.*, u.first_name, u.last_name, u.email
FROM teachers t JOIN auth_users u ON t.user_id = u.id
WHERE t.user_id = ?");
$stmt->execute([$iduserlogin]);
$teacher = $stmt->fetch();
$teacher = $stmt->fetch(PDO::FETCH_ASSOC);
$is_new = false;
// Genera QR Code per il nuovo insegnante
try {
$base_dir = __DIR__ . '/../../public/phototeachers/qrcodes/';
$qr_code_filename = "{$base_dir}{$iduserlogin}-{$unique_code}.png";
$qr_filename = "{$base_dir}{$iduserlogin}-{$unique_code}.png";
$qr_code_path = "phototeachers/qrcodes/{$iduserlogin}-{$unique_code}.png";
if (!file_exists($qr_code_filename)) {
if (!is_dir($base_dir)) {
mkdir($base_dir, 0755, true) or die("Errore: Impossibile creare la directory.");
if (!file_exists($qr_filename)) {
if (!is_dir($base_dir)) mkdir($base_dir, 0755, true);
$writer = new PngWriter();
if (!file_exists($qr_filename)) {
if (!is_dir($base_dir)) mkdir($base_dir, 0755, true);
writeQrPng($unique_code, $qr_filename, 150, 10);
}
$builder = new Builder();
$result = $builder->build(
writer: new PngWriter(),
data: $unique_code,
size: 150,
margin: 10
);
$result->saveToFile($qr_code_filename);
$result = $writer->write($qrCode);
$result->saveToFile($qr_filename);
}
} catch (Exception $e) {
$error = "Errore generazione QR Code: " . $e->getMessage();
error_log($error);
error_log("Errore QR: " . $e->getMessage());
}
} else {
$error = "Errore durante la creazione dell'insegnante.";
}
} else $error = "Errore creazione.";
} else {
$stmt = $pdo->prepare("
UPDATE teachers
SET phone = ?, description = ?, specializations = ?, profile_picture = ?, status = ?
WHERE user_id = ?
");
$success = $stmt->execute([$phone, $description, $specializations, $profile_picture, $status, $iduserlogin]);
$success = $stmt->execute([$phone ?: null, $description, $specializations, $profile_picture, $status, $target_user_id]);
if ($success) {
$success_message = "Dati aggiornati con successo!";
$stmt = $pdo->prepare("
SELECT t.*, u.first_name, u.last_name, u.email
FROM auth_users u
LEFT JOIN teachers t ON t.user_id = u.id
WHERE u.id = ?
");
$success_message = "Dati aggiornati!";
$stmt = $pdo->prepare("SELECT t.*, u.first_name, u.last_name, u.email
FROM teachers t JOIN auth_users u ON t.user_id = u.id
WHERE t.user_id = ?");
$stmt->execute([$iduserlogin]);
$teacher = $stmt->fetch();
} else {
$error = "Errore durante l'aggiornamento dei dati.";
}
$teacher = $stmt->fetch(PDO::FETCH_ASSOC);
} else $error = "Errore aggiornamento.";
}
}
?>
<!doctype html>
<html lang="en">
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
<title><?php echo $is_new ? 'Crea' : 'Modifica'; ?> Profilo Insegnante</title>
<?php include('cssinclude.php'); ?>
<?php include('siteinfo.php'); ?>
<link href="https://cdn.jsdelivr.net/npm/quill@2.0.2/dist/quill.snow.css" rel="stylesheet" />
<style>
.teacher-photo {
max-width: 100%;
height: auto;
max-height: 260px;
object-fit: contain;
border: 1px solid #dee2e6;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
background: #fff;
padding: 10px;
margin-bottom: 1.5rem;
}
.quill-wrapper {
min-height: 300px;
display: flex;
flex-direction: column;
}
.ql-container {
flex: 1;
font-size: 15px;
border: 1px solid #ced4da;
border-radius: 0 0 0.375rem 0.375rem;
}
.ql-editor {
min-height: 220px;
}
.ql-toolbar {
border-radius: 0.375rem 0.375rem 0 0;
border-color: #ced4da;
}
.form-section {
margin-bottom: 2rem;
}
.form-label {
font-weight: 500;
margin-bottom: 0.5rem;
}
</style>
</head>
<body>
<div class="wrapper">
<?php include('include/navbar.php'); ?>
<?php include('include/topbar.php'); ?>
<div class="page-wrapper">
<div class="page-content">
<div class="card radius-10">
<div class="card-header">
<h6 class="mb-0"><?php echo $is_new ? 'Crea Profilo Insegnante' : 'Profilo Insegnante'; ?></h6>
</div>
<div class="card-body">
<?php if (isset($success_message)): ?>
<div class="alert alert-success" role="alert">
<?php echo $success_message; ?>
<div class="alert alert-success alert-dismissible fade show">
<?php echo htmlspecialchars($success_message); ?>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<?php endif; ?>
<?php if (isset($error)): ?>
<div class="alert alert-danger" role="alert">
<?php echo $error; ?>
<div class="alert alert-danger alert-dismissible fade show">
<?php echo htmlspecialchars($error); ?>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<?php endif; ?>
<form method="POST" enctype="multipart/form-data">
<div class="row">
<div class="col-md-4 text-center">
<div class="mb-3">
<img src="<?php echo $teacher['profile_picture'] ? htmlspecialchars($teacher['profile_picture']) : 'phototeachers/ndphoto.png'; ?>"
alt="Foto Profilo" class="img-fluid rounded-circle" style="width: 150px; height: 150px; object-fit: cover;">
</div>
<div class="mb-3">
<form method="POST" enctype="multipart/form-data" id="teacherForm">
<div class="row g-4">
<!-- Colonna sinistra: foto + QR -->
<div class="col-lg-4 text-center">
<img src="<?php echo $teacher['profile_picture'] ? htmlspecialchars($teacher['profile_picture']) : 'phototeachers/ndphoto.png'; ?>"
alt="Foto Profilo" class="teacher-photo">
<div class="mb-4">
<label for="profile_picture" class="form-label">Carica nuova foto</label>
<input type="file" class="form-control" id="profile_picture" name="profile_picture" accept="image/*">
<input type="file" class="form-control" id="profile_picture" name="profile_picture" accept="image/jpeg,image/png,image/gif">
<small class="text-muted d-block mt-1">Max 2MB JPG, PNG, GIF</small>
</div>
<?php if (!$is_new && $qr_code_path): ?>
<div class="mb-3">
<label class="form-label">Codice Univoco</label>
<input type="text" class="form-control" value="<?php echo htmlspecialchars($teacher['unique_code']); ?>" readonly>
</div>
<div class="mb-3">
<label class="form-label">QR Code</label><br>
<img src="<?php echo htmlspecialchars($qr_code_path); ?>" alt="QR Code" class="img-fluid" style="width: 150px; height: 150px;">
<img src="<?php echo htmlspecialchars($qr_code_path); ?>" alt="QR Code" class="img-fluid shadow-sm" style="max-width: 180px;">
</div>
<?php endif; ?>
</div>
<div class="col-md-8">
<div class="row">
<div class="col-md-6 mb-3">
<!-- Colonna destra: campi organizzati -->
<div class="col-lg-8">
<div class="row g-3">
<div class="col-md-6">
<label for="first_name" class="form-label">Nome</label>
<input type="text" class="form-control" id="first_name" name="first_name" value="<?php echo htmlspecialchars($teacher['first_name']); ?>" required>
<input type="text" class="form-control" id="first_name" name="first_name"
value="<?php echo htmlspecialchars($teacher['first_name'] ?? ''); ?>" required>
</div>
<div class="col-md-6 mb-3">
<div class="col-md-6">
<label for="last_name" class="form-label">Cognome</label>
<input type="text" class="form-control" id="last_name" name="last_name" value="<?php echo htmlspecialchars($teacher['last_name']); ?>" required>
<input type="text" class="form-control" id="last_name" name="last_name"
value="<?php echo htmlspecialchars($teacher['last_name'] ?? ''); ?>" required>
</div>
<div class="col-12">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" name="email"
value="<?php echo htmlspecialchars($teacher['email'] ?? ''); ?>" readonly>
</div>
<div class="col-md-6">
<label for="phone" class="form-label">Telefono</label>
<input type="tel" class="form-control" id="phone" name="phone"
value="<?php echo htmlspecialchars($teacher['phone'] ?? ''); ?>">
</div>
<!-- Editor descrizione -->
<div class="col-12 form-section">
<label class="form-label">Descrizione insegnante</label>
<div class="quill-wrapper">
<div id="quill-editor"></div>
</div>
<input type="hidden" name="description" id="description-hidden">
</div>
<!-- Specializzazioni -->
<div class="col-12 form-section">
<label for="specializations" class="form-label">Specializzazioni</label>
<textarea class="form-control" id="specializations" name="specializations" rows="3"><?php echo htmlspecialchars($teacher['specializations'] ?? ''); ?></textarea>
<small class="text-muted">Es: Hatha Yoga, Vinyasa, Yin, Restorative...</small>
</div>
<div class="col-md-6">
<label class="form-label">Stato</label>
<div class="form-check form-switch mt-2">
<input class="form-check-input" type="checkbox" id="status" name="status" value="active"
<?php echo ($teacher['status'] ?? 'active') === 'active' ? 'checked' : ''; ?>>
<label class="form-check-label" for="status">
<?php echo ($teacher['status'] ?? 'active') === 'active' ? 'Attivo' : 'Inattivo'; ?>
</label>
</div>
</div>
<?php if (!$is_new): ?>
<div class="col-md-6">
<label class="form-label">Data Creazione</label>
<input type="text" class="form-control" value="<?php echo htmlspecialchars($teacher['created_at'] ?? ''); ?>" readonly>
</div>
<div class="col-md-6">
<label class="form-label">Ultimo Aggiornamento</label>
<input type="text" class="form-control" value="<?php echo htmlspecialchars($teacher['updated_at'] ?? ''); ?>" readonly>
</div>
<?php endif; ?>
<div class="col-12 mt-5">
<button type="submit" class="btn btn-primary btn-lg px-5">
<?php echo $is_new ? 'Crea Profilo' : 'Salva Modifiche'; ?>
</button>
</div>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" name="email" value="<?php echo htmlspecialchars($teacher['email']); ?>" readonly>
</div>
<div class="mb-3">
<label for="phone" class="form-label">Telefono</label>
<input type="text" class="form-control" id="phone" name="phone" value="<?php echo htmlspecialchars($teacher['phone'] ?? ''); ?>">
</div>
<div class="mb-3">
<label for="description" class="form-label">Descrizione</label>
<textarea class="form-control" id="description" name="description" rows="3"><?php echo htmlspecialchars($teacher['description'] ?? ''); ?></textarea>
</div>
<div class="mb-3">
<label for="specializations" class="form-label">Specializzazioni</label>
<textarea class="form-control" id="specializations" name="specializations" rows="2"><?php echo htmlspecialchars($teacher['specializations'] ?? ''); ?></textarea>
</div>
<div class="mb-3">
<label for="status" class="form-label">Stato</label>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="status" name="status" value="active" <?php echo $teacher['status'] === 'active' ? 'checked' : ''; ?>>
<label class="form-check-label" for="status"><?php echo $teacher['status'] === 'active' ? 'Attivo' : 'Inattivo'; ?></label>
</div>
</div>
<?php if (!$is_new): ?>
<div class="mb-3">
<label class="form-label">Data Creazione</label>
<input type="text" class="form-control" value="<?php echo htmlspecialchars($teacher['created_at']); ?>" readonly>
</div>
<div class="mb-3">
<label class="form-label">Ultimo Aggiornamento</label>
<input type="text" class="form-control" value="<?php echo htmlspecialchars($teacher['updated_at']); ?>" readonly>
</div>
<?php endif; ?>
<button type="submit" class="btn btn-primary"><?php echo $is_new ? 'Crea Profilo' : 'Salva Modifiche'; ?></button>
</div>
</div>
</form>
@@ -317,11 +431,51 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
</div>
</div>
</div>
<div class="overlay toggle-icon"></div>
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
<?php include('include/footer.php'); ?>
</div>
<?php include('jsinclude.php'); ?>
<!-- Quill -->
<script src="https://cdn.jsdelivr.net/npm/quill@2.0.2/dist/quill.js"></script>
<script>
const quill = new Quill('#quill-editor', {
theme: 'snow',
modules: {
toolbar: [
['bold', 'italic', 'underline', 'strike'],
['blockquote', 'code-block'],
[{
'header': [1, 2, 3, false]
}],
[{
'color': ['#000000', '#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff', '#808080', '#c0c0c0']
}, {
'background': []
}],
[{
'list': 'ordered'
}, {
'list': 'bullet'
}],
[{
'align': []
}],
['link', 'clean']
]
}
});
quill.root.innerHTML = `<?php echo addslashes($teacher['description'] ?? ''); ?>`;
document.getElementById('teacherForm').addEventListener('submit', function() {
document.getElementById('description-hidden').value = quill.root.innerHTML;
});
</script>
</body>
</html>