8790 sujets

Développement web côté serveur, CMS

Bonjour, je ne sais pas trop si je suis au bon endroit c'est une première pour moi sur un forum.
Pour ouvrir la discussion voici ma problématique, j'ai un espace client privé qui affiche dans un tableau une liste de facture qui est en base données avec un bouton PDF et quand on clique dessus la facture est générée puis ouverte dans un nouvel onglet pour que le client puisse consulter sa facture et la télécharger. Problème et cela n'avait pas tait prévu les clients ont finalement donné leurs accès à leurs comptables et bien sur maintenant les clients souhaitent sélectionner plusieurs factures et toutes les télécharger en une fois dans un fichier ZIP (je pense que c’est le mieux mais ouvert aux propositions alternatives).
Après plusieurs manipulation et tentatives seul et avec ChatGPT, j'arrive à créer une colonne pour la sélection des factures une par une ou avec un bouton tout sélectionner en début et fin de tableau, j'ai créé un bouton de téléchargement et la soit il ne se passe rien soit j'arrive à avoir un fichier ZIP mais impossible de l'ouvrir il est endommagé ou vide bref cela ne marche pas. J'aimerai savoir de quoi avez-vous besoin pour m'aider car je dois avouer avoir du code de partout et être revenu au début à chaque fois pour éviter de laisser une fonction qui ne fonctionne pas en ligne ce qui est pas top.
SI vous avez une liste des besoins, liste, versions serveur ou PHP, code etc...demandez moi que je fournisse l'ensemble en une fois. Je dois avouer être un peu dépassé car je pensais pas que cela soit aussi compliqué pour une fonction assez commune mais comme le code et le développement sont très alambiqué on va dire, la personne qui a fait le site et qui est compétente car cela fonctionne avec le bouton PDF étant devenu injoignable je fais appel à vous.
Pour info développé sur CMS MadeSimple. Voila j'attends vos demande de code version etc...et j'espère trouver une solution grâce à la communauté.
Modérateur
Bonjour,

A quoi ressemble la structure de ton formulaire et comment est -il traité ?
A quoi ressemble ton script qui créer le fichier zip puis y ajoute tes pdf ?

Ce que tu veut faire est possible , mais sans code pour voir comment tu t'y prend et découvrir où ça coince, il va être difficile de t'aider.

S'agit-il d'un plugin embarqué que tu veut modifier ? Si oui lequel et sur quel version de ton CMS

Cdt
Modifié par gcyrillus (26 Mar 2025 - 19:22)
alors voici la structure de la page qui liste les factures :

{$uid=feu_smarty::get_current_userid()}
{$expired=feu_smarty::user_expired($uid)}
{if $expired || $uid == ''}
<h1> Vous n'êtes plus connecté </h1>
{cms_selflink href='home' assign='requested_url'}
{$requested_url=$requested_url scope=global}
<script>
$(location).attr('href', '{$requested_url}');
</script>
{redirect_url to=$requested_url}
{/if}

{authPDF OKPDF='TRUE'}
{*$smarty.session|@print_r*}
{*{get_documents where="DOC_NUMERO='0000247038'"}
{assign var='title' value='0000247038' scope=global}
{$count_doc}
{$documents|print_r}
{get_lignes where="DOC_NUMERO='0000247038'"}
{$lignes|@print_r}
{$count_lig}*}
{*
{$smarty.now|date_format:'%B %Y'}
{$smarty.now|date_format:'%d-%m-%Y %H:%M:%S'}
*}

{$userprops=feu_smarty::get_user_properties()}
{$time = $smarty.now|date_format:'%Y-%m-%d'}
{if $smarty.get.StartDateMonth && $smarty.get.StartDateYear}
{$time = "{$smarty.get.StartDateYear}-{$smarty.get.StartDateMonth}-01"}
{/if}


<h4 class="txtcenter">{$userprops.raison_sociale} ({feu_smarty::get_username($the_uid)})</h4>

