20 maggio 2016

PHP: creare dinamicamente un elenco ordinabile di file contenuti in una cartella

Nella creazione di un sito ci si può imbattere nella necessità di gestire un insieme di documenti liberamente scaricabili dagli utenti. Di per sé la realizzazione è semplice: una cartella sul server che contiene i file ed una pagina con tanti tag <a> quanti sono i documenti da scaricare. Ma, ad ogni nuovo inserimento o rimozione, saremmo costretti a mettere mano al codice HTML della pagina.
Per automatizzare il tutto ci sono varie soluzioni. Oggi vi mostreremo un metodo semplice, che non richiede l'uso del database, per visualizzare dinamicamente in una tabella un insieme di documenti scaricabili contenuti in un'unica cartella, con la possibilità di ordinare i documenti in base alla data, al nome o alle dimensioni dei file.

Per realizzare il nostro intento utilizzeremo, come abbiamo già visto in questo articolo, la funzione glob() di PHP grazie a cui è possibile memorizzare in un array i nomi dei file, con estensioni da noi specificate, contenuti in una cartella.

Qui la demo:

download elenco file
DEMO

Questo il codice HTML e PHP utilizzato per generare dinamicamente la tabella della nostra demo:

<table id="fileTable">
  <thead>
    <tr>
      <th>Data</th>
      <th>Nome</th>
      <th>Dim.</th>
      <th class="no-order">&darr;</th>
    </tr>
  </thead>
 <tbody>
 <?php
 /* ===============================================================
 Author's custom code: http://quellidelcucuzzolo.blogspot.it
 Please do not remove credit
 ============================================================== */
 foreach (glob("nomecartella/*.{doc,pdf,docx,xls}", GLOB_BRACE) as $filename) {
     $nomefile = pathinfo($filename); //array contenente nome, estensione e percorso del file
     $timefile = filemtime($filename); //data in timestamp
     $modifica = date("d/m/Y", $timefile); //data in formato dd/mm/yyyy
     $peso     = round(filesize($filename) / 1024); //dimensioni del file arrotondate ai KB
     echo "<tr>
           <td data-ordina='$timefile'>$modifica</td>
           <td class='nomefile' data-ordina='$nomefile[basename]'>$nomefile[basename]</td>
           <td class='size' data-ordina='$peso'>$peso KB</td>
           <td>
             <a href='$filename' title='Scarica il file' download><img src='img/d-icon.png' alt='icona download' /></a>
           </td>
         </tr>
         ";
 }
 ?>
 </tbody>
</table>

I parametri passati alla funzione glob()sono da personalizzare e si riferiscono al nome della cartella in cui sono inseriti i documenti (in rosso) e alle estensioni dei file scaricabili (in blu, separate da virgole):

glob("nomecartella/*.{doc,pdf,docx,xls}", GLOB_BRACE)

La forzatura del download dei file è stata affidata all'attributo HTML5 download (si fa presente che non è compatibile con tutti i browser).

Per rendere ordinabili i documenti visualizzati abbiamo utilizzato lo script TinySort, che nasce come plugin jQuery ma che è stato successivamente riscritto dall'autore in JavaScript per renderlo indipendente e più snello. Occorre quindi scaricare dal sito dell'autore (oppure dalla nostra demo) il file tinysort.min.js e richiamarlo nella pagina.
Per poter applicare lo script TinySort ad una tabella, nella documentazione dell'autore, viene proposto un codice JavaScript aggiuntivo, codice che, per semplicità nostra, non conoscendo a fondo JavaScript puro, abbiamo riconvertito in jQuery in modo da poterlo personalizzare più facilmente in base alle nostre necessità.
Si rende quindi necessario caricare preventivamente nella pagina anche la libreria jQuery.

Questo lo script da inserire in head:
<script>
$('document').ready(function() {
  var totale = $('#fileTable tbody tr').length;
  $('#totale').text(totale);
  $('#fileTable th:not(".no-order")').click(function() {
    var tableHeaderIndex = $(this).index();
    var order = $(this).attr('data-order') === 'asc' ? 'desc' : 'asc';
    $(this).attr('data-order', order);
    $(this).siblings().attr('data-order', '');
    tinysort(
      '#fileTable tbody tr', {
        selector: 'td:nth-child(' + (tableHeaderIndex + 1) + ')',
        data: 'ordina',
        order: order
      }
    );
  });
});
</script> 

