function google_appliance_parse_device_response_xml in Google Search Appliance 7
Parse the response from the Google Search Appliance device into a php array
@arg $gsa_xml response text obtained from the device query @arg $use_cached Whether or not to use the cached version of this query
Return value
php array structure to iterate when displaying results
1 call to google_appliance_parse_device_response_xml()
- google_appliance_search_view in ./
google_appliance.module - Top level search execution (menu callback)
1 string reference to 'google_appliance_parse_device_response_xml'
- google_appliance_block_view in ./
google_appliance.module - Implements hook_block_view().
File
- ./
google_appliance.module, line 637 - Google Appliance module enables searching via a dedicated Google Search Appliance hardware device. See README.txt and the help page at admin/help/google_appliance.
Code
function google_appliance_parse_device_response_xml($gsa_xml, $use_cached = TRUE) {
$results =& drupal_static(__FUNCTION__);
if (!isset($results) || $use_cached === FALSE) {
// look for xml parse errors
libxml_use_internal_errors(TRUE);
$payload = simplexml_load_string($gsa_xml);
if (!$payload) {
// XML parse error(s)
$errors = array();
foreach (libxml_get_errors() as $error) {
$errors[] = $error->message;
}
// roll up the errors
$errors = join(', ', $errors);
$results['error'] = array(
'lib_xml_parse_error' => $errors,
);
// displaying useful error messages depends upon the use of the array key
// 'lib_xml_parse_error' ... the actual error is displayed elsewhere.
// @see google_appliance.theme.inc
}
else {
// store metrics for stat reporting
$results['total_results'] = (int) $payload->RES->M;
// somewhat unreliable
$results['last_result'] = (string) $payload->RES['EN'];
// check if there is an result at all ($payload->RES),
// secure search doesn't provide a value for $payload->RES->M
if ($results['total_results'] == 0 && isset($payload->RES)) {
$results['total_results'] = (int) $payload->RES['EN'];
$param_start = $payload
->xpath('/GSP/PARAM[@name="start"]');
$param_num = $payload
->xpath('/GSP/PARAM[@name="num"]');
$request_max_total = (int) $param_start[0]['value'] + (int) $param_num[0]['value'];
if ($results['total_results'] == $request_max_total) {
$results['total_results']++;
}
}
// Spelling suggestions.
if (isset($payload->Spelling->Suggestion)) {
$spelling_suggestion = (string) $payload->Spelling->Suggestion;
$results['spelling_suggestion'] = filter_xss($spelling_suggestion, array(
'b',
'i',
));
}
// Onebox results.
// @see https://developers.google.com/search-appliance/documentation/614/oneboxguide#providerresultsschema
// @see https://developers.google.com/search-appliance/documentation/614/oneboxguide#mergingobs
foreach ($payload
->xpath('//ENTOBRESULTS/OBRES') as $mod) {
$result_code = empty($mod->resultCode) ? '' : (string) $mod->resultCode;
if (empty($result_code) || $result_code == 'success') {
$module_name = (string) $mod['module_name'];
$onebox = array();
$onebox['module_name'] = $module_name;
$onebox['provider'] = (string) $mod->provider;
$onebox['url_text'] = (string) $mod->title->urlText;
$onebox['url_link'] = (string) $mod->title->urlLink;
$onebox['image'] = (string) $mod->IMAGE_SOURCE;
$onebox['description'] = (string) $mod->description;
foreach ($mod
->xpath('./MODULE_RESULT') as $res) {
$result = array();
$result['abs_url'] = (string) $res->U;
$result['title'] = (string) $res->Title;
foreach ($res
->xpath('./Field') as $field) {
$field_name = (string) $field['name'];
$result['fields'][$field_name] = (string) $field;
}
$onebox['results'][] = $result;
}
$results['onebox'][$module_name] = $onebox;
}
}
if ($results['total_results'] == 0) {
// search returned zero results
$results['error'] = array(
'gsa_no_results' => TRUE,
);
return $results;
}
else {
// parse results
foreach ($payload
->xpath('//GM') as $km) {
$keymatch = array();
// keymatch information
$keymatch['description'] = (string) $km->GD;
$keymatch['url'] = (string) $km->GL;
$results['keymatch'][] = $keymatch;
}
// If there are any synonyms returned by the appliance, put them in the results as a new array
// @see http://code.google.com/apis/searchappliance/documentation/50/xml_reference.html#tag_onesynonym
foreach ($payload
->xpath('//OneSynonym') as $syn_element) {
$synonym = array();
// synonym information
$synonym['description'] = (string) $syn_element;
$synonym['url'] = (string) $syn_element['q'];
$results['synonyms'][] = $synonym;
}
foreach ($payload
->xpath('//R') as $res) {
$result = array();
// handy variants of the url for the result
$result['abs_url'] = (string) $res->U;
$result['enc_url'] = (string) $res->UE;
// urlencoded URL of result
$result['short_url'] = substr($result['abs_url'], 0, 80) . (strlen($result['abs_url']) > 80 ? '...' : '');
// result info
$result['title'] = (string) $res->T;
$result['snippet'] = (string) $res->S;
$result['crawl_date'] = (string) $res->FS['VALUE'];
$result['level'] = isset($res['L']) ? (int) $res['L'] : 1;
// result meta data
// here we just collect the data from the device and leave implementing
// display of meta data to the themer (use-case specific)
// @see google-appliance-result.tpl.php
$meta = array();
foreach ($res
->xpath('./MT') as $mt) {
$meta[(string) $mt['N']] = (string) $mt['V'];
}
$result['meta'] = $meta;
// detect the mime type to allow themes to decorate with mime icons
// @see google-appliance-result.tpl.php
$result['mime']['type'] = (string) $res['MIME'];
// collect
$results['entry'][] = $result;
}
}
drupal_alter('google_appliance_results', $results, $payload);
}
}
return $results;
}