<div class="txtcenter mbm">
{$op_annee = 0}
<a href="{$content_obj->GetURL()}?StartDateMonth={if {$time|date_format:'%m'} > 1}{{$time|date_format:'%m'}-1}{else}12{$op_annee = -1}{/if}&StartDateYear={{$time|date_format:'%Y'}+$op_annee}{if $userprops.super_utilisateur}&user_select={$smarty.get.user_select}{/if}" class="u-bigger prev-month arrow-date mrs"><i class="icon-arrow--left"></i></a>
<h2 class="inbl u-uppercase">{$time|date_format:'%B %Y'}</h2>
{$op_annee = 0}
<a href="{$content_obj->GetURL()}?StartDateMonth={if {$time|date_format:'%m'} < 12}{{$time|date_format:'%m'}+1}{else}1{$op_annee = 1}{/if}&StartDateYear={{$time|date_format:'%Y'}+$op_annee}{if $userprops.super_utilisateur}&user_select={$smarty.get.user_select}{/if}" class="u-bigger next-month arrow-date mls"><i class="icon-arrow--right"></i></a>
<form id="selectDate" action="{$content_obj->GetURL()}" method="get" class="txtcenter">
<p>{html_select_date prefix="StartDate" time=$time start_year="2023" end_year="+1" display_days=false reverse_years=true}</p>

{$selected_user = false}
{if $userprops.super_utilisateur}
<p>{$Ambapharm_members=feu_smarty::get_users_by_groupname('Axipharm')}
<label for="user_select" class="inbl mts">Choisir un compte</label>
<select name="user_select" id="user_select" class="w66">
<option value="">Tout</option>
{foreach $Ambapharm_members user}
<option value="{$user.id}"{if $user.id == $smarty.get.user_select} selected{$selected_user = feu_smarty::get_user_property('id_pharmaml',$user.id)}{/if}>{feu_smarty::get_user_property('raison_sociale',$user.id)} ({$user.username})</option>
{/foreach}
</select></p>
{else}
{$selected_user = $userprops.id_pharmaml}
{/if}

{if $selected_user !== false && $selected_user == ''}
{$selected_user = 'NOPE'}
{/if}
</form>
<script>
{literal}
$('#selectDate select').on('change', function() {
$('#selectDate').submit();
});
{/literal}
</script>
<div class="inbl tiny-w100 center bdrform" style="background-color:#f8f9fa;">
<form id="formrecherche" action="{$content_obj->GetURL()}" method="get" class="txtcenter">
<label for="recherche" class="w100">Rechercher une facture</label>
<div>
<span class="mts"><input id="recherche" class="tiny-w50" name="recherche" type="search" placeholder="FA 000000" value="{$smarty.get.recherche}"></span>
<span class="mts">
<input type="submit" value="OK" class="btn">
{if $smarty.get.recherche}<input type="reset" value="Reset" class="btn bdr">{/if}
</span>
</div>
</form>
<script>
{literal}
$('#formrecherche input:reset').bind('click', function() {
$('#selectDate').submit();
});
{/literal}
</script>
</div>
</div>
{if isset($smarty.get.recherche) && $smarty.get.recherche != '' && !$userprops.super_utilisateur}
{get_documents_search recherche = $smarty.get.recherche PCF_CODE = $selected_user}
{elseif isset($smarty.get.recherche) && $smarty.get.recherche != '' && $userprops.super_utilisateur}
{get_documents_search recherche = $smarty.get.recherche}
{else}
{capture name="where"}
YEAR(DOC_DATE) = {$time|date_format:'%Y'} AND MONTH(DOC_DATE) = {$time|date_format:'%m'} AND PCF_CODE <> '0' {if $selected_user} AND PCF_CODE = '{$selected_user}'{/if} ORDER BY DOC_DATE DESC{/capture}
{get_documents where = $smarty.capture.where}
{/if}
<table id="tableau" class="tableau display cell-border compact stripe" data-order='[[ 1, "desc" ],[ 0, "desc" ],[ 2, "desc" ],[ 3, "desc" ]]' data-page-length='50'>
<thead>
<tr>
<th class="txtcenter" data-class-name="priority">N<sup>o</sup> de facture</th>
<th class="txtcenter">Date de facture</th>
<th class="txtcenter">Date d'échéance</th>
<th class="txtcenter">Montant brut</th>
<th class="txtcenter">TVA</th>
<th class="txtcenter">Net à payer</th>
<th class="txtcenter" data-searchable='false' data-orderable='false'>Éditer la facture</th>

