source: spip-zone/_plugins_/convertisseur/trunk/spip-cli/ConvertisseurImporter.php @ 116116

Last change on this file since 116116 was 116116, checked in by booz@…, 7 months ago

pouvoir importer dans un secteur

File size: 18.6 KB
Line 
1<?php
2
3/***
4
5Importer en masse des fichiers txt dans spip_articles.
6Les articles sont ajoutés avec leurs info sauf id_article dans des rubriques créées si besoin.
7Les documents <docxxx> sont gérés
8Les raccourcis de liens [xxx->12345] sont gérés
9
10*/
11
12use Symfony\Component\Console\Command\Command;
13use Symfony\Component\Console\Input\InputArgument;
14use Symfony\Component\Console\Input\InputInterface;
15use Symfony\Component\Console\Input\InputOption;
16use Symfony\Component\Console\Output\OutputInterface;
17use Symfony\Component\Console\Helper\ProgressBar;
18
19class ConvertisseurImporter extends Command {
20        protected function configure() {
21                $this
22                        ->setName('convertisseur:importer')
23                        ->setDescription('Importer des fichiers SPIP txt dans la table spip_articles (ou autre).')
24                        ->setAliases(array(
25                                'import' // abbréviation commune pour "import"
26                        ))
27                        ->addOption(
28                                'source',
29                                's',
30                                InputOption::VALUE_OPTIONAL,
31                                'Répertoire source',
32                                'conversion_spip'
33                        )
34                        ->addOption(
35                                'dest',
36                                'd',
37                                InputOption::VALUE_OPTIONAL,
38                                'id_rubrique de la rubrique où importer la hierarchie de rubriques et les articles défini dans les fichiers txt (en général l\'id_secteur ou on veut importer)',
39                                '0'
40                        )
41                        ->addOption(
42                                'auteur_defaut',
43                                'a',
44                                InputOption::VALUE_OPTIONAL,
45                                'Auteur par défaut (id_auteur)',
46                                '1'
47                        )
48                        ->addOption(
49                                'racine_documents',
50                                'r',
51                                InputOption::VALUE_OPTIONAL,
52                                'path ajouté devant le `fichier` des documents joints importés',
53                                ''
54                        )
55                        ->addOption(
56                                'conserver_id_article',
57                                'c',
58                                InputOption::VALUE_OPTIONAL,
59                                'option -c oui pour conserver les id_article',
60                                ''
61                        )
62                ;
63        }
64       
65        protected function execute(InputInterface $input, OutputInterface $output) {
66                global $spip_racine;
67                global $spip_loaded;
68                $spip_version_branche = $GLOBALS['spip_version_branche'] ;
69               
70                include_spip("iterateur/data");
71               
72                $source = $input->getOption('source') ;
73                $id_parent = $input->getOption('dest') ;
74                $racine_documents = $input->getOption('racine_documents') ;
75                $conserver_id_article = $input->getOption('conserver_id_article') ;
76                $auteur_defaut = $input->getOption('auteur_defaut') ;
77               
78                // Répertoire source
79                if(!is_dir($source)){
80                        $output->writeln("<error>Préciser le répertoire avec les fichiers à importer. spip import -s repertoire </error>\n");
81                        exit ;
82                }
83               
84                if ($spip_loaded) {
85                        chdir($spip_racine);
86                       
87                        if (!function_exists('passthru')){
88                                $output->writeln("<error>Votre installation de PHP doit pouvoir exécuter des commandes externes avec la fonction passthru().</error>");
89                        }
90                        // Si c'est bon on continue
91                        else{
92                               
93                                // Champs d'un article
94                                include_spip("base/abstract_sql");
95                                $show = sql_showtable("spip_articles");
96                                $champs = array_keys($show['field']);
97                               
98                                $show = sql_showtable("spip_documents");
99                                $champs_documents = array_keys($show['field']);
100                               
101                                // Ajout d'un champ la premiere fois pour stocker les éventuelles <ins> qui n'ont pas de champs (peut-être long).
102                                if(!in_array('metadonnees', $champs)){
103                                        $output->writeln("MAJ BDD : alter table spip_articles add metadonnees MEDIUMTEXT NOT NULL DEFAULT ''");
104                                        sql_query("alter table spip_articles add metadonnees MEDIUMTEXT NOT NULL DEFAULT ''");
105                                }
106                                // Ajout d'un champ la premiere fois pour stocker l'id_article original (pour ensuite remapper les liens [->123]).
107                                if(!in_array('id_source', $champs)){
108                                        $output->writeln("MAJ BDD : alter table spip_articles add id_source BIGINT(21)");
109                                        sql_query("alter table spip_articles add id_source BIGINT(21)");
110                                }
111                                // Ajout d'un champ la premiere fois pour stocker le nom du fichier source, pour reconnaitre un article déjà importé.
112                                if(!in_array('fichier_source', $champs)){
113                                        $output->writeln("MAJ BDD : alter table spip_articles add fichier_source MEDIUMTEXT NOT NULL DEFAULT ''");
114                                        sql_query("alter table spip_articles add fichier_source MEDIUMTEXT NOT NULL DEFAULT ''");
115                                }
116                               
117                                // on prend tous les fichiers txt dans la source, sauf si metadata.txt a la fin.
118                                $fichiers = preg_files($source . "/", "(?:(?<!\.metadata\.)txt$)", 100000);
119                                if(sizeof($fichiers)>0){
120                                        // start and displays the progress bar
121                                        $progress = new ProgressBar($output, sizeof($fichiers));
122                                        $progress->setBarWidth(100);
123                                        $progress->setRedrawFrequency(1);
124                                        $progress->setMessage(" Import de $source/*.txt en cours dans la rubrique $id_parent ... ", 'message'); /**/
125                                        $progress->setMessage("", 'inforub');
126                                        $progress->start();
127                                       
128                                        foreach($fichiers as $f){
129                                                // date d'apres le nom du fichier
130                                                $fichier = basename($f);
131                                                preg_match("/^(\d{4})-\d{2}/", $fichier, $m);
132                                                $mois = $m[0];
133                                                $annee = $m[1] ;
134                                               
135                                                // chopper l'id_parent dans le fichier ?
136                                                include_spip("inc/flock");
137                                                lire_fichier($f, $texte);
138                                               
139                                                // menage
140                                                //@@COLLECTION:esRetour ligne automatique
141                                                //@@SOURCE:article914237.html
142                                               
143                                                $texte = preg_replace("/@@COLLECTION.*/", "", $texte);
144                                                $texte = preg_replace("/@@SOURCE.*/", "", $texte);
145                                               
146                                                // Si des <ins> correspondent à des champs metadonnees connus, on les ajoute.
147                                                $champs_metadonnees = array("mots_cles", "auteurs", "hierarchie", "documents", "descriptif_rubrique", "texte_rubrique");
148                                                $hierarchie = "" ;
149                                                $auteurs = "" ;
150                                                $mots_cles = "" ;
151                                                $documents = "" ;
152                                                $texte_rubrique = "" ;
153                                                $descriptif_rubrique = "" ;
154                                               
155                                                if (preg_match_all(",<ins[^>]+class='(.*?)'[^>]*?>(.*?)</ins>,ims", $texte, $z, PREG_SET_ORDER)){ 
156                                                        foreach($z as $d){ 
157                                                                if(in_array($d[1], $champs_metadonnees)){ 
158                                                                        // class="truc" => $truc
159                                                                        $$d[1] = split("@@", $d[2]); 
160                                                                        // virer du texte
161                                                                        $texte = substr_replace($texte, '', strpos($texte, $d[0]), strlen($d[0])); 
162                                                                }
163                                                        }
164                                                }
165                                               
166                                                if (preg_match(",<ins class='id_article'>(.*?)</ins>,ims", $texte, $z))
167                                                        $id_source = $z[1];
168                                               
169                                                // dans quelle rubrique importer ?
170                                                // La hierarchie est-elle précisée dans le fichier ? (en principe oui)
171                                                if($hierarchie){
172                                                        $hierarchie = implode("/", $hierarchie);
173                                                }else{ // sinon on genere des rubriques annees / mois
174                                                        $hierarchie = "$annee/$annee-$mois";
175                                                }
176                                               
177                                                include_spip("inc/rubriques");
178                                               
179                                                // Les éventuels / sont échappés \/ ; exemple : 1999/1999\/06
180                                                $hierarchie = preg_replace("`\\\/`","`--**--`", $hierarchie);
181                                               
182                                                // rétablir les échapemments
183                                                // ajout  des échapemments à creer_rubrique_nommee($titre, $id_parent = 0, $serveur = '')
184                                               
185                                                $arbo = explode("/", $hierarchie);
186                                               
187                                                $id_parent_rubrique = $id_parent ;
188                                               
189                                                foreach ($arbo as $titre) {
190                                                        // retablir les </multi> et autres balises fermantes html
191                                                        $titre = preg_replace(",<@([a-z][^>]*)>,ims", "</\\1>", $titre);
192                                                        // rétablir les échapemments \/
193                                                        $titre = preg_replace(",`--\*\*--`,","/", $titre);
194                                                       
195                                                        $r = sql_getfetsel("id_rubrique", "spip_rubriques",
196                                                                "titre = " . sql_quote($titre) . " AND id_parent=" . intval($id_parent_rubrique),
197                                                                $groupby = array(), $orderby = array(), $limit = '', $having = array(), $serveur);
198                                                       
199                                                        if ($r !== null) {
200                                                                $id_parent_rubrique = $r;
201                                                        } else {
202                                                                $id_rubrique = sql_insertq('spip_rubriques', array(
203                                                                                'titre' => $titre,
204                                                                                'id_parent' => $id_parent_rubrique,
205                                                                                'statut' => 'prepa'
206                                                                        ), $desc = array(), $serveur);
207                                                                if ($id_parent_rubrique > 0) {
208                                                                        $data = sql_fetsel("id_secteur,lang", "spip_rubriques", "id_rubrique=$id_parent_rubrique",
209                                                                                $groupby = array(), $orderby = array(), $limit = '', $having = array(), $serveur);
210                                                                        $id_secteur = $data['id_secteur'];
211                                                                        $lang = $data['lang'];
212                                                                } else {
213                                                                        $id_secteur = $id_rubrique;
214                                                                        $lang = $GLOBALS['meta']['langue_site'];
215                                                                }
216                                                               
217                                                                sql_updateq('spip_rubriques', array('id_secteur' => $id_secteur, "lang" => $lang),
218                                                                        "id_rubrique=" . intval($id_rubrique), $desc = '', $serveur);
219                                                               
220                                                                // pour la recursion
221                                                                $id_parent_rubrique = $id_rubrique;
222                                                        }
223                                                }
224                                               
225                                                $hierarchie = preg_replace(",`--\*\*--`,","/", $hierarchie);
226                                               
227                                                $id_rubrique = intval($id_parent_rubrique);
228                                               
229                                                if($descriptif_rubrique OR $texte_rubrique){
230                                                        $up = sql_update('spip_rubriques', array('statut' => sql_quote("publie"), 'texte' => sql_quote($texte_rubrique), 'descriptif' => sql_quote($descriptif_rubrique)), "id_rubrique=$id_rubrique");
231                                                }
232                                                else
233                                                        $up = sql_updateq('spip_rubriques', array('statut' => 'publie'), "id_rubrique=$id_rubrique");
234                                               
235                                                $hierarchie_rub = sql_allfetsel("id_secteur,id_parent","spip_rubriques","id_rubrique=$id_rubrique");
236                                               
237                                                if($hierarchie_rub[0]["id_secteur"] == 0){
238                                                        die("Erreur de création de rubrique $id_rubrique : id_secteur=0");
239                                                }
240                                               
241                                                if($up)
242                                                        $progress->setMessage(" Rubrique $hierarchie => $id_rubrique (" . $hierarchie_rub[0]["id_secteur"] ." > " . $hierarchie_rub[0]["id_parent"] .") ", 'inforub');
243                                               
244                                                $progress->setMessage("", 'docs');
245                                                $progress->setMessage("", 'mot');
246                                                $progress->setMessage("", 'auteur');
247                                               
248                                                // inserer l'article
249                                                include_spip("inc/convertisseur");
250                                               
251                                                // auteur par défaut (admin)
252                                                $id_admin = sql_getfetsel("id_auteur", "spip_auteurs", "id_auteur=" . $auteur_defaut);
253                                                $id_admin = ($id_admin)? $id_admin : 12166 ;
254                                               
255                                                $GLOBALS['auteur_session']['id_auteur'] = $id_admin ;
256                                               
257                                                if($id_article = inserer_conversion($texte, $id_rubrique, $f)){
258                                                       
259                                                        // doit-on conserver l'id_article (option) ?
260                                                        // sql_update spip_articles id_article=$id_source
261                                                        if($conserver_id_article == "oui" and $id_source > 0){
262                                                                sql_update("spip_articles", array("id_article" => $id_source), "id_article=$id_article") ;
263                                                                // maj le lien auteur admin
264                                                                if($spip_version_branche > "3")
265                                                                        sql_update('spip_auteurs_liens',
266                                                                                array(
267                                                                                'id_objet' => $id_source
268                                                                                ),
269                                                                                "objet='article' and id_objet=$id_article"
270                                                                        );
271                                                                else
272                                                                        sql_update('spip_auteurs_articles',
273                                                                                array(
274                                                                                'id_article' => $id_source
275                                                                                ),
276                                                                                "id_article=$id_article"
277                                                                        );
278                                                                $id_article = $id_source ;
279                                                        }
280                                                        // Créer l'auteur ?
281                                                        if($auteurs){
282                                                                // on efface les auteurs, puis on remet les nouveaux
283                                                                if($spip_version_branche > "3")
284                                                                        sql_delete('spip_auteurs_liens', 'id_objet = ' . intval($id_article) . ' and objet="article" and id_auteur !=' . $id_admin);
285                                                                else // spip2
286                                                                        sql_delete('spip_auteurs_articles', 'id_article = ' . intval($id_article) . 'and id_auteur !=' . $id_admin);
287                                                               
288                                                                foreach($auteurs as $auteur){
289                                                                       
290                                                                        list($nom_auteur,$bio_auteur) = explode("::", $auteur);
291                                                                        // On essaie de trouver un nom*prénom dans les auteurs
292                                                                        $a_nom = explode(" ", $nom_auteur);
293                                                                        $prenom_nom = array_pop($a_nom) . "*" . join(" ", $a_nom);
294                                                                       
295                                                                        // echo "\n$prenom_nom\n" ;
296                                                                       
297                                                                        if($id_auteur = sql_getfetsel("id_auteur", "spip_auteurs", "nom=" . sql_quote($prenom_nom))){
298                                                                               
299                                                                        }else
300                                                                                $id_auteur = sql_getfetsel("id_auteur", "spip_auteurs", "nom=" . sql_quote($nom_auteur));
301                                                                       
302                                                                        if(!$id_auteur){
303                                                                                $id_auteur = sql_insertq("spip_auteurs", array(
304                                                                                                "nom" => $nom_auteur,
305                                                                                                "statut" => "1comite",
306                                                                                                "bio" => $bio_auteur
307                                                                                ));
308                                                                               
309                                                                                $auteur_m = substr("Création de l'auteur " . $auteur, 0, 100) ;
310                                                                                $progress->setMessage($auteur_m, 'auteur');
311                                                                        }
312                                                                       
313                                                                        if($spip_version_branche > "3"){
314                                                                                if(!sql_getfetsel("id_auteur", "spip_auteurs_liens", "id_auteur=$id_auteur and id_objet=$id_article and objet='article'"))
315                                                                                        sql_insertq("spip_auteurs_liens", array(
316                                                                                                "id_auteur" => $id_auteur,
317                                                                                                "id_objet" => $id_article,
318                                                                                                "objet" => "article"
319                                                                                        ));
320                                                                        }else // spip 2
321                                                                                if(!sql_getfetsel("id_auteur", "spip_auteurs_articles", "id_auteur=$id_auteur and id_article=$id_article"))
322                                                                                        sql_insertq("spip_auteurs_articles", array(
323                                                                                                "id_auteur" => $id_auteur,
324                                                                                                "id_article" => $id_article
325                                                                                        ));
326                                                                       
327                                                                }
328                                                        }
329                                                       
330                                                        // Créer des mots clés ?
331                                                        if($mots_cles){
332                                                                // on commence par effacer les mots déjà sur l'article, puis on remet les mots.
333                                                                if($spip_version_branche > "3")
334                                                                        sql_delete('spip_mots_liens', 'id_objet = ' . intval($id_article) . ' and objet="article"');
335                                                                else // spip2
336                                                                        sql_delete('spip_mots_articles', 'id_article = ' . intval($id_article));
337                                                               
338                                                                foreach($mots_cles as $mot){
339                                                                        // groupe mot-clé
340                                                                        list($type_mot,$titre_mot) = explode("::", $mot);
341                                                                        $type_mot = ($type_mot)? $type_mot : "Mots importés" ;
342                                                                       
343                                                                        $id_groupe_mot = sql_getfetsel("id_groupe", "spip_groupes_mots", "titre=" . sql_quote($type_mot));
344                                                                        if(!$id_groupe_mot)
345                                                                                $id_groupe_mot = sql_insertq("spip_groupes_mots", array("titre" => $type_mot));
346                                                                       
347                                                                        $id_mot = sql_getfetsel("id_mot", "spip_mots", "titre=" . sql_quote($titre_mot));
348                                                                        if(!$id_mot AND $titre_mot !=""){
349                                                                                $id_mot = sql_insertq("spip_mots", array(
350                                                                                        "titre" => $titre_mot,
351                                                                                        "type" => $type_mot,
352                                                                                        "id_groupe" => $id_groupe_mot
353                                                                                ));
354                                                                                $mot_m = substr("Création du mot " . $titre_mot . " (" . $type_mot .")", 0, 100) ;
355                                                                                $progress->setMessage($mot_m, 'mot');
356                                                                        }
357                                                                       
358                                                                        if($spip_version_branche > "3"){
359                                                                                if(!sql_getfetsel("id_mot", "spip_mots_liens", "id_mot=$id_mot and id_objet=$id_article and objet='article'"))
360                                                                                        sql_insertq("spip_mots_liens", array(
361                                                                                                "id_mot" => $id_mot,
362                                                                                                "id_objet" => $id_article,
363                                                                                                "objet" => "article"
364                                                                                        ));
365                                                                        }else // spip 2
366                                                                                if(!sql_getfetsel("id_mot", "spip_mots_articles", "id_mot=$id_mot and id_article=$id_article"))
367                                                                                        sql_insertq("spip_mots_articles", array(
368                                                                                                "id_mot" => $id_mot,
369                                                                                                "id_article" => $id_article
370                                                                                        ));
371                                                                }
372                                                        }
373                                                       
374                                                        // Créer des documents ?
375                                                        if($documents){
376                                                                // on commence par effacer les docs déjà sur l'article, puis on remet les mots.
377                                                                sql_delete('spip_documents_liens', 'id_objet = ' . intval($id_article) . ' and objet="article"');
378                                                               
379                                                                foreach($documents as $doc){
380                                                                        $d = json_decode($doc, true);
381                                                                        $id_doc = $d['id_document'] ;
382                                                                        unset($d['id_document']);
383                                                                        if(strlen($racine_documents) > 0 AND !preg_match(",/$,",$racine_documents))
384                                                                                $racine_documents = $racine_documents . "/" ;
385                                                                       
386                                                                        if(!preg_match(",^http://,",$d['fichier']))
387                                                                                $d['fichier'] = $racine_documents . $d['fichier'] ;
388                                                                       
389                                                                        // champs ok dans les documents ?
390                                                                        foreach($d as $k => $v)
391                                                                                if(in_array($k, $champs_documents))
392                                                                                        $document_a_inserer[$k] = $v ;
393                                                                       
394                                                                        // insertion du doc
395                                                                        $id_document = sql_getfetsel("id_document", "spip_documents", "fichier=" . sql_quote($d['fichier']));
396                                                                       
397                                                                        if(!$id_document){
398                                                                                $id_document = sql_insertq("spip_documents", $document_a_inserer);
399                                                                                $progress->setMessage("Création du document " . $d['titre'] . " (" . $d['fichier'] .")", 'docs');
400                                                                        }else{
401                                                                                unset($document_a_inserer["id_document"]);
402                                                                                sql_updateq("spip_documents", $document_a_inserer, "id_document=$id_document") ;
403                                                                        }
404                                                                       
405                                                                        if($id_document AND !sql_getfetsel("id_document", "spip_documents_liens", "id_document=$id_document and id_objet=$id_article and objet='article'"))
406                                                                                sql_insertq("spip_documents_liens", array(
407                                                                                                "id_document" => $id_document,
408                                                                                                "id_objet" => $id_article,
409                                                                                                "objet" => "article"
410                                                                        ));
411                                                                       
412                                                                        // modifier le texte qui appelle peut etre un <doc123>
413                                                                        if($id_document){
414                                                                                // ressortir le texte propre...
415                                                                                $texte_art = sql_getfetsel("texte", "spip_articles", "id_article=$id_article");
416                                                                                $texte_art = preg_replace("/(<(doc|img|emb))". $id_doc . "/i", "\${1}$id_document", $texte_art);
417                                                                                sql_update("spip_articles", array("texte" => sql_quote($texte_art)), "id_article=$id_article");
418                                                                               
419                                                                                // le chapo aussi
420                                                                                $chapo_art = sql_getfetsel("chapo", "spip_articles", "id_article=$id_article");
421                                                                                $chapo_art = preg_replace("/(<(doc|img|emb))". $id_doc . "/i", "\${1}$id_document", $chapo_art);
422                                                                                sql_update("spip_articles", array("chapo" => sql_quote($chapo_art)), "id_article=$id_article");
423                                                                               
424                                                                                // le ps aussi
425                                                                                $ps_art = sql_getfetsel("ps", "spip_articles", "id_article=$id_article");
426                                                                                $ps_art = preg_replace("/(<(doc|img|emb))". $id_doc . "/i", "\${1}$id_document", $ps_art);
427                                                                                sql_update("spip_articles", array("ps" => sql_quote($ps_art)), "id_article=$id_article");
428                                                                        }
429                                                                }
430                                                        }
431                                                       
432                                                        // recaler des liens [->123456] dans les textes
433                                                        // si on ne conserve pas le meme id_article
434                                                        include_spip("inc/lien");
435                                                        if(preg_match(_RACCOURCI_LIEN, $texte) and $conserver_id_article == "")
436                                                                passthru("echo '$id_article     $id_source' >> liens_a_corriger.txt");
437                                                       
438                                                        // Si tout s'est bien passé, on avance la barre
439                                                        $progress->setMessage($f, 'filename');
440                                                        $progress->setFormat("<fg=white;bg=blue>%message%</>\n" . "<fg=white;bg=red>%inforub% %auteur% %mot%</>\n" . '%current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%' . "\n  %filename%\n%docs%\n\n");
441                                                        $progress->advance();
442                                                       
443                                                }else{
444                                                        $output->writeln("<error>échec de l'import de $f</error>");
445                                                        exit ;
446                                                }
447                                        }
448                                       
449                                        // ensure that the progress bar is at 100%
450                                        $progress->finish();
451                                       
452                                        // remapper les liens [->12345]
453                                        lire_fichier("liens_a_corriger.txt", $articles);
454                                        $corrections_liens = inc_file_to_array_dist($articles);
455                                       
456                                        if(is_array($corrections_liens))
457                                                foreach($corrections_liens as $k => $v){
458                                                        if($v){
459                                                                list($id_article, $id_source) = explode("\t", $v);
460                                                                include_spip("action/corriger_liens_internes");
461                                                                convertisseur_corriger_liens_internes($id_article,$id_parent,'texte');
462                                                                convertisseur_corriger_liens_internes($id_article,$id_parent,'chapo');
463                                                        }
464                                                }
465                                       
466                                        $output->writeln("");
467                                        if(is_file("liens_a_corriger.txt"))
468                                                unlink("liens_a_corriger.txt");
469                                }
470                        }
471                }
472                else{
473                        $output->writeln('<error>Vous n’êtes pas dans une installation de SPIP. Impossible de convertir le texte.</error>');
474                }
475        }
476}
Note: See TracBrowser for help on using the repository browser.