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

Last change on this file since 16924 was 16924, checked in by mistic100, 12 years ago

add rating_score filter

File size: 12.7 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  // representant, 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    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
49    set_random_representant(array($cat_id));
50  }
51 
52  return $images;
53}
54
55
56/*
57 * Make associations for all SmartAlbums
58 * Called with invalidate_user_cache
59 */
60function smart_make_all_associations()
61{
62  global $conf;
63 
64  if ( defined('SMART_NOT_UPDATE') OR !$conf['SmartAlbums']['update_on_upload'] ) return;
65 
66  /* get categories with smart filters */
67  $query = '
68SELECT DISTINCT id
69  FROM '.CATEGORIES_TABLE.' AS c
70    INNER JOIN '.CATEGORY_FILTERS_TABLE.' AS cf
71    ON c.id = cf.category_id
72;';
73 
74  /* regenerate photo list */
75  $smart_cats = array_from_query($query, 'id');
76  array_map('smart_make_associations', $smart_cats);
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    $result = pwg_query($query);
100   
101    if (!pwg_db_num_rows($result)) return array();
102   
103    $filters = array();
104    while ($row = pwg_db_fetch_assoc($result))
105    {
106      $filters[] = array(
107        'type' => $row['type'],
108        'cond' => $row['cond'],
109        'value' => $row['value'],
110        );
111    }
112  }
113  else if (!count($filters))
114  {
115    return array();
116  }
117   
118  /* build constrains */
119  ## generate 'join', 'where' arrays and 'limit' string to create the SQL query
120  ## inspired by PicsEngine 3 by Michael Villar
121  $i_tags = 1;
122  foreach ($filters as $filter)
123  {
124    switch ($filter['type'])
125    {
126      // tags
127      case 'tags':
128      {
129        switch ($filter['cond'])
130        {
131          // search images which have all tags
132          case 'all':
133          {
134            $tags_arr = explode(',', $filter['value']);
135            foreach($tags_arr as $value)
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 = '.$value;
139              $i_tags++;
140            }
141           
142            break;
143          }
144          // search images which tags are in the list
145          case 'one':
146          {
147            $join[] = IMAGE_TAG_TABLE.' AS it'.$i_tags.' ON i.id = it'.$i_tags.'.image_id';
148            $where[] = 'it'.$i_tags.'.tag_id IN ('.$filter['value'].')';
149            $i_tags++;
150           
151            break;
152          }
153          // exclude images which tags are in the list
154          case 'none':
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 IN ('.$filter['value'].')
162        GROUP BY it'.$i_tags.'.image_id
163      ';
164            $join[] = IMAGE_TAG_TABLE.' AS it'.$i_tags.' ON i.id = it'.$i_tags.'.image_id';
165            $where[] = 'NOT EXISTS ('.$sub_query.')';
166            $i_tags++;
167           
168            break;
169          }
170          // exclude images which tags are not in the list and search images which have all tags
171          case 'only':
172          {
173            $sub_query = '
174      SELECT it'.$i_tags.'.image_id
175        FROM '.IMAGE_TAG_TABLE.' AS it'.$i_tags.'
176        WHERE
177          it'.$i_tags.'.image_id = i.id AND
178          it'.$i_tags.'.tag_id NOT IN ('.$filter['value'].')
179        GROUP BY it'.$i_tags.'.image_id
180      ';
181            $join[] = IMAGE_TAG_TABLE.' AS it'.$i_tags.' ON i.id = it'.$i_tags.'.image_id';
182            $where[] = 'NOT EXISTS ('.$sub_query.')';
183            $i_tags++;
184           
185            $tags_arr = explode(',', $filter['value']);
186            foreach($tags_arr as $value)
187            {
188              $join[] = IMAGE_TAG_TABLE.' AS it'.$i_tags.' ON i.id = it'.$i_tags.'.image_id';
189              $where[] = 'it'.$i_tags.'.tag_id = '.$value;
190              $i_tags++;
191            }
192           
193            break;
194          }
195        }
196       
197        break;
198      }
199   
200      // date
201      case 'date':
202      {
203        switch ($filter['cond'])
204        {
205          case 'the_post':
206            $where[] = 'date_available BETWEEN "'.$filter['value'].' 00:00:00" AND "'.$filter['value'].' 23:59:59"';
207            break;
208          case 'before_post':
209            $where[] = 'date_available < "'.$filter['value'].' 00:00:00"';
210            break;
211          case 'after_post':
212            $where[] = 'date_available > "'.$filter['value'].' 23:59:59"';
213            break;
214          case 'the_taken':
215            $where[] = 'date_creation BETWEEN "'.$filter['value'].' 00:00:00" AND "'.$filter['value'].' 23:59:59"';
216            break;
217          case 'before_taken':
218            $where[] = 'date_creation < "'.$filter['value'].' 00:00:00"';
219            break;
220          case 'after_taken':
221            $where[] = 'date_creation > "'.$filter['value'].' 23:59:59"';
222            break;
223        }
224       
225        break;
226      }
227     
228      // name
229      case 'name':
230      {
231        switch ($filter['cond'])
232        {
233          case 'contain':
234            $where[] = 'name LIKE "%'.$filter['value'].'%"';
235            break;
236          case 'begin':
237            $where[] = 'name LIKE "'.$filter['value'].'%"';
238            break;
239          case 'end':
240            $where[] = 'name LIKE "%'.$filter['value'].'"';
241            break;
242          case 'not_contain':
243            $where[] = 'name NOT LIKE "%'.$filter['value'].'%"';
244            break;
245          case 'not_begin':
246            $where[] = 'name NOT LIKE "'.$filter['value'].'%"';
247            break;
248          case 'not_end':
249            $where[] = 'name NOT LIKE "%'.$filter['value'].'"';
250            break;
251        }
252       
253        break;
254      }
255     
256      // author
257      case 'author':
258      {
259        switch ($filter['cond'])
260        {
261          case 'is':
262            if ($filter['value'] != 'NULL') $filter['value'] = '"'.$filter['value'].'"';
263            $where[] = 'author = '.$filter['value'].'';
264            break;
265          case 'not_is':
266            if ($filter['value'] != 'NULL') $filter['value'] = '"'.$filter['value'].'"';
267            $where[] = 'author != '.$filter['value'].'';
268            break;
269          case 'in':
270            $filter['value'] = '"'.str_replace(',', '","', $filter['value']).'"';
271            $where[] = 'author IN('.$filter['value'].')';
272            break;
273          case 'not_in':
274            $filter['value'] = '"'.str_replace(',', '","', $filter['value']).'"';
275            $where[] = 'author NOT IN('.$filter['value'].')';
276            break;
277        }
278       
279        break;
280      }
281     
282      // hit
283      case 'hit':
284      {
285        switch ($filter['cond'])
286        {
287          case 'less':
288            $where[] = 'hit < '.$filter['value'].'';
289            break;
290          case 'more':
291            $where[] = 'hit >= '.$filter['value'].'';
292            break;
293        }
294       
295        break;
296      }
297     
298      // rating_score
299      case 'rating_score':
300      {
301        switch ($filter['cond'])
302        {
303          case 'less':
304            $where[] = 'rating_score < '.$filter['value'].'';
305            break;
306          case 'more':
307            $where[] = 'rating_score >= '.$filter['value'].'';
308            break;
309        }
310       
311        break;
312      }
313     
314      // level
315      case 'level':
316      {
317        $where[] = 'level = '.$filter['value'].'';
318        break;
319      }
320     
321      // limit
322      case 'limit':
323      {
324        $limit = '0, '.$filter['value'];
325        break;
326      }
327    }
328  }
329 
330  /* bluid query */
331  $MainQuery = '
332SELECT i.id
333  FROM '.IMAGES_TABLE.' AS i';
334   
335    if (isset($join))
336    {
337      $MainQuery.= '
338    LEFT JOIN '.implode("\n    LEFT JOIN ", $join);
339    }
340    if (isset($where))
341    {
342      $MainQuery.= '
343  WHERE
344    '.implode("\n    AND ", $where);
345    }
346
347  $MainQuery.= '
348  GROUP BY i.id
349  '.$conf['order_by'].'
350  '.(isset($limit) ? "LIMIT ".$limit : null).'
351;';
352
353  // file_put_contents(SMART_PATH.'query.sql', $MainQuery);
354  return array_from_query($MainQuery, 'id');
355}
356
357
358/**
359 * Check if the filter is proper
360 * @param array filter
361 * @return array or false
362 */
363function smart_check_filter($filter)
364{
365  global $page, $limit_is_set, $level_is_set;
366  $error = false;
367 
368  if (!isset($limit_is_set)) $limit_is_set = false;
369  if (!isset($level_is_set)) $level_is_set = false;
370 
371  # tags
372  if ($filter['type'] == 'tags')
373  {
374    if ($filter['value'] == null)
375    {
376      $error = true;
377      array_push($page['errors'], l10n('No tag selected'));
378    }
379    else
380    {
381      $filter['value'] = implode(',', get_tag_ids($filter['value']));
382    }
383  }
384  # date
385  else if ($filter['type'] == 'date')
386  {
387    if (!preg_match('#([0-9]{4})-([0-9]{2})-([0-9]{2})#', $filter['value']))
388    {
389      $error = true;
390      array_push($page['errors'], l10n('Date string is malformed'));
391    }
392  }
393  # name
394  else if ($filter['type'] == 'name')
395  {
396    if (empty($filter['value']))
397    {
398      $error = true;
399      array_push($page['errors'], l10n('Name is empty'));
400    }
401  }
402  # author
403  else if ($filter['type'] == 'author')
404  {
405    if (empty($filter['value']))
406    {
407      $error = true;
408      array_push($page['errors'], l10n('Author is empty'));
409    }
410    else
411    {
412      $filter['value'] = preg_replace('#([ ]?),([ ]?)#', ',', $filter['value']);
413    }
414  }
415  # hit
416  else if ($filter['type'] == 'hit')
417  {
418    if (!preg_match('#([0-9]{1,})#', $filter['value']))
419    {
420      $error = true;
421      array_push($page['errors'], l10n('Hits must be an integer'));
422    }
423  }
424  # rating_score
425  else if ($filter['type'] == 'rating_score')
426  {
427    if (!preg_match('#([0-9]{1,})#', $filter['value']))
428    {
429      $error = true;
430      array_push($page['errors'], l10n('Rating score must be an integer'));
431    }
432  }
433  # level
434  else if ($filter['type'] == 'level')
435  {
436    if ($level_is_set == true) // only one level is allowed, first is saved
437    {
438      $error = true;
439      array_push($page['errors'], l10n('You can\'t use more than one level filter'));
440    }
441    else
442    {
443      $level_is_set = true;
444    }
445  }
446  # limit
447  else if ($filter['type'] == 'limit')
448  {
449    if (!preg_match('#([0-9]{1,})#', $filter['value']))
450    {
451      $error = true;
452      array_push($page['errors'], l10n('Limit must be an integer'));
453    }
454    else if ($limit_is_set == true) // only one limit is allowed, first is saved
455    {
456      $error = true;
457      array_push($page['errors'], l10n('You can\'t use more than one limit filter'));
458    }
459    else
460    {
461      $limit_is_set = true;
462    }
463  }
464 
465  # out
466  if ($error == false)
467  {
468    return $filter;
469  }
470  else
471  {
472    return false;
473  }
474}
475
476
477/**
478 * inserts multiple lines in a table, ignore duplicate entries
479 * @param string table_name
480 * @param array dbfields
481 * @param array inserts
482 * @return void
483 */
484function mass_inserts_ignore($table_name, $dbfields, $datas)
485{
486  if (count($datas) != 0)
487  {
488    $first = true;
489
490    $query = 'SHOW VARIABLES LIKE \'max_allowed_packet\'';
491    list(, $packet_size) = pwg_db_fetch_row(pwg_query($query));
492    $packet_size = $packet_size - 2000; // The last list of values MUST not exceed 2000 character*/
493    $query = '';
494
495    foreach ($datas as $insert)
496    {
497      if (strlen($query) >= $packet_size)
498      {
499        pwg_query($query);
500        $first = true;
501      }
502
503      if ($first)
504      {
505        $query = '
506INSERT IGNORE INTO '.$table_name.'
507  ('.implode(',', $dbfields).')
508  VALUES';
509        $first = false;
510      }
511      else
512      {
513        $query .= '
514  , ';
515      }
516
517      $query .= '(';
518      foreach ($dbfields as $field_id => $dbfield)
519      {
520        if ($field_id > 0)
521        {
522          $query .= ',';
523        }
524
525        if (!isset($insert[$dbfield]) or $insert[$dbfield] === '')
526        {
527          $query .= 'NULL';
528        }
529        else
530        {
531          $query .= "'".$insert[$dbfield]."'";
532        }
533      }
534      $query .= ')';
535    }
536    pwg_query($query);
537  }
538}
539
540?>
Note: See TracBrowser for help on using the repository browser.