From c5cd5cd2165c0077b1981bec4fc975c9c60f27ab Mon Sep 17 00:00:00 2001 From: plegall Date: Thu, 30 Mar 2017 15:27:20 +0200 Subject: [PATCH] issue #343, quick search takes album into account I basically duplicated qsearch_get_tags as qsearch_get_categories and replaced "tag" by "cat" + obvious changes like table name to query. I also used the resulting $qsr->cat_iids for merging with other results. --- include/functions_search.inc.php | 98 +++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/include/functions_search.inc.php b/include/functions_search.inc.php index a9c3af0c6..7f1437bd6 100644 --- a/include/functions_search.inc.php +++ b/include/functions_search.inc.php @@ -908,6 +908,9 @@ class QResults var $all_tags; var $tag_ids; var $tag_iids; + var $all_cats; + var $cat_ids; + var $cat_iids; var $images_iids; var $iids; } @@ -1120,6 +1123,91 @@ SELECT image_id FROM '.IMAGE_TAG_TABLE.' $qsr->tag_ids = $token_tag_ids; } +function qsearch_get_categories(QExpression $expr, QResults $qsr) +{ + $token_cat_ids = $qsr->cat_iids = array_fill(0, count($expr->stokens), array() ); + $all_cats = array(); + + for ($i=0; $istokens); $i++) + { + $token = $expr->stokens[$i]; + if (isset($token->scope) && 'category' != $token->scope->id) // not relevant yet + continue; + if (empty($token->term)) + continue; + + $clauses = qsearch_get_text_token_search_sql( $token, array('name', 'comment')); + $query = 'SELECT * FROM '.CATEGORIES_TABLE.' +WHERE ('. implode("\n OR ",$clauses) .')'; + $result = pwg_query($query); + while ($cat = pwg_db_fetch_assoc($result)) + { + $token_cat_ids[$i][] = $cat['id']; + $all_cats[$cat['id']] = $cat; + } + } + + // check adjacent short words + for ($i=0; $istokens)-1; $i++) + { + if ( (strlen($expr->stokens[$i]->term)<=3 || strlen($expr->stokens[$i+1]->term)<=3) + && (($expr->stoken_modifiers[$i] & (QST_QUOTED|QST_WILDCARD)) == 0) + && (($expr->stoken_modifiers[$i+1] & (QST_BREAK|QST_QUOTED|QST_WILDCARD)) == 0) ) + { + $common = array_intersect( $token_cat_ids[$i], $token_cat_ids[$i+1] ); + if (count($common)) + { + $token_cat_ids[$i] = $token_cat_ids[$i+1] = $common; + } + } + } + + // get images + $positive_ids = $not_ids = array(); + for ($i=0; $istokens); $i++) + { + $cat_ids = $token_cat_ids[$i]; + $token = $expr->stokens[$i]; + + if (!empty($cat_ids)) + { + $query = ' +SELECT image_id FROM '.IMAGE_CATEGORY_TABLE.' + WHERE category_id IN ('.implode(',',$cat_ids).') + GROUP BY image_id'; + $qsr->cat_iids[$i] = query2array($query, null, 'image_id'); + if ($expr->stoken_modifiers[$i]&QST_NOT) + $not_ids = array_merge($not_ids, $cat_ids); + else + { + if (strlen($token->term)>2 || count($expr->stokens)==1 || isset($token->scope) || ($token->modifier&(QST_WILDCARD|QST_QUOTED)) ) + {// add cat ids to list only if the word is not too short (such as de / la /les ...) + $positive_ids = array_merge($positive_ids, $cat_ids); + } + } + } + elseif (isset($token->scope) && 'category' == $token->scope->id && strlen($token->term)==0) + { + if ($token->modifier & QST_WILDCARD) + {// eg. 'category:*' returns all images associated to an album + $qsr->cat_iids[$i] = query2array('SELECT DISTINCT image_id FROM '.IMAGE_CATEGORY_TABLE, null, 'image_id'); + } + else + {// eg. 'category:' returns all orphan images + $qsr->tag_iids[$i] = query2array('SELECT id FROM '.IMAGES_TABLE.' LEFT JOIN '.IMAGE_CATEGORY_TABLE.' ON id=image_id WHERE image_id IS NULL', null, 'id'); + } + } + } + + $all_cats = array_intersect_key($all_cats, array_flip( array_diff($positive_ids, $not_ids) ) ); + usort($all_cats, 'tag_alpha_compare'); + foreach ( $all_cats as &$cat ) + { + $cat['name'] = trigger_change('render_category_name', $cat['name'], $cat); + } + $qsr->all_cats = $all_cats; + $qsr->cat_ids = $token_cat_ids; +} function qsearch_eval(QMultiToken $expr, QResults $qsr, &$qualifies, &$ignored_terms) @@ -1134,7 +1222,13 @@ function qsearch_eval(QMultiToken $expr, QResults $qsr, &$qualifies, &$ignored_t $crt = $expr->tokens[$i]; if ($crt->is_single) { - $crt_ids = $qsr->iids[$crt->idx] = array_unique( array_merge($qsr->images_iids[$crt->idx], $qsr->tag_iids[$crt->idx]) ); + $crt_ids = $qsr->iids[$crt->idx] = array_unique( + array_merge( + $qsr->images_iids[$crt->idx], + $qsr->cat_iids[$crt->idx], + $qsr->tag_iids[$crt->idx] + ) + ); $crt_qualifies = count($crt_ids)>0 || count($qsr->tag_ids[$crt->idx])>0; $crt_ignored_terms = $crt_qualifies ? array() : array((string)$crt); } @@ -1287,6 +1381,7 @@ function get_quick_search_results_no_cache($q, $options) } $qsr = new QResults; qsearch_get_tags($expression, $qsr); + qsearch_get_categories($expression, $qsr); qsearch_get_images($expression, $qsr); // allow plugins to evaluate their own scopes @@ -1305,6 +1400,7 @@ function get_quick_search_results_no_cache($q, $options) $debug[] = 'before perms '.count($ids); $search_results['qs']['matching_tags'] = $qsr->all_tags; + $search_results['qs']['matching_cats'] = $qsr->all_cats; $search_results = trigger_change('qsearch_results', $search_results, $expression, $qsr); global $template;