Edició de dades de l'usuari: diferència entre les revisions

De Wiki personal d'en Guillem Serrat
Cap resum de modificació
Cap resum de modificació
 
Línia 50: Línia 50:
Un cop obtingudes les dades, en el formulari definirem l'argument "value" dels inputs com al resultat de la consulta SQL, excepte per les contrasenyes, per motius obvis<pre>
Un cop obtingudes les dades, en el formulari definirem l'argument "value" dels inputs com al resultat de la consulta SQL, excepte per les contrasenyes, per motius obvis<pre>
<form method="post" class="edit-card">
<form method="post" class="edit-card">
            <div class="form-section">
    <div class="form-section">
                <h3>Dades personals</h3>
        <h3>Dades personals</h3>
                <div class="input-grid">
        <div class="input-grid">
                    <div class="input-group">
            <div class="input-group">
                        <label>Nom d'usuari</label>
                <label>Nom d'usuari</label>
                        <input type="text" name="nom_usuari" value="<?= htmlspecialchars($usuari['nom_usuari']) ?>" required>
                <input type="text" name="nom_usuari" value="<?= htmlspecialchars($usuari['nom_usuari']) ?>" required>
                    </div>
                    <div class="input-group">
                        <label>Nom complet</label>
                        <input type="text" name="nom_complet" value="<?= htmlspecialchars($usuari['nom_complet']) ?>" required>
                    </div>
                    <div class="input-group full-width">
                        <label>Email <span class="info-tag">(Es requerirà nova verificació si es canvia)</span></label>
                        <input type="email" name="email" value="<?= htmlspecialchars($usuari['email']) ?>" required>
                    </div>
                    <div class="input-group">
                        <label>Telèfon</label>
                        <input type="text" name="telefon" value="<?= htmlspecialchars($usuari['telefon']) ?>" required>
                    </div>
                    <div class="input-group">
                        <label>Ciutat</label>
                        <input type="text" name="ciutat" value="<?= htmlspecialchars($usuari['ciutat']) ?>" required>
                    </div>
                    <div class="input-group">
                        <label>Edat</label>
                        <input type="number" name="edat" min="0" max="120" value="<?= htmlspecialchars($usuari['edat']) ?>" required>
                    </div>
                </div>
             </div>
             </div>
            <div class="input-group">
                <label>Nom complet</label>
                <input type="text" name="nom_complet" value="<?= htmlspecialchars($usuari['nom_complet']) ?>" required>
            </div>
            <div class="input-group full-width">
                <label>Email <span class="info-tag">(Es requerirà nova verificació si es canvia)</span></label>
                <input type="email" name="email" value="<?= htmlspecialchars($usuari['email']) ?>" required>
            </div>
            <div class="input-group">
                <label>Telèfon</label>
                <input type="text" name="telefon" value="<?= htmlspecialchars($usuari['telefon']) ?>" required>
            </div>
            <div class="input-group">
                <label>Ciutat</label>
                <input type="text" name="ciutat" value="<?= htmlspecialchars($usuari['ciutat']) ?>" required>
            </div>
            <div class="input-group">
                <label>Edat</label>
                <input type="number" name="edat" min="0" max="120" value="<?= htmlspecialchars($usuari['edat']) ?>" required>
            </div>
        </div>
    </div>


            <hr class="divider">
    <hr class="divider">


            <div class="form-section">
    <div class="form-section">
                <h3>Seguretat <span class="sub-title">(Opcional)</span></h3>
        <h3>Seguretat <span class="sub-title">(Opcional)</span></h3>
                <div class="input-group">
        <div class="input-group">
                    <label>Contrasenya actual</label>
            <label>Contrasenya actual</label>
                    <input type="password" name="contrasenya_actual">
            <input type="password" name="contrasenya_actual">
                </div>
        </div>
                <div class="input-grid">
        <div class="input-grid">
                    <div class="input-group">
            <div class="input-group">
                        <label>Nova contrasenya</label>
                <label>Nova contrasenya</label>
                        <input type="password" name="nova_contrasenya">
                <input type="password" name="nova_contrasenya">
                    </div>
            </div>
                    <div class="input-group">
            <div class="input-group">
                        <label>Confirmar nova contrasenya</label>
                <label>Confirmar nova contrasenya</label>
                        <input type="password" name="confirmar_contrasenya">
                <input type="password" name="confirmar_contrasenya">
                    </div>
                </div>
             </div>
             </div>
        </div>
    </div>


            <div class="form-actions">
    <div class="form-actions">
                <a href="privada.php" class="btn-cancel">Tornar enrere</a>
        <a href="privada.php" class="btn-cancel">Tornar enrere</a>
                <button type="submit" class="btn-submit">Desar canvis</button>
        <button type="submit" class="btn-submit">Desar canvis</button>
            </div>
    </div>
        </form>
</form>
</pre>La visualització del formulari serà com la següent:
</pre>La visualització del formulari serà com la següent:
[[Fitxer:FormulariActualitzaDades.png|center|miniatura|627x627px]]
[[Fitxer:FormulariActualitzaDades.png|center|miniatura|627x627px]]
Línia 112: Línia 112:
=== Recuperació de les dades del formulari ===
=== Recuperació de les dades del formulari ===
Un cop s'ha respost el formulari, recuperarem tots els valors de les entrades<pre>
Un cop s'ha respost el formulari, recuperarem tots els valors de les entrades<pre>
    $nom_usuari  = trim($_POST['nom_usuari']);
$nom_usuari  = trim($_POST['nom_usuari']);
    $nom_complet = trim($_POST['nom_complet']);
$nom_complet = trim($_POST['nom_complet']);
    $email      = trim($_POST['email']);
$email      = trim($_POST['email']);
    $telefon    = trim($_POST['telefon']);
$telefon    = trim($_POST['telefon']);
    $ciutat      = trim($_POST['ciutat']);
$ciutat      = trim($_POST['ciutat']);
    $edat        = trim($_POST['edat']);
$edat        = trim($_POST['edat']);
    $contrasenya_actual    = $_POST['contrasenya_actual'];
$contrasenya_actual    = $_POST['contrasenya_actual'];
    $nova_contrasenya      = $_POST['nova_contrasenya'];
$nova_contrasenya      = $_POST['nova_contrasenya'];
    $confirmar_contrasenya = $_POST['confirmar_contrasenya'];
$confirmar_contrasenya = $_POST['confirmar_contrasenya'];
</pre>
</pre>


Línia 134: Línia 134:


En cas de la contrasenya, al no estar obligats a canviar-la, no és un camp requerit i per tant es pot deixar buit. Per això, en cas de voler modificar una contrasenya, ens hem d'assegurar que el camp no estigui buit, a més de fer altres comprovacions a nivell de contrasenya.<pre>
En cas de la contrasenya, al no estar obligats a canviar-la, no és un camp requerit i per tant es pot deixar buit. Per això, en cas de voler modificar una contrasenya, ens hem d'assegurar que el camp no estigui buit, a més de fer altres comprovacions a nivell de contrasenya.<pre>
    // Determinar si l'email, el telèfon o el nom d'usuari ha canviat
// Determinar si l'email, el telèfon o el nom d'usuari ha canviat
    $email_ha_canviat = ($email !== $usuari['email']);
$email_ha_canviat = ($email !== $usuari['email']);
    $telefon_ha_canviat = ($telefon !== $usuari['telefon']);
$telefon_ha_canviat = ($telefon !== $usuari['telefon']);
    $usuari_ha_canviat = ($nom_usuari !== $usuari['nom_usuari']);
$usuari_ha_canviat = ($nom_usuari !== $usuari['nom_usuari']);


    // Determinem si volem canviar la contrasenya mirant si tots els camps estan plens
// Determinem si volem canviar la contrasenya mirant si tots els camps estan plens
    $canvi_contrasenya = ( // Si hi ha algun camp buit = fals = NO es vol canviar la contrasenya
$canvi_contrasenya = ( // Si hi ha algun camp buit = fals = NO es vol canviar la contrasenya
        $contrasenya_actual !== '' ||
    $contrasenya_actual !== '' ||
        $nova_contrasenya !== '' ||
    $nova_contrasenya !== '' ||
        $confirmar_contrasenya !== ''
    $confirmar_contrasenya !== ''
    );
);
</pre>
</pre>


Línia 150: Línia 150:
A continuació es faran unes validacions bàsiques que sempre s'executaran. Aquestes validacions són les mateixes que al [[registre d'usuaris]].<pre>
A continuació es faran unes validacions bàsiques que sempre s'executaran. Aquestes validacions són les mateixes que al [[registre d'usuaris]].<pre>
// Validacions bàsiques
// Validacions bàsiques
    // Verifiquem que cap camp estigui buit
// Verifiquem que cap camp estigui buit
    if ($nom_usuari === '' || $nom_complet === '' || $email === '' || $ciutat === '' || $telefon === '' || $edat === '') {
if ($nom_usuari === '' || $nom_complet === '' || $email === '' || $ciutat === '' || $telefon === '' || $edat === '') {
        $error = "Els camps obligatoris no poden estar buits";
    $error = "Els camps obligatoris no poden estar buits";
    }  
}  


    // Verifiquem que l'email sigui realment un email
// Verifiquem que l'email sigui realment un email
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $error = "L'email introduït no és vàlid";
    $error = "L'email introduït no és vàlid";
    }  
}  


    // Verifiquem que el telèfon sigui vàlid
// Verifiquem que el telèfon sigui vàlid
    if (strlen($telefon) != 9) {
if (strlen($telefon) != 9) {
        $error = "Telèfon no vàlid";
    $error = "Telèfon no vàlid";
    }
}


    // Verifiquem que la ciutat sigui vàlida
// Verifiquem que la ciutat sigui vàlida
    if (strlen($ciutat) > 100) {
if (strlen($ciutat) > 100) {
        $error = "Ciutat no vàlida";
    $error = "Ciutat no vàlida";
    }
}


    // Verifiquem que l'edat sigui vàlida
// Verifiquem que l'edat sigui vàlida
    if ($edat < 18 || $edat > 120) {
if ($edat < 18 || $edat > 120) {
        $error = "Edat no vàlida";
    $error = "Edat no vàlida";
    }
}
</pre>
</pre>


Línia 179: Línia 179:
A continuació, depenent de si s'ha modificat el camp únic o no, realitzarem una consulta SQL on cercarem un usuari a la BD amb el mateix valor del camp comprovat. En cas que es retorni algun resultat, voldrà dir que ja hi ha un usuari amb aquella informació registrada<pre>
A continuació, depenent de si s'ha modificat el camp únic o no, realitzarem una consulta SQL on cercarem un usuari a la BD amb el mateix valor del camp comprovat. En cas que es retorni algun resultat, voldrà dir que ja hi ha un usuari amb aquella informació registrada<pre>
// Validar si el mail ja està registrat per qualsevol altre usuari
// Validar si el mail ja està registrat per qualsevol altre usuari
    if ($email_ha_canviat && $error === '') {
if ($email_ha_canviat && $error === '') {
        $stmt_check = $pdo->prepare("SELECT id FROM usuaris WHERE email = ?"); // Realitzem una consulta on busquem un usuari amb el mateix email
    $stmt_check = $pdo->prepare("SELECT id FROM usuaris WHERE email = ?"); // Realitzem una consulta on busquem un usuari amb el mateix email
        $stmt_check->execute([$email]); // Si retorna algun resultat, significa que el email ja està a la BD
    $stmt_check->execute([$email]); // Si retorna algun resultat, significa que el email ja està a la BD
        if ($stmt_check->fetch()) {
    if ($stmt_check->fetch()) {
            $error = "Aquest email ja està registrat per un altre usuari";
        $error = "Aquest email ja està registrat per un altre usuari";
        }
     }
     }
}


    // Validar si el telèfon ja està registrat per qualsevol altre usuari
// Validar si el telèfon ja està registrat per qualsevol altre usuari
    if ($telefon_ha_canviat && $error === '') {
if ($telefon_ha_canviat && $error === '') {
        $stmt_tel = $pdo->prepare("SELECT id FROM usuaris WHERE telefon = ?"); // Realitzem una consulta on busquem un usuari amb el mateix telèfon
    $stmt_tel = $pdo->prepare("SELECT id FROM usuaris WHERE telefon = ?"); // Realitzem una consulta on busquem un usuari amb el mateix telèfon
        $stmt_tel->execute([$telefon]);
    $stmt_tel->execute([$telefon]);
        if ($stmt_tel->fetch()) { // Si retorna algun resultat, significa que el telèfon ja està a la BD
    if ($stmt_tel->fetch()) { // Si retorna algun resultat, significa que el telèfon ja està a la BD
            $error = "Aquest telèfon ja està registrat";  
        $error = "Aquest telèfon ja està registrat";  
        }
     }
     }
}


    // Validar si el nom d'usuari ja està registrat per qualsevol altre usuari
// Validar si el nom d'usuari ja està registrat per qualsevol altre usuari
    if ($usuari_ha_canviat && $error === '') {
if ($usuari_ha_canviat && $error === '') {
        $stmt_user = $pdo->prepare("SELECT id FROM usuaris WHERE nom_usuari = ?"); // Realitzem una consulta on busquem un usuari amb el mateix nom d'usuari
    $stmt_user = $pdo->prepare("SELECT id FROM usuaris WHERE nom_usuari = ?"); // Realitzem una consulta on busquem un usuari amb el mateix nom d'usuari
        $stmt_user->execute([$nom_usuari]); // Si retorna algun resultat, significa que el nom d'usuari ja està a la BD
    $stmt_user->execute([$nom_usuari]); // Si retorna algun resultat, significa que el nom d'usuari ja està a la BD
        if ($stmt_user->fetch()) {  
    if ($stmt_user->fetch()) {  
            $error = "Aquest nom d'usuari ja està registrat";  
        $error = "Aquest nom d'usuari ja està registrat";  
        }
     }
     }
}
</pre>En cas de verificar la contrasenya, verificarem:
</pre>En cas de verificar la contrasenya, verificarem:


Línia 211: Línia 211:
<pre>
<pre>
// En cas que volguem canviar la contrasenya, farem les següent validacions
// En cas que volguem canviar la contrasenya, farem les següent validacions
    if ($canvi_contrasenya && $error === '') {
if ($canvi_contrasenya && $error === '') {
        if ($contrasenya_actual === '' || $nova_contrasenya === '' || $confirmar_contrasenya === '') { // Revisem que tots els camps estiguin plens
    if ($contrasenya_actual === '' || $nova_contrasenya === '' || $confirmar_contrasenya === '') { // Revisem que tots els camps estiguin plens
            $error = "Has d'omplir tots els camps de contrasenya";
        $error = "Has d'omplir tots els camps de contrasenya";
        } elseif (!verificar_contrasenya($contrasenya_actual, $usuari['contrasenya'])) { // Que la contrasenya de l'usuari sigui correcte
    } elseif (!verificar_contrasenya($contrasenya_actual, $usuari['contrasenya'])) { // Que la contrasenya de l'usuari sigui correcte
            $error = "La contrasenya actual no és correcta";
        $error = "La contrasenya actual no és correcta";
        } elseif ($nova_contrasenya !== $confirmar_contrasenya) { // Que la nova contrasenya i la seva verificació coincideixin
    } elseif ($nova_contrasenya !== $confirmar_contrasenya) { // Que la nova contrasenya i la seva verificació coincideixin
            $error = "Les noves contrasenyes no coincideixen";
        $error = "Les noves contrasenyes no coincideixen";
        }
     }
     }
}
</pre>
</pre>