</tr>
</thead>
<tfoot>
<tr>
<th class="txtcenter" data-class-name="priority">N<sup>o</sup> de facture</th>
<th class="txtcenter">Date de facture</th>
<th class="txtcenter">Date d'échéance</th>
<th class="txtcenter">Montant brut</th>
<th class="txtcenter">TVA</th>
<th class="txtcenter">Net à payer</th>
<th class="txtcenter" data-searchable='false' data-orderable='false'>Éditer la facture</th>


</tr>
</tfoot>
<tbody>
{if $count_doc > 0}
{foreach $documents as $document}
<tr>
<td class="txtcenter u-bold">{$document['DOC_PIECE']}</td>
<td class="txtcenter">{$document['DOC_DATE']|date_format:"%d/%m/%y"}</td>
<td class="txtcenter">{$document['ECH_DATE']|date_format:"%d/%m/%y"}</td>
<td class="txtright tiny-txtcenter">{$document['DOC_BRUT']|number_format:2:',':''}<span class="tiny-hidden"> €</span></td>
<td class="txtright">{$document['DOC_MT_TVA']|number_format:2:',':''}<span class="tiny-hidden"> €</span></td>
<td class="txtright">{$document['DOC_MT_NET']|number_format:2:',':''}<span class="tiny-hidden"> €</span></td>
<td class="txtcenter">
<form method="post" action="facture_axipharm_pdf.php?facture={$document['DOC_PIECE']|replace:' ':''}" target="_blank">
<input type="hidden" name="PCF_CODE" value="{$document['PCF_CODE']}">
<input type="hidden" name="DOC_NUMERO" value="{$document['DOC_NUMERO']}">
<input type="hidden" name="DOC_PIECE" value="{$document['DOC_PIECE']|replace:' ':''}">
<input type="hidden" name="CLE" value="{(($document['DOC_NUMERO']+$document['PCF_CODE'])/3+2)|round}">
{*<input type="hidden" name="CLE" value="{($document['DOC_NUMERO']+$document['PCF_CODE'])}">*}
<button type="submit" name="PDF" class="btn">PDF <i class='icon-arrow--right tiny-hidden'></i></button>
</form>
</td>
</tr>
{/foreach}
{else}
<tr>
<td class="txtcenter" colspan="7">
<h3 class="txtcenter mtl mbl">{if $alerte}{$alerte}{else}IL N'Y A PAS DE FACTURE ENREGISTRÉE POUR CETTE PÉRIODE{/if}</h3>
</td>
</tr>
{/if}
</tbody>
</table>
<div class="txtcenter mtl mbl">
{$op_annee = 0}
<a href="{$content_obj->GetURL()}?StartDateMonth={if {$time|date_format:'%m'} > 1}{{$time|date_format:'%m'}-1}{else}12{$op_annee = -1}{/if}&StartDateYear={{$time|date_format:'%Y'}+$op_annee}{if $userprops.super_utilisateur}&user_select={$smarty.get.user_select}{/if}" class="u-bigger prev-month arrow-date mrs"><i class="icon-arrow--left"></i></a>
<h2 class="inbl u-uppercase">{$time|date_format:'%B %Y'}</h2>
{$op_annee = 0}
<a href="{$content_obj->GetURL()}?StartDateMonth={if {$time|date_format:'%m'} < 12}{{$time|date_format:'%m'}+1}{else}1{$op_annee = 1}{/if}&StartDateYear={{$time|date_format:'%Y'}+$op_annee}{if $userprops.super_utilisateur}&user_select={$smarty.get.user_select}{/if}" class="u-bigger next-month arrow-date mls"><i class="icon-arrow--right"></i></a>
</div>

Voici le code qui créé le PDF quand on clique sur le bouton PDF :

<?php
require_once __DIR__.'/vendor/autoload.php';

use Spipu\Html2Pdf\Html2Pdf;
use Spipu\Html2Pdf\Exception\Html2PdfException;
use Spipu\Html2Pdf\Exception\ExceptionFormatter;

require_once __DIR__.'/config.php';
$conn = mysqli_connect($config['db_hostname'], $config['db_username'], $config['db_password'], $config['db_name']);


if (!$conn) {
//echo "Erreur : Impossible de se connecter à MySQL." . PHP_EOL;
//echo "Errno de débogage : " . mysqli_connect_errno() . PHP_EOL;
//echo "Erreur de débogage : " . mysqli_connect_error() . PHP_EOL;
exit;
}

