source: trunk/admin/include/functions.php @ 881

Last change on this file since 881 was 881, checked in by plg, 19 years ago
  • new: mass virtual categories movement manager in Administration>Categories>Move screen.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 35.3 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | PhpWebGallery - a PHP based picture gallery                           |
4// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
5// | Copyright (C) 2003-2005 PhpWebGallery Team - http://phpwebgallery.net |
6// +-----------------------------------------------------------------------+
7// | branch        : BSF (Best So Far)
8// | file          : $RCSfile$
9// | last update   : $Date: 2005-10-07 22:04:53 +0000 (Fri, 07 Oct 2005) $
10// | last modifier : $Author: plg $
11// | revision      : $Revision: 881 $
12// +-----------------------------------------------------------------------+
13// | This program is free software; you can redistribute it and/or modify  |
14// | it under the terms of the GNU General Public License as published by  |
15// | the Free Software Foundation                                          |
16// |                                                                       |
17// | This program is distributed in the hope that it will be useful, but   |
18// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
19// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
20// | General Public License for more details.                              |
21// |                                                                       |
22// | You should have received a copy of the GNU General Public License     |
23// | along with this program; if not, write to the Free Software           |
24// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
25// | USA.                                                                  |
26// +-----------------------------------------------------------------------+
27
28include(PHPWG_ROOT_PATH.'admin/include/functions_metadata.php');
29
30/**
31 * returns an array with all picture files according to $conf['file_ext']
32 *
33 * @param string $dir
34 * @return array
35 */
36function get_pwg_files($dir)
37{
38  global $conf;
39
40  $pictures = array();
41  if ($opendir = opendir($dir))
42  {
43    while ($file = readdir($opendir))
44    {
45      if (in_array(get_extension($file), $conf['file_ext']))
46      {
47        array_push($pictures, $file);
48      }
49    }
50  }
51  return $pictures;
52}
53
54/**
55 * returns an array with all thumbnails according to $conf['picture_ext']
56 * and $conf['prefix_thumbnail']
57 *
58 * @param string $dir
59 * @return array
60 */
61function get_thumb_files($dir)
62{
63  global $conf;
64
65  $prefix_length = strlen($conf['prefix_thumbnail']);
66 
67  $thumbnails = array();
68  if ($opendir = @opendir($dir.'/thumbnail'))
69  {
70    while ($file = readdir($opendir))
71    {
72      if (in_array(get_extension($file), $conf['picture_ext'])
73          and substr($file, 0, $prefix_length) == $conf['prefix_thumbnail'])
74      {
75        array_push($thumbnails, $file);
76      }
77    }
78  }
79  return $thumbnails;
80}
81
82/**
83 * returns an array with representative picture files of a directory
84 * according to $conf['picture_ext']
85 *
86 * @param string $dir
87 * @return array
88 */
89function get_representative_files($dir)
90{
91  global $conf;
92
93  $pictures = array();
94  if ($opendir = @opendir($dir.'/pwg_representative'))
95  {
96    while ($file = readdir($opendir))
97    {
98      if (in_array(get_extension($file), $conf['picture_ext']))
99      {
100        array_push($pictures, $file);
101      }
102    }
103  }
104  return $pictures;
105}
106
107// The function delete_site deletes a site and call the function
108// delete_categories for each primary category of the site
109function delete_site( $id )
110{
111  // destruction of the categories of the site
112  $query = '
113SELECT id
114  FROM '.CATEGORIES_TABLE.'
115  WHERE site_id = '.$id.'
116;';
117  $result = pwg_query($query);
118  $category_ids = array();
119  while ($row = mysql_fetch_array($result))
120  {
121    array_push($category_ids, $row['id']);
122  }
123  delete_categories($category_ids);
124               
125  // destruction of the site
126  $query = '
127DELETE FROM '.SITES_TABLE.'
128  WHERE id = '.$id.'
129;';
130  pwg_query($query);
131}
132       
133
134// The function delete_categories deletes the categories identified by the
135// (numeric) key of the array $ids. It also deletes (in the database) :
136//    - all the elements of the category (delete_elements, see further)
137//    - all the links between elements and this category
138//    - all the restrictions linked to the category
139// The function works recursively.
140function delete_categories($ids)
141{
142  global $counts;
143
144  if (count($ids) == 0)
145  {
146    return;
147  }
148
149  // add sub-category ids to the given ids : if a category is deleted, all
150  // sub-categories must be so
151  $ids = get_subcat_ids($ids);
152 
153  // destruction of all the related elements
154  $query = '
155SELECT id
156  FROM '.IMAGES_TABLE.'
157  WHERE storage_category_id IN (
158'.wordwrap(implode(', ', $ids), 80, "\n").')
159;';
160  $result = pwg_query($query);
161  $element_ids = array();
162  while ($row = mysql_fetch_array($result))
163  {
164    array_push($element_ids, $row['id']);
165  }
166  delete_elements($element_ids);
167
168  // destruction of the links between images and this category
169  $query = '
170DELETE FROM '.IMAGE_CATEGORY_TABLE.'
171  WHERE category_id IN (
172'.wordwrap(implode(', ', $ids), 80, "\n").')
173;';
174  pwg_query($query);
175
176  // destruction of the access linked to the category
177  $query = '
178DELETE FROM '.USER_ACCESS_TABLE.'
179  WHERE cat_id IN (
180'.wordwrap(implode(', ', $ids), 80, "\n").')
181;';
182  pwg_query($query);
183  $query = '
184DELETE FROM '.GROUP_ACCESS_TABLE.'
185  WHERE cat_id IN (
186'.wordwrap(implode(', ', $ids), 80, "\n").')
187;';
188  pwg_query($query);
189
190  // destruction of the category
191  $query = '
192DELETE FROM '.CATEGORIES_TABLE.'
193  WHERE id IN (
194'.wordwrap(implode(', ', $ids), 80, "\n").')
195;';
196  pwg_query($query);
197
198  if (isset($counts['del_categories']))
199  {
200    $counts['del_categories']+= count($ids);
201  }
202}
203
204// The function delete_elements deletes the elements identified by the
205// (numeric) values of the array $ids. It also deletes (in the database) :
206//    - all the comments related to elements
207//    - all the links between categories and elements
208//    - all the favorites associated to elements
209function delete_elements($ids)
210{
211  global $counts;
212
213  if (count($ids) == 0)
214  {
215    return;
216  }
217 
218  // destruction of the comments on the image
219  $query = '
220DELETE FROM '.COMMENTS_TABLE.'
221  WHERE image_id IN (
222'.wordwrap(implode(', ', $ids), 80, "\n").')
223;';
224  pwg_query($query);
225
226  // destruction of the links between images and this category
227  $query = '
228DELETE FROM '.IMAGE_CATEGORY_TABLE.'
229  WHERE image_id IN (
230'.wordwrap(implode(', ', $ids), 80, "\n").')
231;';
232  pwg_query($query);
233
234  // destruction of the favorites associated with the picture
235  $query = '
236DELETE FROM '.FAVORITES_TABLE.'
237  WHERE image_id IN (
238'.wordwrap(implode(', ', $ids), 80, "\n").')
239;';
240  pwg_query($query);
241
242  // destruction of the rates associated to this element
243  $query = '
244DELETE FROM '.RATE_TABLE.'
245  WHERE element_id IN (
246'.wordwrap(implode(', ', $ids), 80, "\n").')
247;';
248  pwg_query($query);
249
250  // destruction of the rates associated to this element
251  $query = '
252DELETE FROM '.CADDIE_TABLE.'
253  WHERE element_id IN (
254'.wordwrap(implode(', ', $ids), 80, "\n").')
255;';
256  pwg_query($query);
257               
258  // destruction of the image
259  $query = '
260DELETE FROM '.IMAGES_TABLE.'
261  WHERE id IN (
262'.wordwrap(implode(', ', $ids), 80, "\n").')
263;';
264  pwg_query($query);
265
266  if (isset($counts['del_elements']))
267  {
268    $counts['del_elements']+= count($ids);
269  }
270}
271
272// The delete_user function delete a user identified by the $user_id
273// It also deletes :
274//     - all the access linked to this user
275//     - all the links to any group
276//     - all the favorites linked to this user
277//     - all sessions linked to this user
278//     - calculated permissions linked to the user
279function delete_user($user_id)
280{
281  global $conf;
282 
283  // destruction of the access linked to the user
284  $query = '
285DELETE FROM '.USER_ACCESS_TABLE.'
286  WHERE user_id = '.$user_id.'
287;';
288  pwg_query($query);
289
290  // destruction of the group links for this user
291  $query = '
292DELETE FROM '.USER_GROUP_TABLE.'
293  WHERE user_id = '.$user_id.'
294;';
295  pwg_query($query);
296
297  // destruction of the favorites associated with the user
298  $query = '
299DELETE FROM '.FAVORITES_TABLE.'
300  WHERE user_id = '.$user_id.'
301;';
302  pwg_query($query);
303
304  // destruction of the sessions linked with the user
305  $query = '
306DELETE FROM '.SESSIONS_TABLE.'
307  WHERE user_id = '.$user_id.'
308;';
309  pwg_query($query);
310
311  // deletion of calculated permissions linked to the user
312  $query = '
313DELETE FROM '.USER_CACHE_TABLE.'
314  WHERE user_id = '.$user_id.'
315;';
316  pwg_query($query);
317
318  // deletion of phpwebgallery specific informations
319  $query = '
320DELETE FROM '.USER_INFOS_TABLE.'
321  WHERE user_id = '.$user_id.'
322;';
323  pwg_query($query);
324
325  // destruction of the user
326  $query = '
327DELETE FROM '.USERS_TABLE.'
328  WHERE '.$conf['user_fields']['id'].' = '.$user_id.'
329;';
330  pwg_query($query);
331}
332
333/**
334 * updates calculated informations about a set of categories : date_last and
335 * nb_images. It also verifies that the representative picture is really
336 * linked to the category. Optionnaly recursive.
337 *
338 * @param mixed category id
339 * @param boolean recursive
340 * @returns void
341 */
342function update_category($ids = 'all', $recursive = false)
343{
344  global $conf;
345 
346  // retrieving all categories to update
347  $cat_ids = array();
348 
349  $query = '
350SELECT id
351  FROM '.CATEGORIES_TABLE;
352  if (is_array($ids))
353  {
354    if ($recursive)
355    {
356      foreach ($ids as $num => $id)
357      {
358        if ($num == 0)
359        {
360          $query.= '
361  WHERE ';
362        }
363        else
364        {
365          $query.= '
366  OR    ';
367        }
368        $query.= 'uppercats REGEXP \'(^|,)'.$id.'(,|$)\'';
369      }
370    }
371    else
372    {
373      $query.= '
374  WHERE id IN ('.wordwrap(implode(', ', $ids), 80, "\n").')';
375    }
376  }
377  $query.= '
378;';
379  $cat_ids = array_unique(array_from_query($query, 'id'));
380
381  if (count($cat_ids) == 0)
382  {
383    return false;
384  }
385 
386  // calculate informations about categories retrieved
387  $query = '
388SELECT category_id,
389       COUNT(image_id) AS nb_images,
390       MAX(date_available) AS date_last
391  FROM '.IMAGES_TABLE.' INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id = image_id
392  WHERE category_id IN ('.wordwrap(implode(', ', $cat_ids), 80, "\n").')
393  GROUP BY category_id
394;';
395  $result = pwg_query($query);
396  $datas = array();
397  $query_ids = array();
398  while ( $row = mysql_fetch_array( $result ) )
399  {
400    array_push($query_ids, $row['category_id']);
401    array_push($datas, array('id' => $row['category_id'],
402                             'date_last' => $row['date_last'],
403                             'nb_images' => $row['nb_images']));
404  }
405  // if all links between a category and elements have disappeared, no line
406  // is returned but the update must be done !
407  foreach (array_diff($cat_ids, $query_ids) as $id)
408  {
409    array_push($datas, array('id' => $id, 'nb_images' => 0));
410  }
411 
412  $fields = array('primary' => array('id'),
413                  'update'  => array('date_last', 'nb_images'));
414  mass_updates(CATEGORIES_TABLE, $fields, $datas);
415
416  // representative pictures
417  if (count($cat_ids) > 0)
418  {
419    // find all categories where the setted representative is not possible :
420    // the picture does not exist
421    $query = '
422SELECT c.id
423  FROM '.CATEGORIES_TABLE.' AS c LEFT JOIN '.IMAGES_TABLE.' AS i
424    ON c.representative_picture_id = i.id
425  WHERE representative_picture_id IS NOT NULL
426    AND c.id IN ('.wordwrap(implode(', ', $cat_ids), 80, "\n").')
427    AND i.id IS NULL
428;';
429    $wrong_representant = array_from_query($query, 'id');
430
431    if ($conf['allow_random_representative'])
432    {
433      if (count($wrong_representant) > 0)
434      {
435        $query = '
436UPDATE '.CATEGORIES_TABLE.'
437  SET representative_picture_id = NULL
438  WHERE id IN ('.wordwrap(implode(', ', $wrong_representant), 80, "\n").')
439;';
440        pwg_query($query);
441      }
442    }
443    else
444    {
445      $to_null = array();
446      $to_rand = array();
447
448      if (count($wrong_representant) > 0)
449      {
450        // among the categories with an unknown representant, we dissociate
451        // categories containing pictures and categories containing no
452        // pictures. Indeed, the representant must set to NULL if no picture
453        // in the category and set to a random picture otherwise.
454        $query = '
455SELECT id
456  FROM '.CATEGORIES_TABLE.'
457  WHERE id IN ('.wordwrap(implode(', ', $wrong_representant), 80, "\n").')
458    AND nb_images = 0
459;';
460        $to_null = array_from_query($query, 'id');
461        $to_rand = array_diff($wrong_representant, $to_null);
462      }
463     
464      if (count($to_null) > 0)
465      {
466        $query = '
467UPDATE '.CATEGORIES_TABLE.'
468  SET representative_picture_id = NULL
469  WHERE id IN ('.wordwrap(implode(', ', $to_null), 80, "\n").')
470;';
471        pwg_query($query);
472      }
473     
474      // If the random representant is not allowed, we need to find
475      // categories with elements and with no representant. Those categories
476      // must be added to the list of categories to set to a random
477      // representant.
478      $query = '
479SELECT id
480  FROM '.CATEGORIES_TABLE.'
481  WHERE representative_picture_id IS NULL
482    AND nb_images != 0
483    AND id IN ('.wordwrap(implode(', ', $cat_ids), 80, "\n").')
484;';
485      $to_rand =
486        array_unique(
487          array_merge(
488            $to_rand,
489            array_from_query($query, 'id')
490            )
491          );
492     
493      if (count($to_rand) > 0)
494      {
495        set_random_representant($to_rand);
496      }
497    }
498  }
499}
500
501function date_convert_back( $date )
502{
503  // date arrives at this format : YYYY-MM-DD
504  // It must be transformed in DD/MM/YYYY
505  if ( $date != '' )
506  {
507    list($year,$month,$day) = explode( '-', $date );
508    return $day.'/'.$month.'/'.$year;
509  }
510  else
511  {
512    return '';
513  }
514}
515
516/**
517 * returns an array with relevant keywords found in the given string.
518 *
519 * Keywords must be separated by comma or space characters.
520 *
521 * @param string keywords_string
522 * @return array
523 */
524function get_keywords($keywords_string)
525{
526  return
527    array_unique(
528      preg_split(
529        '/[\s,]+/',
530        $keywords_string
531        )
532      );
533}
534
535/**
536 * returns an array containing sub-directories which can be a category,
537 * recursive by default
538 *
539 * directories nammed "thumbnail", "pwg_high" or "pwg_representative" are
540 * omitted
541 *
542 * @param string $basedir
543 * @return array
544 */
545function get_fs_directories($path, $recursive = true)
546{
547  $dirs = array();
548 
549  if (is_dir($path))
550  {
551    if ($contents = opendir($path))
552    {
553      while (($node = readdir($contents)) !== false)
554      {
555        if (is_dir($path.'/'.$node)
556            and $node != '.'
557            and $node != '..'
558            and $node != 'thumbnail'
559            and $node != 'pwg_high'
560            and $node != 'pwg_representative')
561        {
562          array_push($dirs, $path.'/'.$node);
563          if ($recursive)
564          {
565            $dirs = array_merge($dirs, get_fs_directories($path.'/'.$node));
566          }
567        }
568      }
569    }
570  }
571
572  return $dirs;
573}
574
575/**
576 * inserts multiple lines in a table
577 *
578 * @param string table_name
579 * @param array dbfields
580 * @param array inserts
581 * @return void
582 */
583function mass_inserts($table_name, $dbfields, $datas)
584{
585  // inserts all found categories
586  $query = '
587INSERT INTO '.$table_name.'
588  ('.implode(',', $dbfields).')
589   VALUES';
590  foreach ($datas as $insert_id => $insert)
591  {
592    $query.= '
593  ';
594    if ($insert_id > 0)
595    {
596      $query.= ',';
597    }
598    $query.= '(';
599    foreach ($dbfields as $field_id => $dbfield)
600    {
601      if ($field_id > 0)
602      {
603        $query.= ',';
604      }
605     
606      if (!isset($insert[$dbfield]) or $insert[$dbfield] == '')
607      {
608        $query.= 'NULL';
609      }
610      else
611      {
612        $query.= "'".$insert[$dbfield]."'";
613      }
614    }
615    $query.=')';
616  }
617  $query.= '
618;';
619  pwg_query($query);
620}
621
622/**
623 * updates multiple lines in a table
624 *
625 * @param string table_name
626 * @param array dbfields
627 * @param array datas
628 * @return void
629 */
630function mass_updates($tablename, $dbfields, $datas)
631{
632  // depending on the MySQL version, we use the multi table update or N
633  // update queries
634  $query = 'SELECT VERSION() AS version;';
635  list($mysql_version) = mysql_fetch_array(pwg_query($query));
636  if (count($datas) < 10 or version_compare($mysql_version, '4.0.4') < 0)
637  {
638    // MySQL is prior to version 4.0.4, multi table update feature is not
639    // available
640    foreach ($datas as $data)
641    {
642      $query = '
643UPDATE '.$tablename.'
644  SET ';
645      $is_first = true;
646      foreach ($dbfields['update'] as $num => $key)
647      {
648        if (!$is_first)
649        {
650          $query.= ",\n      ";
651        }
652        $query.= $key.' = ';
653        if (isset($data[$key]) and $data[$key] != '')
654        {
655          $query.= '\''.$data[$key].'\'';
656        }
657        else
658        {
659          $query.= 'NULL';
660        }
661        $is_first = false;
662      }
663      $query.= '
664  WHERE ';
665      foreach ($dbfields['primary'] as $num => $key)
666      {
667        if ($num > 1)
668        {
669          $query.= ' AND ';
670        }
671        $query.= $key.' = \''.$data[$key].'\'';
672      }
673      $query.= '
674;';
675      pwg_query($query);
676    }
677  }
678  else
679  {
680    // creation of the temporary table
681    $query = '
682DESCRIBE '.$tablename.'
683;';
684    $result = pwg_query($query);
685    $columns = array();
686    $all_fields = array_merge($dbfields['primary'], $dbfields['update']);
687    while ($row = mysql_fetch_array($result))
688    {
689      if (in_array($row['Field'], $all_fields))
690      {
691        $column = $row['Field'];
692        $column.= ' '.$row['Type'];
693        if (!isset($row['Null']) or $row['Null'] == '')
694        {
695          $column.= ' NOT NULL';
696        }
697        if (isset($row['Default']))
698        {
699          $column.= " default '".$row['Default']."'";
700        }
701        array_push($columns, $column);
702      }
703    }
704   
705    $temporary_tablename = $tablename.'_'.micro_seconds();
706   
707    $query = '
708CREATE TABLE '.$temporary_tablename.'
709(
710'.implode(",\n", $columns).',
711PRIMARY KEY ('.implode(',', $dbfields['primary']).')
712)
713;';
714    pwg_query($query);
715    mass_inserts($temporary_tablename, $all_fields, $datas);
716    // update of images table by joining with temporary table
717    $query = '
718UPDATE '.$tablename.' AS t1, '.$temporary_tablename.' AS t2
719  SET '.implode("\n    , ",
720                array_map(
721                  create_function('$s', 'return "t1.$s = t2.$s";')
722                  , $dbfields['update'])).'
723  WHERE '.implode("\n    AND ",
724                array_map(
725                  create_function('$s', 'return "t1.$s = t2.$s";')
726                  , $dbfields['primary'])).'
727;';
728    pwg_query($query);
729    $query = '
730DROP TABLE '.$temporary_tablename.'
731;';
732    pwg_query($query);
733  }
734}
735
736/**
737 * updates the global_rank of categories under the given id_uppercat
738 *
739 * @param int id_uppercat
740 * @return void
741 */
742function update_global_rank($id_uppercat = 'all')
743{
744  $query = '
745SELECT id,rank
746  FROM '.CATEGORIES_TABLE.'
747;';
748  $result = pwg_query($query);
749  $ranks_array = array();
750  while ($row = mysql_fetch_array($result))
751  {
752    $ranks_array[$row['id']] = $row['rank'];
753  }
754
755  // which categories to update ?
756  $uppercats_array = array();
757
758  $query = '
759SELECT id,uppercats
760  FROM '.CATEGORIES_TABLE;
761  if (is_numeric($id_uppercat))
762  {
763    $query.= '
764  WHERE uppercats REGEXP \'(^|,)'.$id_uppercat.'(,|$)\'
765    AND id != '.$id_uppercat.'
766';
767  }
768  $query.= '
769;';
770  $result = pwg_query($query);
771  while ($row = mysql_fetch_array($result))
772  {
773    $uppercats_array[$row['id']] =  $row['uppercats'];
774  }
775 
776  $datas = array();
777  foreach ($uppercats_array as $id => $uppercats)
778  {
779    $data = array();
780    $data['id'] = $id;
781    $global_rank = preg_replace('/(\d+)/e',
782                                "\$ranks_array['$1']",
783                                str_replace(',', '.', $uppercats));
784    $data['global_rank'] = $global_rank;
785    array_push($datas, $data);
786  }
787
788  $fields = array('primary' => array('id'), 'update' => array('global_rank'));
789  mass_updates(CATEGORIES_TABLE, $fields, $datas);
790}
791
792/**
793 * change the visible property on a set of categories
794 *
795 * @param array categories
796 * @param string value
797 * @return void
798 */
799function set_cat_visible($categories, $value)
800{
801  if (!in_array($value, array('true', 'false')))
802  {
803    return false;
804  }
805
806  // unlocking a category => all its parent categories become unlocked
807  if ($value == 'true')
808  {
809    $uppercats = get_uppercat_ids($categories);
810    $query = '
811UPDATE '.CATEGORIES_TABLE.'
812  SET visible = \'true\'
813  WHERE id IN ('.implode(',', $uppercats).')
814;';
815    pwg_query($query);
816  }
817  // locking a category   => all its child categories become locked
818  if ($value == 'false')
819  {
820    $subcats = get_subcat_ids($categories);
821    $query = '
822UPDATE '.CATEGORIES_TABLE.'
823  SET visible = \'false\'
824  WHERE id IN ('.implode(',', $subcats).')
825;';
826    pwg_query($query);
827  }
828}
829
830/**
831 * change the status property on a set of categories : private or public
832 *
833 * @param array categories
834 * @param string value
835 * @return void
836 */
837function set_cat_status($categories, $value)
838{
839  if (!in_array($value, array('public', 'private')))
840  {
841    return false;
842  }
843
844  // make public a category => all its parent categories become public
845  if ($value == 'public')
846  {
847    $uppercats = get_uppercat_ids($categories);
848    $query = '
849UPDATE '.CATEGORIES_TABLE.'
850  SET status = \'public\'
851  WHERE id IN ('.implode(',', $uppercats).')
852;';
853    pwg_query($query);
854  }
855  // make a category private => all its child categories become private
856  if ($value == 'private')
857  {
858    $subcats = get_subcat_ids($categories);
859    $query = '
860UPDATE '.CATEGORIES_TABLE.'
861  SET status = \'private\'
862  WHERE id IN ('.implode(',', $subcats).')
863;';
864    pwg_query($query);
865  }
866}
867
868/**
869 * returns all uppercats category ids of the given category ids
870 *
871 * @param array cat_ids
872 * @return array
873 */
874function get_uppercat_ids($cat_ids)
875{
876  if (!is_array($cat_ids) or count($cat_ids) < 1)
877  {
878    return array();
879  }
880 
881  $uppercats = array();
882
883  $query = '
884SELECT uppercats
885  FROM '.CATEGORIES_TABLE.'
886  WHERE id IN ('.implode(',', $cat_ids).')
887;';
888  $result = pwg_query($query);
889  while ($row = mysql_fetch_array($result))
890  {
891    $uppercats = array_merge($uppercats,
892                             explode(',', $row['uppercats']));
893  }
894  $uppercats = array_unique($uppercats);
895
896  return $uppercats;
897}
898
899/**
900 * set a new random representant to the categories
901 *
902 * @param array categories
903 */
904function set_random_representant($categories)
905{
906  $datas = array();
907  foreach ($categories as $category_id)
908  {
909    $query = '
910SELECT image_id
911  FROM '.IMAGE_CATEGORY_TABLE.'
912  WHERE category_id = '.$category_id.'
913  ORDER BY RAND()
914  LIMIT 0,1
915;';
916    list($representative) = mysql_fetch_array(pwg_query($query));
917    $data = array('id' => $category_id,
918                  'representative_picture_id' => $representative);
919    array_push($datas, $data);
920  }
921
922  $fields = array('primary' => array('id'),
923                  'update' => array('representative_picture_id'));
924  mass_updates(CATEGORIES_TABLE, $fields, $datas);
925}
926
927/**
928 * order categories (update categories.rank and global_rank database fields)
929 *
930 * the purpose of this function is to give a rank for all categories
931 * (insides its sub-category), even the newer that have none at te
932 * beginning. For this, ordering function selects all categories ordered by
933 * rank ASC then name ASC for each uppercat.
934 *
935 * @returns void
936 */
937function ordering()
938{
939  $current_rank = 0;
940  $current_uppercat = '';
941               
942  $query = '
943SELECT id, if(id_uppercat is null,\'\',id_uppercat) AS id_uppercat
944  FROM '.CATEGORIES_TABLE.'
945  ORDER BY id_uppercat,rank,name
946;';
947  $result = pwg_query($query);
948  $datas = array();
949  while ($row = mysql_fetch_array($result))
950  {
951    if ($row['id_uppercat'] != $current_uppercat)
952    {
953      $current_rank = 0;
954      $current_uppercat = $row['id_uppercat'];
955    }
956    $data = array('id' => $row['id'], 'rank' => ++$current_rank);
957    array_push($datas, $data);
958  }
959
960  $fields = array('primary' => array('id'), 'update' => array('rank'));
961  mass_updates(CATEGORIES_TABLE, $fields, $datas);
962}
963
964/**
965 * returns the fulldir for each given category id
966 *
967 * @param array cat_ids
968 * @return array
969 */
970function get_fulldirs($cat_ids)
971{
972  if (count($cat_ids) == 0)
973  {
974    return array();
975  }
976 
977  // caching directories of existing categories
978  $query = '
979SELECT id, dir
980  FROM '.CATEGORIES_TABLE.'
981  WHERE dir IS NOT NULL
982;';
983  $result = pwg_query($query);
984  $cat_dirs = array();
985  while ($row = mysql_fetch_array($result))
986  {
987    $cat_dirs[$row['id']] = $row['dir'];
988  }
989
990  // caching galleries_url
991  $query = '
992SELECT id, galleries_url
993  FROM '.SITES_TABLE.'
994;';
995  $result = pwg_query($query);
996  $galleries_url = array();
997  while ($row = mysql_fetch_array($result))
998  {
999    $galleries_url[$row['id']] = $row['galleries_url'];
1000  }
1001
1002  // categories : id, site_id, uppercats
1003  $categories = array();
1004 
1005  $query = '
1006SELECT id, uppercats, site_id
1007  FROM '.CATEGORIES_TABLE.'
1008  WHERE id IN (
1009'.wordwrap(implode(', ', $cat_ids), 80, "\n").')
1010;';
1011  $result = pwg_query($query);
1012  while ($row = mysql_fetch_array($result))
1013  {
1014    array_push($categories, $row);
1015  }
1016 
1017  // filling $cat_fulldirs
1018  $cat_fulldirs = array();
1019  foreach ($categories as $category)
1020  {
1021    $uppercats = str_replace(',', '/', $category['uppercats']);
1022    $cat_fulldirs[$category['id']] = $galleries_url[$category['site_id']];
1023    $cat_fulldirs[$category['id']].= preg_replace('/(\d+)/e',
1024                                                  "\$cat_dirs['$1']",
1025                                                  $uppercats);
1026  }
1027
1028  return $cat_fulldirs;
1029}
1030
1031/**
1032 * returns an array with all file system files according to
1033 * $conf['file_ext']
1034 *
1035 * @param string $path
1036 * @param bool recursive
1037 * @return array
1038 */
1039function get_fs($path, $recursive = true)
1040{
1041  global $conf;
1042
1043  // because isset is faster than in_array...
1044  if (!isset($conf['flip_picture_ext']))
1045  {
1046    $conf['flip_picture_ext'] = array_flip($conf['picture_ext']);
1047  }
1048  if (!isset($conf['flip_file_ext']))
1049  {
1050    $conf['flip_file_ext'] = array_flip($conf['file_ext']);
1051  }
1052
1053  $fs['elements'] = array();
1054  $fs['thumbnails'] = array();
1055  $fs['representatives'] = array();
1056  $subdirs = array();
1057
1058  if (is_dir($path))
1059  {
1060    if ($contents = opendir($path))
1061    {
1062      while (($node = readdir($contents)) !== false)
1063      {
1064        if (is_file($path.'/'.$node))
1065        {
1066          $extension = get_extension($node);
1067         
1068//          if (in_array($extension, $conf['picture_ext']))
1069          if (isset($conf['flip_picture_ext'][$extension]))
1070          {
1071            if (basename($path) == 'thumbnail')
1072            {
1073              array_push($fs['thumbnails'], $path.'/'.$node);
1074            }
1075            else if (basename($path) == 'pwg_representative')
1076            {
1077              array_push($fs['representatives'], $path.'/'.$node);
1078            }
1079            else
1080            {
1081              array_push($fs['elements'], $path.'/'.$node);
1082            }
1083          }
1084//          else if (in_array($extension, $conf['file_ext']))
1085          else if (isset($conf['flip_file_ext'][$extension]))
1086          {
1087            array_push($fs['elements'], $path.'/'.$node);
1088          }
1089        }
1090        else if (is_dir($path.'/'.$node)
1091                 and $node != '.'
1092                 and $node != '..'
1093                 and $node != 'pwg_high'
1094                 and $recursive)
1095        {
1096          array_push($subdirs, $node);
1097        }
1098      }
1099    }
1100    closedir($contents);
1101
1102    foreach ($subdirs as $subdir)
1103    {
1104      $tmp_fs = get_fs($path.'/'.$subdir);
1105
1106      $fs['elements']        = array_merge($fs['elements'],
1107                                           $tmp_fs['elements']);
1108     
1109      $fs['thumbnails']      = array_merge($fs['thumbnails'],
1110                                           $tmp_fs['thumbnails']);
1111     
1112      $fs['representatives'] = array_merge($fs['representatives'],
1113                                           $tmp_fs['representatives']);
1114    }
1115  }
1116  return $fs;
1117}
1118
1119/**
1120 * stupidly returns the current microsecond since Unix epoch
1121 */
1122function micro_seconds()
1123{
1124  $t1 = explode(' ', microtime());
1125  $t2 = explode('.', $t1[0]);
1126  $t2 = $t1[1].substr($t2[1], 0, 6);
1127  return $t2;
1128}
1129
1130/**
1131 * synchronize base users list and related users list
1132 *
1133 * compares and synchronizes base users table (USERS_TABLE) with its child
1134 * tables (USER_INFOS_TABLE, USER_ACCESS, USER_CACHE, USER_GROUP) : each
1135 * base user must be present in child tables, users in child tables not
1136 * present in base table must be deleted.
1137 *
1138 * @return void
1139 */
1140function sync_users()
1141{
1142  global $conf;
1143 
1144  $query = '
1145SELECT '.$conf['user_fields']['id'].' AS id
1146  FROM '.USERS_TABLE.'
1147;';
1148  $base_users = array_from_query($query, 'id');
1149
1150  $query = '
1151SELECT user_id
1152  FROM '.USER_INFOS_TABLE.'
1153;';
1154  $infos_users = array_from_query($query, 'user_id');
1155
1156  // users present in $base_users and not in $infos_users must be added
1157  $to_create = array_diff($base_users, $infos_users);
1158
1159  if (count($to_create) > 0)
1160  {
1161    $inserts = array();
1162
1163    list($dbnow) = mysql_fetch_row(pwg_query('SELECT NOW();'));
1164
1165    foreach ($to_create as $user_id)
1166    {
1167      $insert = array();
1168      $insert['user_id'] = $user_id;
1169      $insert['status'] = 'guest';
1170      $insert['template'] = $conf['default_template'];
1171      $insert['nb_image_line'] = $conf['nb_image_line'];
1172      $insert['nb_line_page'] = $conf['nb_line_page'];
1173      $insert['language'] = $conf['default_language'];
1174      $insert['recent_period'] = $conf['recent_period'];
1175      $insert['expand'] = boolean_to_string($conf['auto_expand']);
1176      $insert['show_nb_comments'] =
1177        boolean_to_string($conf['show_nb_comments']);
1178      $insert['maxwidth'] = $conf['default_maxwidth'];
1179      $insert['maxheight'] = $conf['default_maxheight'];
1180      $insert['registration_date'] = $dbnow;
1181
1182      array_push($inserts, $insert);
1183    }
1184
1185    mass_inserts(USER_INFOS_TABLE,
1186                 array_keys($inserts[0]),
1187                 $inserts);
1188  }
1189
1190  // users present in user related tables must be present in the base user
1191  // table
1192  $tables =
1193    array(
1194      USER_FEED_TABLE,
1195      USER_INFOS_TABLE,
1196      USER_ACCESS_TABLE,
1197      USER_CACHE_TABLE,
1198      USER_GROUP_TABLE
1199      );
1200  foreach ($tables as $table)
1201  {
1202    $query = '
1203SELECT user_id
1204  FROM '.$table.'
1205;';
1206    $to_delete =
1207      array_diff(
1208        array_from_query($query, 'user_id'),
1209        $base_users
1210        );
1211   
1212    if (count($to_delete) > 0)
1213    {
1214      $query = '
1215DELETE
1216  FROM '.$table.'
1217  WHERE user_id in ('.implode(',', $to_delete).')
1218;';
1219      pwg_query($query);
1220    }
1221  }
1222}
1223
1224/**
1225 * updates categories.uppercats field based on categories.id +
1226 * categories.id_uppercat
1227 *
1228 * @return void
1229 */
1230function update_uppercats()
1231{
1232  $uppercat_ids = array();
1233 
1234  $query = '
1235SELECT id, id_uppercat
1236  FROM '.CATEGORIES_TABLE.'
1237;';
1238  $result = pwg_query($query);
1239  while ($row = mysql_fetch_array($result))
1240  {
1241    $uppercat_ids[$row['id']] =
1242      !empty($row['id_uppercat']) ? $row['id_uppercat'] : 'NULL';
1243  }
1244 
1245  // uppercats array associates a category id to the list of uppercats id.
1246  $uppercats = array();
1247 
1248  foreach (array_keys($uppercat_ids) as $id)
1249  {
1250    $uppercats[$id] = array();
1251
1252    $uppercat = $id;
1253
1254    while ($uppercat != 'NULL')
1255    {
1256      array_push($uppercats[$id], $uppercat);
1257      $uppercat = $uppercat_ids[$uppercat];
1258    }
1259  }
1260
1261  $datas = array();
1262
1263  foreach ($uppercats as $id => $list)
1264  {
1265    array_push(
1266      $datas,
1267      array(
1268        'id' => $id,
1269        'uppercats' => implode(',', array_reverse($list))
1270        )
1271      );
1272  }
1273
1274  $fields = array('primary' => array('id'), 'update' => array('uppercats'));
1275  mass_updates(CATEGORIES_TABLE, $fields, $datas);
1276}
1277
1278/**
1279 * update images.path field
1280 *
1281 * @return void
1282 */
1283function update_path()
1284{
1285  $query = '
1286SELECT DISTINCT(storage_category_id)
1287  FROM '.IMAGES_TABLE.'
1288;';
1289  $cat_ids = array_from_query($query, 'storage_category_id');
1290  $fulldirs = get_fulldirs($cat_ids);
1291 
1292  foreach ($cat_ids as $cat_id)
1293  {
1294    $query = '
1295UPDATE '.IMAGES_TABLE.'
1296  SET path = CONCAT(\''.$fulldirs[$cat_id].'\',\'/\',file)
1297  WHERE storage_category_id = '.$cat_id.'
1298;';
1299    pwg_query($query);
1300  }
1301}
1302
1303/**
1304 * update images.average_rate field
1305 *
1306 * @return void
1307 */
1308function update_average_rate()
1309{
1310  $average_rates = array();
1311 
1312  $query = '
1313SELECT element_id,
1314       ROUND(AVG(rate),2) AS average_rate
1315  FROM '.RATE_TABLE.'
1316  GROUP BY element_id
1317;';
1318  $result = pwg_query($query);
1319  while ($row = mysql_fetch_array($result))
1320  {
1321    array_push($average_rates, $row);
1322  }
1323
1324  $datas = array();
1325  foreach ($average_rates as $item)
1326  {
1327    array_push(
1328      $datas,
1329      array(
1330        'id' => $item['element_id'],
1331        'average_rate' => $item['average_rate']
1332        )
1333      );
1334  }
1335  $fields = array('primary' => array('id'), 'update' => array('average_rate'));
1336  mass_updates(IMAGES_TABLE, $fields, $datas);
1337}
1338
1339/**
1340 * change the parent category of the given categories. The categories are
1341 * supposed virtual.
1342 *
1343 * @param array category identifiers
1344 * @param int parent category identifier
1345 * @return void
1346 */
1347function move_categories($category_ids, $new_parent = -1)
1348{
1349  global $page;
1350
1351  if (count($category_ids) == 0)
1352  {
1353    return;
1354  }
1355
1356  $new_parent = $new_parent < 1 ? 'NULL' : $new_parent;
1357
1358  $categories = array();
1359 
1360  $query = '
1361SELECT id, id_uppercat, status, uppercats
1362  FROM '.CATEGORIES_TABLE.'
1363  WHERE id IN ('.implode(',', $category_ids).')
1364;';
1365  $result = pwg_query($query);
1366  while ($row = mysql_fetch_array($result))
1367  {
1368    $categories[$row['id']] =
1369      array(
1370        'parent' => empty($row['id_uppercat']) ? 'NULL' : $row['id_uppercat'],
1371        'status' => $row['status'],
1372        'uppercats' => $row['uppercats']
1373        );
1374  }
1375 
1376  // is the movement possible? The movement is impossible if you try to move
1377  // a category in a sub-category or itself
1378  if ('NULL' != $new_parent)
1379  {
1380    $query = '
1381SELECT uppercats
1382  FROM '.CATEGORIES_TABLE.'
1383  WHERE id = '.$new_parent.'
1384;';
1385    list($new_parent_uppercats) = mysql_fetch_row(pwg_query($query));
1386
1387    foreach ($categories as $category)
1388    {
1389      // technically, you can't move a category with uppercats 12,125,13,14
1390      // into a new parent category with uppercats 12,125,13,14,24
1391      if (preg_match('/^'.$category['uppercats'].'/', $new_parent_uppercats))
1392      {
1393        array_push(
1394          $page['errors'],
1395          l10n('You cannot move a category in its own sub category')
1396          );
1397        return;
1398      }
1399    }
1400  }
1401 
1402  $tables =
1403    array(
1404      USER_ACCESS_TABLE => 'user_id',
1405      GROUP_ACCESS_TABLE => 'group_id'
1406      );
1407 
1408  $query = '
1409UPDATE '.CATEGORIES_TABLE.'
1410  SET id_uppercat = '.$new_parent.'
1411  WHERE id IN ('.implode(',', $category_ids).')
1412;';
1413  pwg_query($query);
1414
1415  update_uppercats();
1416  ordering();
1417  update_global_rank();
1418
1419  // status and related permissions management
1420  if ('NULL' == $new_parent)
1421  {
1422    $parent_status = 'public';
1423  }
1424  else
1425  {
1426    $query = '
1427SELECT status
1428  FROM '.CATEGORIES_TABLE.'
1429  WHERE id = '.$new_parent.'
1430;';
1431    list($parent_status) = mysql_fetch_row(pwg_query($query));
1432  }
1433
1434  if ('private' == $parent_status)
1435  {
1436    foreach ($categories as $cat_id => $category)
1437    {
1438      switch ($category['status'])
1439      {
1440        case 'public' :
1441        {
1442          set_cat_status(array($cat_id), 'private');
1443          break;
1444        }
1445        case 'private' :
1446        {
1447          $subcats = get_subcat_ids(array($cat_id));
1448       
1449          foreach ($tables as $table => $field)
1450          {
1451            $query = '
1452SELECT '.$field.'
1453  FROM '.$table.'
1454  WHERE cat_id = '.$cat_id.'
1455;';
1456            $category_access = array_from_query($query, $field);
1457
1458            $query = '
1459SELECT '.$field.'
1460  FROM '.$table.'
1461  WHERE cat_id = '.$new_parent.'
1462;';
1463            $parent_access = array_from_query($query, $field);
1464         
1465            $to_delete = array_diff($parent_access, $category_access);
1466         
1467            if (count($to_delete) > 0)
1468            {
1469              $query = '
1470DELETE FROM '.$table.'
1471  WHERE '.$field.' IN ('.implode(',', $to_delete).')
1472    AND cat_id IN ('.implode(',', $subcats).')
1473;';
1474              pwg_query($query);
1475            }
1476          }
1477          break;
1478        }
1479      }
1480    }
1481  }
1482
1483  array_push(
1484    $page['infos'],
1485    sprintf(
1486      l10n('%d categories moved'),
1487      count($categories)
1488      )
1489    );
1490}
1491?>
Note: See TracBrowser for help on using the repository browser.