[Xapian-discuss] PHP functions in Ubuntu packages

Francis Irving francis at flourish.org
Sun Nov 19 09:46:53 GMT 2006


On Wed, Nov 15, 2006 at 05:14:55AM +0000, Olly Betts wrote:
> > What's going on with the PHP4 bindings again?
> 
> This is where this was discussed last month:
> 
> http://article.gmane.org/gmane.comp.search.xapian.general/3340
> 
> Hmm, I never wrote that script.  Here it is now:
> 
> http://www.oligarchy.co.uk/xapian/patches/xapian-php-update

Ah super! Thanks Olly.

It nearly worked on the file I tested it on, but gave these errors.

$ cat xapian.module | xapian-php-update >out
Use of uninitialized value in concatenation (.) or string at
/usr/local/bin/xapian-php-update line 22, <> line 18.
Use of uninitialized value in concatenation (.) or string at
/usr/local/bin/xapian-php-update line 22, <> line 223.
Use of uninitialized value in concatenation (.) or string at
/usr/local/bin/xapian-php-update line 22, <> line 224.
Use of uninitialized value in concatenation (.) or string at
/usr/local/bin/xapian-php-update line 22, <> line 226.
Use of uninitialized value in concatenation (.) or string at
/usr/local/bin/xapian-php-update line 22, <> line 230.
*** 27 change(s) in 27 line(s) :
17,180,182,183,193,194,195,197,198,199,200,201,202,203,204,205,206,207,209,211,215,220,222,223,224,225,229

The file xapian.module (a PHP file) which I was processing is
attached. I think the problem is when one line of code contains two
calls. It was easy enough to fix manually though.

Francis
-------------- next part --------------
	<?php
# vim:set filetype=php:
# vim:sw=2:ts=2:et:nowrap

/**
 * This drupal module links drupal and the result of a xapian search.  
 * The main point of it is to provide the xapian_do_search() function.  
 * I've also added some settings, to make it a bit more pluggable.
 */


/**
 * 15/11/2006 - Sym
 * $query is now the first arg in xapian_do_search
 * Made undata path and dbpath optional
 * Added dbpath to settings page (drupal only)
 * Made xapian_do_search in to an object that has info and data.  
   Info is the string returned by Query_get_description($query)
   and data is an array with the filename, offset and length of the result.
   The idea is to leave the formatting until later on - so xapian_do_search
   will only deal with the search.   
 */


/**
 * Implementation of hook_help().
 */
function xapian_help($section) {
  switch ($section) {
    case 'admin/modules#description':
      return t('Provides options to display content from xapian in drupal, as a node.');
  }
}

/**
 * Implementation of hook_menu().
 */
function xapian_menu($may_cache) {
  $items = array();
  if ($may_cache) {
    $items[] = array(
      'path' => 'admin/settings/xapian',
      'title' => t('xapian settings'),
      'access' => user_access('administer xapian'),   
      'callback' => 'xapian_settings'
     );
     $items[] = array(
      'path' => 'admin/settings/xapian/settings',
      'title' => 'Settings',
      'type' => MENU_DEFAULT_LOCAL_TASK,
      'weight' => '-10',
     );

     $items[] = array(
      'path' => 'admin/settings/xapian/test',
      'title' => t('Databse test'),
      'access' => user_access('administer xapian'),
      'type' => MENU_LOCAL_TASK,
      'callback' => 'xapian_dbtest'
     );
  }
  return $items;
}


/**
 *  Module functions
 */
 
function xapian_settings() {
  $output = drupal_get_form('xapian_settings_form', $form);
  return $output;
}

function xapian_settings_form() {

  $form['undatapath'] = array(
    '#type' => textfield,
    '#title' => 'Path to UN data',
    '#default_value' => variable_get('xapian_undatapath', '/path/to/undata'),
    '#description' => 'Location of undata directory',
  );
  
  $form['dbpath'] = array(
    '#type' => textfield,
    '#title' => 'Database name',
    '#default_value' => variable_get('xapian_dbpath', 'xapdex.db'),
    '#description' => 'Name of xapian database, relitive to the undata directory',
  );

  $form['submit'] = array(
    '#type' => submit,
    '#title' => 'Save',
    '#value' => 'Save',
  );
  return $form;
} 

