source: spip-zone/_plugins_/convertisseur/trunk/spip-cli/convertisseurImporter.php @ 107728

Last change on this file since 107728 was 107728, checked in by booz@…, 3 years ago

conserver les id_article avec l'option -c oui

File size: 15.5 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 fichiersImporter 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 rurbriques 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                                'racine_documents',
43                                'r',
44                                InputOption::VALUE_OPTIONAL,
45                                'path ajouté devant le `fichier` des documents joints importés',
46                                ''
47                        )
48                        ->addOption(
49                                'conserver_id_article',
50                                'c',
51                                InputOption::VALUE_OPTIONAL,
52                                'option -c oui pour conserver les id_article',
53                                ''
54                        )
55                ;
56        }
57       
58        protected function execute(InputInterface $input, OutputInterface $output) {
59                global $spip_racine;
60                global $spip_loaded;
61                global $spip_version_branche ;
62               
63                include_spip("iterateur/data");
64               
65                $source = $input->getOption('source') ;
66                $id_parent = $input->getOption('dest') ;
67                $racine_documents = $input->getOption('racine_documents') ;
68                $conserver_id_article = $input->getOption('conserver_id_article') ;
69               
70                // Répertoire source
71                if(!is_dir($source)){
72                        $output->writeln("<error>Préciser le répertoire avec les fichiers à importer. spip import -s repertoire </error>\n");
73                        exit ;
74                }
75               
76                if($id_parent == 0){
77                        $output->writeln("<error>Préciser dans quelle rubrique importer les articles. spip import -d `id_rubrique` </error>\n");
78                        exit ;
79                }
80               
81                if ($spip_loaded) {
82                        chdir($spip_racine);
83                       
84                        if (!function_exists('passthru')){
85                                $output->writeln("<error>Votre installation de PHP doit pouvoir exécuter des commandes externes avec la fonction passthru().</error>");
86                        }
87                        // Si c'est bon on continue
88                        else{
89                               
90                                // Champs d'un article
91                                include_spip("base/abstract_sql");
92                                $show = sql_showtable("spip_articles");
93                                $champs = array_keys($show['field']);
94                               
95                                $show = sql_showtable("spip_documents");
96                                $champs_documents = array_keys($show['field']);
97                               
98                                // Ajout d'un champ la premiere fois pour stocker les éventuelles <ins> qui n'ont pas de champs (peut-être long).
99                                if(!in_array('metadonnees', $champs)){
100                                        $output->writeln("MAJ BDD : alter table spip_articles add metadonnees MEDIUMTEXT NOT NULL DEFAULT ''");
101                                        sql_query("alter table spip_articles add metadonnees MEDIUMTEXT NOT NULL DEFAULT ''");
102                                }
103                                // Ajout d'un champ la premiere fois pour stocker l'id_article original (pour ensuite remapper les liens [->123]).
104                                if(!in_array('id_source', $champs)){
105                                        $output->writeln("MAJ BDD : alter table spip_articles add id_source BIGINT(21) NOT NULL DEFAULT ''");
106                                        sql_query("alter table spip_articles add id_source BIGINT(21) NOT NULL DEFAULT ''");
107                                }
108                                // Ajout d'un champ la premiere fois pour stocker le nom du fichier source, pour reconnaitre un article déjà importé.
109                                if(!in_array('fichier_source', $champs)){
110                                        $output->writeln("MAJ BDD : alter table spip_articles add fichier_source MEDIUMTEXT NOT NULL DEFAULT ''");
111                                        sql_query("alter table spip_articles add fichier_source MEDIUMTEXT NOT NULL DEFAULT ''");
112                                }
113                                // on prend tous les fichiers txt dans la source, sauf si metadata.txt a la fin.
114                                $fichiers = preg_files($source . "/", "(?:(?<!\.metadata\.)txt$)", 100000);
115                               
116                                // start and displays the progress bar
117                                $progress = new ProgressBar($output, sizeof($fichiers));
118                                $progress->setBarWidth(100);
119                                $progress->setRedrawFrequency(1);
120                                $progress->setMessage(" Import de $source/*.txt en cours dans la rubrique $id_parent ... ", 'message'); /**/ 
121                                $progress->setMessage("", 'inforub');
122                                $progress->start();
123                               
124                                if(is_file("liens_a_corriger.txt"))
125                                        unlink("liens_a_corriger.txt");
126                                if(is_file("liens_non_corriges.txt"))
127                                        unlink("liens_non_corriges.txt");
128                                if(is_file("liens_corriges.txt"))
129                                        unlink("liens_corriges.txt");
130                               
131                                foreach($fichiers as $f){
132                                        // date d'apres le nom du fichier
133                                        $fichier = basename($f);
134                                        preg_match("/^(\d{4})-\d{2}/", $fichier, $m);
135                                        $mois = $m[0];
136                                        $annee = $m[1] ;
137                                       
138                                        // chopper l'id_parent dans le fichier ?
139                                        include_spip("inc/flock");
140                                        lire_fichier($f, $texte);
141                                       
142                                        // menage
143                                        //@@COLLECTION:esRetour ligne automatique
144                                        //@@SOURCE:article914237.html
145                                       
146                                        $texte = preg_replace("/@@COLLECTION.*/", "", $texte);
147                                        $texte = preg_replace("/@@SOURCE.*/", "", $texte);
148                                       
149                                        // Si des <ins> correspondent à des champs metadonnees connus, on les ajoute.
150                                        $champs_metadonnees = array("mots_cles", "auteurs", "hierarchie", "documents");
151                                        $hierarchie = "" ;
152                                        $auteurs = "" ;
153                                        $mots_cles = "" ;
154                                        $documents = "" ;
155                                       
156                                        if (preg_match_all(",<ins[^>]+class='(.*?)'[^>]*?>(.*?)</ins>,ims", $texte, $z, PREG_SET_ORDER)){ 
157                                                foreach($z as $d){ 
158                                                        if(in_array($d[1], $champs_metadonnees)){ 
159                                                                // class="truc" => $truc
160                                                                $$d[1] = split("@@", $d[2]); 
161                                                                // virer du texte
162                                                                $texte = substr_replace($texte, '', strpos($texte, $d[0]), strlen($d[0])); 
163                                                        }
164                                                }
165                                        }
166                                       
167                                        if (preg_match(",<ins class='id_article'>(.*?)</ins>,ims", $texte, $z))
168                                                $id_source = $z[1];
169                                       
170                                        // dans quelle rubrique importer ?
171                                        // La hierarchie est-elle précisée dans le fichier ? (en principe oui)
172                                        if($hierarchie){
173                                                $titre_parent = $hierarchie[0] ;
174                                                $titre_rubrique = $hierarchie[1] ;
175                                               
176                                                // hack perso diplo 2006/02 => 02 ou 2006-02 => 02
177                                                $titre_rubrique = preg_replace(",^(\d{4})(?:/|-)(\d{2})$,", "\\2", $titre_rubrique); 
178                                       
179                                        }else{ // sinon on genere des rubriques annees / mois
180                                                $titre_parent = $annee ;
181                                                $titre_rubrique = "$annee-$mois" ;
182                                        }
183                                       
184                                        include_spip("inc/rubriques");
185                                        $id_rubrique = creer_rubrique_nommee("$titre_parent/$titre_rubrique", $id_parent);
186                                        $up = sql_updateq('spip_rubriques', array('statut' => 'publie'), "id_rubrique=$id_rubrique");
187                                       
188                                        if($up)
189                                                $progress->setMessage(" Rubrique $titre_parent/$titre_rubrique => $id_rubrique ", 'inforub');
190                                       
191                                        $progress->setMessage("", 'docs');
192                                        $progress->setMessage("", 'mot');
193                                        $progress->setMessage("", 'auteur');
194                                       
195                                        // inserer l'article
196                                        include_spip("inc/convertisseur");
197                                       
198                                        // auteur par défaut (admin)
199                                        $id_admin = sql_getfetsel("id_auteur", "spip_auteurs", "id_auteur=1");
200                                        $id_admin = ($id_admin)? $id_admin : 12166 ;
201                                       
202                                        $GLOBALS['auteur_session']['id_auteur'] = $id_admin ;
203                                       
204                                        if($id_article = inserer_conversion($texte, $id_rubrique, $f)){
205                                               
206                                                // doit-on conserver l'id_article (option) ?
207                                                // sql_update spip_articles id_article=$id_source
208                                                if($conserver_id_article == "oui" and $id_source > 0){
209                                                        // var_dump($id_article . " est " . $id_source);
210                                                        sql_update("spip_articles", array("id_article" => $id_source), "id_article=$id_article") ;
211                                                        // s'ajouter en auteur en spip 2 ou 3
212                                                        if($spip_version_branche > "3")
213                                                                sql_update('spip_auteurs_liens',
214                                                                        array(
215                                                                        'id_objet' => $id_source
216                                                                        ),
217                                                                        "id_objet='article' and id_objet=$id_source"
218                                                                );
219                                                        else
220                                                                sql_update('spip_auteurs_articles',
221                                                                        array(
222                                                                        'id_article' => $id_source
223                                                                        ),
224                                                                        "id_article=$id_article"
225                                                                );
226                                                        $id_article = $id_source ;
227                                                }
228                                               
229                                                // Créer l'auteur ?
230                                                if($auteurs){
231                                                       
232                                                        foreach($auteurs as $auteur){
233                                                               
234                                                                list($nom_auteur,$bio_auteur) = explode("::", $auteur);
235                                                                // On essaie de trouver un nom*prénom dans les auteurs
236                                                                $a_nom = explode(" ", $nom_auteur);
237                                                                $prenom_nom = array_pop($a_nom) . "*" . join(" ", $a_nom);
238                                                               
239                                                                // echo "\n$prenom_nom\n" ;
240                                                               
241                                                                if($id_auteur = sql_getfetsel("id_auteur", "spip_auteurs", "nom=" . sql_quote($prenom_nom))){
242                                                                       
243                                                                }else
244                                                                        $id_auteur = sql_getfetsel("id_auteur", "spip_auteurs", "nom=" . sql_quote($nom_auteur));
245                                                               
246                                                                if(!$id_auteur){
247                                                                        $id_auteur = sql_insertq("spip_auteurs", array(
248                                                                                        "nom" => $nom_auteur,
249                                                                                        "statut" => "1comite",
250                                                                                        "bio" => $bio_auteur
251                                                                        ));
252                                                                       
253                                                                        $auteur_m = substr("Création de l'auteur " . $auteur, 0, 100) ;
254                                                                        $progress->setMessage($auteur_m, 'auteur');
255                                                                }
256                                                               
257                                                                if($spip_version_branche > "3"){
258                                                                        if(!sql_getfetsel("id_auteur", "spip_auteurs_liens", "id_auteur=$id_auteur and id_objet=$id_article and objet='article'"))
259                                                                                sql_insertq("spip_auteurs_liens", array(
260                                                                                        "id_auteur" => $id_auteur,
261                                                                                        "id_objet" => $id_article,
262                                                                                        "objet" => "article"
263                                                                                ));
264                                                                }else // spip 2
265                                                                        if(!sql_getfetsel("id_auteur", "spip_auteurs_articles", "id_auteur=$id_auteur and id_article=$id_article"))
266                                                                                sql_insertq("spip_auteurs_articles", array(
267                                                                                        "id_auteur" => $id_auteur,
268                                                                                        "id_article" => $id_article
269                                                                                ));
270                                                               
271                                                        }
272                                                }
273                                               
274                                                // Créer des mots clés ?
275                                                if($mots_cles){
276                                                        foreach($mots_cles as $mot){
277                                                                // groupe mot-clé
278                                                                list($type_mot,$titre_mot) = explode("::", $mot);
279                                                                $type_mot = ($type_mot)? $type_mot : "Mots importés" ;
280                                                               
281                                                                $id_groupe_mot = sql_getfetsel("id_groupe", "spip_groupes_mots", "titre=" . sql_quote($type_mot));
282                                                                if(!$id_groupe_mot)
283                                                                        $id_groupe_mot = sql_insertq("spip_groupes_mots", array("titre" => $type_mot));
284                                                               
285                                                                $id_mot = sql_getfetsel("id_mot", "spip_mots", "titre=" . sql_quote($titre_mot));
286                                                                if(!$id_mot AND $titre_mot !=""){
287                                                                        $id_mot = sql_insertq("spip_mots", array(
288                                                                                "titre" => $titre_mot,
289                                                                                "type" => $type_mot,
290                                                                                "id_groupe" => $id_groupe_mot
291                                                                        ));
292                                                                        $mot_m = substr("Création du mot " . $titre_mot . " (" . $type_mot .")", 0, 100) ;
293                                                                        $progress->setMessage($mot_m, 'mot');
294                                                                }
295                                                               
296                                                                if($spip_version_branche > "3"){
297                                                                        if(!sql_getfetsel("id_mot", "spip_mots_liens", "id_mot=$id_mot and id_objet=$id_article and objet='article'"))
298                                                                                sql_insertq("spip_mots_liens", array(
299                                                                                        "id_mot" => $id_mot,
300                                                                                        "id_objet" => $id_article,
301                                                                                        "objet" => "article"
302                                                                                ));
303                                                                }else // spip 2
304                                                                        if(!sql_getfetsel("id_mot", "spip_mots_articles", "id_mot=$id_mot and id_article=$id_article"))
305                                                                                sql_insertq("spip_mots_articles", array(
306                                                                                        "id_mot" => $id_mot,
307                                                                                        "id_article" => $id_article
308                                                                                ));
309                                                        }
310                                                }
311                                               
312                                                // Créer des documents ?
313                                                if($documents){
314                                                        foreach($documents as $doc){
315                                                                $d = json_decode($doc, true);
316                                                                $id_doc = $d['id_document'] ;
317                                                                unset($d['id_document']);
318                                                                if(strlen($racine_documents) > 0 AND !preg_match(",/$,",$racine_documents))
319                                                                        $racine_documents = $racine_documents . "/" ;
320                                                                $d['fichier'] = $racine_documents . $d['fichier'] ;
321                                                               
322                                                                // champs ok dans les documents ?
323                                                                foreach($d as $k => $v)
324                                                                        if(in_array($k, $champs_documents))
325                                                                                $document_a_inserer[$k] = $v ;
326                                                               
327                                                                // insertion du doc
328                                                                $id_document = sql_getfetsel("id_document", "spip_documents", "fichier=" . sql_quote($d['fichier']));
329                                                                if(!$id_document){
330                                                                        $id_document = sql_insertq("spip_documents", $document_a_inserer);
331                                                                        $progress->setMessage("Création du document " . $d['titre'] . " (" . $d['fichier'] .")", 'docs');
332                                                                }
333                                                               
334                                                                if($id_document AND !sql_getfetsel("id_document", "spip_documents_liens", "id_document=$id_document and id_objet=$id_article and objet='article'"))
335                                                                        sql_insertq("spip_documents_liens", array(
336                                                                                        "id_document" => $id_document,
337                                                                                        "id_objet" => $id_article,
338                                                                                        "objet" => "article"
339                                                                ));
340                                                               
341                                                                // modifier le texte qui appelle peut etre un <doc123>
342                                                                if($id_document){
343                                                                        // ressortir le texte propre...
344                                                                        $texte = sql_getfetsel("texte", "spip_articles", "id_article=$id_article");
345                                                                        $texte = preg_replace("/(<(doc|img|emb))". $id_doc . "/i", "\${1}" . $id_document, $texte);
346                                                                        sql_update("spip_articles", array("texte" => sql_quote($texte)), "id_article=$id_article");
347                                                                }
348                                                        }
349                                                }
350                                               
351                                                // recaler des liens [->123456] ?
352                                                // si on ne conserve pas le meme id_article
353                                                include_spip("inc/lien");
354                                                if(preg_match(_RACCOURCI_LIEN, $texte))
355                                                        passthru("echo '$id_article     $id_source' >> liens_a_corriger.txt");
356                                               
357                                                // Si tout s'est bien passé, on avance la barre
358                                                $progress->setMessage($f, 'filename');
359                                                $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");
360                                                $progress->advance();
361                                               
362                                        }else{
363                                                $output->writeln("<error>échec de l'import de $f</error>");
364                                                exit ;
365                                        }
366                                }
367                               
368                                // ensure that the progress bar is at 100%
369                                $progress->finish();
370                               
371                                // remapper les liens [->12345]
372                                lire_fichier("liens_a_corriger.txt", $articles);
373                                $corrections_liens = inc_file_to_array_dist($articles);
374                               
375                                if(is_array($corrections_liens))
376                                        foreach($corrections_liens as $k => $v){
377                                                if($v){
378                                                        list($id_article, $id_source) = explode("\t", $v);
379                                                        $texte = sql_getfetsel("texte", "spip_articles", "id_article=$id_article") ;
380                                                        // recaler des liens [->123456] ?
381                                                        include_spip("inc/lien");
382                                                        if(preg_match_all(_RACCOURCI_LIEN, $texte, $liens, PREG_SET_ORDER)){
383                                                                foreach($liens as $l){
384                                                                        if(preg_match("/^[0-9]+$/", $l[4])){
385                                                                                // trouver l'article dont l'id_source est $l[4] dans le secteur
386                                                                                if($id_dest = sql_getfetsel("id_article", "spip_articles", "id_source=" . trim($l[4]) . " and id_secteur=$id_parent")){
387                                                                                        $lien_actuel = $l[0] ;
388                                                                                        $lien_corrige = str_replace($l[4], $id_dest, $l[0]) ;
389                                                                                       
390                                                                                        $lien = escapeshellarg("$id_article : $lien_actuel => $lien_corrige");
391                                                                                        passthru("echo $lien >> liens_corriges.txt");
392                                                                                        // maj le texte
393                                                                                        $texte_corrige = str_replace($lien_actuel, $lien_corrige, $texte);
394                                                                                        sql_update("spip_articles", array("texte" => sql_quote($texte_corrige)), "id_article=$id_article");
395                                                                                        // attention s'il y a plusieurs liens
396                                                                                        $texte = $texte_corrige ;
397                                                                                }else{
398                                                                                        $commande = escapeshellarg("Dans $id_article (source $id_source)" . $l[0] . " : lien vers " . $l[4] . " non trouvé") ;
399                                                                                        passthru("echo $commande >> liens_non_corriges.txt");
400                                                                                }
401                                                                               
402                                                                        }
403                                                                }
404                                                        }
405                                                }
406                                        }
407                               
408                                $output->writeln("");
409                                if(is_file("liens_a_corriger.txt"))
410                                        unlink("liens_a_corriger.txt");
411                        }
412                }
413                else{
414                        $output->writeln('<error>Vous n’êtes pas dans une installation de SPIP. Impossible de convertir le texte.</error>');
415                }
416        }
417}
Note: See TracBrowser for help on using the repository browser.