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

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

indentation

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