Drupal: indexing nodes with Agrovoc (without a module)

Instructions to implement manual Agrovoc indexing (with an Agrovoc search popup) in Drupal without the need of a dedicated module.

1. Taxonomies to create
A) A taxonomy with no multilingual settings for Agrovoc codes.
B) A multilingual taxonomy (with translation) for Agrovoc terms.
Following the steps below, at the moment of saving a node Agrovoc codes will be saved to taxonomy A, while Agrovoc terms in all enabled languages will be saved to taxonomy B (automatically linked as reciprocal translations), where the description of each term would be its URI.
 
2. Fields to add to content type(s)
Machine-readable names are only recommended in order not to have to edit their names in the PHP code in the selectTerms.php file and in the PHP Rule (see below, point 4.2)
The following fields should be added to all content types for which you want to enable Agrovoc indexing:
A) A text field called “Agrovoc keywords” (temporary text field): recommended machine readable name: field_agrovocsubject_text.
B) A content taxonomy field called “Agrovoc codes” (linked to taxonomy A, multiple, freetagging): recommended machine readable name: field_subject
C) A content taxonomy field called “Agrovoc terms” (linked to taxonomy B, multiple, freetagging): recommended machine readable name: field_agrovocsubject_all
This field will be hidden by a Rule (see point 4), so the user will not see it in the input form.
 
3. Agrovoc search popup
Place the following files (attached): nusoap.php, selectTerms.php, results.php in the same folder, preferably under the website root. If you have not used the recommended field names above, you will have to edit the IDs of the corresponding HTML elements in the first lines of the selectTerms.php file.
To activate the Agrovoc search popup from the Drupal edit form, just insert a target=_blank link in the help text of the “Agrovoc keywords” field  linking to the “selectTerms.php” file, wherever you put it.
 
4. Rule to apply when saving a node that uses Agrovoc indexing
Module: Rules
1) Create the following rule for each content type that uses Agrovoc indexing:
- Admin > Rules > Triggered rules > Add a new rule
- Event: “Xxx [name of content type] node form is being built”
- Action: Hide form element (hide the field_agrovocsubject_all field)
2) Create the following single rule:
- Admin > Rules > Triggered rules > Add a new rule
- Event: Content is going to be saved
- Condition: saved content is of type... (select types for which you use Agrovoc)
- Action: PHP: copy the PHP below (change the $vid variable to the ID of your multilingual vocabulary for the Agrovoc Terms taxonomy; if you have not used the above recommended field names, change the field name on line 2 and $node->field_agrovocsubject_all on the following page)

__________________________________________________________________

$vid = 16; // id of the vocabulary you use for multilingual Agrovoc terms
$terms_list = $node->field_subject; // the field you use for Agrovoc codes

require_once 'sites/all/modules/i18n/i18ntaxonomy/i18ntaxonomy.admin.inc';

$agrovocURIbase = "http://www.fao.org/aims/aos/agrovoc/c_";
$url = "http://www.fao.org/webservices/AgrovocWS";
$function_soap = "simpleSearchByMode2";
$uri = "AgrovocWS";
$client = new SoapClient(null, array('location' => $url, 'uri' => $uri, 'exceptions' => true));
//Test if Web Services are working: if not, display message after saving:
$soapOk = true;
$paramsTest = array('termcode' => 1234,'language' => 'en');
try {
$resultTest = $client->__soapCall("getTermByLanguage", $paramsTest);
} catch (Exception $e) {
drupal_set_message("WARNING. SOAP call failed: " . $e->getMessage() . ". AGROVOC INDEXING NOT UPDATED.");
$soapOk = false;
}