function xapian_settings_form_submit($form_id, $form) {
  variable_set('xapian_dbpath', $form['dbpath']);
  
  if (substr($form['undatapath'], -1, 1) != '/') {
    $form['undatapath'] .= "/";
  }
  variable_set('xapian_undatapath', $form['undatapath']);
}

function xapian_dbtest() {
  $output = drupal_get_form('xapian_dbtest_form', $form);
  return $output;
}

function xapian_dbtest_form() {
  $q = arg(4);
  $form['search'] = array(
    '#type' => 'fieldset',
    '#title' => t('Search'),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE, 
  );

  $form['search']['word'] = array(
    '#type' => textfield,
    '#title' => 'Search',
    '#default_value' => $q,
  );

  $form['search']['submit'] = array(
    '#type' => submit,
    '#title' => 'Search',
    '#value' => 'Search',
  );

  if (arg(4)) {
    $form['result'] = array(
      '#value' => "<h2>results</h2>",
    );
    $result = xapian_do_search($q);
    if (is_array($result->data)) {
      foreach ($result->data as $item) {
        $results .= $item['file'] . "<br />\n";
      }
    }
    $form['result_content'] = array(
      '#value' => $results,
    );

  }
  return $form;
}


function xapian_dbtest_form_submit($form_id, $form) {
  $q = $form['word'];
//  $q = str_replace('/', 'x', $q);
  return 'admin/settings/xapian/test/' . $q;
}


/**
 * This is the main search function, that tries to copy xapque.py
 */

function xapian_do_search($query, $undata_path = NULL, $db_path = NULL) {
  
  if (!$undata_path) {
    // XXX what should we call this parameter? is location of undata directory
    $undata_path = variable_get('xapian_undatapath', '/path/to/undata');
  }
  if (substr($undata_path, -1, 1) != '/') {
    $undata_path .= "/";
  }
  
  if (!$db_path) {
    $db_path = variable_get('xapian_dbpath', 'path/to/database.db');
  }
  
  $db_path = $undata_path . $db_path;

  // XXX this doesn't break well if it can't find the database
  $database = new_Database($db_path);  

  $enquire = new_Enquire($database);
  $stemmer = new_Stem("english");
  // XXX this for my testing when not in drupal as don't have "arg()".
  // However, not sure what the $query parameters was for anyone when
  // running under Drupal?
  if ($query) { 
    $terms = $query;
  } else {
    $terms = arg(4);
  }

  $queryparser = new_queryparser();
  queryparser_set_stemming_strategy($queryparser, QueryParser_STEM_NONE);
  queryparser_set_default_op($queryparser, Query_OP_AND);

  queryparser_add_prefix($queryparser, "class", "C");
  queryparser_add_prefix($queryparser, "id", "I");
  queryparser_add_prefix($queryparser, "subid", "J");
  queryparser_add_prefix($queryparser, "class", "C");
  queryparser_add_prefix($queryparser, "name", "S");
  queryparser_add_prefix($queryparser, "nation", "N");
  queryparser_add_prefix($queryparser, "language", "L");
  queryparser_add_prefix($queryparser, "document", "D");
  queryparser_add_prefix($queryparser, "reference", "R");
  queryparser_add_prefix($queryparser, "date", "E");
  queryparser_add_prefix($queryparser, "heading", "H");

  $query = queryparser_parse_query($queryparser, $terms);

  enquire_set_query($enquire, $query);

  # XXX for actual searches will want to sort by relevance instead, or fancier
  # things like set_sort_by_value_then_relevance
  enquire_set_sort_by_value($enquire, 0, false); // false for order forwards in date/time


  # XXX will want more than 100 here! See mset_get_matches_estimated in
  # searchengine.php from TWFY for code to work out set result sizes
  $matches = Enquire_get_mset($enquire, 0, 100); 

  $result->info = Query_get_description($query);
  $mseti = MSet_begin($matches);
  while (! MSetIterator_equals($mseti, MSet_end($matches))) {  
    $doc_data = Document_get_data(MSetIterator_get_document($mseti));
    list($doc_file, $doc_offset, $doc_len) = split("\|", $doc_data);
    $result->data[] = array('file' => $doc_file, 'offset' => $doc_offset, 'len' => $doc_len);
    // Next result
    MSetIterator_next($mseti);
  }
  return $result;
}


More information about the Xapian-discuss mailing list