Línia 225: Línia 225:
A cada pas de les verificacions anteriors, en cas d'haver-hi algun error es registrarà dins la variable $error, que servirà per imprimir-ho i que l'usuari sigui conscient i verificar si és correcte actualitzar les dades o no<pre>
A cada pas de les verificacions anteriors, en cas d'haver-hi algun error es registrarà dins la variable $error, que servirà per imprimir-ho i que l'usuari sigui conscient i verificar si és correcte actualitzar les dades o no<pre>
// Si s'ha superat totes les validacions
// Si s'ha superat totes les validacions
    if ($error === '') {
if ($error === '') {
</pre>Un cop verificat que no hi hagi hagut cap error, inserirem les dades obtingudes del formulari a la taula usuaris.
</pre>Un cop verificat que no hi hagi hagut cap error, inserirem les dades obtingudes del formulari a la taula usuaris.


Abans, definirem l'estat de verificació de l'email. En cas que l'email hagi estat modificat, establirem la verificació a "no", si no ho ha estat, deixarem l'estat de verificació actual<pre>
Abans, definirem l'estat de verificació de l'email. En cas que l'email hagi estat modificat, establirem la verificació a "no", si no ho ha estat, deixarem l'estat de verificació actual<pre>
if ($email_ha_canviat) { // Si l'email ha canviat
if ($email_ha_canviat) { // Si l'email ha canviat
                $nou_estat_verificacio = 'no'; // Definirem que l'estat de verificació és no
    $nou_estat_verificacio = 'no'; // Definirem que l'estat de verificació és no
            } else { // Si l'email no ha canviat
} else { // Si l'email no ha canviat
                $nou_estat_verificacio = $usuari['email_verificat']; // Valor original de l'usuari
    $nou_estat_verificacio = $usuari['email_verificat']; // Valor original de l'usuari
            }
}
</pre>En cas que s'hagi modificat la contrasenya, realitzarem un update on encriptarem al contrasenya amb la funció encriptar_contrasenya i actualitzarem no només les dades personals sinó també la contrasenya. També afegirem una acció indicant que la contrasenya s'ha restablert.
</pre>En cas que s'hagi modificat la contrasenya, realitzarem un update on encriptarem al contrasenya amb la funció encriptar_contrasenya i actualitzarem no només les dades personals sinó també la contrasenya. També afegirem una acció indicant que la contrasenya s'ha restablert.


En cas que la contrasenya no s'hagi modificat, únicament actualitzarem les dades personals amb les dades del formulari<pre>
En cas que la contrasenya no s'hagi modificat, únicament actualitzarem les dades personals amb les dades del formulari<pre>
            if ($canvi_contrasenya) { // Si canviem la contrasenya
if ($canvi_contrasenya) { // Si canviem la contrasenya
                $hash = encriptar_contrasenya($nova_contrasenya);
    $hash = encriptar_contrasenya($nova_contrasenya);
                $stmt = $pdo->prepare("
    $stmt = $pdo->prepare("
                    UPDATE usuaris  
        UPDATE usuaris  
                    SET nom_usuari = ?, nom_complet = ?, email = ?, telefon = ?, ciutat = ?, edat = ?, contrasenya = ?, email_verificat = ?
        SET nom_usuari = ?, nom_complet = ?, email = ?, telefon = ?, ciutat = ?, edat = ?, contrasenya = ?, email_verificat = ?
                    WHERE id = ?
        WHERE id = ?
                ");
    ");
                // Fem un Update de tots els camps de la BD: Dades personals + contrasenya
    // Fem un Update de tots els camps de la BD: Dades personals + contrasenya
                $stmt->execute([$nom_usuari, $nom_complet, $email, $telefon, $ciutat, $edat, $hash, $nou_estat_verificacio, $usuari_id]);
    $stmt->execute([$nom_usuari, $nom_complet, $email, $telefon, $ciutat, $edat, $hash, $nou_estat_verificacio, $usuari_id]);
                registrar_activitat($pdo, $usuari_id, 'restablir-contrasenya');
    registrar_activitat($pdo, $usuari_id, 'restablir-contrasenya');
            } else { // Si no canviem la contrasenya
} else { // Si no canviem la contrasenya
                $stmt = $pdo->prepare("
    $stmt = $pdo->prepare("
                    UPDATE usuaris  
        UPDATE usuaris  
                    SET nom_usuari = ?, nom_complet = ?, email = ?, telefon = ?, ciutat = ?, edat = ?, email_verificat = ?
        SET nom_usuari = ?, nom_complet = ?, email = ?, telefon = ?, ciutat = ?, edat = ?, email_verificat = ?
                    WHERE id = ?
        WHERE id = ?
                ");
    ");
                // Únicament actualitzem les dades personals
    // Únicament actualitzem les dades personals
                $stmt->execute([$nom_usuari, $nom_complet, $email, $telefon, $ciutat, $edat, $nou_estat_verificacio, $usuari_id]);
    $stmt->execute([$nom_usuari, $nom_complet, $email, $telefon, $ciutat, $edat, $nou_estat_verificacio, $usuari_id]);
            }
}
</pre>Un cop actualitzades les dades a la BD, actualitzarem la sessió i les dades que es mostraran al formulari<pre>
</pre>Un cop actualitzades les dades a la BD, actualitzarem la sessió i les dades que es mostraran al formulari<pre>
            // Actualizar sessió
// Actualizar sessió
            $_SESSION['usuari']['nom_usuari']  = $nom_usuari;
$_SESSION['usuari']['nom_usuari']  = $nom_usuari;
            $_SESSION['usuari']['nom_complet']  = $nom_complet;
$_SESSION['usuari']['nom_complet']  = $nom_complet;
            $_SESSION['usuari']['email']        = $email;
$_SESSION['usuari']['email']        = $email;


            // Actualitzar les dades modificades obtenides a la consulta per mostrar-les al formulari
// Actualitzar les dades modificades obtenides a la consulta per mostrar-les al formulari
            $usuari['nom_usuari']  = $nom_usuari;
$usuari['nom_usuari']  = $nom_usuari;
            $usuari['nom_complet'] = $nom_complet;
$usuari['nom_complet'] = $nom_complet;
            $usuari['email']      = $email;
$usuari['email']      = $email;
            $usuari['telefon']    = $telefon;
$usuari['telefon']    = $telefon;
            $usuari['ciutat']      = $ciutat;
$usuari['ciutat']      = $ciutat;
            $usuari['edat']        = $edat;
$usuari['edat']        = $edat;
</pre>Si hem modificat el correu electrònic, esborrarem qualsevol codi de verificació que s’hagi desat a la sessió i mostrarem un missatge diferent al genèric, recordant que s’ha de tornar a verificar el correu electrònic.<pre>
</pre>Si hem modificat el correu electrònic, esborrarem qualsevol codi de verificació que s’hagi desat a la sessió i mostrarem un missatge diferent al genèric, recordant que s’ha de tornar a verificar el correu electrònic.<pre>
if ($email_ha_canviat) { // Si hem canviat l'email
if ($email_ha_canviat) { // Si hem canviat l'email
                // Borrar codi de verificació
    // Borrar codi de verificació
                unset($_SESSION['codi_verificacio']);
    unset($_SESSION['codi_verificacio']);
                $correcte = "Perfil actualitzat. Com que has canviat l'email, l'hauràs de tornar a verificar.";
    $correcte = "Perfil actualitzat. Com que has canviat l'email, l'hauràs de tornar a verificar.";
            } else {
} else {
                $correcte = "Perfil actualitzat correctament";
    $correcte = "Perfil actualitzat correctament";
            }
}
</pre>Per últim, registrarem una acció d'usuari on indicarem que s'ha modificat el perfil<pre>
</pre>Per últim, registrarem una acció d'usuari on indicarem que s'ha modificat el perfil<pre>
registrar_activitat($pdo, $usuari_id, 'editar-perfil');
registrar_activitat($pdo, $usuari_id, 'editar-perfil');
Línia 283: Línia 283:
== Mostra de missatges d'error o èxit ==
== Mostra de missatges d'error o èxit ==
En cas que l'usuari cometi algun error o completi l'operació amb èxit, es mostrarà un missatge a la part superior del formulari<pre>
En cas que l'usuari cometi algun error o completi l'operació amb èxit, es mostrarà un missatge a la part superior del formulari<pre>
        <?php if ($error): // En cas que hi hagi un error es mostrarà?>
<?php if ($error): // En cas que hi hagi un error es mostrarà?>
            <div class="alert alert-error"><?= htmlspecialchars($error) ?></div>
    <div class="alert alert-error"><?= htmlspecialchars($error) ?></div>
        <?php endif; ?>
<?php endif; ?>


        <?php if ($correcte): // En cas que hi hagi un missatge d'èxit es mostrarà?>
<?php if ($correcte): // En cas que hi hagi un missatge d'èxit es mostrarà?>
            <div class="alert alert-success"><?= htmlspecialchars($correcte) ?></div>
    <div class="alert alert-success"><?= htmlspecialchars($correcte) ?></div>
        <?php endif; ?>
<?php endif; ?>
</pre>Un exemple de missatge d'error es visualitzaria de la següent forma
</pre>Un exemple de missatge d'error es visualitzaria de la següent forma
[[Fitxer:ErrorEditarPerfil.png|center|miniatura|652x652px]]
[[Fitxer:ErrorEditarPerfil.png|center|miniatura|652x652px]]

Revisió de 02:25, 12 gen 2026

Edició de les dades de l'usuari

Qualsevol usuari de l'aplicatiu pot modificar les seves dades personals i la seva contrasenya gràcies al formulari d'edició de dades de l'usuari.

Aquest formulari mostra les dades actuals dins dels camps d'entrada per fer més fàcil la modificació d'aquestes, tant per part de l'usuari com per part de la BD

Inicialització de la sessió i connexió a la BD

Sempre que es treballa amb sessions, el primer que hem de fer és iniciar-la abans d'escriure el codi HTML

session_start();

A més, hem de requerir el fitxer amb les funcions i una connexió a la BD. En aquest cas, com hem de modificar dades de l'usuari i per tant actualitzar registres de la BD farem servir la connexió d'escriptura.

require 'funcions.php';
require './connexioBD/connexioRW.php';

Requerir autenticació

Per accedir a aquesta pàgina, és imperatiu que l'usuari estigui autenticat, en cas contrari no hi pot accedir.

Per verificar que l'usuari està autenticat, farem servir la funció requerir_autenticacio

// Requerir autenticació per accedir a la pàgina
requerir_autenticacio();

Formulari d'edició de dades

Recuperació de les dades de l'usuari a la BD

El formulari d'edició de dades mostra les dades actuals dins dels camps. És a dir, al camp "nom d'usuari" enlloc de sortir en blanc sortirà el nom d'usuari actual. Així l’usuari sap quins valors hi havien i pot modificar-los més fàcilment, a més que a nivell de gestió de BD, podrem fer un update de tot sense haver de comprovar quin camp ha canviat l’usuari, fent-ho més senzill.

Per això, recuperarem la ID de l'usuari a partir de la sessió

// 2. Obtenir ID de l'usuari autenticat
$usuari_id = $_SESSION['usuari']['id'];

I realitzarem una consulta SQL per recuperar les seves dades personals. En cas que la consulta no retorni res, voldrà dir que l'usuari no existeix

// 3. Obtenir les dades de l'usuari try {

   $stmt = $pdo->prepare("
   SELECT nom_usuari, nom_complet, email, telefon, ciutat, edat, contrasenya, email_verificat
   FROM usuaris
   WHERE id = ?
   ");
   $stmt->execute([$usuari_id]);
   $usuari = $stmt->fetch();

} catch (PDOException $e) {

   $error = "No s'ha pogut recuperar les dades de l'usuari. Motiu: " . $e->getMessage();

}

// En cas que la consulta no retorni res, voldrà dir que no hi ha cap usuari amb aquella ID if (!$usuari) {

   die("Usuari no trobat");

}

Mostra del formulari amb els valors predefinits

Un cop obtingudes les dades, en el formulari definirem l'argument "value" dels inputs com al resultat de la consulta SQL, excepte per les contrasenyes, per motius obvis

<form method="post" class="edit-card">
    <div class="form-section">
        <h3>Dades personals</h3>
        <div class="input-grid">
            <div class="input-group">
                <label>Nom d'usuari</label>
                <input type="text" name="nom_usuari" value="<?= htmlspecialchars($usuari['nom_usuari']) ?>" required>
            </div>
            <div class="input-group">
                <label>Nom complet</label>
                <input type="text" name="nom_complet" value="<?= htmlspecialchars($usuari['nom_complet']) ?>" required>
            </div>
            <div class="input-group full-width">
                <label>Email <span class="info-tag">(Es requerirà nova verificació si es canvia)</span></label>
                <input type="email" name="email" value="<?= htmlspecialchars($usuari['email']) ?>" required>
            </div>
            <div class="input-group">
                <label>Telèfon</label>
                <input type="text" name="telefon" value="<?= htmlspecialchars($usuari['telefon']) ?>" required>
            </div>
            <div class="input-group">
                <label>Ciutat</label>
                <input type="text" name="ciutat" value="<?= htmlspecialchars($usuari['ciutat']) ?>" required>
            </div>
            <div class="input-group">
                <label>Edat</label>
                <input type="number" name="edat" min="0" max="120" value="<?= htmlspecialchars($usuari['edat']) ?>" required>
            </div>
        </div>
    </div>

    <hr class="divider">

    <div class="form-section">
        <h3>Seguretat <span class="sub-title">(Opcional)</span></h3>
        <div class="input-group">
            <label>Contrasenya actual</label>
            <input type="password" name="contrasenya_actual">
        </div>
        <div class="input-grid">
            <div class="input-group">
                <label>Nova contrasenya</label>
                <input type="password" name="nova_contrasenya">
            </div>
            <div class="input-group">
                <label>Confirmar nova contrasenya</label>
                <input type="password" name="confirmar_contrasenya">
            </div>
        </div>
    </div>

    <div class="form-actions">
        <a href="privada.php" class="btn-cancel">Tornar enrere</a>
        <button type="submit" class="btn-submit">Desar canvis</button>
    </div>
</form>

La visualització del formulari serà com la següent:

Actualització de dades

Recuperació de les dades del formulari

Un cop s'ha respost el formulari, recuperarem tots els valors de les entrades

$nom_usuari  = trim($_POST['nom_usuari']);
$nom_complet = trim($_POST['nom_complet']);
$email       = trim($_POST['email']);
$telefon     = trim($_POST['telefon']);
$ciutat      = trim($_POST['ciutat']);
$edat        = trim($_POST['edat']);
$contrasenya_actual    = $_POST['contrasenya_actual'];
$nova_contrasenya      = $_POST['nova_contrasenya'];
$confirmar_contrasenya = $_POST['confirmar_contrasenya'];

Determinar si camps únics han canviat

Seguidament, a partir d'aquests valors haurem de comprovar si els següents camps han estat modificats:

  • Nom d'usuari
  • Email
  • Telèfon
  • Contrasenya

En cas del nom d'usuari, email i telèfon, hem de recordar que són valors únics dins la BD i per tant s'ha de realitzar unes comprovacions a part per assegurar que el nou valor no està ja registrat, a diferència de les demés dades que poden estar repetides

En cas de la contrasenya, al no estar obligats a canviar-la, no és un camp requerit i per tant es pot deixar buit. Per això, en cas de voler modificar una contrasenya, ens hem d'assegurar que el camp no estigui buit, a més de fer altres comprovacions a nivell de contrasenya.

// Determinar si l'email, el telèfon o el nom d'usuari ha canviat
$email_ha_canviat = ($email !== $usuari['email']);
$telefon_ha_canviat = ($telefon !== $usuari['telefon']);
$usuari_ha_canviat = ($nom_usuari !== $usuari['nom_usuari']);

// Determinem si volem canviar la contrasenya mirant si tots els camps estan plens
$canvi_contrasenya = ( // Si hi ha algun camp buit = fals = NO es vol canviar la contrasenya
    $contrasenya_actual !== '' ||
    $nova_contrasenya !== '' ||
    $confirmar_contrasenya !== ''
);

Verificacions bàsiques

A continuació es faran unes validacions bàsiques que sempre s'executaran. Aquestes validacions són les mateixes que al registre d'usuaris.

// Validacions bàsiques
// Verifiquem que cap camp estigui buit
if ($nom_usuari === '' || $nom_complet === '' || $email === '' || $ciutat === '' || $telefon === '' || $edat === '') {
    $error = "Els camps obligatoris no poden estar buits";
} 

// Verifiquem que l'email sigui realment un email
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $error = "L'email introduït no és vàlid";
} 

// Verifiquem que el telèfon sigui vàlid
if (strlen($telefon) != 9) {
    $error = "Telèfon no vàlid";
}

// Verifiquem que la ciutat sigui vàlida
if (strlen($ciutat) > 100) {
    $error = "Ciutat no vàlida";
}

// Verifiquem que l'edat sigui vàlida
if ($edat < 18 || $edat > 120) {
    $error = "Edat no vàlida";
}

Verificacions de camps únics

A continuació, depenent de si s'ha modificat el camp únic o no, realitzarem una consulta SQL on cercarem un usuari a la BD amb el mateix valor del camp comprovat. En cas que es retorni algun resultat, voldrà dir que ja hi ha un usuari amb aquella informació registrada

// Validar si el mail ja està registrat per qualsevol altre usuari
if ($email_ha_canviat && $error === '') {
    $stmt_check = $pdo->prepare("SELECT id FROM usuaris WHERE email = ?"); // Realitzem una consulta on busquem un usuari amb el mateix email
    $stmt_check->execute([$email]); // Si retorna algun resultat, significa que el email ja està a la BD
    if ($stmt_check->fetch()) {
        $error = "Aquest email ja està registrat per un altre usuari";
    }
}

// Validar si el telèfon ja està registrat per qualsevol altre usuari
if ($telefon_ha_canviat && $error === '') {
    $stmt_tel = $pdo->prepare("SELECT id FROM usuaris WHERE telefon = ?"); // Realitzem una consulta on busquem un usuari amb el mateix telèfon
    $stmt_tel->execute([$telefon]);
    if ($stmt_tel->fetch()) { // Si retorna algun resultat, significa que el telèfon ja està a la BD
        $error = "Aquest telèfon ja està registrat"; 
    }
}

// Validar si el nom d'usuari ja està registrat per qualsevol altre usuari
if ($usuari_ha_canviat && $error === '') {
    $stmt_user = $pdo->prepare("SELECT id FROM usuaris WHERE nom_usuari = ?"); // Realitzem una consulta on busquem un usuari amb el mateix nom d'usuari
    $stmt_user->execute([$nom_usuari]); // Si retorna algun resultat, significa que el nom d'usuari ja està a la BD
    if ($stmt_user->fetch()) { 
        $error = "Aquest nom d'usuari ja està registrat"; 
    }
}

En cas de verificar la contrasenya, verificarem:

  • Que els tres camps tenen algun valor
  • Que la contrasenya actual sigui correcta, amb la funcio verificar_contrasenya
  • Que les noves contrasenyes coincideixin en els dos camps
// En cas que volguem canviar la contrasenya, farem les següent validacions
if ($canvi_contrasenya && $error === '') {
    if ($contrasenya_actual === '' || $nova_contrasenya === '' || $confirmar_contrasenya === '') { // Revisem que tots els camps estiguin plens
        $error = "Has d'omplir tots els camps de contrasenya";
    } elseif (!verificar_contrasenya($contrasenya_actual, $usuari['contrasenya'])) { // Que la contrasenya de l'usuari sigui correcte
        $error = "La contrasenya actual no és correcta";
    } elseif ($nova_contrasenya !== $confirmar_contrasenya) { // Que la nova contrasenya i la seva verificació coincideixin
        $error = "Les noves contrasenyes no coincideixen";
    }
}

Inserció de dades a la BD

A cada pas de les verificacions anteriors, en cas d'haver-hi algun error es registrarà dins la variable $error, que servirà per imprimir-ho i que l'usuari sigui conscient i verificar si és correcte actualitzar les dades o no

// Si s'ha superat totes les validacions
if ($error === '') {

Un cop verificat que no hi hagi hagut cap error, inserirem les dades obtingudes del formulari a la taula usuaris. Abans, definirem l'estat de verificació de l'email. En cas que l'email hagi estat modificat, establirem la verificació a "no", si no ho ha estat, deixarem l'estat de verificació actual

if ($email_ha_canviat) { // Si l'email ha canviat
    $nou_estat_verificacio = 'no'; // Definirem que l'estat de verificació és no
} else { // Si l'email no ha canviat
    $nou_estat_verificacio = $usuari['email_verificat']; // Valor original de l'usuari
}

En cas que s'hagi modificat la contrasenya, realitzarem un update on encriptarem al contrasenya amb la funció encriptar_contrasenya i actualitzarem no només les dades personals sinó també la contrasenya. També afegirem una acció indicant que la contrasenya s'ha restablert. En cas que la contrasenya no s'hagi modificat, únicament actualitzarem les dades personals amb les dades del formulari

if ($canvi_contrasenya) { // Si canviem la contrasenya
    $hash = encriptar_contrasenya($nova_contrasenya);
    $stmt = $pdo->prepare("
        UPDATE usuaris 
        SET nom_usuari = ?, nom_complet = ?, email = ?, telefon = ?, ciutat = ?, edat = ?, contrasenya = ?, email_verificat = ?
        WHERE id = ?
    ");
    // Fem un Update de tots els camps de la BD: Dades personals + contrasenya
    $stmt->execute([$nom_usuari, $nom_complet, $email, $telefon, $ciutat, $edat, $hash, $nou_estat_verificacio, $usuari_id]);
    registrar_activitat($pdo, $usuari_id, 'restablir-contrasenya');
} else { // Si no canviem la contrasenya
    $stmt = $pdo->prepare("
        UPDATE usuaris 
        SET nom_usuari = ?, nom_complet = ?, email = ?, telefon = ?, ciutat = ?, edat = ?, email_verificat = ?
        WHERE id = ?
    ");
    // Únicament actualitzem les dades personals
    $stmt->execute([$nom_usuari, $nom_complet, $email, $telefon, $ciutat, $edat, $nou_estat_verificacio, $usuari_id]);
}

Un cop actualitzades les dades a la BD, actualitzarem la sessió i les dades que es mostraran al formulari

// Actualizar sessió $_SESSION['usuari']['nom_usuari'] = $nom_usuari; $_SESSION['usuari']['nom_complet'] = $nom_complet; $_SESSION['usuari']['email'] = $email;

// Actualitzar les dades modificades obtenides a la consulta per mostrar-les al formulari $usuari['nom_usuari'] = $nom_usuari; $usuari['nom_complet'] = $nom_complet; $usuari['email'] = $email; $usuari['telefon'] = $telefon; $usuari['ciutat'] = $ciutat; $usuari['edat'] = $edat;

Si hem modificat el correu electrònic, esborrarem qualsevol codi de verificació que s’hagi desat a la sessió i mostrarem un missatge diferent al genèric, recordant que s’ha de tornar a verificar el correu electrònic.

if ($email_ha_canviat) { // Si hem canviat l'email

   // Borrar codi de verificació
   unset($_SESSION['codi_verificacio']);
   $correcte = "Perfil actualitzat. Com que has canviat l'email, l'hauràs de tornar a verificar.";

} else {

   $correcte = "Perfil actualitzat correctament";

}

Per últim, registrarem una acció d'usuari on indicarem que s'ha modificat el perfil

registrar_activitat($pdo, $usuari_id, 'editar-perfil');

Mostra de missatges d'error o èxit

En cas que l'usuari cometi algun error o completi l'operació amb èxit, es mostrarà un missatge a la part superior del formulari

<?php if ($error): // En cas que hi hagi un error es mostrarà?>
    <div class="alert alert-error"><?= htmlspecialchars($error) ?></div>
<?php endif; ?>

<?php if ($correcte): // En cas que hi hagi un missatge d'èxit es mostrarà?>
    <div class="alert alert-success"><?= htmlspecialchars($correcte) ?></div>
<?php endif; ?>

Un exemple de missatge d'error es visualitzaria de la següent forma


Un exemple de missatge d'èxit es visualitzaria de la següent forma

I en cas d'editar el correu electrònic es visualitzaria de la següent forma

Codi complet

<?php
date_default_timezone_set('Europe/Madrid');

session_start();
require 'funcions.php';
require './connexioBD/connexioRW.php';

// 1. Verifiquem que l'usuari està autenticat
requerir_autenticacio();

// Inicialització de les variables de missatge
$error = '';
$correcte = '';

// 2. Obtenir ID de l'usuari autenticat
$usuari_id = $_SESSION['usuari']['id'];

// 3. Obtenir les dades de l'usuari 
try {
    $stmt = $pdo->prepare("
    SELECT nom_usuari, nom_complet, email, telefon, ciutat, edat, contrasenya, email_verificat
    FROM usuaris
    WHERE id = ?
    ");
    $stmt->execute([$usuari_id]);
    $usuari = $stmt->fetch();
} catch (PDOException $e) {
    $error = "No s'ha pogut recuperar les dades de l'usuari. Motiu: " . $e->getMessage();
}  

// En cas que la consulta no retorni res, voldrà dir que no hi ha cap usuari amb aquella ID
if (!$usuari) {
    die("Usuari no trobat");
}

// 4. Processar formulari
if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    $nom_usuari  = trim($_POST['nom_usuari']);
    $nom_complet = trim($_POST['nom_complet']);
    $email       = trim($_POST['email']);
    $telefon     = trim($_POST['telefon']);
    $ciutat      = trim($_POST['ciutat']);
    $edat        = trim($_POST['edat']);
    $contrasenya_actual    = $_POST['contrasenya_actual'];
    $nova_contrasenya      = $_POST['nova_contrasenya'];
    $confirmar_contrasenya = $_POST['confirmar_contrasenya'];

    // Determinar si l'email, el telèfon o el nom d'usuari ha canviat
    $email_ha_canviat = ($email !== $usuari['email']);
    $telefon_ha_canviat = ($telefon !== $usuari['telefon']);
    $usuari_ha_canviat = ($nom_usuari !== $usuari['nom_usuari']);

    // Determinem si volem canviar la contrasenya mirant si tots els camps estan plens
    $canvi_contrasenya = ( // Si hi ha algun camp buit = fals = NO es vol canviar la contrasenya
        $contrasenya_actual !== '' ||
        $nova_contrasenya !== '' ||
        $confirmar_contrasenya !== ''
    );

    // Validacions bàsiques
    // Verifiquem que cap camp estigui buit
    if ($nom_usuari === '' || $nom_complet === '' || $email === '' || $ciutat === '' || $telefon === '' || $edat === '') {
        $error = "Els camps obligatoris no poden estar buits";
    } 

    // Verifiquem que l'email sigui realment un email
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $error = "L'email introduït no és vàlid";
    } 

    // Verifiquem que el telèfon sigui vàlid
    if (strlen($telefon) != 9) {
        $error = "Telèfon no vàlid";
    }

    // Verifiquem que la ciutat sigui vàlida
    if (strlen($ciutat) > 100) {
        $error = "Ciutat no vàlida";
    }

    // Verifiquem que l'edat sigui vàlida
    if ($edat < 18 || $edat > 120) {
        $error = "Edat no vàlida";
    }

    // Validar si el mail ja està registrat per qualsevol altre usuari
    if ($email_ha_canviat && $error === '') {
        $stmt_check = $pdo->prepare("SELECT id FROM usuaris WHERE email = ?"); // Realitzem una consulta on busquem un usuari amb el mateix email
        $stmt_check->execute([$email]); // Si retorna algun resultat, significa que el email ja està a la BD
        if ($stmt_check->fetch()) {
            $error = "Aquest email ja està registrat per un altre usuari";
        }
    }

    // Validar si el telèfon ja està registrat per qualsevol altre usuari
    if ($telefon_ha_canviat && $error === '') {
        $stmt_tel = $pdo->prepare("SELECT id FROM usuaris WHERE telefon = ?"); // Realitzem una consulta on busquem un usuari amb el mateix telèfon
        $stmt_tel->execute([$telefon]);
        if ($stmt_tel->fetch()) { // Si retorna algun resultat, significa que el telèfon ja està a la BD
            $error = "Aquest telèfon ja està registrat"; 
        }
    }

    // Validar si el nom d'usuari ja està registrat per qualsevol altre usuari
    if ($usuari_ha_canviat && $error === '') {
        $stmt_user = $pdo->prepare("SELECT id FROM usuaris WHERE nom_usuari = ?"); // Realitzem una consulta on busquem un usuari amb el mateix nom d'usuari
        $stmt_user->execute([$nom_usuari]); // Si retorna algun resultat, significa que el nom d'usuari ja està a la BD
        if ($stmt_user->fetch()) { 
            $error = "Aquest nom d'usuari ja està registrat"; 
        }
    }

    // En cas que volguem canviar la contrasenya, farem les següent validacions
    if ($canvi_contrasenya && $error === '') {
        if ($contrasenya_actual === '' || $nova_contrasenya === '' || $confirmar_contrasenya === '') { // Revisem que tots els camps estiguin plens
            $error = "Has d'omplir tots els camps de contrasenya";
        } elseif (!verificar_contrasenya($contrasenya_actual, $usuari['contrasenya'])) { // Que la contrasenya de l'usuari sigui correcte
            $error = "La contrasenya actual no és correcta";
        } elseif ($nova_contrasenya !== $confirmar_contrasenya) { // Que la nova contrasenya i la seva verificació coincideixin
            $error = "Les noves contrasenyes no coincideixen";
        }
    }

    // Si s'ha superat totes les validacions
    if ($error === '') {
        try {
            if ($email_ha_canviat) { // Si l'email ha canviat
                $nou_estat_verificacio = 'no'; // Definirem que l'estat de verificació és no
            } else { // Si l'email no ha canviat
                $nou_estat_verificacio = $usuari['email_verificat']; // Valor original de l'usuari
            }

            if ($canvi_contrasenya) { // Si canviem la contrasenya
                $hash = encriptar_contrasenya($nova_contrasenya);
                $stmt = $pdo->prepare("
                    UPDATE usuaris 
                    SET nom_usuari = ?, nom_complet = ?, email = ?, telefon = ?, ciutat = ?, edat = ?, contrasenya = ?, email_verificat = ?
                    WHERE id = ?
                ");
                // Fem un Update de tots els camps de la BD: Dades personals + contrasenya
                $stmt->execute([$nom_usuari, $nom_complet, $email, $telefon, $ciutat, $edat, $hash, $nou_estat_verificacio, $usuari_id]);
                registrar_activitat($pdo, $usuari_id, 'restablir-contrasenya');
            } else { // Si no canviem la contrasenya
                $stmt = $pdo->prepare("
                    UPDATE usuaris 
                    SET nom_usuari = ?, nom_complet = ?, email = ?, telefon = ?, ciutat = ?, edat = ?, email_verificat = ?
                    WHERE id = ?
                ");
                // Únicament actualitzem les dades personals
                $stmt->execute([$nom_usuari, $nom_complet, $email, $telefon, $ciutat, $edat, $nou_estat_verificacio, $usuari_id]);
            }

            // Actualizar sessió
            $_SESSION['usuari']['nom_usuari']   = $nom_usuari;
            $_SESSION['usuari']['nom_complet']  = $nom_complet;
            $_SESSION['usuari']['email']        = $email;

            // Actualitzar les dades modificades obtenides a la consulta per mostrar-les al formulari
            $usuari['nom_usuari']  = $nom_usuari;
            $usuari['nom_complet'] = $nom_complet;
            $usuari['email']       = $email;
            $usuari['telefon']     = $telefon;
            $usuari['ciutat']      = $ciutat;
            $usuari['edat']        = $edat;

            if ($email_ha_canviat) { // Si hem canviat l'email
                // Borrar codi de verificació
                unset($_SESSION['codi_verificacio']);
                $correcte = "Perfil actualitzat. Com que has canviat l'email, l'hauràs de tornar a verificar.";
            } else {
                $correcte = "Perfil actualitzat correctament";
            }

            registrar_activitat($pdo, $usuari_id, 'editar-perfil');

        } catch (PDOException $e) {
            $error = "Error en actualitzar les dades: " . $e->getMessage();
        }
    }
}
?>

<!DOCTYPE html>
<html lang="ca">
<head>
    <meta charset="UTF-8">
    <title>Edició de perfil d'usuari</title>
    <link rel="stylesheet" href="./css/editarPerfil.css">
</head>
<body>
    <div class="edit-container">
        <header class="edit-header">
            <h2>Editar el teu perfil</h2>
            <p>Mantén les teves dades actualitzades</p>
        </header>

        <?php if ($error): // En cas que hi hagi un error es mostrarà?>
            <div class="alert alert-error"><?= htmlspecialchars($error) ?></div>
        <?php endif; ?>

        <?php if ($correcte): // En cas que hi hagi un missatge d'èxit es mostrarà?>
            <div class="alert alert-success"><?= htmlspecialchars($correcte) ?></div>
        <?php endif; ?>

        <form method="post" class="edit-card">
            <div class="form-section">
                <h3>Dades personals</h3>
                <div class="input-grid">
                    <div class="input-group">
                        <label>Nom d'usuari</label>
                        <input type="text" name="nom_usuari" value="<?= htmlspecialchars($usuari['nom_usuari']) ?>" required>
                    </div>
                    <div class="input-group">
                        <label>Nom complet</label>
                        <input type="text" name="nom_complet" value="<?= htmlspecialchars($usuari['nom_complet']) ?>" required>
                    </div>
                    <div class="input-group full-width">
                        <label>Email <span class="info-tag">(Es requerirà nova verificació si es canvia)</span></label>
                        <input type="email" name="email" value="<?= htmlspecialchars($usuari['email']) ?>" required>
                    </div>
                    <div class="input-group">
                        <label>Telèfon</label>
                        <input type="text" name="telefon" value="<?= htmlspecialchars($usuari['telefon']) ?>" required>
                    </div>
                    <div class="input-group">
                        <label>Ciutat</label>
                        <input type="text" name="ciutat" value="<?= htmlspecialchars($usuari['ciutat']) ?>" required>
                    </div>
                    <div class="input-group">
                        <label>Edat</label>
                        <input type="number" name="edat" min="0" max="120" value="<?= htmlspecialchars($usuari['edat']) ?>" required>
                    </div>
                </div>
            </div>

            <hr class="divider">

            <div class="form-section">
                <h3>Seguretat <span class="sub-title">(Opcional)</span></h3>
                <div class="input-group">
                    <label>Contrasenya actual</label>
                    <input type="password" name="contrasenya_actual">
                </div>
                <div class="input-grid">
                    <div class="input-group">
                        <label>Nova contrasenya</label>
                        <input type="password" name="nova_contrasenya">
                    </div>
                    <div class="input-group">
                        <label>Confirmar nova contrasenya</label>
                        <input type="password" name="confirmar_contrasenya">
                    </div>
                </div>
            </div>

            <div class="form-actions">
                <a href="privada.php" class="btn-cancel">Tornar enrere</a>
                <button type="submit" class="btn-submit">Desar canvis</button>
            </div>
        </form>
    </div>
</body>
</html>