$DOC_NUMERO = isset($_POST["DOC_NUMERO"])? $_POST["DOC_NUMERO"] : FALSE;
$PCF_CODE = isset($_POST["PCF_CODE"])? $_POST["PCF_CODE"] : FALSE;
$DOC_PIECE = isset($_POST["DOC_PIECE"])? $_POST["DOC_PIECE"] : FALSE;
if( $DOC_PIECE != $_GET["facture"]){
$DOC_PIECE = FALSE;
}

$CLE = isset($_POST["CLE"])? $_POST["CLE"] : FALSE;
//if( $CLE != ($DOC_NUMERO + $PCF_CODE) ){
if( $CLE != round(($DOC_NUMERO + $PCF_CODE)/ 3 + 2 )){
$CLE = FALSE;
}

$edit_PDF = FALSE;

while(list ($key, $val) = each ($_COOKIE)) {
if(strstr($key, 'CMSSESSID') ) {
$session_key = $key;
break;
}
}
@session_name($session_key);
session_start();
//if ($DOC_NUMERO && is_numeric($DOC_NUMERO) && $PCF_CODE && $DOC_PIECE && $CLE && $_SESSION["OKPDF"]) {
if ($DOC_NUMERO && is_numeric($DOC_NUMERO) && $PCF_CODE && is_numeric($PCF_CODE) && $DOC_PIECE && $CLE && $_SESSION["OKPDF"]) {
//if ($DOC_NUMERO && is_numeric($DOC_NUMERO) && is_numeric($PCF_CODE) && is_numeric($PCF_CODE) && $DOC_PIECE && $CLE && $_SESSION["OKPDF"]) {
//if ($DOC_NUMERO && is_numeric($DOC_NUMERO) && $PCF_CODE && is_numeric($PCF_CODE) && $DOC_PIECE && $CLE) {
$sqlVerif = "SELECT COUNT(IF(DOC_NUMERO = '".$DOC_NUMERO."' AND PCF_CODE = '".$PCF_CODE."', 1, NULL)) as 'nb_doc' FROM ambapharm_documents"; //vérification d'occurence en BD
$resultVerif = mysqli_query($conn, $sqlVerif);
$data = mysqli_fetch_assoc($resultVerif);
//echo '<br/>Résultat pour DOC_NUMERO et PCF_CODE dans la table DOCUMENTS : '.$data['nb_doc'].' élément(s) trouvé(s)<br/>';
if ($data['nb_doc'] > 0) {
$sqlVerif = "SELECT COUNT(IF(DOC_NUMERO = '".$DOC_NUMERO."', 1, NULL)) as 'nb_lig' FROM ambapharm_lignes"; //vérification d'occurence en BD
$resultVerif = mysqli_query($conn, $sqlVerif);
$data = mysqli_fetch_assoc($resultVerif);
//echo '<br/>Résultat pour DOC_NUMERO dans la table LIGNES : '.$data['nb_lig'].' élément(s) trouvé(s)<br/>';
if ($data['nb_lig'] > 0) {
$edit_PDF = TRUE;
} else {
echo "Erreur : Les valeurs de requêtes transmises ne correspondent à 1 facture archivée mais aucune ligne correspondante.";
$type = "error";
$message = "Aucune ligne dans la facture correspondante";
exit;
}
} else {
echo "Erreur : Les valeurs de requêtes transmises ne correspondent à aucune facture archivée.";
$type = "error";
$message = "Aucune facture correspondante";
exit;
}
} else {
echo "Erreur : Les valeurs de requêtes transmises sont incomplètes.";
$type = "error";
$message = "Aucune facture correspondante";
exit;
}

try {
ob_start();
include __DIR__.'/facture_axipharm_contenu.php';
$content = ob_get_clean();
$html2pdf = new Html2Pdf('P', 'A4', 'fr', true, 'UTF-8', array(0, 0, 0, 0));
$html2pdf->pdf->SetDisplayMode('fullpage');
$html2pdf->setTestIsImage(false);
$html2pdf->setFallbackImage('./examples/res/off.png');
$html2pdf->writeHTML($content);
$html2pdf->output(str_replace(" ", "", $doc['DOC_PIECE']).'.pdf');
} catch (Html2PdfException $e) {
$html2pdf->clean();

$formatter = new ExceptionFormatter($e);
echo $formatter->getHtmlMessage();
}

