Prima di procedere all'estrazione dei dati risolviamo il problema della paginazione: andremo a contare quanti record soddisfano la nostra query, in base al numero di record da visualizzare per pagina definiremo il numero di pagine. Per prima cosa impostiamo un limite di 10 record per pagina:
$perpage = 10;
Poi eseguiamo la query per il conteggio dove va notata la clausola WHERE creata nel precedente ciclo:
$sql = 'SELECT id FROM '.$this->tipo.' WHERE 1 '.$where;
Eseguiamo la query con PDO e andiamo a memorizzare in una variabile $totale
il numero di record estratti:
$stmt = $db->prepare($sql);
$stmt->execute();
$totale = $stmt->rowCount();
Calcoliamo il numero di pagine totale arrotondando all'intero successivo:
$pagine = ceil($totale/$perpage);
Sanifichiamo la variabile contenente il numero di pagina. Per questo operazione creeremo un metodo ad hoc, sanitize_int($valore)
; esso riceve un input, lo sanifica tramite filter_var
e restituisce il valore ripulito.
$page = $this->sanitize_int($page);
private function sanitize_int($x){
$x = filter_var($x, FILTER_SANITIZE_NUMBER_INT);
return($x);
}
Calcoliamo infine l'indice del primo record da estrarre:
$primo = ($page-1)*$perpage;
La query va letta con attenzione, infatti oltre alle parole riservate di SQL il resto sono variabili PHP:
$sql='SELECT '.implode(',',$campi).' FROM '.$this->tipo.' WHERE 1 '.$where.' ORDER BY '.$orderby.' LIMIT '.$primo.','.$perpage;
I campi da estrarre sono contenuti nell'array $campi
che ora "esplodiamo". La tabella sarà la proprietà tipo
della classe, la clausola WHERE
l'abbiamo costruita in precedenza così come l'ORDER BY
, mentre le informazioni per la clausola LIMIT provengono dai calcoli fatti precedentemente.
Dopo aver eseguito la query:
$stmt = $db->prepare($sql);
$stmt->execute();
dovremo eseguire un ciclo while
sui dati estratti per creare le righe della tabella:
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$out.='<tr>';
e poi un ciclo for
sull'array $campi
per stampare ogni campo di ciascuna riga.
In questo secondo ciclo inseriremo due controlli: il primo verifica se si tratta di una data e la formatta in modo corretto, il secondo per verificare se si tratta di una tabella di relazione e mostrare il valore corrispondente e non la variabile $id
.
Per questo dobbiamo interrogare la tabella struttura
usando come clausola WHERE
la tabella su cui lavoriamo e il nome del campo che recuperiamo grazie all'indice del secondo ciclo:
for($i=0;$itipo.'" AND nome="'.$campi[$i].'" LIMIT 1';
Eseguiamo la query:
$stmt1 = $db->prepare($sql); $stmt1->execute(); $row1 = $stmt1->fetch(PDO::FETCH_ASSOC);
E procediamo con il primo controllo. Se si tratta di una data modifichiamo il formato grazie a un metodo private
definito ad hoc:
if($row1['tipo_input']=='date'){$testo = $this->giradata_ita($row[$campi[$i]]);}
Ecco il codice del metodo:
private function giradata_ita($valore){
$list = explode('-',$valore);
$valore = $list[2].'-'.$list[1].'-'.$list[0];
return($valore);
}
Il valore restituito sarà memorizzato in una variabile $testo
.
Il secondo controllo riguarda le tabelle di relazione, in questo caso se il tipo di input è una SELECT
dovremo interrogare la tabella di relazione e non la tabella principale:
else if($row1['tipo_input']=='select'){
$sql = 'SELECT '.$row1['origine_testo'].' FROM '.$row1['origine_tabella'].' WHERE '.$row1['origine_id'].'="'.$row[$campi[$i]].'"';
$stmt2 = $db->prepare($sql);
$stmt2->execute();
$row2 = $stmt2->fetch(PDO::FETCH_ASSOC);
$testo = $row2[$row1['origine_testo']];
}
Quindi usiamo i campi della tabella struttura e nella clausola WHERE verifichiamo la corrispondenza fra $id
della tabella principale e la chiave esterna oggetto del ciclo. Anche in questo caso l'esito sarà memorizzato in una variabile $testo
.
Per tutti gli altri casi possiamo tranquillamente limitarci a leggere il contenuto del campo:
else{
$testo = $row[$campi[$i]];
}
Con la variabile $testo
valorizzata possiamo stampare l'HTML:
$out.='<td class="'.$campi[$i].'">'.$testo.'</td>';
Alla fine del ciclo sui campi da estrarre creiamo quattro bottoni per le funzionalità dettaglio, edit, copia ed elimina. Saranno normalissimi link contenenti la variabile $id
e $azione
che stabilirà quale metodo della classe richiamare.
Esaurito il ciclo esterno sulle righe estratte dal database resta da creare la paginazione ma si tratta di un semplice ciclo sul numero totale di pagine:
for($i=1;$i
Questa di fatto era la nostra ultima operazione di questo primo metodo. Passiamo ora alla prima pagina dove useremo la nostra classe.