source: trunk/include/functions_search.inc.php @ 20384

Last change on this file since 20384 was 19703, checked in by plg, 11 years ago

update Piwigo headers to 2013 (the end of the world didn't occur as expected on r12922)

  • Property svn:eol-style set to LF
File size: 22.0 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based photo gallery                                    |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008-2013 Piwigo Team                  http://piwigo.org |
6// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
7// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
8// +-----------------------------------------------------------------------+
9// | This program is free software; you can redistribute it and/or modify  |
10// | it under the terms of the GNU General Public License as published by  |
11// | the Free Software Foundation                                          |
12// |                                                                       |
13// | This program is distributed in the hope that it will be useful, but   |
14// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
15// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
16// | General Public License for more details.                              |
17// |                                                                       |
18// | You should have received a copy of the GNU General Public License     |
19// | along with this program; if not, write to the Free Software           |
20// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
21// | USA.                                                                  |
22// +-----------------------------------------------------------------------+
23
24
25/**
26 * returns search rules stored into a serialized array in "search"
27 * table. Each search rules set is numericaly identified.
28 *
29 * @param int search_id
30 * @return array
31 */
32function get_search_array($search_id)
33{
34  if (!is_numeric($search_id))
35  {
36    die('Search id must be an integer');
37  }
38
39  $query = '
40SELECT rules
41  FROM '.SEARCH_TABLE.'
42  WHERE id = '.$search_id.'
43;';
44  list($serialized_rules) = pwg_db_fetch_row(pwg_query($query));
45
46  return unserialize($serialized_rules);
47}
48
49/**
50 * returns the SQL clause from a search identifier
51 *
52 * Search rules are stored in search table as a serialized array. This array
53 * need to be transformed into an SQL clause to be used in queries.
54 *
55 * @param array search
56 * @return string
57 */
58function get_sql_search_clause($search)
59{
60  // SQL where clauses are stored in $clauses array during query
61  // construction
62  $clauses = array();
63
64  foreach (array('file','name','comment','author') as $textfield)
65  {
66    if (isset($search['fields'][$textfield]))
67    {
68      $local_clauses = array();
69      foreach ($search['fields'][$textfield]['words'] as $word)
70      {
71        array_push($local_clauses, $textfield." LIKE '%".$word."%'");
72      }
73
74      // adds brackets around where clauses
75      $local_clauses = prepend_append_array_items($local_clauses, '(', ')');
76
77      array_push(
78        $clauses,
79        implode(
80          ' '.$search['fields'][$textfield]['mode'].' ',
81          $local_clauses
82          )
83        );
84    }
85  }
86
87  if (isset($search['fields']['allwords']))
88  {
89    $fields = array('file', 'name', 'comment', 'author');
90    // in the OR mode, request bust be :
91    // ((field1 LIKE '%word1%' OR field2 LIKE '%word1%')
92    // OR (field1 LIKE '%word2%' OR field2 LIKE '%word2%'))
93    //
94    // in the AND mode :
95    // ((field1 LIKE '%word1%' OR field2 LIKE '%word1%')
96    // AND (field1 LIKE '%word2%' OR field2 LIKE '%word2%'))
97    $word_clauses = array();
98    foreach ($search['fields']['allwords']['words'] as $word)
99    {
100      $field_clauses = array();
101      foreach ($fields as $field)
102      {
103        array_push($field_clauses, $field." LIKE '%".$word."%'");
104      }
105      // adds brackets around where clauses
106      array_push(
107        $word_clauses,
108        implode(
109          "\n          OR ",
110          $field_clauses
111          )
112        );
113    }
114
115    array_walk(
116      $word_clauses,
117      create_function('&$s','$s="(".$s.")";')
118      );
119
120    array_push(
121      $clauses,
122      "\n         ".
123      implode(
124        "\n         ".
125              $search['fields']['allwords']['mode'].
126        "\n         ",
127        $word_clauses
128        )
129      );
130  }
131
132  foreach (array('date_available', 'date_creation') as $datefield)
133  {
134    if (isset($search['fields'][$datefield]))
135    {
136      array_push(
137        $clauses,
138        $datefield." = '".$search['fields'][$datefield]['date']."'"
139        );
140    }
141
142    foreach (array('after','before') as $suffix)
143    {
144      $key = $datefield.'-'.$suffix;
145
146      if (isset($search['fields'][$key]))
147      {
148        array_push(
149          $clauses,
150
151          $datefield.
152          ($suffix == 'after'             ? ' >' : ' <').
153          ($search['fields'][$key]['inc'] ? '='  : '').
154          " '".$search['fields'][$key]['date']."'"
155
156          );
157      }
158    }
159  }
160
161  if (isset($search['fields']['cat']))
162  {
163    if ($search['fields']['cat']['sub_inc'])
164    {
165      // searching all the categories id of sub-categories
166      $cat_ids = get_subcat_ids($search['fields']['cat']['words']);
167    }
168    else
169    {
170      $cat_ids = $search['fields']['cat']['words'];
171    }
172
173    $local_clause = 'category_id IN ('.implode(',', $cat_ids).')';
174    array_push($clauses, $local_clause);
175  }
176
177  // adds brackets around where clauses
178  $clauses = prepend_append_array_items($clauses, '(', ')');
179
180  $where_separator =
181    implode(
182      "\n    ".$search['mode'].' ',
183      $clauses
184      );
185
186  $search_clause = $where_separator;
187
188  return $search_clause;
189}
190
191/**
192 * returns the list of items corresponding to the advanced search array
193 *
194 * @param array search
195 * @return array
196 */
197function get_regular_search_results($search, $images_where)
198{
199  global $conf;
200  $forbidden = get_sql_condition_FandF(
201        array
202          (
203            'forbidden_categories' => 'category_id',
204            'visible_categories' => 'category_id',
205            'visible_images' => 'id'
206          ),
207        "\n  AND"
208    );
209
210  $items = array();
211  $tag_items = array();
212
213  if (isset($search['fields']['tags']))
214  {
215    $tag_items = get_image_ids_for_tags(
216      $search['fields']['tags']['words'],
217      $search['fields']['tags']['mode']
218      );
219  }
220
221  $search_clause = get_sql_search_clause($search);
222
223  if (!empty($search_clause))
224  {
225    $query = '
226SELECT DISTINCT(id)
227  FROM '.IMAGES_TABLE.' i
228    INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
229  WHERE '.$search_clause;
230    if (!empty($images_where))
231    {
232      $query .= "\n  AND ".$images_where;
233    }
234    $query .= $forbidden.'
235  '.$conf['order_by'];
236    $items = array_from_query($query, 'id');
237  }
238
239  if ( !empty($tag_items) )
240  {
241    switch ($search['mode'])
242    {
243      case 'AND':
244        if (empty($search_clause))
245        {
246          $items = $tag_items;
247        }
248        else
249        {
250          $items = array_values( array_intersect($items, $tag_items) );
251        }
252        break;
253      case 'OR':
254        $before_count = count($items);
255        $items = array_unique(
256          array_merge(
257            $items,
258            $tag_items
259            )
260          );
261        break;
262    }
263  }
264
265  return $items;
266}
267
268
269function is_word_char($ch)
270{
271  return ($ch>='0' && $ch<='9') || ($ch>='a' && $ch<='z') || ($ch>='A' && $ch<='Z') || ord($ch)>127;
272}
273
274function is_odd_wbreak_begin($ch)
275{
276  return strpos('[{<=*+', $ch)===false ? false:true;
277}
278
279function is_odd_wbreak_end($ch)
280{
281  return strpos(']}>=*+', $ch)===false ? false:true;
282}
283
284define('QST_QUOTED',   0x01);
285define('QST_NOT',      0x02);
286define('QST_WILDCARD_BEGIN',0x04);
287define('QST_WILDCARD_END',  0x08);
288define('QST_WILDCARD', QST_WILDCARD_BEGIN|QST_WILDCARD_END);
289
290
291/**
292 * analyzes and splits the quick/query search query $q into tokens
293 * q='john bill' => 2 tokens 'john' 'bill'
294 * Special characters for MySql full text search (+,<,>,~) appear in the token modifiers.
295 * The query can contain a phrase: 'Pierre "New York"' will return 'pierre' qnd 'new york'.
296 */
297function analyse_qsearch($q, &$qtokens, &$qtoken_modifiers)
298{
299  $q = stripslashes($q);
300  $tokens = array();
301  $token_modifiers = array();
302  $crt_token = "";
303  $crt_token_modifier = 0;
304
305  for ($i=0; $i<strlen($q); $i++)
306  {
307    $ch = $q[$i];
308    if ( ($crt_token_modifier&QST_QUOTED)==0)
309    {
310        if ($ch=='"')
311        {
312          if (strlen($crt_token))
313          {
314            $tokens[] = $crt_token; $token_modifiers[] = $crt_token_modifier;
315            $crt_token = ""; $crt_token_modifier = 0;
316          }
317          $crt_token_modifier |= QST_QUOTED;
318        }
319        elseif ( strcspn($ch, '*+-><~')==0 )
320        { //special full text modifier
321          if (strlen($crt_token))
322          {
323            $crt_token .= $ch;
324          }
325          else
326          {
327            if ( $ch=='*' )
328              $crt_token_modifier |= QST_WILDCARD_BEGIN;
329            if ( $ch=='-' )
330              $crt_token_modifier |= QST_NOT;
331          }
332        }
333        elseif (preg_match('/[\s,.;!\?]+/', $ch))
334        { // white space
335          if (strlen($crt_token))
336          {
337            $tokens[] = $crt_token; $token_modifiers[] = $crt_token_modifier;
338            $crt_token = "";
339          }
340          $crt_token_modifier = 0;
341        }
342        else
343        {
344          $crt_token .= $ch;
345        }
346    }
347    else // qualified with quotes
348    {
349      if ($ch=='"')
350      {
351        if ($i+1 < strlen($q) && $q[$i+1]=='*')
352        {
353          $crt_token_modifier |= QST_WILDCARD_END;
354          $i++;
355        }
356        $tokens[] = $crt_token; $token_modifiers[] = $crt_token_modifier;
357        $crt_token = ""; $crt_token_modifier = 0;
358        $state=0;
359      }
360      else
361        $crt_token .= $ch;
362    }
363  }
364
365  if (strlen($crt_token))
366  {
367    $tokens[] = $crt_token;
368    $token_modifiers[] = $crt_token_modifier;
369  }
370
371  $qtokens = array();
372  $qtoken_modifiers = array();
373  for ($i=0; $i<count($tokens); $i++)
374  {
375    if (strstr($token_modifiers[$i], 'q')===false)
376    {
377      if ( substr($tokens[$i], -1)=='*' )
378      {
379        $tokens[$i] = rtrim($tokens[$i], '*');
380        $token_modifiers[$i] .= '*';
381      }
382    }
383    if ( strlen($tokens[$i])==0)
384      continue;
385    $qtokens[] = $tokens[$i];
386    $qtoken_modifiers[] = $token_modifiers[$i];
387  }
388}
389
390
391/**
392 * returns the LIKE sql clause corresponding to the quick search query
393 * that has been split into tokens
394 * for example file LIKE '%john%' OR file LIKE '%bill%'.
395 */
396function get_qsearch_like_clause($tokens, $token_modifiers, $field)
397{
398  $clauses = array();
399  for ($i=0; $i<count($tokens); $i++)
400  {
401    $token = trim($tokens[$i], '%');
402    if ($token_modifiers[$i]&QST_NOT)
403      continue;
404    if ( strlen($token)==0 )
405      continue;
406    $token = addslashes($token);
407    $token = str_replace( array('%','_'), array('\\%','\\_'), $token); // escape LIKE specials %_
408    $clauses[] = $field.' LIKE \'%'.$token.'%\'';
409  }
410
411  return count($clauses) ? '('.implode(' OR ', $clauses).')' : null;
412}
413
414/**
415*/
416function get_qsearch_tags($tokens, $token_modifiers, &$token_tag_ids, &$not_tag_ids, &$all_tags)
417{
418  $token_tag_ids = array_fill(0, count($tokens), array() );
419  $not_tag_ids = $all_tags = array();
420
421  $token_tag_scores = $token_tag_ids;
422  $transliterated_tokens = array();
423  foreach ($tokens as $token)
424  {
425    $transliterated_tokens[] = transliterate($token);
426  }
427
428  $query = '
429SELECT t.*, COUNT(image_id) AS counter
430  FROM '.TAGS_TABLE.' t
431    INNER JOIN '.IMAGE_TAG_TABLE.' ON id=tag_id
432  GROUP BY id';
433  $result = pwg_query($query);
434  while ($tag = pwg_db_fetch_assoc($result))
435  {
436    $transliterated_tag = transliterate($tag['name']);
437
438    // find how this tag matches query tokens
439    for ($i=0; $i<count($tokens); $i++)
440    {
441      $transliterated_token = $transliterated_tokens[$i];
442
443      $match = false;
444      $pos = 0;
445      while ( ($pos = strpos($transliterated_tag, $transliterated_token, $pos)) !== false)
446      {
447        if ( ($token_modifiers[$i]&QST_WILDCARD)==QST_WILDCARD )
448        {// wildcard in this token
449          $match = 1;
450          break;
451        }
452        $token_len = strlen($transliterated_token);
453
454        // search begin of word
455        $wbegin_len=0; $wbegin_char=' ';
456        while ($pos-$wbegin_len > 0)
457        {
458          if (! is_word_char($transliterated_tag[$pos-$wbegin_len-1]) )
459          {
460            $wbegin_char = $transliterated_tag[$pos-$wbegin_len-1];
461            break;
462          }
463          $wbegin_len++;
464        }
465
466        // search end of word
467        $wend_len=0; $wend_char=' ';
468        while ($pos+$token_len+$wend_len < strlen($transliterated_tag))
469        {
470          if (! is_word_char($transliterated_tag[$pos+$token_len+$wend_len]) )
471          {
472            $wend_char = $transliterated_tag[$pos+$token_len+$wend_len];
473            break;
474          }
475          $wend_len++;
476        }
477
478        $this_score = 0;
479        if ( ($token_modifiers[$i]&QST_WILDCARD)==0 )
480        {// no wildcard begin or end
481          if ($token_len <= 2)
482          {// search for 1 or 2 characters must match exactly to avoid retrieving too much data
483            if ($wbegin_len==0 && $wend_len==0 && !is_odd_wbreak_begin($wbegin_char) && !is_odd_wbreak_end($wend_char) )
484              $this_score = 1;
485          }
486          elseif ($token_len == 3)
487          {
488            if ($wbegin_len==0)
489              $this_score = $token_len / ($token_len + $wend_len);
490          }
491          else
492          {
493            $this_score = $token_len / ($token_len + 1.1 * $wbegin_len + 0.9 * $wend_len);
494          }
495        }
496
497        if ($this_score>0)
498          $match = max($match, $this_score );
499        $pos++;
500      }
501
502      if ($match)
503      {
504        $tag_id = (int)$tag['id'];
505        $all_tags[$tag_id] = $tag;
506        $token_tag_ids[$i][] = $tag_id;
507        $token_tag_scores[$i][] = $match;
508      }
509    }
510  }
511
512  // process not tags
513  for ($i=0; $i<count($tokens); $i++)
514  {
515    if ( ! ($token_modifiers[$i]&QST_NOT) )
516      continue;
517
518    array_multisort($token_tag_scores[$i], SORT_DESC|SORT_NUMERIC, $token_tag_ids[$i]);
519
520    for ($j=0; $j<count($token_tag_scores[$i]); $j++)
521    {
522      if ($token_tag_scores[$i][$j] < 0.8)
523        break;
524      if ($j>0 && $token_tag_scores[$i][$j] < $token_tag_scores[$i][0])
525        break;
526      $tag_id = $token_tag_ids[$i][$j];
527      if ( isset($all_tags[$tag_id]) )
528      {
529        unset($all_tags[$tag_id]);
530        $not_tag_ids[] = $tag_id;
531      }
532    }
533    $token_tag_ids[$i] = array();
534  }
535
536  // process regular tags
537  for ($i=0; $i<count($tokens); $i++)
538  {
539    if ( $token_modifiers[$i]&QST_NOT )
540      continue;
541
542    array_multisort($token_tag_scores[$i], SORT_DESC|SORT_NUMERIC, $token_tag_ids[$i]);
543
544    $counter = 0;
545    for ($j=0; $j<count($token_tag_scores[$i]); $j++)
546    {
547      $tag_id = $token_tag_ids[$i][$j];
548      if ( ! isset($all_tags[$tag_id]) )
549      {
550        array_splice($token_tag_ids[$i], $j, 1);
551        array_splice($token_tag_scores[$i], $j, 1);
552      }
553
554      $counter += $all_tags[$tag_id]['counter'];
555      if ($counter > 200 && $j>0 && $token_tag_scores[$i][0] > $token_tag_scores[$i][$j] )
556      {// "many" images in previous tags and starting from this tag is less relevent
557        array_splice($token_tag_ids[$i], $j);
558        array_splice($token_tag_scores[$i], $j);
559        break;
560      }
561    }
562  }
563 
564  usort($all_tags, 'tag_alpha_compare');
565  foreach ( $all_tags as &$tag )
566    $tag['name'] = trigger_event('render_tag_name', $tag['name']);
567}
568
569/**
570 * returns the search results corresponding to a quick/query search.
571 * A quick/query search returns many items (search is not strict), but results
572 * are sorted by relevance unless $super_order_by is true. Returns:
573 * array (
574 * 'items' => array(85,68,79...)
575 * 'qs'    => array(
576 *    'matching_tags' => array of matching tags
577 *    'matching_cats' => array of matching categories
578 *    'matching_cats_no_images' =>array(99) - matching categories without images
579 *      ))
580 *
581 * @param string q
582 * @param bool super_order_by
583 * @param string images_where optional aditional restriction on images table
584 * @return array
585 */
586function get_quick_search_results($q, $super_order_by, $images_where='')
587{
588  global $user, $conf;
589
590  $search_results =
591    array(
592      'items' => array(),
593      'qs' => array('q'=>stripslashes($q)),
594    );
595  $q = trim($q);
596  analyse_qsearch($q, $tokens, $token_modifiers);
597  if (count($tokens)==0)
598  {
599    return $search_results;
600  }
601  $debug[] = '<!--'.count($tokens).' tokens';
602
603  $q_like_field = '@@__db_field__@@'; //something never in a search
604  $q_like_clause = get_qsearch_like_clause($tokens, $token_modifiers, $q_like_field );
605
606  // Step 1 - first we find matches in #images table ===========================
607  $where_clauses='MATCH(i.name, i.comment) AGAINST( \''.$q.'\' IN BOOLEAN MODE)';
608  if (!empty($q_like_clause))
609  {
610    $where_clauses .= '
611    OR '. str_replace($q_like_field, 'CONVERT(file, CHAR)', $q_like_clause);
612    $where_clauses = '('.$where_clauses.')';
613  }
614  $where_clauses = array($where_clauses);
615  if (!empty($images_where))
616  {
617    $where_clauses[]='('.$images_where.')';
618  }
619  $where_clauses[] .= get_sql_condition_FandF
620      (
621        array( 'visible_images' => 'i.id' ), null, true
622      );
623  $query = '
624SELECT i.id,
625    MATCH(i.name, i.comment) AGAINST( \''.$q.'\' IN BOOLEAN MODE) AS weight
626  FROM '.IMAGES_TABLE.' i
627  WHERE '.implode("\n AND ", $where_clauses);
628
629  $by_weights=array();
630  $result = pwg_query($query);
631  while ($row = pwg_db_fetch_assoc($result))
632  { // weight is important when sorting images by relevance
633    if ($row['weight'])
634    {
635      $by_weights[(int)$row['id']] =  2*$row['weight'];
636    }
637    else
638    {//full text does not match but file name match
639      $by_weights[(int)$row['id']] =  2;
640    }
641  }
642  $debug[] = count($by_weights).' fulltext';
643  if (!empty($by_weights))
644  {
645    $debug[] = 'ft score min:'.min($by_weights).' max:'.max($by_weights);
646  }
647
648
649  // Step 2 - get the tags and the images for tags
650  get_qsearch_tags($tokens, $token_modifiers, $token_tag_ids, $not_tag_ids, $search_results['qs']['matching_tags']);
651  $debug[] = count($search_results['qs']['matching_tags']).' tags';
652
653  for ($i=0; $i<count($token_tag_ids); $i++)
654  {
655    $tag_ids = $token_tag_ids[$i];
656    $debug[] = count($tag_ids).' unique tags';
657
658    if (!empty($tag_ids))
659    {
660      $tag_photo_count=0;
661      $query = '
662SELECT image_id FROM '.IMAGE_TAG_TABLE.'
663  WHERE tag_id IN ('.implode(',',$tag_ids).')
664  GROUP BY image_id';
665      $result = pwg_query($query);
666      while ($row = pwg_db_fetch_assoc($result))
667      { // weight is important when sorting images by relevance
668        $image_id=(int)$row['image_id'];
669        @$by_weights[$image_id] += 1;
670        $tag_photo_count++;
671      }
672      $debug[] = $tag_photo_count.' photos for tag';
673      $debug[] = count($by_weights).' photos after';
674    }
675  }
676
677  // Step 3 - search categories corresponding to the query $q ==================
678  $query = '
679SELECT id, name, permalink, nb_images
680  FROM '.CATEGORIES_TABLE.'
681    INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.' ON id=cat_id
682  WHERE user_id='.$user['id'].'
683    AND MATCH(name, comment) AGAINST( \''.$q.'\' IN BOOLEAN MODE)'.
684  get_sql_condition_FandF (
685      array( 'visible_categories' => 'cat_id' ), "\n    AND"
686    );
687  $result = pwg_query($query);
688  while ($row = pwg_db_fetch_assoc($result))
689  { // weight is important when sorting images by relevance
690    if ($row['nb_images']==0)
691    {
692      $search_results['qs']['matching_cats_no_images'][] = $row;
693    }
694    else
695    {
696      $search_results['qs']['matching_cats'][$row['id']] = $row;
697    }
698  }
699  $debug[] = count(@$search_results['qs']['matching_cats']).' albums with images';
700
701  if ( empty($by_weights) and empty($search_results['qs']['matching_cats']) )
702  {
703    return $search_results;
704  }
705
706  if (!empty($not_tag_ids))
707  {
708    $query = '
709SELECT image_id FROM '.IMAGE_TAG_TABLE.'
710  WHERE tag_id IN ('.implode(',',$not_tag_ids).')
711  GROUP BY image_id';
712      $result = pwg_query($query);
713      while ($row = pwg_db_fetch_row($result))
714      {
715        $id = $row[0];
716        unset($by_weights[$id]);
717      }
718      $debug[] = count($by_weights).' after not tags';
719  }
720  // Step 4 - now we have $by_weights ( array image id => weight ) that need
721  // permission checks and/or matching categories to get images from
722  $where_clauses = array();
723  if ( !empty($by_weights) )
724  {
725    $where_clauses[]='i.id IN ('
726      . implode(',', array_keys($by_weights)) . ')';
727  }
728  if ( !empty($search_results['qs']['matching_cats']) )
729  {
730    $where_clauses[]='category_id IN ('.
731      implode(',',array_keys($search_results['qs']['matching_cats'])).')';
732  }
733  $where_clauses = array( '('.implode("\n    OR ",$where_clauses).')' );
734  if (!empty($images_where))
735  {
736    $where_clauses[]='('.$images_where.')';
737  }
738  $where_clauses[] = get_sql_condition_FandF(
739      array
740        (
741          'forbidden_categories' => 'category_id',
742          'visible_categories' => 'category_id',
743          'visible_images' => 'i.id'
744        ),
745      null,true
746    );
747
748  $query = '
749SELECT DISTINCT(id)
750  FROM '.IMAGES_TABLE.' i
751    INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
752  WHERE '.implode("\n AND ", $where_clauses)."\n".
753  $conf['order_by'];
754
755  $allowed_images = array_from_query( $query, 'id');
756
757  $debug[] = count($allowed_images).' final photo count -->';
758  global $template;
759  $template->append('footer_elements', implode(', ', $debug) );
760
761  if ( $super_order_by or empty($by_weights) )
762  {
763    $search_results['items'] = $allowed_images;
764    return $search_results;
765  }
766
767  $allowed_images = array_flip( $allowed_images );
768  $divisor = 5.0 * count($allowed_images);
769  foreach ($allowed_images as $id=>$rank )
770  {
771    $weight = isset($by_weights[$id]) ? $by_weights[$id] : 1;
772    $weight -= $rank/$divisor;
773    $allowed_images[$id] = $weight;
774  }
775  arsort($allowed_images, SORT_NUMERIC);
776  $search_results['items'] = array_keys($allowed_images);
777  return $search_results;
778}
779
780/**
781 * returns an array of 'items' corresponding to the search id
782 *
783 * @param int search id
784 * @param string images_where optional aditional restriction on images table
785 * @return array
786 */
787function get_search_results($search_id, $super_order_by, $images_where='')
788{
789  $search = get_search_array($search_id);
790  if ( !isset($search['q']) )
791  {
792    $result['items'] = get_regular_search_results($search, $images_where);
793    return $result;
794  }
795  else
796  {
797    return get_quick_search_results($search['q'], $super_order_by, $images_where);
798  }
799}
800?>
Note: See TracBrowser for help on using the repository browser.