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

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

importer le descriptif de la rubrique de l'article

File size: 15.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 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", "descriptif_rubrique");
151                                        $hierarchie = "" ;
152                                        $auteurs = "" ;
153                                        $mots_cles = "" ;
154                                        $documents = "" ;
155                                        $descriptif_rubrique = "" ;
156                                       
157                                        if (preg_match_all(",<ins[^>]+class='(.*?)'[^>]*?>(.*?)</ins>,ims", $texte, $z, PREG_SET_ORDER)){ 
158                                                foreach($z as $d){ 
159                                                        if(in_array($d[1], $champs_metadonnees)){ 
160                                                                // class="truc" => $truc
161                                                                $$d[1] = split("@@", $d[2]); 
162                                                                // virer du texte
163                                                                $texte = substr_replace($texte, '', strpos($texte, $d[0]), strlen($d[0])); 
164                                                        }
165                                                }
166                                        }
167                                       
168                                        $descriptif_rubrique = $descriptif_rubrique[0] ;
169                                       
170                                        if (preg_match(",<ins class='id_article'>(.*?)</ins>,ims", $texte, $z))
171                                                $id_source = $z[1];
172                                       
173                                        // dans quelle rubrique importer ?
174                                        // La hierarchie est-elle précisée dans le fichier ? (en principe oui)
175                                        if($hierarchie){
176                                                $titre_parent = $hierarchie[0] ;
177                                                $titre_rubrique = $hierarchie[1] ;
178                                               
179                                                // hack perso diplo 2006/02 => 02 ou 2006-02 => 02
180                                                $titre_rubrique = preg_replace(",^(\d{4})(?:/|-)(\d{2})$,", "\\2", $titre_rubrique); 
181                                       
182                                        }else{ // sinon on genere des rubriques annees / mois
183                                                $titre_parent = $annee ;
184                                                $titre_rubrique = "$annee-$mois" ;
185                                        }
186                                       
187                                        include_spip("inc/rubriques");
188                                        $id_rubrique = creer_rubrique_nommee("$titre_parent/$titre_rubrique", $id_parent);
189                                        $up = sql_updateq('spip_rubriques', array('statut' => 'publie', 'descriptif' => $descriptif_rubrique), "id_rubrique=$id_rubrique");
190                                       
191                                        if($up)
192                                                $progress->setMessage(" Rubrique $titre_parent/$titre_rubrique => $id_rubrique ", 'inforub');
193                                       
194                                        $progress->setMessage("", 'docs');
195                                        $progress->setMessage("", 'mot');
196                                        $progress->setMessage("", 'auteur');
197                                       
198                                        // inserer l'article
199                                        include_spip("inc/convertisseur");
200                                       
201                                        // auteur par défaut (admin)
202                                        $id_admin = sql_getfetsel("id_auteur", "spip_auteurs", "id_auteur=1");
203                                        $id_admin = ($id_admin)? $id_admin : 12166 ;
204                                       
205                                        $GLOBALS['auteur_session']['id_auteur'] = $id_admin ;
206                                       
207                                        if($id_article = inserer_conversion($texte, $id_rubrique, $f)){
208                                               
209                                                // doit-on conserver l'id_article (option) ?
210                                                // sql_update spip_articles id_article=$id_source
211                                                if($conserver_id_article == "oui" and $id_source > 0){
212                                                        sql_update("spip_articles", array("id_article" => $id_source), "id_article=$id_article") ;
213                                                        // maj le lien auteur admin
214                                                        if($spip_version_branche > "3")
215                                                                sql_update('spip_auteurs_liens',
216                                                                        array(
217                                                                        'id_objet' => $id_source
218                                                                        ),
219                                                                        "objet='article' and id_objet=$id_article"
220                                                                );
221                                                        else
222                                                                sql_update('spip_auteurs_articles',
223                                                                        array(
224                                                                        'id_article' => $id_source
225                                                                        ),
226                                                                        "id_article=$id_article"
227                                                                );
228                                                        $id_article = $id_source ;
229                                                }
230                                                // Créer l'auteur ?
231                                                if($auteurs){
232                                                       
233                                                        foreach($auteurs as $auteur){
234                                                               
235                                                                list($nom_auteur,$bio_auteur) = explode("::", $auteur);
236                                                                // On essaie de trouver un nom*prénom dans les auteurs
237                                                                $a_nom = explode(" ", $nom_auteur);
238                                                                $prenom_nom = array_pop($a_nom) . "*" . join(" ", $a_nom);
239                                                               
240                                                                // echo "\n$prenom_nom\n" ;
241                                                               
242                                                                if($id_auteur = sql_getfetsel("id_auteur", "spip_auteurs", "nom=" . sql_quote($prenom_nom))){
243                                                                       
244                                                                }else
245                                                                        $id_auteur = sql_getfetsel("id_auteur", "spip_auteurs", "nom=" . sql_quote($nom_auteur));
246                                                               
247                                                                if(!$id_auteur){
248                                                                        $id_auteur = sql_insertq("spip_auteurs", array(
249                                                                                        "nom" => $nom_auteur,
250                                                                                        "statut" => "1comite",
251                                                                                        "bio" => $bio_auteur
252                                                                        ));
253                                                                       
254                                                                        $auteur_m = substr("Création de l'auteur " . $auteur, 0, 100) ;
255                                                                        $progress->setMessage($auteur_m, 'auteur');
256                                                                }
257                                                               
258                                                                if($spip_version_branche > "3"){
259                                                                        if(!sql_getfetsel("id_auteur", "spip_auteurs_liens", "id_auteur=$id_auteur and id_objet=$id_article and objet='article'"))
260                                                                                sql_insertq("spip_auteurs_liens", array(
261                                                                                        "id_auteur" => $id_auteur,
262                                                                                        "id_objet" => $id_article,
263                                                                                        "objet" => "article"
264                                                                                ));
265                                                                }else // spip 2
266                                                                        if(!sql_getfetsel("id_auteur", "spip_auteurs_articles", "id_auteur=$id_auteur and id_article=$id_article"))
267                                                                                sql_insertq("spip_auteurs_articles", array(
268                                                                                        "id_auteur" => $id_auteur,
269                                                                                        "id_article" => $id_article
270                                                                                ));
271                                                               
272                                                        }
273                                                }
274                                               
275                                                // Créer des mots clés ?
276                                                if($mots_cles){
277                                                        foreach($mots_cles as $mot){
278                                                                // groupe mot-clé
279                                                                list($type_mot,$titre_mot) = explode("::", $mot);
280                                                                $type_mot = ($type_mot)? $type_mot : "Mots importés" ;
281                                                               
282                                                                $id_groupe_mot = sql_getfetsel("id_groupe", "spip_groupes_mots", "titre=" . sql_quote($type_mot));
283                                                                if(!$id_groupe_mot)
284                                                                        $id_groupe_mot = sql_insertq("spip_groupes_mots", array("titre" => $type_mot));
285                                                               
286                                                                $id_mot = sql_getfetsel("id_mot", "spip_mots", "titre=" . sql_quote($titre_mot));
287                                                                if(!$id_mot AND $titre_mot !=""){
288                                                                        $id_mot = sql_insertq("spip_mots", array(
289                                                                                "titre" => $titre_mot,
290                                                                                "type" => $type_mot,
291                                                                                "id_groupe" => $id_groupe_mot
292                                                                        ));
293                                                                        $mot_m = substr("Création du mot " . $titre_mot . " (" . $type_mot .")", 0, 100) ;
294                                                                        $progress->setMessage($mot_m, 'mot');
295                                                                }
296                                                               
297                                                                if($spip_version_branche > "3"){
298                                                                        if(!sql_getfetsel("id_mot", "spip_mots_liens", "id_mot=$id_mot and id_objet=$id_article and objet='article'"))
299                                                                                sql_insertq("spip_mots_liens", array(
300                                                                                        "id_mot" => $id_mot,
301                                                                                        "id_objet" => $id_article,
302                                                                                        "objet" => "article"
303                                                                                ));
304                                                                }else // spip 2
305                                                                        if(!sql_getfetsel("id_mot", "spip_mots_articles", "id_mot=$id_mot and id_article=$id_article"))
306                                                                                sql_insertq("spip_mots_articles", array(
307                                                                                        "id_mot" => $id_mot,
308                                                                                        "id_article" => $id_article
309                                                                                ));
310                                                        }
311                                                }
312                                               
313                                                // Créer des documents ?
314                                                if($documents){
315                                                        foreach($documents as $doc){
316                                                                $d = json_decode($doc, true);
317                                                                $id_doc = $d['id_document'] ;
318                                                                unset($d['id_document']);
319                                                                if(strlen($racine_documents) > 0 AND !preg_match(",/$,",$racine_documents))
320                                                                        $racine_documents = $racine_documents . "/" ;
321                                                                $d['fichier'] = $racine_documents . $d['fichier'] ;
322                                                               
323                                                                // champs ok dans les documents ?
324                                                                foreach($d as $k => $v)
325                                                                        if(in_array($k, $champs_documents))
326                                                                                $document_a_inserer[$k] = $v ;
327                                                               
328                                                                // insertion du doc
329                                                                $id_document = sql_getfetsel("id_document", "spip_documents", "fichier=" . sql_quote($d['fichier']));
330                                                                if(!$id_document){
331                                                                        $id_document = sql_insertq("spip_documents", $document_a_inserer);
332                                                                        $progress->setMessage("Création du document " . $d['titre'] . " (" . $d['fichier'] .")", 'docs');
333                                                                }
334                                                               
335                                                                if($id_document AND !sql_getfetsel("id_document", "spip_documents_liens", "id_document=$id_document and id_objet=$id_article and objet='article'"))
336                                                                        sql_insertq("spip_documents_liens", array(
337                                                                                        "id_document" => $id_document,
338                                                                                        "id_objet" => $id_article,
339                                                                                        "objet" => "article"
340                                                                ));
341                                                               
342                                                                // modifier le texte qui appelle peut etre un <doc123>
343                                                                if($id_document){
344                                                                        // ressortir le texte propre...
345                                                                        $texte = sql_getfetsel("texte", "spip_articles", "id_article=$id_article");
346                                                                        $texte = preg_replace("/(<(doc|img|emb))". $id_doc . "/i", "\${1}" . $id_document, $texte);
347                                                                        sql_update("spip_articles", array("texte" => sql_quote($texte)), "id_article=$id_article");
348                                                                }
349                                                        }
350                                                }
351                                               
352                                                // recaler des liens [->123456] ?
353                                                // si on ne conserve pas le meme id_article
354                                                include_spip("inc/lien");
355                                                if(preg_match(_RACCOURCI_LIEN, $texte) and $conserver_id_article == "")
356                                                        passthru("echo '$id_article     $id_source' >> liens_a_corriger.txt");
357                                               
358                                                // Si tout s'est bien passé, on avance la barre
359                                                $progress->setMessage($f, 'filename');
360                                                $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");
361                                                $progress->advance();
362                                               
363                                        }else{
364                                                $output->writeln("<error>échec de l'import de $f</error>");
365                                                exit ;
366                                        }
367                                }
368                               
369                                // ensure that the progress bar is at 100%
370                                $progress->finish();
371                               
372                                // remapper les liens [->12345]
373                                lire_fichier("liens_a_corriger.txt", $articles);
374                                $corrections_liens = inc_file_to_array_dist($articles);
375                               
376                                if(is_array($corrections_liens))
377                                        foreach($corrections_liens as $k => $v){
378                                                if($v){
379                                                        list($id_article, $id_source) = explode("\t", $v);
380                                                        $texte = sql_getfetsel("texte", "spip_articles", "id_article=$id_article") ;
381                                                        // recaler des liens [->123456] ?
382                                                        include_spip("inc/lien");
383                                                        if(preg_match_all(_RACCOURCI_LIEN, $texte, $liens, PREG_SET_ORDER)){
384                                                                foreach($liens as $l){
385                                                                        if(preg_match("/^[0-9]+$/", $l[4])){
386                                                                                // trouver l'article dont l'id_source est $l[4] dans le secteur
387                                                                                if($id_dest = sql_getfetsel("id_article", "spip_articles", "id_source=" . trim($l[4]) . " and id_secteur=$id_parent")){
388                                                                                        $lien_actuel = $l[0] ;
389                                                                                        $lien_corrige = str_replace($l[4], $id_dest, $l[0]) ;
390                                                                                       
391                                                                                        $lien = escapeshellarg("$id_article : $lien_actuel => $lien_corrige");
392                                                                                        passthru("echo $lien >> liens_corriges.txt");
393                                                                                        // maj le texte
394                                                                                        $texte_corrige = str_replace($lien_actuel, $lien_corrige, $texte);
395                                                                                        sql_update("spip_articles", array("texte" => sql_quote($texte_corrige)), "id_article=$id_article");
396                                                                                        // attention s'il y a plusieurs liens
397                                                                                        $texte = $texte_corrige ;
398                                                                                }else{
399                                                                                        $commande = escapeshellarg("Dans $id_article (source $id_source)" . $l[0] . " : lien vers " . $l[4] . " non trouvé") ;
400                                                                                        passthru("echo $commande >> liens_non_corriges.txt");
401                                                                                }
402                                                                               
403                                                                        }
404                                                                }
405                                                        }
406                                                }
407                                        }
408                               
409                                $output->writeln("");
410                                if(is_file("liens_a_corriger.txt"))
411                                        unlink("liens_a_corriger.txt");
412                        }
413                }
414                else{
415                        $output->writeln('<error>Vous n’êtes pas dans une installation de SPIP. Impossible de convertir le texte.</error>');
416                }
417        }
418}
Note: See TracBrowser for help on using the repository browser.