Changeset 76417 in spip-zone


Ignore:
Timestamp:
Sep 23, 2013, 2:13:14 PM (6 years ago)
Author:
cedric@…
Message:

Version portée et fonctionnelle du plugin pour SPIP 3.
Nouveautés :

  • recherche dans tous les objets editoriaux de SPIP (déclarés selon l'API)
  • recherche dans les champs editables (ou si non declares, dans les champs versionnes), en filtrant pour ne prendre que les champs texte (on exclue aussi qq champs bien connus qui ne sont pas editoriaux)
  • affiche les résultats de la recherche par type d'objet, avec nombre d'occurence dans chaque objet
  • affiche les résultats de la recherche avant tout remplacement
  • remplacement cochable type par type (on peut ne remplacer que dans les articles par exemple)

La recherche est du type str_replace, donc recherche la chaine exacte, sensible à la casse. Améliorations possibles de ce côté là, donc.

Location:
_plugins_/rechremp/trunk
Files:
6 added
1 deleted
4 edited
2 copied
1 moved

Legend:

Unmodified
Added
Removed
  • _plugins_/rechremp/trunk/formulaires/rechercher_remplacer.html

    r49251 r76417  
    11<div class="formulaire_spip formulaire_editer formulaire_rechercher_remplacer">
    22
    3 [<p class="reponse_formulaire reponse_formulaire_ok">(#ENV*{message_ok})</p>]
    4 [<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>]
     3        [<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>]
    54
    6 <form action="#ENV{action}" method="post" style="padding:15px;">
    7         #ACTION_FORMULAIRE{#ENV{action}}
    8         <p class="explication">Recherche et remplace du texte dans les champs texte de la BDD</p>
    9        
    10         <br><br>
    11         [<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{txt_search})</span><br>]
    12         Texte à rechercher : <input type="text" name="txt_search" value="#ENV{txt_search}" size="55px" />
     5        <form action="#ENV{action}" method="post">
     6                #ACTION_FORMULAIRE{#ENV{action}}
     7                <p class="explication"><:rechremp:explication_rechremp:></p>
    138
    14         <br><br>Remplacement du texte <input type="checkbox" name="remplace" value="oui"><br>   
    15         <br>Remplacer le texte recherché par : <input type="text" name="remplacer_par" value="#ENV{remplacer_par}" size="55px" />
     9                #SET{fl,rechremp}
     10                <ul>
     11                        #SET{name,search}#SET{obli,''}#SET{defaut,''}#SET{erreurs,#ENV**{erreurs}|table_valeur{#GET{name}}}
     12                        <li class="editer editer_[(#GET{name})][ (#GET{obli})][ (#GET{erreurs}|oui)erreur]">
     13                                <label for="#GET{name}">[(#GET{fl}|concat{':label_',#GET{name}}|_T)]</label>[
     14                                <span class='erreur_message'>(#GET{erreurs})</span>
     15                                ]<input type="text" name="#GET{name}" class="text" value="#ENV*{#GET{name},#GET{defaut}}" id="#GET{name}" [(#HTML5|et{#GET{obli}})required='required']/>
     16                        </li>
     17                        #SET{name,replace}#SET{obli,''}#SET{defaut,''}#SET{erreurs,#ENV**{erreurs}|table_valeur{#GET{name}}}
     18                        <li class="editer editer_[(#GET{name})][ (#GET{obli})][ (#GET{erreurs}|oui)erreur]">
     19                                #SET{val,yes}
     20                                <div class="choix">
     21                                        <input type="checkbox" name="#GET{name}_#GET{val}" class="checkbox" id="#GET{name}_#GET{val}" value="#GET{val}"[(#GET{val}|=={#ENV{#GET{name}_#GET{val},''}}|oui)checked="checked"] onchange="update_do_replace()"/>
     22                                        <label for="#GET{name}_#GET{val}">[(#GET{fl}|concat{':label_',#GET{name},'_',#GET{val}}|_T)]</label>
     23                                </div>
     24                                <div class="do_replace[(#ENV{replace_yes,''}|non)none]">
     25                                        <label for="#GET{name}">[(#GET{fl}|concat{':label_',#GET{name}}|_T)]</label>[
     26                                        <span class='erreur_message'>(#GET{erreurs})</span>
     27                                        ]<input type="text" name="#GET{name}" class="text" value="#ENV*{#GET{name},#GET{defaut}}" id="#GET{name}" [(#HTML5|et{#GET{obli}})required='required']/>
     28                                </div>
     29                        </li>
     30                </ul>
     31                <!--extra-->
     32                <p class='boutons'><span class='image_loading'>&nbsp;</span>
     33                <input type='submit' name="rechercher" class='submit' value='<:rechremp:bouton_rechercher|attribut_html:>' /></p>
    1634
    17        
    18         <p class="boutons">
    19         <input type='submit' name='ok' value="Rechercher" />
    20         </p>
    21 </form>
     35                <!-- Resultat de la recherche -->
     36                [<ul><li class="editer pleine_largeur">
     37                <h3><:resultats_recherche:> [<small>&#171;&nbsp;(#ENV{search})&nbsp;&#187;</small>]</h3>
     38                (#ENV**{erreurs/search_results})
     39                </li></ul>
     40                [(#ENV{replace_yes,''}|oui)
     41                <p class='boutons'><span class='image_loading'>&nbsp;</span>
     42                <input type='submit' name="remplacer" class='submit' value='<:rechremp:bouton_remplacer|attribut_html:>' /></p>
     43                ]
     44                ]
     45        </form>
     46        [<div class="reponse_formulaire reponse_formulaire_ok">(#ENV*{message_ok})</div>]
     47
    2248</div>
     49<script type="text/javascript">
     50function update_do_replace(){
     51        if (jQuery('input.checkbox[name="replace_yes"]').is(":checked"))
     52                jQuery(".do_replace").show("fast");
     53        else
     54                jQuery(".do_replace").hide("fast");
     55}
     56jQuery(update_do_replace);
     57</script>
  • _plugins_/rechremp/trunk/formulaires/rechercher_remplacer.php

    r49251 r76417  
    11<?php
     2/**
     3 * Plugin Rechercher/Remplacer
     4 * Licence GPL-v3
     5 *
     6 */
    27
    3 include_spip('inc/utils');
    4 
    5 define("TXT_A_RECHERCHER", "votre recherche");
    6 
    7 function remplace_txt($entite, $id, $champs, $txt_search, $remplace, $remplace_par="") {
    8         $nom_table = "spip_".$entite;
    9         if($entite=="article" || $entite=="rubrique" || $entite=="auteur")
    10                 $nom_table .= "s";
    11 
    12         $retour = "";
    13         $select = $id;
    14 
    15         foreach ($champs as $i => $nom_champ) {
    16                 $select .= ', '.$nom_champ;
    17         }
    18 
    19         if($resultats = sql_select($select, $nom_table)) {
    20                 while($res = sql_fetch($resultats)) {
    21                         $nouvelles_valeurs = array();
    22                         $update = false;
    23 
    24                         // on parcourt tous les champs
    25                         foreach ($champs as $i => $nom_champ) {
    26                                 $nb = 0;
    27                                 $nouvelles_valeurs[$nom_champ] = str_replace($txt_search, $remplace_par, $res[$nom_champ], $nb);
    28                                 if($nb>0) $update = true;
    29                         }
    30 
    31                         // Mise à jour d'un champ de la table
    32                         if($update) {
    33                                 $retour .= "Texte trouv&eacute; dans <a href=\"".generer_url_entite($res[$id], $entite)."\">$entite ".$res[$id]."</a><br>";
    34                                 if($remplace)
    35                                         sql_updateq($nom_table, $nouvelles_valeurs, $id."=".intval($res[$id]));
    36                         }
    37                 }
    38         }
    39         return $retour;
    40 }
     8if (!defined("_ECRIRE_INC_VERSION")) return;
    419
    4210function formulaires_rechercher_remplacer_charger_dist(){
    43         $valeurs = array('txt_search'=> TXT_A_RECHERCHER,
    44                 'remplace'=>'',
    45                 'remplacer_par'=>'');
     11        $valeurs = array(
     12                'search'=>'',
     13                'replace_yes' => '',
     14                'replace'=>''
     15        );
    4616
    4717        return $valeurs;
     
    5121        $erreurs = array();
    5222
    53         if(!_request('txt_search'))
    54                 $erreurs['txt_search'] = 'Saisie obligatoire';
     23        if(!_request('search'))
     24                $erreurs['search'] = _T('info_obligatoire');
    5525
    56         if(count($erreurs))
    57                 $erreurs['message_erreur'] = 'Votre saisie contient des erreurs !';
     26        else
     27                if(!_request('remplacer'))
     28                        // recherche a blanc pour voir/confirmer le remplacement
     29                        $erreurs['search_results'] =
     30                                "<input type='hidden' name='replace_check_table[dummy]' value='yes' />"
     31                                . rechremp_search_and_replace(_request('search'),'',false,_request('replace_yes')?"replace_check_table":null);
    5832
    5933        return $erreurs;
    6034}
    6135
    62 function formulaires_rechercher_remplacer_traiter_dist(){       
    63         $msg = "";
     36function formulaires_rechercher_remplacer_traiter_dist(){
    6437
    65         $msg .= remplace_txt('article', 'id_article', array("surtitre","titre","soustitre","descriptif","texte","chapo","ps"), _request('txt_search'), _request('remplace'), _request('remplacer_par'));
    66         $msg .= remplace_txt('rubrique', 'id_rubrique', array("titre","descriptif","texte"), _request('txt_search'), _request('remplace'), _request('remplacer_par'));
    67         $msg .= remplace_txt('auteur', 'id_auteur', array("bio"), _request('txt_search'), _request('remplace'), _request('remplacer_par'));
    68         $msg .= remplace_txt('forum', 'id_forum', array("texte"), _request('txt_search'), _request('remplace'), _request('remplacer_par'));
    69         $msg .= remplace_txt('syndic', 'id_syndic', array("descriptif"), _request('txt_search'), _request('remplace'), _request('remplacer_par'));
    70         $msg .= "Fin du traitement";
    71         return array('message_ok'=>$msg);
     38        $res = array();
     39
     40        // remplacer si demande
     41        if (_request('remplacer')
     42          AND _request('replace_yes')){
     43                $check_replace = _request('replace_check_table');
     44                $res['message_ok'] =
     45                        "<h3>"._T("rechremp:resultat_remplacement")."<small>&#171;&nbsp;".entites_html(_request('search'))."&nbsp;&#187;</small></h3>"
     46                . rechremp_search_and_replace(_request('search'),_request('replace'),true,$check_replace);
     47        }
     48        else
     49                // sinon simple recherche, mais normalement on arrive pas la
     50                $res['message_ok'] = rechremp_search_and_replace(_request('search'));
     51
     52        return $res;
     53}
     54
     55
     56
     57
     58function rechremp_search_and_replace($search,$replace=null,$do_replace=false,$check_replace=null){
     59        include_spip("base/objets");
     60        $tables_exclues = array('spip_messages','spip_depots','spip_paquets','spip_plugins');
     61        $champs_exclus = array("extra","tables_liees","obligatoire","comite","minirezo","forum","mode","fichier","distant","media");
     62        $liste = lister_tables_objets_sql();
     63        $trouver_table = charger_fonction("trouver_table","base");
     64
     65        $out = array();
     66        foreach($liste as $table => $desc){
     67                if (!in_array($table,$tables_exclues)){
     68                        $champs = array();
     69                        if (isset($desc['champs_editables']) AND $desc['champs_editables'])
     70                                $champs = $desc['champs_editables'];
     71                        elseif(isset($desc['champs_versionnes']))
     72                                $champs = $desc['champs_versionnes'];
     73
     74                        // trouver les champs de la vrai table
     75                        $desc = $trouver_table($table);
     76                        // pas touche au champ extra serialize
     77                        $champs = array_diff($champs,$champs_exclus);
     78                        // que les champs qui existent
     79                        $champs = array_intersect($champs,array_keys($desc['field']));
     80                        // et qui sont en texte
     81                        foreach($champs as $c){
     82                                if (!preg_match(",text|varchar,",$desc['field'][$c]))
     83                                        $champs = array_diff($champs,array($c));
     84                        }
     85
     86                        if (count($champs)){
     87
     88                                $replace_here = $do_replace;
     89                                if  (is_array($check_replace) AND !isset($check_replace[$table]))
     90                                        $replace_here = false;
     91
     92                                $t = rechremp_search_and_replace_table($table,$champs,$search,$replace,$replace_here);
     93                                if ($t AND is_string($check_replace)){
     94                                        $i = "<input type='checkbox' name='{$check_replace}[$table]' />";
     95                                        $t = preg_replace(",<label[^>]*>,","\\0$i",$t,1);
     96                                }
     97                                if ($t){
     98                                        if ($do_replace AND !$replace_here)
     99                                                $t = _T('rechremp:aucun_remplacement_sur',array('objets'=>_T(objet_info(objet_type($table),"texte_objets"))));
     100                                        $out[] = $t;
     101                                }
     102                        }
     103                }
     104        }
     105        $out = array_filter($out);
     106        if (count($out))
     107                $out = implode("<br />",$out);
     108        else
     109                $out = _T('rechremp:aucune_occurence_trouvee');
     110
     111        return $out;
     112}
     113
     114function rechremp_search_and_replace_table($table, $champs, $search,$replace=null,$do_replace=false) {
     115        if (!count($champs) OR !$search)
     116                return "";
     117
     118        include_spip("action/editer_objet");
     119        include_spip("inc/filtres");
     120        include_spip("inc/texte");
     121
     122        $objet = objet_type($table);
     123        $primary = id_table_objet($table);
     124        $select = "$primary,".implode(",",$champs);
     125
     126        $nb_occurences = 0;
     127        $founds = array();
     128        $res = sql_select($select,$table);
     129
     130        while($row = sql_fetch($res)) {
     131
     132                $set = array();
     133                foreach($champs as $c){
     134                        $nb = 0;
     135                        $v = str_replace($search, $replace, $row[$c], $nb);
     136                        if ($nb){
     137                                $set[$c] = $v;
     138                                if (!isset($founds[$row[$primary]]))
     139                                        $founds[$row[$primary]] = 0;
     140                                $founds[$row[$primary]] += $nb;
     141                                $nb_occurences += $nb;
     142                        }
     143                }
     144
     145                // Mise à jour d'un champ de la table
     146                if($do_replace AND count($set)) {
     147                        objet_modifier($objet,$row[$primary],$set);
     148                }
     149        }
     150
     151        if (!$nb_occurences)
     152                return "";
     153
     154        $out = singulier_ou_pluriel($nb_occurences,'rechremp:1_occurence_dans','rechremp:nb_occurences_dans');
     155
     156        $out .= " ".objet_afficher_nb(count($founds),$objet);
     157        $out = "<label><strong>$out</strong></label><ul class='spip'>";
     158
     159        foreach($founds as $id_objet=>$nb){
     160                $l = singulier_ou_pluriel($nb,'rechremp:1_occurence_dans','rechremp:nb_occurences_dans');
     161                $l .= " <a href=\"".generer_url_entite($id_objet,$objet)."\">".generer_info_entite($id_objet,$objet,"titre")."</a>";
     162                $out .="<li>$l</li>\n";
     163        }
     164
     165        $out .= "</ul>";
     166
     167
     168        return $out;
    72169}
    73170
  • _plugins_/rechremp/trunk/lang/paquet-rechremp_fr.php

    r75988 r76417  
    1515// R
    1616        'rechremp_description' => 'Rechercher les occurences d\'un texte et les remplacer par un autre texte, dans les champs de type texte des objets SPIP.',
    17         'rechremp_slogan' => 'Rechercher des chaines dans la BDD SPIP et eventuellement les remplacer par une autre chaine',
     17        'rechremp_slogan' => 'Rechercher/Remplacer en base',
    1818);
    1919?>
  • _plugins_/rechremp/trunk/lang/rechremp_fr.php

    r76412 r76417  
    1313$GLOBALS[$GLOBALS['idx_lang']] = array(
    1414
    15 // R
    16         'rechremp_description' => 'Rechercher les occurences d\'un texte et les remplacer par un autre texte, dans les champs de type texte des objets SPIP.',
    17         'rechremp_slogan' => 'Rechercher des chaines dans la BDD SPIP et eventuellement les remplacer par une autre chaine',
     15        'titre_rechremp' => 'Rechercher/Remplacer',
     16        'explication_rechremp' => 'Recherche et remplace du texte dans les objets éditoriaux de SPIP (article, rubrique...).
     17Seuls les champs de type texte sont pris en compte.',
     18        'label_search' => 'Rechercher :',
     19        'label_replace' => 'Remplacer par :',
     20        'label_replace_yes' => 'Remplacer',
     21        'bouton_rechercher' => 'Rechercher',
     22        'bouton_remplacer' => 'Remplacer',
     23
     24        'aucune_occurence_trouvee' => 'Aucune occurence trouvée dans le site.',
     25        '1_occurence_dans' => '1 occurence dans',
     26        'nb_occurences_dans' => '@nb@ occurences dans',
     27
     28        'resultat_remplacement' => 'Résultat du remplacement',
     29        'aucun_remplacement_sur' => 'Aucun remplacement sur les @objets@',
     30
    1831);
    1932?>
  • _plugins_/rechremp/trunk/paquet.xml

    r75988 r76417  
    22        prefix="rechremp"
    33        categorie="outil"
    4         version="1.0.0"
     4        version="1.1.0"
    55        etat="stable"
    66        compatibilite="[3.0.0;3.0.*]"
    7         logo="images/loupe-64.png"
     7        logo="images/rechremp-32.png"
    88        documentation="http://www.spip-contrib.net/3941"
    9 >       
     9>
    1010
    11         <nom>Rechercher-Remplacer</nom>
     11        <nom>Rechercher/Remplacer</nom>
    1212        <!-- Rechercher des chaines dans la BDD SPIP et eventuellement les remplacer par une autre chaine -->
    1313
     
    1717        <licence>GNU/GLP</licence>
    1818
    19         <menu nom="rechremp" titre="Rechercher/Remplacer" parent="menu_edition" icone="prive/images/loupe-24.png" action="rechercher_remplacer" />
     19        <menu nom="rechremp" titre="rechremp:titre_rechremp" parent="menu_administration" icone="images/rechremp-16.png" />
    2020</paquet>
  • _plugins_/rechremp/trunk/prive/squelettes/contenu/rechremp.html

    r76412 r76417  
    1 <h1 class="grostitre">Recherche et remplacement de texte en BDD</h1>
     1<h1 class="grostitre"><:rechremp:titre_rechremp:></h1>
    22<div class="ajax">
    33        #FORMULAIRE_RECHERCHER_REMPLACER
Note: See TracChangeset for help on using the changeset viewer.