Extension:FileIndexer

From MediaWiki.org

Jump to: navigation, search
This extension requires patches to core MediaWiki code when used with MediaWiki 1.8 and before. Extensions implemented using patches may be disabled by or interfere with upgrades and security patches. If you would like to use this extension, we strongly recommend you upgrade to a version later than 1.8. Alternatively, if a suitable alternative without a patch is available, we recommend you use that extension instead.


             

Manual on MediaWiki Extensions
List of MediaWiki Extensions
Crystal Clear action run.png
FileIndexer

Release status: beta

Implementation  Special page
Description This extension makes uploaded document files searchable.
Author(s)  MHart, Flominator, Hxwiki, raZe (RazqubikTalk)
Last Version  0.2.2.00
MediaWiki  New version: 1.11 - 1.14 +
Flominators version: 1.9.0 - 1.11
(Versions before require patching)
License No license specified
Download no link
See section 'Changelog'

check usage (experimental)

Contents

[edit] History

MHart modified the standard upload page so that uploaded Microsoft Word, Microsoft Excel, Microsoft PowerPoint, and Adobe PDF documents will have their contents indexable.

He started by downloading and installing various Linux command line utilities that will take one of the above formats and output the text - antiword, xls2csv, ppt2text (catppt), and pdftotext.

Then he modified SpecialUpload.php where it tests for a successful upload and just before it inserts the uploaded file information into the database. What it did was make the text of the word document an HTML comment block in the description text of the image's file page.

Two years later Flominator found the hook UploadForm:BeforeProcessing and created an extension out of it. Then Hxwiki came and modified the code to work with MediaWiki 1.11.

May 2008 raZe published a new variant of this extension to get slightly better performance which built the base for his latest release published 29th of June 2009 with many new possibilities for configuration and more performance improvements. The latest version can be found here. As of now I (raZe) have the permission to continue this extension officially, I feel the need to explain myself for the reasons I had to rearrange this page: The newest version of this extension is developed with mediawiki 1.14. I have no idea if this is still running with earlier versions right now. Nevertheless as long as I don't know better I do not want to delete relevant content so I moved the least versions developed for MediaWiki pre 1.11 to the bottom of the page. Please: if someone tries to migrate the current version to the old mediawikis please give me a sign if you succeeded.

[edit] Requirements

Installing these tools depends on the operating system of your server. If you use webspace on the server of a hosting company, you might ask them for help, since you usually can't install software on their servers by yourself.

For debian-like GNU/Linux distributions simply use the command:

apt-get install <toolname>

For Fedora-style distributions (tested with no extra repositories, Fedora Core 8 64-bit):

yum -y install xpdf recode antiword 

Fedora notes:

  1. xpdf package contains pdftotext command referenced above.
  2. recode package contains iconv
  3. strings was already installed; it appears to be part of binutils
  4. A single distribution from the catdoc link above will make/build/build install catdoc, xls2csv, and catppt as a group

[edit] Compatibility

