diff --git a/include/functions_search.inc.php b/include/functions_search.inc.php index 2d6ba1bcc..124e2fcb6 100644 --- a/include/functions_search.inc.php +++ b/include/functions_search.inc.php @@ -616,6 +616,74 @@ SELECT ); } +/** + * Returns the SQL WHERE clause to be used to build filter values + * + * @since 15 + * + * @param string $filter_name + * + * @return string + */ +function get_clause_for_filter($filter_name) +{ + global $page; + + $other_filters_items = get_items_for_filter($filter_name); + if (false === $other_filters_items) + { + return '1=1'.$page['search_details']['forbidden']; + } + + return 'image_id IN ('.implode(',', $other_filters_items).')'; +} + +/** + * Returns the list of items (image_ids) to be used to build filter values + * for a given filter. Depends on the other filters. Use a cache to avoid + * computing the same large array_intersect several times. + * + * @since 15 + * + * @param string $filter_name + * + * @return array of image_ids (or false) + */ +function get_items_for_filter($filter_name) +{ + global $page, $logger; + + $other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array($filter_name)); + + if (empty($other_filters)) + { + return false; + } + + $cache_key = md5(implode(',', $other_filters)); + + if (!isset($page['search_details'][__FUNCTION__][$cache_key])) + { + $function_start = get_moment(); + + $other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)]; + foreach ($other_filters as $other_filter) + { + $other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]); + } + + $other_filters_items = array_unique($other_filters_items); + + $debug_msg = '['.__FUNCTION__.'] cache computed for '.(count($other_filters)+1).' other filters'; + $debug_msg.= ' ('.count($other_filters_items).' items)'; + $debug_msg.= ', time = '.get_elapsed_time($function_start, get_moment()); + $logger->debug($debug_msg); + + @$page['search_details'][__FUNCTION__][$cache_key] = $other_filters_items; + } + + return $page['search_details'][__FUNCTION__][$cache_key]; +} define('QST_QUOTED', 0x01); diff --git a/index.php b/index.php index 05d095f80..968c7adc0 100644 --- a/index.php +++ b/index.php @@ -183,7 +183,7 @@ if ( empty($page['is_external']) ) $my_search = get_search_array($page['search']); - $search_forbidden = get_sql_condition_FandF( + $page['search_details']['forbidden'] = get_sql_condition_FandF( array( 'forbidden_categories' => 'category_id', 'visible_categories' => 'category_id', @@ -215,16 +215,14 @@ if ( empty($page['is_external']) ) // TODO calling get_available_tags(), with lots of photos/albums/tags may cost time, // we should reuse the result if already executed (for building the menu for example) - $other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('tags')); - if (count($other_filters) > 0) + $other_filters_items = get_items_for_filter('tags'); + if (false === $other_filters_items) + { + $filter_tags = get_available_tags(); + usort($filter_tags, 'tag_alpha_compare'); + } + else { - $other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)]; - foreach ($other_filters as $other_filter) - { - $other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]); - } - $other_filters_items = array_unique($other_filters_items); - $filter_tags = get_common_tags($other_filters_items, 0); // the user may have started a search on 2 or more tags that have no @@ -238,11 +236,6 @@ if ( empty($page['is_external']) ) $filter_tags = array_merge(get_available_tags($missing_tag_ids), $filter_tags); } } - else - { - $filter_tags = get_available_tags(); - usort($filter_tags, 'tag_alpha_compare'); - } $template->assign('TAGS', $filter_tags); @@ -254,22 +247,7 @@ if ( empty($page['is_external']) ) if (isset($my_search['fields']['author'])) { - $other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('author')); - if (count($other_filters) > 0) - { - $other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)]; - foreach ($other_filters as $other_filter) - { - $other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]); - } - $other_filters_items = array_unique($other_filters_items); - - $filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')'; - } - else - { - $filter_clause = '1=1'.$search_forbidden; - } + $filter_clause = get_clause_for_filter('author'); $query = ' SELECT @@ -295,22 +273,7 @@ SELECT if (isset($my_search['fields']['date_posted'])) { - $other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('date_posted')); - if (count($other_filters) > 0) - { - $other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)]; - foreach ($other_filters as $other_filter) - { - $other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]); - } - $other_filters_items = array_unique($other_filters_items); - - $filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')'; - } - else - { - $filter_clause = '1=1'.$search_forbidden; - } + $filter_clause = get_clause_for_filter('date_posted'); $query = ' SELECT @@ -390,22 +353,7 @@ SELECT if (isset($my_search['fields']['added_by'])) { - $other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('added_by')); - if (count($other_filters) > 0) - { - $other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)]; - foreach ($other_filters as $other_filter) - { - $other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]); - } - $other_filters_items = array_unique($other_filters_items); - - $filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')'; - } - else - { - $filter_clause = '1=1'.$search_forbidden; - } + $filter_clause = get_clause_for_filter('added_by'); $query = ' SELECT @@ -483,22 +431,7 @@ SELECT if (isset($my_search['fields']['filetypes'])) { - $other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('filetypes')); - if (count($other_filters) > 0) - { - $other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)]; - foreach ($other_filters as $other_filter) - { - $other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]); - } - $other_filters_items = array_unique($other_filters_items); - - $filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')'; - } - else - { - $filter_clause = '1=1'.$search_forbidden; - } + $filter_clause = get_clause_for_filter('filetypes'); $query = ' SELECT @@ -516,22 +449,7 @@ SELECT // For rating if (isset($my_search['fields']['ratings'])) { - $other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('ratings')); - if (count($other_filters) > 0) - { - $other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)]; - foreach ($other_filters as $other_filter) - { - $other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]); - } - $other_filters_items = array_unique($other_filters_items); - - $filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')'; - } - else - { - $filter_clause = '1=1'.$search_forbidden; - } + $filter_clause = get_clause_for_filter('ratings'); $ratings = array_fill(0, 6, 0); @@ -573,22 +491,7 @@ SELECT // For filesize if (isset($my_search['fields']['filesize_min']) && isset($my_search['fields']['filesize_max'])) { - $other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('filesize')); - if (count($other_filters) > 0) - { - $other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)]; - foreach ($other_filters as $other_filter) - { - $other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]); - } - $other_filters_items = array_unique($other_filters_items); - - $filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')'; - } - else - { - $filter_clause = '1=1'.$search_forbidden; - } + $filter_clause = get_clause_for_filter('filesize'); $filesizes = array(); $filesize = array(); @@ -635,22 +538,7 @@ SELECT if (isset($my_search['fields']['ratios'])) { - $other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('ratios')); - if (count($other_filters) > 0) - { - $other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)]; - foreach ($other_filters as $other_filter) - { - $other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]); - } - $other_filters_items = array_unique($other_filters_items); - - $filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')'; - } - else - { - $filter_clause = '1=1'.$search_forbidden; - } + $filter_clause = get_clause_for_filter('ratios'); $query = ' SELECT @@ -696,22 +584,7 @@ SELECT if (isset($my_search['fields']['height_min']) and isset($my_search['fields']['height_max'])) { - $other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('height')); - if (count($other_filters) > 0) - { - $other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)]; - foreach ($other_filters as $other_filter) - { - $other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]); - } - $other_filters_items = array_unique($other_filters_items); - - $filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')'; - } - else - { - $filter_clause = '1=1'.$search_forbidden; - } + $filter_clause = get_clause_for_filter('height'); $query = ' SELECT @@ -742,22 +615,7 @@ SELECT if (isset($my_search['fields']['width_min']) and isset($my_search['fields']['width_max'])) { - $other_filters = array_diff(array_keys($page['search_details']['image_ids_for_filter']), array('width')); - if (count($other_filters) > 0) - { - $other_filters_items = $page['search_details']['image_ids_for_filter'][array_shift($other_filters)]; - foreach ($other_filters as $other_filter) - { - $other_filters_items = array_intersect($other_filters_items, $page['search_details']['image_ids_for_filter'][$other_filter]); - } - $other_filters_items = array_unique($other_filters_items); - - $filter_clause = 'image_id IN ('.implode(',', $other_filters_items).')'; - } - else - { - $filter_clause = '1=1'.$search_forbidden; - } + $filter_clause = get_clause_for_filter('width'); $query = ' SELECT