Bonjour,
Je suis artisan et je bricole le php en amateur depuis quelques années. Pour joindre l'utile à l'agréable, j'ai fait un script (basé sur un que j'ai trouvé) qui me permet de récupérer les factures PDF de mes fournisseurs en pièce jointe depuis ma boite mail, puis de les parser.
Cela marche pour la quasi-totalité de mes factures à l'exception d'un fournisseur et cela m'embête bien.
Je précise que les mails de ce fournisseur sont générer automatiquement.
Lorsque je télécharge la pièce jointe manuellement depuis mon client de messagerie (Thunder birds), pas de problème le PDF peut être ouvert et parsé.
En revanche le PDF que je récupère depuis mon script est mauvais.
Voici les messages d'erreur que j'ai :
En affichant le PDF dans vsCode :
PDF.js v2.10.377 (identifiant de compilation : 156762c48)
Message : Invalid PDF structure.
En ouvrant le PDF avec Acrobat :
J'ai l'impression que cela viens du décodage
Voici le script :
Là je vous ai mis l'object résultant de imap_fetchstructure
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124 <?php $server = '{monserver}INBOX'; $username = 'mon@mail.com'; $password = 'pass'; $imap = imap_open($server, $username, $password) or die("imap connection error"); $message_count = imap_num_msg($imap); for($m = $message_count; $m >= $message_count-5; $m--) //je regarde sur les 5 derniers mails { $header = imap_headerinfo($imap, $m); $adresse_expediteur = iconv_mime_decode($header->fromaddress, 0, "ISO-8859-1"); if(preg_match('/mail@de-mon-fournisseur.com/' ,$adresse_expediteur)) // je regarde si ça viens de mon fournisseur { //mise des différentes infos dans un tableau $email[$m]['from'] = $header->from[0]->mailbox.'@'.$header->from[0]->host; $email[$m]['fromaddress'] = $header->from[0]->personal; $email[$m]['to'] = $header->to[0]->mailbox; $email[$m]['subject'] = $header->subject; $email[$m]['message_id'] = $header->message_id; $email[$m]['date'] = $header->udate; $from = $email[$m]['fromaddress']; $from_email = $email[$m]['from']; $to = $email[$m]['to']; $subject = $email[$m]['subject']; $structure = imap_fetchstructure($imap, $m); $attachments = array(); //Je recherche si il y a une pièce jointe if(isset($structure->parts) && count($structure->parts)) { for($i = 0; $i < count($structure->parts); $i++) { echo $i; $attachments[$i] = array( 'is_attachment' => false, 'filename' => '', 'name' => '', 'Dparameter' => '', 'parameter' => '', 'attachment' => ''); if($structure->parts[$i]->ifdparameters) { $attachments[$i]['encoding'] = $structure->parts[$i]->encoding; foreach($structure->parts[$i]->dparameters as $object) { if(strtolower($object->attribute) == 'filename') { $attachments[$i]['is_attachment'] = true; $attachments[$i]['filename'] = $object->value; $attachments[$i]['Dparameter'] = "oui"; } } } else { if($structure->parts[$i]->parts) { foreach($structure->parts[$i]->parts as $key => $sous_array) { $attachments[$i]['encoding'] = $sous_array->encoding; $attachments[$i]['key'] = $key; if($sous_array->disposition == 'attachment') { if($sous_array->parameters[0]->attribute == 'name') { $attachments[$i]['is_attachment'] = true; $attachments[$i]['name'] = $sous_array->parameters[0]->value; $attachments[$i]['filename'] = $sous_array->parameters[0]->value; } } } } } if($structure->parts[$i]->ifparameters) { foreach($structure->parts[$i]->parameters as $object) { if(strtolower($object->attribute) == 'name') { $attachments[$i]['is_attachment'] = true; $attachments[$i]['name'] = $object->value; $attachments[$i]['parameter'] = "oui"; } } } if($attachments[$i]['is_attachment']) { $attachments[$i]['attachment'] = imap_fetchbody($imap, $m, $i+1, FT_PEEK); //Je determine l'encodage if($attachments[$i]['encoding'] == 3) // 3 = BASE64 { $attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']); } elseif($attachments[$i]['encoding'] == 4)// 4 = QUOTED-PRINTABLE { $attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']); } } } } foreach($attachments as $key => $attachment) { //Si c'est un PDF if(strstr(strtolower($attachment['name']), '.pdf')) { $name = $attachment['name']; $nom_d_origine = $name; $contents = $attachment['attachment']; $name = '../factures_fournisseurs/tmp/tmp_fact-'.$m.'.pdf'; file_put_contents($fichier_final, $contents); } } // reste de mon script ou j'utilise le $fichier_final.... } } imap_expunge($imap); imap_close($imap); ?>
Et ici le contenu de la variable $contents:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158 stdClassObject ( |¹[type] => 1 |¹[encoding] => 0 |¹[ifsubtype] => 1 |¹[subtype] => MIXED |¹[ifdescription] => 0 |¹[ifid] => 0 |¹[ifdisposition] => 0 |¹[ifdparameters] => 0 |¹[ifparameters] => 1 |¹[parameters] => Array | ( | |²[0] => stdClassObject | | ( | | |³[attribute] => boundary | | |³[value] => --boundary_46_a865daa0-d325-478a-bc59-40c3330ba4d8 | | ) | ) |¹[parts] => Array | ( | |²[0] => stdClassObject | | ( | | |³[type] => 1 | | |³[encoding] => 0 | | |³[ifsubtype] => 1 | | |³[subtype] => ALTERNATIVE | | |³[ifdescription] => 0 | | |³[ifid] => 0 | | |³[ifdisposition] => 0 | | |³[ifdparameters] => 0 | | |³[ifparameters] => 1 | | |³[parameters] => Array | | | ( | | | |⁴[0] => stdClassObject | | | | ( | | | | |⁵[attribute] => boundary | | | | |⁵[value] => --boundary_44_aaef25fe-1f85-4bb8-9df1-23ecceff9a7b | | | | ) | | | ) | | |³[parts] => Array | | | ( | | | |⁴[0] => stdClassObject | | | | ( | | | | |⁵[type] => 1 | | | | |⁵[encoding] => 0 | | | | |⁵[ifsubtype] => 1 | | | | |⁵[subtype] => RELATED | | | | |⁵[ifdescription] => 0 | | | | |⁵[ifid] => 0 | | | | |⁵[ifdisposition] => 0 | | | | |⁵[ifdparameters] => 0 | | | | |⁵[ifparameters] => 1 | | | | |⁵[parameters] => Array | | | | | ( | | | | | |⁶[0] => stdClassObject | | | | | | ( | | | | | | |⁷[attribute] => boundary | | | | | | |⁷[value] => --boundary_45_81e7fe2c-dc95-4446-b800-fd30f09702ac | | | | | | ) | | | | | |⁶[1] => stdClassObject | | | | | | ( | | | | | | |⁷[attribute] => type | | | | | | |⁷[value] => text/html | | | | | | ) | | | | | ) | | | | |⁵[parts] => Array | | | | | ( | | | | | |⁶[0] => stdClassObject | | | | | | ( | | | | | | |⁷[type] => 0 | | | | | | |⁷[encoding] => 3 | | | | | | |⁷[ifsubtype] => 1 | | | | | | |⁷[subtype] => HTML | | | | | | |⁷[ifdescription] => 0 | | | | | | |⁷[ifid] => 0 | | | | | | |⁷[lines] => 11 | | | | | | |⁷[bytes] => 802 | | | | | | |⁷[ifdisposition] => 0 | | | | | | |⁷[ifdparameters] => 0 | | | | | | |⁷[ifparameters] => 1 | | | | | | |⁷[parameters] => Array | | | | | | | ( | | | | | | | |⁸[0] => stdClassObject | | | | | | | | ( | | | | | | | | |⁹[attribute] => charset | | | | | | | | |⁹[value] => utf-8 | | | | | | | | ) | | | | | | | ) | | | | | | ) | | | | | |⁶[1] => stdClassObject | | | | | | ( | | | | | | |⁷[type] => 5 | | | | | | |⁷[encoding] => 3 | | | | | | |⁷[ifsubtype] => 1 | | | | | | |⁷[subtype] => JPEG | | | | | | |⁷[ifdescription] => 0 | | | | | | |⁷[ifid] => 1 | | | | | | |⁷[id] => | | | | | | |⁷[bytes] => 4940 | | | | | | |⁷[ifdisposition] => 0 | | | | | | |⁷[ifdparameters] => 0 | | | | | | |⁷[ifparameters] => 0 | | | | | | |⁷[parameters] => stdClassObject | | | | | | | ( | | | | | | | ) | | | | | | ) | | | | | ) | | | | ) | | | ) | | ) | |²[1] => stdClassObject | | ( | | |³[type] => 1 | | |³[encoding] => 0 | | |³[ifsubtype] => 1 | | |³[subtype] => MIXED | | |³[ifdescription] => 0 | | |³[ifid] => 0 | | |³[ifdisposition] => 0 | | |³[ifdparameters] => 0 | | |³[ifparameters] => 1 | | |³[parameters] => Array | | | ( | | | |⁴[0] => stdClassObject | | | | ( | | | | |⁵[attribute] => boundary | | | | |⁵[value] => --boundary_47_c0a7e1bd-911b-4463-a672-59bf9b876d5d | | | | ) | | | ) | | |³[parts] => Array | | | ( | | | |⁴[0] => stdClassObject | | | | ( | | | | |⁵[type] => 3 | | | | |⁵[encoding] => 3 | | | | |⁵[ifsubtype] => 1 | | | | |⁵[subtype] => OCTET-STREAM | | | | |⁵[ifdescription] => 0 | | | | |⁵[ifid] => 0 | | | | |⁵[bytes] => 508420 | | | | |⁵[ifdisposition] => 1 | | | | |⁵[disposition] => attachment | | | | |⁵[ifdparameters] => 0 | | | | |⁵[ifparameters] => 1 | | | | |⁵[parameters] => Array | | | | | ( | | | | | |⁶[0] => stdClassObject | | | | | | ( | | | | | | |⁷[attribute] => name | | | | | | |⁷[value] => Fact2704528_01-12-2024.pdf | | | | | | ) | | | | | ) | | | | ) | | | ) | | ) | ) )
Auriez vous une idée de la raison pour laquelle mon ficher est invalide ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 ----boundary_23_745a4124-1aae-4610-81f0-464a9c91ee93 Content-Type: application/octet-stream; name=Fact2704528_01-12-2024.pdf Content-Disposition: attachment Content-Transfer-Encoding: base64 JVBERi0xLjMNCjEgMCBvYmoNClsvUERGIC9UZXh0IC9JbWFnZUIgL0ltYWdlQyAvSW1hZ2VJXQ0K [...] byAxOSAwIFIg Pj4NCnN0YXJ0eHJlZg0KMzc1NjI4DQolJUVPRg== ----boundary_23_745a4124-1aae-4610-81f0-464a9c91ee93--
Je vous remercie
Partager