This extension is implemented on a Linux-System (Open SuSE 10.3 to be concrete but that's irrelevant as I am sure it will run on most other distributions). Windows-users: you may find similar or even more commandline tools to reimplement a windows version. If so, feel free to leave a note!

As mentioned above this version was implemented with 1.14 of MediaWiki but I am very sure that is will run on all versions since 1.11 (including 1.15) but those are untested... experiments? Leave a note in the box below.

 1.11 untested | noone
 1.12 untested | noone
 1.13 untested | noone
 1.14 running 100% | raZe | 29.06.2009
 1.15 fails | Brendan | 20.08.2009 (See Talk section)

[edit] Changelog

Date Version Editor Changes
08.08.2007 n/a Flominator
  • Basic extension created from the hack below
28.11.2007 n/a Flominator
  • Support for MediaWiki 1.11 added
14.05.2008 n/a Flominator
  • Debugging added
15.05.2008 v0.1.0.00 raZe
  • First complete reimplementation with better index-word-filtering and outputcontrol...
29.06.2009 v0.2.1.00 raZe
  • Complete reimplementation including specialpage, much more configurable switches...
01.07.2009 v0.2.2.00 raZe
  • Bugfix: $wgFiAutoIndexMark now leads to an automatic update of the index on new uploaded fileversion

[edit] What's new?

As mentioned above this is not the first version of the extension. Therefore at this point I just want to comment what has changed since my first reimplementation from 2008:

  • There are new ways to index files:
    • by leaving a free configurable string in the comment field in the upload mask (default: :FI:) - this is the old way
    • by configuring to always create an index after each upload
    • by leaving a free configurable string in the article so that each time it is edited the index will be actualized - default: <includeonly><noinclude>FiAutoIndex</noinclude></includeonly>
    • by calling and using 'Special:FileIndexer' where you may specify the file to (re)index.
  • Indexcreation is not limited to namespace 'image' anymore

More detailed information at section 'Configuration'!

[edit] What shortcomings have changed since 2008th version?

  • Warnings (e.b. File-duplication) ended in not performing the indexcreation... this has changed!
  • Forgetting the creation lead to repeated uploads as there was no chance to create the index afterwards... now there are severel ways to do so without spending too much resources.
  • General: there is much more flexibility in configuration... see als section 'Configuration'

[edit] What's different from Flominator's version?

As the main commonality is the external systemtools used to filter the content of uploaded files and the choice of the hooks nearly anything differs from the original, so I will not go into details here.

[edit] Configuration

The following switches and parameters are implemented:

  • $wgFiCheckSystem (BOOL: default = false) If TRUE system will be checked before every try to create an index out of a file.
  • $wgFiPrefix (STRING: default = <!-- FI:INDEX-START -->) Unique string to mark the head of the indexblock which is needed to actualize automaticaly.
    • TIP: You may use this to customize your outputdesign. Therefore you should analyze the way your search engine works!
  • $wgFiPostfix (STRING: default = <!-- FI:INDEX-ENDE -->) Unique string to mark the tail of the indexblock which is needed to actualize automaticaly.
    • TIP: You may use this to customize your outputdesign. Therefore you should analyze the way your search engine works!
  • $wgFiCreateIndexSign (STRING: default = :FI:) Leave this mark in the comment field of the upload mask to create an index.
  • $wgFiCreateIndexOnAllUploads (BOOL: default = false) Switch to generally create an index on every upload.
    • Note that this switch turned to true is only recommanded in wikis where the appearance of all uploads is well known! Big uploads bring big indexes!
  • $wgFiRequestIndexCreationFile (STRING: default = /tmp) This is a required path to a systemdirectory where the webserver has the right to create files. It is needed to leave a note during uploads that an index should be created. Problem was that warnings during upload-dialog resulted in a new http-request. As i know no better technique in php togenerate sessionwide globals than the not-reccommanded 'php-registering-globals' I only came up with this... I would be pleased for any advise to do better!
  • $wgFiMinWordLen (INT: default = 3) As the filtering algorithms are very basic till now by this value you may at least specify a minimum length a string must have to be registered in the index. Values lower than 1 result in the default 3.
  • $wgFiAutoIndexMark (STRING: default = ) This is the mark string to be placed somewhere in an article so that an index will be created each time the article will be saved.
    • Note that the position of this string does not influence the position where the index will be placed! This you may do by using the values of $wgFiPrefix and $wgFiPostfix inside the article.
    • Requirements: There has to exist an uploaded file with the exact same name as the article basename (without namespace)!
  • $wgFiSetAutoIndexMark (BOOL: defualt = true) If set to TRUE the mark in $wgFiAutoIndexMark will be placed in any article an index is created.
  • $wgFiArticleNamespace (INT: default = -1) You may specify one namespace to allow indexcreation into. If so you have to leave the int-value of that namespace - not its name!.
    • The value '-1' stands for no specific namespace - this means all normal and userdefined namespaces are valid.
    • If the chosen namespace is not 'image', uploading files with indexcreation will lead to an extra article in that namespace being extended by that index. The article in 'image' will not be influenced in that case.

[edit] Open shortcomings

  • Breaking up on an upload results in a small but useless file in the specified directory - cronjobs may clean this but... :-(

[edit] What do I plan next?

Here is what I want to implement next in this extension:

  • Give the option to add the index in the article or directly add it in the index-table of mediawiki
  • If noone comes up with an alternative to the temp-files (for upload-index-reminding) - delete files by expiry date
  • New / better word-filtering-algorithms
  • Still: to realize the function of $wgFiCreateIndexSign directly into the uploadform as a checkbox (I just dont know how that works...)

[edit] Installation

Following steps are needed for installation:

[edit] Edit LocalSettings.php file

Add the following lines to LocalSettings.php:

#Makes uploaded documents searchable
include("extensions/FileIndexer/FileIndexer.php");

[edit] Copying files to your extension-folder

Copy the following three files as mentioned above eacht code.
Note: The requirements described at #All_versions are still 100% active so I will only reference them here.

[edit] FileIndexer.php

Copy this into file .../extensions/FileIndexer/FileIndexer.php

<?php
/**
 * TITEL:				Extension: FileIndexer
 * ERSTELLDATUM:		15.05.2008
 * AUTHOR:				Ramon Dohle aka 'raZe'
 * ORGANISATION:		GRASS-MERKUR AG & Co. KG
 * VERSION:				0.2.2.00	01.07.2009
 * REVISION:
 * 		15.05.2008	0.1.0.00	raZe		*	Initiale Version
 * 		26.06.2008	0.2.0.00	raZe		*	Komplettueberarbeitung
 * 		29.06.2009	0.2.1.00	raZe		*	Weitere Offene Punkte abgearbeitet:
 * 												*	$wgFiArticleNamespace auch bei Uploads nutzen.
 * 												*	$wgFiAutoIndexMark automatisch beim Upload mit Indexerstellungs-Aufforderung im Artikel einsetzbar machen. 
 * 													Neue Option: $wgFiSetAutoIndexMark
 * 												*	$wgFiCheckSystem nutzen um Systemvoraussetzung bei jedem Aufruf zu pruefen
 * 													Neue Option: $wgFiCheckSystem
 * 												*	Temporaere Datei muss eindeutig einer Session zugeordnet werden koennen...
 * 		01.07.2009	0.2.2.00	raZe		*	Bug beseitigt, dass $wgFiAutoIndexMark beim Dateiupload nicht beruecksichtigt wurde
 * 												
 * 
 * BESCHREIBUNG:
 * 		Diese Erweiterung basiert auf der Wiki-Erweiterung 'FileIndexer' vom Stand 15.05.2008.
 * 		Wie sein Original soll sie Dateien Indexieren um auch den Inhalt dieser Dateien durch Suchmaschienen zu erfassen.
 * 
 * 		Um dies zu erreichen koennen erstmals verschiedene Wege beschritten werden:
 * 			*	durch Angabe einer frei konfigurierbaren Zeichenkette (default: ':FI:') im Kommentarfeld in der Upload-Maske
 * 			*	durch Konfigurations-Schalter zur grundsaetzlichen Indexerstellung bei allen Uploadvorgaengen
 * 			*	durch Verwendung einer frei konfigurierbaren Zeichenkette (default: '<includeonly><noinclude>FiAutoIndex</noinclude></includeonly>') 
 * 				innerhalb eines Artikels zur automatischen Index-Aktualisierung beim Aendern am Artikel.
 * 			*	durch Aufruf einer Spezialseite 'Spezial:FileIndexer' und Nutzung des entsprechenden Formulars
 * 		 Siehe auch im Abschnitt 'KONFIGURATION'!
 * 
 * BEHOBENE SCHWAECHEN ZU VERSION 0.1.0.00:
 * 		*	Warnungen beim beim Datei-Upload fuehren nun nicht mehr dazu, dass Aufforderungen zur Indexerstellung ignoriert werden.
 * 		*	Wird beim Hochladen die Aufforderung zur Indexerstellung versaeumt, kann dies nun per Spezialseite ohne zweiten Upload und Ressourcenverschwendeung nachgeholt werden.
 * 		*	Allgemein: mehr Flexibilitaet in der Bedienung (siehe Abschnitte 'BESCHREIBUNG' und 'KONFIGURATION')
 * 
 * AENDERUNGEN ZUM ORIGINAL:
 * 		Da die Anederungen zum Original mittlerweile so gravierend sind, wird auf diese von nun an nicht mehr eingegangen. Die grosse Gemeinsamkeit besteht
 * 		hauptsaechlich in der Wahl der externen Tools und den genutzten Hooks.
 * 
 * 		NOTE FOR THE DEVELOPERS OF THE ORIGINAL 'Extension:FileIndexer': Please leave me a note if it is your wish that I change the name of this extension!
 * 
 * ENTWICKLUNGSUMGEBUNG / KOMPATIBILITAET:
 * 		Entwickelt wurde diese Version in einem MediaWiki 1.14.0 Umfeld. Die erste Ablegerversion (v0.1.0.00) entstand in einem 1.11er MediaWiki-Umfeld und lief
 * 		auf allen dazwischen liegenden Versionen wie erwartet. Ungetestet waage ich die Aussage, dass diese Version des FileIndexers ebenfalls fehlerlos ab 1.11
 * 		nutzbar sein sollte. (Ebenfalls ungetestet:) Auch bei Version 1.15 erwarte ich keine Schwierigkeiten.
 *		
 * KONFIGURATION:
 * 		*	$wgFiCheckSystem				BOOL	*	(default = false) Wenn TRUE, dann wird vor jeder Indexerstellung geprueft, ob alle Hilfprogramme erreichbar sind.
 * 		*	$wgFiPrefix:					STRING	*	Ein eindeutiges Praefix vor dem Index-Block, welches bei einer Aktualisierung genutzt wird um den Anfang des Blocks zu erkennen.
 * 													*	TIP: Dieser kann genutzt werden um die Ausgabe zu formatieren. Dabei ist zu beachten, wie die eingesetzten SeachEngines arbeiten!	
 * 		*	$wgFiPostfix:					STRING	*	Ein eindeutiges Postfix hinter dem Index-Block, welches bei einer Aktualisierung genutzt wird um das Ende des Blocks zu erkennen.
 * 													*	TIP: Dieser kann genutzt werden um die Ausgabe zu formatieren. Dabei ist zu beachten, wie die eingesetzten SeachEngines arbeiten!
 * 		*	$wgFiCreateIndexSign			STRING	*	(default = :FI:) Zeichenkette zur Markierung fuer eine Indexerstellung im Anschluss an den Datei-Upload.
 * 		*	$wgFiCreateIndexOnAllUploads	BOOL	*	Schalter fuer das standardmaessige Erstellen eines Indexes, wannimmer eine Datei hochgeladen wird. 
 * 													*	ACHTUNG: DIESE OPTION WIRD NUR EMPFOHLEN, WENN SIE SICHER SIND, MIT WELCHEM UPLOAD-AUFKOMMEN ZU RECHNEN IST!
 * 														GROSSE DATEIEN => GROSSE INDEXE!
 * 		*	$wgFiRequestIndexCreationFile	STRING	*	(default = /tmp) Verzeichnispfad zur Erstellung temporaeren Dateien (SCHREIBRECHTE NOTWENDIG!). Diese werden benoetigt um bei 
 * 														Warnmeldungen waehrend des Fileuploads die Aufforderung zur Indexerstellung nicht zu vergessen (Problematik: neuer Request)
 * 		*	$wgFiMinWordLen					INT		*	(default = 3) Mindestlaenge der Indexworte (Werte <= 0 werden auf 3 gemapt)
 * 		*	$wgFiAutoIndexMark				STRING	*	(default = <includeonly><noinclude>FiAutoIndex</noinclude></includeonly>) Markierungszeichenfolge innerhalb eines Artikels
 * 														zur automatischen Aktualisierung des Indexes nach jeder Aenderung des Artikels.
 * 														VORAUSSETZUNGEN: Es muss eine bereits hogchgeladene Datei vorliegen, deren Namen mit dem des Artikels uerbereinstimmt (ohne Namensraum)!
 * 		*	$wgFiSetAutoIndexMark			BOOL	*	(defualt = true) Dieses Feld legt fest, ob die Markierung $wgFiAutoIndexMark im Index-Zielartikel bei der Indexerstellung 
 * 														sichergestellt werden soll.
 * 		*	$wgFiArticleNamespace			INT		*	(default = -1) Dieses Feld legt fest, ob das Erstellen eines Indexes ausschliesslich in einem bestimmten Namensraum ermoeglicht sein
 * 														soll. Hier ist die Nummer des Namensraumes anzugeben. Der Wert '-1' fuehrt zu keiner Einschraenkung.
 * 													*	Sollte ein anderer Namensraum als 'image' gewaehlt werden, wird beim Upload von Dateien wird im Artikel des Namensraums 'image' kein 
 * 														Index erstellt, hingegen wird im gleichnamigen Artikel des gewaehlten Namensraums der index hinterlegt. 
 *
 * OFFENE PUNKTE:
 * 	1	TODO:	[ ]	Wahlweise Index im Artikel oder im MediaWiki-Index zum Artikel hinterlegbar machen.
 * 	5	TODO:	[ ]	Bessere Filter-Operationen einbauen.
 * 	6	TODO:	[ ]	$wgFiCreateIndexSign nach Moeglichkeit im Formular als Formularelement realisieren
 * 	9	TODO:	[ ]	Temporaere Dateien mit Datum versehen, sodass sie ggf. per Verfallsdatum geloescht werden koennen.
 * 
 * LEGELDE:
 * 		[ ]: Offen
 * 		[B]: Beschlossen zum kommenden Release
 * 		[I]: Inaktiv aber reserviert / zeitlich geplant
 * 		[A]: Aktiv in Bearbeitung
 * 		[T]: Realisiert, aber ungetestet
 * 		[P]: Neu zu pruefen und zu bewerten, ggf. abzusagen
 * 		[D]: Realisiert und getestet, aber noch nicht dokumentiert
 * 		[X]: Temporaere Markierung fuer die Fertigstellung fuer Patchnotes
 */
 
/*
 * **********************************************************************************************
 * *********************************** Vorbereitung/Skriptteil **********************************
 * **********************************************************************************************
 */
 
// Hooks
$wgHooks['UploadForm:BeforeProcessing'][] = 'wfFiBeforeProcessing';
$wgHooks['ArticleSave'][] = 'wfFiArticleSave';
$wgHooks['UploadComplete'][] = 'wfFiUploadComplete';
 
// Konfigurationsvariablen
$wgFiCheckSystem = false;
$wgFiPrefix = "<!-- FI:INDEX-START -->";
$wgFiPostfix = "<!-- FI:INDEX-ENDE -->";
$wgFiCreateIndexSign = ":FI:";
$wgFiCreateIndexOnAllUploads = false;
$wgFiArticleNamespace = -1;
$wgFiRequestIndexCreationFile = "/tmp";
$wgFiMinWordLen = 3;
$wgFiAutoIndexMark = "<includeonly><noinclude>FiAutoIndex</noinclude></includeonly>";
$wgFiSetAutoIndexMark = true;
 
// intern genutzte, globale Variablen - NICHT ZUM CUSTOMIZING RELEVANT!
$wgFiCreateIndexThisTime = false;							// Temporaerer Schalter fuer die Erstellung eines neuen Indexes fuer den aktuellen Upload
$wgFiSpecialPageCall = false;								// Temporaerer Schalter fuer die Erstellung eines neuen Indexes aus der Spezialseite "FileIndexer" heuraus
$wgFiTempFilePrefix = "/fi.requested.article.";				// Endet $wgFiRequestIndexCreationFile nicht mit einem "/", muss $wgFiTempFilePrefix damit beginnen.
 
// Informationen fuer Special:Version
$wgExtensionCredits['other'][] = array(
	'name' => 'FileIndexer',
	'version' => '0.2.2.00',
	'author' => 'Ramon Dohle (raZe) | Original: MHart and Flominator',
	'description' => 'Index-Erzeugung aus hochgeladenen Dateien zur Erfassung durch Suchfunktionen',
	'url' => 'http://www.mediawiki.org/wiki/Extension:FileIndexer'
);
 
// Auch in Bezug auf die neue Spezialseite "Special:FileIndexer"
$wgExtensionCredits['specialpage'][] = array(
	'name' => 'FileIndexer',
	'version' => '0.2.2.00',
	'author' => 'Ramon Dohle (raZe) | Original: MHart and Flominator',
	'description' => 'Index-Erzeugung aus hochgeladenen Dateien zur Erfassung durch Suchfunktionen',
	'url' => 'http://www.mediawiki.org/wiki/Extension:FileIndexer'
);
 
$wgExtensionFunctions[] = 'wfFiSetupExtension';
 
$dir = dirname(__FILE__) . '/';
$wgAutoloadClasses['FileIndexer'] = $dir . 'FileIndexer_body.php';
$wgSpecialPages['FileIndexer'] = 'FileIndexer';
 
/**
 * Bereitet das Wiki auf die Spezialseite vor.
 * 
 * @return BOOL TRUE
 */
function wfFiSetupExtension() {
	global $wgMessageCache;
 
	if(!function_exists('efFiMessages')){
		require_once('FileIndexer.i18n.php');
 
		foreach(efFiMessages() as $sLanguage => $sMessages){
			$wgMessageCache->addMessages($sMessages, $sLanguage);
		}
	}
 
	return true;
}
 
/*
 * **********************************************************************************************
 * *********************************** Hookfunktionen *******************************************
 * **********************************************************************************************
 */
 
/**
 * Diese Hook-Funktion wird nach dem erfolgreichen Upload einer Datei aufgerufen und stoesst das Update des zur Datei 
 * gehoerigen Artikels an, sollte die Indexerstellung gefordert sein.
 * 
 * @param $oImage OBJECT Die Uploadinformationen
 * @return BOOL TRUE
 */
function wfFiUploadComplete(&$oImage){
	global $wgFiCreateIndexOnAllUploads, $wgFiCreateIndexThisTime, $wgFiRequestIndexCreationFile, $wgFiTempFilePrefix, $wgFiArticleNamespace, $wgUser;
 
	// Zunaechst wird der Artikel gesucht und ggf. geladen, in den der Index abgelegt wuerde...
	$oArticle = false; // Bekannt machen...
	if($wgFiArticleNamespace != -1 && $wgFiArticleNamespace != NS_IMAGE){
		$oTitle = Title::makeTitleSafe($wgFiArticleNamespace, $oImage->mLocalFile->getTitle()->getDBkey());
		if($oTitle === NULL){
			// Titel ungueltig... Abbruch ohne Hinweis!
			return true;
		}
 
		$oArticle = new Article($oTitle);
	}
	else{
		$oArticle = new Article($oImage->mLocalFile->getTitle());
	}
 
	// Pruefen auf Existenz und AutoIndex-Markierung...
	$bAutoIndexSet = false;
	if($oArticle->exists()){
		$oArticle->loadContent();
 
		// Pruefung auf AutoIndex-Markierung ist nur relevant, wenn nicht immer ein Index erzeugt werden soll...
		if(!$wgFiCreateIndexOnAllUploads){
			$bAutoIndexSet = wfFiCheckAutoIndexMark($oArticle->mContent);
		}
	}
 
	// Pruefen, ob diesmalig zur Indexierung aufgefordert....
	if(!$wgFiCreateIndexOnAllUploads && !$bAutoIndexSet){
		$sUploadedFilepath = $oImage->mLocalFile->repo->directory . "/" . $oImage->mLocalFile->hashPath . $oImage->mLocalFile->name;
		$sCreateIndexFilepath = wfFiReadFilepath();
 
		$bCreateIndexSignSet = ($sCreateIndexFilepath !== false && $sCreateIndexFilepath == $sUploadedFilepath);
	}
 
	if($wgFiCreateIndexOnAllUploads || $bAutoIndexSet || $bCreateIndexSignSet){
		// Es soll ein Index erzeugt werden
		$wgFiCreateIndexThisTime = true;
		$oArticle->doEdit($oArticle->mContent, "FileIndexer: Upload fordert Indexerstellung.\n", 0);
		$wgFiCreateIndexThisTime = false;
 
		// Alles in Ausgangslage zuruecksetzen (temporaere Datei loeschen und Flag zuruecknehmen)...
		if(file_exists($wgFiRequestIndexCreationFile . $wgFiTempFilePrefix . session_id())){
			unlink($wgFiRequestIndexCreationFile . $wgFiTempFilePrefix . session_id());
		}
	}
 
	return true;
}
 
/**
 * Diese Hook-Funktion aktualisiert die Index-Sektion, sollte es sich um einen FileUpload handeln
 * und ein neuer Inhalt fuer diese Sektion vorbereitet worden sein.
 * In jedem Fall wird die global abgelegte Index-Sektions-Inhalts-Variable wieder geleert.
 * 
 * @param $oArticle OBJECT Der Artikel
 * @param $oUser OBJECT Der Benutzer
 * @param $sContent STRING Inhalt des Artikels
 * @param $sSummary STRING Zusammenfassung fuer das Update
 * @param $minor SIEHE WIKIDOKU 
 * @param $watch SIEHE WIKIDOKU
 * @param $sectionanchor SIEHE WIKIDOKU
 * @param $flags SIEHE WIKIDOKU
 * @return BOOL TRUE
 */
function wfFiArticleSave(&$oArticle, &$oUser, &$sContent, &$sSummary, $minor, $watch, $sectionanchor, &$flags){
	global $wgFiPrefix, $wgFiPostfix, $wgUploadDirectory, $wgFiSetAutoIndexMark, $wgFiAutoIndexMark;
 
	if(wfFiCheckIndexcreation($oArticle, $sContent)){
		$sFilepath = $wgUploadDirectory . "/" . FileRepo::getHashPathForLevel($oArticle->mTitle->mTextform, 2) . $oArticle->mTitle->mTextform;
		$sIndex = wfFiGetIndex($sFilepath);
 
		// Suchen und ersetzen des Datei-Indexbereiches
		$sOriginalContent = $sContent;
		$sContent = "";
 
		// Ggf. AutoIndexMark setzen...
		if($wgFiSetAutoIndexMark && strpos($sOriginalContent, $wgFiAutoIndexMark) === false){
			$sOriginalContent .= $wgFiAutoIndexMark;
		}
 
		// Nach $wgFiPrefix und Postfix suchen und alten Text davor uebertragen...
		$iPostFileIndexPos = false;
		$iFileIndexPos = strpos($sOriginalContent, $wgFiPrefix);
		if($iFileIndexPos === false){
			// Kompletten Inhalt vor neuen Index packen, weil vorher anscheinend kein Index existierte...
			$sContent = substr($sOriginalContent, 0);
		}
		else{
			// Alles vor altem Index schon mal in den neuen Inhalt packen...
			$sContent = substr($sOriginalContent, 0, $iFileIndexPos);
 
			// Nur wenn auch ein Prefix gefunden wurde, wird nach einen Postfix gesucht...
			$iPostFileIndexPos = strpos($sOriginalContent, $wgFiPostfix, $iFileIndexPos);
		}
 
		// Index selbst anfuegen... (beim ersten erzeugen wird darauf geachtet, dass dieser in einer neuen Zeile beginnt)
		if($iPostFileIndexPos === false && (substr($sContent, strlen($sContent) - 1, 1) != "\n")){
			$sContent .= "\n";
		}
		$sContent .= $sIndex;
 
		// Restliche Beschreibung wieder anfuegen...
		if($iPostFileIndexPos !== false){
			$sContent .= substr($sOriginalContent, $iPostFileIndexPos + strlen($wgFiPostfix));
		}
 
		// In der Summary vermerken, dass hier ein neuer Index eingefuegt wurde...
		$sSummary .= ((substr($sSummary, strlen($sSummary) - 1, 1) == "\n") ? "" : "\n") . "FileIndexer: Neuer Index erstellt.\n";
	}
 
	return true;
}
 
/**
 * Sucht im Kommentar nach dem Zeichen zur Indexerzeugung und erstellt unter Einsatz externer Programme den Index. Dieser wird zunaechst
 * in einer globalen Variable abgelegt um spaeter von anderen Funktionen verarbeitet zu werden.
 * 
 * @param $oUploadForm OBJECT Alle Informationen aus dem Uploadformular
 * @return BOOL TRUE
 */
function wfFiBeforeProcessing(&$oUploadForm){
	global $wgFiCreateIndexSign, $wgFiRequestIndexCreationFile, $wgUploadDirectory, $wgFiTempFilePrefix;
 
	// Sicherstellen, dass bei einer unvollstaendigen Konfiguration nicht ungewollt ein Index erstellt wird...
	if($wgFiCreateIndexSign === false || $wgFiCreateIndexSign == ""){
		$wgFiCreateIndexSign = ":FI:";
	}
 
	// Im Kommentar zum Upload wird geschaut, ob der Index erzeugt werden soll. Wenn ja, dann entferne das Zeichen aus dem Kommentar. Ansonsten gehe ohne getane Arbeit raus.
	$iSignCreateIndexPos = strpos($oUploadForm->mComment, $wgFiCreateIndexSign);
	if($iSignCreateIndexPos === false){
		return true;
	}
	else{
		$oUploadForm->mComment = substr($oUploadForm->mComment, 0, $iSignCreateIndexPos) . substr($oUploadForm->mComment, $iSignCreateIndexPos + strlen($wgFiCreateIndexSign));
	}
 
	// Im Falle einer gueltigen Dateiendung => Endgueltigen Pfad in temporaere Datei schreiben
	switch(strtolower(substr(strrchr($oUploadForm->mDesiredDestName, '.'), 1))){
		case "pdf":{}
		case "dot":{}
		case "doc":{}
		case "xls":{}
		case "ppt":{}
		case "rtf":{}
		case "ods":{}
		case "odp":{}
		case "odg":{}
		case "odt":{
			exec("echo \"" . $wgUploadDirectory . "/" . FileRepo::getHashPathForLevel($oUploadForm->mDesiredDestName, 2) . $oUploadForm->mDesiredDestName . "\" > " . $wgFiRequestIndexCreationFile . $wgFiTempFilePrefix . session_id());
			break;
		}
	}
 
	return true;
}
 
/*
 * **********************************************************************************************
 * *********************************** Hilfsfunktionen ******************************************
 * **********************************************************************************************
 */
 
/**
 * Prueft, ob der Artikel zur Erstellung eines Indexes gemaess der Namensraumkonfigurationen valide ist.
 * 
 * @param $oTitle OBJECT Der Artikel
 * @return BOOL Erfolg
 */
function wfFiCheckNamespace($oTitle){
	global $wgFiArticleNamespace;
 
	// Abruch, wenn der Namensraum eingeschraenkt sein soll und der Artikeltitel nicht in diesem liegt...
	if($wgFiArticleNamespace != -1 && $wgFiArticleNamespace != $oTitle->mNamespace){
		return false;
	}
 
	return true;
}
 
/**
 * Prueft, ob er uebergebene Artikelinhalt die Markierung $wgFiAutoIndexMark ausserhalb eines nowiki-Blocks beinhaltet.
 * 
 * @param $sContent Artikelinhalt
 * @return BOOL Ergebnis
 */
function wfFiCheckAutoIndexMark($sContent){
	global $wgFiAutoIndexMark;
 
	// Markierung regelkonform vorhanden?
	$bMarkFound = false;
	$iPosMark = strpos($sContent, $wgFiAutoIndexMark);
	while (!$bMarkFound && $iPosMark !== false){
		$iPosNowikiStart = strrpos(substr($sContent, 0, $iPosMark), "<nowiki>");
 
		$iPosNowikiEnd = strrpos(substr($sContent, 0, $iPosMark), "</nowiki>");
 
		if($iPosNowikiStart === false || $iPosNowikiEnd !== false && $iPosNowikiEnd > $iPosNowikiStart){
			$bMarkFound = true;
			break;
		}
 
		$iPosMark = strpos($sContent, $wgFiAutoIndexMark, $iPosMark + 1);
	}
 
	return $bMarkFound;
}
 
/**
 * Prueft, ob ein Index erstellt werden soll.
 * 
 * @param $oArticle OBJECT Atrikel
 * @param $sContent Artikelinhalt
 * @return BOOL Ergebnis
 */
function wfFiCheckIndexcreation($oArticle = false, $sContent = false){
	global $wgFiCreateIndexThisTime;
 
	return (($wgFiCreateIndexThisTime) || (wfFiCheckNamespace($Article->mTitle) && wfFiCheckAutoIndexMark($sContent)));
}
 
/**
 * Versucht die temporaere Datei auszulesen und prueft, ob der Inhalt eine existierende Datei darstellt.
 * 
 * @return STRING | FALSE Pfad oder Fehler
 */
function wfFiReadFilepath(){
	global $wgFiRequestIndexCreationFile, $wgFiTempFilePrefix;
 
	if(file_exists($wgFiRequestIndexCreationFile . $wgFiTempFilePrefix . session_id())){
		exec ("cat \"" . $wgFiRequestIndexCreationFile . $wgFiTempFilePrefix . session_id() . "\"", $aReturn);
		$sFileHashPath = $aReturn[0];
		if($sFileHashPath != ""){
			if(!file_exists($sFileHashPath)){
				// Datei konnte nicht gefunden werden...
				return false;
			}
			else{
				return $sFileHashPath;
			}
		}
		else{
			// Es ist kein Dateipfad zur Indexerstellung hinterlegt worden...
			return false;
		}
	}
	else{
		// Es ist keine Datei zur Indexerstellung hinterlegt worden.
		return false;
	}
 
}
 
/**
 * Sucht im Kommentar nach dem Zeichen zur Indexerzeugung und erstellt unter Einsatz externer Programme den Index. Dieser wird zunaechst
 * in einer globalen Variable abgelegt um spaeter von anderen Funktionen verarbeitet zu werden.
 * 
 * @param $sFileHashPath STRING (optional) Dateipfad
 * @return STRING Index
 */
function wfFiGetIndex($sFileHashPath = false){
	global $wgFiPrefix, $wgFiPostfix, $wgFiMinWordLen;
 
	$sReturn = "";
 
	// Systemvoraussetzungen checken...
	if(FileIndexer::checkNecessaryCommands() !== true){
		return $sReturn;
	}
 
	// Dateipfad und Dateiendung auslesen
	if($sFileHashPath == false){
		$sFileHashPath = wfFiReadFilepath();
	}
	if($sFileHashPath === false){
		return $sReturn;
	}
	$sFileExtension = substr(strrchr($sFileHashPath, '.'),1);
 
	// ExecutionCommand ermitteln
	$bRemoveTags = false;
	$sExecutionCommand = "";
	switch(strtolower($sFileExtension)){
		case "pdf":{
			$sExecutionCommand = "/usr/local/bin/pdftotext -raw -nopgbrk " . $sFileHashPath . " -";
			$sExecutionCommand.="| /usr/local/bin/iconv -f ISO-8859-1 -t UTF-8";
			break;
		}
 
		case "dot":{}
		case "doc":{
			$sExecutionCommand = "/usr/local/bin/antiword -s ".$sFileHashPath;
			break;
		}
 
		case "xls":{
			$sExecutionCommand = "/usr/local/bin/xls2csv ".$sFileHashPath;
			break;
		}
 
		case "ppt":{
			$sExecutionCommand = "/usr/local/bin/catppt ".$sFileHashPath;
			break;
		}
 
		case "rtf":{
			$sExecutionCommand = "/usr/local/bin/strings ".$sFileHashPath;
			break;
		}
 
		case "ods":{}
		case "odp":{}
		case "odg":{}
		case "odt":{
			$sExecutionCommand = "unzip -p " . $sFileHashPath . " content.xml";
			$bRemoveTags = true;
			break;
		}
	}
 
	if ($sExecutionCommand != ""){
		exec($sExecutionCommand, $sDocText);
 
		$sReturn = $wgFiPrefix;
		$aIndex = array();
 
		// Feststellung der Mindest-Wortlaenge fuer ein Indexwort
		$wgFiMinWordLen = ($wgFiMinWordLen > 0) ? $wgFiMinWordLen : 3;
 
		foreach ($sDocText as $sDocLine){
			if($bRemoveTags){
				// Tags entfernen... Vorher vor jedem "<" Leerzeichen einfuegen, damit keine Worte zusammenfallen!
				$sDocLine = strip_tags(str_replace("<", " <", $sDocLine));
			}
 
			// Sonderzeichen entfernen...
			// ATTENTION: German only! Umlaute werden durch strtolower nicht in Kleinbuchstaben gewandelt...
			$sDocLine = strtolower(ereg_replace("[[:punct:]][[:space:]]|[[:space:]][[:punct:]]|[[:punct:]][[:punct:]]", " ", ereg_replace("Ä", "ä", ereg_replace("Ö", "ö", ereg_replace("Ü", "ü", $sDocLine)))));
 
			// Worte filtern und in Index packen...
			$aSplit = split(" ", $sDocLine);
			foreach($aSplit as $sWord){
				if($sWord != "" && !is_numeric($sWord) && strlen($sWord) >= $wgFiMinWordLen){
					$aIndex[$sWord] = true;
				}
			}
		}
 
		// Index global setzen...
		foreach(array_keys($aIndex) as $skeyword){
			$sReturn .= $skeyword . " ";
		}
 
		$sReturn .= $wgFiPostfix;
	}
 
	return $sReturn;
}

[edit] FileIndexer_body.php

Copy this into file .../extensions/FileIndexer/FileIndexer_body.php

<?php
/**
 * TITEL:				Extension: FileIndexer / FileIndexer_body.php
 * ERSTELLDATUM:		26.06.2008
 * AUTHOR:				Ramon Dohle aka 'raZe'
 * ORGANISATION:		GRASS-MERKUR AG & Co. KG
 * VERSION:				0.1.2.00	01.07.2009
 * REVISION:
 * 		26.06.2008	0.1.0.00	raZe		*	Initiale Version
 * 		29.06.2009	0.1.1.00	raZe		*	Weitere Offene Punkte abgearbeitet:
 * 												*	$wgFiArticleNamespace auch bei Uploads nutzen.
 * 												*	$wgFiAutoIndexMark automatisch beim Upload mit Indexerstellungs-Aufforderung im Artikel einsetzbar machen. 
 * 													Neue Option: $wgFiSetAutoIndexMark
 * 												*	$wgFiCheckSystem nutzen um Systemvoraussetzung bei jedem Aufruf zu pruefen
 * 													Neue Option: $wgFiCheckSystem
 * 												*	Temporaere Datei muss eindeutig einer Session zugeordnet werden koennen...
 * 		01.07.2009	0.1.2.00	raZe		*	An neue Funktionen in FileIndexer.php angeglichen
 * 												
 * 
 * BESCHREIBUNG:
 * 		Diese Erweiterung basiert auf der Wiki-Erweiterung 'FileIndexer' vom Stand 15.05.2008.
 * 		Wie sein Original soll sie Dateien Indexieren um auch den Inhalt dieser Dateien durch Suchmaschienen zu erfassen.
 * 
 * 		Hier wird die Spezialseitenklasse zur Verfuegung gestellt.
 */
 
class FileIndexer extends SpecialPage{
// CONFIGURATION
 
	var $insertEditTools = true;
 
	/**
	 * Konstruktor der Spezialseite.
	 */
	function FileIndexer() {
		SpecialPage::SpecialPage('FileIndexer');
	}
 
	/**
	 * Systempruefung eines Kommandos
	 * 
	 * @param $sCommand STRING Systemkommando
	 * @return STRING | TRUE Fehlermeldung oder TRUE fuer Erfolgreiche Pruefung
	 */
	static private function isCommandPresent($sCommand){
		if(file_exists($sCommand) === false){
			$iLastSlash = strrpos($sCommand, '/');
			if($iLastSlash != ''){
				$sCommandWithoutSlashes = substr($sCommand, $iLastSlash + 1);
			}
			else{
				$sCommandWithoutSlashes = $sCommand;
			}
 
			$sExecutionCommand = "whereis " . $sCommandWithoutSlashes;
			exec($sExecutionCommand, $whereis);
			return "*Command '" . $sCommand . "' missing! Result of 'whereis': " . $whereis[0] . "\n";
		}
 
		return true;
	}
 
	/**
	 * Systemvoraussetzungen werden geprueft.
	 * 
	 * @return STRING | TRUE Fehlermeldung oder TRUE fuer Erfolgreiche Pruefung
	 */
	static function checkNecessaryCommands(){
		global $wgFiCheckSystem;
 
		$sAnswer = "";
		// Testen, ob alle benoetigten Tools auf dem System vorhanden sind.
		if($wgFiCheckSystem === true){
			$xCheck = self::isCommandPresent("/usr/local/bin/pdftotext");
			if($xCheck !== true){
				$sAnswer .= $xCheck;
			}
			$xCheck = self::isCommandPresent("/usr/local/bin/iconv");
			if($xCheck !== true){
				$sAnswer .= $xCheck;
			}
			$xCheck = self::isCommandPresent("/usr/local/bin/antiword");
			if($xCheck !== true){
				$sAnswer .= $xCheck;
			}
			$xCheck = self::isCommandPresent("/usr/local/bin/xls2csv");
			if($xCheck !== true){
				$sAnswer .= $xCheck;
			}
			$xCheck = self::isCommandPresent("/usr/local/bin/catppt");
			if($xCheck !== true){
				$sAnswer .= $xCheck;
			}
			$xCheck = self::isCommandPresent("/usr/bin/strings");
			if($xCheck !== true){
				$sAnswer .= $xCheck;
			}
		}
 
		return ($sAnswer == "") ? true : $sAnswer;
	}
 
	/**
	 * Ausfuehrung nach Aufruf und nach Formularsubmit. Startet den Indexerstellungsprozess.
	 */
	function execute($par){
		global $wgRequest, $wgOut;
 
		if(!is_null($wgRequest->getVal('wpSubmitImage')) && !is_null($wgRequest->getVal('wpImage'))){
			$this->image = $wgRequest->getVal('wpImage');
			$this->prozessIndex();
		}
 
		$this->showForm();
	}
 
	/**
	 * Fuehrt den Prozess der Indexerstellung durch.
	 */
	function prozessIndex() {
		global $wgRequest, $wgOut, $wgDBtype, $wgDBprefix, $wgFiCreateIndexThisTime;
 
		wfProfileIn('FileIndexer::prozessIndex');
 
		if($wgRequest->getVal('wpImage') == ""){
			$wgOut->addHTML('<h3>' . wfMsg('fileindexer_no_params') . '</h3><br /><hr /><br />');
			return;
		}
 
		$id = (is_object(Title::newFromText($wgRequest->getVal('wpImage')))) ? Title::newFromText($wgRequest->getVal('wpImage'))->getArticleId() : 0;
		$oArticle = Article::newFromId($id);
 
		if($id == 0){
			// Artikel existiert nicht...
			$wgOut->addHTML('<h3>' . wfMsg('fileindexer_no_params') . '</h3><br /><hr /><br />');
			return;
		}
 
		if(!wfFiCheckNamespace($oArticle->mTitle)){
			// Artikel existiert nicht...
			$wgOut->addHTML('<h3>' . wfMsg('fileindexer_wrong_namespace') . '</h3><br /><hr /><br />');
			return;
		}
 
		$oArticle->loadContent();
		$wgFiCreateIndexThisTime = true;
		$oArticle->doEdit($oArticle->mContent, "FileIndexer: Spezialseite fordert Indexerstellung.\n");
		$wgFiCreateIndexThisTime = false;
 
		$wgOut->addHTML(wfMsg('fileindexer_articlelink'));
		$wgOut->addWikiText("[[" . $wgRequest->getVal('wpImage') . "]]");
		$wgOut->addHTML("<br /><hr /><br />");
 
		wfProfileOut('FileIndexer::prozessIndex');
	}
 
	/**
	 * Baut das Formular der Spezialseite auf.
	 */
	function showForm() {
		global $wgOut, $wgUser, $wgRequest;
		global $wgScriptPath, $wgUseAjax, $wgJsMimeType;
 
		$wgOut->setPagetitle(wfMsg('fileindexer'));
		$oTitle = Title::makeTitle(NS_SPECIAL, 'FileIndexer');
		$sAction = $oTitle->escapeLocalURL('');
 
		$sComment = wfMsgHtml('fileindexer_comment');
		$sImages = wfMsgHtml('fileindexer_destination');
		$sSubmitButton = wfMsgHtml('fileindexer_submit_button');
 
		$xCheck = FileIndexer::checkNecessaryCommands();
		if($xCheck !== true){
			// Systemvoraussetzungen sind nicht erfuellt...
			$wgOut->addHTML('<h3>' . wfMsg('fileindexer_systemcheck_with_errors') . '</h3><br />');
			$wgOut->addWikiText($xCheck);
			return;
		}
 
		$wgOut->addWikiText($sComment);
		$wgOut->addHTML("
	<br />
	<form id=\"FileIndexer\" method=\"POST\" action=\"{$sAction}\">
	<table border=\"0\">
		<tr>
			<td colspan=\"2\" align=\"left\">{$sImages}</td>
		</tr>
		<tr>
			<td colspan=\"2\">
				<input tabindex=\"1\" type=\"text\" size=\"40\" name=\"wpImage\" value=\"\" />
			</td>
		</tr>
		<tr>
			<td colspan=\"2\" style=\"padding-top: 1em\" align=\"right\">
				<input tabindex=\"2\" type=\"submit\" name=\"wpSubmitImage\" value=\"{$sSubmitButton}\" />
			</td>
		</tr>
	</table>
	</form>\n");
 
		if($this->insertEditTools == true && $wgUseAjax == true && function_exists('charInsert')){
			$currentPath = str_replace('\\', '/', dirname(__FILE__));
			$curServerPath = substr($currentPath, stripos($currentPath, $wgScriptPath . '/'));
			$wgOut->addScript("<script type=\"{$wgJsMimeType}\" src=\"{$curServerPath}/edittools.js\"></script>\n");
 
			$filename = dirname(__FILE__) . '/EditTools.htm';
			$handle = fopen($filename, 'rb');
			$contents = fread($handle, filesize($filename));
			fclose($handle);
 
			$wgOut->addHtml('<div class="mw-editTools">');
			$wgOut->addWikiText($contents);
			$wgOut->addHtml('</div>');
		}
	}
}

[edit] FileIndexer.i18n.php

Copy this into file .../extensions/FileIndexer/FileIndexer.i18n.php

<?php
/**
 * TITEL:				Extension: FileIndexer / FileIndexer.i18n.php
 * ERSTELLDATUM:		26.06.2008
 * AUTHOR:				Ramon Dohle aka 'raZe'
 * ORGANISATION:		GRASS-MERKUR AG & Co. KG
 * VERSION:				0.1.1.00	29.06.2009
 * REVISION:
 * 		26.06.2008	0.1.0.00	raZe		*	Initiale Version
 * 		29.06.2009	0.1.1.00	raZe		*	Texte ueberarbeitet
 * 												
 * 
 * BESCHREIBUNG:
 * 		Diese Erweiterung basiert auf der Wiki-Erweiterung 'FileIndexer' vom Stand 15.05.2008.
 * 		Wie sein Original soll sie Dateien Indexieren um auch den Inhalt dieser Dateien durch Suchmaschienen zu erfassen.
 * 
 * 		Hier wird speziell die Funktion zur multilingualen Nutzbarkeit zur Verfuegung gestellt.
 */
 
/**
 * Erweiterng der Wiki-Messages fuer den FileIndexer.
 * 
 * @return ARRAY Messages
 */
function efFiMessages() {
	$messages = array();
 
	$messages['en'] = array( 
		'fileindexer' => 'FineIndexer: create index from file',
		'fileindexer_wrong_namespace' => 'The given namespace is not valid!',
		'fileindexer_destination' => 'Destinationarticle:',
		'fileindexer_comment' => "On this form you may specify an articletitle <namespace>:<name> to fill with an index of all words used in an allready uploaded file. The name of the article an the file have to be equal! Even so the namespace may differ from 'image'!",
		'fileindexer_no_params' => 'You have to spezifie a valid, articletitle &lt;namespace&gt;:&lt;name&gt and an allready uploaded file with the exact same name has to be present!',
		'fileindexer_articlelink' => 'The article:',
		'fileindexer_systemcheck_with_errors' => 'Systemcheck returned with missing dependencies!',
		'fileindexer_submit_button' => 'Create'
	);
 
	$messages['de'] = array(
		'fileindexer' => 'FineIndexer: Index einer Datei erstellen',
		'fileindexer_wrong_namespace' => 'Der angegebene Namensraum ist nicht zulässig!',
		'fileindexer_destination' => 'Titel des Zielartikels:',
		'fileindexer_comment' => "In diesem Formular kann ein Artikeltitel <Namensraum>:<Name> angegeben werden, in welchem ein Index über eine bereits in die Applikation hochgeladene Datei erstellt werden soll. Der Artikelname muss gleich dem Dateinahmen sein. Der Namensraum des Zielartikels muss jedoch nicht 'image' sein!",
		'fileindexer_no_params' => 'Sie müssen einen gültigen Artikeltitel &lt;Namensraum&gt;:&lt;Name&gt; angeben und die zu indexierende Datei muss unter dem gleichen Namen bereits als hochgeladene Datei vorliegen!',
		'fileindexer_articlelink' => 'Zum Artikel:',
		'fileindexer_systemcheck_with_errors' => 'Eine Prüfung der Systemvoraussetzungen lieferte Defizite!',
		'fileindexer_submit_button' => 'Erstellen'
	);
 
	return $messages;
}

[edit] Historical Versions

The following version of this extension was developed by Flominator and is left untouched for historical reasons an for the slight hope of friendly people who try to use it for migrating the current version to older wikis.

[edit] MediaWiki >= 1.11.0

<?php
$wgHooks['UploadForm:BeforeProcessing'][] = 'ScanFileForIndex';
 
//Testing if these commands are available
if($wgFileIndexerDebug==true)
{
	isCommandPresent("/usr/bin/pdftotext");
	isCommandPresent("/usr/bin/iconv");
	isCommandPresent("/usr/bin/antiword");
	isCommandPresent("/usr/bin/xls2csv");
	isCommandPresent("/usr/bin/catppt");
	isCommandPresent("/usr/bin/strings");
}
 
function ScanFileForIndex($uploadFormObj) 
{
 
         $NewDesc = '';
         $RemoveTags = false;  //remove HTML-Tags created during conversion?
 
         $extension = substr(strrchr($uploadFormObj->mDesiredDestName, '.'),1); //extract the extension of the destination filename
 
          switch(strtolower($extension)) //methods for text extraction 
          {
                case "pdf": 
                {                 
                        //using XPDF and iconv for conversion purposes
                        $toexec = "/usr/bin/pdftotext  -raw -nopgbrk " . $uploadFormObj->mTempPath . " -";
                        $toexec.="| /usr/bin/iconv -f ISO-8859-1 -t UTF-8";
                        break;
                }
 
                case "dot": {}
                case "doc": 
                {
                        //using antiword
                        $toexec = "/usr/bin/antiword -s ".$uploadFormObj->mTempPath;
                        break;
                }
 
                case "xls":
                {
                        $toexec = "/usr/bin/xls2csv ".$uploadFormObj->mTempPath;
                        break;
                }
 
                case "ppt":
                {
                        $toexec = "/usr/bin/catppt ".$uploadFormObj->mTempPath; 
                        break;
                }
 
                case "rtf": # any file extension with text in it will be okay here
                {
                        $toexec = "/usr/bin/strings ".$uploadFormObj->mTempPath; # string's output isn't neat, but it works.
                        break;
                }
 
                //OpenOffice.org documents
                case "ods": {}
                case "odp": {}
                case "odg": {}
                case "odt":
                {
                        $toexec = "unzip -p " . $uploadFormObj->mTempPath . " content.xml";
                        $RemoveTags = true;
                        break;
                }
        }
        if ($toexec != "")
        {
                exec($toexec, $DocText);
                $NewDesc = $uploadFormObj->mComment . "\r\n" . "<!-- ";
                foreach ($DocText as $DocLine) 
                {
                        if($RemoveTags == false)
                        {
                                $NewDesc .= "\r\n" . str_replace("-->","",$DocLine);
                        }
                        else
                        {
                                $NewDesc .= "\r\n" . strip_tags(str_replace("-->","",$DocLine));
                        }
                }
                $NewDesc .= "\r\n" . " -->";
                $uploadFormObj->mComment = $NewDesc;
        }
        return $uploadFormObj;
}
 
function isCommandPresent($command)
{
	if(file_exists($command)==false)
	{
		//extract the command from the path
		$lastSlash = strrpos($command, '/');
		if($lastSlash!='')
		{
			$commandWithoutSlashes = substr($command, $lastSlash+1);
		}
		else
		{
			$commandWithoutSlashes = $command;
		}
 
		$toexec = "whereis $commandWithoutSlashes";
		//lookup the command
		exec($toexec, $whereis);
		echo "FileIndexer: The file $command is missing ... whereis result: $whereis[0] <br>";
	}
}
 
/**
  * Add extension information to Special:Version
 */
$wgExtensionCredits['other'][] = array(
        'name' => 'FileIndexer',
        'author' => 'MHart and Flominator',
        'description' => 'makes uploaded documents searchable',
        'url' => 'http://www.mediawiki.org/wiki/Extension:FileIndexer'
        );

[edit] pre MediaWiki 1.11.0

<?php
$wgHooks['UploadForm:BeforeProcessing'][] = 'ScanFileForIndex';
 
 
//Testing if these commands are available
if($wgFileIndexerDebug==true)
{
	isCommandPresent("/usr/bin/pdftotext");
	isCommandPresent("/usr/bin/iconv");
	isCommandPresent("/usr/bin/antiword");
	isCommandPresent("/usr/bin/xls2csv");
	isCommandPresent("/usr/bin/catppt");
	isCommandPresent("/usr/bin/strings");
}
 
function ScanFileForIndex($uploadFormObj) 
{
	 $NewDesc = '';
	 $RemoveTags = false;  //remove HTML-Tags created during conversion?
 
	 $extension = substr(strrchr($uploadFormObj->mDestFile, '.'),1); //extract the extension of the destination filename
 
	  switch(strtolower($extension)) //methods for text extraction 
	  {
		case "pdf": 
		{
			//using XPDF and iconv for conversion purposes
			$toexec = "/usr/local/bin/pdftotext  -raw -nopgbrk " . $uploadFormObj->mUploadTempName . " -";
			// Alternative: $toexec = "/usr/bin/pdftotext  -raw -nopgbrk " . $uploadFormObj->mUploadTempName . " -";
			$toexec.="| iconv -f ISO-8859-1 -t UTF-8";
			break;
		}
 
		case "dot": {}
		case "doc": 
		{
			//using antiword 
			$toexec = "/usr/bin/antiword -s ".$uploadFormObj->mUploadTempName;
			break;
		}
 
		case "xls":
		{
			$toexec = "/usr/bin/xls2csv ".$uploadFormObj->mUploadTempName;
			break;
		}
 
		case "ppt":
		{
			$toexec = "/usr/bin/catppt ".$uploadFormObj->mUploadTempName; 
			break;
		}
 
		case "rtf": # any file extension with text in it will be okay here
		{
			$toexec = "/usr/bin/strings ".$uploadFormObj->mUploadTempName; # string's output isn't neat, but it works.
			break;
		}
 
		//OpenOffice.org documents
		case "ods": {}
		case "odp": {}
		case "odg": {}
		case "odt":
		{
			$toexec = "unzip -p " . $uploadFormObj->mUploadTempName . " content.xml";
			$RemoveTags = true;
			break;
		}
	}
	if ($toexec != "")
	{
		exec($toexec, $DocText);
		$NewDesc = $uploadFormObj->mUploadDescription . "\r\n" . "<!-- ";
		foreach ($DocText as $DocLine) 
		{
			if($RemoveTags == false)
			{
				$NewDesc .= "\r\n" . str_replace("-->","",$DocLine);
			}
			else
			{
				$NewDesc .= "\r\n" . strip_tags(str_replace("-->","",$DocLine));
			}
		}
		$NewDesc .= "\r\n" . " -->";
		$uploadFormObj->mUploadDescription = $NewDesc;
	}
	return $uploadFormObj;
}
 
function isCommandPresent($command)
{
	if(file_exists($command)==false)
	{
		//extract the command from the path
		$lastSlash = strrpos($command, '/');
		if($lastSlash!='')
		{
			$commandWithoutSlashes = substr($command, $lastSlash+1);
		}
		else
		{
			$commandWithoutSlashes = $command;
		}
 
		$toexec = "whereis $commandWithoutSlashes";
		//lookup the command
		exec($toexec, $whereis);
		echo "FileIndexer: The file $command is missing ... whereis result: $whereis[0] <br>";
	}
}
 
/**
  * Add extension information to Special:Version
 */
$wgExtensionCredits['other'][] = array(
	'name' => 'FileIndexer',
	'author' => 'MHart and Flominator',
	'description' => 'makes uploaded documents searchable',
	'url' => 'http://www.mediawiki.org/wiki/Extension:FileIndexer'
	);

[edit] pre MediaWiki 1.9.0

Insert the hook into SpecialUpload.php on MediaWiki 1.6.7 around line 158:

	function processUpload() {
		global $wgUser, $wgOut;
 
		if( !wfRunHooks( 'UploadForm:BeforeProcessing', array( &$this ) ) )
		{
			wfDebug( "Hook 'UploadForm:BeforeProcessing' broke processing the file." );
			return false;
		}
 
		/* Check for PHP error if any, requires php 4.2 or newer */

[edit] Any questions

For more hints and a place to ask your questions, see Extension talk:FileIndexer