Changeset 1537


Ignore:
Timestamp:
Aug 15, 2006, 4:06:06 AM (18 years ago)
Author:
rvelices
Message:

feature 519: quick search (first version)

Location:
trunk
Files:
1 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/config_default.inc.php

    r1531 r1537  
    207207
    208208// enabled_format_email:
    209 //  on true email will be formatted with name and address 
     209//  on true email will be formatted with name and address
    210210//  on false email will be only address
    211211// There are webhosting wich not allow email formatted (Lycos, ...)
     
    474474$conf['full_tag_cloud_items_number'] = 200;
    475475
     476// menubar_tag_cloud_items_number: number of tags to show in the tag
     477// cloud in the menubar. Only the most represented tags will be shown
     478$conf['menubar_tag_cloud_items_number'] = 100;
     479
     480// content_tag_cloud_items_number: number of tags to show in the tag
     481// cloud on the content page. Only the most represented tags will be shown
     482$conf['content_tag_cloud_items_number'] = 12;
     483
    476484// tags_levels: number of levels to use for display. Each level is bind to a
    477485// CSS class tagLevelX.
     
    506514//        null value, user_layout is used for admin layout
    507515//        defined value, this value are used for admin layout
    508 // Next on step 2, default_admin_layout will be used 
     516// Next on step 2, default_admin_layout will be used
    509517//                 if there are not checked like admin layout
    510518// stored on user informations
  • trunk/include/functions_search.inc.php

    r1119 r1537  
    7474 * need to be transformed into an SQL clause to be used in queries.
    7575 *
    76  * @param int search_id
     76 * @param array search
    7777 * @return string
    7878 */
    79 function get_sql_search_clause($search_id)
    80 {
    81   $search = get_search_array($search_id);
    82 
     79function get_sql_search_clause($search)
     80{
    8381  // SQL where clauses are stored in $clauses array during query
    8482  // construction
     
    213211
    214212/**
    215  * returns the list of items corresponding to the search id
    216  *
    217  * @param int search id
     213 * returns the list of items corresponding to the advanced search array
     214 *
     215 * @param array search
    218216 * @return array
    219217 */
    220 function get_search_items($search_id)
     218function get_regular_search_results($search)
    221219{
    222220  $items = array();
    223  
    224   $search_clause = get_sql_search_clause($search_id);
    225  
     221
     222  $search_clause = get_sql_search_clause($search);
     223
    226224  if (!empty($search_clause))
    227225  {
     
    270268    }
    271269  }
    272  
     270
    273271  return $items;
    274272}
     273
     274
     275if (!function_exists('array_intersect_key')) {
     276   function array_intersect_key()
     277   {
     278       $arrs = func_get_args();
     279       $result = array_shift($arrs);
     280       foreach ($arrs as $array) {
     281           foreach ($result as $key => $v) {
     282               if (!array_key_exists($key, $array)) {
     283                   unset($result[$key]);
     284               }
     285           }
     286       }
     287       return $result;
     288   }
     289}
     290
     291
     292function get_qsearch_like_clause($q, $field)
     293{
     294  $tokens = preg_split('/[\s,.;!\?]+/', $q);
     295  for ($i=0; $i<count($tokens); $i++)
     296  {
     297    $tokens[$i]=str_replace('*','%', $tokens[$i]);
     298    if (preg_match('/^[+<>]/',$tokens[$i]) )
     299      $tokens[$i]=substr($tokens[$i], 1);
     300    else if (substr($tokens[$i], 0, 1)=='-')
     301    {
     302      unset($tokens[$i]);
     303      $i--;
     304    }
     305  }
     306
     307  if (!empty($tokens))
     308  {
     309    $query = '(';
     310    for ($i=0; $i<count($tokens); $i++)
     311    {
     312      if ($i>0) $query .= 'OR ';
     313      $query .= ' '.$field.' LIKE "%'.$tokens[$i].'%" ';
     314    }
     315    $query .= ')';
     316    return $query;
     317  }
     318  return null;
     319}
     320
     321
     322/**
     323 * returns the search results corresponding to a quick search
     324 *
     325 * @param string q
     326 * @return array
     327 */
     328function get_quick_search_results($q)
     329{
     330  global $user, $page;
     331  $search_results = array();
     332
     333  $q_like_clause = get_qsearch_like_clause($q, 'CONVERT(name, CHAR)' );
     334  $by_tag_weights=array();
     335  if (!empty($q_like_clause))
     336  {
     337    $query = '
     338SELECT id
     339  FROM '.TAGS_TABLE.'
     340  WHERE '.$q_like_clause;
     341    $tag_ids = array_from_query( $query, 'id');
     342    if (!empty($tag_ids))
     343    {
     344      $query = '
     345SELECT image_id, COUNT(tag_id) AS q
     346  FROM '.IMAGE_TAG_TABLE.'
     347  WHERE tag_id IN ('.implode(',',$tag_ids).')
     348  GROUP BY image_id';
     349      $result = pwg_query($query);
     350      while ($row = mysql_fetch_array($result))
     351      {
     352        $by_tag_weights[(int)$row['image_id']] = $row['q'];
     353      }
     354    }
     355  }
     356
     357  $query = '
     358SELECT
     359  i.id, i.file, CAST( CONCAT_WS(" ",
     360    IFNULL(i.name,""),
     361    IFNULL(i.comment,""),
     362    IFNULL(GROUP_CONCAT(DISTINCT co.content),""),
     363    IFNULL(GROUP_CONCAT(DISTINCT c.dir),""),
     364    IFNULL(GROUP_CONCAT(DISTINCT c.name),""),
     365    IFNULL(GROUP_CONCAT(DISTINCT c.comment),"") ) AS CHAR) AS ft
     366FROM (
     367  (
     368    '.IMAGES_TABLE.' i LEFT JOIN '.COMMENTS_TABLE.' co on i.id=co.image_id
     369  )
     370    INNER JOIN
     371  '.IMAGE_CATEGORY_TABLE.' ic on ic.image_id=i.id
     372  )
     373    INNER JOIN
     374  '.CATEGORIES_TABLE.' c on c.id=ic.category_id
     375WHERE category_id NOT IN ('.$user['forbidden_categories'].')
     376GROUP BY i.id';
     377
     378  $query = 'SELECT id, MATCH(ft) AGAINST( "'.$q.'" IN BOOLEAN MODE) AS q FROM ('.$query.') AS Y
     379WHERE MATCH(ft) AGAINST( "'.$q.'" IN BOOLEAN MODE)';
     380
     381  $q_like_clause = get_qsearch_like_clause($q, 'file' );
     382  if (! empty($q_like_clause) )
     383  {
     384    $query .= ' OR '.$q_like_clause;
     385  }
     386
     387  $by_weights=array();
     388  $result = pwg_query($query);
     389  while ($row = mysql_fetch_array($result))
     390  {
     391    $by_weights[(int)$row['id']] = $row['q'] ? $row['q'] : 0;
     392  }
     393
     394  foreach ( $by_weights as $image=>$w )
     395  {
     396    $by_tag_weights[$image] = 2*$w+ (isset($by_tag_weights[$image])?$by_tag_weights[$image]:0);
     397  }
     398
     399  if ( empty($by_tag_weights) or isset($page['super_order_by']) )
     400  {
     401    if (! isset($page['super_order_by']) )
     402    {
     403      arsort($by_tag_weights, SORT_NUMERIC);
     404      $search_results['as_is']=1;
     405    }
     406    $search_results['items'] = array_keys($by_tag_weights);
     407  }
     408  else
     409  {
     410    $query = '
     411SELECT DISTINCT(id)
     412  FROM '.IMAGES_TABLE.'
     413    INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
     414  WHERE id IN ('.implode(',', array_keys($by_tag_weights) ).')
     415    AND category_id NOT IN ('.$user['forbidden_categories'].')';
     416
     417    $allowed_image_ids = array_from_query( $query, 'id');
     418    $by_tag_weights = array_intersect_key($by_tag_weights, array_flip($allowed_image_ids));
     419    arsort($by_tag_weights, SORT_NUMERIC);
     420    $search_results = array(
     421          'items'=>array_keys($by_tag_weights),
     422          'as_is'=>1
     423        );
     424  }
     425  return $search_results;
     426}
     427
     428/**
     429 * returns an array of 'items' corresponding to the search id
     430 *
     431 * @param int search id
     432 * @return array
     433 */
     434function get_search_results($search_id)
     435{
     436  $search = get_search_array($search_id);
     437  if ( !isset($search['q']) )
     438  {
     439    $result['items'] = get_regular_search_results($search);
     440    return $result;
     441  }
     442  else
     443  {
     444    return get_quick_search_results($search['q']);
     445  }
     446}
    275447?>
  • trunk/include/functions_tag.inc.php

    • Property svn:eol-style set to native
    r1310 r1537  
    222222  }
    223223}
     224
     225/**
     226 * return a list of tags corresponding to given items.
     227 *
     228 * @param array items
     229 * @param array max_tags
     230 * @param array excluded_tag_ids
     231 * @return array
     232 */
     233function get_common_tags($items, $max_tags, $excluded_tag_ids=null)
     234{
     235  if (empty($items))
     236  {
     237    return array();
     238  }
     239  $query = '
     240SELECT tag_id, name, url_name, count(*) counter
     241  FROM '.IMAGE_TAG_TABLE.'
     242    INNER JOIN '.TAGS_TABLE.' ON tag_id = id
     243  WHERE image_id IN ('.implode(',', $items).')';
     244  if (!empty($excluded_tag_ids))
     245  {
     246    $query.='
     247    AND tag_id NOT IN ('.implode(',', $excluded_tag_ids).')';
     248  }
     249  $query .='
     250  GROUP BY tag_id
     251  ORDER BY counter DESC';
     252  if ($max_tags>0)
     253  {
     254    $query .= '
     255  LIMIT 0,'.$max_tags;
     256  }
     257
     258  $result = pwg_query($query);
     259  $tags = array();
     260  while($row = mysql_fetch_array($result))
     261  {
     262    array_push($tags, $row);
     263  }
     264  usort($tags, 'name_compare');
     265  return $tags;
     266}
    224267?>
  • trunk/include/menubar.inc.php

    r1511 r1537  
    7777  if ( !empty($page['items']) )
    7878  {
    79     $query = '
    80 SELECT tag_id, name, url_name, count(*) counter
    81   FROM '.IMAGE_TAG_TABLE.'
    82     INNER JOIN '.TAGS_TABLE.' ON tag_id = id
    83   WHERE image_id IN ('.implode(',', $items).')
    84     AND tag_id NOT IN ('.implode(',', $page['tag_ids']).')
    85   GROUP BY tag_id
    86   ORDER BY name ASC
    87 ;';
    88     $result = pwg_query($query);
    89     while($row = mysql_fetch_array($result))
    90     {
    91       array_push($tags, $row);
    92     }
     79    $tags = get_common_tags($page['items'],
     80        $conf['menubar_tag_cloud_items_number'], $page['tag_ids']);
    9381  }
    9482
     
    270258    )
    271259  );
     260$template->assign_block_vars( 'summary.quick_search',  array() );
    272261
    273262// comments link
  • trunk/include/section_init.inc.php

    r1500 r1537  
    451451    include_once( PHPWG_ROOT_PATH .'include/functions_search.inc.php' );
    452452
    453     $search_items = get_search_items($page['search']);
    454     if ( !empty($search_items) )
     453    $search_result = get_search_results($page['search']);
     454    if ( !empty($search_result['items']) and !isset($search_result['as_is']) )
    455455    {
    456456      $query = '
     
    458458  FROM '.IMAGES_TABLE.'
    459459    INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
    460   WHERE id IN ('.implode(',', $search_items).')
     460  WHERE id IN ('.implode(',', $search_result['items']).')
    461461    AND '.$forbidden.'
    462462  '.$conf['order_by'].'
     
    466466    else
    467467    {
    468       $page['items'] = array();
     468      $page['items'] = $search_result['items'];
    469469    }
    470470
  • trunk/index.php

    r1511 r1537  
    199199  }
    200200
     201if ( $page['section']=='search' and $page['start']==0 )
     202{
     203  $tags = get_common_tags($page['items'],
     204      $conf['content_tag_cloud_items_number'], null);
     205  if ( count($tags)>1 )
     206  {
     207    $template->assign_block_vars('related_tags', array() );
     208
     209    $tags = add_level_to_tags($tags);
     210    foreach ($tags as $tag)
     211    {
     212      $template->assign_block_vars(
     213      'related_tags.tag', array(
     214        'URL' => make_index_url(
     215          array(
     216            'tags' => array(
     217              array(
     218                'id' => $tag['tag_id'],
     219                'url_name' => $tag['url_name'],
     220                ),
     221              )
     222            )
     223          ),
     224        'NAME' => $tag['name'],
     225        'TITLE' => sprintf(
     226          l10n('%d pictures are also linked to current tags'),
     227          $tag['counter']
     228          ),
     229        'CLASS' => 'tagLevel'.$tag['level']
     230        )
     231      );
     232    }
     233  }
     234}
     235
    201236//------------------------------------------------------ main part : thumbnails
    202237if (isset($page['thumbnails_include']))
  • trunk/search_rules.php

    r1119 r1537  
    6262$search = get_search_array($_GET['search_id']);
    6363
    64 $template->assign_vars(
    65   array(
    66     'INTRODUCTION'
    67       => 'OR' == $search['mode']
    68       ? l10n('At least one listed rule must be satisfied.')
    69       : l10n('Each listed rule must be satisfied.'),
    70     )
    71   );
     64if (isset($search['q']))
     65{
     66  $template->assign_block_vars(
     67    'words',
     68    array(
     69      'CONTENT' => $search['q']
     70        )
     71    );
     72}
     73else
     74{
     75  $template->assign_vars(
     76    array(
     77      'INTRODUCTION'
     78        => 'OR' == $search['mode']
     79        ? l10n('At least one listed rule must be satisfied.')
     80        : l10n('Each listed rule must be satisfied.'),
     81      )
     82    );
     83}
    7284
    7385if (isset($search['fields']['allwords']))
  • trunk/template/yoga/default-layout.css

    r1506 r1537  
    238238}
    239239
    240 #fullTagCloud { font-size: 140%; }
    241 
    242 #fullTagCloud LI { display: inline; }
     240#fullTagCloud {
     241  font-size: 140%;
     242  text-align: justify;
     243  padding: 0;
     244  margin: 1em 2em 1em 2em;
     245}
     246
     247#fullTagCloud LI {
     248  display: inline;
     249  white-space: nowrap;
     250}
     251
     252#content #fullTagCloud {
     253  font-size: 120%;
     254}
    243255
    244256.tagLevel5 { font-size: 150%; }
  • trunk/template/yoga/index.tpl

    r1384 r1537  
    9191<!-- END cat_infos -->
    9292
     93<!-- BEGIN related_tags -->
     94  <ul id="fullTagCloud">
     95    <li>{lang:Related tags}:</li>
     96    <!-- BEGIN tag -->
     97    <li><a href="{related_tags.tag.URL}" class="{related_tags.tag.CLASS}" title="{related_tags.tag.TITLE}">{related_tags.tag.NAME}</a></li>
     98    <!-- END tag -->
     99  </ul>
     100<!-- END related_tags -->
     101
     102
    93103</div> <!-- content -->
  • trunk/template/yoga/menubar.css

    r1513 r1537  
    5858
    5959/* quickconnect form */
    60 FORM#quickconnect { 
     60FORM#quickconnect {
    6161  margin: 0;
    6262  padding: 5px;
     
    115115}*/
    116116
     117FORM#quicksearch {
     118  margin-top: 4px;
     119  margin-bottom: 1px;
     120}
     121
    117122#menubar #menuTagCloud {
    118123  text-align: center;
  • trunk/template/yoga/menubar.tpl

    • Property svn:eol-style set to native
    r1491 r1537  
    5252    <ul>
    5353      <!-- BEGIN summary -->
     54      <!-- BEGIN quick_search -->
     55      <form action="{pwg_root}qsearch.php" method="get" id="quicksearch"><input type="text" name="q" id="qsearchInput" onfocus="if (value==qsearch_prompt) value='';" onblur="if (value=='') value=qsearch_prompt;"></form>
     56      <script type="text/javascript">var qsearch_prompt="{lang:search}"; document.getElementById('qsearchInput').value=qsearch_prompt;</script>
     57      <!-- END quick_search -->
    5458      <li><a href="{summary.U_SUMMARY}" title="{summary.TITLE}" {summary.REL}>{summary.NAME}</a></li>
    5559      <!-- END summary -->
Note: See TracChangeset for help on using the changeset viewer.