Ressources Spip-Agora Clever Age

Indexer des documents PDF et Word, le 4 août 2005

sans utiliser de moteur de recherche externe

Objectif

Je voudrais que la boucle (DOCUMENTS){recherche} puissent me remonter les documents PDF contenant le mot tapé dans le formulaire de recherche.

Une solution consiste à utiliser un moteur de recherche externe.

Une autre consiste à écrire son propre driver d’indexation et d’extraire les mots contenus à partir d’un programme à disposition sur le serveur ou tourne SPIP-Agora.

Comment faire ?

Nous allons surcharger une partie du driver common [1] par un bout de code personnel.

1- Déclarer le driver

Ajouter dans le fichier mes_options.php3 le code suivant :


<?php 
...
$GLOBALS['type_indexation'] = 'perso';
...
?>

2 - Copie des fichiers

Créer le répertoire : ecrire/include/indexer/perso

Copier les fichiers ecrire/include/indexer/common/Indexer_Document_common.php et configurationDocumentPoids_common.php dans ce répertoire

3 - Personnalisation de notre driver

Renommer nos fichiers en Indexer_Document_perso.php et configurationDocumentPoids_perso.php

configurationDocumentPoids_perso.php :
<?php

$poids
['document']['titre'] = 8;
$poids['document']['descriptif'] = 5;
$poids['document']['contenu'] = 5;

$min_long 3;

?>

Indexer_Document_perso.php :
<?php
require_once dirname(__FILE__)."/../Indexer.php";
require_once 
dirname(__FILE__)."/../../bd/inc_index_documents_factory.php";

class 
Indexer_Document_perso extends Indexer {
    
    
// {{{ constructor

    /**
     * ListeAction constructor.
     *
     * @access public
     */

    
function Indexer_Document_perso() {

        
    
$this->_setPoids($this->_findConfigFile('configurationDocumentPoids'$GLOBALS['type_indexation']) );
        
        
    
$this->_full false;
        
    
$this->_type 'document';
        
        
$this->_minlong $min_long;
        
    }

    
// }}}

    // {{{
    
    
function alreadyIndex($id_objet) {

        
$indexDocMetier = &recuperer_instance_index_documents();
        return ( 
$indexDocMetier->howManyIndexDocumentForDocumentId($id_objet) > );
    
    }
        
    
// }}}
    
    // {{{

    
function _indexData($id_objet) {
        include_once (
dirname(__FILE__).'/../../bd/inc_document_factory.php');
        
$documentMetier = &recuperer_instance_document();
        
        
$loadOk $documentMetier->load($id_objet);
        if (!
PEAR::isError($loadOk)) {
            
// indexation du doc
            
$this->_indexer_chaine($documentMetier->getTitre(), $this->_poids['document']['titre'], $this->_minlong'titre'); 
            if (
$this->_full) {
                    
$this->_indexer_chaine($documentMetier->getDescriptif(), $this->_poids['document']['descriptif'], $this->_minlong'descriptif'); 
                
// si c un pdf je tente d'indexer les mots                 
                
if (eregi (".*\.pdf$"basename($documentMetier->getFichier())) ) {
                    
$contenu exec ('pdftohtml -q -i -stdout '.dirname(__FILE__).'/../../../../'.$documentMetier->getFichier() );
                    
$this->_indexer_chaine(strip_tags($contenu), $this->_poids['document']['contenu'], $this->_minlong'contenu');
                }

// si c un doc je tente d'indexer les mots
                
if (eregi (".*\.doc$"basename($documentMetier->getFichier())) ) {
                    
$contenu = array ();
                    
exec ('wvText '.dirname(__FILE__).'/../../../../'.$documentMetier->getFichier().' /dev/stdout '$contenu);
                    
$str_contenu join (' '$contenu);
                    
$this->_indexer_chaine($str_contenu$this->_poids['document']['contenu'], $this->_minlong'contenu');

                }


            }
        
        } else {
            
PEAR::raiseError("indexer document $id_object : ".$loadOk->getMessage(), PEAR_LOG_ERR,
                
nullnullnullnullfalse); 
        }
        
                
        
$indexDocumentMetier = &recuperer_instance_index_documents();
        
$indexDocumentMetier->deleteIndexDocumentForDocumentId($id_objet);
        
    }

    
// }}}
    
    

}

?>

En comparaison avec le driver de base, seul la fonction indexData a changée, j’ai simplement rajouté :
<?php 
...
// si c un pdf je tente d'indexer les mots                 
if (eregi (".*\.pdf$"basename($documentMetier->getFichier())) ) {
$contenu exec ('pdftohtml -q -i -stdout '.dirname(__FILE__).'/../../../../'.$documentMetier->getFichier() );
$this->_indexer_chaine(strip_tags($contenu),$this->_poids['document']['contenu'], $this->_minlong'contenu');
}
// si c un doc je tente d'indexer les mots
                
if (eregi (".*\.doc$"basename($documentMetier->getFichier())) ) {
    
$contenu = array ();
    
exec ('wvText '.dirname(__FILE__).'/../../../../'.$documentMetier->getFichier().' /dev/stdout '$contenu);
    
$str_contenu join (' '$contenu);
    
$this->_indexer_chaine($str_contenu$this->_poids['document']['contenu'], $this->_minlong'contenu');
 }

... 
?>

Bien sur les exécutables pdftohml et wvText doivent être accessibles.

Facile non ? on peut étendre cela à l’indexation de n’importe quel autre type de fichier en utilisant les programmes adéquats.

Ce script fonctionne sous Linux et a été testé avec succès sur Clever Hosting

[1] celui fourni de base par SPIP-Agora