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) {
$filename = basename($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);
}
Ajouter un commentaire