source: branches/branch-1_5/admin/include/functions.php @ 1001

Last change on this file since 1001 was 1001, checked in by nikrou, 18 years ago

not include .svn directory in the candidates directories for update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 35.4 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: 2006-01-09 19:43:07 +0000 (Mon, 09 Jan 2006) $
10// | last modifier : $Author: nikrou $
11// | revision      : $Revision: 1001 $
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 != '.svn'
559            and $node != 'thumbnail'
560            and $node != 'pwg_high'
561            and $node != 'pwg_representative')
562        {
563          array_push($dirs, $path.'/'.$node);
564          if ($recursive)
565          {
566            $dirs = array_merge($dirs, get_fs_directories($path.'/'.$node));
567          }
568        }
569      }
570    }
571  }
572
573  return $dirs;
574}
575
576/**
577 * inserts multiple lines in a table
578 *
579 * @param string table_name
580 * @param array dbfields
581 * @param array inserts
582 * @return void
583 */
584function mass_inserts($table_name, $dbfields, $datas)
585{
586  // inserts all found categories
587  $query = '
588INSERT INTO '.$table_name.'
589  ('.implode(',', $dbfields).')
590   VALUES';
591  foreach ($datas as $insert_id => $insert)
592  {
593    $query.= '
594  ';
595    if ($insert_id > 0)
596    {
597      $query.= ',';
598    }
599    $query.= '(';
600    foreach ($dbfields as $field_id => $dbfield)
601    {
602      if ($field_id > 0)
603      {
604        $query.= ',';
605      }
606     
607      if (!isset($insert[$dbfield]) or $insert[$dbfield] == '')
608      {
609        $query.= 'NULL';
610      }
611      else
612      {
613        $query.= "'".$insert[$dbfield]."'";
614      }
615    }
616    $query.=')';
617  }
618  $query.= '
619;';
620  pwg_query($query);
621}
622
623/**
624 * updates multiple lines in a table
625 *
626 * @param string table_name
627 * @param array dbfields
628 * @param array datas
629 * @return void
630 */
631function mass_updates($tablename, $dbfields, $datas)
632{
633  // depending on the MySQL version, we use the multi table update or N
634  // update queries
635  $query = 'SELECT VERSION() AS version;';
636  list($mysql_version) = mysql_fetch_array(pwg_query($query));
637  if (count($datas) < 10 or version_compare($mysql_version, '4.0.4') < 0)
638  {
639    // MySQL is prior to version 4.0.4, multi table update feature is not
640    // available
641    foreach ($datas as $data)
642    {
643      $query = '
644UPDATE '.$tablename.'
645  SET ';
646      $is_first = true;
647      foreach ($dbfields['update'] as $num => $key)
648      {
649        if (!$is_first)
650        {
651          $query.= ",\n      ";
652        }
653        $query.= $key.' = ';
654        if (isset($data[$key]) and $data[$key] != '')
655        {
656          $query.= '\''.$data[$key].'\'';
657        }
658        else
659        {
660          $query.= 'NULL';
661        }
662        $is_first = false;
663      }
664      $query.= '
665  WHERE ';
666      foreach ($dbfields['primary'] as $num => $key)
667      {
668        if ($num > 1)
669        {
670          $query.= ' AND ';
671        }
672        $query.= $key.' = \''.$data[$key].'\'';
673      }
674      $query.= '
675;';
676      pwg_query($query);
677    }
678  }
679  else
680  {
681    // creation of the temporary table
682    $query = '
683DESCRIBE '.$tablename.'
684;';
685    $result = pwg_query($query);
686    $columns = array();
687    $all_fields = array_merge($dbfields['primary'], $dbfields['update']);
688    while ($row = mysql_fetch_array($result))
689    {
690      if (in_array($row['Field'], $all_fields))
691      {
692        $column = $row['Field'];
693        $column.= ' '.$row['Type'];
694        if (!isset($row['Null']) or $row['Null'] == '')
695        {
696          $column.= ' NOT NULL';
697        }
698        if (isset($row['Default']))
699        {
700          $column.= " default '".$row['Default']."'";
701        }
702        array_push($columns, $column);
703      }
704    }
705   
706    $temporary_tablename = $tablename.'_'.micro_seconds();
707   
708    $query = '
709CREATE TABLE '.$temporary_tablename.'
710(
711'.implode(",\n", $columns).',
712PRIMARY KEY ('.implode(',', $dbfields['primary']).')
713)
714;';
715    pwg_query($query);
716    mass_inserts($temporary_tablename, $all_fields, $datas);
717    // update of images table by joining with temporary table
718    $query = '
719UPDATE '.$tablename.' AS t1, '.$temporary_tablename.' AS t2
720  SET '.implode("\n    , ",
721                array_map(
722                  create_function('$s', 'return "t1.$s = t2.$s";')
723                  , $dbfields['update'])).'
724  WHERE '.implode("\n    AND ",
725                array_map(
726                  create_function('$s', 'return "t1.$s = t2.$s";')
727                  , $dbfields['primary'])).'
728;';
729    pwg_query($query);
730    $query = '
731DROP TABLE '.$temporary_tablename.'
732;';
733    pwg_query($query);
734  }
735}
736
737/**
738 * updates the global_rank of categories under the given id_uppercat
739 *
740 * @param int id_uppercat
741 * @return void
742 */
743function update_global_rank($id_uppercat = 'all')
744{
745  $query = '
746SELECT id,rank
747  FROM '.CATEGORIES_TABLE.'
748;';
749  $result = pwg_query($query);
750  $ranks_array = array();
751  while ($row = mysql_fetch_array($result))
752  {
753    $ranks_array[$row['id']] = $row['rank'];
754  }
755
756  // which categories to update ?
757  $uppercats_array = array();
758
759  $query = '
760SELECT id,uppercats
761  FROM '.CATEGORIES_TABLE;
762  if (is_numeric($id_uppercat))
763  {
764    $query.= '
765  WHERE uppercats REGEXP \'(^|,)'.$id_uppercat.'(,|$)\'
766    AND id != '.$id_uppercat.'
767';
768  }
769  $query.= '
770;';
771  $result = pwg_query($query);
772  while ($row = mysql_fetch_array($result))
773  {
774    $uppercats_array[$row['id']] =  $row['uppercats'];
775  }
776 
777  $datas = array();
778  foreach ($uppercats_array as $id => $uppercats)
779  {
780    $data = array();
781    $data['id'] = $id;
782    $global_rank = preg_replace('/(\d+)/e',
783                                "\$ranks_array['$1']",
784                                str_replace(',', '.', $uppercats));
785    $data['global_rank'] = $global_rank;
786    array_push($datas, $data);
787  }
788
789  $fields = array('primary' => array('id'), 'update' => array('global_rank'));
790  mass_updates(CATEGORIES_TABLE, $fields, $datas);
791}
792
793/**
794 * change the visible property on a set of categories
795 *
796 * @param array categories
797 * @param string value
798 * @return void
799 */
800function set_cat_visible($categories, $value)
801{
802  if (!in_array($value, array('true', 'false')))
803  {
804    return false;
805  }
806
807  // unlocking a category => all its parent categories become unlocked
808  if ($value == 'true')
809  {
810    $uppercats = get_uppercat_ids($categories);
811    $query = '
812UPDATE '.CATEGORIES_TABLE.'
813  SET visible = \'true\'
814  WHERE id IN ('.implode(',', $uppercats).')
815;';
816    pwg_query($query);
817  }
818  // locking a category   => all its child categories become locked
819  if ($value == 'false')
820  {
821    $subcats = get_subcat_ids($categories);
822    $query = '
823UPDATE '.CATEGORIES_TABLE.'
824  SET visible = \'false\'
825  WHERE id IN ('.implode(',', $subcats).')
826;';
827    pwg_query($query);
828  }
829}
830
831/**
832 * change the status property on a set of categories : private or public
833 *
834 * @param array categories
835 * @param string value
836 * @return void
837 */
838function set_cat_status($categories, $value)
839{
840  if (!in_array($value, array('public', 'private')))
841  {
842    return false;
843  }
844
845  // make public a category => all its parent categories become public
846  if ($value == 'public')
847  {
848    $uppercats = get_uppercat_ids($categories);
849    $query = '
850UPDATE '.CATEGORIES_TABLE.'
851  SET status = \'public\'
852  WHERE id IN ('.implode(',', $uppercats).')
853;';
854    pwg_query($query);
855  }
856  // make a category private => all its child categories become private
857  if ($value == 'private')
858  {
859    $subcats = get_subcat_ids($categories);
860    $query = '
861UPDATE '.CATEGORIES_TABLE.'
862  SET status = \'private\'
863  WHERE id IN ('.implode(',', $subcats).')
864;';
865    pwg_query($query);
866  }
867}
868
869/**
870 * returns all uppercats category ids of the given category ids
871 *
872 * @param array cat_ids
873 * @return array
874 */
875function get_uppercat_ids($cat_ids)
876{
877  if (!is_array($cat_ids) or count($cat_ids) < 1)
878  {
879    return array();
880  }
881 
882  $uppercats = array();
883
884  $query = '
885SELECT uppercats
886  FROM '.CATEGORIES_TABLE.'
887  WHERE id IN ('.implode(',', $cat_ids).')
888;';
889  $result = pwg_query($query);
890  while ($row = mysql_fetch_array($result))
891  {
892    $uppercats = array_merge($uppercats,
893                             explode(',', $row['uppercats']));
894  }
895  $uppercats = array_unique($uppercats);
896
897  return $uppercats;
898}
899
900/**
901 * set a new random representant to the categories
902 *
903 * @param array categories
904 */
905function set_random_representant($categories)
906{
907  $datas = array();
908  foreach ($categories as $category_id)
909  {
910    $query = '
911SELECT image_id
912  FROM '.IMAGE_CATEGORY_TABLE.'
913  WHERE category_id = '.$category_id.'
914  ORDER BY RAND()
915  LIMIT 0,1
916;';
917    list($representative) = mysql_fetch_array(pwg_query($query));
918    $data = array('id' => $category_id,
919                  'representative_picture_id' => $representative);
920    array_push($datas, $data);
921  }
922
923  $fields = array('primary' => array('id'),
924                  'update' => array('representative_picture_id'));
925  mass_updates(CATEGORIES_TABLE, $fields, $datas);
926}
927
928/**
929 * order categories (update categories.rank and global_rank database fields)
930 *
931 * the purpose of this function is to give a rank for all categories
932 * (insides its sub-category), even the newer that have none at te
933 * beginning. For this, ordering function selects all categories ordered by
934 * rank ASC then name ASC for each uppercat.
935 *
936 * @returns void
937 */
938function ordering()
939{
940  $current_rank = 0;
941  $current_uppercat = '';
942               
943  $query = '
944SELECT id, if(id_uppercat is null,\'\',id_uppercat) AS id_uppercat
945  FROM '.CATEGORIES_TABLE.'
946  ORDER BY id_uppercat,rank,name
947;';
948  $result = pwg_query($query);
949  $datas = array();
950  while ($row = mysql_fetch_array($result))
951  {
952    if ($row['id_uppercat'] != $current_uppercat)
953    {
954      $current_rank = 0;
955      $current_uppercat = $row['id_uppercat'];
956    }
957    $data = array('id' => $row['id'], 'rank' => ++$current_rank);
958    array_push($datas, $data);
959  }
960
961  $fields = array('primary' => array('id'), 'update' => array('rank'));
962  mass_updates(CATEGORIES_TABLE, $fields, $datas);
963}
964
965/**
966 * returns the fulldir for each given category id
967 *
968 * @param array cat_ids
969 * @return array
970 */
971function get_fulldirs($cat_ids)
972{
973  if (count($cat_ids) == 0)
974  {
975    return array();
976  }
977 
978  // caching directories of existing categories
979  $query = '
980SELECT id, dir
981  FROM '.CATEGORIES_TABLE.'
982  WHERE dir IS NOT NULL
983;';
984  $result = pwg_query($query);
985  $cat_dirs = array();
986  while ($row = mysql_fetch_array($result))
987  {
988    $cat_dirs[$row['id']] = $row['dir'];
989  }
990
991  // caching galleries_url
992  $query = '
993SELECT id, galleries_url
994  FROM '.SITES_TABLE.'
995;';
996  $result = pwg_query($query);
997  $galleries_url = array();
998  while ($row = mysql_fetch_array($result))
999  {
1000    $galleries_url[$row['id']] = $row['galleries_url'];
1001  }
1002
1003  // categories : id, site_id, uppercats
1004  $categories = array();
1005 
1006  $query = '
1007SELECT id, uppercats, site_id
1008  FROM '.CATEGORIES_TABLE.'
1009  WHERE id IN (
1010'.wordwrap(implode(', ', $cat_ids), 80, "\n").')
1011;';
1012  $result = pwg_query($query);
1013  while ($row = mysql_fetch_array($result))
1014  {
1015    array_push($categories, $row);
1016  }
1017 
1018  // filling $cat_fulldirs
1019  $cat_fulldirs = array();
1020  foreach ($categories as $category)
1021  {
1022    $uppercats = str_replace(',', '/', $category['uppercats']);
1023    $cat_fulldirs[$category['id']] = $galleries_url[$category['site_id']];
1024    $cat_fulldirs[$category['id']].= preg_replace('/(\d+)/e',
1025                                                  "\$cat_dirs['$1']",
1026                                                  $uppercats);
1027  }
1028
1029  return $cat_fulldirs;
1030}
1031
1032/**
1033 * returns an array with all file system files according to
1034 * $conf['file_ext']
1035 *
1036 * @param string $path
1037 * @param bool recursive
1038 * @return array
1039 */
1040function get_fs($path, $recursive = true)
1041{
1042  global $conf;
1043
1044  // because isset is faster than in_array...
1045  if (!isset($conf['flip_picture_ext']))
1046  {
1047    $conf['flip_picture_ext'] = array_flip($conf['picture_ext']);
1048  }
1049  if (!isset($conf['flip_file_ext']))
1050  {
1051    $conf['flip_file_ext'] = array_flip($conf['file_ext']);
1052  }
1053
1054  $fs['elements'] = array();
1055  $fs['thumbnails'] = array();
1056  $fs['representatives'] = array();
1057  $subdirs = array();
1058
1059  if (is_dir($path))
1060  {
1061    if ($contents = opendir($path))
1062    {
1063      while (($node = readdir($contents)) !== false)
1064      {
1065        if (is_file($path.'/'.$node))
1066        {
1067          $extension = get_extension($node);
1068         
1069//          if (in_array($extension, $conf['picture_ext']))
1070          if (isset($conf['flip_picture_ext'][$extension]))
1071          {
1072            if (basename($path) == 'thumbnail')
1073            {
1074              array_push($fs['thumbnails'], $path.'/'.$node);
1075            }
1076            else if (basename($path) == 'pwg_representative')
1077            {
1078              array_push($fs['representatives'], $path.'/'.$node);
1079            }
1080            else
1081            {
1082              array_push($fs['elements'], $path.'/'.$node);
1083            }
1084          }
1085//          else if (in_array($extension, $conf['file_ext']))
1086          else if (isset($conf['flip_file_ext'][$extension]))
1087          {
1088            array_push($fs['elements'], $path.'/'.$node);
1089          }
1090        }
1091        else if (is_dir($path.'/'.$node)
1092                 and $node != '.'
1093                 and $node != '..'
1094                 and $node != 'pwg_high'
1095                 and $recursive)
1096        {
1097          array_push($subdirs, $node);
1098        }
1099      }
1100    }
1101    closedir($contents);
1102
1103    foreach ($subdirs as $subdir)
1104    {
1105      $tmp_fs = get_fs($path.'/'.$subdir);
1106
1107      $fs['elements']        = array_merge($fs['elements'],
1108                                           $tmp_fs['elements']);
1109     
1110      $fs['thumbnails']      = array_merge($fs['thumbnails'],
1111                                           $tmp_fs['thumbnails']);
1112     
1113      $fs['representatives'] = array_merge($fs['representatives'],
1114                                           $tmp_fs['representatives']);
1115    }
1116  }
1117  return $fs;
1118}
1119
1120/**
1121 * stupidly returns the current microsecond since Unix epoch
1122 */
1123function micro_seconds()
1124{
1125  $t1 = explode(' ', microtime());
1126  $t2 = explode('.', $t1[0]);
1127  $t2 = $t1[1].substr($t2[1], 0, 6);
1128  return $t2;
1129}
1130
1131/**
1132 * synchronize base users list and related users list
1133 *
1134 * compares and synchronizes base users table (USERS_TABLE) with its child
1135 * tables (USER_INFOS_TABLE, USER_ACCESS, USER_CACHE, USER_GROUP) : each
1136 * base user must be present in child tables, users in child tables not
1137 * present in base table must be deleted.
1138 *
1139 * @return void
1140 */
1141function sync_users()
1142{
1143  global $conf;
1144 
1145  $query = '
1146SELECT '.$conf['user_fields']['id'].' AS id
1147  FROM '.USERS_TABLE.'
1148;';
1149  $base_users = array_from_query($query, 'id');
1150
1151  $query = '
1152SELECT user_id
1153  FROM '.USER_INFOS_TABLE.'
1154;';
1155  $infos_users = array_from_query($query, 'user_id');
1156
1157  // users present in $base_users and not in $infos_users must be added
1158  $to_create = array_diff($base_users, $infos_users);
1159
1160  if (count($to_create) > 0)
1161  {
1162    $inserts = array();
1163
1164    list($dbnow) = mysql_fetch_row(pwg_query('SELECT NOW();'));
1165
1166    foreach ($to_create as $user_id)
1167    {
1168      $insert = array();
1169      $insert['user_id'] = $user_id;
1170      $insert['status'] = 'guest';
1171      $insert['template'] = $conf['default_template'];
1172      $insert['nb_image_line'] = $conf['nb_image_line'];
1173      $insert['nb_line_page'] = $conf['nb_line_page'];
1174      $insert['language'] = $conf['default_language'];
1175      $insert['recent_period'] = $conf['recent_period'];
1176      $insert['expand'] = boolean_to_string($conf['auto_expand']);
1177      $insert['show_nb_comments'] =
1178        boolean_to_string($conf['show_nb_comments']);
1179      $insert['maxwidth'] = $conf['default_maxwidth'];
1180      $insert['maxheight'] = $conf['default_maxheight'];
1181      $insert['registration_date'] = $dbnow;
1182
1183      array_push($inserts, $insert);
1184    }
1185
1186    mass_inserts(USER_INFOS_TABLE,
1187                 array_keys($inserts[0]),
1188                 $inserts);
1189  }
1190
1191  // users present in user related tables must be present in the base user
1192  // table
1193  $tables =
1194    array(
1195      USER_FEED_TABLE,
1196      USER_INFOS_TABLE,
1197      USER_ACCESS_TABLE,
1198      USER_CACHE_TABLE,
1199      USER_GROUP_TABLE
1200      );
1201  foreach ($tables as $table)
1202  {
1203    $query = '
1204SELECT user_id
1205  FROM '.$table.'
1206;';
1207    $to_delete =
1208      array_diff(
1209        array_from_query($query, 'user_id'),
1210        $base_users
1211        );
1212   
1213    if (count($to_delete) > 0)
1214    {
1215      $query = '
1216DELETE
1217  FROM '.$table.'
1218  WHERE user_id in ('.implode(',', $to_delete).')
1219;';
1220      pwg_query($query);
1221    }
1222  }
1223}
1224
1225/**
1226 * updates categories.uppercats field based on categories.id +
1227 * categories.id_uppercat
1228 *
1229 * @return void
1230 */
1231function update_uppercats()
1232{
1233  $uppercat_ids = array();
1234 
1235  $query = '
1236SELECT id, id_uppercat
1237  FROM '.CATEGORIES_TABLE.'
1238;';
1239  $result = pwg_query($query);
1240  while ($row = mysql_fetch_array($result))
1241  {
1242    $uppercat_ids[$row['id']] =
1243      !empty($row['id_uppercat']) ? $row['id_uppercat'] : 'NULL';
1244  }
1245 
1246  // uppercats array associates a category id to the list of uppercats id.
1247  $uppercats = array();
1248 
1249  foreach (array_keys($uppercat_ids) as $id)
1250  {
1251    $uppercats[$id] = array();
1252
1253    $uppercat = $id;
1254
1255    while ($uppercat != 'NULL')
1256    {
1257      array_push($uppercats[$id], $uppercat);
1258      $uppercat = $uppercat_ids[$uppercat];
1259    }
1260  }
1261
1262  $datas = array();
1263
1264  foreach ($uppercats as $id => $list)
1265  {
1266    array_push(
1267      $datas,
1268      array(
1269        'id' => $id,
1270        'uppercats' => implode(',', array_reverse($list))
1271        )
1272      );
1273  }
1274
1275  $fields = array('primary' => array('id'), 'update' => array('uppercats'));
1276  mass_updates(CATEGORIES_TABLE, $fields, $datas);
1277}
1278
1279/**
1280 * update images.path field
1281 *
1282 * @return void
1283 */
1284function update_path()
1285{
1286  $query = '
1287SELECT DISTINCT(storage_category_id)
1288  FROM '.IMAGES_TABLE.'
1289;';
1290  $cat_ids = array_from_query($query, 'storage_category_id');
1291  $fulldirs = get_fulldirs($cat_ids);
1292 
1293  foreach ($cat_ids as $cat_id)
1294  {
1295    $query = '
1296UPDATE '.IMAGES_TABLE.'
1297  SET path = CONCAT(\''.$fulldirs[$cat_id].'\',\'/\',file)
1298  WHERE storage_category_id = '.$cat_id.'
1299;';
1300    pwg_query($query);
1301  }
1302}
1303
1304/**
1305 * update images.average_rate field
1306 *
1307 * @return void
1308 */
1309function update_average_rate()
1310{
1311  $average_rates = array();
1312 
1313  $query = '
1314SELECT element_id,
1315       ROUND(AVG(rate),2) AS average_rate
1316  FROM '.RATE_TABLE.'
1317  GROUP BY element_id
1318;';
1319  $result = pwg_query($query);
1320  while ($row = mysql_fetch_array($result))
1321  {
1322    array_push($average_rates, $row);
1323  }
1324
1325  $datas = array();
1326  foreach ($average_rates as $item)
1327  {
1328    array_push(
1329      $datas,
1330      array(
1331        'id' => $item['element_id'],
1332        'average_rate' => $item['average_rate']
1333        )
1334      );
1335  }
1336  $fields = array('primary' => array('id'), 'update' => array('average_rate'));
1337  mass_updates(IMAGES_TABLE, $fields, $datas);
1338}
1339
1340/**
1341 * change the parent category of the given categories. The categories are
1342 * supposed virtual.
1343 *
1344 * @param array category identifiers
1345 * @param int parent category identifier
1346 * @return void
1347 */
1348function move_categories($category_ids, $new_parent = -1)
1349{
1350  global $page;
1351
1352  if (count($category_ids) == 0)
1353  {
1354    return;
1355  }
1356
1357  $new_parent = $new_parent < 1 ? 'NULL' : $new_parent;
1358
1359  $categories = array();
1360 
1361  $query = '
1362SELECT id, id_uppercat, status, uppercats
1363  FROM '.CATEGORIES_TABLE.'
1364  WHERE id IN ('.implode(',', $category_ids).')
1365;';
1366  $result = pwg_query($query);
1367  while ($row = mysql_fetch_array($result))
1368  {
1369    $categories[$row['id']] =
1370      array(
1371        'parent' => empty($row['id_uppercat']) ? 'NULL' : $row['id_uppercat'],
1372        'status' => $row['status'],
1373        'uppercats' => $row['uppercats']
1374        );
1375  }
1376 
1377  // is the movement possible? The movement is impossible if you try to move
1378  // a category in a sub-category or itself
1379  if ('NULL' != $new_parent)
1380  {
1381    $query = '
1382SELECT uppercats
1383  FROM '.CATEGORIES_TABLE.'
1384  WHERE id = '.$new_parent.'
1385;';
1386    list($new_parent_uppercats) = mysql_fetch_row(pwg_query($query));
1387
1388    foreach ($categories as $category)
1389    {
1390      // technically, you can't move a category with uppercats 12,125,13,14
1391      // into a new parent category with uppercats 12,125,13,14,24
1392      if (preg_match('/^'.$category['uppercats'].'/', $new_parent_uppercats))
1393      {
1394        array_push(
1395          $page['errors'],
1396          l10n('You cannot move a category in its own sub category')
1397          );
1398        return;
1399      }
1400    }
1401  }
1402 
1403  $tables =
1404    array(
1405      USER_ACCESS_TABLE => 'user_id',
1406      GROUP_ACCESS_TABLE => 'group_id'
1407      );
1408 
1409  $query = '
1410UPDATE '.CATEGORIES_TABLE.'
1411  SET id_uppercat = '.$new_parent.'
1412  WHERE id IN ('.implode(',', $category_ids).')
1413;';
1414  pwg_query($query);
1415
1416  update_uppercats();
1417  ordering();
1418  update_global_rank();
1419
1420  // status and related permissions management
1421  if ('NULL' == $new_parent)
1422  {
1423    $parent_status = 'public';
1424  }
1425  else
1426  {
1427    $query = '
1428SELECT status
1429  FROM '.CATEGORIES_TABLE.'
1430  WHERE id = '.$new_parent.'
1431;';
1432    list($parent_status) = mysql_fetch_row(pwg_query($query));
1433  }
1434
1435  if ('private' == $parent_status)
1436  {
1437    foreach ($categories as $cat_id => $category)
1438    {
1439      switch ($category['status'])
1440      {
1441        case 'public' :
1442        {
1443          set_cat_status(array($cat_id), 'private');
1444          break;
1445        }
1446        case 'private' :
1447        {
1448          $subcats = get_subcat_ids(array($cat_id));
1449       
1450          foreach ($tables as $table => $field)
1451          {
1452            $query = '
1453SELECT '.$field.'
1454  FROM '.$table.'
1455  WHERE cat_id = '.$cat_id.'
1456;';
1457            $category_access = array_from_query($query, $field);
1458
1459            $query = '
1460SELECT '.$field.'
1461  FROM '.$table.'
1462  WHERE cat_id = '.$new_parent.'
1463;';
1464            $parent_access = array_from_query($query, $field);
1465         
1466            $to_delete = array_diff($parent_access, $category_access);
1467         
1468            if (count($to_delete) > 0)
1469            {
1470              $query = '
1471DELETE FROM '.$table.'
1472  WHERE '.$field.' IN ('.implode(',', $to_delete).')
1473    AND cat_id IN ('.implode(',', $subcats).')
1474;';
1475              pwg_query($query);
1476            }
1477          }
1478          break;
1479        }
1480      }
1481    }
1482  }
1483
1484  array_push(
1485    $page['infos'],
1486    sprintf(
1487      l10n('%d categories moved'),
1488      count($categories)
1489      )
1490    );
1491}
1492?>
Note: See TracBrowser for help on using the repository browser.