Avez vous besoin du code du masque de facture qui se trouve dans facture_axipharm_contenu.php ?
Modifié par Bus (26 Mar 2025 - 20:30)
pour le moment j'ai enlevé le code pour effectuer ma demande je me suis dit partir de ce que j'ai à la base sera plus simple, je souhaite ajouter une colonne pour sélectionner plusieurs PDF et une case tout sélectionner et un bouton télécharger les PDF qui vont dans un ZIP téléchargé directement dans le navigateur. Pour ce qui est du code pour le ZIP j'en ai tellement des essais que je me suis noyé dedans et je me demande si ce n'est pas plus simple de partir de zéro que chercher une erreur ?
Modérateur
Bonsoir,

désolé de ne pas être repassé plus tôt.

En fait je ne voulais voir que le html rendu par le navigateur et en particulier comment tu gérer les checbox pour sélectionner tes fichiers. et pas tout ce code qui fabrique à la volée les PDF.
En gros , si tu as plusieurs checkbox, il peut-être plus simple d'utiliser la même valeur pour l'attribut name pour toutes ces cases à cochées et leur attribué un id si tu as besoin de les liés à un label.
Après soumission du formulaire un tableau à traiter plutôt est plus simple que de tester une ribambelle de données individuelles. C'est la partie de ton traitement de formulaire qui m’intéressait à voir.


A partir de la, on à quelque chose à envoyer à ta fonction de zippage qui devrait :
1. créer ou remettre à zéros un fichier ZIP
2. boucler sur les pdf sélectionner à inclure. (si il n'y en a pas des centaines , il n'est pas forcement utile de sauvegarder le fichier à chaque fois.)
3. renvoyer au navigateur le fichier créer et rempli avec la selection avec les bon ent^tes pour déclencher le téléchargement .

Là idem, il n'y a probablement pas grand chose à faire sur ton script pour qu'il te donne tous tes fichiers et pas un seul.

L'idée de tout reprendre de zéro ne va t'aider à part reperdre du temps, cade plus je n'ai pas ce CMS d'installé sur ma machine , ni les données qui vont avec pour le tester. Le code que tu partage à priori ne sert qu'a afficher un pdf , il ne sert pas a grand chose à priori pour ton soucis.

Si tu peut nous donner
- le HTML contenant ton formulaire avec un tableau de 2 ou 3 pdf (cela suffit amplement) et leurs liens de téléchargement individuels et cases à cochées.
- le script qui récupère la soumission de ton formulaire avec la partie qui traite les cases cochées
- le script qui construit ton fichier ZIP et le renvoi au visiteur.

Cdt
Modifié par gcyrillus (28 Mar 2025 - 01:12)
Bonjour, alors je comprends ta demande mais je ne pourrais pas te fournir deux trois PDF car ils sont en bases de données et créés à la demande en appuyant sur le bouton PDF comme je l'ai posté dans mon premier message, par contre ci dessous je vais poster ce que j'ai fait pour ajouter dans le tableau qui liste les factures une colonne avec les cases à cocher et le code de la page qui s'occupe de créer les PDF et les inclure dans un fichier ZIP.
Avec le code que je vais partager mon problème c'est que cela récupère bien les numéros de factures, cela récupère les masques de factures et ajoute le tout dans un fichier ZIP. problème les factures sont vides il n'y a que le masque de facture sans données dedans.

Page Lise Facture avec colonne case à cocher et Bouton télécharger le ZIP :
<form method="post" action="download_zip.php" id="downloadForm">
<input type="hidden" name="PCF_CODE" value="{$document['PCF_CODE']}">
<input type="hidden" name="DOC_NUMERO" value="{$document['DOC_NUMERO']}">
<input type="hidden" name="DOC_PIECE" value="{$document['DOC_PIECE']|replace:' ':''}">
<input type="hidden" name="CLE" value="{(($document['DOC_NUMERO']+$document['PCF_CODE'])/3+2)|round}">
<table id="tableau" class="tableau display cell-border compact stripe" data-order='[[ 1, "desc" ],[ 0, "desc" ],[ 2, "desc" ],[ 3, "desc" ]]' data-page-length='50'>
<thead>
<tr>
<th class="txtcenter" data-class-name="priority">
<input type="checkbox" id="selectAll">
</th>
<th class="txtcenter" data-class-name="priority">N<sup>o</sup> de facture</th>
<th class="txtcenter">Date de facture</th>
<th class="txtcenter">Date d'échéance</th>
<th class="txtcenter">Montant brut</th>
<th class="txtcenter">TVA</th>
<th class="txtcenter">Net à payer</th>
<th class="txtcenter" data-searchable='false' data-orderable='false'>Éditer la facture</th>

