fix video

This commit is contained in:
Francesco Picone
2025-12-09 16:46:59 +01:00
parent 625acba431
commit e7ea7dbd3b
5 changed files with 320 additions and 30 deletions

View File

@@ -86,6 +86,65 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['change_password'])) {
}
}
// Processa test invio email
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['test_email'])) {
$test_email = sanitize_input($_POST['test_email_address'] ?? '');
if (empty($test_email) || !validate_email($test_email)) {
$error = 'Inserisci un indirizzo email valido';
} else {
$subject = "Test Email - " . SITE_NAME;
$body = "
<html>
<head>
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; text-align: center; border-radius: 8px 8px 0 0; }
.content { background: #f9f9f9; padding: 30px; border-radius: 0 0 8px 8px; }
.success { color: #2ECC71; font-size: 24px; font-weight: bold; }
.info { background: #e8f4f8; padding: 15px; border-left: 4px solid #3498db; margin: 15px 0; }
</style>
</head>
<body>
<div class='container'>
<div class='header'>
<h1>✅ Test Email Configurazione SMTP</h1>
</div>
<div class='content'>
<p class='success'>Congratulazioni!</p>
<p>La configurazione SMTP funziona correttamente.</p>
<p>Hai ricevuto questa email di test da <strong>" . SITE_NAME . "</strong></p>
<div class='info'>
<strong>Dettagli configurazione:</strong><br>
Host: " . SMTP_HOST . "<br>
Port: " . SMTP_PORT . "<br>
Username: " . SMTP_USERNAME . "<br>
Encryption: " . SMTP_ENCRYPTION . "
</div>
<p>Ora il sistema è pronto per inviare email agli utenti per:</p>
<ul>
<li>Benvenuto alla registrazione</li>
<li>Reset password</li>
<li>Conferma acquisti</li>
<li>Notifiche importanti</li>
</ul>
</div>
</div>
</body>
</html>
";
if (send_email($test_email, $subject, $body)) {
set_flash_message('success', '✅ Email di test inviata con successo a ' . htmlspecialchars($test_email) . '! Controlla la casella di posta.');
header('Location: profile.php');
exit;
} else {
$error = '❌ Errore durante l\'invio dell\'email. Verifica le impostazioni SMTP in config.php';
}
}
}
?>
<!DOCTYPE html>
<html lang="it">
@@ -241,6 +300,36 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['change_password'])) {
</div>
</div>
<!-- Test Invio Email -->
<div class="card">
<div class="card-header">
<h2>📧 Test Invio Email</h2>
</div>
<div class="card-body">
<p style="margin-bottom: 1rem; color: #666;">
Verifica che la configurazione SMTP funzioni correttamente inviando una email di test.
</p>
<form method="POST" class="form">
<div class="form-group">
<label for="test_email_address">Indirizzo Email per Test</label>
<input
type="email"
id="test_email_address"
name="test_email_address"
value="<?php echo htmlspecialchars($user['email']); ?>"
placeholder="tua-email@esempio.com"
required
>
<small class="form-text">Riceverai una email di test a questo indirizzo</small>
</div>
<button type="submit" name="test_email" class="btn btn-secondary">
📨 Invia Email di Test
</button>
</form>
</div>
</div>
<!-- Informazioni Account -->
<div class="card">
<div class="card-header">

View File

@@ -134,30 +134,67 @@ $can_view = $lesson['is_demo'] || $user_owns;
style="border-radius: 8px;"></iframe>
<?php endif; ?>
<?php else: ?>
<!-- Video locale o altro -->
<!-- Video locale protetto -->
<?php
// Determina il percorso completo del video
$video_path = $lesson['video_url'];
// Se il percorso non inizia con http, aggiungi il SITE_URL
if (!preg_match('/^https?:\/\//', $video_path)) {
// Rimuovi eventuali slash iniziali
$video_path = ltrim($video_path, '/');
$video_path = SITE_URL . '/' . $video_path;
}
// Determina il tipo MIME dal file
$extension = strtolower(pathinfo($lesson['video_url'], PATHINFO_EXTENSION));
$mime_types = [
'mp4' => 'video/mp4',
'webm' => 'video/webm',
'ogg' => 'video/ogg',
'mov' => 'video/quicktime'
];
$mime_type = $mime_types[$extension] ?? 'video/mp4';
// Usa lo stream protetto per i video locali
$stream_url = SITE_URL . '/stream_video.php?lesson_id=' . $lesson_id;
?>
<video controls width="100%" height="100%" style="border-radius: 8px;" preload="metadata">
<source src="<?php echo htmlspecialchars($video_path); ?>" type="<?php echo $mime_type; ?>">
Il tuo browser non supporta il tag video.
<video
id="videoPlayer"
controls
controlslist="nodownload"
width="100%"
height="100%"
style="border-radius: 8px; background: #000;"
preload="auto"
playsinline
oncontextmenu="return false;">
<source src="<?php echo htmlspecialchars($stream_url); ?>" type="video/mp4">
<p style="color: white; padding: 20px;">
Il tuo browser non supporta la riproduzione video.<br>
Prova ad aggiornare il browser o usa Chrome/Firefox.
</p>
</video>
<script>
(function() {
var video = document.getElementById('videoPlayer');
// Disabilita tasto destro sul video
video.addEventListener('contextmenu', function(e) {
e.preventDefault();
return false;
});
// Debug: mostra errori del video
video.addEventListener('error', function(e) {
console.error('Errore video:', e);
var errorMsg = 'Errore nel caricamento del video.';
if (video.error) {
switch (video.error.code) {
case 1: errorMsg = 'Caricamento video interrotto.'; break;
case 2: errorMsg = 'Errore di rete nel caricamento.'; break;
case 3: errorMsg = 'Errore nella decodifica del video.'; break;
case 4: errorMsg = 'Formato video non supportato.'; break;
}
}
alert(errorMsg + ' Ricarica la pagina o contatta il supporto.');
});
// Conferma quando il video è pronto
video.addEventListener('loadedmetadata', function() {
console.log('Video caricato correttamente');
this.controlsList.add('nodownload');
});
// Disabilita screenshot (limitato)
document.addEventListener('keyup', function(e) {
if (e.key === 'PrintScreen') {
navigator.clipboard.writeText('');
alert('Gli screenshot sono disabilitati per questo contenuto.');
}
});
})();
</script>
<?php endif; ?>
<?php else: ?>
<div style="display: flex; align-items: center; justify-content: center; height: 100%; color: white;">

View File

@@ -51,6 +51,50 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($user_id) {
$success = true;
// Invia email di benvenuto
$subject = "Benvenuto su " . SITE_NAME . "!";
$body = "
<html>
<head>
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; text-align: center; border-radius: 8px 8px 0 0; }
.content { background: #f9f9f9; padding: 30px; border-radius: 0 0 8px 8px; }
.button { display: inline-block; padding: 12px 30px; background: #667eea; color: white; text-decoration: none; border-radius: 5px; margin: 20px 0; }
.footer { text-align: center; color: #999; font-size: 12px; margin-top: 20px; }
</style>
</head>
<body>
<div class='container'>
<div class='header'>
<h1>Benvenuto su " . SITE_NAME . "!</h1>
</div>
<div class='content'>
<p>Ciao <strong>" . htmlspecialchars($first_name) . "</strong>,</p>
<p>Grazie per esserti registrato sulla nostra piattaforma! Il tuo account è stato creato con successo.</p>
<p><strong>I tuoi dati di accesso:</strong></p>
<ul>
<li>Email: " . htmlspecialchars($email) . "</li>
<li>Password: quella che hai scelto durante la registrazione</li>
</ul>
<p>Ora puoi accedere al catalogo delle nostre lezioni e iniziare il tuo percorso di Pilates!</p>
<div style='text-align: center;'>
<a href='" . SITE_URL . "/user/dashboard.php' class='button'>Vai alla Dashboard</a>
</div>
<p>Se hai domande o hai bisogno di assistenza, non esitare a contattarci.</p>
<p>Buon allenamento!<br>Il team di " . SITE_NAME . "</p>
</div>
<div class='footer'>
<p>Questa è una email automatica, per favore non rispondere a questo messaggio.</p>
</div>
</div>
</body>
</html>
";
send_email($email, $subject, $body);
// Log attività
$pdo = get_db_connection();
$stmt = $pdo->prepare("

122
stream_video.php Normal file
View File

@@ -0,0 +1,122 @@
<?php
/**
* Stream Video Protetto
*
* Serve i video in modo protetto, verificando i permessi dell'utente
* e impedendo il download diretto
*/
require_once 'includes/config.php';
require_once 'includes/functions.php';
session_start();
// Ottieni parametri
$lesson_id = isset($_GET['lesson_id']) && is_numeric($_GET['lesson_id']) ? (int)$_GET['lesson_id'] : 0;
if (!$lesson_id) {
http_response_code(404);
exit('Video non trovato');
}
// Ottieni lezione
$lesson = get_lesson_by_id($lesson_id);
if (!$lesson || !$lesson['is_active']) {
http_response_code(404);
exit('Video non trovato');
}
// Verifica permessi
$can_view = false;
// Se è demo, tutti possono vedere
if ($lesson['is_demo']) {
$can_view = true;
} elseif (is_logged_in()) {
// Verifica se l'utente possiede la lezione
$can_view = user_owns_lesson($_SESSION['user_id'], $lesson_id);
}
if (!$can_view) {
http_response_code(403);
exit('Non hai i permessi per visualizzare questo video');
}
// Verifica che sia un video locale
if (empty($lesson['video_url']) || $lesson['video_platform'] !== 'local') {
http_response_code(404);
exit('Video non disponibile');
}
// Costruisci il percorso del file
$video_path = ltrim($lesson['video_url'], '/');
$file = __DIR__ . '/' . $video_path;
if (!file_exists($file)) {
http_response_code(404);
exit('File video non trovato');
}
// Ottieni informazioni sul file
$file_size = filesize($file);
$file_name = basename($file);
$extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
// Determina il tipo MIME
$mime_types = [
'mp4' => 'video/mp4',
'webm' => 'video/webm',
'ogg' => 'video/ogg',
'mov' => 'video/quicktime'
];
$mime_type = $mime_types[$extension] ?? 'video/mp4';
// Gestisci Range Request per supportare seek nel video
$start = 0;
$end = $file_size - 1;
$length = $file_size;
if (isset($_SERVER['HTTP_RANGE'])) {
$range = $_SERVER['HTTP_RANGE'];
if (preg_match('/bytes=(\d+)-(\d*)/', $range, $matches)) {
$start = intval($matches[1]);
if (!empty($matches[2])) {
$end = intval($matches[2]);
}
$length = $end - $start + 1;
http_response_code(206); // Partial Content
}
} else {
http_response_code(200);
}
// Invia header
header("Content-Type: $mime_type");
header("Accept-Ranges: bytes");
header("Content-Length: $length");
header("Content-Range: bytes $start-$end/$file_size");
// Header per impedire il download e la cache aggressiva
header("Content-Disposition: inline; filename=\"video.{$extension}\"");
header("X-Content-Type-Options: nosniff");
// Header di cache per migliorare le performance
header("Cache-Control: public, max-age=3600");
header("Pragma: public");
// Apri e leggi il file
$fp = fopen($file, 'rb');
fseek($fp, $start);
$buffer = 1024 * 8; // 8KB buffer
while (!feof($fp) && ($pos = ftell($fp)) <= $end) {
if ($pos + $buffer > $end) {
$buffer = $end - $pos + 1;
}
echo fread($fp, $buffer);
flush();
}
fclose($fp);
exit;

View File

@@ -1,11 +1,9 @@
# Proteggi i video a pagamento
# Permetti solo l'accesso tramite PHP
# Proteggi i video da accesso diretto
# I video possono essere visualizzati solo tramite stream_video.php
<FilesMatch "\.(mp4|webm|ogg|mov)$">
# Permetti l'accesso solo se proveniente da script PHP
Order Deny,Allow
Deny from all
</FilesMatch>
# Opzionale: previeni il listing delle directory
# Impedisci il listing delle directory
Options -Indexes
# Nota: I video sono serviti tramite stream_video.php che verifica i permessi
# Questo file .htaccess fornisce una protezione aggiuntiva ma i video
# sono accessibili tramite PHP per permettere lo streaming protetto