[ Index ]
 

Code source de LifeType 1.2.4

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/class/dao/ -> searchengine.class.php (source)

   1  <?php
   2  
   3      lt_include( PLOG_CLASS_PATH."class/dao/articlestatus.class.php" );
   4      lt_include( PLOG_CLASS_PATH."class/dao/model.class.php" );
   5      lt_include( PLOG_CLASS_PATH."class/dao/searchresult.class.php" );
   6      lt_include( PLOG_CLASS_PATH."class/dao/blogstatus.class.php" );            
   7  
   8      define( "SEARCH_ARTICLE", 1 );
   9      define( "SEARCH_BLOG", 2 );
  10      define( "SEARCH_GALLERYRESOURCE", 3 );
  11          
  12      /**
  13       * \ingroup DAO
  14       *
  15       * Provides search facilities.
  16       *
  17       * This class provides methods for searching through articles, comments and custom fields.
  18       *
  19       * @see Articles
  20       * @see ArticleComments
  21       * @see CustomFields
  22       */
  23      class SearchEngine extends Model
  24      {
  25          /**
  26           * takes the search string as originally input by a user and makes it "better", in the sense
  27           * that for example converts it to "term1 AND term2" instead of "term1 OR term2" which is the
  28           * default behaviour. In order to do so, the "+" operator must be added before each one of the
  29           * search terms as long as it is not already there.
  30           *
  31           * @param searchTerms The original search string
  32           * @return Returns an 'improved' version of the search terms
  33           * @static
  34           */ 
  35          function adaptSearchString( $searchTerms )
  36          {
  37              // load this module only if needed...
  38              lt_include( PLOG_CLASS_PATH."class/data/textfilter.class.php" );        
  39              $tf = new Textfilter();
  40              $resultTerms = $tf->filterCharacters( $searchTerms, Array( '"', ';', '.' ));
  41              $resultTerms = Db::qstr($resultTerms);            
  42              
  43              $resultTerms = trim($resultTerms);
  44              return $resultTerms;
  45          }
  46  
  47          /**
  48           * MARKWU:
  49           * takes the search string as originally input by a user and makes it "better", in the sense
  50           * that for example converts it to "term1 AND term2" instead of "term1 OR term2" which is the
  51           * default behaviour. In order to do so, the "+" operator must be added before each one of the
  52           * search terms as long as it is not already there. This one is for public use, and will also 
  53           * convert the search string to a search terms array.
  54           *
  55           * @param searchTerms The original search string
  56           * @return Returns an 'improved' and 'arraized' version of the search terms
  57           */ 
  58          function getAdaptSearchTerms ( $searchTerms )
  59          {
  60              $resultTerms = Db::qstr($searchTerms);          
  61              $resultTerms = trim($resultTerms);
  62              $resultTerms = explode(' ',$resultTerms);
  63              return $resultTerms;
  64          }
  65          
  66          /**
  67           * Searches through articles, custom fields and comments only if enabled
  68           *
  69           * @param blogId The blog id where we're searching, or -1 if we're doing a global search
  70           * @param searchTerms A string containing the search terms
  71           * @param status In case we're looking for a particular status
  72           * @param includeFuture
  73           * @param page Page of results to return
  74           * @param itemsPerPage Number of items per page
  75           * @return
  76           * @see searchArticles
  77           * @see searchCustomFields
  78           * @see searchComments
  79           */
  80  		function search( $blogId, $searchTerms, $status = POST_STATUS_PUBLISHED, $includeFuture = true, $page = -1, $itemsPerPage = -1 )
  81          {            
  82              // calculate the conditions right away, they will be used by both sides of the union
  83              $conds = "";
  84              if( $blogId != -1 )
  85                  $conds .= " AND a.blog_id = ".Db::qstr( $blogId );
  86              if( $status != -1 ) 
  87                  $conds .= " AND a.status = ".$status;
  88              if( !$includeFuture )
  89                  $conds .= " AND a.date < NOW()";
  90  
  91              // first change
  92              $prefix = $this->getPrefix();
  93              
  94              // check if we can use fulltext indexes
  95              $db =& Db::getDb();
  96              if( $db->isFullTextSupported()) {
  97                  $query = "(SELECT a.* FROM {$prefix}articles a 
  98                            INNER JOIN {$prefix}articles_text at ON a.id = at.article_id
  99                            WHERE MATCH(at.normalized_text, at.normalized_topic) AGAINST ('".Db::qstr($searchTerms)."' IN BOOLEAN MODE) 
 100                            {$conds})
 101                             UNION
 102                            (SELECT a.* FROM {$prefix}articles a 
 103                            INNER JOIN {$prefix}custom_fields_values cfv ON a.id = cfv.article_id
 104                            WHERE MATCH(cfv.normalized_value) AGAINST ('".Db::qstr($searchTerms)."' IN BOOLEAN MODE) 
 105                            {$conds})
 106                            ORDER BY date DESC";
 107              }
 108              else {
 109                  $query = "SELECT DISTINCT a.id AS id FROM {$prefix}articles a ".
 110                           "WHERE ".$this->getArticleSearchConditions( $searchTerms )." {$conds} ORDER BY a.date DESC";
 111              }
 112  
 113              $result = $this->Execute( $query, $page, $itemsPerPage );
 114  
 115              lt_include( PLOG_CLASS_PATH."class/dao/articles.class.php" );
 116              $articles = new Articles();
 117  
 118              if( !$result )
 119                  return( Array());
 120  
 121              $results = Array();
 122              while( $row = $result->FetchRow()) {
 123                  // depending on whether fulltext is available, we will have either fetched all we need so that
 124                  // we can map the row directly into an object, or then we have to use the cache to get all
 125                  // articles one by one
 126                  if( $db->isFullTextSupported()) 
 127                      $results[] = new SearchResult( $articles->mapRow( $row ), SEARCH_RESULT_ARTICLE, $searchTerms );
 128                  else
 129                      $results[] =  new SearchResult( $articles->getArticle( $row["id"] ), SEARCH_RESULT_ARTICLE, $searchTerms );
 130              }
 131  
 132              return( $results );
 133          }
 134          
 135          /**
 136           * Returns the number of search results, but this method only applies to article
 137           * searches. If you're interested in getting the number of total matching blogs or
 138           * resources, use getNumSiteSearchResults
 139           *
 140           * @param blogId
 141           * @param searchTerms
 142           * @param status
 143           * @return
 144           */
 145  		function getNumSearchResults( $blogId, $searchTerms, $status, $includeFuture = true )
 146          {
 147              $prefix = $this->getPrefix();    
 148  
 149              // calculate the additional conditions beforehad
 150              $conds = "";
 151              if( $blogId != -1 )
 152                  $conds .= " AND a.blog_id = ".Db::qstr( $blogId );                    
 153              if( $status != -1 )
 154                  $conds .= " AND a.status = ".$status;                            
 155              if( !$includeFuture )
 156                  $conds .= " AND a.date < NOW()";
 157              
 158              // check if the db supports fulltext searches and if so act accordingly        
 159              $db =& Db::getDb();
 160              if( $db->isFullTextSupported()) {
 161                  // faster path via the fulltext indexes
 162                  $query = "(SELECT COUNT(a.id) AS total FROM {$prefix}articles a 
 163                            INNER JOIN {$prefix}articles_text at ON a.id = at.article_id
 164                            WHERE MATCH(at.normalized_text, at.normalized_topic) AGAINST ('".Db::qstr($searchTerms)."' IN BOOLEAN MODE) 
 165                            {$conds})
 166                             UNION
 167                            (SELECT COUNT(a.id) AS total FROM {$prefix}articles a 
 168                            INNER JOIN {$prefix}custom_fields_values cfv ON a.id = cfv.article_id
 169                            WHERE MATCH(cfv.normalized_value) AGAINST ('".Db::qstr($searchTerms)."' IN BOOLEAN MODE) 
 170                            {$conds})";
 171                  // execute the query, and it should give us exactly two rows: one per each one of the queries of the union, so 
 172                  // the total amount of posts that match the search condition should be the sum of those two rows
 173                  $result = $this->Execute( $query );
 174                  if( !$result )                
 175                      return 0;
 176                      
 177                  $total = 0;
 178                  while( $row = $result->FetchRow()) {
 179                      $total += $row["total"];
 180                  }
 181              }
 182              else {
 183                  // alternative, slower path
 184                  $query = $this->getArticleSearchConditions( $searchTerms );
 185                                  
 186                  $total = $this->getNumItems( "{$prefix}articles a", $query, "a.id" );                
 187              }
 188              
 189              return( $total );            
 190          }
 191          
 192          /**
 193           * @private
 194           * Returns a string that can be used as part of WHERE condition in an SQL query and that will return
 195           * all the articles in any blog that match the given search terms. It works by building 3
 196           * different queries, one to find all the matching articles, one to find all the matching custom fields
 197           * and another one to find all the matching comments and then puts the results together. 
 198           */
 199  		function getArticleSearchConditions( $searchTerms )
 200          {
 201              lt_include( PLOG_CLASS_PATH."class/dao/articles.class.php" );
 202              lt_include( PLOG_CLASS_PATH."class/dao/articlecomments.class.php" );
 203              lt_include( PLOG_CLASS_PATH."class/dao/customfields/customfieldsvalues.class.php" );
 204              
 205              $prefix = $this->getPrefix();
 206              
 207              // get the search conditions for articles
 208              $articles = new Articles();
 209              $articlesConds = $articles->getSearchConditions( $searchTerms );
 210              
 211              // now for comments
 212              $comments = new ArticleComments();
 213              $tmpCond = $comments->getSearchConditions( $searchTerms );
 214              $query = "SELECT c.article_id AS article_id FROM {$prefix}articles_comments c 
 215                        WHERE $tmpCond AND c.status = ".COMMENT_STATUS_NONSPAM;
 216              $result = $this->Execute( $query );
 217                  
 218              $ids = Array();
 219              while( $row = $result->FetchRow()) {
 220                  $ids[] = $row['article_id'];
 221              }
 222              $result->Close();
 223              if ( !empty( $ids ) )
 224                  $commentsConds = 'a.id IN ('.implode( ', ', $ids ).')';
 225              else
 226                  $commentsConds = 'a.id = -1';                            
 227              
 228              // and finally for custom fields
 229              $fields = new CustomFieldsValues();
 230              $tmpCond = $fields->getSearchConditions( $searchTerms );
 231              $query = "SELECT v.article_id AS article_id FROM {$prefix}custom_fields_values v WHERE $tmpCond";
 232              $result = $this->Execute( $query );    
 233                  
 234              $ids = Array();
 235              while( $row = $result->FetchRow()) {
 236                  $ids[] = $row['article_id'];
 237              }
 238              $result->Close();
 239              if ( !empty( $ids ) )
 240                  $fieldsConds = 'a.id IN ('.implode( ', ', $ids ).')';
 241              else
 242                  $fieldsConds = 'a.id = -1';
 243              
 244              // and try to build a combined query
 245              $query = "(({$articlesConds}) OR ({$commentsConds}) OR ({$fieldsConds}))";
 246              
 247              return( $query );
 248          }
 249          
 250          /**
 251           * performs a site-wide search
 252           * @param searchTerms An string with the terms for the search
 253           * @param searchType One of the following: SEARCH_ARTICLE, SEARCH_BLOG or SEARCH_GALLERYRESOURCE
 254           * @param status The status. Each item has its own constants for status codes, so this value will depend
 255           * on what we're looking for.
 256           * @param includeFuture Whether to include posts with a future date in the results
 257           * @param page The page of results to get
 258           * @param itemsPerPage Number of items per page
 259           * @return
 260           * @see search
 261           * @see searchArticles
 262           * @see searchCustomFields
 263           * @see searchComments
 264           */
 265  		function siteSearch( $searchTerms, $searchType, $status = -1, $includeFuture = true, $page = -1, $itemsPerPage = DEFAULT_ITEMS_PER_PAGE )
 266          {
 267              switch ( $searchType )
 268              {
 269                  case SEARCH_BLOG:
 270                      if ( $status == -1 ) 
 271                          $status = BLOG_STATUS_ACTIVE;            
 272                      $result = $this->searchBlogs( $searchTerms, $status, $includeFuture, $page, $itemsPerPage );
 273                  break;
 274                  case SEARCH_GALLERYRESOURCE:
 275                      $result = $this->searchGalleryResources( '_all_', $searchTerms, $page, $itemsPerPage );
 276                  break;
 277                  default:
 278                      // search articles and any other value of the $searchType parameter
 279                      if ( $status == -1 ) 
 280                          $status = POST_STATUS_PUBLISHED;
 281                      $result = $this->search( -1, $searchTerms, $status, $includeFuture, $page, $itemsPerPage );
 282              }
 283              return $result;                
 284          }
 285          
 286          /**
 287           * Returns the total number of matching items, be it articles, blogs or files.
 288           *
 289           * @param searchTerms An string with the terms for the search
 290           * @param searchType One of the following: SEARCH_ARTICLE, SEARCH_BLOG or SEARCH_GALLERYRESOURCE
 291           * @param status The status. Each item has its own constants for status codes, so this value will depend
 292           * on what we're looking for.
 293           * @param includeFuture whether to include future articles in the search
 294           * @return The number of matching items for the given search terms
 295           */
 296  		function getNumSiteSearchResults( $searchTerms, $searchType, $status = -1, $includeFuture = true )
 297          {
 298              if( $searchType == SEARCH_ARTICLE ) {
 299                  if( $status == -1 ) 
 300                      $status = POST_STATUS_PUBLISHED;
 301                  
 302                  $result = $this->getNumSearchResults( -1, $searchTerms, $status, $includeFuture );
 303              }
 304              elseif( $searchType == SEARCH_BLOG ) {
 305                  if ( $status == -1 ) 
 306                      $status = BLOG_STATUS_ACTIVE;                            
 307                  
 308                  lt_include( PLOG_CLASS_PATH."class/dao/blogs.class.php" );
 309                  
 310                  $blogs = new Blogs();
 311                  $result = $blogs->getNumBlogs( $status, ALL_BLOG_CATEGORIES, $searchTerms );
 312              }
 313              else {
 314                  lt_include( PLOG_CLASS_PATH."class/gallery/dao/galleryresources.class.php" );
 315                  
 316                  $resources = new GalleryResources();
 317                  $result = $resources->getNumUserResources( -1,  // owner id
 318                                                             GALLERY_NO_ALBUM,   // any album
 319                                                             GALLERY_RESOURCE_ANY,   // of any kind
 320                                                             $searchTerms   // search terms
 321                                                            );                                                    
 322              }
 323              
 324              return( $result );
 325          }
 326  
 327          /**
 328           * Returns an array of SearchResult objects containing information about the search, such as the
 329           * relevance (not very relevant, though :)), and the BlogObject
 330           *
 331           * @param searchTerms An string with the terms for the search
 332           * @param blogStatus        
 333           * @param page The page of results to get
 334           * @param itemsPerPage Number of items per page
 335           * @return An array of SearchResult objects
 336           */
 337          function searchBlogs( $searchTerms, $blogStatus = BLOG_STATUS_ACTIVE, $page = -1, $itemsPerPage = DEFAULT_ITEMS_PER_PAGE )
 338          {
 339              lt_include( PLOG_CLASS_PATH."class/dao/blogs.class.php" );
 340      
 341              $blogs = new Blogs();
 342              $blogsResult = $blogs->getAllBlogs( $blogStatus,  
 343                                                  ALL_BLOG_CATEGORIES,
 344                                                  $searchTerms,
 345                                                    $page, 
 346                                                     $itemsPerPage );                                            
 347                                                            
 348              $results = Array();
 349              foreach( $blogsResult as $blog ) {
 350                  $results[] = new SearchResult( $blog, SEARCH_RESULT_ARTICLE, $searchTerms );
 351              }
 352              
 353              return( $results );
 354          }
 355  
 356          /**
 357           * Returns an array of SearchResult objects containing information about the searchand the GalleryResource object
 358           *
 359           * @param ownerId the id of the blog/user whose pictures we're searching, or "-1" or "_all_" to search through
 360           * all of them.
 361           * @param searchTerms An string with the terms for the search
 362           * @param page The page of results to get
 363           * @param itemsPerPage Number of items per page        
 364           * @return An array of SearchResult objects
 365           */
 366          function searchGalleryResources( $ownerId, $searchTerms, $page = -1, $itemsPerPage = DEFAULT_ITEMS_PER_PAGE )
 367          {
 368              lt_include( PLOG_CLASS_PATH."class/gallery/dao/galleryresources.class.php" );
 369      
 370              $galleryResources = new GalleryResources();
 371              $galleryResourcesResult = $galleryResources->getUserResources( $ownerId, 
 372                                                                                GALLERY_NO_ALBUM, 
 373                                                                                GALLERY_RESOURCE_ANY,
 374                                                                                $searchTerms,
 375                                                                                $page, 
 376                                                                                $itemsPerPage );                                            
 377                                                            
 378              $results = Array();
 379              foreach( $galleryResourcesResult as $galleryResource ) {
 380                  $results[] = new SearchResult( $galleryResource, SEARCH_RESULT_GALLERYRESOURCE, $searchTerms );
 381              }
 382              
 383              return( $results );
 384          }               
 385      }
 386  ?>


Généré le : Mon Nov 26 21:04:15 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics