source: trunk/admin/batch_manager.php @ 24835

Last change on this file since 24835 was 24835, checked in by mistic100, 11 years ago

bug 2970: Division by zero on batch manager

File size: 15.8 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based photo gallery                                    |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008-2013 Piwigo Team                  http://piwigo.org |
6// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
7// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
8// +-----------------------------------------------------------------------+
9// | This program is free software; you can redistribute it and/or modify  |
10// | it under the terms of the GNU General Public License as published by  |
11// | the Free Software Foundation                                          |
12// |                                                                       |
13// | This program is distributed in the hope that it will be useful, but   |
14// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
15// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
16// | General Public License for more details.                              |
17// |                                                                       |
18// | You should have received a copy of the GNU General Public License     |
19// | along with this program; if not, write to the Free Software           |
20// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
21// | USA.                                                                  |
22// +-----------------------------------------------------------------------+
23
24/**
25 * Management of elements set. Elements can belong to a category or to the
26 * user caddie.
27 *
28 */
29
30if (!defined('PHPWG_ROOT_PATH'))
31{
32  die('Hacking attempt!');
33}
34
35include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
36include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
37
38// +-----------------------------------------------------------------------+
39// | Check Access and exit when user status is not ok                      |
40// +-----------------------------------------------------------------------+
41
42check_status(ACCESS_ADMINISTRATOR);
43
44check_input_parameter('selection', $_POST, true, PATTERN_ID);
45
46
47// +-----------------------------------------------------------------------+
48// |                      initialize current set                           |
49// +-----------------------------------------------------------------------+
50
51// filters from form
52if (isset($_POST['submitFilter']))
53{
54  // echo '<pre>'; print_r($_POST); echo '</pre>';
55  unset($_REQUEST['start']); // new photo set must reset the page
56  $_SESSION['bulk_manager_filter'] = array();
57
58  if (isset($_POST['filter_prefilter_use']))
59  {
60    $_SESSION['bulk_manager_filter']['prefilter'] = $_POST['filter_prefilter'];
61  }
62
63  if (isset($_POST['filter_category_use']))
64  {
65    $_SESSION['bulk_manager_filter']['category'] = $_POST['filter_category'];
66
67    if (isset($_POST['filter_category_recursive']))
68    {
69      $_SESSION['bulk_manager_filter']['category_recursive'] = true;
70    }
71  }
72
73  if (isset($_POST['filter_tags_use']))
74  {
75    $_SESSION['bulk_manager_filter']['tags'] = get_tag_ids($_POST['filter_tags'], false);
76
77    if (isset($_POST['tag_mode']) and in_array($_POST['tag_mode'], array('AND', 'OR')))
78    {
79      $_SESSION['bulk_manager_filter']['tag_mode'] = $_POST['tag_mode'];
80    }
81  }
82
83  if (isset($_POST['filter_level_use']))
84  {
85    if (in_array($_POST['filter_level'], $conf['available_permission_levels']))
86    {
87      $_SESSION['bulk_manager_filter']['level'] = $_POST['filter_level'];
88     
89      if (isset($_POST['filter_level_include_lower']))
90      {
91        $_SESSION['bulk_manager_filter']['level_include_lower'] = true;
92      }
93    }
94  }
95 
96  if (isset($_POST['filter_dimension_use']))
97  {
98    foreach (array('min_width','max_width','min_height','max_height') as $type)
99    {
100      if ( preg_match('#^[0-9]+$#', $_POST['filter_dimension_'. $type ]) )
101      {
102        $_SESSION['bulk_manager_filter']['dimension'][$type] = $_POST['filter_dimension_'. $type ];
103      }
104    }
105    foreach (array('min_ratio','max_ratio') as $type)
106    {
107      if ( preg_match('#^[0-9\.]+$#', $_POST['filter_dimension_'. $type ]) )
108      {
109        $_SESSION['bulk_manager_filter']['dimension'][$type] = $_POST['filter_dimension_'. $type ];
110      }
111    }
112  }
113}
114// filters from url
115else if (isset($_GET['filter']))
116{
117  if (!is_array($_GET['filter']))
118  {
119    $_GET['filter'] = explode(',', $_GET['filter']);
120  }
121 
122  $_SESSION['bulk_manager_filter'] = array();
123 
124  foreach ($_GET['filter'] as $filter)
125  {
126    list($type, $value) = explode('-', $filter);
127   
128    switch ($type)
129    {
130    case 'prefilter':
131      $_SESSION['bulk_manager_filter']['prefilter'] = $value;
132      break;
133   
134    case 'album':
135      if (is_numeric($value))
136      {
137        $_SESSION['bulk_manager_filter']['category'] = $value;
138      }
139      break;
140     
141    case 'tag':
142      if (is_numeric($value))
143      {
144        $_SESSION['bulk_manager_filter']['tags'] = array($value);
145        $_SESSION['bulk_manager_filter']['tag_mode'] = 'AND';
146      }
147      break;
148     
149    case 'level':
150      if (is_numeric($value) && in_array($value, $conf['available_permission_levels']))
151      {
152        $_SESSION['bulk_manager_filter']['level'] = $value;
153      }
154      break;
155    }
156  }
157}
158
159if (empty($_SESSION['bulk_manager_filter']))
160{
161  $_SESSION['bulk_manager_filter'] = array(
162    'prefilter' => 'caddie'
163    );
164}
165
166// echo '<pre>'; print_r($_SESSION['bulk_manager_filter']); echo '</pre>';
167
168// depending on the current filter (in session), we find the appropriate photos
169$filter_sets = array();
170if (isset($_SESSION['bulk_manager_filter']['prefilter']))
171{
172  switch ($_SESSION['bulk_manager_filter']['prefilter'])
173  {
174  case 'caddie':
175    $query = '
176SELECT element_id
177  FROM '.CADDIE_TABLE.'
178  WHERE user_id = '.$user['id'].'
179;';
180    array_push(
181      $filter_sets,
182      array_from_query($query, 'element_id')
183      );
184   
185    break;
186
187  case 'favorites':
188    $query = '
189SELECT image_id
190  FROM '.FAVORITES_TABLE.'
191  WHERE user_id = '.$user['id'].'
192;';
193    array_push(
194      $filter_sets,
195      array_from_query($query, 'image_id')
196      );
197   
198    break;
199
200  case 'last_import':
201    $query = '
202SELECT MAX(date_available) AS date
203  FROM '.IMAGES_TABLE.'
204;';
205    $row = pwg_db_fetch_assoc(pwg_query($query));
206    if (!empty($row['date']))
207    {
208      $query = '
209SELECT id
210  FROM '.IMAGES_TABLE.'
211  WHERE date_available BETWEEN '.pwg_db_get_recent_period_expression(1, $row['date']).' AND \''.$row['date'].'\'
212;';
213      array_push(
214        $filter_sets,
215        array_from_query($query, 'id')
216        );
217    }
218   
219    break;
220
221  case 'no_virtual_album':
222    // we are searching elements not linked to any virtual category
223    $query = '
224 SELECT id
225   FROM '.IMAGES_TABLE.'
226 ;';
227    $all_elements = array_from_query($query, 'id');
228
229    $query = '
230 SELECT id
231   FROM '.CATEGORIES_TABLE.'
232   WHERE dir IS NULL
233 ;';
234    $virtual_categories = array_from_query($query, 'id');
235    if (!empty($virtual_categories))
236    {
237      $query = '
238 SELECT DISTINCT(image_id)
239   FROM '.IMAGE_CATEGORY_TABLE.'
240   WHERE category_id IN ('.implode(',', $virtual_categories).')
241 ;';
242      $linked_to_virtual = array_from_query($query, 'image_id');
243    }
244
245    array_push(
246      $filter_sets,
247      array_diff($all_elements, $linked_to_virtual)
248      );
249   
250    break;
251
252  case 'no_album':
253    $query = '
254SELECT
255    id
256  FROM '.IMAGES_TABLE.'
257    LEFT JOIN '.IMAGE_CATEGORY_TABLE.' ON id = image_id
258  WHERE category_id is null
259;';
260    array_push(
261      $filter_sets,
262      array_from_query($query, 'id')
263      );
264   
265    break;
266
267  case 'no_tag':
268    $query = '
269SELECT
270    id
271  FROM '.IMAGES_TABLE.'
272    LEFT JOIN '.IMAGE_TAG_TABLE.' ON id = image_id
273  WHERE tag_id is null
274;';
275    array_push(
276      $filter_sets,
277      array_from_query($query, 'id')
278      );
279   
280    break;
281
282
283  case 'duplicates':
284    // we could use the group_concat MySQL function to retrieve the list of
285    // image_ids but it would not be compatible with PostgreSQL, so let's
286    // perform 2 queries instead. We hope there are not too many duplicates.
287    $query = '
288SELECT file
289  FROM '.IMAGES_TABLE.'
290  GROUP BY file
291  HAVING COUNT(*) > 1
292;';
293    $duplicate_files = array_from_query($query, 'file');
294
295    $query = '
296SELECT id
297  FROM '.IMAGES_TABLE.'
298  WHERE file IN (\''.implode("','", $duplicate_files).'\')
299;';
300
301    array_push(
302      $filter_sets,
303      array_from_query($query, 'id')
304      );
305   
306    break;
307
308  case 'all_photos':
309    $query = '
310SELECT id
311  FROM '.IMAGES_TABLE.'
312  '.$conf['order_by'];
313
314    $filter_sets[] = array_from_query($query, 'id');
315   
316    break;
317  }
318
319  $filter_sets = trigger_event('perform_batch_manager_prefilters', $filter_sets, $_SESSION['bulk_manager_filter']['prefilter']);
320}
321
322if (isset($_SESSION['bulk_manager_filter']['category']))
323{
324  $categories = array();
325
326  if (isset($_SESSION['bulk_manager_filter']['category_recursive']))
327  {
328    $categories = get_subcat_ids(array($_SESSION['bulk_manager_filter']['category']));
329  }
330  else
331  {
332    $categories = array($_SESSION['bulk_manager_filter']['category']);
333  }
334
335  $query = '
336 SELECT DISTINCT(image_id)
337   FROM '.IMAGE_CATEGORY_TABLE.'
338   WHERE category_id IN ('.implode(',', $categories).')
339 ;';
340  array_push(
341    $filter_sets,
342    array_from_query($query, 'image_id')
343    );
344}
345
346if (isset($_SESSION['bulk_manager_filter']['level']))
347{
348  $operator = '=';
349  if (isset($_SESSION['bulk_manager_filter']['level_include_lower']))
350  {
351    $operator = '<=';
352  }
353 
354  $query = '
355SELECT id
356  FROM '.IMAGES_TABLE.'
357  WHERE level '.$operator.' '.$_SESSION['bulk_manager_filter']['level'].'
358  '.$conf['order_by'];
359
360  $filter_sets[] = array_from_query($query, 'id');
361}
362
363if (!empty($_SESSION['bulk_manager_filter']['tags']))
364{
365  array_push(
366    $filter_sets,
367    get_image_ids_for_tags(
368      $_SESSION['bulk_manager_filter']['tags'],
369      $_SESSION['bulk_manager_filter']['tag_mode'],
370      null,
371      null,
372      false // we don't apply permissions in administration screens
373      )
374    );
375}
376
377if (isset($_SESSION['bulk_manager_filter']['dimension']))
378{
379  $where_clauses = array();
380  if (isset($_SESSION['bulk_manager_filter']['dimension']['min_width']))
381  {
382    $where_clause[] = 'width >= '.$_SESSION['bulk_manager_filter']['dimension']['min_width'];
383  }
384  if (isset($_SESSION['bulk_manager_filter']['dimension']['max_width']))
385  {
386    $where_clause[] = 'width <= '.$_SESSION['bulk_manager_filter']['dimension']['max_width'];
387  }
388  if (isset($_SESSION['bulk_manager_filter']['dimension']['min_height']))
389  {
390    $where_clause[] = 'height >= '.$_SESSION['bulk_manager_filter']['dimension']['min_height'];
391  }
392  if (isset($_SESSION['bulk_manager_filter']['dimension']['max_height']))
393  {
394    $where_clause[] = 'height <= '.$_SESSION['bulk_manager_filter']['dimension']['max_height'];
395  }
396  if (isset($_SESSION['bulk_manager_filter']['dimension']['min_ratio']))
397  {
398    $where_clause[] = 'width/height >= '.$_SESSION['bulk_manager_filter']['dimension']['min_ratio'];
399  }
400  if (isset($_SESSION['bulk_manager_filter']['dimension']['max_ratio']))
401  {
402    // max_ratio is a floor value, so must be a bit increased
403    $where_clause[] = 'width/height < '.($_SESSION['bulk_manager_filter']['dimension']['max_ratio']+0.01);
404  }
405 
406  $query = '
407SELECT id
408  FROM '.IMAGES_TABLE.'
409  WHERE '.implode(' AND ',$where_clause).'
410  '.$conf['order_by'];
411
412  $filter_sets[] = array_from_query($query, 'id');
413}
414
415$current_set = array_shift($filter_sets);
416foreach ($filter_sets as $set)
417{
418  $current_set = array_intersect($current_set, $set);
419}
420$page['cat_elements_id'] = $current_set;
421
422
423// +-----------------------------------------------------------------------+
424// |                       first element to display                        |
425// +-----------------------------------------------------------------------+
426
427// $page['start'] contains the number of the first element in its
428// category. For exampe, $page['start'] = 12 means we must show elements #12
429// and $page['nb_images'] next elements
430
431if (!isset($_REQUEST['start'])
432    or !is_numeric($_REQUEST['start'])
433    or $_REQUEST['start'] < 0
434    or (isset($_REQUEST['display']) and 'all' == $_REQUEST['display']))
435{
436  $page['start'] = 0;
437}
438else
439{
440  $page['start'] = $_REQUEST['start'];
441}
442
443
444// +-----------------------------------------------------------------------+
445// |                                 Tabs                                  |
446// +-----------------------------------------------------------------------+
447$manager_link = get_root_url().'admin.php?page=batch_manager&amp;mode=';
448
449if (isset($_GET['mode']))
450{
451  $page['tab'] = $_GET['mode'];
452}
453else
454{
455  $page['tab'] = 'global';
456}
457
458$tabsheet = new tabsheet();
459$tabsheet->set_id('batch_manager');
460$tabsheet->select($page['tab']);
461$tabsheet->assign();
462
463
464// +-----------------------------------------------------------------------+
465// |                              tags                                     |
466// +-----------------------------------------------------------------------+
467
468$query = '
469SELECT id, name
470  FROM '.TAGS_TABLE.'
471;';
472$template->assign('tags', get_taglist($query, false));
473
474
475// +-----------------------------------------------------------------------+
476// |                              dimensions                               |
477// +-----------------------------------------------------------------------+
478
479$widths = array();
480$heights = array();
481$ratios = array();
482
483// get all width, height and ratios
484$query = '
485SELECT
486  DISTINCT width, height
487  FROM '.IMAGES_TABLE.'
488  WHERE width IS NOT NULL
489    AND height IS NOT NULL
490;';
491$result = pwg_query($query);
492
493if (pwg_db_num_rows($result))
494{
495  while ($row = pwg_db_fetch_assoc($result))
496  {
497    if ($row['width']>0 && $row['height']>0)
498    {
499      $widths[] = $row['width'];
500      $heights[] = $row['height'];
501      $ratios[] = floor($row['width'] / $row['height'] * 100) / 100;
502    }
503  }
504}
505if (empty($widths))
506{ // arbitrary values, only used when no photos on the gallery
507  $widths = array(600, 1920, 3500);
508  $heights = array(480, 1080, 2300);
509  $ratios = array(1.25, 1.52, 1.78);
510}
511
512
513
514$widths = array_unique($widths);
515sort($widths);
516
517$heights = array_unique($heights);
518sort($heights);
519
520$ratios = array_unique($ratios);
521sort($ratios);
522
523$dimensions['widths'] = implode(',', $widths);
524$dimensions['heights'] = implode(',', $heights);
525$dimensions['ratios'] = implode(',', $ratios);
526
527$dimensions['bounds'] = array(
528  'min_width' => $widths[0],
529  'max_width' => $widths[count($widths)-1],
530  'min_height' => $heights[0],
531  'max_height' => $heights[count($heights)-1],
532  'min_ratio' => $ratios[0],
533  'max_ratio' => $ratios[count($ratios)-1],
534  );
535
536// find ratio categories
537$ratio_categories = array(
538  'portrait' => array(),
539  'square' => array(),
540  'landscape' => array(),
541  'panorama' => array(),
542  );
543
544foreach ($ratios as $ratio)
545{
546  if ($ratio < 0.95)
547  {
548    $ratio_categories['portrait'][] = $ratio;
549  }
550  else if ($ratio >= 0.95 and $ratio <= 1.05)
551  {
552    $ratio_categories['square'][] = $ratio;
553  }
554  else if ($ratio > 1.05 and $ratio < 2)
555  {
556    $ratio_categories['landscape'][] = $ratio;
557  }
558  else if ($ratio >= 2)
559  {
560    $ratio_categories['panorama'][] = $ratio;
561  }
562}
563
564foreach (array_keys($ratio_categories) as $ratio_category)
565{
566  if (count($ratio_categories[$ratio_category]) > 0)
567  {
568    $dimensions['ratio_'.$ratio_category] = array(
569      'min' => $ratio_categories[$ratio_category][0],
570      'max' => array_pop($ratio_categories[$ratio_category]),
571      );
572  }
573}
574
575// selected=bound if nothing selected
576foreach (array_keys($dimensions['bounds']) as $type)
577{
578  $dimensions['selected'][$type] = isset($_SESSION['bulk_manager_filter']['dimension'][$type])
579    ? $_SESSION['bulk_manager_filter']['dimension'][$type]
580    : $dimensions['bounds'][$type]
581  ;
582}
583
584$template->assign('dimensions', $dimensions);
585
586
587// +-----------------------------------------------------------------------+
588// |                         open specific mode                            |
589// +-----------------------------------------------------------------------+
590
591include(PHPWG_ROOT_PATH.'admin/batch_manager_'.$page['tab'].'.php');
592?>
Note: See TracBrowser for help on using the repository browser.