Search engine redesign, first part :

- new table #search to store search rules associated to a search id.

- search rules are not passed through GET anymore, the search array build in
  search.php is serialized in #search table, so no need to rebuild it in
  function include/functions_category.inc.php::category_initialize

- search array build code is improved (efficiency and layout) in search.php

- SQL related to search is build in a dedicated function
  include/functions::get_sql_search_clause

- direct search author:<...>, date_avalaible:<...>, date_creation:<...>,
  keywords:<...> from picture.php are not available anymore. They will come
  back later, with improvement (new design). Same for date_*:<> in calendar
  calendar category.


git-svn-id: http://piwigo.org/svn/trunk@1008 68402e56-0260-453c-a942-63ccdbb3a9ee
This commit is contained in:
plegall
2006-01-20 14:34:37 +00:00
parent 9410522e9f
commit 7b2ff328cb
7 changed files with 374 additions and 221 deletions
+1
View File
@@ -60,4 +60,5 @@ define('RATE_TABLE', $prefixeTable.'rate');
define('USER_CACHE_TABLE', $prefixeTable.'user_cache');
define('CADDIE_TABLE', $prefixeTable.'caddie');
define('UPGRADE_TABLE', $prefixeTable.'upgrade');
define('SEARCH_TABLE', $prefixeTable.'search');
?>
+184 -2
View File
@@ -741,8 +741,8 @@ function l10n($key)
}
/**
* returns the corresponding value from $themeconf if existing. Else, the key is
* returned
* returns the corresponding value from $themeconf if existing. Else, the
* key is returned
*
* @param string key
* @return string
@@ -753,4 +753,186 @@ function get_themeconf($key)
return $themeconf[$key];
}
/**
* Prepends and appends a string at each value of the given array.
*
* @param array
* @param string prefix to each array values
* @param string suffix to each array values
*/
function prepend_append_array_items($array, $prepend_str, $append_str)
{
array_walk(
$array,
create_function('&$s', '$s = "'.$prepend_str.'".$s."'.$append_str.'";')
);
return $array;
}
/**
* returns the SQL clause from a search identifier
*
* Search rules are stored in search table as a serialized array. This array
* need to be transformed into an SQL clause to be used in queries.
*
* @param int search_id
* @return string
*/
function get_sql_search_clause($search_id)
{
if (!is_numeric($search_id))
{
die('Search id must be an integer');
}
$query = '
SELECT rules
FROM '.SEARCH_TABLE.'
WHERE id = '.$_GET['search'].'
;';
list($serialized_rules) = mysql_fetch_row(pwg_query($query));
$search = unserialize($serialized_rules);
// echo '<pre>';
// print_r($search);
// echo '</pre>';
// SQL where clauses are stored in $clauses array during query
// construction
$clauses = array();
foreach (array('file','name','comment','keywords','author') as $textfield)
{
if (isset($search['fields'][$textfield]))
{
$local_clauses = array();
foreach ($search['fields'][$textfield]['words'] as $word)
{
array_push($local_clauses, $textfield." LIKE '%".$word."%'");
}
// adds brackets around where clauses
$local_clauses = prepend_append_array_items($local_clauses, '(', ')');
array_push(
$clauses,
implode(
' '.$search['fields'][$textfield]['mode'].' ',
$local_clauses
)
);
}
}
if (isset($search['fields']['allwords']))
{
$fields = array('file', 'name', 'comment', 'keywords', 'author');
// in the OR mode, request bust be :
// ((field1 LIKE '%word1%' OR field2 LIKE '%word1%')
// OR (field1 LIKE '%word2%' OR field2 LIKE '%word2%'))
//
// in the AND mode :
// ((field1 LIKE '%word1%' OR field2 LIKE '%word1%')
// AND (field1 LIKE '%word2%' OR field2 LIKE '%word2%'))
$word_clauses = array();
foreach ($search['fields']['allwords']['words'] as $word)
{
$field_clauses = array();
foreach ($fields as $field)
{
array_push($field_clauses, $field." LIKE '%".$word."%'");
}
// adds brackets around where clauses
array_push(
$word_clauses,
implode(
"\n OR ",
$field_clauses
)
);
}
array_walk(
$word_clauses,
create_function('&$s','$s="(".$s.")";')
);
array_push(
$clauses,
"\n ".
implode(
"\n ".
$search['fields']['allwords']['mode'].
"\n ",
$word_clauses
)
);
}
foreach (array('date_available', 'date_creation') as $datefield)
{
if (isset($search['fields'][$datefield]))
{
array_push(
$clauses,
$datefield." = '".$search['fields'][$datefield]['date']."'"
);
}
foreach (array('after','before') as $suffix)
{
$key = $datefield.'-'.$suffix;
if (isset($search['fields'][$key]))
{
array_push(
$clauses,
$datefield.
($suffix == 'after' ? ' >' : ' <').
($search['fields'][$key]['inc'] ? '=' : '').
" '".$search['fields'][$key]['date']."'"
);
}
}
}
if (isset($search['fields']['cat']))
{
if ($search['fields']['cat']['sub_inc'])
{
// searching all the categories id of sub-categories
$cat_ids = get_subcat_ids($search['fields']['cat']['words']);
}
else
{
$cat_ids = $search['fields']['cat']['words'];
}
$local_clause = 'category_id IN ('.implode(',', $cat_ids).')';
array_push($clauses, $local_clause);
}
// adds brackets around where clauses
$clauses = prepend_append_array_items($clauses, '(', ')');
$where_separator =
implode(
"\n ".$search['mode'].' ',
$clauses
);
$search_clause = $where_separator;
if (isset($forbidden))
{
$search_clause.= "\n AND ".$forbidden;
}
return $search_clause;
}
?>
+6 -146
View File
@@ -103,7 +103,9 @@ function check_cat_id( $cat )
{
$page['cat'] = $cat;
}
if ($cat == 'search' and isset($_GET['search']))
if ($cat == 'search'
and isset($_GET['search'])
and is_numeric($_GET['search']))
{
$page['cat'] = $cat;
}
@@ -381,44 +383,6 @@ function initialize_category( $calling_page = 'category' )
// search result
if ( $page['cat'] == 'search' )
{
// analyze search string given in URL (created in search.php)
$tokens = explode('|', $_GET['search']);
if (isset($tokens[1]) and $tokens[1] == 'AND')
{
$search['mode'] = 'AND';
}
else
{
$search['mode'] = 'OR';
}
$search_tokens = explode('--', $tokens[0]);
foreach ($search_tokens as $search_token)
{
$tokens = explode(':', $search_token);
$field_name = $tokens[0];
$field_content = $tokens[1];
$tokens = explode('~', $tokens[1]);
if (isset($tokens[1]))
{
$search['fields'][$field_name]['mode'] = $tokens[1];
}
else
{
$search['fields'][$field_name]['mode'] = '';
}
$search['fields'][$field_name]['words'] = array();
$tokens = explode(',', $tokens[0]);
foreach ($tokens as $token)
{
array_push($search['fields'][$field_name]['words'],
htmlentities($token));
}
}
$page['title'] = $lang['search_result'];
if ( $calling_page == 'picture' )
{
@@ -426,117 +390,13 @@ function initialize_category( $calling_page = 'category' )
$page['title'].= $_GET['search']."</span>";
}
// SQL where clauses are stored in $clauses array during query
// construction
$clauses = array();
$page['where'] = 'WHERE '.get_sql_search_clause($_GET['search']);
$textfields = array('file', 'name', 'comment', 'keywords', 'author');
foreach ($textfields as $textfield)
if (isset($forbidden))
{
if (isset($search['fields'][$textfield]))
{
$local_clauses = array();
foreach ($search['fields'][$textfield]['words'] as $word)
{
array_push($local_clauses, $textfield." LIKE '%".$word."%'");
}
// adds brackets around where clauses
array_walk($local_clauses,create_function('&$s','$s="(".$s.")";'));
array_push($clauses,
implode(' '.$search['fields'][$textfield]['mode'].' ',
$local_clauses));
}
$page['where'].= "\n AND ".$forbidden;
}
if (isset($search['fields']['allwords']))
{
$fields = array('file', 'name', 'comment', 'keywords', 'author');
// in the OR mode, request bust be :
// ((field1 LIKE '%word1%' OR field2 LIKE '%word1%')
// OR (field1 LIKE '%word2%' OR field2 LIKE '%word2%'))
//
// in the AND mode :
// ((field1 LIKE '%word1%' OR field2 LIKE '%word1%')
// AND (field1 LIKE '%word2%' OR field2 LIKE '%word2%'))
$word_clauses = array();
foreach ($search['fields']['allwords']['words'] as $word)
{
$field_clauses = array();
foreach ($fields as $field)
{
array_push($field_clauses, $field." LIKE '%".$word."%'");
}
// adds brackets around where clauses
array_push($word_clauses, implode(' OR ', $field_clauses));
}
array_walk($word_clauses, create_function('&$s','$s="(".$s.")";'));
array_push($clauses,
implode(' '.$search['fields']['allwords']['mode'].' ',
$word_clauses));
}
$datefields = array('date_available', 'date_creation');
foreach ($datefields as $datefield)
{
$key = $datefield;
if (isset($search['fields'][$key]))
{
$local_clause = $datefield." = '";
$local_clause.= str_replace('.', '-',
$search['fields'][$key]['words'][0]);
$local_clause.= "'";
array_push($clauses, $local_clause);
}
foreach (array('after','before') as $suffix)
{
$key = $datefield.'-'.$suffix;
if (isset($search['fields'][$key]))
{
$local_clause = $datefield;
if ($suffix == 'after')
{
$local_clause.= ' >';
}
else
{
$local_clause.= ' <';
}
if (isset($search['fields'][$key]['mode'])
and $search['fields'][$key]['mode'] == 'inc')
{
$local_clause.= '=';
}
$local_clause.= " '";
$local_clause.= str_replace('.', '-',
$search['fields'][$key]['words'][0]);
$local_clause.= "'";
array_push($clauses, $local_clause);
}
}
}
if (isset($search['fields']['cat']))
{
if ($search['fields']['cat']['mode'] == 'sub_inc')
{
// searching all the categories id of sub-categories
$cat_ids = get_subcat_ids($search['fields']['cat']['words']);
}
else
{
$cat_ids = $search['fields']['cat']['words'];
}
$local_clause = 'category_id IN ('.implode(',', $cat_ids).')';
array_push($clauses, $local_clause);
}
// adds brackets around where clauses
array_walk($clauses, create_function('&$s', '$s = "(".$s.")";'));
$page['where'] = 'WHERE '.implode(' '.$search['mode'].' ', $clauses);
if ( isset( $forbidden ) ) $page['where'].= ' AND '.$forbidden;
$query = '
SELECT COUNT(DISTINCT(id)) AS nb_total_images
FROM '.IMAGES_TABLE.'