18 require_once SQ_CORE_PACKAGE_PATH.
'/page/page.inc';
19 require_once SQ_PACKAGES_PATH.
'/cms/listing_engine/listing_engine.inc';
20 require_once SQ_LIB_PATH.
'/html_form/html_form.inc';
41 var $bodycopies = Array(
42 'initial' =>
'Initial Search Page Layout',
43 'results' =>
'Results Page Layout',
44 'no_results' =>
'No Results Page Layout',
52 var $defaults = Array(
'query_width' => 25);
59 var $keywords = Array(
76 'fluster_category_type',
77 'fluster_category_topic',
78 'fluster_category_site',
79 'fluster_current_term',
84 'result_count_partially',
88 'current_result_page',
89 'current_result_page_start',
90 'current_result_page_end',
92 'previous_result_page_link',
93 'next_result_page_link',
94 'previous_result_page_href',
95 'next_result_page_href',
98 'no_results' => Array(
102 'default_format' => Array(
105 'result_name_linked',
109 'result_url_click_event',
110 'result_url_click_js',
115 'featured_format' => Array(
121 'context_format' => Array(
122 'fluster_category_name',
123 'fluster_current_term',
124 'fluster_navigation',
127 'cluster_format' => Array(
132 'navigation_format' => Array(
136 'spell_format' => Array(
151 $this->_ser_attrs = TRUE;
152 parent::__construct($assetid);
183 $GLOBALS[
'SQ_SYSTEM']->am->includeAsset(
'bodycopy');
184 $GLOBALS[
'SQ_SYSTEM']->am->includeAsset(
'folder');
187 'type_format' =>
'folder',
188 'fluster_format' =>
'folder',
189 'spell_format' =>
'folder',
192 $type_formats = NULL;
193 foreach ($sub_assets as $name => $type) {
194 $asset =
new $type();
195 $copy_link = Array(
'asset' => &$this,
'value' => $name ,
'link_type' => SQ_LINK_TYPE_2,
'is_dependant' => 1,
'is_exclusive' => 1);
197 $asset->setAttrValue(
'name', translate($name));
198 if (!$asset->create($copy_link))
return FALSE;
202 case 'fluster_format':
203 foreach (Array(
'cluster_format',
'navigation_format',
'context_format') as $extra_format) {
205 $bc2_copy_link = Array(
'asset' => &$asset,
'value' => $extra_format,
'link_type' => SQ_LINK_TYPE_2,
'is_dependant' => 1,
'is_exclusive' => 1);
206 $bc2_asset->setAttrValue(
'name', translate($extra_format));
208 if (!$bc2_asset->create($bc2_copy_link, $bc2_args))
return FALSE;
209 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($bc2_asset);
215 foreach (Array(
'featured_format',
'default_format') as $extra_format) {
217 $bc2_copy_link = Array(
'asset' => &$asset,
'value' => $extra_format,
'link_type' => SQ_LINK_TYPE_2,
'is_dependant' => 1,
'is_exclusive' => 1);
218 $bc2_asset->setAttrValue(
'name', translate($extra_format));
220 if (!$bc2_asset->create($bc2_copy_link, $bc2_args))
return FALSE;
221 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($bc2_asset);
227 $extra_format =
'spell_format';
229 $bc_copy_link = Array(
'asset' => &$asset,
'value' => $extra_format,
'link_type' => SQ_LINK_TYPE_2,
'is_dependant' => 1,
'is_exclusive' => 1);
230 $bc_asset->setAttrValue(
'name', translate($extra_format));
232 if (!$bc_asset->create($bc_copy_link, $bc_args))
return FALSE;
240 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($bc_asset);
241 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($asset);
261 foreach ($this->bodycopies as $value => $name) {
264 'link_type' => SQ_LINK_TYPE_2,
271 $bodycopy->setAttrValue(
'name', $name);
273 if (!$bodycopy->create($copy_link, $args)) {
293 switch ($bodycopy_code) {
295 return '<p>Search: %search_query% %search_sort% %submit_button%</p>';
297 return '<p>%initial_layout%<br />%spell_suggestion%<br /> %result_count% Results found:</p><p>%result_featured% <br />%result_list%</p><p>%previous_result_page_link% %page_list_10% %next_result_page_link%</p><p>%fluster_category_topic%</p>';
299 return '<p>No results</p>%initial_layout%';
300 case 'default_format':
301 case 'custom_format':
302 return '<p>%result_name_linked%<br />%result_summary%</p>';
303 case 'featured_format':
304 return '<p><a href="%featured_url%">%featured_title%</a><br />%featured_summary%</p>';
305 case 'context_format':
306 return '<p>%fluster_current_term% by %fluster_category_name%</p> <p>%fluster_list%</p>';
307 case 'cluster_format':
308 return '<p><a href="%cluster_url%">%cluster_name%</a> (%cluster_count%)</p>';
309 case 'navigation_format':
310 return '<p><a href="%navigation_url%">%navigation_name%</a></p>';
312 return '<p>Did you mean: <a href="%spell_url%">%spell_text%</a>?</p>';
317 return parent::_getDefaultBodycopyContent($bodycopy_code);
342 function prepareLink(&$asset, $side_of_link, &$link_type, &$value, &$sort_order, &$dependant, &$exclusive)
345 if ($side_of_link ==
'major' && ($asset instanceof
Bodycopy) && $dependant !=
'1') {
365 $folder_link = $GLOBALS[
'SQ_SYSTEM']->am->getLink($this->
id, SQ_LINK_TYPE_2,
'folder', TRUE,
'type_format');
366 if (!empty($folder_link)) {
367 if ($folder_link[
'linkid'] == $linkid && !$GLOBALS[
'SQ_PURGING_TRASH']) {
368 return translate(
'cms_listing_cannot_delete_type_formats_link', str_replace(
'_',
' ', $this->
type()));
372 $fluster_folder_link = $GLOBALS[
'SQ_SYSTEM']->am->getLink($this->
id, SQ_LINK_TYPE_2,
'folder', TRUE,
'fluster_format');
373 if (!empty($fluster_folder_link)) {
374 if ($fluster_folder_link[
'linkid'] == $linkid && !$GLOBALS[
'SQ_PURGING_TRASH']) {
375 return translate(
'funnelback_cannot_delete_fluster_format_link', str_replace(
'_',
' ', $this->
type()));
379 $spelling_folder_link = $GLOBALS[
'SQ_SYSTEM']->am->getLink($this->
id, SQ_LINK_TYPE_2,
'folder', TRUE,
'spell_format');
380 if (!empty($spelling_folder_link)) {
381 if ($spelling_folder_link[
'linkid'] == $linkid && !$GLOBALS[
'SQ_PURGING_TRASH']) {
382 return translate(
'funnelback_cannot_delete_spelling_format_link', str_replace(
'_',
' ', $this->
type()));
388 $bodycopy_link = $GLOBALS[
'SQ_SYSTEM']->am->getLinkById($linkid);
389 if ($bodycopy_link[
'minor_type_code'] ==
'bodycopy' && array_key_exists($bodycopy_link[
'value'], $this->bodycopies) && !$GLOBALS[
'SQ_PURGING_TRASH']) {
390 return translate(
'funnelback_cannot_delete_bodycopy_link', str_replace(
'_',
' ', ucwords($bodycopy_link[
'value'])), str_replace(
'_',
' ', ucwords($this->
type())));
393 return parent::isDeletableLink($linkid);
407 $page_links = parent::_getAllowedLinks();
408 $page_links[SQ_LINK_TYPE_2][
'bodycopy'] = Array(
'card' =>
'M',
'exclusive' => TRUE);
409 $page_links[SQ_LINK_TYPE_2][
'folder'] = Array(
'card' => 4,
'exclusive' => FALSE);
410 $page_links[SQ_LINK_TYPE_3][
'folder'] = Array(
'card' => 1,
'exclusive' => FALSE);
411 $page_links[SQ_LINK_NOTICE][
'asset'] = Array(
'card' =>
'M',
'exclusive' => FALSE);
425 $url = $this->
attr(
'submit_to_page_url') ? $this->
getURL() : current_url();
439 $click = array_get_index($_GET,
'click', 0);
440 $query = array_get_index($_GET,
'click_query',
'');
441 $rank = array_get_index($_GET,
'click_rank',
'');
442 $url = array_get_index($_GET,
'click_url',
'');
443 $collection = array_get_index($_GET,
'click_collection',
'');
445 if ($click ==
'1' && !empty($query) && !empty($rank) && !empty($url) && !empty($collection)) {
447 $fm = $GLOBALS[
'SQ_SYSTEM']->am->getSystemAsset(
'funnelback_manager');
448 $binary = $fm->getFunnelbackPath().
'/bin/clix2anx';
449 $coll_path = $fm->getCollectionDataPath($collection);
450 $log_file = $fm->getCollectionDataPath($collection,
'log').
'/click.log';
451 $command = $binary.
' '.$query.
' '.$url.
' '.$rank.
' '.$log_file;
453 $fm->runCommand($command, $output, NULL, NULL, $coll_path);
454 header(
'Location: '.$url);
459 parent::printFrontend();
473 if (isset($_REQUEST[$prefix.
'_submit_button']) && empty($_REQUEST[
'mode'])) {
474 $_REQUEST[
'mode'] =
'results';
476 $mode = array_get_index($_REQUEST,
'mode',
'');
478 $search_vars = Array();
479 $search_vars[
'query'] = htmlspecialchars(array_get_index($_REQUEST, $prefix.
'_search_query',
''), ENT_NOQUOTES, SQ_CONF_DEFAULT_CHARACTER_SET);
480 $search_vars[
'scope'] = htmlspecialchars(array_get_index($_REQUEST, $prefix.
'_search_scope',
''), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
481 $search_vars[
'sort'] = htmlspecialchars(array_get_index($_REQUEST, $prefix.
'_search_sort',
''), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
482 $search_vars[
'page'] = htmlspecialchars(array_get_index($_REQUEST,
'current_result_page', 1), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
483 $search_vars[
'num_per_page'] = htmlspecialchars(array_get_index($_REQUEST,
'results_per_page', $this->
_getNumPerPage()), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
486 $search_vars[
'stem'] = htmlspecialchars(array_get_index($_REQUEST, $prefix.
'_stem',
''), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
487 $search_vars[
'type_max'] = htmlspecialchars(array_get_index($_REQUEST, $prefix.
'_type_max_clusters',
''), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
488 $search_vars[
'topic_max'] = htmlspecialchars(array_get_index($_REQUEST, $prefix.
'_topic_max_clusters',
''), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
489 $search_vars[
'site_max'] = htmlspecialchars(array_get_index($_REQUEST, $prefix.
'_site_max_clusters',
''), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
491 $search_vars[
'cluster'] = Array();
492 foreach ($_GET as $index => $value) {
493 if (strpos($index, $prefix.
'_cluster') !== FALSE) {
494 $count = str_replace($prefix.
'_cluster',
'', $index);
495 $search_vars[
'cluster'][$count] = $value;
499 if($this->
attr(
'disable_keyword_replacements') && isset($search_vars[
'query']) && !empty($search_vars[
'query'])) {
500 $search_vars[
'query'] = $this->_sanitizeQueries($search_vars[
'query']);
505 $pmap_params = $pmap->getParameters();
506 $jump_to_result = FALSE;
508 if (is_array($pmap_params) && !empty($pmap_params)) {
509 foreach ($pmap_params as $params) {
512 $dynamic_query = $pmap->getParameterValue($params);
513 if (!empty($dynamic_query) && empty($search_vars[
'query'])) {
514 $search_vars[
'query'] = $dynamic_query;
515 $jump_to_result = TRUE;
519 case 'results_per_page':
520 $dynamic_results = $pmap->getParameterValue($params);
521 if (!empty($dynamic_results)) {
522 $search_vars[
'num_per_page'] = $dynamic_results;
527 $dynamic_scope = $pmap->getParameterValue($params);
528 if (!empty($dynamic_scope) && empty($search_vars[
'scope'])) {
529 $search_vars[
'scope'] = $dynamic_scope;
534 $dynamic_sort = $pmap->getParameterValue($params);
535 if (!empty($dynamic_sort) && empty($search_vars[
'sort'])) {
536 $search_vars[
'sort'] = $dynamic_sort;
551 if (empty($search_vars[
'sort'])) {
552 $search_vars[
'sort'] = $this->
attr(
'sort_order');
556 if ($this->
attr(
'stored_query_show_results') && $mode ==
'initial' && $jump_to_result) {
563 echo $this->_getSearchPageJavascript();
587 $search_results[
'params'] = $search;
588 $results = array_get_index($search_results,
'results', Array());
590 $this->_tmp[
'search_results'] =& $results;
591 $bc_name =
'results';
592 if (empty($results)) $bc_name =
'no_results';
613 $search_summary = Array(
'summary' => Array(),
'fluster' => Array(),
'spell' => Array());
614 $search_results = Array(
'results' => Array(),
'summary' => $search_summary);
617 $type = $this->
attr(
'search_type');
621 $xml_results = $this->_querySquizSearch($search);
622 if (empty($xml_results)) {
624 trigger_localised_error(
'FNB0002', E_USER_WARNING);
625 return $search_results;
635 return $search_results;
638 $xml_results = $this->_queryFunnelback($url);
639 if (empty($xml_results)) {
641 trigger_localised_error(
'FNB0002', E_USER_WARNING);
642 return $search_results;
648 $xml_results = $this->_searchFunnelback($search);
650 if ($xml_results === FALSE) {
652 trigger_localised_error(
'FNB0003', E_USER_WARNING);
653 return $search_results;
654 }
else if (empty($xml_results)) {
656 return $search_results;
662 $old_error_handler = set_error_handler(
'funnelback_xml_error_handler');
665 $xml_results = utf8_encode($xml_results);
666 $dom =
new DOMDocument(
'1.0',
'UTF-8');
667 $dom->loadXML($xml_results);
668 }
catch (ErrorException $e) {
669 restore_error_handler();
670 trigger_localised_error(
'FNB0002', E_USER_WARNING);
671 return $search_results;
674 restore_error_handler();
676 $errorNode = $dom->getElementsByTagName(
'error')->item(0);
677 if (isset($errorNode)) {
678 $errorMessage = $dom->getElementsByTagName(
'usermsg')->item(0);
679 $errorMsg = (isset($errorMessage)) ? $errorMessage->nodeValue :
'';
680 trigger_localised_error(
'FNB0002', E_USER_WARNING);
690 return $search_results;
710 $vars[
'keywords'] = isset($vars[
'keywords']) ? $vars[
'keywords'] : Array();
712 $parents = $GLOBALS[
'SQ_SYSTEM']->am->getParents($broadcaster->id,
'bodycopy', TRUE);
713 $bodycopy_links = $GLOBALS[
'SQ_SYSTEM']->am->getLinks($this->
id, SQ_LINK_TYPE_2,
'bodycopy');
715 $bodycopies = Array();
716 $type_formats = Array();
719 foreach ($bodycopy_links as $link_info) {
720 if (isset($parents[$link_info[
'minorid']])) {
721 $bodycopies[] = $link_info[
'value'];
728 if (empty($bodycopies)) {
730 $bc_parents = $GLOBALS[
'SQ_SYSTEM']->am->getParents($broadcaster->id,
'folder', TRUE);
731 $folder_links = $GLOBALS[
'SQ_SYSTEM']->am->getLinks($this->
id, SQ_LINK_TYPE_2,
'folder');
733 foreach ($folder_links as $link_info) {
734 if (isset($bc_parents[$link_info[
'minorid']])) {
735 $bc_folder = $GLOBALS[
'SQ_SYSTEM']->am->getLinks($link_info[
'minorid'], SQ_LINK_TYPE_2,
'bodycopy');
736 foreach ($bc_folder as $bc_link_info) {
737 if (isset($parents[$bc_link_info[
'minorid']])) {
738 $bodycopies[] = $bc_link_info[
'value'];
744 if (empty($bodycopies)) {
745 parent::onRequestKeywords($broadcaster, $vars);
750 foreach ($bodycopies as $bodycopy) {
751 if (!isset($this->keywords[$bodycopy])) {
753 $bodycopy =
'default_format';
755 foreach ($this->keywords[$bodycopy] as $keyword) {
756 $keywords[$keyword] = ucwords(str_replace(
'_',
' ', $keyword));
760 $vars[
'keywords'] = array_merge($vars[
'keywords'], $keywords);
777 $keywords = $bodycopy->getKeywords();
780 foreach ($keywords as $keyword) {
800 $results = array_get_index($search_results,
'results', Array());
802 $mode = htmlspecialchars(array_get_index($_REQUEST,
'mode',
'results'), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
804 $keywords = $bodycopy->getKeywords();
807 $this->_tmp[
'initial_results'] = $results;
809 foreach ($keywords as $keyword) {
811 $replaces[$keyword] = $replacement;
832 $default_fluster = Array(
'category' => Array(
'type' => Array(),
'topic' => Array(),
'site' => Array()));
833 $default_summary = Array(
'summary' => Array(),
'fluster' => $default_fluster,
'spell' => Array(),
'featured' => Array());
834 $results = array_get_index($search_results,
'results', Array());
835 $summary = array_get_index($search_results,
'summary', $default_summary);
836 $params = array_get_index($search_results,
'params', Array());
839 $mode = htmlspecialchars(array_get_index($_REQUEST,
'mode',
'results'), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
843 foreach ($_GET as $query_name => $query_value) {
845 if (!in_array($query_name, Array(
'mode',
'current_result_page',
'results_per_page'))) {
846 if (is_array($query_value)) {
847 foreach ($query_value as $value_index => $value_contents) {
848 $queries .=
'&'.urlencode($query_name).
'['.urlencode($value_index).
']='.urlencode($value_contents);
851 $queries .=
'&'.urlencode($query_name).
'='.urlencode($query_value);
858 $num_per_page = array_get_index($summary[
'summary'],
'num_ranks', 10);
859 $start_record = array_get_index($summary[
'summary'],
'currstart', 1);
860 $last_record = array_get_index($summary[
'summary'],
'currend', 1);
861 $total_result = array_get_index($summary[
'summary'],
'total_matching', 0);
862 $total_pages_main = floor($total_result / $num_per_page);
863 $total_pages = $total_pages_main + (($total_result % $num_per_page == 0) ? 0 : 1);
864 $fully_result = array_get_index($summary[
'summary'],
'fully_matching', 0);
865 $partial_result = array_get_index($summary[
'summary'],
'partially_matching', 0);
866 $current_result_page = floor($last_record / $num_per_page);
867 $current_result_page = (($last_record % $num_per_page) != 0) ? $current_result_page+1 : $current_result_page;
868 $category = array_get_index($summary[
'fluster'],
'category', Array(
'type' => Array(),
'topic' => Array(),
'site' => Array()));
869 $category_type = array_get_index($category, $type, Array());
870 $keyword = parse_keyword($keyword, $modifiers);
872 $replacement =
'%'.$keyword.
'%';
873 if (strpos($keyword,
'page_list') === 0) {
875 $show_pages = substr($keyword, 9);
876 $show_pages = ltrim($show_pages,
'_');
877 if (empty($show_pages) || $show_pages > $total_pages) {
878 $show_pages = $total_pages;
880 $replacement = $this->_paintSlidingPageNavigation($mode, $current_result_page, $total_pages, $show_pages, $num_per_page, $queries);
881 }
else if (strpos($keyword,
'result_meta') === 0) {
883 $metadata_class = substr($keyword, 12, 1);
885 if ($metadata_class !==
'S') {
886 $metadata_field =
'meta_'.$metadata_class;
887 $replacement = array_get_index(array_get_index($results, $index, Array()), $metadata_field,
'');
895 $this->_printResultList($search_results);
896 $replacement = ob_get_contents();
900 case 'fluster_category_type':
902 $fluster_category_type = array_get_index($category,
'type', Array());
903 if (!empty($summary[
'fluster']) && !empty($fluster_category_type)) {
906 $replacement = ob_get_contents();
911 case 'fluster_category_topic':
913 $fluster_category_type = array_get_index($category,
'topic', Array());
914 if (!empty($summary[
'fluster']) && !empty($fluster_category_type)) {
917 $replacement = ob_get_contents();
922 case 'fluster_category_site':
924 $fluster_category_type = array_get_index($category,
'site', Array());
925 if (!empty($summary[
'fluster']) && !empty($fluster_category_type)) {
928 $replacement = ob_get_contents();
933 case 'fluster_current_term':
935 $navigation = array_get_index($summary[
'fluster'],
'navigation', Array());
936 if (!empty($navigation)) {
937 $last_record = array_pop($navigation);
938 $replacement = array_get_index($last_record,
'name',
'');
942 case 'fluster_navigation':
943 $navigation = array_get_index($summary[
'fluster'],
'navigation', Array());
945 echo
'<div id="fluster_navigation">';
946 foreach ($navigation as $index => $nav) {
950 $replacement = ob_get_contents();
954 case 'result_featured':
956 if (!empty($summary[
'featured'])) {
958 $featured = array_get_index($summary,
'featured', Array());
959 if (!empty($featured)) {
960 foreach ($featured as $index => $feature) {
962 $replacement = ob_get_contents();
969 case 'current_result_page':
970 $replacement = $current_result_page;
973 case 'current_result_page_start':
974 $replacement = $start_record;
977 case 'current_result_page_end':
978 $replacement = $last_record;
982 $replacement = $total_result;
985 case 'result_count_fully':
986 $replacement = $fully_result;
989 case 'result_count_partially':
990 $replacement = $partial_result;
993 case 'result_count_pages':
994 $replacement = $total_pages;
997 case 'result_per_page':
998 $replacement = $num_per_page;
1001 case 'result_page_index':
1002 $replacement = $this->_paintSlidingPageNavigation($mode, $current_result_page, $total_pages, $total_pages, $num_per_page, $queries);
1005 case 'previous_result_page_link':
1006 if ($current_result_page <= 1) {
1007 $replacement = htmlspecialchars($this->
attr(
'prev_page_text'), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
1009 $replacement =
'<a href="'.$this->getSearchURL().
'?'.htmlspecialchars(
'mode='.$mode.
'¤t_result_page='.($current_result_page - 1).
'&results_per_page='.$num_per_page.$queries).
'">'.htmlspecialchars($this->
attr(
'prev_page_text'), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET).
'</a>';
1013 case 'next_result_page_link':
1014 if ($current_result_page >= $total_pages) {
1015 $replacement = htmlspecialchars($this->
attr(
'next_page_text'), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
1017 $replacement =
'<a href="'.$this->getSearchURL().
'?'.htmlspecialchars(
'mode='.$mode.
'¤t_result_page='.($current_result_page + 1).
'&results_per_page='.$num_per_page.$queries).
'">'.htmlspecialchars($this->
attr(
'next_page_text'), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET).
'</a>';
1021 case 'previous_result_page_href':
1022 if ($current_result_page <= 1) {
1025 $replacement = $this->
getSearchURL().
'?'.htmlspecialchars(
'mode='.$mode.
'¤t_result_page='.($current_result_page - 1).
'&results_per_page='.$num_per_page.$queries);
1029 case 'next_result_page_href':
1030 if ($current_result_page >= $total_pages - 1) {
1033 $replacement = $this->
getSearchURL().
'?'.htmlspecialchars(
'mode='.$mode.
'¤t_result_page='.($current_result_page + 1).
'&results_per_page='.$num_per_page.$queries);
1037 case 'initial_layout':
1042 $replacement = array_get_index(array_get_index($results, $index, Array()),
'rank',
'');
1045 case 'result_score':
1046 $replacement = array_get_index(array_get_index($results, $index, Array()),
'score',
'');
1049 case 'result_title':
1050 $replacement = array_get_index(array_get_index($results, $index, Array()),
'title',
'');
1053 case 'result_summary':
1054 $replacement = array_get_index(array_get_index($results, $index, Array()),
'summary',
'');
1058 $replacement = array_get_index(array_get_index($results, $index, Array()),
'live_url',
'');
1062 $replacement = array_get_index(array_get_index($results, $index, Array()),
'date',
'');
1065 case 'result_url_click_event':
1067 $field_name = $prefix.
'_search_query';
1068 $query = htmlspecialchars(array_get_index($_REQUEST, $field_name,
''), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
1069 $rank = array_get_index(array_get_index($results, $index, Array()),
'rank',
'');
1070 $url = array_get_index(array_get_index($results, $index, Array()),
'live_url',
'');
1072 $replacement = $this->_getClickLoggingJavascript($query, $rank, $url);
1076 case 'result_url_click_js':
1078 $field_name = $prefix.
'_search_query';
1079 $query = htmlspecialchars(array_get_index($_REQUEST, $field_name,
''), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
1080 $rank = array_get_index(array_get_index($results, $index, Array()),
'rank',
'');
1081 $url = array_get_index(array_get_index($results, $index, Array()),
'live_url',
'');
1083 $replacement = $this->_getClickLoggingJavascript($query, $rank, $url, FALSE);
1087 case 'result_name_linked':
1089 $field_name = $prefix.
'_search_query';
1090 $query = htmlspecialchars(array_get_index($_REQUEST, $field_name,
''), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
1091 $rank = array_get_index(array_get_index($results, $index, Array()),
'rank',
'');
1092 $title = array_get_index(array_get_index($results, $index, Array()),
'title',
'');
1093 $url = array_get_index(array_get_index($results, $index, Array()),
'live_url',
'');
1094 if (!empty($title) && !empty($url)) {
1095 $js = $this->_getClickLoggingJavascript($query, $rank, $url);
1096 $replacement =
'<a href="'.$url.
'" '.$js.
'>'.$title.
'</a>';
1100 case 'result_cache_url':
1101 $search_type = $this->
attr(
'search_type');
1103 if ($search_type ==
'web') {
1105 $replacement = array_get_index(array_get_index($results, $index, Array()),
'cache_url',
'');
1110 $replacement = easy_filesize(array_get_index(array_get_index($results, $index, Array()),
'filesize',
''));
1114 $replacement = array_get_index(array_get_index($results, $index, Array()),
'filetype',
'');
1117 case 'featured_trigger':
1118 $current_feature = array_get_index($summary[
'featured'], $index, Array());
1119 $replacement = array_get_index($current_feature,
'fp_trigger',
'');
1122 case 'featured_url':
1123 $current_feature = array_get_index($summary[
'featured'], $index, Array());
1124 $replacement = array_get_index($current_feature,
'fp_link',
'');
1127 case 'featured_title':
1128 $current_feature = array_get_index($summary[
'featured'], $index, Array());
1129 $replacement = array_get_index($current_feature,
'fp_title',
'');
1132 case 'featured_summary':
1133 $current_feature = array_get_index($summary[
'featured'], $index, Array());
1134 $replacement = array_get_index($current_feature,
'fp_desc',
'');
1137 case 'fluster_category_name':
1138 $replacement = ucwords($type);
1141 case 'fluster_current_term':
1142 $navigation = array_get_index($summary[
'fluster'],
'navigation', Array());
1144 if (!empty($navigation)) {
1145 $last_record = array_pop($navigation);
1146 $replacement = array_get_index($last_record,
'name',
'');
1150 case 'fluster_navigation':
1151 $navigation = array_get_index($summary[
'fluster'],
'navigation', Array());
1153 echo
'<div id="fluster_navigation">';
1154 foreach ($navigation as $index => $nav) {
1158 $replacement = ob_get_contents();
1162 case 'fluster_list':
1165 if (!empty($category[$type])) {
1166 echo
'<div id="fluster_category">';
1169 foreach ($category[$type] as $index => $cluster) {
1170 if ((
string)$index !=
'more') {
1176 if ($this->
attr(
'show_fluster_more')) {
1177 if (isset($category[$type][
'more']) && $category[$type][
'more']) {
1179 $query_cluster = $type.
'_max_clusters';
1180 $max_attr =
'more_'.$type.
'_num';
1181 $max_clusters = $this->
attr($max_attr);
1182 $min_attr =
'less_'.$type.
'_num';
1183 $min_clusters = $this->
attr($min_attr);
1184 $cluster_query = $this->
getPrefix().
'_'.$query_cluster.
'='.$max_clusters;
1185 $cluster_name = $this->
attr(
'more_'.$type.
'_text');
1189 foreach ($_GET as $query_name => $query_value) {
1190 if ($query_name ==
'current_result_page')
continue;
1191 if (is_array($query_value)) {
1192 foreach ($query_value as $value_index => $value_contents) {
1193 $queries .=
'&'.$query_name.
'['.$value_index.
']='.$value_contents;
1196 $current_query = $query_name.
'='.$query_value;
1197 $queries .=
'&'.$current_query;
1199 if (strpos($current_query, $cluster_query) === 0) {
1200 $cluster_query = $this->
getPrefix().
'_'.$query_cluster.
'='.$min_clusters;
1201 $cluster_name = $this->
attr(
'less_'.$type.
'_text');
1207 if (strpos($queries,
'&') === 0) {
1208 $queries = substr($queries, 1);
1210 $url = $this->getSearchUrl().
'?'.htmlspecialchars($queries.
'&'.$cluster_query, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
1213 echo
'<a href="'.$url.
'">'.htmlspecialchars($cluster_name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET).
'</a>';
1218 $query_cluster = $type.
'_max_clusters';
1219 $max_attr =
'more_'.$type.
'_num';
1220 $max_clusters = $this->
attr($max_attr);
1221 $cluster_query = $this->
getPrefix().
'_'.$query_cluster.
'='.$max_clusters;
1222 $cluster_name = $this->
attr(
'less_'.$type.
'_text');
1223 foreach ($_GET as $query_name => $query_value) {
1224 if ($query_name ==
'current_result_page')
continue;
1225 if (is_array($query_value)) {
1226 foreach ($query_value as $value_index => $value_contents) {
1227 $queries .=
'&'.$query_name.
'['.$value_index.
']='.$value_contents;
1230 $current_query = $query_name.
'='.$query_value;
1231 if ($current_query != $cluster_query) {
1232 $queries .=
'&'.$current_query;
1240 if (strpos($queries,
'&') === 0) {
1241 $queries = substr($queries, 1);
1243 $url = $this->getSearchUrl().
'?'.htmlspecialchars($queries, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
1247 echo
'<a href="'.$url.
'">'.htmlspecialchars($cluster_name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET).
'</a>';
1253 $replacement = ob_get_contents();
1257 case 'cluster_name':
1258 $replacement = array_get_index(array_get_index($category_type, $index, Array()),
'name',
'');
1264 $url = array_get_index(array_get_index($category_type, $index, Array()),
'href',
'');
1265 $query = array_get_index(array_get_index($category_type, $index, Array()),
'query',
'');
1267 $parts = $this->_getQueryVars($url);
1269 $query_found = FALSE;
1270 foreach ($parts as $switch => $param) {
1271 if (strpos($switch,
'query') === 0) {
1272 $queries[$this->
getPrefix().
'_search_query'] = $param;
1273 $query_found = TRUE;
1275 $queries[$this->
getPrefix().
'_'.$switch] = $param;
1281 $queries[$this->
getPrefix().
'_submit_button'] = $this->
attr(
'submit_button_text');
1282 $queries[
'mode'] =
'results';
1286 if (!empty($queries)) {
1288 foreach ($queries as $switch => $param) {
1289 $get_vars .=
'&'.$switch.
'='.$param;
1292 $get_vars = substr($get_vars, 1);
1293 $get_vars = htmlspecialchars($get_vars, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
1296 }
else if (!empty($query)) {
1298 $query_found = FALSE;
1299 $url = array_get_index($_SERVER,
'QUERY_STRING',
'');
1300 $parts = $this->_getQueryVars($url);
1301 foreach ($parts as $switch => $param) {
1302 if ($switch == $this->
getPrefix().
'_search_query') {
1303 $queries[$this->
getPrefix().
'_search_query'] = $query;
1304 $query_found = TRUE;
1306 $queries[$switch] = $param;
1312 $queries[$this->
getPrefix().
'_submit_button'] = $this->
attr(
'submit_button_text');
1313 $queries[
'mode'] =
'results';
1317 if (!empty($queries)) {
1319 foreach ($queries as $switch => $param) {
1320 if ($switch ==
'current_result_page')
continue;
1321 $get_vars .=
'&'.$switch.
'='.$param;
1324 $get_vars = substr($get_vars, 1);
1325 $get_vars = htmlspecialchars($get_vars, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
1329 $replacement = $cluster_url;
1332 case 'cluster_count':
1333 $replacement = array_get_index(array_get_index($category_type, $index, Array()),
'count',
'');
1336 case 'navigation_name':
1337 $navigation = array_get_index($summary[
'fluster'],
'navigation', Array());
1338 $current_element = array_get_index($navigation, $index, Array());
1339 $replacement = array_get_index($current_element,
'name',
'');
1342 case 'navigation_url':
1344 $navigation = array_get_index($summary[
'fluster'],
'navigation', Array());
1346 $current_element = array_get_index($navigation, $index, Array());
1348 $url = array_get_index($current_element,
'url',
'');
1349 if (!empty($url) && (strpos($url,
'&') !== FALSE)) {
1350 $query_vars = $this->_getQueryVars($url);
1351 $query_term = array_get_index($query_vars,
'query_prox',
'');
1352 if (!empty($query_term)) {
1354 $replacement .=
'?'.$this->getPrefix().
'_search_query='.$query_term;
1355 $replacement .=
'&'.$this->getPrefix().
'_submit_button='.$this->
attr(
'submit_button_text');
1356 $replacement .=
'&mode=results';
1367 apply_keyword_modifiers($replacement, $modifiers, Array(
'assetid' => $this->
id));
1369 return $replacement;
1388 if (strpos($keyword,
'metadata_scope') === 0) {
1389 $class = str_replace(
'metadata_scope_',
'', $keyword);
1390 $fm = $GLOBALS[
'SQ_SYSTEM']->am->getSystemAsset(
'funnelback_manager');
1391 $all_class = $fm->getMetadataAliases();
1392 if (array_key_exists($class, $all_class)) {
1394 $current_class =
'';
1395 $all_current_class = array_get_index($_GET, $prefix.
'_metadata_scope', Array());
1396 if (isset($all_current_class[$class])) $current_class = $all_current_class[$class];
1398 text_box($prefix.
'_metadata_scope['.$class.
']', $current_class);
1399 $replacement = ob_get_contents();
1402 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($fm, TRUE);
1403 }
else if (strpos($keyword,
'metadata_logic') === 0) {
1404 $class = str_replace(
'metadata_logic_',
'', $keyword);
1405 $fm = $GLOBALS[
'SQ_SYSTEM']->am->getSystemAsset(
'funnelback_manager');
1406 $all_metadata_config = array_get_index($fm->attr(
'metamap'), $this->
attr(
'collection'), Array());
1407 $metadata_config = Array();
1408 foreach($all_metadata_config as $config) {
1409 if (isset($config[
'alias']) && $config[
'alias'] == $class) {
1410 $metadata_config = $config;
1414 $all_class = $fm->getMetadataAliases();
1415 if (array_key_exists($class, $all_class)) {
1417 $current_logic = array_get_index($metadata_config,
'word_logic', 2);
1418 $all_current_logic = array_get_index($_GET, $prefix.
'_metadata_logic', Array());
1419 if (isset($all_current_logic[$class])) $current_logic = $all_current_logic[$class];
1420 $logic_options = Array(
'Exclude',
'Include any',
'Include all');
1422 combo_box($prefix.
'_metadata_logic['.$class.
']', $logic_options, FALSE, $current_logic);
1423 $replacement = ob_get_contents();
1426 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($fm, TRUE);
1430 case 'current_query_term':
1431 $field_name = $prefix.
'_search_query';
1432 $current_value = htmlspecialchars(array_get_index($_REQUEST, $field_name,
''), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
1434 $replacement = $current_value;
1437 case 'search_query':
1438 $field_name = $prefix.
'_search_query';
1439 $current_value = htmlspecialchars(array_get_index($_REQUEST, $field_name,
''), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
1440 $dynamic_query = array_get_index($extra,
'query',
'');
1441 if (!empty($dynamic_query) && empty($current_value)) {
1442 $current_value = $dynamic_query;
1445 if($this->
attr(
'disable_keyword_replacements') && !empty($current_value)) {
1446 $current_value = $this->_sanitizeQueries($current_value);
1450 $replacement =
'<input type="text" name="'.$field_name.
'" id="'.$field_name.
'" value="'.$current_value.
'" />';
1453 case 'search_logic':
1454 $current_sort_logic = array_get_index($_GET, $prefix.
'_search_logic', $this->attr(
'word_logic'));
1455 $logic_options = Array(
'Exclude' ,
'Include any',
'Include all');
1457 combo_box($this->
getPrefix().
'_search_logic', $logic_options, FALSE, $current_sort_logic);
1458 $replacement = ob_get_contents();
1462 case 'search_scope':
1463 $field_name = $prefix.
'_search_scope';
1464 $scope = $this->
attr(
'scope');
1465 $current_value = htmlspecialchars(array_get_index($_REQUEST, $field_name,
''), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
1466 $dynamic_scope = array_get_index($extra,
'scope',
'');
1467 if (!empty($dynamic_scope) && empty($current_value)) {
1468 $current_value = $dynamic_scope;
1470 if (empty($current_value)) {
1471 $current_value = $this->
attr(
'default_scope');
1476 foreach ($scope as $key => $value) {
1478 if ($key == $current_value) {
1481 radio_button($field_name, $key, $checked);
1482 label($value, $field_name);
1484 $replacement = ob_get_contents();
1490 $current_sort = $this->
attr(
'sort_order');
1491 if (isset($_REQUEST[$this->
getPrefix().
'_search_sort'])) {
1493 $current_sort = htmlspecialchars($_REQUEST[$this->
getPrefix().
'_search_sort'], ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
1496 combo_box($this->
getPrefix().
'_search_sort', $sort_options, FALSE, $current_sort);
1497 $replacement = ob_get_contents();
1502 case 'spell_suggestion':
1504 if (!empty($spelling)) {
1506 $current_term = htmlspecialchars(array_get_index($_REQUEST, $this->
getPrefix().
'_search_query',
''), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
1507 $spell_term = array_get_index($spelling,
'text',
'');
1508 $spell_term = trim($spell_term);
1509 if ($current_term != $spell_term) {
1512 $replacement = ob_get_contents();
1520 $spell_url = array_get_index($spelling,
'url',
'');
1522 $returned_get_vars = $this->_getQueryVars($spell_url);
1524 foreach ($returned_get_vars as $var_name => $var_value) {
1525 if ($var_name ==
'query') {
1526 $var_name =
'search_query';
1528 $get_vars .=
'&'.$this->getPrefix().
'_'.$var_name.
'='.$var_value;
1531 if (!empty($get_vars)) $url =
'?mode=results'.$get_vars;
1536 $replacement = array_get_index($spelling,
'text',
'');
1539 case 'search_button':
1540 case 'submit_button':
1542 foreach ($_GET as $index => $value) {
1543 if ((strpos($index, $prefix.
'_cluster') !== FALSE) || $index == $prefix.
'_stem') {
1544 $count = str_replace($prefix.
'_cluster',
'', $index);
1545 hidden_field($index,
'');
1551 $field_name = $prefix.
'_submit_button';
1553 $this->_tmp[
'prints_submit'] = TRUE;
1557 $mode = htmlspecialchars(array_get_index($_REQUEST,
'mode',
'initial'), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
1558 if ($mode ==
'initial') {
1559 $replacement =
'<input type="submit" name="'.$field_name.
'"
1560 value="'.$this->
attr(
'submit_button_text').
'" />';
1562 $replacement =
'<input type="submit" name="'.$field_name.
'" onclick="listing_form = document.getElementById(\''.$this->
getPrefix().
'\');
1563 if (typeof listing_form.current_result_page != \
'undefined\' ) listing_form.current_result_page.value=\'1\';
1564 if (typeof listing_form.mode != \'undefined\') listing_form.mode.value = \'results\';
1566 " value="'.$this->attr(
'submit_button_text').
'" />';
1572 $replacement =
'<input type="text" name="'.$prefix.
'_extra_field" id="'.$prefix.
'_extra_field" style="display:none" />'.$replacement;
1575 case 'results_per_page':
1577 $field_name =
'results_per_page';
1578 $results_per_page = htmlspecialchars(array_get_index($_REQUEST, $field_name, $this->
_getNumPerPage()), ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET);
1580 $replacement =
'<input type="text" name="'.$field_name.
'" onchange="listing_form = document.getElementById(\''.$this->
getPrefix().
'\');
1581 listing_form.results_per_page.value = this.value;
1582 " value="'.$results_per_page.'" size="5
" />';
1586 $replacement = $this->getKeywordReplacement($keyword);
1591 return $replacement;
1593 }//end getGeneralReplacement()
1602 public function getSortOptions()
1605 'rank' => translate('funnelback_sort_rank'),
1606 'date' => translate('funnelback_sort_date'),
1607 'title' => translate('funnelback_sort_title'),
1608 'url' => translate('funnelback_sort_url'),
1611 }//end getSortOptions()
1627 private function _paintSlidingPageNavigation($mode, $current_result_page, $total_pages, $show_pages, $num_per_page, $queries='')
1630 if ($total_pages == $show_pages) {
1632 $end_page = $total_pages;
1634 $start_page = max(1, min(($current_result_page - (int) floor($show_pages / 2)), $total_pages - $show_pages + 1));
1635 $end_page = min($total_pages, $start_page + $show_pages - 1);
1638 for ($i = $start_page; $i <= $end_page; $i++) {
1639 if ($replacement != '') $replacement .= ' ';
1641 if ($i == $current_result_page) {
1642 $replacement .= '<b>'.$i.'</b>';
1644 $replacement .= '<a href="'.$this->getSearchURL().'?
'.htmlspecialchars('mode=
'.$mode.'¤t_result_page=
'.$i.'&results_per_page=
'.$num_per_page.$queries).'">'.$i.'</a>';
1648 return $replacement;
1650 }//end _paintSlidingPageNavigation()
1653 // -- BODYCOPY FUNCTIONS -- //
1667 public function &getBodycopy($name)
1671 if (array_key_exists($name, $this->bodycopies)) {
1672 $am =& $GLOBALS['SQ_SYSTEM']->am;
1673 $link = $am->getLink($this->id, SQ_LINK_TYPE_2, 'bodycopy', TRUE, $name, 'major', '1');
1674 $bodycopy = $am->getAsset($link['minorid'], $link['minor_type_code']);
1679 }//end getBodycopy()
1693 public function &getBodycopyContents($name, $replacements=Array())
1695 $bodycopy =& $this->getBodycopy($name);
1696 if (is_null($bodycopy)) return '';
1698 $bodycopy->setKeywordReplacements($replacements);
1701 $bodycopy->printBody();
1702 $html = ob_get_contents();
1707 }//end getBodycopyContents()
1716 public function getFormatFolderLink()
1718 $link = $GLOBALS['SQ_SYSTEM']->am->getLinks($this->id, SQ_LINK_TYPE_2 | SQ_LINK_TYPE_3, 'folder', TRUE, 'major', 'format_folder');
1719 return (!empty($link)) ? $link[0] : Array();
1721 }//end getFormatFolderLink()
1730 public function &getFormatFolder()
1734 $link = $this->getFormatFolderLink();
1735 if (!empty($link)) {
1736 $folder = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['minorid'], $link['minor_type_code']);
1741 }//end getFormatFolder()
1752 public function getFormatBodycopyLink($link_value)
1754 $format_folder =& $this->getFormatFolder();
1755 if (is_null($format_folder)) return Array();
1757 $link = $GLOBALS['SQ_SYSTEM']->am->getLinks($format_folder->id, SQ_LINK_TYPE_2 | SQ_LINK_TYPE_3, 'bodycopy', TRUE, 'major', $link_value);
1758 return (!empty($link)) ? $link[0] : Array();
1760 }//end getFormatBodycopyLink()
1774 public function &getFormatBodycopy($link_value)
1778 $bodycopy_link = $this->getFormatBodycopyLink($link_value);
1779 if (!empty($bodycopy_link)) {
1780 $bodycopy = $GLOBALS['SQ_SYSTEM']->am->getAsset($bodycopy_link['minorid'], $bodycopy_link['minor_type_code']);
1785 }//end getFormatBodycopy()
1788 // --- RESULT LISTING FUNCTIONS --- //
1802 private function _printResultList($search_results)
1804 $todo = array_get_index($search_results, 'results', Array());
1805 if (empty($todo)) return;
1807 foreach ($todo as $index => $result) {
1808 $this->_printResult($search_results, $index);
1811 }//end _printResultList()
1823 private function _printResult($search_results, $index)
1825 $results = array_get_index($search_results, 'results', Array());
1827 // Setting the Default Type Folder
1828 if (!isset($this->_tmp['type_folder_id'])) {
1829 $type_folder = $this->getFolder('type_format');
1830 $this->_tmp['type_folder_id'] = $type_folder->id;
1833 // Getting the Default Format Bodycopy
1834 if (!isset($this->_tmp['default_format_bc'])) {
1835 $link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->_tmp['type_folder_id'], SQ_LINK_TYPE_2, 'bodycopy', TRUE, 'default_format');
1837 $this->_tmp['default_format_bc'] = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['minorid'], 'bodycopy');
1839 trigger_localised_error('FNB0004', E_USER_WARNING, 'Default');
1843 $bodycopy = $this->_tmp['default_format_bc'];
1845 // Check for a customised layout for this item only
1846 $filetype = array_get_index($results[$index], 'filetype', '');
1847 $custom_type = $GLOBALS['SQ_SYSTEM']->am->getLink($this->_tmp['type_folder_id'], SQ_LINK_TYPE_2, 'bodycopy', TRUE, $filetype);
1848 if (!empty($custom_type)) {
1849 $bodycopy = $GLOBALS['SQ_SYSTEM']->am->getAsset($custom_type['minorid'], 'bodycopy');
1852 // by the time we reach this point we already have a bodycopy for this asset
1853 $bc_keywords = $bodycopy->getKeywords();
1854 $keywords = Array();
1855 foreach ($bc_keywords as $keyword) {
1856 $keywords[$keyword] = $this->getFunnelbackReplacement($keyword, $search_results, $index);
1859 $bodycopy->setKeywordReplacements($keywords);
1860 $bodycopy->printBody();
1862 }//end _printResult()
1874 public function printFeaturedList($results, $index)
1876 // Setting the Default Type Folder
1877 if (!isset($this->_tmp['type_folder_id'])) {
1878 $type_folder = $this->getFolder('type_format');
1879 $this->_tmp['type_folder_id'] = $type_folder->id;
1882 // Getting the Default Format Bodycopy
1883 if (!isset($this->_tmp['featured_format_bc'])) {
1884 $link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->_tmp['type_folder_id'], SQ_LINK_TYPE_2, 'bodycopy', TRUE, 'featured_format');
1886 $this->_tmp['featured_format_bc'] = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['minorid'], 'bodycopy');
1888 trigger_localised_error('FNB0004', E_USER_WARNING, 'Featured');
1892 $bodycopy = $this->_tmp['featured_format_bc'];
1894 // by the time we reach this point we already have a bodycopy for this asset
1895 $bc_keywords = $bodycopy->getKeywords();
1896 $keywords = Array();
1897 foreach ($bc_keywords as $keyword) {
1898 $keywords[$keyword] = $this->getFunnelbackReplacement($keyword, $results, $index);
1901 $bodycopy->setKeywordReplacements($keywords);
1902 $bodycopy->printBody();
1904 }//end printFeaturedList()
1916 public function printFlusterList($results, $type='site')
1918 // Getting the Fluster Format folder
1919 if (!isset($this->_tmp['fluster_folder_id'])) {
1920 $fluster_folder = $this->getFolder('fluster_format');
1921 $this->_tmp['fluster_folder_id'] = $fluster_folder->id;
1924 // Getting the Fluster Default Format Bodycopy
1925 if (!isset($this->_tmp['fluster_format_bc'])) {
1926 $link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->_tmp['fluster_folder_id'], SQ_LINK_TYPE_2, 'bodycopy', TRUE, 'context_format');
1928 $this->_tmp['fluster_format_bc'] = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['minorid'], 'bodycopy');
1930 trigger_localised_error('FNB0004', E_USER_WARNING, 'Context');
1934 $bodycopy = $this->_tmp['fluster_format_bc'];
1936 // by the time we reach this point we already have a bodycopy for this asset
1937 $bc_keywords = $bodycopy->getKeywords();
1938 $keywords = Array();
1939 foreach ($bc_keywords as $keyword) {
1940 $keywords[$keyword] = $this->getFunnelbackReplacement($keyword, $results, 0, $type);
1943 $bodycopy->setKeywordReplacements($keywords);
1944 $bodycopy->printBody();
1946 }//end printFlusterList()
1959 public function printClusterList($results, $index, $type='site')
1961 // Getting the Cluster Format folder
1962 if (!isset($this->_tmp['fluster_folder_id'])) {
1963 $fluster_folder = $this->getFolder('fluster_format');
1964 $this->_tmp['fluster_folder_id'] = $fluster_folder->id;
1967 // Getting the Cluster Default Format Bodycopy
1968 if (!isset($this->_tmp['cluster_format_bc'])) {
1969 $link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->_tmp['fluster_folder_id'], SQ_LINK_TYPE_2, 'bodycopy', TRUE, 'cluster_format');
1971 $this->_tmp['cluster_format_bc'] = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['minorid'], 'bodycopy');
1973 trigger_localised_error('FNB0004', E_USER_WARNING, 'Cluster');
1977 $bodycopy = $this->_tmp['cluster_format_bc'];
1979 // by the time we reach this point we already have a bodycopy for this asset
1980 $bc_keywords = $bodycopy->getKeywords();
1981 $keywords = Array();
1982 // Go through and replace keywords
1983 foreach ($bc_keywords as $keyword) {
1984 $keywords[$keyword] = $this->getFunnelbackReplacement($keyword, $results, $index, $type);
1987 $bodycopy->setKeywordReplacements($keywords);
1988 $bodycopy->printBody();
1990 }//end printClusterList()
2002 public function printNavigationList($results, $index)
2004 // Getting the Fluster Format folder
2005 if (!isset($this->_tmp['fluster_folder_id'])) {
2006 $fluster_folder = $this->getFolder('fluster_format');
2007 $this->_tmp['fluster_folder_id'] = $fluster_folder->id;
2010 // Getting the Navigation Default Format Bodycopy
2011 if (!isset($this->_tmp['nav_format_bc'])) {
2012 $link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->_tmp['fluster_folder_id'], SQ_LINK_TYPE_2, 'bodycopy', TRUE, 'navigation_format');
2014 $this->_tmp['nav_format_bc'] = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['minorid'], 'bodycopy');
2016 trigger_localised_error('FNB0004', E_USER_WARNING, 'Navigation');
2020 $bodycopy = $this->_tmp['nav_format_bc'];
2022 // by the time we reach this point we already have a bodycopy for this asset
2023 $bc_keywords = $bodycopy->getKeywords();
2024 $keywords = Array();
2025 foreach ($bc_keywords as $keyword) {
2026 $keywords[$keyword] = $this->getFunnelbackReplacement($keyword, $results, $index);
2029 $bodycopy->setKeywordReplacements($keywords);
2030 $bodycopy->printBody();
2032 }//end printNavigationList()
2043 public function printSpellList($results)
2045 // Getting the Spell Formats folder
2046 if (!isset($this->_tmp['spell_folder_id'])) {
2047 $spell_folder = $this->getFolder('spell_format');
2048 $this->_tmp['spell_folder_id'] = $spell_folder->id;
2051 // Getting the Spell Default Format Bodycopy
2052 if (!isset($this->_tmp['spell_format_bc'])) {
2053 $link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->_tmp['spell_folder_id'], SQ_LINK_TYPE_2, 'bodycopy', TRUE, 'spell_format');
2055 $this->_tmp['spell_format_bc'] = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['minorid'], 'bodycopy');
2057 trigger_localised_error('FNB0004', E_USER_WARNING, 'Spell');
2061 $bodycopy = $this->_tmp['spell_format_bc'];
2063 // by the time we reach this point we already have a bodycopy for this asset
2064 $bc_keywords = $bodycopy->getKeywords();
2065 $keywords = Array();
2066 foreach ($bc_keywords as $keyword) {
2067 $keywords[$keyword] = $this->getGeneralReplacement($keyword, Array(), $results);
2070 $bodycopy->setKeywordReplacements($keywords);
2071 $bodycopy->printBody();
2073 }//end printSpellList()
2076 // --- PRIVATE FUNCTIONS --- //
2087 private function _getQueryVars($query_string)
2089 // get rid of any leadin '?' if any
2090 $query_string = ltrim($query_string, '?');
2092 // The regex expression expects a start & so let us do that first
2093 if (strpos($query_string, '&') !== 0) {
2094 $query_string = '&'.$query_string;
2098 preg_match_all('|&([^=]+)=([^&]+)?|', $query_string, $matches);
2099 foreach ($matches[1] as $index => $query_name) {
2100 $vars[$query_name] = isset($matches[2][$index]) ? $matches[2][$index] : '';
2105 }//end _getQueryVars()
2116 public function parseURL($search)
2118 // Get the query term
2119 $query = array_get_index($search, 'query', '');
2120 $query = str_replace(' ', '+', $query);
2123 $query = str_replace('&', '', $query);
2126 $funnelback_url = $this->attr('funnelback_url');
2127 $funnelback_url = trim($funnelback_url);
2129 // Get the other vars
2130 $collection = $this->attr('collection');
2131 $scope = array_get_index($search, 'scope', '');
2132 $current_result_page = array_get_index($search, 'page', 1);
2133 $num_per_page = array_get_index($search, 'num_per_page', $this->_getNumPerPage());
2134 $cluster = array_get_index($search, 'cluster', Array());
2135 $stem = array_get_index($search, 'stem', 0);
2136 $type_max = array_get_index($search, 'type_max', 0);
2137 $topic_max = array_get_index($search, 'topic_max', 0);
2138 $site_max = array_get_index($search, 'site_max', 0);
2139 $valid_sort = Array ('date' , 'adate' , 'title' , 'dtitle' , 'size' , 'dsize' , 'url' , 'durl' , 'coll' , 'dcoll' , 'shuffle');
2140 $sort = array_get_index($search, 'sort', 'rank');
2142 // Check for required information
2143 if (empty($funnelback_url) || empty($collection)) {
2145 trigger_localised_error('FNB0003', E_USER_WARNING);
2149 // Add in the collection
2150 $url = '?collection='.urlencode($collection);
2153 if (empty($scope)) {
2154 $scope = $this->attr('default_scope');
2156 if (!empty($scope) && $scope != 'ALL') {
2157 $url .= '&scope='.urlencode($scope);
2160 // Add in the paging commands
2161 if ($current_result_page != 1) {
2162 $url .= '&start_rank='.urlencode((($current_result_page-1) * $num_per_page) + 1);
2164 if (!empty($num_per_page)) {
2165 $url .= '&num_ranks='.urlencode($num_per_page);
2168 if (!empty($cluster)) {
2169 // If flustering links where clicked
2170 $cluster_string = '';
2171 foreach ($cluster as $count => $item) {
2172 if (empty($item)) continue;
2173 $cluster_string .= '&cluster'.$count.'='.urlencode($item);
2177 foreach ($cluster as $item) {
2178 $query_string .= ' '.$item;
2180 $query_string = substr($query_string, 1);
2181 if (!empty($cluster_string)) {
2182 $url .= $cluster_string;
2183 $url .= '&query_prox='.urlencode(str_replace('+', ' ', $query));
2185 // Add in the stem var
2186 if (!empty($stem)) {
2187 $url .= '&stem='.urlencode($stem);
2190 $url .= '&query='.$query;
2194 $url .= '&query='.$query;
2197 // Fluster more/less links
2198 if (!empty($type_max)) {
2199 $url .= '&type.max_clusters='.$type_max;
2201 $url .= '&type.max_clusters='.$this->attr('less_type_num');
2203 if (!empty($topic_max)) {
2204 $url .= '&topic.max_clusters='.$topic_max;
2206 $url .= '&topic.max_clusters='.$this->attr('less_topic_num');
2208 if (!empty($site_max)) {
2209 $url .= '&site.max_clusters='.$site_max;
2211 $url .= '&site.max_clusters='.$this->attr('less_site_num');
2216 if (!empty($sort) && $sort !== 'rank' && in_array($sort, $valid_sort)) {
2217 $url .= '&sort='.$sort;
2220 // get the current user and also the assetid
2221 // of all the groups the user is in
2222 $user_info = Array($GLOBALS['SQ_SYSTEM']->user->id);
2223 $user_info = array_merge($GLOBALS['SQ_SYSTEM']->user->getUserGroups(), $user_info);
2225 $url .= '&userkeys='.implode(',', $user_info);
2227 return $funnelback_url.$url;
2240 private function _queryFunnelback($url)
2243 trigger_localised_error('FNB0003', E_USER_WARNING);
2247 $url_ok = @parse_url($url);
2249 trigger_localised_error('FNB0003', E_USER_WARNING);
2255 'CONNECTTIMEOUT' => 5,
2257 'FOLLOWLOCATION' => true,
2258 'RETURNTRANSFER' => true,
2262 'X-Forwarded-For' => $_SERVER['REMOTE_ADDR'],
2265 $urlResponse = fetch_url($url, $options, $headers);
2266 if ($urlResponse['errornumber'] != 0) {
2267 trigger_localised_error('FNB0002', E_USER_WARNING);
2271 $xml = $urlResponse['response'];
2272 $code = $urlResponse['curlinfo']['http_code'];
2274 if (empty($xml) || empty($code) || $code != '200') {
2280 }//end _queryFunnelback()
2291 private function _searchFunnelback($params)
2295 // Wha..? No params no search
2296 if (empty($params)) {
2300 // Get the params to work with
2301 $fm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('funnelback_manager');
2302 $nullquery = $fm->getNullQueryKeyword();
2303 $collection_id = $this->attr('collection');
2304 $bin_path = $fm->getFunnelbackPath().'/bin/';
2305 if (!$fm->isCollectionValid($collection_id)) {
2307 // Collection is not valid, stop the search...
2310 $coll_path = $fm->getCollectionDataPath($collection_id);
2311 $data_path = $fm->getCollectionDataPath($collection_id, 'idx');
2312 $log_file = $fm->getCollectionDataPath($collection_id, 'log').'/query.log';
2313 $thesaurus_config = $fm->getCollectionDataPath($collection_id, 'conf').'/synonyms.cfg';
2314 $search_term = array_get_index($params, 'query', '');
2315 $scope = array_get_index($params, 'scope', '');
2316 $page = array_get_index($params, 'page', 1);
2317 $num_per_page = array_get_index($params, 'num_per_page', $this->_getNumPerPage());
2318 $sort = array_get_index($params, 'sort', $this->attr('sort_order'));
2319 $metadata_scope = $this->_getMetadataScope();
2320 if (empty($scope)) {
2321 $scope = $this->attr('default_scope');
2324 // Build the command line based on params set above
2326 $query = $this->_getSearchQuery($search_term);
2327 if (empty($query)) {
2328 if ($this->attr('allow_empty')) {
2329 // 'NULL' query (basically use a string with no meaning and use ! - which match everything else)
2330 $query = $nullquery;
2331 $fluster = ''; // Flustering is disabled on a NULL query
2333 // Empty searches are not permitted
2337 // Enable flustering
2338 $fluster = $this->_getFlusterOptions($params);
2340 $command .= escapeshellarg($query.' '.$metadata_scope);
2341 $command .= ' | '.$bin_path.'padre-sw'; // Pipe the query to the search command (padre-sw)
2342 $command .= ' '.escapeshellarg($collection_id); // Index Stem aka Collection
2343 $command .= ' -res xml -SMboth -SF'.$this->_getMetadataFields().' -spelling_enabled -qlog_file='.$log_file.$fluster;
2344 $command .= ' -userkeys="'.implode(',
', $this->_getUserKeys()).'"';
2345 if (!empty($scope) && $scope != 'ALL') {
2346 $command .= ' -scope '.escapeshellarg($scope);
2349 $command .= ' -start_rank'.((($page-1) * $num_per_page) + 1);
2351 if (!empty($num_per_page)) {
2352 $command .= ' -num_ranks'.$num_per_page;
2358 $command .= ' -sort '.$sort;
2363 // Default to rank, already handled by default by Funnelback
2367 // Searching... Searching... Searching...
2368 $status = $fm->runCommand($command, $output, NULL, NULL, $data_path, Array('SITE_SEARCH_ROOT' => $coll_path));
2370 // Make sure the 'NULL' query doesn't come through in the results
2371 $output = str_replace($nullquery, '', $output);
2375 }//end _searchFunnelback()
2386 private function _querySquizSearch($search)
2388 $systemid = $this->attr('systemid');
2390 // Get the query term
2391 $query = array_get_index($search, 'query', '');
2392 $query = str_replace('&', '', $query);
2394 // Get the collection
2395 $collection = $this->attr('collection');
2397 // Get the other vars
2398 $current_result_page = array_get_index($search, 'page', 1);
2399 $num_per_page = array_get_index($search, 'num_per_page', $this->_getNumPerPage());
2400 $valid_sort = Array ('date' , 'adate' , 'title' , 'dtitle' , 'size' , 'dsize' , 'url' , 'durl' , 'coll' , 'dcoll' , 'shuffle');
2401 $sort = array_get_index($search, 'sort', 'rank');
2402 $scope = array_get_index($search, 'scope', '');
2403 $type_max = array_get_index($search, 'type_max', 0);
2404 $topic_max = array_get_index($search, 'topic_max', 0);
2405 $site_max = array_get_index($search, 'site_max', 0);
2407 // Build the options.
2409 $options['num_per_page'] = $num_per_page;
2410 $options['contextual_navigation_enabled'] = TRUE;
2411 $options['userkeys'] = $this->_getUserKeys(TRUE);
2413 // Check for required information
2414 if (empty($systemid) || empty($collection)) {
2416 trigger_localised_error('FNB0003', E_USER_WARNING);
2421 if (empty($scope)) {
2422 $scope = $this->attr('default_scope');
2424 if (!empty($scope) && $scope != 'ALL') {
2425 $options['scope'] = $scope;
2428 // Add in the paging commands
2429 if ($current_result_page != 1) {
2430 $options['start_at'] = ((($current_result_page-1) * $num_per_page) + 1);
2433 // Fluster more/less links
2434 if (!empty($type_max)) {
2435 $options['type_max_clusters'] = $type_max;
2437 $options['type_max_clusters'] = $this->attr('less_type_num');
2439 if (!empty($topic_max)) {
2440 $options['topic_max_clusters'] = $topic_max;
2442 $options['topic_max_clusters'] = $this->attr('less_topic_num');
2444 if (!empty($site_max)) {
2445 $options['site_max_clusters'] = $site_max;
2447 $options['site_max_clusters'] = $this->attr('less_site_num');
2451 if (!empty($sort) && $sort !== 'rank' && in_array($sort, $valid_sort)) {
2452 $options['sort'] = $sort;
2455 $suitem = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('suite_manager');
2456 $system = $suitem->getProduct($systemid);
2460 'query' => $suitem->encodeJson($query),
2461 'collectionid' => $collection,
2462 'options' => $suitem->encodeJson($options),
2464 if (!empty($system)) {
2465 $response = $suitem->sendRequest($systemid, 'json', 'SquizSearch', 'Search', $request);
2466 if (isset($response['curlInfo']['http_code']) === TRUE && $response['curlInfo']['http_code'] == 200) {
2467 $resultData = $response['result'];
2468 $resultData = (array) $suitem->decodeJson($resultData);
2469 $xml = (string) $resultData['result'];
2473 // Services_JSON will forcibly change Content-type header to json, which is not expected
2474 if (!headers_sent()) {
2475 header('Content-type: text/html;');
2480 }//end _querySquizSearch()
2491 private function _getUserKeys($useSuiteSystemId=FALSE)
2493 // Default to the public user keys
2494 $keys = array("'public'");
2495 $user_id = $GLOBALS['SQ_SYSTEM']->currentUserId();
2496 if (!empty($user_id)) {
2497 // Return if public user
2498 $public_user = $GLOBALS['SQ_SYSTEM']->am->getSystemAssetId('public_user');
2499 if ($user_id == $public_user) return $keys;
2501 // Collate the user and his/her groups
2502 $user = $GLOBALS['SQ_SYSTEM']->am->getAsset($user_id);
2503 if (!is_null($user)) {
2505 if ($useSuiteSystemId == TRUE) {
2506 $sm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('suite_manager');
2507 $current = $sm->getCurrentProduct();
2508 $prefix = array_get_index($current, 'systemid', '');
2509 if (!empty($prefix)) $prefix .= '://';
2512 $fm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('funnelback_manager');
2513 $keys = Array($user->id, $public_user, 'public');
2514 $groups = $user->getUserGroups();
2515 $keys = array_merge($keys, $groups);
2518 // Nasty.... but essential
2519 foreach ($keys as $index => $key) {
2520 if ($key === 'public') continue;
2521 $keys[$index] = "'".$prefix.$fm->encodeText((string) $key)."'";
2524 $userkeys = ' -userkeys="'.implode(',
', $keys).'"';
2530 }//end _getUserKeys()
2541 private function _getFlusterOptions($params)
2543 $fluster = ' -contextual_navigation_enabled';
2544 // $cluster = array_get_index($params, 'cluster', Array());
2545 // $stem = array_get_index($params, 'stem', 0);
2546 $type_max = array_get_index($params, 'type_max', 0);
2547 $topic_max = array_get_index($params, 'topic_max', 0);
2548 $site_max = array_get_index($params, 'site_max', 0);
2550 if (!empty($type_max)) {
2551 $fluster .= ' -type.max_clusters='.(int) $type_max;
2553 $fluster .= ' -type.max_clusters='.(int) $this->attr('less_type_num');
2556 if (!empty($topic_max)) {
2557 $fluster .= ' -topic.max_clusters='.(int) $topic_max;
2559 $fluster .= ' -topic.max_clusters='.(int) $this->attr('less_topic_num');
2562 if (!empty($site_max)) {
2563 $fluster .= ' -site.max_clusters='.(int) $site_max;
2565 $fluster .= ' -site.max_clusters='.(int) $this->attr('less_site_num');
2570 }//end _getFlusterOptions()
2579 private function _getMetadataFields()
2583 $fm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('funnelback_manager');
2584 $all_metadata_config = array_get_index($fm->attr('metamap'), $this->attr('collection'), Array());
2587 foreach($all_metadata_config as $metamap) {
2588 if ($metamap['alias'] !== 'S') {
2589 $fields[] = $metamap['alias'];
2593 $fields = array_unique($fields);
2595 return implode($fields);
2597 }//end _getMetadataFields()
2607 private function _getMetadataScope()
2612 $fm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('funnelback_manager');
2613 $all_metadata_config = array_get_index($fm->attr('metamap'), $this->attr('collection'), Array());
2614 $metadata_scope = array_get_index($_GET, $this->getPrefix().'_metadata_scope', Array());
2616 $default_metadata_logic = Array();
2617 foreach($all_metadata_config as $metamap) {
2618 if (array_get_index($metadata_scope, $metamap['alias'], FALSE) !== FALSE) {
2619 $default_metadata_logic[$metamap['alias']] = $metamap['word_logic'];
2622 $metadata_logic = array_get_index($_GET, $this->getPrefix().'_metadata_logic', $default_metadata_logic);
2623 foreach ($metadata_scope as $index => $metadata_terms) {
2624 $keywords = preg_split('/([\s\+\-\|\*]*"[^
"]+")[\s]*|
'.'([\s\+\-\|\*]*`[^`]+`)[\s]*|
'.'[\s]+/
', $metadata_terms, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
2625 // The query having search operator overrides the default word logic settings
2626 // NOTE: A search operator inside double quotes is part of the search keyword and does not overrides the word logic
2627 $contains_op = FALSE;
2628 foreach($keywords as $keyword) {
2629 if (preg_match('/^\s*[\+\-\|\*]\s*/
', $keyword)) {
2630 $contains_op = TRUE;
2633 $logic = array_get_index($metadata_logic, $index, array_get_index($default_metadata_logic, $index, 2));
2634 foreach($keywords as $value) {
2635 $value = trim($value);
2636 if (!empty($value)) {
2638 $scope .= ' '.preg_replace('/^([\+\-\|\*]?)
'.'([^\+\-\|\*]+)
'.'|(
".+?")|(`.+?`)$/
','$1
'.$index.':$2
', $value);
2639 } else if ($logic == '0
') {
2640 $scope .= ' -
'.$index.':
'.$value;
2641 } else if ($logic == '1
') {
2642 $group_scope .= ' '.$index.':
'.$value;
2644 $scope .= ' +
'.$index.':
'.$value;
2647 }//end foreach $keywords
2650 $scope = trim($group_scope) ? '|[
'.trim($group_scope).']
'.trim($scope) : trim($scope);
2654 }//end _getMetadataScope()
2665 private function _getSearchQuery($search_term)
2667 $keywords = preg_split('/([\s\+\-\|\*]*
"[^"]+
")[\s]*|'.'([\s\+\-\|\*]*`[^`]+`)[\s]*|'.'[\s]+/', $search_term, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
2669 // Query having search operator overrides the word logic settings
2670 foreach($keywords as $keyword) {
2671 if (preg_match('/^\s*[\+\-\|\*]\s*/', $keyword)) {
2672 return $search_term;
2676 $logic = array_get_index($_GET, $this->getPrefix().'_search_logic', $this->attr('word_logic'));
2679 foreach ($keywords as $keyword) {
2680 $keyword = trim($keyword);
2682 if (!empty($keyword)) {
2683 if ($logic == '0') {
2684 $search_query .= ' -'.$keyword;
2685 } else if ($logic == '1') {
2686 $search_query .= ' '.$keyword;
2688 $search_query .= ' +'.$keyword;
2693 return trim($search_query);
2695 }//end _getSearchQuery()
2709 private function _getClickLoggingJavascript($query, $rank, $url, $event=TRUE)
2711 // At minimum, the click logging program needs query, rank and url
2712 if (empty($query)) return '';
2713 if (empty($rank)) return '';
2714 if (empty($url)) return '';
2717 $click_event .= (($event) ? 'onclick="' : '');
2718 $click_event .= "FunnelbackSearch.clickLog('".$query."','".$rank."','".$url."'); return true;";
2719 $click_event .= (($event) ? '"' : '');
2721 return $click_event;
2723 }//end _getClickLoggingJavascript()
2732 private function _getSearchPageJavascript()
2734 $collection = $this->attr('collection');
2737 <script type="text/javascript
">
2738 var FunnelbackSearch = function() {
2741 clickLog : function(query,rank,url) {
2742 if (window.XMLHttpRequest) {
2743 var xhr = new window.XMLHttpRequest();
2745 var xhr = new ActiveXObject("Microsoft.XMLHTTP
");
2748 var getURL = '<?php echo current_url(); ?>?click=1&click_query='+query+'&click_rank='+rank+'&click_url='+url+'&click_collection=<?php echo $collection; ?>';
2749 xhr.open("GET
", getURL, true);
2756 $contents = ob_get_contents();
2761 }//end _getSearchPageJavascript()
2772 public function _stripURL($url)
2774 return str_replace('/search/xml.cgi?', '', $url);
2787 public function processSearchSummary(&$xml)
2789 $default_fluster = Array('category' => Array('type' => Array(), 'topic' => Array(), 'site' => Array()));
2790 $results = Array('summary' => Array(), 'fluster' => $default_fluster, 'spell' => Array(), 'featured' => Array());
2792 $adv_hosted_search = FALSE;
2793 if ($this->attr('search_type') == 'hosted' && $this->attr('hosted_mode')) {
2794 $response = $xml->getElementsByTagName('response');
2795 $result_packet = $response->item(0)->getElementsByTagName('resultPacket');
2796 $adv_hosted_search = TRUE;
2809 if ($adv_hosted_search) {
2810 $mapping_array = Array(
2811 'fullyMatching'=> 'fully_matching',
2812 'estimatedHits'=> 'estimated_hits',
2813 'partiallyMatching'=> 'partially_matching',
2814 'totalMatching'=> 'total_matching',
2815 'numRanks'=> 'num_ranks',
2816 'currStart'=> 'currstart',
2817 'currEnd'=> 'currend',
2818 'prevStart'=> 'prevstart',
2819 'nextStart'=> 'nextstart',
2821 $result_summary = $result_packet->item(0)->getElementsByTagName('resultsSummary');
2823 $result_summary = $xml->getElementsByTagName('results_summary');
2826 for ($i=0; $i<$result_summary->length; $i++) {
2827 if ($result_summary->item($i)->hasChildNodes()) {
2828 foreach ($result_summary->item($i)->childNodes as $summary) {
2829 $name = isset($mapping_array[$summary->nodeName]) ? $mapping_array[$summary->nodeName] : $summary->nodeName;
2830 $value = $summary->nodeValue;
2831 $results['summary'][$name] = (string) $value;
2848 if ($adv_hosted_search) {
2849 $mapping_array = Array(
2850 'trigger'=> 'bb_trigger',
2852 'title'=> 'bb_title',
2853 'description'=> 'bb_desc',
2855 $feature_pages = $result_packet->item(0)->getElementsByTagName('bestBets');
2857 $feature_pages = $xml->getElementsByTagName('best_bets');
2859 // before FB v9.1, we call it featured_pages
2860 if($feature_pages->length == 0) $feature_pages = $xml->getElementsByTagName('featured_pages');
2862 if ($feature_pages->length >= 1) {
2863 $tag_name = ($adv_hosted_search) ? 'com.funnelback.publicui.search.model.padre.BestBet' : 'bb';
2864 $featured_pages = $feature_pages->item(0)->getElementsByTagName('bb');
2865 // before FB v9.1, we call it fp
2866 if($featured_pages->length == 0)
2867 $featured_pages = $feature_pages->item(0)->getElementsByTagName('fp');
2868 for ($j=0; $j<$featured_pages->length; $j++) {
2870 if ($featured_pages->item($j)->hasChildNodes()) {
2871 foreach ($featured_pages->item($j)->childNodes as $entry) {
2872 $name = (isset($array_mapping[$entry->nodeName])) ? $array_mapping[$entry->nodeName] : $entry->nodeName;
2873 // before FB v9.1, we call it fp_xx, so to make sure it doesn't break existing keywords etc, we have to stick with old names.
2876 $name = 'fp_trigger';
2890 $value = $entry->nodeValue;
2891 if ($name != '#text') {
2892 $bb[$name] = $value;
2896 $results['featured'][] = $bb;
2918 if ($adv_hosted_search) {
2919 $mapping_array = Array(
2920 'clusterNav'=> 'cluster_nav',
2921 'moreLink'=> 'more_link',
2922 'fewerLink'=> 'fewer_link',
2924 $fluster = $result_packet->item(0)->getElementsByTagName('contextualNavigation');
2926 $fluster = $xml->getElementsByTagName('contextual_navigation');
2928 // before FB v9.1, we call it fluster
2929 if($fluster->length == 0) $fluster = $xml->getElementsByTagName('fluster');
2931 for ($l=0; $l<$fluster->length; $l++) {
2932 // Process the cluster_nav elements
2933 $tag_name = $adv_hosted_search ? 'clusterNav' : 'cluster_nav';
2934 $cluster_nav = $fluster->item($l)->getElementsByTagName($tag_name);
2935 for ($m=0; $m<$cluster_nav->length; $m++) {
2936 $current_nav = Array();
2937 $current_nav['name'] = $cluster_nav->item($m)->nodeValue;
2938 if ($cluster_nav->item($m)->hasAttributes()) {
2939 foreach ($cluster_nav->item($m)->attributes as $attr) {
2940 if ($attr->name == 'url') {
2941 $current_nav[$attr->name] = $this->_stripURL($attr->value);
2943 $current_nav[$attr->name] = $attr->value;
2947 $level = array_get_index($current_nav, 'level', 0);
2948 $results['fluster']['navigation'][$level] = $current_nav;
2951 // Process the category elements
2952 $tag_name = $adv_hosted_search ? 'com.funnelback.publicui.search.model.padre.Category' : 'category';
2953 $category = $fluster->item($l)->getElementsByTagName($tag_name);
2954 for ($n=0; $n<$category->length; $n++) {
2955 $value = $category->item($n)->getAttribute('name');
2956 $more = (int) $category->item($n)->getAttribute('more');
2957 if (!empty($more)) {
2958 $results['fluster']['category'][$value]['more'] = TRUE;
2960 $results['fluster']['category'][$value]['more']= FALSE;
2962 if ($category->item($n)->hasChildNodes()) {
2963 foreach ($category->item($n)->childNodes as $cluster) {
2964 // For Funnelback 9.0 and higher, this is the more link
2965 $tag_name = isset($mapping_array[$cluster->nodeName]) ? $mapping_array[$cluster->nodeName] : $cluster->nodeName;
2966 if ($tag_name == 'more_link') {
2967 $results['fluster']['category'][$value]['more'] = TRUE;
2971 $tag_name = $adv_hosted_search ? 'com.funnelback.publicui.search.model.padre.Cluster' : 'cluster';
2972 if ($cluster->nodeName != $tag_name) continue;
2973 $fluster_cluster = Array();
2974 if ($cluster->hasAttributes()) {
2975 foreach ($cluster->attributes as $attr) {
2976 if ($attr->name == 'href') {
2977 $fluster_cluster[$attr->name] = $this->_stripURL($attr->value);
2979 $fluster_cluster[$attr->name] = $attr->value;
2983 $cluster_name_value = trim((string) $cluster->nodeValue);
2984 if (!empty($cluster_name_value)) {
2985 $fluster_cluster['name'] = $cluster_name_value;
2986 $results['fluster']['category'][$value][] = $fluster_cluster;
3005 $spell = $xml->getElementsByTagName('spell');
3006 for ($o=0; $o<$spell->length; $o++) {
3007 if ($spell->item($o)->hasChildNodes()) {
3008 foreach ($spell->item($o)->childNodes as $spell_value) {
3009 $spell_name = $spell_value->nodeName;
3010 if ($spell_name == 'map') {
3012 if ($spell_value->hasChildNodes()) {
3013 foreach ($spell_value->childNodes as $map_value) {
3014 $map_name = $map_value->nodeValue;
3015 $map[$map_name] = (string)$map_value->nodeValue;
3018 $results['spell']['map'][] = $map;
3020 $results['spell'][$spell_name] = (string) $spell_value->nodeValue;
3028 }//end processSearchSummary()
3039 public function processSearchResults(&$xml)
3043 $adv_hosted_search = FALSE;
3044 if ($this->attr('search_type') == 'hosted' && $this->attr('hosted_mode')) {
3045 $mapping_array = Array(
3046 'liveUrl' => 'live_url',
3047 'cacheUrl' => 'cache_url',
3048 'fileSize' => 'filesize',
3049 'fileType' => 'filetype',
3050 'docNum' => 'docnum',
3051 'clickTrackingUrl' => 'click_tracking_url',
3053 $response = $xml->getElementsByTagName('response');
3054 $resultPacket = $response->item(0)->getElementsByTagName('resultPacket');
3055 $result = $resultPacket->item(0)->getElementsByTagName('results');
3056 $adv_hosted_search = TRUE;
3058 $result = $xml->getElementsByTagName('results');
3061 for ($p=0; $p<$result->length; $p++) {
3062 if ($result->item($p)->hasChildNodes()) {
3063 foreach ($result->item($p)->childNodes as $single_result) {
3064 $expected_tag = $adv_hosted_search ? 'com.funnelback.publicui.search.model.padre.Result' : 'result';
3065 $name = $single_result->nodeName;
3066 if ($name == $expected_tag) {
3067 $each_result = Array();
3086 if ($single_result->hasChildNodes()) {
3087 foreach ($single_result->childNodes as $value) {
3088 $nodeName = $value->nodeName;
3089 if ($nodeName == 'md' && $value->hasAttribute('f')) {
3090 $nodeName = 'meta_'.$value->getAttribute('f');
3092 if ($adv_hosted_search)
3093 $nodeName = (isset($mapping_array[$nodeName])) ? $mapping_array[$nodeName] : $nodeName;
3094 $each_result[$nodeName] = utf8_decode($value->nodeValue);
3098 // Return a result TODO Unsure about this yet!
3099 $rank = array_get_index($each_result, 'rank', 0);
3100 if (!empty($rank)) {
3101 $results[$rank] = $each_result;
3110 }//end processSearchResults()
3122 private function _sanitizeQueries($queries)
3124 if(is_array($queries)) {
3125 foreach($queries as $field => $query) {
3126 $queries[$field] = $this->_sanitizeQueries($query);
3129 // sanitise it by removing '%' from keywords so that
3130 // they dont go ahead and try to fetch it replacement
3131 $keywords = extract_keywords($queries);
3132 foreach ($keywords as $keyword) {
3133 $pattern = '/(%*)'.$keyword.'(%*)/';
3134 $queries = preg_replace($pattern, $keyword, $queries);
3140 }//end _sanitizeQueries()
3158 function funnelback_xml_error_handler($errno, $errstr, $errfile, $errline)
3160 if ($errno & (E_USER_ERROR | E_ERROR | E_USER_WARNING | E_WARNING)) {
3161 log_dump('XML ERROR: '.$errstr.'. Error Number:'.$errno.'. Error File:'.$errfile.'. Error Line:'.$errline);
3162 throw new ErrorException($errstr, $errno);
3165 }//end funnelback_xml_error_handler()