Index: google_cse.theme.inc
===================================================================
--- google_cse.theme.inc (.../vendor/drupal-contrib/modules/google_cse/current) (revision 1372)
+++ google_cse.theme.inc (.../appistry.com/trunk/sites/all/modules/google_cse) (revision 1372)
@@ -1,5 +1,5 @@
variable_get('google_cse_cx', ''),
'cof' => variable_get('google_cse_cof_google', 'FORID:0'),
'sitesearch' => google_cse_sitesearch_default(),
- ) + google_cse_advanced_settings();
+ ) + google_cse_advanced_settings();
$variables['results_searchbox_form'] = $variables['form'] ? drupal_get_form('google_cse_results_searchbox_form', $variables['self']) : '';
$variables['noscript'] = t('!google, or enable JavaScript to view them here.', array('!google' => l(t('View the results at Google'), 'http://'. variable_get('google_cse_domain', 'www.google.com') .'/cse', array('query' => $query))));
@@ -26,12 +27,109 @@
'googleCSE' => array(
'resultsWidth' => intval(variable_get('google_cse_results_width', 600)),
'domain' => variable_get('google_cse_domain', 'www.google.com'),
- ),
- );
+ ),
+ );
drupal_add_js($settings, 'setting');
}
/**
+ * The search results page can be themed/customized. This is the
+ * function for theming the Business search results page.
+ *
+ * The input is a "results" array.
+ *
+ * Component 'items' is an array of search results,
+ * where each item is an array with the
+ * following components (not all are displayed in this default function):
+ * 'url' - URL of search result
+ * 'title' - Title of search result
+ * 'crawldate' - Date page was last indexed by Google
+ * 'excerpt' - Excerpt of page with search terms highlighted
+ * 'lang' - Google's guess as to the language of the search result
+ * 'crowd_host' - Indicates that lots more results were found on this
+ * host, and you could do another query on this host to find more
+ * results (value is a URL-encoded host name to be used in a query)
+ *
+ * Components 'from', 'to', and 'total'
+ * indicate "Viewing results [from] to [to] of approximately [total]'.
+ *
+ *
+ */
+function template_preprocess_google_cse_xml_results(&$variables) {
+ $results = $variables['form'];
+
+ $variables['prefix'] = filter_xss_admin(variable_get('google_cse_results_prefix', ''));
+ $variables['suffix'] = filter_xss_admin(variable_get('google_cse_results_suffix', ''));
+ $variables['results_searchbox_form'] = $variables['form'] ? drupal_get_form('google_cse_results_searchbox_form', $variables['self']) : '';
+
+ $variables['header'] = check_plain(variable_get('google_cse_results_title', t('Search Results')));
+
+ $variables['has_results'] = !(empty($results) || empty($results['items']));
+ $variables['no_results'] = t('Your search returned no results. Please try a different search.');
+
+ $variables['pager_status'] = t('Viewing results !from to !to of approximately !total',
+ array(
+ '!from' => intval($results['from']),
+ '!to' => intval($results['to']),
+ '!total' => intval($results['total'])
+ )
+ );
+
+ $perpage = variable_get('google_cse_results_num', 10);
+ $query = array('query' => $_GET['query']);
+
+ if ($results['from'] > 1) {
+ $newstart = intval($results['from']) - $perpage - 1;
+ if ($newstart < 0) {
+ $newstart = 0;
+ }
+ $query['start'] = $newstart;
+
+ $variables['pager_prev'] = l(t('Previous page'),
+ variable_get('google_cse_results_path', 'search/google'),
+ array('query' => drupal_query_string_encode($query)));
+ }
+
+ if ($results['to'] < $results['total']) {
+ $query['start'] = intval($results['to']);
+
+ $variables['pager_next'] = l(t('Next page'),
+ variable_get('google_cse_results_path', 'search/google'),
+ array('query' => drupal_query_string_encode($query)));
+ }
+
+ $variables['original_query'] = preg_replace('/ more:[^&]*/', '', $_GET['query']);
+ $variables['has_refinements'] = count($results['labels']) == TRUE;
+
+ if ($variables['has_refinements']) {
+ $variables['refinements_label'] = t('Refine results for');
+ $variables['refinements'] = array();
+
+ preg_match('/ more:([^&]*)/', $_GET['query'], $selected_label);
+ $selected_label = $selected_label[1];
+
+ foreach ($results['labels'] as $label => $title) {
+ $selected = ($label == $selected_label) ? ' selected' : '';
+ $classes = "google-cse-refinements-label" . $selected;
+ $attributes = drupal_attributes(array('class' => $classes));
+ $new_query['query'] = $variables['original_query'] . " more:$label";
+ $link = l(t($title),
+ variable_get('google_cse_results_path', 'search/google'),
+ array('query' => drupal_query_string_encode($new_query)));
+ $variables['refinements'][] = array('link' => $link, 'attributes' => $attributes);
+ }
+ }
+
+ $variables['results'] = array();
+ foreach ($results['items'] as $item) {
+ $link = l($item['title'], $item['url'], array('html' => TRUE));
+ $filtered_excerpt = filter_xss_admin(preg_replace('/
/', '', $item['excerpt']));
+ $url = l($item['url'], $item['url']);
+ $variables['results'][] = array('title' => $link, 'excerpt' => $filtered_excerpt, 'url' => $url);
+ }
+}
+
+/**
* Display an Add-to-Google button.
*/
function template_preprocess_google_cse_results_gadget(&$variables) {
Index: google_cse.admin.inc
===================================================================
--- google_cse.admin.inc (.../vendor/drupal-contrib/modules/google_cse/current) (revision 1372)
+++ google_cse.admin.inc (.../appistry.com/trunk/sites/all/modules/google_cse) (revision 1372)
@@ -23,9 +23,10 @@
'#default_value' => variable_get('google_cse_results_display', 'here'),
'#options' => array(
'here' => t('On this site (requires JavaScript)'),
+ 'xml' => t('On this site (without JavaScript or frames, requires current Google Business account)'),
'google' => t('On Google'),
),
- '#description' => t('Search results can be displayed on this site, using JavaScript, or on Google, which does not require JavaScript.'),
+ '#description' => t('Search results can be displayed on this site, using JavaScript, or on Google, which does not require JavaScript. If you have a Business account on Google Custom Search, you can also display results on this site without using JavaScript.'),
);
$form['google_cse_results_title'] = array(
'#title' => t('Search results page title'),
Index: google_cse.module
===================================================================
--- google_cse.module (.../vendor/drupal-contrib/modules/google_cse/current) (revision 1372)
+++ google_cse.module (.../appistry.com/trunk/sites/all/modules/google_cse) (revision 1372)
@@ -1,5 +1,5 @@
array('search Google CSE'),
'title callback' => 'google_cse_results_tab',
'description' => 'Google Custom Search Engine',
@@ -40,13 +41,18 @@
'arguments' => array('form' => TRUE, 'self' => FALSE),
'file' => 'google_cse.theme.inc',
'template' => 'google_cse_results',
- ),
+ ),
+ 'google_cse_xml_results' => array(
+ 'arguments' => array('form' => TRUE, 'self' => FALSE),
+ 'file' => 'google_cse.theme.inc',
+ 'template' => 'google_cse_xml_results',
+ ),
'google_cse_results_gadget' => array(
'arguments' => array(),
'file' => 'google_cse.theme.inc',
'template' => 'google_cse_results_gadget',
- ),
- );
+ ),
+ );
}
/**
@@ -57,7 +63,7 @@
return array(
0 => array('info' => t('Google CSE'), 'cache' => BLOCK_NO_CACHE),
1 => array('info' => t('Google CSE results'), 'cache' => BLOCK_NO_CACHE),
- );
+ );
}
elseif ($op == 'view' && user_access('search Google CSE')) {
switch ($delta) {
@@ -74,11 +80,11 @@
*/
function google_cse_forms() {
$forms = array();
- $forms['google_cse_searchbox_form'] = array(
+ $forms['google_cse_searchbox_form'] = array(
'callback' => 'google_cse_searchbox_form_builder',
'callback arguments' => array('google_cse_searchbox_form'),
);
- $forms['google_cse_results_searchbox_form'] = array(
+ $forms['google_cse_results_searchbox_form'] = array(
'callback' => 'google_cse_searchbox_form_builder',
'callback arguments' => array('google_cse_results_searchbox_form'),
);
@@ -91,37 +97,48 @@
function google_cse_searchbox_form_builder(&$form_state, $form_id, $self = FALSE) {
$form = array();
// The default form.
- if (variable_get('google_cse_results_display', 'here') == 'here') {
- $form['#action'] = url($self ? $_GET['q'] : 'search/google');
+ if (variable_get('google_cse_results_display', 'here') != 'google') {
+ $form['#action'] = url($self ? $_GET['q'] : variable_get('google_cse_results_path', 'search/google'));
$cof = variable_get('google_cse_cof_here', 'FORID:11');
}
else {
$form['#action'] = 'http://'. variable_get('google_cse_domain', 'www.google.com') .'/cse';
$cof = variable_get('google_cse_cof_google', 'FORID:0');
}
+
$form['#method'] = 'get';
- $form['cx'] = array(
- '#type' => 'hidden',
- '#value' => variable_get('google_cse_cx', ''),
- );
- $form['cof'] = array(
- '#type' => 'hidden',
- '#value' => $cof,
- );
+
$form['query'] = array(
'#type' => 'textfield',
- '#default_value' => isset($_GET['query']) ? $_GET['query'] : '',
+ '#default_value' => isset($_GET['query']) ? preg_replace('/ more:[^&]*/', '', $_GET['query']) : '',
);
$form['sa'] = array(
'#type' => 'submit',
'#value' => t('Search'),
);
- foreach (google_cse_advanced_settings() as $parameter => $setting) {
- $form[$parameter] = array(
+
+ // items needed for non-XML-display versions of search form,
+ // whether it is in the block or on the results page
+
+ if (variable_get('google_cse_results_display', 'here') != 'xml') {
+ $form['cx'] = array(
'#type' => 'hidden',
- '#value' => $setting,
+ '#value' => variable_get('google_cse_cx', ''),
);
+
+ $form['cof'] = array(
+ '#type' => 'hidden',
+ '#value' => $cof,
+ );
+
+ foreach (google_cse_advanced_settings() as $parameter => $setting) {
+ $form[$parameter] = array(
+ '#type' => 'hidden',
+ '#value' => $setting,
+ );
+ }
}
+
// And the small differences between both.
switch ($form_id) {
case 'google_cse_searchbox_form':
@@ -130,12 +147,13 @@
break;
case 'google_cse_results_searchbox_form':
$form['query']['#size'] = intval(variable_get('google_cse_results_searchbox_width', 40));
- $form['query']['#title'] = t('Enter your keywords');
+ $form['query']['#title'] = variable_get('google_cse_searchbox_header', t('Enter your keywords'));
if (variable_get('google_cse_results_gadget', 1)) {
$form['sa']['#suffix'] = theme('google_cse_results_gadget');
}
- break;
}
+
+ // TODO: May need to remove
google_cse_sitesearch_form($form);
return $form;
}
@@ -145,7 +163,12 @@
*/
function google_cse_results() {
google_cse_results_set_title();
- return theme('google_cse_results');
+ if (variable_get('google_cse_results_display', 'here') == 'here') {
+ print theme('page', theme('google_cse_results'));
+ } else {
+ $results = _google_cse_get_search_results();
+ print theme('page', theme('google_cse_xml_results', $results));
+ }
}
/**
@@ -220,7 +243,7 @@
'#type' => $type,
'#options' => array(
'' => ($var = variable_get('google_cse_sitesearch_option', '')) ? (($type == 'radios') ? check_plain($var) : $var) : t('Search the web'),
- ) + $options,
+ ) + $options,
'#default_value' => google_cse_sitesearch_default(),
);
if ($type == 'select' && isset($form['sa'])) {
@@ -235,3 +258,214 @@
function google_cse_sitesearch_default() {
return isset($_GET['sitesearch']) ? $_GET['sitesearch'] : (variable_get('google_cse_sitesearch_default', 0) ? array_shift(preg_split('/[\s]+/', variable_get('google_cse_sitesearch', ''))) : '');
}
+
+/* Queries Google to get XML results, and parses them into an array
+ * of search items -- see theme_google_cse_result_items() function below
+ * for documentation of this array.
+ */
+function _google_cse_get_search_results() {
+
+ // formulate the query for Google
+
+ $url = 'http://www.google.com/search';
+
+ $query = array(
+ 'q' => $_GET['refinement'] == '' ? $_GET['query'] : $_GET['query'] . ' more:' . $_GET['refinement'],
+ 'start' => $_GET['start'],
+ 'num' => variable_get('google_cse_results_num', 10),
+ 'client' => 'google-csbe',
+ 'output' => 'xml_no_dtd',
+ 'cx' => variable_get('google_cse_cx', ''),
+ ) + google_cse_advanced_settings();
+
+ // get the XML results
+
+ $res = drupal_http_request($url . '?' . drupal_query_string_encode($query));
+
+ if ($res->code != '200') {
+ return array();
+ }
+
+ // parse results and return them
+ return _google_cse_parse_xml_results($res->data);
+
+}
+
+
+/*
+ * Internal function: parses the XML results returned by Google into
+ * a results array (see function theme_google_cse_result_items for doc)
+ */
+function _google_cse_parse_xml_results($data) {
+
+ global $google_cse_elem;
+ global $google_cse_item_index;
+ global $google_cse_results;
+ global $google_cse_in_facet_item;
+
+ $google_cse_in_facet_item = FALSE;
+
+ $xml_p = drupal_xml_parser_create($data);
+ xml_set_element_handler($xml_p, '_google_cse_xml_elem_start',
+ '_google_cse_xml_elem_end');
+ xml_set_character_data_handler($xml_p, '_google_cse_xml_character_data');
+
+ $google_cse_elem = '';
+ $google_cse_item_index = 0;
+ $google_cse_results = array('items' => array());
+
+ if (!xml_parse($xml_p, $data, 1)) {
+ return array();
+ }
+
+ return $google_cse_results;
+}
+
+/*
+ * Internal function for handling XML elements when parsing Google results.
+ */
+function _google_cse_xml_elem_start($parser, $name, $attribs = array()) {
+ global $google_cse_elem;
+ global $google_cse_item_index;
+ global $google_cse_results;
+ global $google_cse_partial_data;
+ global $google_cse_in_facet_item;
+ global $google_cse_curr_facet_label;
+
+ // we only care about some of the XML elements in the Google results
+ // See http://www.google.com/coop/docs/cse/resultsxml.html for doc
+
+ switch ($name) {
+ case 'RES':
+ // attributes give the from/to indices of this results set
+ $google_cse_results['from'] = $attribs['SN'];
+ $google_cse_results['to'] = $attribs['EN'];
+ break;
+
+ case 'M':
+ // gives approx total number of results of search
+ $google_cse_elem = 'total';
+ break;
+
+ case 'R':
+ // starts a new search result item
+ $google_cse_item_index = count($google_cse_results['items']);
+ $google_cse_results['items'][$google_cse_item_index] = array();
+ break;
+
+ case 'FACETITEM':
+ // starts a new facet item
+ $google_cse_in_facet_item = TRUE;
+ break;
+
+ case 'LABEL':
+ $google_cse_elem = $google_cse_in_facet_item ? 'facetlabel' : 'label';
+ break;
+
+ case 'ANCHOR_TEXT':
+ $google_cse_elem = 'anchor_text';
+ break;
+
+ // The rest of these are components of search result items
+
+ case 'U':
+ $google_cse_elem = 'url';
+ break;
+
+ case 'T':
+ $google_cse_elem = 'title';
+ break;
+
+ case 'CRAWLDATE':
+ $google_cse_elem = 'crawldate';
+ break;
+
+ case 'S':
+ $google_cse_elem = 'excerpt';
+ break;
+
+ case 'LANG':
+ $google_cse_elem = 'lang';
+ break;
+
+ case 'HN':
+ $google_cse_elem = 'crowd_host';
+ break;
+
+ // anything else: make sure we are not getting data now!
+ default:
+ $google_cse_elem = '';
+ break;
+
+ }
+
+ // this flag makes sure the character data handler gets reset
+ $google_cse_partial_data = 0;
+}
+
+/*
+ * Internal function for handling XML elements when parsing Google results
+ */
+function _google_cse_xml_elem_end($parser, $name) {
+ global $google_cse_elem;
+ global $google_cse_item_index;
+ global $google_cse_partial_data;
+ global $google_cse_in_facet_item;
+
+ // close out the element and make sure character data handler gets reset
+ $google_cse_elem = '';
+ $google_cse_partial_data = 0;
+ switch ($name) {
+ case 'FACETITEM':
+ $google_cse_in_facet_item = FALSE;
+ break;
+ }
+}
+
+
+/*
+ * Internal function for handling XML elements when parsing Google results
+ */
+function _google_cse_xml_character_data($parser, $data) {
+ global $google_cse_elem;
+ global $google_cse_item_index;
+ global $google_cse_results;
+ global $google_cse_partial_data;
+ global $google_cse_curr_facet_label;
+
+ if ($google_cse_elem == 'total') {
+ // handle the "total" element
+ if (!$google_cse_partial_data) {
+ $google_cse_results['total'] = '';
+ }
+ $google_cse_results['total'] .= $data;
+
+ } else if ($google_cse_elem == 'facetlabel') {
+ if (!$google_cse_partial_data) {
+ $google_cse_curr_facet_label = '';
+ }
+ $google_cse_curr_facet_label .= html_entity_decode($data);
+
+ } else if ($google_cse_elem == 'anchor_text') {
+ if (!$google_cse_partial_data) {
+ $google_cse_results['labels'][$google_cse_curr_facet_label] = '';
+ }
+ $google_cse_results['labels'][$google_cse_curr_facet_label] .= html_entity_decode($data);
+
+ } else if (array_search($google_cse_elem,
+ array('url', 'title', 'crawldate',
+ 'excerpt', 'lang', 'crowd_host')) !== FALSE) {
+
+ // handle the item sub-elements
+ if (!$google_cse_partial_data) {
+ $google_cse_results['items'][$google_cse_item_index][$google_cse_elem] = '';
+ }
+
+ $google_cse_results['items'][$google_cse_item_index][$google_cse_elem] .= html_entity_decode($data);
+
+ }
+
+ // sometimes this gets called multiple times within the same element,
+ // due to line breaks or whatever, so make sure we append data
+ $google_cse_partial_data = 1;
+}
\ No newline at end of file
Index: google_cse_xml_results.tpl.php
===================================================================
--- google_cse_xml_results.tpl.php (.../vendor/drupal-contrib/modules/google_cse/current) (revision 0)
+++ google_cse_xml_results.tpl.php (.../appistry.com/trunk/sites/all/modules/google_cse) (revision 1372)
@@ -0,0 +1,56 @@
+
+
+ +
+ + + +:
+ + > + ++ + | + + +
+ + ++ + | + + +
+ + + + + + +