Changeset 27868 for trunk/include/functions_search.inc.php
- Timestamp:
- Mar 21, 2014, 6:16:35 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/functions_search.inc.php
r26825 r27868 292 292 define('QST_QUOTED', 0x01); 293 293 define('QST_NOT', 0x02); 294 define('QST_WILDCARD_BEGIN', 0x04); 295 define('QST_WILDCARD_END', 0x08); 294 define('QST_OR', 0x04); 295 define('QST_WILDCARD_BEGIN', 0x08); 296 define('QST_WILDCARD_END', 0x10); 296 297 define('QST_WILDCARD', QST_WILDCARD_BEGIN|QST_WILDCARD_END); 297 298 … … 303 304 * 304 305 * @param string $q 305 * @param array &$qtokens 306 * @param array &$qtoken_modifiers 307 */ 308 function analyse_qsearch($q, &$qtokens, &$qtoken_modifiers) 309 { 310 $q = stripslashes($q); 311 $tokens = array(); 312 $token_modifiers = array(); 313 $crt_token = ""; 314 $crt_token_modifier = 0; 315 316 for ($i=0; $i<strlen($q); $i++) 317 { 318 $ch = $q[$i]; 319 if ( ($crt_token_modifier&QST_QUOTED)==0) 320 { 306 */ 307 308 class QSingleToken 309 { 310 var $is_single = true; 311 var $token; 312 var $idx; 313 314 function __construct($token) 315 { 316 $this->token = $token; 317 } 318 } 319 320 class QMultiToken 321 { 322 var $is_single = false; 323 var $tokens = array(); 324 var $token_modifiers = array(); 325 326 function __toString() 327 { 328 $s = ''; 329 for ($i=0; $i<count($this->tokens); $i++) 330 { 331 $modifier = $this->token_modifiers[$i]; 332 if ($i) 333 $s .= ' '; 334 if ($modifier & QST_OR) 335 $s .= 'OR '; 336 if ($modifier & QST_NOT) 337 $s .= 'NOT '; 338 if ($modifier & QST_WILDCARD_BEGIN) 339 $s .= '*'; 340 if ($modifier & QST_QUOTED) 341 $s .= '"'; 342 if (! ($this->tokens[$i]->is_single) ) 343 { 344 $s .= '('; 345 $s .= $this->tokens[$i]; 346 $s .= ')'; 347 } 348 else 349 { 350 $s .= $this->tokens[$i]->token; 351 } 352 if ($modifier & QST_QUOTED) 353 $s .= '"'; 354 if ($modifier & QST_WILDCARD_END) 355 $s .= '*'; 356 357 } 358 return $s; 359 } 360 361 function push(&$token, &$modifier) 362 { 363 $this->tokens[] = new QSingleToken($token); 364 $this->token_modifiers[] = $modifier; 365 $token = ""; 366 $modifier = 0; 367 } 368 369 protected function parse_expression($q, &$qi, $level) 370 { 371 $crt_token = ""; 372 $crt_modifier = 0; 373 374 for ($stop=false; !$stop && $qi<strlen($q); $qi++) 375 { 376 $ch = $q[$qi]; 377 if ( ($crt_modifier&QST_QUOTED)==0) 378 { 379 switch ($ch) 380 { 381 case '(': 382 if (strlen($crt_token)) 383 $this->push($crt_token, $crt_modifier); 384 $sub = new QMultiToken; 385 $qi++; 386 $sub->parse_expression($q, $qi, $level+1); 387 $this->tokens[] = $sub; 388 $this->token_modifiers[] = $crt_modifier; 389 $crt_modifier = 0; 390 break; 391 case ')': 392 if ($level>0) 393 $stop = true; 394 break; 395 case '"': 396 if (strlen($crt_token)) 397 $this->push($crt_token, $crt_modifier); 398 $crt_modifier |= QST_QUOTED; 399 break; 400 case '-': 401 if (strlen($crt_token)) 402 $crt_token .= $ch; 403 else 404 $crt_modifier |= QST_NOT; 405 break; 406 case '*': 407 if (strlen($crt_token)) 408 $crt_token .= $ch; // wildcard end later 409 else 410 $crt_modifier |= QST_WILDCARD_BEGIN; 411 break; 412 default: 413 if (preg_match('/[\s,.;!\?]+/', $ch)) 414 { // white space 415 if (strlen($crt_token)) 416 $this->push($crt_token, $crt_modifier); 417 $crt_modifier = 0; 418 } 419 else 420 $crt_token .= $ch; 421 break; 422 } 423 } 424 else 425 {// quoted 321 426 if ($ch=='"') 322 427 { 323 if ( strlen($crt_token))428 if ($qi+1 < strlen($q) && $q[$qi+1]=='*') 324 429 { 325 $tokens[] = $crt_token; $token_modifiers[] = $crt_token_modifier; 326 $crt_token = ""; $crt_token_modifier = 0; 327 } 328 $crt_token_modifier |= QST_QUOTED; 329 } 330 elseif ( strcspn($ch, '*+-><~')==0 ) 331 { //special full text modifier 332 if (strlen($crt_token)) 430 $crt_modifier |= QST_WILDCARD_END; 431 $ai++; 432 } 433 $this->push($crt_token, $crt_modifier); 434 } 435 else 436 $crt_token .= $ch; 437 } 438 } 439 440 if (strlen($crt_token)) 441 $this->push($crt_token, $crt_modifier); 442 443 for ($i=0; $i<count($this->tokens); $i++) 444 { 445 $token = $this->tokens[$i]; 446 $remove = false; 447 if ($token->is_single) 448 { 449 if ( ($this->token_modifiers[$i]&QST_QUOTED)==0 ) 450 { 451 if ('not' == strtolower($token->token)) 333 452 { 334 $crt_token .= $ch; 335 } 336 else 453 if ($i+1 < count($this->tokens)) 454 $this->token_modifiers[$i+1] |= QST_NOT; 455 $token->token = ""; 456 } 457 if ('or' == strtolower($token->token)) 337 458 { 338 if ( $ch=='*' ) 339 $crt_token_modifier |= QST_WILDCARD_BEGIN; 340 if ( $ch=='-' ) 341 $crt_token_modifier |= QST_NOT; 342 } 343 } 344 elseif (preg_match('/[\s,.;!\?]+/', $ch)) 345 { // white space 346 if (strlen($crt_token)) 459 if ($i+1 < count($this->tokens)) 460 $this->token_modifiers[$i+1] |= QST_OR; 461 $token->token = ""; 462 } 463 if ('and' == strtolower($token->token)) 347 464 { 348 $tokens[] = $crt_token; $token_modifiers[] = $crt_token_modifier; 349 $crt_token = ""; 350 } 351 $crt_token_modifier = 0; 352 } 353 else 354 { 355 $crt_token .= $ch; 356 } 357 } 358 else // qualified with quotes 359 { 360 if ($ch=='"') 361 { 362 if ($i+1 < strlen($q) && $q[$i+1]=='*') 363 { 364 $crt_token_modifier |= QST_WILDCARD_END; 365 $i++; 366 } 367 $tokens[] = $crt_token; $token_modifiers[] = $crt_token_modifier; 368 $crt_token = ""; $crt_token_modifier = 0; 369 $state=0; 465 $token->token = ""; 466 } 467 if ( substr($token->token, -1)=='*' ) 468 { 469 $token->token = rtrim($token->token, '*'); 470 $this->token_modifiers[$i] |= QST_WILDCARD_END; 471 } 472 } 473 if (!strlen($token->token)) 474 $remove = true; 370 475 } 371 476 else 372 $crt_token .= $ch; 373 } 374 } 375 376 if (strlen($crt_token)) 377 { 378 $tokens[] = $crt_token; 379 $token_modifiers[] = $crt_token_modifier; 380 } 381 382 $qtokens = array(); 383 $qtoken_modifiers = array(); 384 for ($i=0; $i<count($tokens); $i++) 385 { 386 if ( !($token_modifiers[$i] & QST_QUOTED) ) 387 { 388 if ( substr($tokens[$i], -1)=='*' ) 389 { 390 $tokens[$i] = rtrim($tokens[$i], '*'); 391 $token_modifiers[$i] |= QST_WILDCARD_END; 392 } 393 } 394 if ( strlen($tokens[$i])==0) 395 continue; 396 $qtokens[] = $tokens[$i]; 397 $qtoken_modifiers[] = $token_modifiers[$i]; 398 } 399 } 400 401 /** 402 * Returns the LIKE SQL clause corresponding to the quick search query 403 * that has been split into tokens. 404 * for example file LIKE '%john%' OR file LIKE '%bill%'. 405 * 406 * @param array $tokens 407 * @param array $token_modifiers 408 * @param string $field 409 * @return string|null 410 */ 411 function get_qsearch_like_clause($tokens, $token_modifiers, $field) 412 { 413 $clauses = array(); 414 for ($i=0; $i<count($tokens); $i++) 415 { 416 $token = trim($tokens[$i], '%'); 417 if ($token_modifiers[$i]&QST_NOT) 418 continue; 419 if ( strlen($token)==0 ) 420 continue; 421 $token = addslashes($token); 422 $token = str_replace( array('%','_'), array('\\%','\\_'), $token); // escape LIKE specials %_ 423 $clauses[] = $field.' LIKE \'%'.$token.'%\''; 424 } 425 426 return count($clauses) ? '('.implode(' OR ', $clauses).')' : null; 427 } 428 429 /** 430 * Returns tags corresponding to the quick search query that has been split into tokens. 431 * 432 * @param array $tokens 433 * @param array $token_modifiers 434 * @param array &$token_tag_ids 435 * @param array &$not_tag_ids 436 * @param array &$all_tags 437 */ 438 function get_qsearch_tags($tokens, $token_modifiers, &$token_tag_ids, &$not_tag_ids, &$all_tags) 439 { 477 { 478 if (!count($token->tokens)) 479 $remove = true; 480 } 481 if ($remove) 482 { 483 array_splice($this->tokens, $i, 1); 484 array_splice($this->token_modifiers, $i, 1); 485 $i--; 486 } 487 } 488 } 489 } 490 491 class QExpression extends QMultiToken 492 { 493 var $stokens = array(); 494 var $stoken_modifiers = array(); 495 496 function __construct($q) 497 { 498 $i = 0; 499 $this->parse_expression($q, $i, 0); 500 //@TODO: manipulate the tree so that 'a OR b c' is the same as 'b c OR a' 501 $this->build_single_tokens($this); 502 } 503 504 private function build_single_tokens(QMultiToken $expr) 505 { 506 //@TODO: double negation results in no negation in token modifier 507 for ($i=0; $i<count($expr->tokens); $i++) 508 { 509 $token = $expr->tokens[$i]; 510 if ($token->is_single) 511 { 512 $token->idx = count($this->stokens); 513 $this->stokens[] = $token->token; 514 $this->stoken_modifiers[] = $expr->token_modifiers[$i]; 515 } 516 else 517 $this->build_single_tokens($token); 518 } 519 } 520 } 521 522 class QResults 523 { 524 var $all_tags; 525 var $tag_ids; 526 var $tag_iids; 527 var $images_iids; 528 var $iids; 529 } 530 531 function qsearch_get_images(QExpression $expr, QResults $qsr) 532 { 533 //@TODO: inflections for english / french 534 $qsr->images_iids = array_fill(0, count($expr->tokens), array()); 535 $query_base = 'SELECT id from '.IMAGES_TABLE.' i WHERE '; 536 for ($i=0; $i<count($expr->stokens); $i++) 537 { 538 $token = $expr->stokens[$i]; 539 $clauses = array(); 540 541 $like = addslashes($token); 542 $like = str_replace( array('%','_'), array('\\%','\\_'), $like); // escape LIKE specials %_ 543 $clauses[] = 'CONVERT(file, CHAR) LIKE \'%'.$like.'%\''; 544 545 if (strlen($token)>3) // default minimum full text index 546 { 547 $ft = $token; 548 if ($expr->stoken_modifiers[$i] & QST_QUOTED) 549 $ft = '"'.$ft.'"'; 550 if ($expr->stoken_modifiers[$i] & QST_WILDCARD_END) 551 $ft .= '*'; 552 $clauses[] = 'MATCH(i.name, i.comment) AGAINST( \''.addslashes($ft).'\' IN BOOLEAN MODE)'; 553 } 554 else 555 { 556 foreach( array('i.name', 'i.comment') as $field) 557 { 558 $clauses[] = $field.' LIKE \''.$like.' %\''; 559 $clauses[] = $field.' LIKE \'% '.$like.'\''; 560 $clauses[] = $field.' LIKE \'% '.$like.' %\''; 561 } 562 } 563 $query = $query_base.'('.implode(' OR ', $clauses).')'; 564 $qsr->images_iids[$i] = query2array($query,null,'id'); 565 } 566 } 567 568 function qsearch_get_tags(QExpression $expr, QResults $qsr) 569 { 570 $tokens = $expr->stokens; 571 $token_modifiers = $expr->stoken_modifiers; 572 440 573 $token_tag_ids = array_fill(0, count($tokens), array() ); 441 $ not_tag_ids = $all_tags = array();574 $all_tags = array(); 442 575 443 576 $token_tag_scores = $token_tag_ids; … … 532 665 } 533 666 534 // process not tags 667 // process tags 668 $not_tag_ids = array(); 535 669 for ($i=0; $i<count($tokens); $i++) 536 670 { 537 if ( ! ($token_modifiers[$i]&QST_NOT) )538 continue;539 540 671 array_multisort($token_tag_scores[$i], SORT_DESC|SORT_NUMERIC, $token_tag_ids[$i]); 672 $is_not = $token_modifiers[$i]&QST_NOT; 673 $counter = 0; 541 674 542 675 for ($j=0; $j<count($token_tag_scores[$i]); $j++) 543 676 { 544 if ($token_tag_scores[$i][$j] < 0.8) 545 break; 546 if ($j>0 && $token_tag_scores[$i][$j] < $token_tag_scores[$i][0]) 547 break; 548 $tag_id = $token_tag_ids[$i][$j]; 549 if ( isset($all_tags[$tag_id]) ) 550 { 551 unset($all_tags[$tag_id]); 552 $not_tag_ids[] = $tag_id; 553 } 554 } 555 $token_tag_ids[$i] = array(); 556 } 557 558 // process regular tags 559 for ($i=0; $i<count($tokens); $i++) 560 { 561 if ( $token_modifiers[$i]&QST_NOT ) 562 continue; 563 564 array_multisort($token_tag_scores[$i], SORT_DESC|SORT_NUMERIC, $token_tag_ids[$i]); 565 566 $counter = 0; 567 for ($j=0; $j<count($token_tag_scores[$i]); $j++) 568 { 569 $tag_id = $token_tag_ids[$i][$j]; 570 if ( ! isset($all_tags[$tag_id]) ) 571 { 572 array_splice($token_tag_ids[$i], $j, 1); 573 array_splice($token_tag_scores[$i], $j, 1); 574 $j--; 575 continue; 576 } 577 578 $counter += $all_tags[$tag_id]['counter']; 579 if ($counter > 200 && $j>0 && $token_tag_scores[$i][0] > $token_tag_scores[$i][$j] ) 580 {// "many" images in previous tags and starting from this tag is less relevent 581 array_splice($token_tag_ids[$i], $j); 582 array_splice($token_tag_scores[$i], $j); 583 break; 584 } 585 } 586 } 587 677 if ($is_not) 678 { 679 if ($token_tag_scores[$i][$j] < 0.8 || 680 ($j>0 && $token_tag_scores[$i][$j] < $token_tag_scores[$i][0]) ) 681 { 682 array_splice($token_tag_scores[$i], $j); 683 array_splice($token_tag_ids[$i], $j); 684 } 685 } 686 else 687 { 688 $tag_id = $token_tag_ids[$i][$j]; 689 $counter += $all_tags[$tag_id]['counter']; 690 if ($counter > 200 && $j>0 && $token_tag_scores[$i][0] > $token_tag_scores[$i][$j] ) 691 {// "many" images in previous tags and starting from this tag is less relevent 692 array_splice($token_tag_ids[$i], $j); 693 array_splice($token_tag_scores[$i], $j); 694 break; 695 } 696 } 697 } 698 699 if ($is_not) 700 { 701 $not_tag_ids = array_merge($not_tag_ids, $token_tag_ids[$i]); 702 } 703 } 704 705 $all_tags = array_diff_key($all_tags, array_flip($not_tag_ids)); 588 706 usort($all_tags, 'tag_alpha_compare'); 589 707 foreach ( $all_tags as &$tag ) … … 591 709 $tag['name'] = trigger_event('render_tag_name', $tag['name'], $tag); 592 710 } 711 $qsr->all_tags = $all_tags; 712 713 $qsr->tag_ids = $token_tag_ids; 714 $qsr->tag_iids = array_fill(0, count($tokens), array() ); 715 716 for ($i=0; $i<count($tokens); $i++) 717 { 718 $tag_ids = $token_tag_ids[$i]; 719 720 if (!empty($tag_ids)) 721 { 722 $query = ' 723 SELECT image_id FROM '.IMAGE_TAG_TABLE.' 724 WHERE tag_id IN ('.implode(',',$tag_ids).') 725 GROUP BY image_id'; 726 $qsr->tag_iids[$i] = query2array($query, null, 'image_id'); 727 } 728 } 729 } 730 731 732 function qsearch_eval(QExpression $expr, QResults $qsr, QMultiToken $crt_expr) 733 { 734 $ids = $not_ids = array(); 735 $first = true; 736 for ($i=0; $i<count($crt_expr->tokens); $i++) 737 { 738 $current = $crt_expr->tokens[$i]; 739 if ($current->is_single) 740 { 741 $crt_ids = $qsr->iids[$current->idx] = array_unique( array_merge($qsr->images_iids[$current->idx], $qsr->tag_iids[$current->idx]) ); 742 } 743 else 744 $crt_ids = qsearch_eval($expr, $qsr, $current); 745 $modifier = $crt_expr->token_modifiers[$i]; 746 747 if ($modifier & QST_NOT) 748 $not_ids = array_unique( array_merge($not_ids, $crt_ids)); 749 else 750 { 751 if ($modifier & QST_OR) 752 $ids = array_unique( array_merge($ids, $crt_ids) ); 753 else 754 { 755 if ($current->is_single && empty($crt_ids)) 756 { 757 //@TODO: mark this term as unmatched and tell users 758 //@TODO: if we don't find a term at all, maybe ignore it and produce some results 759 } 760 if ($first) 761 $ids = $crt_ids; 762 else 763 $ids = array_intersect($ids, $crt_ids); 764 $first= false; 765 } 766 } 767 } 768 769 if (count($not_ids)) 770 $ids = array_diff($ids, $not_ids); 771 return $ids; 593 772 } 594 773 … … 621 800 ); 622 801 $q = trim($q); 623 analyse_qsearch($q, $tokens, $token_modifiers); 624 if (count($tokens)==0) 625 { 802 $expression = new QExpression($q); 803 //var_export($expression); 804 805 $qsr = new QResults; 806 qsearch_get_tags($expression, $qsr); 807 qsearch_get_images($expression, $qsr); 808 //var_export($qsr->all_tags); 809 810 $ids = qsearch_eval($expression, $qsr, $expression); 811 812 $debug[] = "<!--\nparsed: ".$expression; 813 $debug[] = count($expression->stokens).' tokens'; 814 for ($i=0; $i<count($expression->stokens); $i++) 815 { 816 $debug[] = $expression->stokens[$i].': '.count($qsr->tag_ids[$i]).' tags, '.count($qsr->tag_iids[$i]).' tiids, '.count($qsr->images_iids[$i]).' iiids, '.count($qsr->iids[$i]).' iids'; 817 } 818 $debug[] = 'before perms '.count($ids); 819 820 $search_results['qs']['matching_tags'] = $qsr->all_tags; 821 global $template; 822 823 if (empty($ids)) 824 { 825 $debug[] = '-->'; 826 $template->append('footer_elements', implode("\n", $debug) ); 626 827 return $search_results; 627 828 } 628 $debug[] = '<!--'.count($tokens).' tokens'; 629 630 $q_like_field = '@@__db_field__@@'; //something never in a search 631 $q_like_clause = get_qsearch_like_clause($tokens, $token_modifiers, $q_like_field ); 632 633 // Step 1 - first we find matches in #images table =========================== 634 $where_clauses='MATCH(i.name, i.comment) AGAINST( \''.$q.'\' IN BOOLEAN MODE)'; 635 if (!empty($q_like_clause)) 636 { 637 $where_clauses .= ' 638 OR '. str_replace($q_like_field, 'CONVERT(file, CHAR)', $q_like_clause); 639 $where_clauses = '('.$where_clauses.')'; 640 } 641 $where_clauses = array($where_clauses); 642 if (!empty($images_where)) 643 { 644 $where_clauses[]='('.$images_where.')'; 645 } 646 $where_clauses[] .= get_sql_condition_FandF 647 ( 648 array( 'visible_images' => 'i.id' ), null, true 649 ); 650 $query = ' 651 SELECT i.id, 652 MATCH(i.name, i.comment) AGAINST( \''.$q.'\' IN BOOLEAN MODE) AS weight 653 FROM '.IMAGES_TABLE.' i 654 WHERE '.implode("\n AND ", $where_clauses); 655 656 $by_weights=array(); 657 $result = pwg_query($query); 658 while ($row = pwg_db_fetch_assoc($result)) 659 { // weight is important when sorting images by relevance 660 if ($row['weight']) 661 { 662 $by_weights[(int)$row['id']] = 2*$row['weight']; 663 } 664 else 665 {//full text does not match but file name match 666 $by_weights[(int)$row['id']] = 2; 667 } 668 } 669 $debug[] = count($by_weights).' fulltext'; 670 if (!empty($by_weights)) 671 { 672 $debug[] = 'ft score min:'.min($by_weights).' max:'.max($by_weights); 673 } 674 675 676 // Step 2 - get the tags and the images for tags 677 get_qsearch_tags($tokens, $token_modifiers, $token_tag_ids, $not_tag_ids, $search_results['qs']['matching_tags']); 678 $debug[] = count($search_results['qs']['matching_tags']).' tags'; 679 680 for ($i=0; $i<count($token_tag_ids); $i++) 681 { 682 $tag_ids = $token_tag_ids[$i]; 683 $debug[] = count($tag_ids).' unique tags'; 684 685 if (!empty($tag_ids)) 686 { 687 $tag_photo_count=0; 688 $query = ' 689 SELECT image_id FROM '.IMAGE_TAG_TABLE.' 690 WHERE tag_id IN ('.implode(',',$tag_ids).') 691 GROUP BY image_id'; 692 $result = pwg_query($query); 693 while ($row = pwg_db_fetch_assoc($result)) 694 { // weight is important when sorting images by relevance 695 $image_id=(int)$row['image_id']; 696 @$by_weights[$image_id] += 1; 697 $tag_photo_count++; 698 } 699 $debug[] = $tag_photo_count.' photos for tag'; 700 $debug[] = count($by_weights).' photos after'; 701 } 702 } 703 704 // Step 3 - search categories corresponding to the query $q ================== 705 $query = ' 706 SELECT id, name, permalink, nb_images 707 FROM '.CATEGORIES_TABLE.' 708 INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.' ON id=cat_id 709 WHERE user_id='.$user['id'].' 710 AND MATCH(name, comment) AGAINST( \''.$q.'\' IN BOOLEAN MODE)'. 711 get_sql_condition_FandF ( 712 array( 'visible_categories' => 'cat_id' ), "\n AND" 713 ); 714 $result = pwg_query($query); 715 while ($row = pwg_db_fetch_assoc($result)) 716 { // weight is important when sorting images by relevance 717 if ($row['nb_images']==0) 718 { 719 $search_results['qs']['matching_cats_no_images'][] = $row; 720 } 721 else 722 { 723 $search_results['qs']['matching_cats'][$row['id']] = $row; 724 } 725 } 726 $debug[] = count(@$search_results['qs']['matching_cats']).' albums with images'; 727 728 if ( empty($by_weights) and empty($search_results['qs']['matching_cats']) ) 729 { 730 return $search_results; 731 } 732 733 if (!empty($not_tag_ids)) 734 { 735 $query = ' 736 SELECT image_id FROM '.IMAGE_TAG_TABLE.' 737 WHERE tag_id IN ('.implode(',',$not_tag_ids).') 738 GROUP BY image_id'; 739 $result = pwg_query($query); 740 while ($row = pwg_db_fetch_row($result)) 741 { 742 $id = $row[0]; 743 unset($by_weights[$id]); 744 } 745 $debug[] = count($by_weights).' after not tags'; 746 } 747 // Step 4 - now we have $by_weights ( array image id => weight ) that need 748 // permission checks and/or matching categories to get images from 829 749 830 $where_clauses = array(); 750 if ( !empty($by_weights) ) 751 { 752 $where_clauses[]='i.id IN (' 753 . implode(',', array_keys($by_weights)) . ')'; 754 } 755 if ( !empty($search_results['qs']['matching_cats']) ) 756 { 757 $where_clauses[]='category_id IN ('. 758 implode(',',array_keys($search_results['qs']['matching_cats'])).')'; 759 } 760 $where_clauses = array( '('.implode("\n OR ",$where_clauses).')' ); 831 $where_clauses[]='i.id IN ('. implode(',', $ids) . ')'; 761 832 if (!empty($images_where)) 762 833 { … … 780 851 $conf['order_by']; 781 852 782 $allowed_images = array_from_query( $query, 'id'); 783 784 $debug[] = count($allowed_images).' final photo count -->'; 785 global $template; 786 $template->append('footer_elements', implode(', ', $debug) ); 787 788 if ( $super_order_by or empty($by_weights) ) 789 { 790 $search_results['items'] = $allowed_images; 791 return $search_results; 792 } 793 794 $allowed_images = array_flip( $allowed_images ); 795 $divisor = 5.0 * count($allowed_images); 796 foreach ($allowed_images as $id=> &$rank ) 797 { 798 $weight = isset($by_weights[$id]) ? $by_weights[$id] : 1; 799 $weight -= $rank/$divisor; 800 $rank = $weight; 801 } 802 unset($rank); 803 804 arsort($allowed_images, SORT_NUMERIC); 805 $search_results['items'] = array_keys($allowed_images); 853 $ids = query2array($query, null, 'id'); 854 855 $debug[] = count($ids).' final photo count -->'; 856 $template->append('footer_elements', implode("\n", $debug) ); 857 858 $search_results['items'] = $ids; 806 859 return $search_results; 807 860 }
Note: See TracChangeset
for help on using the changeset viewer.