</tr>
</thead>
<tfoot>
<tr>
<th class="txtcenter" data-class-name="priority">
<input type="checkbox" id="selectAllFooter">
</th>
<th class="txtcenter" data-class-name="priority">N<sup>o</sup> de facture</th>
<th class="txtcenter">Date de facture</th>
<th class="txtcenter">Date d'échéance</th>
<th class="txtcenter">Montant brut</th>
<th class="txtcenter">TVA</th>
<th class="txtcenter">Net à payer</th>
<th class="txtcenter" data-searchable='false' data-orderable='false'>Éditer la facture</th>
</tr>
</tfoot>
<tbody>
{if $count_doc > 0}
{foreach $documents as $document}
<tr>{*<td class="txtcenter">
<input type="checkbox" name="selected_invoices[]" value="{$document['DOC_NUMERO']}">
</td>*}
<td class="txtcenter u-bold">{$document['DOC_PIECE']}</td>
<td class="txtcenter">{$document['DOC_DATE']|date_format:"%d/%m/%y"}</td>
<td class="txtcenter">{$document['ECH_DATE']|date_format:"%d/%m/%y"}</td>
<td class="txtright tiny-txtcenter">{$document['DOC_BRUT']|number_format:2:',':''}<span class="tiny-hidden"> €</span></td>
<td class="txtright">{$document['DOC_MT_TVA']|number_format:2:',':''}<span class="tiny-hidden"> €</span></td>
<td class="txtright">{$document['DOC_MT_NET']|number_format:2:',':''}<span class="tiny-hidden"> €</span></td>
<td class="txtcenter">
<form method="post" action="facture_axipharm_pdf.php?facture={$document['DOC_PIECE']|replace:' ':''}" target="_blank">
<input type="hidden" name="PCF_CODE" value="{$document['PCF_CODE']}">
<input type="hidden" name="DOC_NUMERO" value="{$document['DOC_NUMERO']}">
<input type="hidden" name="DOC_PIECE" value="{$document['DOC_PIECE']|replace:' ':''}">
<input type="hidden" name="CLE" value="{(($document['DOC_NUMERO']+$document['PCF_CODE'])/3+2)|round}">
{*<input type="hidden" name="CLE" value="{($document['DOC_NUMERO']+$document['PCF_CODE'])}">*}
<button type="submit" name="PDF" class="btn">PDF <i class='icon-arrow--right tiny-hidden'></i></button>
</form>
</td>
</tr>
{/foreach}
{else}
<tr>
<td class="txtcenter" colspan="7">
<h3 class="txtcenter mtl mbl">{if $alerte}{$alerte}{else}IL N'Y A PAS DE FACTURE ENREGISTRÉE POUR CETTE PÉRIODE{/if}</h3>
</td>
</tr>
{/if}
</tbody>
</table>
<button type="submit" class="btn">Télécharger les factures sélectionnées</button>
</form>
<script>
document.getElementById('selectAll').addEventListener('change', function () {
var checkboxes = document.querySelectorAll('input[name="selected_invoices[]"]');
for (var checkbox of checkboxes) {
checkbox.checked = this.checked;
}
});
document.getElementById('selectAllFooter').addEventListener('change', function () {
var checkboxes = document.querySelectorAll('input[name="selected_invoices[]"]');
for (var checkbox of checkboxes) {
checkbox.checked = this.checked;
}
});

document.getElementById('downloadForm').addEventListener('submit', function(event) {
var checkboxes = document.querySelectorAll('input[name="selected_invoices[]"]:checked');
if (checkboxes.length === 0) {
event.preventDefault();
alert('Veuillez sélectionner au moins une facture.');
}
});
</script>
Code download_zip.php :
<?php
require_once __DIR__.'/vendor/autoload.php';
use Spipu\Html2Pdf\Html2Pdf;
use Spipu\Html2Pdf\Exception\Html2PdfException;
use Spipu\Html2Pdf\Exception\ExceptionFormatter;
require_once __DIR__.'/config.php';

