source: extensions/SmartAlbums/include/functions.inc.php @ 11380

Last change on this file since 11380 was 11380, checked in by mistic100, 13 years ago

add filters on date_creation fields, remove 'make associations on login'

File size: 8.4 KB
Line 
1<?php
2if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
3
4/*
5 * Associates images to the category according to the filters
6 * @param int category_id
7 * @return array
8 */
9function smart_make_associations($cat_id)
10{
11  pwg_query('DELETE FROM '.IMAGE_CATEGORY_TABLE.' WHERE category_id = '.$cat_id.' AND smart = true;');
12 
13  $images = smart_get_pictures($cat_id);
14 
15  if (count($images) != 0)
16  {
17    foreach ($images as $img)
18    {
19      $datas[] = array(
20        'image_id' => $img,
21        'category_id' => $cat_id,
22        'smart' => true,
23        );
24    }
25    mass_inserts_ignore(
26      IMAGE_CATEGORY_TABLE, 
27      array_keys($datas[0]), 
28      $datas
29      );
30  }
31 
32  if (!function_exists('set_rendom_representant'))
33  {
34    include(PHPWG_ROOT_PATH.'admin/include/functions.php');
35  }
36  set_random_representant(array($cat_id));
37 
38  return $images;
39}
40
41
42/*
43 * Make associations for all SmartAlbums
44 * Called with invalidate_user_cache
45 */
46function smart_make_all_associations()
47{
48  global $conf;
49   
50  if (!is_array($conf['SmartAlbums'])) $conf['SmartAlbums'] = unserialize($conf['SmartAlbums']);
51 
52  if ( defined('SMART_NOT_UPDATE') OR $conf['SmartAlbums']['update_on_upload'] == 'false' ) return;
53 
54  /* get categories with smart filters */
55  $query = '
56SELECT DISTINCT id
57  FROM '.CATEGORIES_TABLE.' AS c
58    INNER JOIN '.CATEGORY_FILTERS_TABLE.' AS cf
59    ON c.id = cf.category_id
60;';
61 
62  /* regenerate photo list */
63  $smart_cats = array_from_query($query, 'id');
64  array_map('smart_make_associations', $smart_cats);
65}
66
67
68/*
69 * Generates the list of images, according to the filters of the category
70 * @param int category_id
71 * @param array filters, if null => catch from db
72 * @return array
73 */
74function smart_get_pictures($cat_id, $filters = null)
75{
76  global $conf;
77
78  /* get filters */
79  if ($filters == null)
80  {
81    $query = '
82SELECT *
83  FROM '.CATEGORY_FILTERS_TABLE.'
84  WHERE category_id = '.$cat_id.'
85  ORDER BY type ASC, cond ASC
86;';
87    $filters = pwg_query($query);
88   
89    if (!pwg_db_num_rows($filters)) return array();
90   
91    while ($filter = pwg_db_fetch_assoc($filters))
92    {
93      $temp[] = array(
94        'type' => $filter['type'],
95        'cond' => $filter['cond'],
96        'value' => $filter['value'],
97        );
98    }
99     
100    $filters = $temp;
101  }
102   
103  /* build constrains */
104  ## generate 'join', 'where' arrays and 'limit' string to create the SQL query
105  ## inspired by PicsEngine by Michael Villar
106  $i_tags = 1;
107  foreach ($filters as $filter)
108  {
109    // tags
110    if ($filter['type'] == 'tags')
111    {
112        if($filter['cond'] == "all")
113        {
114          $tags_arr = explode(',', $filter['value']);
115         
116          foreach($tags_arr as $value)
117          {
118            $join[] = IMAGE_TAG_TABLE.' AS it_'.$i_tags.' ON i.id = it_'.$i_tags.'.image_id';
119            $where[] = 'it_'.$i_tags.'.tag_id = '.$value;
120            $i_tags++;
121          }
122        }
123        else if ($filter['cond'] == 'one') 
124        {
125          $join[] = IMAGE_TAG_TABLE.' AS it_'.$i_tags.' ON i.id = it_'.$i_tags.'.image_id';
126          $where[] = 'it_'.$i_tags.'.tag_id IN ('.$filter['value'].')';
127          $i_tags++;
128        }
129        else if ($filter['cond'] == 'none') 
130        {
131          $sub_query = '
132      SELECT it_'.$i_tags.'.image_id
133        FROM '.IMAGE_TAG_TABLE.' AS it_'.$i_tags.'
134        WHERE
135          it_'.$i_tags.'.image_id = i.id AND
136          it_'.$i_tags.'.tag_id IN ('.$filter['value'].')
137        GROUP BY it_'.$i_tags.'.image_id
138    ';
139          $where[] = 'NOT EXISTS ('.$sub_query.')';
140          $i_tags++;
141        }
142        else if ($filter['cond'] == 'only') 
143        {
144          $sub_query = '
145      SELECT it_'.$i_tags.'.image_id
146        FROM '.IMAGE_TAG_TABLE.' AS it_'.$i_tags.'
147        WHERE
148          it_'.$i_tags.'.image_id = i.id AND
149          it_'.$i_tags.'.tag_id NOT IN ('.$filter['value'].')
150        GROUP BY it_'.$i_tags.'.image_id
151    ';
152          $where[] = 'NOT EXISTS ('.$sub_query.')';
153       
154          $i_tags++;
155          $tags_arr = explode(',', $filter['value']);
156         
157          foreach($tags_arr as $value)
158          {
159            $join[] = IMAGE_TAG_TABLE.' AS it_'.$i_tags.' ON i.id = it_'.$i_tags.'.image_id';
160            $where[] = 'it_'.$i_tags.'.tag_id = '.$value;
161            $i_tags++;
162          }
163        }       
164    }
165    // date
166    else if ($filter['type'] == 'date')
167    {
168      switch ($filter['cond'])
169      {
170        case 'the':
171          $where[] = 'date_available BETWEEN "'.$filter['value'].' 00:00:00" AND "'.$filter['value'].' 23:59:59"';
172          break;
173        case 'before':
174          $where[] = 'date_available < "'.$filter['value'].' 00:00:00"';
175          break;
176        case 'after':
177          $where[] = 'date_available > "'.$filter['value'].' 23:59:59"';
178          break;
179        case 'the_crea':
180          $where[] = 'date_creation BETWEEN "'.$filter['value'].' 00:00:00" AND "'.$filter['value'].' 23:59:59"';
181          break;
182        case 'before_crea':
183          $where[] = 'date_creation < "'.$filter['value'].' 00:00:00"';
184          break;
185        case 'after_crea':
186          $where[] = 'date_creation > "'.$filter['value'].' 23:59:59"';
187          break;
188      }
189    }
190    // limit
191    else if ($filter['type'] == 'limit')
192    {
193      $limit = '0, '.$filter['value'];
194    }
195  }
196 
197  /* bluid query */
198  $MainQuery = '
199SELECT i.id
200  FROM '.IMAGES_TABLE.' AS i';
201   
202    if (isset($join))
203    {
204      foreach ($join as $query)
205      {
206        $MainQuery .= '
207    LEFT JOIN '.$query;
208      }
209    }
210    if (isset($where))
211    {
212      $MainQuery .= '
213  WHERE';
214      $i = 0;
215      foreach ($where as $query)
216      {
217        if ($i != 0) $MainQuery .= ' AND';
218        $MainQuery .= '
219    '.$query;
220        $i++;
221      }
222    }
223
224    $MainQuery .= '
225  GROUP BY i.id
226 '.$conf['order_by_inside_category'].'
227  '.(isset($limit) ? "LIMIT ".$limit : null).'
228;';
229
230  return array_from_query($MainQuery, 'id');
231}
232
233
234/**
235 * Check if the filter is proper
236 *
237 * @param array filter
238 * @return array or false
239 */
240function smart_check_filter($filter)
241{
242  global $limit_is_set, $page;
243  $error = false;
244 
245  # tags
246  if ($filter['type'] == 'tags')
247  {
248    if ($filter['value'] == null) // tags fields musn't be null
249    {
250      $error = true;
251      array_push($page['errors'], l10n('No tag selected'));
252    }
253    else
254    {
255      $filter['value'] = implode(',', get_tag_ids($filter['value']));
256    }
257  }
258  # date
259  else if ($filter['type'] == 'date')
260  {
261    if (!preg_match('#([0-9]{4})-([0-9]{2})-([0-9]{2})#', $filter['value'])) // dates must be proper
262    {
263      $error = true;
264      array_push($page['errors'], l10n('Date string is malformed'));
265    }
266  }
267  # limit
268  else if ($filter['type'] == 'limit')
269  {
270    if (!preg_match('#([0-9]{1,})#', $filter['value'])) // limit must be an integer
271    {
272      $error = true;
273      array_push($page['errors'], l10n('Limit must be an integer'));
274    }
275    else if ($limit_is_set == true) // only one limit is allowed, first is saved
276    {
277      $error = true;
278      array_push($page['errors'], l10n('You can\'t use more than one limit'));
279    }
280    else
281    {
282      $limit_is_set = true;
283    }
284  }
285 
286  # out
287  if ($error == false)
288  {
289    return $filter;
290  }
291  else
292  {
293    return false;
294  }
295}
296
297
298/**
299 * inserts multiple lines in a table, ignore duplicate entries
300 *
301 * @param string table_name
302 * @param array dbfields
303 * @param array inserts
304 * @return void
305 */
306function mass_inserts_ignore($table_name, $dbfields, $datas)
307{
308  if (count($datas) != 0)
309  {
310    $first = true;
311
312    $query = 'SHOW VARIABLES LIKE \'max_allowed_packet\'';
313    list(, $packet_size) = pwg_db_fetch_row(pwg_query($query));
314    $packet_size = $packet_size - 2000; // The last list of values MUST not exceed 2000 character*/
315    $query = '';
316
317    foreach ($datas as $insert)
318    {
319      if (strlen($query) >= $packet_size)
320      {
321        pwg_query($query);
322        $first = true;
323      }
324
325      if ($first)
326      {
327        $query = '
328INSERT IGNORE INTO '.$table_name.'
329  ('.implode(',', $dbfields).')
330  VALUES';
331        $first = false;
332      }
333      else
334      {
335        $query .= '
336  , ';
337      }
338
339      $query .= '(';
340      foreach ($dbfields as $field_id => $dbfield)
341      {
342        if ($field_id > 0)
343        {
344          $query .= ',';
345        }
346
347        if (!isset($insert[$dbfield]) or $insert[$dbfield] === '')
348        {
349          $query .= 'NULL';
350        }
351        else
352        {
353          $query .= "'".$insert[$dbfield]."'";
354        }
355      }
356      $query .= ')';
357    }
358    pwg_query($query);
359  }
360}
361?>
Note: See TracBrowser for help on using the repository browser.