Changeset 91373 in spip-zone


Ignore:
Timestamp:
Aug 15, 2015, 10:59:55 PM (4 years ago)
Author:
rastapopoulos@…
Message:

Grosse update de Indexer. Comme on a sauver la branche v1 on passe le trunk en 2.0.0 dev. Au menu : ajout de la source du site (configurable) ; possibilité de configuration pour chaque objet qu'on veut indexer (articles, rubriques, etc) avec une conf générique par défaut qui cherche les statuts existants pour pouvoir en ignorer, et sinon on peut ajouter un fichier de conf (formulaires/configurer_indexer/patate.html) si on veut préciser pour un type ; pour chaque objet on détecte ses jointures possibles et s'il existe une fonction d'indexation dédiée (indexer_jointure_patates) alors on permet de configurer si on veut enregistrer cette jointure dans l'index de cet objet, et là parail pour chaque jointure on peut avoir une configuration dédiée (par ex : ignorer des groupes pour la jointure mots) ; la source SpipDocuments? utilise le filtre introduction pour le summary et on ajoute automatiquement la hiérarchie complète des rubriques si on la trouve (ce qui permet de filtrer par branche en Sphinx)

Location:
_plugins_/indexer/trunk
Files:
7 added
1 deleted
5 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/indexer/trunk/Sources/SpipDocuments.php

    r91223 r91373  
    77
    88class SpipDocuments implements SourceInterface {
    9         /** SPIP récent ? spip_xx_liens ou spip_xx_yy */
    10         private $tables_liens = true;
    119        /** Type d'objet SPIP */
    1210        private $objet = null;
     
    6058                        if ($start) $where[] = "$column >= $start";
    6159                        if ($end)   $where[] = "$column < $end";
    62 
     60                       
     61                        // S'il y a des statuts ignorés… ben on les ignore
     62                        if (
     63                                $statuts_ignores = ('indexer/'.$this->objet.'/statuts_ignores')
     64                                and is_array($statuts_ignores)
     65                        ) {
     66                                $where[] = sql_in('statut', $statuts_ignores, 'not');
     67                        }
     68                       
    6369                        $all = sql_allfetsel(
    6470                                '*',
     
    8793                include_spip('inc/filtres');
    8894                include_spip('inc/texte');
     95                include_spip('inc/config');
     96                include_spip('base/objets');
     97                include_spip('indexer_fonctions');
    8998               
    9099                $doc = array('properties' => array());         
     100               
     101                // S'il y a des statuts ignorés et que c'est le cas, on indexe pas
     102                // Normalement déjà ignoré dans le SQL, mais si jamais la fonction est appelée autre part…
     103                if (
     104                        $statuts_ignores = lire_config('indexer/'.$this->objet.'/statuts_ignores')
     105                        and is_array($statuts_ignores)
     106                        and isset($contenu['statut'])
     107                        and in_array($contenu['statut'], $statuts_ignores)
     108                ) {
     109                        return null;
     110                }
    91111               
    92112                // On cherche les éléments dont on va avoir besoin
     
    97117                $doc['properties']['id_objet'] = $id;
    98118               
    99                 // Pour le titre
     119                // Pour la source du site : config explicite sinon l'URL du site
     120                $doc['properties']['source'] = lire_config('indexer/source', lire_config('adresse_site'));
     121               
     122                // Pour le titre (TODO : mieux détecter, mais la déclaration de l'API est faite pour une requête SQL)
    100123                if (isset($contenu['titre'])) {
    101124                        $doc['title'] = supprimer_numero($contenu['titre']);
     
    108131                }
    109132               
    110                 // Pour le contenu principal
    111                 if (isset($contenu['texte'])) {
     133                // Pour le contenu principal, on va chercher la liste des champs fulltext déclarés
     134                if ($rechercher_champs = array_keys(objet_info($this->objet, 'rechercher_champs'))) {
     135                        $doc['content'] = '';
     136                       
     137                        foreach ($rechercher_champs as $champ) {
     138                                // On ne remet pas le titre
     139                                if ($champ != 'titre' and isset($contenu[$champ]) and $contenu[$champ]) {
     140                                        $doc['content'] .= "\n\n".$contenu[$champ];
     141                                }
     142                        }
     143                }
     144                // Sinon on détecte les cas courants
     145                elseif (isset($contenu['texte'])) {
    112146                        $doc['content'] = $contenu['texte'];
    113147                }
     
    122156                }
    123157               
    124                 // Pour le résumé
    125                 // (on gère direct le cas particulier des articles qui sont dans le core et qu'on connait bien)
    126                 if (
    127                         $this->objet == 'article'
    128                         and $summary = trim($contenu['surtitre']."\n".$contenu['soustitre']."\n".$article['chapo'])
    129                 ) {
    130                         $doc['summary'] = $summary;
    131                 }
    132                 elseif (isset($contenu['descriptif'])) {
    133                         $doc['summary'] = couper($contenu['descriptif'], 200);
    134                 }
    135                 else {
    136                         $doc['summary'] = couper($doc['content'], 200);
     158                // Pour le résumé, on utilise le filtre d'intro de SPIP
     159                // = descriptif s'il existe sinon le contenu principal précédent coupé
     160                $descriptif = isset($contenu['descriptif']) ? $contenu['descriptif'] : ''; // on s'assure que le descriptif soit bien une chaine
     161                if ($fonction_introduction = chercher_filtre('introduction')) {
     162                        $doc['summary'] = $fonction_introduction($descriptif, $doc['content'], 400, '');
    137163                }
    138164               
    139165                // Pour la date
     166                // S'il y a un champ de date de rédaction et qu'il est utilisé, on prend en priorité à celle de publication
    140167                if (isset($contenu['date_redac']) and substr($contenu['date_redac'],0,4) != '0000') {
    141168                        $doc['date'] = $contenu['date_redac'];
    142169                }
     170                // Sinon on utilise la date de publication déclarée par l'API
     171                elseif ($champ_date = objet_info($this->objet, 'date')) {
     172                        $doc['date'] = $contenu[$champ_date];
     173                }
     174                // Sinon le champ "date" tout simplement
    143175                elseif (isset($contenu['date'])) {
    144176                        $doc['date'] = $contenu['date'];
     
    153185                }
    154186               
    155                 // Les auteurs
    156                 if ($authors = $this->getAuthorsProperties($this->objet, $id)) {
    157                         $doc['properties']['authors'] = $authors;
    158                 }
    159                
    160                 // Les mots/tags basiquement
    161                 if ($tags = $this->getTagsProperties($this->objet, $id)) {
    162                         $doc['properties']['tags'] = $tags;
    163                 }
     187                // S'il y a un statut
     188                if (isset($contenu['statut'])) {
     189                        $doc['properties']['statut'] = $contenu['statut'];
     190                }
     191               
     192                // On garde en mémoire le parent si on trouve quelque chose
     193                if (isset($contenu['id_parent'])) {
     194                        $doc['properties']['id_parent'] = intval($contenu['id_parent']);
     195                        $doc['properties']['objet_parent'] = $this->objet;
     196                }
     197                elseif (isset($contenu['id_rubrique'])) {
     198                        $doc['properties']['id_rubrique'] = intval($contenu['id_rubrique']);
     199                        $doc['properties']['id_parent'] = intval($contenu['id_rubrique']);
     200                        $doc['properties']['objet_parent'] = 'rubrique';
     201                }
     202                // Pour les événements au moins
     203                elseif (isset($contenu['id_article'])) {
     204                        $doc['properties']['id_article'] = intval($contenu['id_article']);
     205                        $doc['properties']['id_parent'] = intval($contenu['id_article']);
     206                        $doc['properties']['objet_parent'] = 'article';
     207                }
     208               
     209                // Et ensuite on tente de trouver une hiérarchie de rubriques
     210                if (
     211                        $this->objet == 'rubrique' and $id_rubrique_enfant = $id
     212                        or isset($doc['properties']['id_rubrique']) and $id_rubrique_enfant = $doc['properties']['id_rubrique']
     213                        or isset($doc['properties']['id_article']) and $id_rubrique_enfant = intval(sql_getfetsel('id_rubrique', 'spip_articles', 'id_article ='.$doc['properties']['id_article']))
     214                ) {
     215                        // Là normalement on a maintenant la rubrique la plus basse
     216                        $doc['properties']['parents']['ids'] = array();
     217                        $doc['properties']['parents']['titres'] = array();
     218                        while ($f = sql_fetsel(
     219                                'id_parent, titre',
     220                                'spip_rubriques',
     221                                'id_rubrique = '.$id_rubrique_enfant
     222                        )){
     223                                $titre_actuel = supprimer_numero($f['titre']);
     224                                $id_parent = intval($f['id_parent']);
     225                                $doc['properties']['parents']['ids'][] = $id_rubrique_enfant;
     226                                $doc['properties']['parents']['titres'][$id_rubrique_enfant] = $titre_actuel;
     227                               
     228                                $id_rubrique_enfant = $id_parent;
     229                        }
     230                       
     231                        // On ajoute la branche dans le fulltext
     232                        $doc['content'] .= "\n\n".join(' | ', $doc['properties']['parents']['titres']);
     233                }
     234               
     235                // On cherche les jointures pour cet objet
     236                // Pour chaque, on va déléguer à une fonction dédiée pour plus de lisibilité, et en plus ça permet d'être surchargeable
     237                foreach (indexer_lister_jointures($this->objet) as $jointure) {
     238                        if (
     239                                lire_config('indexer/'.$this->objet.'/jointure_'.$jointure.'/activer') // indexer/article/jointure_auteurs/activer=oui
     240                                and $jointure_fonction = charger_fonction( // indexer_jointure_auteurs()
     241                                        'jointure_'.$jointure,
     242                                        'indexer',
     243                                        true
     244                                )
     245                        ) {
     246                                $doc = $jointure_fonction($this->objet, $id, $doc);
     247                        }
     248                }
     249               
     250                // Transformation UTF-8
     251                include_spip('inc/charsets');
     252                $doc['title'] = unicode_to_utf_8(html2unicode($doc['title']));
     253                $doc['content'] = unicode_to_utf_8(html2unicode($doc['content']));
     254                $doc['summary'] = unicode_to_utf_8(html2unicode($doc['summary']));
    164255               
    165256                // On crée le Document avec les infos
     
    190281        }
    191282
    192         /** @param bool $bool */
    193         public function setTablesLiens($bool) {
    194                 $this->tables_liens = $bool;
    195         }
    196 
    197283        public function getObjectId($objet, $id_objet){
    198284                return crc32($GLOBALS['meta']['adresse_site'] . $objet) + intval($id_objet);
    199         }
    200 
    201         public function getAuthorsProperties($objet, $id_objet) {
    202                 if ($this->tables_liens) {
    203                         $auteurs = sql_allfetsel('a.nom', 'spip_auteurs AS a, spip_auteurs_liens AS al', array(
    204                                 "al.id_objet = " . intval($id_objet),
    205                                 "al.objet    = " . sql_quote($objet),
    206                                 "a.id_auteur = al.id_auteur",
    207                         ));
    208                 } else {
    209                         $auteurs = sql_allfetsel('a.nom', 'spip_auteurs AS a, spip_auteurs_articles AS al', array(
    210                                 "al.id_article = " . intval($id_objet),
    211                                 "a.id_auteur = al.id_auteur",
    212                         ));
    213                 }
    214                
    215                 return array_map('array_shift', $auteurs);
    216         }
    217 
    218         public function getTagsProperties($objet, $id_objet) {
    219                 if ($this->tables_liens) {
    220                         $tags = sql_allfetsel('m.titre', 'spip_mots AS m, spip_mots_liens AS ml', array(
    221                                 "ml.id_objet = " . intval($id_objet),
    222                                 "ml.objet    = " . sql_quote($objet),
    223                                 "m.id_mot = ml.id_mot",
    224                         ));
    225                 } else {
    226                         $tags = sql_allfetsel('m.titre', 'spip_mots AS m, spip_mots_articles AS ml', array(
    227                                 "ml.id_article = " . intval($id_objet),
    228                                 "m.id_mot = ml.id_mot",
    229                         ));
    230                 }
    231                 return array_map('array_shift', $tags);
    232285        }
    233286
  • _plugins_/indexer/trunk/formulaires/configurer_indexer.html

    r91256 r91373  
    1515                [(#ACTION_FORMULAIRE{#ENV{action}})]
    1616               
    17                 <ul>
    18                         <li class='editer [ (#ENV**{erreurs}|table_valeur{sources_objets}|oui)erreur]'>
     17                <ul class="editer-groupe">
     18                        <li class="editer [ (#ENV**{erreurs/sources_objets}|oui)erreur]">
    1919                                <label><:indexer:configurer_sources_objets_label:></label>
    2020                                #INCLURE{fond=formulaires/inc-choisir-objets,
     
    2222                                        selected=#GET{sources}}
    2323                        </li>
     24                        <li class="editer [ (#ENV**{erreurs/source}|oui)erreur]">
     25                                <label for="source"><:indexer:configurer_source_label:></label>
     26                                <input type="text" class="text" name="source" id="source" value="#ENV{source,#URL_SITE_SPIP}" />
     27                        </li>
     28                       
     29                        [(#REM) Pour chaque objet on peut potentiellement configurer des précisions ]
     30                        <BOUCLE_objets(DATA){source table,#GET{sources}|array_filter}>
     31                        #SET{objet, #VALEUR|objet_type}
     32                       
     33                        [(#REM) S'il y a un squelette dédié pour cet objet sinon squelette générique ]
     34                        [<li class="fieldset">
     35                                <input type="hidden" name="#GET{objet}" /> [(#REM) Pour que l'API configurer charge ]
     36                                <fieldset>
     37                                        <legend>[(#VALEUR|objet_info{texte_objets}|_T)]</legend>
     38                                        <ul class="editer-groupe">
     39                                        (#CHEMIN{formulaires/configurer_indexer/#GET{objet}.html}|?{
     40                                                #INCLURE{fond=formulaires/configurer_indexer/#GET{objet},env},
     41                                                #INCLURE{fond=formulaires/configurer_indexer/objet,objet=#GET{objet},table=#VALEUR,env}
     42                                        })
     43                                        </ul>
     44                                </fieldset>
     45                        </li>]
     46                        </BOUCLE_objets>
    2447                </ul>
    2548               
  • _plugins_/indexer/trunk/indexer_fonctions.php

    r90985 r91373  
    33// Sécurité
    44if (!defined('_ECRIRE_INC_VERSION')) return;
     5
     6/**
     7 * Lister les jointures de recherche possibles pour un objet
     8 *
     9 * On liste les jointures déclarées et on ne garde que celles qui ont une fonction "indexer" dédiée.
     10 *
     11 * @param string $objet
     12 *              Type ou table de l'objet voulu
     13 * @return array
     14 *              Retourne la liste des jointures possibles
     15 **/
     16function indexer_lister_jointures($objet) {
     17        include_spip('base/objets');
     18       
     19        $jointures = array();
     20        $jointures_declarees = array_keys(objet_info($objet, 'rechercher_jointures'));
     21       
     22        // On ne garde que celles qui ont une fonction "indexer" dédiée
     23        foreach ($jointures_declarees as $jointure) {
     24                $table = table_objet($jointure); // article => articles
     25                if (charger_fonction('jointure_'.$table, 'indexer', true)) {
     26                        $jointures[] = $table;
     27                }
     28        }
     29       
     30        return $jointures;
     31}
    532
    633function sphinx_get_array2query($api, $limit=''){
  • _plugins_/indexer/trunk/lang/indexer_fr.php

    r91226 r91373  
    66$GLOBALS[$GLOBALS['idx_lang']] = array(
    77        // C
     8        'configurer_groupes_ignores_explication' => 'Ne PAS indexer les mots de ces groupes.',
     9        'configurer_groupes_ignores_label' => 'Groupes de mots ignorés',
     10        'configurer_indexer_email_label' => 'Indexer l’email des auteur⋅e⋅s',
     11        'configurer_jointure_activer_label' => 'Enregistrer les @jointure@',
     12        'configurer_source_label' => 'Source',
    813        'configurer_sources_objets_label' => 'Activer l’indexation sur les contenus :',
     14        'configurer_statuts_ignores_explication' => 'Ne PAS indexer les contenus avec ce statut.',
     15        'configurer_statuts_ignores_label' => 'Statuts ignorés',
    916        'configurer_titre' => 'Configurer l’indexation',
    1017       
  • _plugins_/indexer/trunk/paquet.xml

    r91238 r91373  
    22        prefix="indexer"
    33        categorie="navigation"
    4         version="1.4.1"
    5         etat="test"
    6         compatibilite="[2.1.0;3.1.*]"
     4        version="2.0.0"
     5        etat="dev"
     6        compatibilite="[3.0.0;3.1.*]"
    77        logo="prive/themes/spip/images/indexer-64.png"
    88        documentation="http://contrib.spip.net/Sphinx-Indexer"
Note: See TracChangeset for help on using the changeset viewer.