From: Roland, R. M <rmr...@in...> - 2003-06-25 18:03:25
|
From Adam's database change, I went through and rewrote the Pagemaster = search function (which I have included below). Search is a large aspect = of what we're doing and I tried to 'googleize' the search results a = little (it's up to you whether this is a good thing or not) to make it = more useful to our users. My version is also streamlined to just two = queries. It also sorts by number of matches found in the content of the = page (ie it strips out all html except META). It also has variables for = maximum number of results to display per page and number of characters = to display on either side of a match. I also tried to be as = non-invasive as possible, so I didn't make any change requirements to = the database and didn't use any additional functions. The only external = change is that this function requires the array of search words to be = passed (ie in the 'mod_search_register' table, the 'search_cols' field = for the Pagemaster record must be blank). =20 If some people can test it out and see what they think, I welcome any = feedback. Thanks, Ryan Roland Application Developer Information Technology Department Division of Recreational Sports Indiana University rmr...@in... Office: 812.855.9617 Cell: 812.320.0032 /** * Function used by search module to search pages * * @author Ryan Roland <rmr...@in...> * @param array Array of search words (strings) * @return array Array of strings of results of search * @access public */ function search($search_array) { // initialization variables =20 // characters on either side of a match to display=20 $chars_surrounding_match =3D 35; =20 // number of results to display per page $max_results_per_page =3D 5; =20 // create where clause $temp_sql =3D ""; $cols_array =3D array("title","text"); for($i=3D0; $i<count($cols_array); $i++) { for($j=3D0; $j<count($search_array); $j++) { $temp_sql .=3D $cols_array[$i] ." LIKE '%" . $search_array[$j] . = "%' "; if($j<count($search_array)) { $temp_sql .=3D "OR "; } } } $where_clause =3D "WHERE (" . substr($temp_sql, 0, -3) . ")"; =20 =20 $resultArray =3D array(); // get all sections with matching string occurences $sql =3D "SELECT * FROM " . $GLOBALS["core"]->tbl_prefix . = "mod_pagemaster_sections $where_clause"; $result =3D $GLOBALS["core"]->getAll($sql); if(!DB::isError($result) && is_array($result) && sizeof($result) > = 0) { $pages =3D array(); $page_count =3D array(); =20 =20 foreach($result as $row) { $section_title =3D strip_tags($row["title"],"<META>"); $section_text =3D strip_tags($row["text"],"<META>"); =20 $pages[$row["page_id"]][$row["id"]]["title"] =3D = $section_title; $pages[$row["page_id"]][$row["id"]]["text"] =3D $section_text; // init number of matches to 0 $section_match_count =3D 0; // loop through the words of the search criteria // counting number of matches found in the section title and = text=20 // this will elminate sections returned by the DB due to matches = in HTML foreach ($search_array as $search_word) { $section_match_count +=3D = substr_count(strtolower($section_title),strtolower($search_word)); $section_match_count +=3D = substr_count(strtolower($section_text),strtolower($search_word)); } =20 if(isset($page_count[$row["page_id"]]))=20 { $page_count[$row["page_id"]] =3D = $page_count[$row["page_id"]] + $section_match_count; } else { $page_count[$row["page_id"]] =3D $section_match_count; } } =20 // sort array ordering by match count highest to lowest arsort($page_count,SORT_NUMERIC); $page_ids =3D implode(" OR ", $page_count); $sql =3D "SELECT id,title,section_order FROM " . = $GLOBALS["core"]->tbl_prefix . "mod_pagemaster_pages WHERE $page_ids"; $result =3D $GLOBALS["core"]->getAll($sql); $ordered_page_results =3D $page_count; if(!DB::isError($result) && is_array($result) && sizeof($result) > = 0) { =20 // loop through all pages foreach($result as $row) { $page_results =3D array(); =20 $page_id =3D $row["id"]; $page_title =3D $row["title"]; $section_order =3D = unserialize($row["section_order"]); $needed_results =3D $max_results_per_page; $pages[$page_id]["page_title"] =3D $page_title; =20 // loop through all sections finding occurrences and parsing = text for ($i=3D0;$i<=3Dsizeof($section_order);$i++) { if ($needed_results > 0) { =20 $section_id =3D $section_order[$i]; =20 $title =3D $pages[$page_id][$section_id]["title"]; $text =3D $pages[$page_id][$section_id]["text"]; =20 foreach ($search_array as $search_word) { // Find occurrences of the search_word(s) in the = sections' title $prev_pos =3D 0; // while there exists another result and we haven't = found all needed results while (($next_pos =3D = strpos(strtolower($title),strtolower($search_word),$prev_pos)) && = $needed_results > 0) { // # of chars from the occurence to the end of the = string $chars_to_end =3D strlen($title) - $next_pos; // add bold tags around the occurence in the text $bolded =3D = substr_replace(substr_replace($title,"<b>",$next_pos,0),"</b>",($next_pos= + 3) + strlen($search_word),0); =20 // set prev_pos to the next char after the current = position $prev_pos =3D $next_pos + 1; // get up to 'chars_surrounding_match' on either side = of the occurrence,=20 // or to the begin/end of the string, whichever comes = first $match_result =3D "..." . substr($bolded,$next_pos - = min($next_pos,$chars_surrounding_match), $chars_surrounding_match * 2) . = "..."; =20 array_push($page_results,$match_result); $needed_results--; }// end while // Find occurrences of the search_word(s) in the = sections' text =20 $prev_pos =3D 0; // while there exists another result and we haven't = found all needed results while (($next_pos =3D = strpos(strtolower($text),strtolower($search_word),$prev_pos)) && = $needed_results > 0) { // # of chars from the occurence to the end of the = string $chars_to_end =3D strlen($title) - $next_pos; // add bold tags around the occurence in the text $bolded =3D = substr_replace(substr_replace($text,"<b>",$next_pos,0),"</b>",($next_pos = + 3) + strlen($search_word),0); =20 // set prev_pos to the next char after the current = position $prev_pos =3D $next_pos + 1; // get up to 'chars_surrounding_match' on either side = of the occurrence,=20 // or to the begin/end of the string, whichever comes = first $match_result =3D "..." . substr($bolded,$next_pos - = min($next_pos,$chars_surrounding_match), $chars_surrounding_match * 2) . = "..."; =20 array_push($page_results,$match_result); $needed_results--; }// end while }// end foreach }// end if }// end for $ordered_page_results[$page_id] =3D $page_results; }// end foreach =20 // loop through results and consolidating them to be returned while($next_page =3D each($page_count)) { $page_id =3D $next_page["key"]; $count =3D $next_page["value"]; =20 $count =3D=3D 1 ? $count_string =3D "match" : $count_string = =3D "matches"; =20 $matches_string =3D ""; foreach($ordered_page_results[$page_id] as $next_match) { $matches_string .=3D $next_match . "<br />"; } =20 $resultArray[$page_id] =3D "<u><b>" . = $pages[$page_id]["page_title"] . "</b> - <b> ". $count ." = </b> ". $count_string ." found : first <b> " . = sizeof($ordered_page_results[$page_id]) . " </b> displayed.</u><br />" . = $matches_string; }// end while }// end if }// end if return $resultArray; }// END FUNC search |