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

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

keep category representant if possible

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