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

Last change on this file since 11376 was 11376, checked in by mistic100, 9 years ago

Add event_handler on 'login_success' and 'invalidate_user_cache' to regenerate SmartAlbums content

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