Nello script originale, di default, i dati vengono ordinati in base al testo contenuto nei tag utilizzati come selettori. Nel nostro caso la data, visualizzata in formato umanamente leggibile, non è utilizzabile per l'ordinamento. Abbiamo allora scelto l'opzione di ordinamento per attributo, impostando, nel codice PHP (presentato sopra) che genera la tabella, un attributo data-ordina che contiene il valore che deve essere utilizzato per l'ordinamento.
Abbiamo aggiunto alle intestazioni di colonna delle icone di background indicanti il verso dell'ordinamento, icone che cambiano in funzione dello stato della colonna: colonna non ordinata, colonna ordinata in senso crescente, colonna ordinata in senso decrescente.
Nella variabile totale viene memorizzato il numero delle righe presenti nella tabella, quindi il numero dei documenti disponibili, che è visualizzato a inizio pagina.

Le regole CSS utilizzate per formattare la tabella sono ovviamente personalizzabili. In particolare sottolineamo che, a risoluzioni inferiori a 480px, la tabella si linearizza e le intestazioni di colonna hanno come unica funzione quella dell'ordinamento.

In rete potete trovare numerosi codici alternativi a quello da noi qui presentato per visualizzare i file contenuti in una cartella. Ne riportiamo alcuni da cui è possibile prendere ulteriori idee:



20 commenti:

  1. Didatticamente interessante. Come funzionalità trovo che dirLIST sia ottimo.
    https://sourceforge.net/projects/dir-list/
    Ciao
    Sandro

    RispondiElimina
    Risposte
    1. Ciao Sandro,

      grazie per il commento e la segnalazione, che inseriremo tra i link alla fine dell'articolo.

      Elimina
  2. Grandi come sempre! Lo provo subito. A me serviva una cosa del genere per consentire di aggiornare in maniera semplice ed immediata lo scaricamento di documenti messi a disposizione sul sito.

    RispondiElimina
    Risposte
    1. Grazie Nicola per il commento e buon lavoro.

      Elimina
  3. scusate ragazzi sarò ignorante ma l'ultima parte non l ho capite cosa è una jQueri e poi questo sistema può essere integrato a website13pro?

    RispondiElimina
    Risposte
    1. Ciao,
      jQuery è una libreria JavaScript che WebSite X5 carica già di default quindi non devi includerla.
      Certo che puoi integrare questo codice in WebSite X5.

      Elimina
  4. ok dove in inserisco il pugin tinysort?

    RispondiElimina
    Risposte
    1. Lo devi richiamare prima dello script da inserire in head.
      Se hai ancora dubbi, visualizza il sorgente della nostra demo.

      Elimina
  5. lo script in head lo inserisco in proprietà pagina sezione esperto prima della chiusura del tag head ?

    RispondiElimina
  6. Salve, in tutto il web ho trovato solo questo articolo su come visualizzare documenti che estrapolo da diverse directory e mostro nella tabella tutti i files che hanno uno stesso nome ma date differenti. Il problema è che nonostante abbia tentato diverse modifiche non sono riuscito a fare in modo che i file vengano mostrati in ordine di data quando il php si apre. Solo con le freccette si riece a mettere in ordine i dati. Poichè non sono molto esperto gradirei un suggerimento su come poter fare.

    RispondiElimina
    Risposte
    1. Ciao,
      senza intervenire sul codice PHP, puoi assegnare un id (ad esempio "load") all'elemento th della colonna che vuoi ordinare al caricamento della pagina ed inserire prima della chiusura del document ready questa riga di codice: $('th#load').trigger('click');
      QUI puoi trovare una pagina test: se hai dei dubbi visualizza il sorgente della pagina.

      Elimina
    2. Molte grazie . Provo...

      Elimina
  7. Grazie, perfetto !! Io uso questo php sul sito e ora funziona veramente bene. Peccato che ora ho un altro problema ma difficilmente risolvibile con Joomla, Cookieaccept mi funziona una volta appena installato ma poi l'avvertenza cookie non viene più visualizzata, sigh.

    RispondiElimina
    Risposte
    1. Bene, siamo contenti.
      Per quanto riguarda il problema con Joomla! ti conviene chiedere aiuto sui forum dedicati.

      Elimina
  8. Salve MAeSi,
    stavo provando il codice ma non si vede la grafica e neanche i filtri per l'ordinamento:
    http://sitiwebapp.16mb.com/dance/pagina-13.php

    RispondiElimina
    Risposte
    1. Ciao,
      la risposta è già nel tuo commento: non hai inserito alcuna regola CSS e immagine per formattare la tabella generata.
      Se apri il sorgente della nostra demo puoi prendere spunto.

      Elimina
    2. Grazie ma inserendo il CSS non ottengo il vostro stesso risultato

      Elimina
    3. "non hai inserito alcuna regola CSS e immagine"

      Leggi meglio l'articolo.

      Elimina
    4. ah vero...grazie mille!

      Elimina