source: spip-zone/_plugins_/mediatheque/action/ajouter_documents.php @ 41565

Last change on this file since 41565 was 41565, checked in by real3t@…, 11 years ago

Permettre de titrer selon le nom des fichiers via
define('_TITRER_DOCUMENTS', true);
dans mes_options.php

Les accents dans les noms des fichiers sont correctement repris.

Le fonctionnement au déballage des .zip n'est modifié que pour la suppression de l'extension ; la case à cocher titrer est bien prise en compte (testé cochée et décochée)

File size: 11.4 KB
Line 
1<?php
2
3/***************************************************************************\
4 *  SPIP, Systeme de publication pour l'internet                           *
5 *                                                                         *
6 *  Copyright (c) 2001-2009                                                *
7 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
8 *                                                                         *
9 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
10 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
11\***************************************************************************/
12
13if (!defined("_ECRIRE_INC_VERSION")) return;
14
15include_spip('inc/getdocument');
16include_spip('inc/documents');
17include_spip('inc/ajouter_documents'); // compat core
18include_spip('inc/choisir_mode_document'); // compat core
19include_spip('inc/renseigner_document');
20
21function action_ajouter_documents_dist($id_document, $files, $objet, $id_objet, $mode){
22        $ajouter_un_document = charger_fonction('ajouter_un_document','action');
23        $ajoutes = array();
24
25        // on ne peut mettre qu'un seul document a la place d'un autre ou en vignette d'un autre
26        if (intval($id_document)){
27                $ajoutes[] = $ajouter_un_document($id_document, reset($files), $objet, $id_objet, $mode);
28        }
29        else
30                foreach($files as $file){
31                        $ajoutes[] = $ajouter_un_document('new', $file, $objet, $id_objet, $mode);
32                }
33        return $ajoutes;
34}
35
36/**
37 * Ajouter un document (au format $_FILES)
38 * $id_document,        # document a remplacer, ou pour une vignette, l'id_document de maman
39 * $source,     # le fichier sur le serveur (/var/tmp/xyz34)
40 * $nom_envoye, # son nom chez le client (portequoi.pdf)
41 * $objet,      # lie a un article, une breve ou une rubrique ?
42 * $id_objet,   # identifiant de l'article (ou rubrique) lie
43 * $mode,       # 'image' => image en mode image
44 *          'vignette' => personnalisee liee a un document
45 *          'document' => doc ou image en mode document
46 *          'distant' => lien internet
47 * $actifs      # les documents dont il faudra ouvrir la boite de dialogue
48 *
49 * @param unknown_type $id_document
50 * @param array $source
51 * @param unknown_type $nom_envoye
52 * @param unknown_type $objet
53 * @param unknown_type $id_objet
54 * @param unknown_type $mode
55 * @param unknown_type $documents_actifs
56 * @param unknown_type $titrer
57 * @return unknown
58 */
59// http://doc.spip.org/@ajouter_un_document
60function action_ajouter_un_document_dist($id_document, $file, $objet, $id_objet, $mode) {
61       
62        $source = $file['tmp_name'];
63        $nom_envoye = $file['name'];
64
65        // passer en minuscules le nom du fichier, pour eviter les collisions
66        // si le file system fait la difference entre les deux il ne detectera
67        // pas que Toto.pdf et toto.pdf
68        // et on aura une collision en cas de changement de file system
69        $file['name'] = strtolower(translitteration($file['name']));
70       
71        // Pouvoir definir dans mes_options.php que l'on veut titrer tous les documents par défaut
72        if (!defined('_TITRER_DOCUMENTS')) { define('_TITRER_DOCUMENTS', false); }
73
74        $titrer = isset($file['titrer'])?$file['titrer']:_TITRER_DOCUMENTS;
75        $mode = ((isset($file['mode']) AND $file['mode'])?$file['mode']:$mode);
76
77        include_spip('inc/modifier');
78        if (isset($file['distant']) AND $file['distant'] AND $mode=='vignette') {
79                include_spip('inc/distant');
80                $file['tmp_name'] = _DIR_RACINE . copie_locale($source);
81                $source = $file['tmp_name'];
82                unset($file['distant']);
83        }
84
85        // Documents distants : pas trop de verifications bloquantes, mais un test
86        // via une requete HEAD pour savoir si la ressource existe (non 404), si le
87        // content-type est connu, et si possible recuperer la taille, voire plus.
88        if (isset($file['distant']) AND $file['distant']) {
89                include_spip('inc/distant');
90                if (is_array($a = renseigner_source_distante($source))) {
91
92                        $champs = $a;
93                        # NB: dans les bonnes conditions (fichier autorise et pas trop gros)
94                        # $a['fichier'] est une copie locale du fichier
95
96                        unset($champs['type_image']);
97                }
98                // on ne doit plus arriver ici, car l'url distante a ete verifiee a la saisie !
99                else {
100                        spip_log("Echec du lien vers le document $source, abandon");
101                        return $a; // message d'erreur
102                }
103        }
104        else { // pas distant
105
106                $champs = array(
107                        'distant' => 'non'
108                );
109               
110                $type_image = ''; // au pire
111                $champs['titre'] = '';
112                if ($titrer){
113                        $titre = substr($nom_envoye,0, strrpos($nom_envoye, ".")); // Enlever l'extension du nom du fichier
114                        $titre = preg_replace(',[[:punct:][:space:]]+,u', ' ', $titre);
115                        $champs['titre'] = preg_replace(',\.([^.]+)$,', '', $titre);
116                }
117
118                if (!$fichier = fixer_fichier_upload($file))
119                        return ("Impossible de telecharger le fichier");
120               
121                $champs['inclus'] = $fichier['inclus'];
122                $champs['extension'] = $fichier['extension'];
123                $champs['fichier'] = $fichier['fichier'];
124
125
126                $infos = renseigner_taille_dimension_image($champs['fichier'],$champs['extension']);
127                if (is_string($infos))
128                        return $infos; // c'est un message d'erreur !
129               
130                $champs = array_merge($champs,$infos);
131
132                // Si mode == 'choix', fixer le mode image/document
133                if ($mode == 'choix' OR !in_array($mode, array('vignette', 'image', 'document'))) {
134                        $choisir_mode_document = charger_fonction('choisir_mode_document','inc');
135                        $mode = $choisir_mode_document($champs, $champs['inclus'] == 'image', $objet);
136                }
137                $champs['mode'] = $mode;
138
139                if (($test = verifier_taille_document_acceptable($champs))!==true){
140                        spip_unlink($champs['fichier']);
141                        return $test; // erreur sur les dimensions du fichier
142                }
143
144               
145                unset($champs['type_image']);
146                unset($champs['inclus']);
147                $champs['fichier'] = set_spip_doc($champs['fichier']);
148        }
149       
150        // lier le parent si necessaire
151        if ($id_objet=intval($id_objet) AND $objet)
152                $champs['parents'][] = "$objet|$id_objet";
153
154        // "mettre a jour un document" si on lui
155        // passe un id_document
156        if ($id_document=intval($id_document)){
157                unset($champs['titre']); // garder le titre d'origine
158                unset($champs['date']); // garder la date d'origine
159                unset($champs['descriptif']); // garder la desc d'origine
160                // unset($a['distant']); # on peut remplacer un doc statique par un doc distant
161                // unset($a['mode']); # on peut remplacer une image par un document ?
162        }
163
164        include_spip('action/editer_document');
165        // Installer le document dans la base
166        // attention piege semantique : les images s'installent en mode 'vignette'
167        if (!$id_document){
168                $id_document = insert_document();
169                spip_log ("ajout du document ".$file['tmp_name']." ".$file['name']."  (M '$mode' T '$objet' L '$id_objet' D '$id_document')");
170        }
171       
172        document_set($id_document,$champs);
173
174        // permettre aux plugins de faire des modifs a l'ajout initial
175        // ex EXIF qui tourne les images si necessaire
176        pipeline('post_edition',
177                array(
178                        'args' => array(
179                                'table' => 'spip_documents', // compatibilite
180                                'table_objet' => 'documents',
181                                'spip_table_objet' => 'spip_documents',
182                                'type' =>'document',
183                                'id_objet' => $id_document,
184                                'champs' => array_keys($champs),
185                                'serveur' => '', // serveur par defaut, on ne sait pas faire mieux pour le moment
186                                'action' => 'ajouter_document',
187                                'operation' => 'ajouter_document', // compat <= v2.0
188                        ),
189                        'data' => $champs
190                )
191        );
192
193        return $id_document ;
194}
195
196
197if (!function_exists('corriger_extension')){
198/**
199 * Corrige l'extension du fichier dans quelques cas particuliers
200 * (a passer dans ecrire/base/typedoc)
201 * A noter : une extension 'pdf ' passe dans la requete de controle
202 * mysql> SELECT * FROM spip_types_documents WHERE extension="pdf ";
203 *
204 * @param string $ext
205 * @return string
206 */
207function corriger_extension($ext) {
208        $ext = preg_replace(',[^a-z0-9],i', '', $ext);
209        switch ($ext) {
210                case 'htm':
211                        $ext='html';
212                        break;
213                case 'jpeg':
214                        $ext='jpg';
215                        break;
216                case 'tiff':
217                        $ext='tif';
218                        break;
219        }
220        return $ext;
221}
222}
223
224/**
225 * Verifie la possibilite d'uploader une extension
226 * renvoie un tableau descriptif si l'extension est acceptee
227 * une chaine 'zip' si il faut zipper
228 * false si l'extension est refusee
229 *
230 */
231function verifier_upload_autorise($source){
232        if (preg_match(",\.([^.]+)$,", $source, $match)
233          AND $ext = $match[1]){
234               
235          $ext = corriger_extension(strtolower($ext));
236                if ($row = sql_fetsel("extension,inclus", "spip_types_documents", "extension=" . sql_quote($ext) . " AND upload='oui'"))
237                        return $row;
238        }
239               
240        if (sql_countsel("spip_types_documents", "extension='zip' AND upload='oui'"))
241                return 'zip';
242
243        spip_log("Extension $ext interdite a l'upload");
244        return false;
245}
246
247
248/**
249 * tester le type de document :
250 * - interdit a l'upload ?
251 * - quelle extension dans spip_types_documents ?
252 * - est-ce "inclus" comme une image ?
253 *
254 * le zipper si necessaire
255 *
256 * @param array $file //format $_FILES
257 * @return array
258 */
259function fixer_fichier_upload($file){
260
261
262
263        if (is_array($row=verifier_upload_autorise($file['name']))) {
264                $row['fichier'] = copier_document($row['extension'], $file['name'], $file['tmp_name']);
265                return $row;
266        }
267        // creer un zip comme demande
268        // pour encapsuler un fichier dont l'extension n'est pas supportee
269        elseif($row==='zip'){
270               
271                $row = array('extension'=>'zip','inclus'=>false);
272
273                $ext = 'zip';
274                if (!$tmp_dir = tempnam(_DIR_TMP, 'tmp_upload'))
275                        return false;
276       
277                spip_unlink($tmp_dir);
278                @mkdir($tmp_dir);
279               
280                include_spip('inc/charset');
281                $tmp = $tmp_dir.'/'.translitteration($file['name']);
282               
283                $file['name'] .= '.zip'; # conserver l'extension dans le nom de fichier, par exemple toto.js => toto.js.zip
284
285                // deplacer le fichier tmp_name dans le dossier tmp
286                deplacer_fichier_upload($file['tmp_name'], $tmp, true);
287               
288                include_spip('inc/pclzip');
289                $source = _DIR_TMP . basename($tmp_dir) . '.zip';
290                $archive = new PclZip($source);
291               
292                $v_list = $archive->create($tmp,
293                                PCLZIP_OPT_REMOVE_PATH, $tmp_dir,
294                                PCLZIP_OPT_ADD_PATH, '');
295               
296                effacer_repertoire_temporaire($tmp_dir);
297                if (!$v_list) {
298                        spip_log("Echec creation du zip ");
299                        return false;
300                }
301               
302                $row['fichier']  = copier_document($row['extension'], $file['name'], $source);
303                spip_unlink($source);
304                return $row;
305        }
306       
307        return false;
308}
309
310
311function verifier_taille_document_acceptable($infos){
312       
313        // si ce n'est pas une image
314        if (!$infos['type_image']) {
315                if (_DOC_MAX_SIZE > 0
316                 AND $infos['taille'] > _DOC_MAX_SIZE*1024)
317                        return _T('gestdoc:info_doc_max_poids', array('maxi' => taille_en_octets(_DOC_MAX_SIZE*1024), 'actuel' => taille_en_octets($infos['taille'])));
318
319                if ($infos['mode'] == 'image')
320                        return _T('gestdoc:erreur_format_fichier_image',array('nom'=> $infos['fichier']));
321        }
322       
323        // si c'est une image
324        else {
325
326                if (_IMG_MAX_SIZE > 0
327                 AND $infos['taille'] > _IMG_MAX_SIZE*1024)
328                        return _T('gestdoc:info_image_max_poids', array('maxi' => taille_en_octets(_IMG_MAX_SIZE*1024), 'actuel' => taille_en_octets($infos['taille'])));
329       
330                if (_IMG_MAX_WIDTH * _IMG_MAX_HEIGHT
331                 AND ($infos['largeur'] > _IMG_MAX_WIDTH
332                 OR $infos['hauteur'] > _IMG_MAX_HEIGHT))
333
334                        return _T('info_logo_max_taille',
335                                        array(
336                                        'maxi' =>
337                                                _T('info_largeur_vignette',
338                                                        array('largeur_vignette' => _IMG_MAX_WIDTH,
339                                                        'hauteur_vignette' => _IMG_MAX_HEIGHT)),
340                                        'actuel' =>
341                                                _T('info_largeur_vignette',
342                                                        array('largeur_vignette' => $infos['largeur'],
343                                                        'hauteur_vignette' => $infos['hauteur']))
344                                ));
345        }
346       
347        // Si on veut uploader une vignette, il faut qu'elle ait ete bien lue
348        if ($infos['mode'] == 'vignette') {
349                if ($infos['inclus'] != 'image')
350                        return _T('gestdoc:erreur_format_fichier_image',array('nom'=> $infos['fichier'])); #SVG
351
352                if (!($infos['largeur'] OR $infos['hauteur']))
353                        return _T('gestdoc:erreur_upload_vignette',array('nom'=>$infos['fichier']));
354        }
355
356        return true;
357}
358
359
360?>
Note: See TracBrowser for help on using the repository browser.