82 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| namespace nur\b\io;
 | |
| 
 | |
| use nur\file;
 | |
| use ZipArchive;
 | |
| 
 | |
| /**
 | |
|  * Class ZipStreamer: classe outil pour faciliter la construction dynamique d'un
 | |
|  * fichier zip qui est streamé vers l'utilisateur
 | |
|  */
 | |
| class ZipBuilder {
 | |
|   const TMPDIR = null;
 | |
| 
 | |
|   function __construct(string $filename) {
 | |
|     $tmpzip = file::temp("zipf", static::TMPDIR);
 | |
|     $zip = new ZipArchive();
 | |
|     if ($zip->open($tmpzip, ZipArchive::CREATE) !== true) {
 | |
|       throw new IOException("unable to create $tmpzip");
 | |
|     }
 | |
|     $this->filename = $filename;
 | |
|     $this->tmpzip = $tmpzip;
 | |
|     $this->zip = $zip;
 | |
|     $this->deletes = [$tmpzip];
 | |
|   }
 | |
| 
 | |
|   private $filename;
 | |
|   private $tmpzip;
 | |
|   private $zip;
 | |
|   private $deletes;
 | |
| 
 | |
|   /**
 | |
|    * ajouter une entrée dans le fichier zip avec le nom spécifié
 | |
|    *
 | |
|    * un fichier temporaire est préparé, et une instance permettant d'y écrire
 | |
|    * est retournée. c'est ce fichier qui sera inséré dans le fichier zip.
 | |
|    */
 | |
|   function newFile(string $entryname): IWriter {
 | |
|     $tmpfile = file::temp("zipe", static::TMPDIR);
 | |
|     $this->deletes[] = $tmpfile;
 | |
|     $outw = new FileWriter($tmpfile, "wb");
 | |
|     if ($this->zip->addFile($tmpfile, $entryname) !== true) {
 | |
|       $outw->close();
 | |
|       throw new IOException("unable to add $entryname");
 | |
|     }
 | |
|     return $outw;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * ajouter une entrée dans le fichier zip construite à partir du fichier
 | |
|    * spécifié. ce fichier doit exister jusqu'à ce que la méthode {@link send()}
 | |
|    * soit appelée
 | |
|    */
 | |
|   function addFile(string $file, ?string $entryname=null): void {
 | |
|     if ($entryname === null) $entryname = basename($file);
 | |
|     if ($this->zip->addFile($file, $entryname) !== true) {
 | |
|       throw new IOException("unable to add $file");
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * ajouter une entrée dans le fichier zip construite à partir de la chaine
 | |
|    * spécifiée
 | |
|    */
 | |
|   function addString(string $entryname, string $content): void {
 | |
|     if ($this->zip->addFromString($entryname, $content) !== true) {
 | |
|       throw new IOException("unable to add $entryname");
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /** finaliser le fichier zip et le streamer vers le client */
 | |
|   function send(): void {
 | |
|     $this->zip->close();
 | |
|     $zipf = file::open($this->tmpzip, "rb");
 | |
|     foreach ($this->deletes as $delete) {
 | |
|       unlink($delete);
 | |
|     }
 | |
|     header("Content-Type: application/zip");
 | |
|     header("Content-Disposition: attachment; filename=\"$this->filename\"");
 | |
|     fpassthru($zipf);
 | |
|   }
 | |
| }
 |