if ($soapOk) {

$tridOrig = 0;
$num_max = count($terms_list);
$i=0;
$k=1;
// REMOVE ALL ASSOCIATIONS WITH TERMS IN AGROVOC VOCABULARIES
// change the name of the field if you did not use our field names
$node->field_agrovocsubject_all = array();

if (empty($terms_list)==false){

//for each term, look up labels in all enabled languages
foreach ($terms_list as $key => $val) {

$dTerm = taxonomy_get_term($val['value']);
$agrovocCode = $dTerm->name;
$agrovocCodeint=(int)$agrovocCode;
$function_soaplang="getTermByLanguage";
$s=0;
$lang_list=Array();
$lanPrm=Array();

//change according to the languages you need: the languages
//have to be enabled in Drupal and existing in Agrovoc
//demo version: only English and French:
$lanPrm[0]="FR";
$lanPrm[1]="EN";

while ($s < 2){
$paramslang = array('termcode' => $agrovocCodeint,'language' => $lanPrm[$s]);
$resultlang = $client->__soapCall($function_soaplang, $paramslang);
$a = 0;
while ($resultlang == "" && $a < 10) { // 10 attempts for WS
$resultlang = $client->__soapCall($function_soaplang, $paramslang);
$a++;
}
$lang_list[$lanPrm[$s]] = trim($resultlang);
$s++;
}
$Frterm=trim($lang_list['FR']);
$Enterm=trim($lang_list['EN']);

// DEMO PACKAGE: ONLY ENGLISH AND FRENCH
// TO ADD NEW LANGUAGES, MODIFY THE ARRAYS
// ABOVE AND REPEAT THE SECTIONS BELOW
// NOTICE: THE LANGUAGES YOU ADD HERE MUST
// BE ENABLED IN YOUR WEBSITE
// for looking up terms in Drupal taxonomy, impossible to use
// taxonomy_get_term_by_name: no language parameter

// ENGLISH
if (trim($Enterm)!= "") {

$sql="SELECT * FROM {term_data} WHERE name = '%s' and language='%s'";
$term=db_query($sql,$Enterm,"en");
$term=db_fetch_object($term);
if ($term->name==""){
$lan="en";
$edit = array('vid' => $vid,
'name' => $Enterm ,
'language' => $lan,
'description' => $agrovocURIbase . $agrovocCode);
taxonomy_save_term($edit);
}
$sql="SELECT * FROM {term_data} WHERE name = '%s' and language='%s'";
$term=db_query($sql,$Enterm,"en");
$term=db_fetch_object($term);
$agrovocTermId=$term->tid;

// TRANSLATIONS: i18ntaxonomy_translation_save doesn't work
// set trid for translations: for English (original)
$tridOrig = i18ntaxonomy_next_trid();
$sql="UPDATE {term_data} SET trid = %d WHERE tid = %d";
$r = db_query($sql,$tridOrig,$term->tid);

$node->field_agrovocsubject_all[$i]['value'] = $agrovocTermId;
$arrTerms['en']=$agrovocTermId;
$arrTermAll[$i]=$agrovocTermId;
}

// FRENCH
if (trim($Frterm)!= "") {
$sql="SELECT * FROM {term_data} WHERE name = '%s' and language='%s'";
$term=db_query($sql,$Frterm,"fr");
$term=db_fetch_object($term);
if (empty($term)==true){
$lan="fr";
$edit = array('vid' => $vid,
'name' => $Frterm ,
'language' => $lan,
'description' => $agrovocURIbase . $agrovocCode);
taxonomy_save_term($edit);
}
$sql="SELECT * FROM {term_data} WHERE name = '%s' and language='%s'";
$term=db_query($sql,$Frterm,"fr");
$term=db_fetch_object($term);
$agrovocTermId=$term->tid;

// TRANSLATIONS: i18ntaxonomy_translation_save doesn't work
// set trid TO ENGLISH TRID (original) for translations
$sql="UPDATE {term_data} SET trid = %d WHERE tid = %d";
$r = db_query($sql,$tridOrig,$term->tid);

$node->field_agrovocsubject_all[$k]['value'] = $agrovocTermId;
$arrTerms['fr']=$agrovocTermId;
$arrTermAll[$k]=$agrovocTermId;
}

// i18ntaxonomy_translation_save($arrTerms);
// to set terms as translations: doesn't work

$i=$i+2;
$k = $k+2;
}
$node->taxonomy[16]=$arrTermAll;

return $node;
}
}

__________________________________________________________________

Below are attached the three files you need to copy to your website root and a Word version of this post.

Agrovoc-indexing-in-Drupal_0.doc41 KB