Drupal 8 et Drupal 9 - Créer une archive Zip

Posté le Jeudi 27 août 2020 - 09:23

Voici comment créer une archive zip et y ajouter des fichiers.

Pour commencer, nous aurons besoin d'injecter deux services, (ici je suis dans un formulaire, à adapter en fonction du contexte)

  public static function create(ContainerInterface $container) {
    $instance = parent::create($container);
    $instance->fileSystem = $container->get('file_system');
    $instance->archiver = $container->get('plugin.manager.archiver');
    return $instance;
  }

Création de l'archive en tant que telle :

// $files contient un tableau de chemin de fichiers à ajouter à l'archive
$files = ['private://monfichier1.pdf', 'private://monfichier2.pdf'];

// Chemin où sera enregistré l'archive
$archivePath = 'private://pdf-export/mon-archive.zip';

// On crée l'archive physiquement sur le disque, avec un contenu vide
// FileSystemInterface::EXISTS_REPLACE indique que si le fichier existe déjà on le remplace, il existe d'autres options
$this->fileSystem->saveData('', $archivePath, FileSystemInterface::EXISTS_REPLACE);

//On récupère l'objet Zip pointant vers l'archive que nous venons de créer.
/** @var Zip $zip */
$zip = $this->archiver->getInstance(['filepath' => $archivePath]);

foreach ($files as $file)  {
  $filepath = $this->fileSystem->realpath($file);
  $zip->add($filepath, $filename);
}

Et voila, cela fonctionne mais ça n'est pas forcément top... Pourquoi pas forcément top ? car toute l’arborescence des différents fichiers est recrée dans l'archive :

Image

 Ça n'est pas forcement très gênant, mais dans mon cas je préférais avoir tous les fichiers à la racine de mon archive. Voila comment faire :

// $files contient un tableau de chemin de fichiers à ajouter à l'archive
$files = ['private://monfichier1.pdf', 'private://monfichier2.pdf'];

// Chemin où sera enregistré l'archive
$archivePath = 'private://pdf-export/mon-archive.zip';

// On crée l'archive physiquement sur le disque, avec un contenu vide
// FileSystemInterface::EXISTS_REPLACE indique que si le fichier existe déjà on le remplace, il existe d'autres options
$this->fileSystem->saveData('', $archivePath, FileSystemInterface::EXISTS_REPLACE);

//On récupère l'objet Zip pointant vers l'archive que nous venons de créer.
/** @var Zip $zip */
$zip = $this->archiver->getInstance(['filepath' => $archivePath]);

// $zip est juste un wrapper Drupal vers un objet \ZipArchive que l'on va récuprérer ici dans $zipArchive
$zipArchive = $zip->getArchive();

foreach ($files as $file)  {
  // on récupère le nom de fichier, sans le chemin
  $filename = basename($file);
  $filepath = $this->fileSystem->realpath($file);

  // on ajoute le fichier à l'archive mais en indiquant comme chemin uniquement le nom du fichier, ainsi, plus de création de dossier
  $zipArchive->addFile($filepath, $filename);
}

 

Aller plus loin ?

Ajouter un commentaire

Ne sera pas publié

CAPTCHA Désolé, pour ça, mais c'est le seul moyen pour éviter le spam...