$conn = mysqli_connect($config['db_hostname'], $config['db_username'], $config['db_password'], $config['db_name']);

if (!$conn) {
echo "Erreur : Impossible de se connecter à MySQL." . PHP_EOL;
echo "Errno de débogage : " . mysqli_connect_errno() . PHP_EOL;
echo "Erreur de débogage : " . mysqli_connect_error() . PHP_EOL;
exit;
}

if (isset($_POST['selected_invoices']) && is_array($_POST['selected_invoices'])) {
$selected_invoices = $_POST['selected_invoices'];
$zip = new ZipArchive();
$zip_filename = tempnam(sys_get_temp_dir(), 'invoices') . '.zip';

if ($zip->open($zip_filename, ZipArchive::CREATE) !== TRUE) {
exit("Impossible d'ouvrir le fichier ZIP\n");
}

foreach ($selected_invoices as $invoice_num) {
$sql = "SELECT * FROM ambapharm_documents WHERE DOC_NUMERO = '$invoice_num'";
$result = mysqli_query($conn, $sql);
$document = mysqli_fetch_assoc($result);

if ($document) {
ob_start();
// Utilisez le contenu de la facture approprié
include __DIR__.'/facture_axipharm_contenu.php';
$content = ob_get_clean();

try {
$html2pdf = new Html2Pdf('P', 'A4', 'fr', true, 'UTF-8', array(0, 0, 0, 0));
$html2pdf->pdf->SetDisplayMode('fullpage');
$html2pdf->setTestIsImage(false);
$html2pdf->setFallbackImage('./examples/res/off.png');
$html2pdf->writeHTML($content);
$pdf_content = $html2pdf->output('', 'S');

$zip->addFromString("N°_{$document['DOC_PIECE']}.pdf", $pdf_content);
} catch (Html2PdfException $e) {
$formatter = new ExceptionFormatter($e);
echo $formatter->getHtmlMessage();
}
}
}

$zip->close();

header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="factures.zip"');
header('Content-Length: ' . filesize($zip_filename));
readfile($zip_filename);
unlink($zip_filename);
} else {
echo "Aucune facture sélectionnée.";
}
?>

Voila j'espère avoir donné les éléments necessaires et merci pour votre temps et vos réponses.
Modérateur
Bojour,

une ligne m'intrigue: include __DIR__.'/facture_axipharm_contenu.php';
$document correspond t-il bien a ce que le script de ce fichier attend ?



Puis : $pdf_content = $html2pdf->output('', 'S'); m'intrigue aussi pour la variable de nom de fichier vide , je ne suis pas familier de html2pdf , ce n'est peut-être pas nécessaire avec l'option 'S' , mais ce n'est pas clairement indiqué dans la doc.

As tu vérifier que ces deux là et $content renvoyés bien quelque chose d'exploitable ?

Le reste semble faire ce qui est prévu.

J'aurai probablement mis cette partie :
if ($document) {
				ob_start();
				// Utilisez le contenu de la facture approprié
				include __DIR__.'/facture_axipharm_contenu.php';
				$content = ob_get_clean();
				
				try {
					$html2pdf = new Html2Pdf('P', 'A4', 'fr', true, 'UTF-8', array(0, 0, 0, 0));
					$html2pdf->pdf->SetDisplayMode('fullpage');
					$html2pdf->setTestIsImage(false);
					$html2pdf->setFallbackImage('./examples/res/off.png');
					$html2pdf->writeHTML($content);
					$pdf_content = $html2pdf->output('', 'S');
					
					$zip->addFromString("N°_{$document['DOC_PIECE']}.pdf", $pdf_content);
					} catch (Html2PdfException $e) {
					$formatter = new ExceptionFormatter($e);
					echo $formatter->getHtmlMessage();
				}
			}

dans une ou deux fonctions externes pour plus facilement déboguer et contrôler ce qu'elles renvoient et ensuite lancé $zip->addFromString() si on a quelque chose d'exploitable. Je ne suis pas fan du try catch mais je n'ai rien contre à mon niveau.

cdt

p.s. y-at-il des messages d'erreur qui s'affichent , tu n'en évoque pas je crois.
Modifié par gcyrillus (28 Mar 2025 - 18:04)