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

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