Segui PHP LEARN su Facebook Segui PHP LEARN su Twitter Iscriviti ai feed di PHP LEARN
CORSO COMPLETO DI PHP E NUMEROSI TUTORIAL DI PHP, MYSQL, JQUERY... E MOLTO ALTRO ?>
[Realizzare un'applicazione complessa] 7. Il profilo utente
Scritto da: Maurizio - lunedì 21 dicembre 2009 - in CORSO DI PHP


Nota. Questa unità didattica fa parte di una serie di diversi articoli ed inizia con questo. La lettura del singolo articolo non contestualizzato e disunito dagli altri può risultare incomprensibile se non addirittura fuorviante.


In questa unità didattica vedremo come implementare le funzioni del profilo utente. Come potete vedere direttamente sul forum di test, il front-end di questa pagina è implementato tramite una user interface di jquery, in particolare ui.tabs. Dovremo per tanto ricordarci di includere la libreria necessaria. Andate ora a vedere nelle demo di jqery come viene implementata questa interfaccia. Come sempre in modo molto semplice. Basterà fare una cosa del genere:


<div id="tabs">
 
	//in questa prima parte vengono definite le "linguette" con il titolo che conterranno
	// ed il riferimento al contenuto
	<ul>
		<li><a href="#tabs-1">titolo 1</li>
		<li><a href="#tabs-2">titolo 2</li>
		<li><a href="#tabs-3">titolo 3</li>
		<li><a href="#tabs-4">titolo 4</li>
	</ul>
 
	// in seguito potremo inserire il contenuto relativo alla "linguetta" con dei
	// div aventi l'id corrispondente al link
 
	<div id="tabs-1">
 
	//contenuto per titolo 1
 
	</div>
 
	<div id="tabs-2">
 
	//contenuto per titolo 2
 
	</div>
 
	// eccetera ....
 
</div>


Molto semplice davvero se si pensa al pregevole effetto finale.
Ora create il file profile_template.php e salvatelo nella cartella template/default.
Ecco il file


<h1>Profilo utente <?php echo $this->_username; ?></h1>
<br><br>
<div id="tabs">
	<ul>
		<li><a href="#tabs-1">Dati personali</a></li>
		<li><a href="#tabs-2">Password</a></li>
		<li><a href="#tabs-3">Immagine</a></li>
	</ul>
 
	<div id="tabs-1">
	<h1>Modifica dati personali</h1><br><br>
 
		<form action="profile_action.php" method="POST">
 
			Nome:<br>
			<input type="text" value="<?php echo $this->_name; ?>" name="name" class="input_form ui-corner-all" maxlength="20"/><br><br>
			Cognome:<br>
			<input type="text" value="<?php echo $this->_cname; ?>" name="cname" class="input_form ui-corner-all" maxlength="20"/><br><br>
			Username:<br>
			<input type="text" value="<?php echo $this->_username; ?>" readonly="readonly" class="input_form ui-corner-all" /><br><br>
			email:<br>
			<input type="text" value="<?php echo $this->_email; ?>" readonly="readonly" class="input_form ui-corner-all" /><br><br>
			<input type="checkbox" value="1" <?php echo $this->_mailer; ?> name="mailer" />&nbsp;Funzione mailer<br><br>
			<input type="submit" value="modifica" name="data" class="bott ui-corner-all ui-state-default" />
 
		</form>
	</div>
 
 
	<div id="tabs-2">
		<h1>Modifica password</h1><br><br>
 
		<form action="profile_action.php" method="POST">
			Nuova password:<br>
			<input type="password" class="input_form ui-corner-all" name="password" /><br><br>
			Riscrivi password:<br>
			<input type="password" class="input_form ui-corner-all" name="password2" /><br><br>
			<input type="submit" value="modifica" name="pass" class="butt ui-corner-all ui-state-default" />	
		</form>
 
	</div>
 
	<div id="tabs-3">
		<h1>Carica immagine personale</h1><br><br>
			<table border="0" cellspacing="30">
				<tr>
					<td>
						<form action="profile_action.php" method="POST" enctype="multipart/form-data">
							<input type="hidden" name="MAX_FILE_SIZE" value="71680" />
							<input type="file" name="upfile" value="" class="ui-corner-all" id="image"/>
 
							<input type="hidden" name="control" value="upload" /><br><br>
							<input type="submit" value="upload" name="upload" class="ui-corner-all ui-state-default"/>
						</form><br><br>
						L'immagine può essere al massimo 70Kb ed avere una dimensione di 65x65 px o almeno essere quadrata. In caso contrario verrà deformata.
					</td>
 
					<td valign="top">
						<center>
						Attuale<br><br>
						<img src="images/users/<?php echo $this->_img; ?>" border="0" width="65" height="65">
						</center>
					</td>
				</tr>
			</table>
	</div>
 
</div>


Come vedete per ogni “tabs” ritroviamo il form rispettivamente per i dati, la modifica password e l’upload immagine. Le variabili già inserite fanno capo alla classe profile che andremo a scrivere ora.


Create il file profile.class.php e salvatelo nella cartella lib
La classe profile sarà un’estensione di newuser in quanto andremo ad ereditare cose che ci interessano.


include_once dirname(__FILE__) . '/newuser.class.php';
 
class Profile extends NewUser
{
	public $_name;
	public $_cname;
	public $_username;
	public $_mailer;
	public $_email;
	public $_img;


Come vedete, all’inizio dichiaro le proprietà che andranno a popolare i form del profilo utente. Ora scriviamo il metodo che si occuperà di leggere i dati dell’utente e di creare la pagina del profilo.


public function ReadUserData()
{
	$sql = "SELECT name,cname,username,email,mailer,image FROM users WHERE id=$_SESSION[user_id]";
	$res = mysql_query ($sql, $this->conn);
	$row = mysql_fetch_array($res);
 
	$this->_name = stripslashes($row['name']);
	$this->_cname = stripslashes($row['cname']);
	$this->_username = stripslashes($row['username']);
	$this->_email = $row['email'];
	$this->_img = $row['image'];
	$this->_mailer = "";
 
	if($row['mailer'])
	{
		$this->_mailer = 'checked="checked"';
	}
 
	include 'template/' . TEMPLATE_NAME . '/profile_template.php';
 
	return;
}


Come potete vedere, una semplice query va a leggere i dati dell’utente. In seguito vengono valorizzate le proprietà che abbiamo precedentemente dichiarato e che vengono utilizzate nel file che abbiamo scritto all’inizio. Unica particolarità è la chekbox per la funzione mailer. Se è selezionata, dovrò aggiungere la proprietà cheked al campo del form. Infine includo il file di template.

Ora scriviamo il metodo DataModify che si occuperà di intercettare i dati inviati dal form per la modifica dei dati personali e di aggiornarli nel database.


public function DataModify()
{
	$name = mysql_real_escape_string($_POST['name']);
	$cname = mysql_real_escape_string($_POST['cname']);
	if(isset($_POST['mailer']))
	{
		$mailer = 1;
	}
	else
	{
		$mailer = 0;
	}
	$sql = "UPDATE users SET name='$name',cname='$cname',mailer=$mailer WHERE id=$_SESSION[user_id]";
	mysql_query($sql, $this->conn);
 
	header("Location: profile.php?alert=13");
 
	return;
}


Come vedete si tratta di un metodo piuttosto semplice. Passiamo ora al metodo per la modifica della password


public function PasswordModify()
{
	if($this->VerifyPassword())
	{
		if(!empty($_POST['password']))
		{
			$password = md5($_POST['password']);
			$sql = "UPDATE users SET password='$password' WHERE id=$_SESSION[user_id]";
			mysql_query($sql, $this->conn);
 
			header("Location: profile.php?alert=13");
		}
		else
		{
			header("Location: profile.php?alert=1");
		}
 
	}
	else
	{
		header("Location: profile.php?alert=2");
	}
}


Qui vedete che utilizzo il metodo VerifyPassword() che è un metodo della classe newuser e che ricorderete restituisce TRUE se le due password corrispondo e FALSE se non corrispondono. Dunque se non dovessero corrispondere tornerà a profile.php con alert=2, errore che abbiamo già utilizzato e che comunica che le due password inserite non corrispondono.
Se le due password corrispondono controlliamo che il campo non sia vuoto. Se lo dovesse essere, si tratterebbe di un errore e dunque si verrà reindirizzati a profile.php con alert=1, mentre se anche questo controllo viene superato, ecco che la password verrà aggiornata nel database.


Passiamo ora al metodo che ci permetterà di caricare l’immagine personale. Utilizzeremo la classe upload (leggermente modificata) che abbiamo visto nell’articolo “Le basi dell’upload di file“; vi consiglio vivamente di rileggerlo.

Ora che l’avete riletto, vi posto la classe modificata ed in seguito farò alcune considerazioni.


<?php
 
class Upload
{
    public      	$SavePath;
    public      	$ErrorReport;
    public  	$file = array();
    public	$FinalName;
    protected   	$AllowedExtensions = array();
    protected   	$SecurityPostName;
    protected   	$SecurityPostKey;
    protected   	$HiddenSecurity;
 
        public function __construct($path, $name, $extensions = "", $PostName ="", $PostKey = "")
        {
            $this->SavePath = $path;
            $this->file = $_FILES[$name];
 
            if ($extensions)
            {
                $this->AllowedExtensions = $this->ParseExtensions($extensions);
            }
            else
            {
                $this->AllowedExtensions = FALSE;
            }
 
            if($PostName AND $PostKey)
            {
                $this->SecurityPostKey = $PostKey;
                $this->SecurityPostName = $PostName;
                $this->HiddenSecurity = TRUE;
            }
            else
            {
                $this->HiddenSecurity = FALSE;
            }
 
            $this->ErrorManagement();
 
        }
 
        private function ParseExtensions($string)
        {
            $ExtensionsArray = explode(",", $string);
            return $ExtensionsArray;
        }
 
        private function FileExtention()
        {
            $exp = explode(".", $this->file['name']);
            $exp = array_reverse($exp);
            return $exp[0];
        }
 
 
        protected function ErrorManagement()
        {
            if ($this->HiddenSecurity)
            {
                if ($_POST[$this->SecurityPostName] != $this->SecurityPostKey)
                {
                    $this->ErrorReport = 14;
                    return FALSE;
                }
            }
 
            if ($this->AllowedExtensions)
            {
                if (!in_array($this->FileExtention(), $this->AllowedExtensions))
                {
                    $this->ErrorReport = 15;
                    return FALSE;
                }
            }
 
            switch($this->file['error'])
            {
                case UPLOAD_ERR_OK:
                $this->ErrorReport = 0;
                $this->SaveUploadFile();
                break;
 
                case UPLOAD_ERR_INI_SIZE:
                $this->ErrorReport = 16;
                break;
 
                case UPLOAD_ERR_FORM_SIZE:
                $this->ErrorReport = 17;
                break;
 
                case UPLOAD_ERR_PARTIAL:
                $this->ErrorReport = 18;
                break;
 
                case UPLOAD_ERR_NO_FILE:
                $this->ErrorReport = 19;
                break;
 
                case UPLOAD_ERR_NO_TMP_DIR:
                $this->ErrorReport = 20;
                break;
 
                case UPLOAD_ERR_CANT_WRITE:
                $this->ErrorReport = 21;
                break;
            }  
        }
 
        protected function SaveUploadFile()
        {
            if(is_uploaded_file($this->file['tmp_name']))
            {
                $this->FinalName = md5(microtime()) . '.' . $this->FileExtention();
				move_uploaded_file($this->file['tmp_name'], $this->SavePath . $this->FinalName);
                return TRUE;
            }
            else
            {
				$this->ErrorReport = 14;
                return FALSE;
			}
 
        }
}
 
 
 
?>


Le modifiche sono le seguenti:
– Ho sostituito i messaggi con i quali veniva valorizzata la proprietà ErrorReport, con i codici numerici che utilizziamo per la gestione degli errori.
– Ho rimosso il metodo che si occupava di evitare (se richiesto) l’overwriting. Al suo posto, utilizzo ora un metodo più comune che è quello di affidare un nome casuale al file. Dichiaro dunque all’inizio della classe la proprietà FinalName, che come vediamo nel metodo SaveUploadFile, viene valorizzata con il microtime passato per md5, seguito da un punto, seguito dall’estensione del file.
Ora che abbiamo questa classe, possiamo scrivere il metodo che si occuperà dell’upload dell’immagine personale


public function UploadImage()
{
	include_once 'lib/upload.class.php';
	$upload = new Upload('images/users/', 'upfile', 'gif,png,jpg,jpeg', 'control', 'upload');
 
	if($upload->ErrorReport == 0)
	{
		$this->DeleteOldImage();
 
		$sql = "UPDATE users SET image='$upload->FinalName' WHERE id=$_SESSION[user_id]";
		mysql_query($sql, $this->conn);
 
		header("Location: profile.php?alert=0");
		die;
	}
	else
	{
		header("Location: profile.php?alert=$upload->ErrorReport");
		die;
	}
}


Dunque includiamo la classe upload che abbiamo appena visto e la istanziamo con i parametri del caso.
In seguito se ErrorReport varrà 0 (dunque se il processo di upload è andato a buon fine), cancelliamo la vecchia immagine con DeleteOldImage (che scriveremo in seguito) e procediamo aggiornando il nome dell’immagine personale nel database con FinalName.
Se ErrorReport non sarà 0, semplicemente reindirizziamo a profile.php passando come valore di alert il valore di ErrorReport.


Scriviamo ora il metodo DeleteOldImage, che si occuperà appunto di cancellare l’immagine precedente a due condizioni: che l’immagine esista e soprattutto che l’immagine non sia nn.gif (che è l’immagine di default per tutti gli utenti e quindi non va cancellata).


private function DeleteOldImage()
{
	$query = "SELECT image FROM users WHERE id=$_SESSION[user_id]";
	$res = mysql_query($query, $this->conn);
	$row = mysql_fetch_array($res);
 
	if(file_exists("images/users/$row[image]") AND $row['image'] != "nn.gif")
	{
		unlink("images/users/$row[image]");
	}
}


Vi posto la classe completa


<?php
include_once dirname(__FILE__) . '/newuser.class.php';
 
class Profile extends NewUser
{
	public $_name;
	public $_cname;
	public $_username;
	public $_mailer;
	public $_email;
	public $_img;
 
		public function ReadUserData()
		{
			$sql = "SELECT name,cname,username,email,mailer,image FROM users WHERE id=$_SESSION[user_id]";
			$res = mysql_query ($sql, $this->conn);
			$row = mysql_fetch_array($res);
 
			$this->_name = stripslashes($row['name']);
			$this->_cname = stripslashes($row['cname']);
			$this->_username = stripslashes($row['username']);
			$this->_email = $row['email'];
			$this->_img = $row['image'];
			$this->_mailer = "";
 
			if($row['mailer'])
			{
				$this->_mailer = 'checked="checked"';
			}
 
			include 'template/' . TEMPLATE_NAME . '/profile_template.php';
 
			return;
		}
 
		public function DataModify()
		{
			$name = mysql_real_escape_string($_POST['name']);
			$cname = mysql_real_escape_string($_POST['cname']);
			if(isset($_POST['mailer']))
			{
				$mailer = 1;
			}
			else
			{
				$mailer = 0;
			}
			$sql = "UPDATE users SET name='$name',cname='$cname',mailer=$mailer WHERE id=$_SESSION[user_id]";
			mysql_query($sql, $this->conn);
 
			header("Location: profile.php?alert=13");
 
			return;
		}
 
		public function PasswordModify()
		{
			if($this->VerifyPassword())
			{
				if(!empty($_POST['password']))
				{
					$password = md5($_POST['password']);
					$sql = "UPDATE users SET password='$password' WHERE id=$_SESSION[user_id]";
					mysql_query($sql, $this->conn);
 
					header("Location: profile.php?alert=13");
				}
				else
				{
					header("Location: profile.php?alert=1");
				}
 
			}
			else
			{
				header("Location: profile.php?alert=2");
			}
		}
 
		public function UploadImage()
		{
			include_once 'lib/upload.class.php';
			$upload = new Upload('images/users/', 'upfile', 'gif,png,jpg,jpeg', 'control', 'upload');
 
			if($upload->ErrorReport == 0)
			{
				$this->DeleteOldImage();
 
				$sql = "UPDATE users SET image='$upload->FinalName' WHERE id=$_SESSION[user_id]";
				mysql_query($sql, $this->conn);
 
				header("Location: profile.php?alert=0");
				die;
			}
			else
			{
				header("Location: profile.php?alert=$upload->ErrorReport");
				die;
			}
		}
 
		private function DeleteOldImage()
		{
			$query = "SELECT image FROM users WHERE id=$_SESSION[user_id]";
			$res = mysql_query($query, $this->conn);
			$row = mysql_fetch_array($res);
 
			if(file_exists("images/users/$row[image]") AND $row['image'] != "nn.gif")
			{
				unlink("images/users/$row[image]");
			}
		}
 
		public function CompositeContent()
		{
			$this->ReadUserData();
		}
}
 
?>


Come vedete, alla fine ho aggiunto il metodo CompositeContent. Si tratta di quel metodo apparentemente inutile nella classe Main. Ora, in questa classe viene sovrascritto in modo che esegua il metodo ReadUserData. In questo modo, nella pagina profile.php che andremo tra poco a scrivere, ci mostrerà la pagina del profilo. Vediamo subito il file profile.php da salvare nella cartella principale


<?php
 
include_once 'lib/profile.class.php';
 
$page = new Profile();
$page->IsAuth();
$page->ExtraHeader[] = '<script type="text/javascript" src="jquery/ui/ui.tabs.js"></script>';
$page->ExtraScript[] = 'profile.js';
 
 
include 'template/' . TEMPLATE_NAME . '/template.php';
 
?>


Dopo aver incluso ed istanziato la classe Profile verifichiamo che l’utente si autenticato con il metodo IsAuth della classe Main (ovviamente per accedere al profilo utente bisogna essere autenticati).
In seguito aggiungiamo con ExtraHeader la libreria tabs di jquery. Con ExtraScript aggiungiamo il file profile.js che vedremo tra poco ed infine includiamo il template.
Il template verrà valorizzato tramite i metodi e le proprietà dalla classe Main che ereditiamo dalla classe newuser che a sua volta è un’estensione di Main. Il metodo CompositeContent, per contro, verrà sovrascritto eseguendo così il metodo ReadUserData che ci mostrerà i form per la modifica.


il file profile.js da salvare nella cartella js, sarà semplicemente così:


$("#tabs").tabs();


Indichiamo che nel div tabs sarà utilizzata la user interface tabs.


A questo punto non ci resta che scrivere il file profile_action.php da salvare nella directory principale; il file al quale puntano i tre form della pagina del profilo.


<?php
 
include_once 'lib/profile.class.php';
 
$profile = new Profile();
$profile->IsAuth();
 
if(isset($_POST['data']))
{
	$profile->DataModify();
	die;
}
if(isset($_POST['pass']))
{
	$profile->PasswordModify();
	die;
}
if(isset($_POST['upload']));
{
	$profile->UploadImage();
	die;
}
 
?>


Molto semplicemente, a dipendenza del form che ne fa richiesta, viene eseguita l’operazione necessaria.
Ed ecco fatto il nostro profilo utente.



L'autore

Maurizio (110 articoli)


Maurizio Tarchini si occupa di web dal 1999, inizialmente con siti dilettanteschi ed in seguito, perfezionando costantemente la tecnica, arriva ad avere in gestione siti di una certa importanza. Studia da autodidatta la tecnologia Apache ed attiva un proprio web server. Affascinato dalla piattaforma LAMP inizia il suo approcio con Linux ed in seguito con le tecnologie PHP e MySql. Nel luglio del 2007 riceve la prestigiosa certificazione di html.it in queste tecnologie. Si è recentemente specializzato inoltre nel framework Jquery e nelle tecnologie asincrone. Oggi Maurizio Tarchini, oltre ad occuparsi della creazione di siti web commerciali in tutte le sue fasi, sviluppa software libero per il web e librerie pubbliche, collabora in alcuni progetti open source, è membro del forum di supporto di PHP e della Free Software Foundation (Europa). E' responsabile di un'importante sito di divulgazione delle tecnologie citate ed autore o coautore di diverse pubblicazioni in ambito della programmazione. Fa parte della redazione di YIW (Your Inspiration Web), uno tra i più autorevoli punti di riferimento dell'ambiente web. E' inoltre autore del potente framework standardLib

Commenti

Lascia un commento