source: branches/1.6/include/functions_search.inc.php @ 27047

Last change on this file since 27047 was 1119, checked in by plg, 19 years ago

improvement: tags replace keywords. Better data model, less
limitations. Each image can be associated to as many tag as needed. Tags can
contain non ASCII characters. Oriented navigation with tags by association.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.1 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | PhpWebGallery - a PHP based picture gallery                           |
4// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
5// | Copyright (C) 2003-2006 PhpWebGallery Team - http://phpwebgallery.net |
6// +-----------------------------------------------------------------------+
7// | branch        : BSF (Best So Far)
8// | file          : $Id: functions_search.inc.php 1119 2006-04-02 22:26:19Z plg $
9// | last update   : $Date: 2006-04-02 22:26:19 +0000 (Sun, 02 Apr 2006) $
10// | last modifier : $Author: plg $
11// | revision      : $Revision: 1119 $
12// +-----------------------------------------------------------------------+
13// | This program is free software; you can redistribute it and/or modify  |
14// | it under the terms of the GNU General Public License as published by  |
15// | the Free Software Foundation                                          |
16// |                                                                       |
17// | This program is distributed in the hope that it will be useful, but   |
18// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
19// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
20// | General Public License for more details.                              |
21// |                                                                       |
22// | You should have received a copy of the GNU General Public License     |
23// | along with this program; if not, write to the Free Software           |
24// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
25// | USA.                                                                  |
26// +-----------------------------------------------------------------------+
27
28
29/**
30 * Prepends and appends a string at each value of the given array.
31 *
32 * @param array
33 * @param string prefix to each array values
34 * @param string suffix to each array values
35 */
36function prepend_append_array_items($array, $prepend_str, $append_str)
37{
38  array_walk(
39    $array,
40    create_function('&$s', '$s = "'.$prepend_str.'".$s."'.$append_str.'";')
41    );
42
43  return $array;
44}
45
46/**
47 * returns search rules stored into a serialized array in "search"
48 * table. Each search rules set is numericaly identified.
49 *
50 * @param int search_id
51 * @return array
52 */
53function get_search_array($search_id)
54{
55  if (!is_numeric($search_id))
56  {
57    die('Search id must be an integer');
58  }
59
60  $query = '
61SELECT rules
62  FROM '.SEARCH_TABLE.'
63  WHERE id = '.$search_id.'
64;';
65  list($serialized_rules) = mysql_fetch_row(pwg_query($query));
66
67  return unserialize($serialized_rules);
68}
69
70/**
71 * returns the SQL clause from a search identifier
72 *
73 * Search rules are stored in search table as a serialized array. This array
74 * need to be transformed into an SQL clause to be used in queries.
75 *
76 * @param int search_id
77 * @return string
78 */
79function get_sql_search_clause($search_id)
80{
81  $search = get_search_array($search_id);
82
83  // SQL where clauses are stored in $clauses array during query
84  // construction
85  $clauses = array();
86
87  foreach (array('file','name','comment','author') as $textfield)
88  {
89    if (isset($search['fields'][$textfield]))
90    {
91      $local_clauses = array();
92      foreach ($search['fields'][$textfield]['words'] as $word)
93      {
94        array_push($local_clauses, $textfield." LIKE '%".$word."%'");
95      }
96
97      // adds brackets around where clauses
98      $local_clauses = prepend_append_array_items($local_clauses, '(', ')');
99
100      array_push(
101        $clauses,
102        implode(
103          ' '.$search['fields'][$textfield]['mode'].' ',
104          $local_clauses
105          )
106        );
107    }
108  }
109
110  if (isset($search['fields']['allwords']))
111  {
112    $fields = array('file', 'name', 'comment', 'author');
113    // in the OR mode, request bust be :
114    // ((field1 LIKE '%word1%' OR field2 LIKE '%word1%')
115    // OR (field1 LIKE '%word2%' OR field2 LIKE '%word2%'))
116    //
117    // in the AND mode :
118    // ((field1 LIKE '%word1%' OR field2 LIKE '%word1%')
119    // AND (field1 LIKE '%word2%' OR field2 LIKE '%word2%'))
120    $word_clauses = array();
121    foreach ($search['fields']['allwords']['words'] as $word)
122    {
123      $field_clauses = array();
124      foreach ($fields as $field)
125      {
126        array_push($field_clauses, $field." LIKE '%".$word."%'");
127      }
128      // adds brackets around where clauses
129      array_push(
130        $word_clauses,
131        implode(
132          "\n          OR ",
133          $field_clauses
134          )
135        );
136    }
137
138    array_walk(
139      $word_clauses,
140      create_function('&$s','$s="(".$s.")";')
141      );
142
143    array_push(
144      $clauses,
145      "\n         ".
146      implode(
147        "\n         ".
148              $search['fields']['allwords']['mode'].
149        "\n         ",
150        $word_clauses
151        )
152      );
153  }
154
155  foreach (array('date_available', 'date_creation') as $datefield)
156  {
157    if (isset($search['fields'][$datefield]))
158    {
159      array_push(
160        $clauses,
161        $datefield." = '".$search['fields'][$datefield]['date']."'"
162        );
163    }
164
165    foreach (array('after','before') as $suffix)
166    {
167      $key = $datefield.'-'.$suffix;
168
169      if (isset($search['fields'][$key]))
170      {
171        array_push(
172          $clauses,
173
174          $datefield.
175          ($suffix == 'after'             ? ' >' : ' <').
176          ($search['fields'][$key]['inc'] ? '='  : '').
177          " '".$search['fields'][$key]['date']."'"
178
179          );
180      }
181    }
182  }
183
184  if (isset($search['fields']['cat']))
185  {
186    if ($search['fields']['cat']['sub_inc'])
187    {
188      // searching all the categories id of sub-categories
189      $cat_ids = get_subcat_ids($search['fields']['cat']['words']);
190    }
191    else
192    {
193      $cat_ids = $search['fields']['cat']['words'];
194    }
195
196    $local_clause = 'category_id IN ('.implode(',', $cat_ids).')';
197    array_push($clauses, $local_clause);
198  }
199
200  // adds brackets around where clauses
201  $clauses = prepend_append_array_items($clauses, '(', ')');
202
203  $where_separator =
204    implode(
205      "\n    ".$search['mode'].' ',
206      $clauses
207      );
208
209  $search_clause = $where_separator;
210
211  return $search_clause;
212}
213
214/**
215 * returns the list of items corresponding to the search id
216 *
217 * @param int search id
218 * @return array
219 */
220function get_search_items($search_id)
221{
222  $items = array();
223 
224  $search_clause = get_sql_search_clause($search_id);
225 
226  if (!empty($search_clause))
227  {
228    $query = '
229SELECT DISTINCT(id)
230  FROM '.IMAGES_TABLE.'
231    INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
232  WHERE '.$search_clause.'
233;';
234    $items = array_from_query($query, 'id');
235  }
236
237  $search = get_search_array($search_id);
238
239  if (isset($search['fields']['tags']))
240  {
241    $tag_items = get_image_ids_for_tags(
242      $search['fields']['tags']['words'],
243      $search['fields']['tags']['mode']
244      );
245
246    switch ($search['mode'])
247    {
248      case 'AND':
249      {
250        if (empty($search_clause))
251        {
252          $items = $tag_items;
253        }
254        else
255        {
256          $items = array_intersect($items, $tag_items);
257        }
258        break;
259      }
260      case 'OR':
261      {
262        $items = array_unique(
263          array_merge(
264            $items,
265            $tag_items
266            )
267          );
268        break;
269      }
270    }
271  }
272 
273  return $items;
274}
275?>
Note: See TracBrowser for help on using the repository browser.