source: spip-zone/_plugins_/_stable_/odt2spip/version_0.1_stable/action/odt2spip_importe.php @ 28686

Last change on this file since 28686 was 28686, checked in by cy_altern@…, 12 years ago

ajout du choix de la langue de publication de l'article généré

File size: 15.4 KB
Line 
1<?php
2
3function action_odt2spip_importe() {
4    global $auteur_session, $spip_version_code;;
5    $id_auteur = $auteur_session['id_auteur'];
6    $arg = _request('arg');
7    $args = explode(":",$arg);
8  // le 1er element de _request('arg') est id_rubrique=XXX
9    $Targs = explode("=", $args[0]);
10    $id_rubrique = $Targs[1];
11    $hash = _request('hash');
12    $redirect = _request('redirect');
13    if ($redirect==NULL) $redirect="";
14    include_spip("inc/securiser_action");
15   
16    if (!autoriser('creerarticledans', 'rubrique', $id_rubrique)) die(_T('avis_non_acces_page'));
17               
18  // les chemins à utiliser
19    $rep_IMG = "../"._NOM_PERMANENTS_ACCESSIBLES;
20                $p = explode(basename(_DIR_PLUGINS)."/", str_replace('\\','/',realpath(dirname(__FILE__))));
21   
22  // ss-rep temporaire specifique de l'auteur en cours: tmp/odt2spip/id_auteur/ => le creer si il n'existe pas
23    $base_dezip = $p[0]._NOM_TEMPORAIRES_INACCESSIBLES."odt2spip/";   // avec / final
24    if (!is_dir($base_dezip)) if (!mkdir($base_dezip,0777)) die (_T('odtspip:err_repertoire_tmp')); 
25    $rep_dezip = $base_dezip.$id_auteur.'/';
26    if (!is_dir($rep_dezip)) if (!mkdir($rep_dezip,0777)) die (_T('odtspip:err_repertoire_tmp')); 
27   
28    $rep_pictures = $rep_dezip."Pictures/";
29   
30  // paramètres de conversion de taille des images : cm -> px (en 96 dpi puisque c'est ce que semble utiliser Writer)
31    $conversion_image = 96/2.54;
32   
33  // traitement d'un fichier odt envoyé par $_POST
34    $fichier_zip = addslashes($_FILES['fichier_odt']['name']);
35    if ($_FILES['fichier_odt']['name'] == '' 
36        OR $_FILES['fichier_odt']['error'] != 0
37        OR !move_uploaded_file($_FILES['fichier_odt']['tmp_name'], $rep_dezip.$fichier_zip)
38       )  die(_T('odtspip:err_telechargement_fichier'));
39
40  // dézipper le fichier odt à la mode SPIP
41    include_spip("inc/pclzip");
42    $zip = new PclZip($rep_dezip.$fichier_zip);
43          $ok = $zip->extract(
44        PCLZIP_OPT_PATH, $rep_dezip,
45        PCLZIP_OPT_SET_CHMOD, _SPIP_CHMOD,
46        PCLZIP_OPT_REPLACE_NEWER
47          );
48          if ($zip->error_code < 0) {
49                    spip_log('charger_decompresser erreur zip ' . $zip->error_code .' pour fichier ' . $rep_dezip.$fichier_zip);
50                    die($zip->errorName(true));  //$zip->error_code
51          }
52   
53  // variables en dur pour xml en entrée et xslt utilisée
54//    $xml_entre = $rep_dezip.'content.xml';  // chemin du fichier xml à lire  !!! ce chemin absolu ne fonctionne pas pour PHP4 !!!
55    $xml_entre = _DIR_TMP.'odt2spip/'.$id_auteur.'/content.xml';  // chemin du fichier xml à lire
56    $xslt_texte = _DIR_PLUGIN_ODT2SPIP.'inc/odt2spip.xsl'; //'inc/odt2spip_texte.xsl';  // chemin de la xslt à utiliser pour le texte
57   
58  // fichier de sortie
59    $fichier_sortie = $rep_dezip.'snippet_odt2spip.xml';
60
61  // determiner si le plugin enluminure_typo ou intertitres_enrichis est present & actif
62    include_spip('inc/plugin');
63    $Tplugins = liste_plugin_actifs();
64    $intertitres_riches = ((array_key_exists('TYPOENLUMINEE', $Tplugins) OR array_key_exists('INTERTITRESTDM', $Tplugins)) ? 'oui' : 'non'); 
65   
66  // faut il mettre les images en mode document?
67    $type = (_request('mode_image') AND _request('mode_image') == 'document') ? 'document' : ($spip_version_code > 2 ? 'image' : 'vignette');
68    $ModeImages = ($type == 'document' ? 'doc' : 'img');
69   
70  // récupérer la langue de publication + verifier la valeur envoyée
71    $Tlangues = explode(',', $GLOBALS['meta']['langues_proposees']);
72    $LanguePublication = (in_array(_request('lang_publi'), $Tlangues) ? _request('lang_publi') : $GLOBALS['meta']['langue_site']);
73   
74   
75  // appliquer la transformation XSLT sur le fichier content.xml
76    // déterminer les fonctions xslt à utiliser (php 4 ou php 5)
77    if (!class_exists('XSLTProcessor')) {
78      // on est en php4 : utiliser l'extension et les fonction xslt de Sablotron
79      // vérifier que l'extension xslt est active
80        if (!function_exists('xslt_create')) die(_T('odtspip:err_extension_xslt'));
81     
82      // Crée le processeur XSLT
83        $xh = xslt_create();
84      // si on est sur un serveur Windows utiliser xslt_set_base avec le préfixe file://
85        if (strpos($_SERVER['SERVER_SOFTWARE'], 'Win') !== false) xslt_set_base($xh, 'file://' . getcwd () . '/');
86//        else xslt_set_base($xh, getcwd () . '/');
87     
88      // definition de l'array des parametres a passer a la xslt
89        $params = array('IntertitresRiches' => $intertitres_riches, 
90                        'ModeImages' => $ModeImages,
91                        'LanguePublication' => $LanguePublication
92                        );
93       
94      // lancer le parseur
95        $xml_sortie = xslt_process($xh, $xml_entre, $xslt_texte, NULL, array(), $params);
96        if (!$xml_sortie) die(_T('odtspip:err_transformation_xslt'));
97     
98      // Détruit le processeur XSLT
99        xslt_free($xh);
100    }
101    else {
102      // on est php5: utiliser les fonctions de la classe XSLTProcessor
103        $proc = new XSLTProcessor();
104
105      // passage des parametres a la xslt
106        $proc->setParameter(null, 'IntertitresRiches', $intertitres_riches);
107        $proc->setParameter(null, 'ModeImages', $ModeImages);
108        $proc->setParameter(null, 'LanguePublication', $LanguePublication);
109       
110        $xml = new DOMDocument();
111        $xml->load($xml_entre);
112        $xsl = new DOMDocument();
113        $xsl->load($xslt_texte);
114        $proc->importStylesheet($xsl); // attachement des règles xsl
115       
116      // lancer le parseur
117        if (!$xml_sortie = $proc->transformToXml($xml)) die(_T('odtspip:err_transformation_xslt'));
118    }
119
120  // traitements complémentaires du flux de sortie
121    // remplacer les &gt; et &lt;
122    $a_remplacer = array('&#60;','&#62;','&lt;','&gt;', '"', "<date/>");
123    $remplace = array('<','>','<','>', "'", '<date>'.(date("Y-m-d H:i:s")).'</date>');
124    $xml_sortie = str_replace($a_remplacer, $remplace, $xml_sortie);
125   
126    // gerer la conversion des <math>Object X</math> => on delegue a /inc/odt2spip_traiter_mathml.php
127    if (preg_match_all('/<math>(.*?)<\/math>/', $xml_sortie, $match, PREG_PATTERN_ORDER) > 0) {
128        include_spip('inc/odt2spip_traiter_mathml');
129        foreach ($match[1] as $balise) {
130            $fic_content = $rep_dezip.$balise.'/content.xml';
131          // si le fichier /Object X/content.xml ne contient pas du mathML, virer la balise <math>
132            if (substr_count(file_get_contents($fic_content), '<!DOCTYPE math:math') < 1) {
133                $xml_sortie = str_replace('<math>'.$balise.'</math>', '', $xml_sortie);
134                continue;
135            }
136          // sinon faire la transfo xsl du contenu du fichier pour obtenir le LateX qu'on place dans la balise
137            $xml_sortie = str_replace($balise, odt2spip_traiter_mathml($fic_content), $xml_sortie);
138        }
139    }
140   
141    // virer les sauts de ligne multiples
142    $xml_sortie = preg_replace('/([\r\n]{2})[ \r\n]*/m', "$1", $xml_sortie);
143   
144    // si malgré toutes les magouille xslt la balise  <titre> est vide, mettre le nom du fichier odt
145    if(preg_match('/<titre>([ ]*?)<\/titre>/', $xml_sortie, $match) == 1)
146        $xml_sortie = preg_replace('/<titre>[ ]*?<\/titre>/', 
147                                   '<titre>'.str_replace(array('_','-','.odt'), array(' ',' ',''), $fichier_zip).'</titre>', 
148                                   $xml_sortie);   
149
150    // traiter les images: dans tous les cas il faut les intégrer dans la table documents
151    // en 1.9.2 c'est mode vignette + il faut les intégrer dans la table de liaison
152    // en 2.0 c'est mode image + les fonctions de snippets font la liaison => on bloque la liaison en filant un id_article vide
153    $id_article_tmp = ($spip_version_code > 2 ? '' : 100000);   
154    preg_match_all('/<'.$ModeImages.'([;a-zA-Z0-9\.]*)/', $xml_sortie, $match, PREG_PATTERN_ORDER);
155    if (@count($match) > 0) {
156        include_spip('inc/ajouter_document');
157        $T_images = array();
158        foreach($match[1] as $ch) {
159            $Tdims = explode(';;;', $ch);
160            $img = $Tdims[0];
161            if (file_exists($rep_pictures.$img)) {
162              // retailler l'image en fct des parametres ;;;largeur;;;hauteur;;;
163                $largeur = round($Tdims[1]*$conversion_image);
164                $hauteur = round($Tdims[2]*$conversion_image);
165                odt2spip_retailler_img($rep_pictures.$img, $largeur, $hauteur);
166              // intégrer l'image comme document spip
167                // la y'a un bogue super-bizarre avec la fonction spip_abstract_insert() qui est donnee comme absente lors de l'appel de ajouter_document()
168                if (!function_exists('spip_abstract_insert')) include_spip('base/abstract_sql');
169                $ajouter_documents = charger_fonction('ajouter_documents','inc');
170//                $type = ($spip_version_code > 2 ? 'image' : 'vignette');
171                if ($id_document = $ajouter_documents($rep_pictures.$img, $img, "article", $id_article_tmp, $type, 0, $toto='')) { 
172                  // uniformiser la sortie: si on est en 1.9.2 inc_ajouter_documents_dist() retourne le type de fichier (extension) alors qu'en 2.0 c'est l'id_document
173                    if (!is_numeric($id_document)) {
174                        $Ttmp = explode('.', $img);
175                        $nom_fic = $Ttmp[0];
176                        $data = spip_fetch_array(spip_query("SELECT id_document FROM spip_documents WHERE fichier LIKE '%$nom_fic%' ORDER BY maj DESC LIMIT 1"));
177                        $id_document = $data['id_document'];
178                    }
179                    $xml_sortie = str_replace($ch, $id_document, $xml_sortie);
180                    $T_images[] = $id_document;
181                };
182            }
183        }
184    }
185   
186  // finalement enregistrer le contenu dans /tmp/odt2spip/id_auteur/snippet_odt2spip.xml
187    if (function_exists('file_put_contents')) {
188        if (!file_put_contents($fichier_sortie, $xml_sortie)) die(_T('odtspip:err_enregistrement_fichier_sortie').$fichier_sortie);
189    }
190    else {  // php4
191        $fic = fopen($fichier_sortie, 'wb');
192        if (!fwrite($fic, $xml_sortie)) die(_T('odtspip:err_enregistrement_fichier_sortie').$fichier_sortie);
193        fclose($fic);
194    }
195/* die;  */ 
196  // générer l'article à partir du fichier xml de sortie (code pompé sur plugins/snippets/action/snippet_importe.php)
197    include_spip('inc/snippets');
198                $table = $id = 'articles';
199                $contexte = $args[0];
200                $source = $fichier_sortie;
201    if (!$f = snippets_fonction_importer($table)) die(_T('odtspip:err_import_snippet'));
202    include_spip('inc/xml');
203    $arbre = spip_xml_load($source, false);
204    $translations = $f($id,$arbre,$contexte);
205    snippets_translate_raccourcis_modeles($translations);
206    $id_article = $translations[0][2]; 
207  // si on est en 1.9.2 mettre à jour l'id_article auquel sont liees les images
208    if ($spip_version_code < 2) spip_query("UPDATE spip_documents_articles SET id_article = $id_article WHERE id_document IN (".implode(',',$T_images).")");
209
210  // passer le statut de l'article en prepa (bizarre que snippets respecte pas le <statut>prop</statut> ???)
211    if ($spip_version_code > 2) sql_updateq('spip_articles', array('statut' => 'prop'), 'id_article='.$id_article);
212    else spip_query("UPDATE spip_articles SET statut = 'prop' WHERE id_article = $id_article LIMIT 1");
213   
214  // si necessaire attacher le fichier odt original à l'article et lui mettre un titre signifiant
215    if (_request('attacher_odt') == '1') {
216      // recuperer le titre
217        preg_match('/<titre>(.*?)<\/titre>/', $xml_sortie, $match);
218        $titre = $match[1];
219        if (!isset($ajouter_documents)) $ajouter_documents = charger_fonction('ajouter_documents','inc');
220        $id_doc_odt = $ajouter_documents($rep_dezip.$fichier_zip, $fichier_zip, "article", $id_article, 'document', 0, $toto='');
221        if (!is_numeric($id_doc_odt)) {
222            $Tfic = explode('.', $fichier_zip);
223            $fichier_zip_av_extension = $Tfic[0];
224            $data = spip_fetch_array(spip_query("SELECT id_document FROM spip_documents WHERE fichier LIKE '%$fichier_zip_av_extension%' ORDER BY maj DESC LIMIT 1"));
225            $id_doc_odt = $data['id_document'];
226        }
227        if (function_exists('sql_updateq')) sql_updateq('spip_documents', array('titre' => $titre, 'descriptif' => _T('odtspip:cet_article_version_odt')), 'id_document='.$id_doc_odt);
228        else spip_query("UPDATE spip_documents SET titre = '".$titre."', descriptif = '"._T('odtspip:cet_article_version_odt')."' WHERE id_document=".$id_doc_odt." LIMIT 1");
229    }
230   
231  // vider le contenu du rep de dezippage
232    if ($spip_version_code >= 12691) {
233        if (!function_exists('effacer_repertoire_temporaire')) include_spip('inc/getdocument');
234        effacer_repertoire_temporaire($rep_dezip);
235    }
236    else odt2spip_effacer_repzip($rep_dezip);
237   
238  // aller sur la page de l'article qui vient d'être créé
239    redirige_par_entete(str_replace("&amp;","&",urldecode($redirect.$id_article)));
240}   
241
242// Efface le repertoire de dezippage de maniere recursive !
243// reprise de http://doc.spip.org/@effacer_repertoire_temporaire + correctif closedir()
244// cette fonction n'est plus utile à partir de spip 2.0.5 [12691] puisque le correctif à été intégré
245function odt2spip_effacer_repzip($nom) {
246        $d = opendir($nom);
247        while (($f = readdir($d)) !== false) {
248                if (is_file("$nom/$f")) @unlink("$nom/$f");
249                else if ($f <> '.' AND $f <> '..' AND is_dir("$nom/$f"))
250                        odt2spip_effacer_repzip("$nom/$f");
251        }
252        closedir($d);
253  @rmdir($nom);
254}
255
256// retailler une image : (ne gère que les images GIF, JPG et PNG)
257//      $img_ini = CHEMIN+NOM_FICHIER de l'img initiale, $l et $h = largeur et hauteur max de l'image finale
258// gestion de la transparence des PNG : code de matt1walsh@gmail.com sur http://fr2.php.net/manual/fr/function.imagecopyresampled.php
259function odt2spip_retailler_img($img_ini, $l = '', $h = 400) {
260    if (!file_exists($img_ini)) return 'Le fichier '.$img_ini.' n\'existe pas';
261  // déterminer le type de fonction de création d'image à utiliser
262    $param_img = getimagesize($img_ini);
263    $type_img = $param_img[2];
264    switch ($type_img) {
265        case 1 :
266            $fct_creation_ext = 'imagecreatefromgif';
267            $fct_ecrire = 'imagegif';
268        break;
269        case 2 :
270            $fct_creation_ext = 'imagecreatefromjpeg';
271            $fct_ecrire = 'imagejpeg';
272        break;
273        case 3 :
274            $fct_creation_ext = 'imagecreatefrompng';
275            $fct_ecrire = 'imagepng';
276        break;
277        default :
278            return;
279        break;
280    } 
281  // calculer le ratio à appliquer aux dimensions initiales
282    $l_ini = $param_img[0];
283    $h_ini = $param_img[1];
284    $ratio = ($l != '' ? (abs($l_ini - $l) >= abs($h_ini - $h) ? $l/$l_ini : $h/$h_ini) : $h/$h_ini); 
285    $img_nv = imagecreatetruecolor($l_ini*$ratio, $h_ini*$ratio); 
286    $img_acopier = $fct_creation_ext($img_ini);
287  // gérer la transparence pour les images PNG (le mec qui a trouvé ce code est génial! :-)
288    if ($type_img == 3) {
289        imagecolortransparent($img_nv, imagecolorallocate($img_nv, 0, 0, 0));
290        imagealphablending($img_nv, false);
291        imagesavealpha($img_nv, true);
292    }
293    imagecopyresampled($img_nv, $img_acopier, 0, 0, 0, 0, $l_ini*$ratio, $h_ini*$ratio, $l_ini, $h_ini);                     
294  // sauvegarder l'image et éventuellement détruire le fichier image initial
295    $fct_ecrire($img_nv, $img_ini);
296    imagedestroy($img_nv);
297    imagedestroy($img_acopier);
298}
299
300
301?>
Note: See TracBrowser for help on using the repository browser.