Beispiel #1
0
	/**
	 * This is where the magic happens - tap into the WordPress query and inject our own search
	 *
	 * @param string $request 
	 * @return void
	 */
	function posts_request( $request ) {
		global $wpdb, $current_user;
		
		$_GET['s'] = get_query_var( 's' );

		// Extract search terms
		$term = trim( $_GET['s'] );
		$term = preg_replace_callback( "/['\"](.*?)['\"]/", array( &$this, 'exact_words' ), $term );
		
		$term = preg_replace_callback( preg_encoding( '/(\w*)\s*AND\s*(\w*)/' ), array( &$this, 'logical_and' ), $term );
		$term = preg_replace( preg_encoding( '/(\w*)\s*OR\s*(\w*)/' ), '$1 $2', $term );

		// Split the words into small and full
		$words = array_filter( preg_split( '/[\s,]+/', trim( $term ) ) );
		foreach ( $words AS $word ) {
			if ( strlen( $word ) >= 4 )
				$this->full[] = $word;
			else
				$this->small[] = $word;
		}

		include_once dirname( dirname( __FILE__ ) ).'/models/search-module.php';
		$modules = Search_Module_Factory::running();

		$and = array();
		
		$have_comments = false;
		foreach ( (array)$modules AS $module ) {
			if ( $module->is_post() )
				$prefix = $wpdb->prefix.'search_post';
			else {
				$have_comments = true;
				$prefix = $wpdb->prefix.'search_comment';
			}
		
			if ( isset( $_GET[$module->field_name()] ) ) {
				$value = $module->field_value( $_GET[$module->field_name()] );
				if ( $value !== false )
					$and[] = $prefix.'.'.$module->field_name()." LIKE '%".$wpdb->escape( $value )."%'";
			}
		}
	
		if ( $have_comments )
			$this->fields .= ",{$wpdb->prefix}search_comment.comment_id";

		// Any fulltext searches?
		$priorities = $fields = array();
		if ( count( $this->full ) > 0 ) {
			$term        = implode( ' ', $this->full );
			$term        = trim( $term );
			$this->terms = $this->full;
			
			$scores = array();
			foreach ( (array)$modules AS $module ) {
				if ( $module->is_post() )
					$item = $wpdb->prefix.'search_post.'.$module->field_name();
				else
					$item = $wpdb->prefix.'search_comment.'.$module->field_name();

				$fields[] = $item;
				$scores[] = sprintf( "(%2.2f * (MATCH(%s) AGAINST ('%s' IN BOOLEAN MODE)))", $module->priority, $item, $wpdb->escape( $term ) );
			}
	
			$this->fields  .= ',MAX('.implode( ' + ', $scores ).') AS score';
			$this->orderby  = 'score DESC,'.$this->orderby;
		}
			
		// Form SQL
		$sql = "SELECT DISTINCT SQL_CALC_FOUND_ROWS ".$this->fields." FROM {$wpdb->posts} LEFT JOIN {$wpdb->prefix}search_post ON {$wpdb->posts}.ID={$wpdb->prefix}search_post.post_id ";

		if ( $have_comments )
			$sql .= " LEFT JOIN {$wpdb->prefix}search_comment ON {$wpdb->posts}.ID={$wpdb->prefix}search_comment.post_id ";

		$sql .= ' WHERE 1=1 ';
		$sql .= $this->get_restricted_posts();
		
		if ( count( $and ) > 0 )
			$sql .= ' AND '.implode( ' AND ', $and );
		
		// Add small words
		foreach ( (array)$this->small AS $small ) {
			$this->terms[] = $small;
			
			foreach ( (array)$modules AS $module ) {
				if ( $module->is_post() )
					$prefix = $wpdb->prefix.'search_post';
				else
					$prefix = $wpdb->prefix.'search_comment';

				$priorities[]  = $prefix.'.'.$module->field_name()." LIKE '%".$wpdb->escape( $small )."%'";
			}
		}

		if ( count( $this->full ) > 0 )
			$priorities[] = sprintf( "(MATCH(".implode( ',', $fields ).") AGAINST ('%s' IN BOOLEAN MODE))", $wpdb->escape( $term ) );

		$sql .= ' AND ('.implode( ' OR ', $priorities ).') ';
		
		if ( count( $this->full ) > 0 )
			$sql .= " GROUP BY {$wpdb->posts}.ID HAVING score ";
			
		$sql .= "ORDER BY ".$this->orderby.' ';
		$sql .= $this->limits;

		return $sql;
	}
Beispiel #2
0
 /**
  * Clean a piece of text suitable for indexing
  * This removes all HTML, removes most entities and empty spaces
  *
  * @param string $text Text to clean
  * @return string Cleaned text
  **/
 function clean_for_search($text)
 {
     // Save HREF and ALT attributes
     preg_match_all('/ href=["\'](.*?)["\']/iu', $text, $href);
     preg_match_all('/ alt=["\'](.*?)["\']/iu', $text, $alt);
     preg_match_all('/ title=["\'](.*?)["\']/iu', $text, $title);
     // Remove comments and JavaScript
     $text = preg_replace(preg_encoding('/<script(.*?)<\\/script>/s'), '', $text);
     $text = preg_replace(preg_encoding('/<!--(.*?)-->/s'), '', $text);
     $text = str_replace('<', ' <', $text);
     // Insert a space before HTML so the strip will have seperate words
     $text = preg_replace('/&#\\d*;/', '', $text);
     $text = addslashes(wp_kses(stripslashes(strip_html($text)), array()));
     $text = preg_replace(preg_encoding('/&\\w*;/'), ' ', $text);
     // Removes entities
     $text = str_replace("'", '', $text);
     $text = str_replace('&shy;', '', $text);
     $text = preg_replace(preg_encoding('/[\'!;#$%&\\,_\\+=\\?\\(\\)\\[\\]\\{\\}\\"<>`]/'), ' ', $text);
     if (count($href) > 0) {
         $text .= ' ' . implode(' ', $href[1]);
     }
     if (count($alt) > 0) {
         $text .= ' ' . implode(' ', $alt[1]);
     }
     if (count($title) > 0) {
         $text .= ' ' . implode(' ', $title[1]);
     }
     while (preg_match(preg_encoding('/\\s{2}/'), $text, $matches) > 0) {
         $text = preg_replace(preg_encoding('/\\s{2}/'), ' ', $text);
     }
     $text = str_replace('"', '', $text);
     $text = str_replace($this->blog_url, '', $text);
     return stripslashes(trim($text));
 }
Beispiel #3
0
	/**
	 * Highlight individual words
	 *
	 * @param object $links Not sure
	 * @return string Highlighted text
	 **/
	function mark_words( $links = false ) {
		$text = $this->text;
		$html = strpos( $text, '<' ) === false ? false : true;
		
		$this->mark_links = $links;
		foreach ( $this->words AS $pos => $word ) {
			if ( $pos > 5 )
				$pos = 1;
		
			$this->word_count = 0;
			$this->word_pos   = $pos;

			if ( $html )
				$text = @preg_replace_callback( preg_encoding( '/(?<=>)([^<]+)?('.$word.')(?!=")/i' ), array( &$this, 'highlight_html_word' ), $text );
			else
				$text = preg_replace_callback( '/('.$word.')(?!=")/iu', array( &$this, 'highlight_plain_word' ), $text );
		}
		
		$this->text = $text;
    return $text;
	}