filterCharacters( $searchTerms, Array( '"', ';', '.' )); $resultTerms = Db::qstr($resultTerms); $resultTerms = trim($resultTerms); return $resultTerms; } /** * MARKWU: * takes the search string as originally input by a user and makes it "better", in the sense * that for example converts it to "term1 AND term2" instead of "term1 OR term2" which is the * default behaviour. In order to do so, the "+" operator must be added before each one of the * search terms as long as it is not already there. This one is for public use, and will also * convert the search string to a search terms array. * * @param searchTerms The original search string * @return Returns an 'improved' and 'arraized' version of the search terms */ function getAdaptSearchTerms ( $searchTerms ) { $resultTerms = Db::qstr($searchTerms); $resultTerms = trim($resultTerms); $resultTerms = explode(' ',$resultTerms); return $resultTerms; } /** * Searches through articles, custom fields and comments only if enabled * * @param blogId The blog id where we're searching, or -1 if we're doing a global search * @param searchTerms A string containing the search terms * @param status In case we're looking for a particular status * @param includeFuture * @param page Page of results to return * @param itemsPerPage Number of items per page * @return * @see searchArticles * @see searchCustomFields * @see searchComments */ function search( $blogId, $searchTerms, $status = POST_STATUS_PUBLISHED, $includeFuture = true, $page = -1, $itemsPerPage = -1 ) { $prefix = $this->getPrefix(); /* $query = "SELECT DISTINCT a.id AS id FROM {$prefix}articles a ". "WHERE ".$this->getArticleSearchConditions( $searchTerms ); */ // first change $query = "SELECT a.* FROM {$prefix}articles a ". "INNER JOIN {$prefix}articles_text at ON a.id=at.article_id ". "WHERE MATCH(at.normalized_text, at.normalized_topic) AGAINST ('{$searchTerms}' IN BOOLEAN MODE) "; if( $blogId != -1 ) $query .= " AND a.blog_id = ".Db::qstr( $blogId ); if( $status != -1 ) $query .= " AND a.status = ".$status; if( !$includeFuture ) $query .= " AND a.date < NOW()"; $query .= " ORDER BY a.date DESC"; $result = $this->Execute( $query, $page, $itemsPerPage ); include_once( PLOG_CLASS_PATH."class/dao/articles.class.php" ); $articles = new Articles(); if( !$result ) return( Array()); $results = Array(); while( $row = $result->FetchRow()) { // second change // i don't think would be good idea take articles from cache in a search when can i take directly from that query $results[] = new SearchResult( $articles->mapRow( $row ), SEARCH_RESULT_ARTICLE, $searchTerms ); } return( $results ); } /** * Returns the number of search results, but this method only applies to article * searches. If you're interested in getting the number of total matching blogs or * resources, use getNumSiteSearchResults * * @param blogId * @param searchTerms * @param status * @return */ function getNumSearchResults( $blogId, $searchTerms, $status, $includeFuture = true ) { $prefix = $this->getPrefix(); // 3rd changes //$query = $this->getArticleSearchConditions( $searchTerms ); $query = "SELECT COUNT(a.id) AS total FROM articles a INNER JOIN {$prefix}articles_text at ON a.id=at.article_id WHERE MATCH(at.normalized_text, at.normalized_topic) AGAINST ('{$searchTerms}' IN BOOLEAN MODE) "; if( $blogId != -1 ) $query .= " AND a.blog_id = ".Db::qstr( $blogId ); if( $status != -1 ) $query .= " AND a.status = ".$status; if( !$includeFuture ) $query .= " AND a.date < NOW()"; // last changes // getNumItems didn't cover this case (with inner join) // execute it $result = $this->Execute( $query ); if( !$result ) return 0; // if no error, get the result $row = $result->FetchRow(); $result->Close(); $total = $row["total"]; if( $total == "" ) $total = 0; return( $total ); } /** * @private * Returns a string that can be used as part of WHERE condition in an SQL query and that will return * all the articles in any blog that match the given search terms. It works by building 3 * different queries, one to find all the matching articles, one to find all the matching custom fields * and another one to find all the matching comments and then puts the results together. */ function getArticleSearchConditions( $searchTerms ) { include_once( PLOG_CLASS_PATH."class/dao/articles.class.php" ); include_once( PLOG_CLASS_PATH."class/dao/articlecomments.class.php" ); include_once( PLOG_CLASS_PATH."class/dao/customfields/customfieldsvalues.class.php" ); $prefix = $this->getPrefix(); // get the search conditions for articles $articles = new Articles(); $articlesConds = $articles->getSearchConditions( $searchTerms ); // now for comments $comments = new ArticleComments(); $tmpCond = $comments->getSearchConditions( $searchTerms ); $query = "SELECT c.article_id AS article_id FROM {$prefix}articles_comments c WHERE $tmpCond AND c.status = ".COMMENT_STATUS_NONSPAM; $result = $this->Execute( $query ); $ids = Array(); while( $row = $result->FetchRow()) { $ids[] = $row['article_id']; } $result->Close(); if ( !empty( $ids ) ) $commentsConds = 'a.id IN ('.implode( ', ', $ids ).')'; else $commentsConds = 'a.id = -1'; // and finally for custom fields $fields = new CustomFieldsValues(); $tmpCond = $fields->getSearchConditions( $searchTerms ); $query = "SELECT v.article_id AS article_id FROM {$prefix}custom_fields_values v WHERE $tmpCond"; $result = $this->Execute( $query ); $ids = Array(); while( $row = $result->FetchRow()) { $ids[] = $row['article_id']; } $result->Close(); if ( !empty( $ids ) ) $fieldsConds = 'a.id IN ('.implode( ', ', $ids ).')'; else $fieldsConds = 'a.id = -1'; // and try to build a combined query $query = "(({$articlesConds}) OR ({$commentsConds}) OR ({$fieldsConds}))"; return( $query ); } /** * performs a site-wide search * @param searchTerms An string with the terms for the search * @param searchType One of the following: SEARCH_ARTICLE, SEARCH_BLOG or SEARCH_GALLERYRESOURCE * @param status The status. Each item has its own constants for status codes, so this value will depend * on what we're looking for. * @param includeFuture Whether to include posts with a future date in the results * @param page The page of results to get * @param itemsPerPage Number of items per page * @return * @see search * @see searchArticles * @see searchCustomFields * @see searchComments */ function siteSearch( $searchTerms, $searchType, $status = -1, $includeFuture = true, $page = -1, $itemsPerPage = DEFAULT_ITEMS_PER_PAGE ) { switch ( $searchType ) { case SEARCH_BLOG: if ( $status == -1 ) $status = BLOG_STATUS_ACTIVE; $result = $this->searchBlogs( $searchTerms, $status, $includeFuture, $page, $itemsPerPage ); break; case SEARCH_GALLERYRESOURCE: $result = $this->searchGalleryResources( '_all_', $searchTerms, $page, $itemsPerPage ); break; default: // search articles and any other value of the $searchType parameter if ( $status == -1 ) $status = POST_STATUS_PUBLISHED; $result = $this->search( -1, $searchTerms, $status, $includeFuture, $page, $itemsPerPage ); } return $result; } /** * Returns the total number of matching items, be it articles, blogs or files. * * @param searchTerms An string with the terms for the search * @param searchType One of the following: SEARCH_ARTICLE, SEARCH_BLOG or SEARCH_GALLERYRESOURCE * @param status The status. Each item has its own constants for status codes, so this value will depend * on what we're looking for. * @param includeFuture whether to include future articles in the search * @return The number of matching items for the given search terms */ function getNumSiteSearchResults( $searchTerms, $searchType, $status = -1, $includeFuture = true ) { if( $searchType == SEARCH_ARTICLE ) { if( $status == -1 ) $status = POST_STATUS_PUBLISHED; $result = $this->getNumSearchResults( -1, $searchTerms, $status, $includeFuture ); } elseif( $searchType == SEARCH_BLOG ) { if ( $status == -1 ) $status = BLOG_STATUS_ACTIVE; include_once( PLOG_CLASS_PATH."class/dao/blogs.class.php" ); $blogs = new Blogs(); $result = $blogs->getNumBlogs( $status, ALL_BLOG_CATEGORIES, $searchTerms ); } else { include_once( PLOG_CLASS_PATH."class/gallery/dao/galleryresources.class.php" ); $resources = new GalleryResources(); $result = $resources->getNumUserResources( -1, // owner id GALLERY_NO_ALBUM, // any album GALLERY_RESOURCE_ANY, // of any kind $searchTerms // search terms ); } return( $result ); } /** * Returns an array of SearchResult objects containing information about the search, such as the * relevance (not very relevant, though :)), and the BlogObject * * @param searchTerms An string with the terms for the search * @param blogStatus * @param page The page of results to get * @param itemsPerPage Number of items per page * @return An array of SearchResult objects */ function searchBlogs( $searchTerms, $blogStatus = BLOG_STATUS_ACTIVE, $page = -1, $itemsPerPage = DEFAULT_ITEMS_PER_PAGE ) { include_once( PLOG_CLASS_PATH."class/dao/blogs.class.php" ); $blogs = new Blogs(); $blogsResult = $blogs->getAllBlogs( $blogStatus, ALL_BLOG_CATEGORIES, $searchTerms, $page, $itemsPerPage ); $results = Array(); foreach( $blogsResult as $blog ) { $results[] = new SearchResult( $blog, SEARCH_RESULT_ARTICLE, $searchTerms ); } return( $results ); } /** * Returns an array of SearchResult objects containing information about the searchand the GalleryResource object * * @param ownerId the id of the blog/user whose pictures we're searching, or "-1" or "_all_" to search through * all of them. * @param searchTerms An string with the terms for the search * @param page The page of results to get * @param itemsPerPage Number of items per page * @return An array of SearchResult objects */ function searchGalleryResources( $ownerId, $searchTerms, $page = -1, $itemsPerPage = DEFAULT_ITEMS_PER_PAGE ) { include_once( PLOG_CLASS_PATH."class/gallery/dao/galleryresources.class.php" ); $galleryResources = new GalleryResources(); $galleryResourcesResult = $galleryResources->getUserResources( $ownerId, GALLERY_NO_ALBUM, GALLERY_RESOURCE_ANY, $searchTerms, $page, $itemsPerPage ); $results = Array(); foreach( $galleryResourcesResult as $galleryResource ) { $results[] = new SearchResult( $galleryResource, SEARCH_RESULT_GALLERYRESOURCE, $searchTerms ); } return( $results ); } } ?>