source: branches/branch-1_6/admin/include/functions.php @ 1222

Last change on this file since 1222 was 1121, checked in by plg, 18 years ago

feature deleted: code for categories link was too complicated for such a
simple fature. Replaced by static association. Links are not persistent
anymore.

modification removed: #image_category.is_storage replaced by
#images.storage_category_id as in branche 1.5..

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 44.0 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-2006 PhpWebGallery Team - http://phpwebgallery.net |
6// +-----------------------------------------------------------------------+
7// | branch        : BSF (Best So Far)
8// | file          : $RCSfile$
9// | last update   : $Date: 2006-04-04 22:29:35 +0000 (Tue, 04 Apr 2006) $
10// | last modifier : $Author: plg $
11// | revision      : $Revision: 1121 $
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
184  $query = '
185DELETE FROM '.GROUP_ACCESS_TABLE.'
186  WHERE cat_id IN (
187'.wordwrap(implode(', ', $ids), 80, "\n").')
188;';
189  pwg_query($query);
190
191  // destruction of the category
192  $query = '
193DELETE FROM '.CATEGORIES_TABLE.'
194  WHERE id IN (
195'.wordwrap(implode(', ', $ids), 80, "\n").')
196;';
197  pwg_query($query);
198
199  if (isset($counts['del_categories']))
200  {
201    $counts['del_categories']+= count($ids);
202  }
203}
204
205// The function delete_elements deletes the elements identified by the
206// (numeric) values of the array $ids. It also deletes (in the database) :
207//    - all the comments related to elements
208//    - all the links between categories and elements
209//    - all the favorites associated to elements
210function delete_elements($ids)
211{
212  global $counts;
213
214  if (count($ids) == 0)
215  {
216    return;
217  }
218
219  // destruction of the comments on the image
220  $query = '
221DELETE FROM '.COMMENTS_TABLE.'
222  WHERE image_id IN (
223'.wordwrap(implode(', ', $ids), 80, "\n").')
224;';
225  pwg_query($query);
226
227  // destruction of the links between images and this category
228  $query = '
229DELETE FROM '.IMAGE_CATEGORY_TABLE.'
230  WHERE image_id IN (
231'.wordwrap(implode(', ', $ids), 80, "\n").')
232;';
233  pwg_query($query);
234
235  // destruction of the links between images and tags
236  $query = '
237DELETE FROM '.IMAGE_TAG_TABLE.'
238  WHERE image_id IN (
239'.wordwrap(implode(', ', $ids), 80, "\n").')
240;';
241  pwg_query($query);
242
243  // destruction of the favorites associated with the picture
244  $query = '
245DELETE FROM '.FAVORITES_TABLE.'
246  WHERE image_id IN (
247'.wordwrap(implode(', ', $ids), 80, "\n").')
248;';
249  pwg_query($query);
250
251  // destruction of the rates associated to this element
252  $query = '
253DELETE FROM '.RATE_TABLE.'
254  WHERE element_id IN (
255'.wordwrap(implode(', ', $ids), 80, "\n").')
256;';
257  pwg_query($query);
258
259  // destruction of the rates associated to this element
260  $query = '
261DELETE FROM '.CADDIE_TABLE.'
262  WHERE element_id IN (
263'.wordwrap(implode(', ', $ids), 80, "\n").')
264;';
265  pwg_query($query);
266
267  // destruction of the image
268  $query = '
269DELETE FROM '.IMAGES_TABLE.'
270  WHERE id IN (
271'.wordwrap(implode(', ', $ids), 80, "\n").')
272;';
273  pwg_query($query);
274
275  if (isset($counts['del_elements']))
276  {
277    $counts['del_elements']+= count($ids);
278  }
279}
280
281// The delete_user function delete a user identified by the $user_id
282// It also deletes :
283//     - all the access linked to this user
284//     - all the links to any group
285//     - all the favorites linked to this user
286//     - calculated permissions linked to the user
287//     - all datas about notifications for the user
288function delete_user($user_id)
289{
290  global $conf;
291
292  // destruction of the access linked to the user
293  $query = '
294DELETE FROM '.USER_ACCESS_TABLE.'
295  WHERE user_id = '.$user_id.'
296;';
297  pwg_query($query);
298
299  // destruction of data notification by mail for this user
300  $query = '
301DELETE FROM '.USER_MAIL_NOTIFICATION_TABLE.'
302  WHERE user_id = '.$user_id.'
303;';
304  pwg_query($query);
305
306  // destruction of data RSS notification for this user
307  $query = '
308DELETE FROM '.USER_FEED_TABLE.'
309  WHERE user_id = '.$user_id.'
310;';
311  pwg_query($query);
312
313  // destruction of the group links for this user
314  $query = '
315DELETE FROM '.USER_GROUP_TABLE.'
316  WHERE user_id = '.$user_id.'
317;';
318  pwg_query($query);
319
320  // destruction of the favorites associated with the user
321  $query = '
322DELETE FROM '.FAVORITES_TABLE.'
323  WHERE user_id = '.$user_id.'
324;';
325  pwg_query($query);
326
327  // deletion of calculated permissions linked to the user
328  $query = '
329DELETE FROM '.USER_CACHE_TABLE.'
330  WHERE user_id = '.$user_id.'
331;';
332  pwg_query($query);
333
334  // deletion of phpwebgallery specific informations
335  $query = '
336DELETE FROM '.USER_INFOS_TABLE.'
337  WHERE user_id = '.$user_id.'
338;';
339  pwg_query($query);
340
341  // destruction of the user
342  $query = '
343DELETE FROM '.USERS_TABLE.'
344  WHERE '.$conf['user_fields']['id'].' = '.$user_id.'
345;';
346  pwg_query($query);
347}
348
349/**
350 * updates calculated informations about a set of categories : date_last and
351 * nb_images. It also verifies that the representative picture is really
352 * linked to the category. Optionnaly recursive.
353 *
354 * @param mixed category id
355 * @param boolean recursive
356 * @returns void
357 */
358function update_category($ids = 'all', $recursive = false)
359{
360  global $conf;
361
362  // retrieving all categories to update
363  $cat_ids = array();
364
365  $query = '
366SELECT id
367  FROM '.CATEGORIES_TABLE;
368  if (is_array($ids))
369  {
370    if ($recursive)
371    {
372      foreach ($ids as $num => $id)
373      {
374        if ($num == 0)
375        {
376          $query.= '
377  WHERE ';
378        }
379        else
380        {
381          $query.= '
382  OR    ';
383        }
384        $query.= 'uppercats REGEXP \'(^|,)'.$id.'(,|$)\'';
385      }
386    }
387    else
388    {
389      $query.= '
390  WHERE id IN ('.wordwrap(implode(', ', $ids), 80, "\n").')';
391    }
392  }
393  $query.= '
394;';
395  $cat_ids = array_unique(array_from_query($query, 'id'));
396
397  if (count($cat_ids) == 0)
398  {
399    return false;
400  }
401
402  // calculate informations about categories retrieved
403  $query = '
404SELECT category_id,
405       COUNT(image_id) AS nb_images,
406       MAX(date_available) AS date_last
407  FROM '.IMAGES_TABLE.' INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id = image_id
408  WHERE category_id IN ('.wordwrap(implode(', ', $cat_ids), 80, "\n").')
409  GROUP BY category_id
410;';
411  $result = pwg_query($query);
412  $datas = array();
413  $query_ids = array();
414  while ( $row = mysql_fetch_array( $result ) )
415  {
416    array_push($query_ids, $row['category_id']);
417
418    array_push(
419      $datas,
420      array(
421        'id'        => $row['category_id'],
422        'date_last' => $row['date_last'],
423        'nb_images' => $row['nb_images']
424        )
425      );
426  }
427  // if all links between a category and elements have disappeared, no line
428  // is returned but the update must be done !
429  foreach (array_diff($cat_ids, $query_ids) as $id)
430  {
431    array_push($datas, array('id' => $id, 'nb_images' => 0));
432  }
433
434  $fields = array('primary' => array('id'),
435                  'update'  => array('date_last', 'nb_images'));
436  mass_updates(CATEGORIES_TABLE, $fields, $datas);
437
438  // representative pictures
439  if (count($cat_ids) > 0)
440  {
441    // find all categories where the setted representative is not possible :
442    // the picture does not exist
443    $query = '
444SELECT c.id
445  FROM '.CATEGORIES_TABLE.' AS c LEFT JOIN '.IMAGES_TABLE.' AS i
446    ON c.representative_picture_id = i.id
447  WHERE representative_picture_id IS NOT NULL
448    AND c.id IN ('.wordwrap(implode(', ', $cat_ids), 80, "\n").')
449    AND i.id IS NULL
450;';
451    $wrong_representant = array_from_query($query, 'id');
452
453    if ($conf['allow_random_representative'])
454    {
455      if (count($wrong_representant) > 0)
456      {
457        $query = '
458UPDATE '.CATEGORIES_TABLE.'
459  SET representative_picture_id = NULL
460  WHERE id IN ('.wordwrap(implode(', ', $wrong_representant), 80, "\n").')
461;';
462        pwg_query($query);
463      }
464    }
465    else
466    {
467      $to_null = array();
468      $to_rand = array();
469
470      if (count($wrong_representant) > 0)
471      {
472        // among the categories with an unknown representant, we dissociate
473        // categories containing pictures and categories containing no
474        // pictures. Indeed, the representant must set to NULL if no picture
475        // in the category and set to a random picture otherwise.
476        $query = '
477SELECT id
478  FROM '.CATEGORIES_TABLE.'
479  WHERE id IN ('.wordwrap(implode(', ', $wrong_representant), 80, "\n").')
480    AND nb_images = 0
481;';
482        $to_null = array_from_query($query, 'id');
483        $to_rand = array_diff($wrong_representant, $to_null);
484      }
485
486      if (count($to_null) > 0)
487      {
488        $query = '
489UPDATE '.CATEGORIES_TABLE.'
490  SET representative_picture_id = NULL
491  WHERE id IN ('.wordwrap(implode(', ', $to_null), 80, "\n").')
492;';
493        pwg_query($query);
494      }
495
496      // If the random representant is not allowed, we need to find
497      // categories with elements and with no representant. Those categories
498      // must be added to the list of categories to set to a random
499      // representant.
500      $query = '
501SELECT id
502  FROM '.CATEGORIES_TABLE.'
503  WHERE representative_picture_id IS NULL
504    AND nb_images != 0
505    AND id IN ('.wordwrap(implode(', ', $cat_ids), 80, "\n").')
506;';
507      $to_rand =
508        array_unique(
509          array_merge(
510            $to_rand,
511            array_from_query($query, 'id')
512            )
513          );
514
515      if (count($to_rand) > 0)
516      {
517        set_random_representant($to_rand);
518      }
519    }
520  }
521}
522
523function date_convert_back( $date )
524{
525  // date arrives at this format : YYYY-MM-DD
526  // It must be transformed in DD/MM/YYYY
527  if ( $date != '' )
528  {
529    list($year,$month,$day) = explode( '-', $date );
530    return $day.'/'.$month.'/'.$year;
531  }
532  else
533  {
534    return '';
535  }
536}
537
538/**
539 * returns an array containing sub-directories which can be a category,
540 * recursive by default
541 *
542 * directories nammed "thumbnail", "pwg_high" or "pwg_representative" are
543 * omitted
544 *
545 * @param string $basedir
546 * @return array
547 */
548function get_fs_directories($path, $recursive = true)
549{
550  $dirs = array();
551
552  if (is_dir($path))
553  {
554    if ($contents = opendir($path))
555    {
556      while (($node = readdir($contents)) !== false)
557      {
558        if (is_dir($path.'/'.$node)
559            and $node != '.'
560            and $node != '..'
561            and $node != '.svn'
562            and $node != 'thumbnail'
563            and $node != 'pwg_high'
564            and $node != 'pwg_representative')
565        {
566          array_push($dirs, $path.'/'.$node);
567          if ($recursive)
568          {
569            $dirs = array_merge($dirs, get_fs_directories($path.'/'.$node));
570          }
571        }
572      }
573    }
574  }
575
576  return $dirs;
577}
578
579/**
580 * inserts multiple lines in a table
581 *
582 * @param string table_name
583 * @param array dbfields
584 * @param array inserts
585 * @return void
586 */
587function mass_inserts($table_name, $dbfields, $datas)
588{
589  // inserts all found categories
590  $query = '
591INSERT INTO '.$table_name.'
592  ('.implode(',', $dbfields).')
593   VALUES';
594  foreach ($datas as $insert_id => $insert)
595  {
596    $query.= '
597  ';
598    if ($insert_id > 0)
599    {
600      $query.= ',';
601    }
602    $query.= '(';
603    foreach ($dbfields as $field_id => $dbfield)
604    {
605      if ($field_id > 0)
606      {
607        $query.= ',';
608      }
609
610      if (!isset($insert[$dbfield]) or $insert[$dbfield] == '')
611      {
612        $query.= 'NULL';
613      }
614      else
615      {
616        $query.= "'".$insert[$dbfield]."'";
617      }
618    }
619    $query.=')';
620  }
621  $query.= '
622;';
623  pwg_query($query);
624}
625
626/**
627 * updates multiple lines in a table
628 *
629 * @param string table_name
630 * @param array dbfields
631 * @param array datas
632 * @return void
633 */
634function mass_updates($tablename, $dbfields, $datas)
635{
636  // depending on the MySQL version, we use the multi table update or N
637  // update queries
638  $query = 'SELECT VERSION() AS version;';
639  list($mysql_version) = mysql_fetch_array(pwg_query($query));
640  if (count($datas) < 10 or version_compare($mysql_version, '4.0.4') < 0)
641  {
642    // MySQL is prior to version 4.0.4, multi table update feature is not
643    // available
644    foreach ($datas as $data)
645    {
646      $query = '
647UPDATE '.$tablename.'
648  SET ';
649      $is_first = true;
650      foreach ($dbfields['update'] as $num => $key)
651      {
652        if (!$is_first)
653        {
654          $query.= ",\n      ";
655        }
656        $query.= $key.' = ';
657        if (isset($data[$key]) and $data[$key] != '')
658        {
659          $query.= '\''.$data[$key].'\'';
660        }
661        else
662        {
663          $query.= 'NULL';
664        }
665        $is_first = false;
666      }
667      $query.= '
668  WHERE ';
669      foreach ($dbfields['primary'] as $num => $key)
670      {
671        if ($num > 1)
672        {
673          $query.= ' AND ';
674        }
675        $query.= $key.' = \''.$data[$key].'\'';
676      }
677      $query.= '
678;';
679      pwg_query($query);
680    }
681  }
682  else
683  {
684    // creation of the temporary table
685    $query = '
686SHOW FULL COLUMNS FROM '.$tablename.'
687;';
688    $result = pwg_query($query);
689    $columns = array();
690    $all_fields = array_merge($dbfields['primary'], $dbfields['update']);
691    while ($row = mysql_fetch_array($result))
692    {
693      if (in_array($row['Field'], $all_fields))
694      {
695        $column = $row['Field'];
696        $column.= ' '.$row['Type'];
697        if (!isset($row['Null']) or $row['Null'] == '')
698        {
699          $column.= ' NOT NULL';
700        }
701        if (isset($row['Default']))
702        {
703          $column.= " default '".$row['Default']."'";
704        }
705        if (isset($row['Collation']) and $row['Collation'] != 'NULL')
706        {
707          $column.= " collate '".$row['Collation']."'";
708        }
709        array_push($columns, $column);
710      }
711    }
712
713    $temporary_tablename = $tablename.'_'.micro_seconds();
714
715    $query = '
716CREATE TABLE '.$temporary_tablename.'
717(
718'.implode(",\n", $columns).',
719PRIMARY KEY ('.implode(',', $dbfields['primary']).')
720)
721;';
722    pwg_query($query);
723    mass_inserts($temporary_tablename, $all_fields, $datas);
724    // update of images table by joining with temporary table
725    $query = '
726UPDATE '.$tablename.' AS t1, '.$temporary_tablename.' AS t2
727  SET '.
728      implode(
729        "\n    , ",
730        array_map(
731          create_function('$s', 'return "t1.$s = t2.$s";'),
732          $dbfields['update']
733          )
734        ).'
735  WHERE '.
736      implode(
737        "\n    AND ",
738        array_map(
739          create_function('$s', 'return "t1.$s = t2.$s";'),
740          $dbfields['primary']
741          )
742        ).'
743;';
744    pwg_query($query);
745    $query = '
746DROP TABLE '.$temporary_tablename.'
747;';
748    pwg_query($query);
749  }
750}
751
752/**
753 * updates the global_rank of categories under the given id_uppercat
754 *
755 * @param int id_uppercat
756 * @return void
757 */
758function update_global_rank($id_uppercat = 'all')
759{
760  $query = '
761SELECT id,rank
762  FROM '.CATEGORIES_TABLE.'
763;';
764  $result = pwg_query($query);
765  $ranks_array = array();
766  while ($row = mysql_fetch_array($result))
767  {
768    $ranks_array[$row['id']] = $row['rank'];
769  }
770
771  // which categories to update ?
772  $uppercats_array = array();
773
774  $query = '
775SELECT id,uppercats
776  FROM '.CATEGORIES_TABLE;
777  if (is_numeric($id_uppercat))
778  {
779    $query.= '
780  WHERE uppercats REGEXP \'(^|,)'.$id_uppercat.'(,|$)\'
781    AND id != '.$id_uppercat.'
782';
783  }
784  $query.= '
785;';
786  $result = pwg_query($query);
787  while ($row = mysql_fetch_array($result))
788  {
789    $uppercats_array[$row['id']] =  $row['uppercats'];
790  }
791
792  $datas = array();
793  foreach ($uppercats_array as $id => $uppercats)
794  {
795    array_push(
796      $datas,
797      array(
798        'id'          => $id,
799        'global_rank' => preg_replace(
800          '/(\d+)/e',
801          "\$ranks_array['$1']",
802          str_replace(',', '.', $uppercats)
803          ),
804        )
805      );
806  }
807
808  mass_updates(
809    CATEGORIES_TABLE,
810    array(
811      'primary' => array('id'),
812      'update'  => array('global_rank')
813      ),
814    $datas
815    );
816}
817
818/**
819 * change the visible property on a set of categories
820 *
821 * @param array categories
822 * @param string value
823 * @return void
824 */
825function set_cat_visible($categories, $value)
826{
827  if (!in_array($value, array('true', 'false')))
828  {
829    return false;
830  }
831
832  // unlocking a category => all its parent categories become unlocked
833  if ($value == 'true')
834  {
835    $uppercats = get_uppercat_ids($categories);
836    $query = '
837UPDATE '.CATEGORIES_TABLE.'
838  SET visible = \'true\'
839  WHERE id IN ('.implode(',', $uppercats).')
840;';
841    pwg_query($query);
842  }
843  // locking a category   => all its child categories become locked
844  if ($value == 'false')
845  {
846    $subcats = get_subcat_ids($categories);
847    $query = '
848UPDATE '.CATEGORIES_TABLE.'
849  SET visible = \'false\'
850  WHERE id IN ('.implode(',', $subcats).')
851;';
852    pwg_query($query);
853  }
854}
855
856/**
857 * change the status property on a set of categories : private or public
858 *
859 * @param array categories
860 * @param string value
861 * @return void
862 */
863function set_cat_status($categories, $value)
864{
865  if (!in_array($value, array('public', 'private')))
866  {
867    return false;
868  }
869
870  // make public a category => all its parent categories become public
871  if ($value == 'public')
872  {
873    $uppercats = get_uppercat_ids($categories);
874    $query = '
875UPDATE '.CATEGORIES_TABLE.'
876  SET status = \'public\'
877  WHERE id IN ('.implode(',', $uppercats).')
878;';
879    pwg_query($query);
880  }
881  // make a category private => all its child categories become private
882  if ($value == 'private')
883  {
884    $subcats = get_subcat_ids($categories);
885    $query = '
886UPDATE '.CATEGORIES_TABLE.'
887  SET status = \'private\'
888  WHERE id IN ('.implode(',', $subcats).')
889;';
890    pwg_query($query);
891  }
892}
893
894/**
895 * returns all uppercats category ids of the given category ids
896 *
897 * @param array cat_ids
898 * @return array
899 */
900function get_uppercat_ids($cat_ids)
901{
902  if (!is_array($cat_ids) or count($cat_ids) < 1)
903  {
904    return array();
905  }
906
907  $uppercats = array();
908
909  $query = '
910SELECT uppercats
911  FROM '.CATEGORIES_TABLE.'
912  WHERE id IN ('.implode(',', $cat_ids).')
913;';
914  $result = pwg_query($query);
915  while ($row = mysql_fetch_array($result))
916  {
917    $uppercats = array_merge($uppercats,
918                             explode(',', $row['uppercats']));
919  }
920  $uppercats = array_unique($uppercats);
921
922  return $uppercats;
923}
924
925/**
926 * set a new random representant to the categories
927 *
928 * @param array categories
929 */
930function set_random_representant($categories)
931{
932  $datas = array();
933  foreach ($categories as $category_id)
934  {
935    $query = '
936SELECT image_id
937  FROM '.IMAGE_CATEGORY_TABLE.'
938  WHERE category_id = '.$category_id.'
939  ORDER BY RAND()
940  LIMIT 0,1
941;';
942    list($representative) = mysql_fetch_array(pwg_query($query));
943    $data = array('id' => $category_id,
944                  'representative_picture_id' => $representative);
945    array_push($datas, $data);
946  }
947
948  $fields = array('primary' => array('id'),
949                  'update' => array('representative_picture_id'));
950  mass_updates(CATEGORIES_TABLE, $fields, $datas);
951}
952
953/**
954 * order categories (update categories.rank and global_rank database fields)
955 *
956 * the purpose of this function is to give a rank for all categories
957 * (insides its sub-category), even the newer that have none at te
958 * beginning. For this, ordering function selects all categories ordered by
959 * rank ASC then name ASC for each uppercat.
960 *
961 * @returns void
962 */
963function ordering()
964{
965  $current_rank = 0;
966  $current_uppercat = '';
967
968  $query = '
969SELECT id, if(id_uppercat is null,\'\',id_uppercat) AS id_uppercat
970  FROM '.CATEGORIES_TABLE.'
971  ORDER BY id_uppercat,rank,name
972;';
973  $result = pwg_query($query);
974  $datas = array();
975  while ($row = mysql_fetch_array($result))
976  {
977    if ($row['id_uppercat'] != $current_uppercat)
978    {
979      $current_rank = 0;
980      $current_uppercat = $row['id_uppercat'];
981    }
982    $data = array('id' => $row['id'], 'rank' => ++$current_rank);
983    array_push($datas, $data);
984  }
985
986  $fields = array('primary' => array('id'), 'update' => array('rank'));
987  mass_updates(CATEGORIES_TABLE, $fields, $datas);
988}
989
990/**
991 * returns the fulldir for each given category id
992 *
993 * @param array cat_ids
994 * @return array
995 */
996function get_fulldirs($cat_ids)
997{
998  if (count($cat_ids) == 0)
999  {
1000    return array();
1001  }
1002
1003  // caching directories of existing categories
1004  $query = '
1005SELECT id, dir
1006  FROM '.CATEGORIES_TABLE.'
1007  WHERE dir IS NOT NULL
1008;';
1009  $result = pwg_query($query);
1010  $cat_dirs = array();
1011  while ($row = mysql_fetch_array($result))
1012  {
1013    $cat_dirs[$row['id']] = $row['dir'];
1014  }
1015
1016  // caching galleries_url
1017  $query = '
1018SELECT id, galleries_url
1019  FROM '.SITES_TABLE.'
1020;';
1021  $result = pwg_query($query);
1022  $galleries_url = array();
1023  while ($row = mysql_fetch_array($result))
1024  {
1025    $galleries_url[$row['id']] = $row['galleries_url'];
1026  }
1027
1028  // categories : id, site_id, uppercats
1029  $categories = array();
1030
1031  $query = '
1032SELECT id, uppercats, site_id
1033  FROM '.CATEGORIES_TABLE.'
1034  WHERE id IN (
1035'.wordwrap(implode(', ', $cat_ids), 80, "\n").')
1036;';
1037  $result = pwg_query($query);
1038  while ($row = mysql_fetch_array($result))
1039  {
1040    array_push($categories, $row);
1041  }
1042
1043  // filling $cat_fulldirs
1044  $cat_fulldirs = array();
1045  foreach ($categories as $category)
1046  {
1047    $uppercats = str_replace(',', '/', $category['uppercats']);
1048    $cat_fulldirs[$category['id']] = $galleries_url[$category['site_id']];
1049    $cat_fulldirs[$category['id']].= preg_replace('/(\d+)/e',
1050                                                  "\$cat_dirs['$1']",
1051                                                  $uppercats);
1052  }
1053
1054  return $cat_fulldirs;
1055}
1056
1057/**
1058 * returns an array with all file system files according to
1059 * $conf['file_ext']
1060 *
1061 * @param string $path
1062 * @param bool recursive
1063 * @return array
1064 */
1065function get_fs($path, $recursive = true)
1066{
1067  global $conf;
1068
1069  // because isset is faster than in_array...
1070  if (!isset($conf['flip_picture_ext']))
1071  {
1072    $conf['flip_picture_ext'] = array_flip($conf['picture_ext']);
1073  }
1074  if (!isset($conf['flip_file_ext']))
1075  {
1076    $conf['flip_file_ext'] = array_flip($conf['file_ext']);
1077  }
1078
1079  $fs['elements'] = array();
1080  $fs['thumbnails'] = array();
1081  $fs['representatives'] = array();
1082  $subdirs = array();
1083
1084  if (is_dir($path))
1085  {
1086    if ($contents = opendir($path))
1087    {
1088      while (($node = readdir($contents)) !== false)
1089      {
1090        if (is_file($path.'/'.$node))
1091        {
1092          $extension = get_extension($node);
1093
1094//          if (in_array($extension, $conf['picture_ext']))
1095          if (isset($conf['flip_picture_ext'][$extension]))
1096          {
1097            if (basename($path) == 'thumbnail')
1098            {
1099              array_push($fs['thumbnails'], $path.'/'.$node);
1100            }
1101            else if (basename($path) == 'pwg_representative')
1102            {
1103              array_push($fs['representatives'], $path.'/'.$node);
1104            }
1105            else
1106            {
1107              array_push($fs['elements'], $path.'/'.$node);
1108            }
1109          }
1110//          else if (in_array($extension, $conf['file_ext']))
1111          else if (isset($conf['flip_file_ext'][$extension]))
1112          {
1113            array_push($fs['elements'], $path.'/'.$node);
1114          }
1115        }
1116        else if (is_dir($path.'/'.$node)
1117                 and $node != '.'
1118                 and $node != '..'
1119                 and $node != 'pwg_high'
1120                 and $recursive)
1121        {
1122          array_push($subdirs, $node);
1123        }
1124      }
1125    }
1126    closedir($contents);
1127
1128    foreach ($subdirs as $subdir)
1129    {
1130      $tmp_fs = get_fs($path.'/'.$subdir);
1131
1132      $fs['elements']        = array_merge($fs['elements'],
1133                                           $tmp_fs['elements']);
1134
1135      $fs['thumbnails']      = array_merge($fs['thumbnails'],
1136                                           $tmp_fs['thumbnails']);
1137
1138      $fs['representatives'] = array_merge($fs['representatives'],
1139                                           $tmp_fs['representatives']);
1140    }
1141  }
1142  return $fs;
1143}
1144
1145/**
1146 * stupidly returns the current microsecond since Unix epoch
1147 */
1148function micro_seconds()
1149{
1150  $t1 = explode(' ', microtime());
1151  $t2 = explode('.', $t1[0]);
1152  $t2 = $t1[1].substr($t2[1], 0, 6);
1153  return $t2;
1154}
1155
1156/**
1157 * synchronize base users list and related users list
1158 *
1159 * compares and synchronizes base users table (USERS_TABLE) with its child
1160 * tables (USER_INFOS_TABLE, USER_ACCESS, USER_CACHE, USER_GROUP) : each
1161 * base user must be present in child tables, users in child tables not
1162 * present in base table must be deleted.
1163 *
1164 * @return void
1165 */
1166function sync_users()
1167{
1168  global $conf;
1169
1170  $query = '
1171SELECT '.$conf['user_fields']['id'].' AS id
1172  FROM '.USERS_TABLE.'
1173;';
1174  $base_users = array_from_query($query, 'id');
1175
1176  $query = '
1177SELECT user_id
1178  FROM '.USER_INFOS_TABLE.'
1179;';
1180  $infos_users = array_from_query($query, 'user_id');
1181
1182  // users present in $base_users and not in $infos_users must be added
1183  $to_create = array_diff($base_users, $infos_users);
1184
1185  if (count($to_create) > 0)
1186  {
1187    $inserts = array();
1188
1189    list($dbnow) = mysql_fetch_row(pwg_query('SELECT NOW();'));
1190
1191    foreach ($to_create as $user_id)
1192    {
1193      $insert = array();
1194      $insert['user_id'] = $user_id;
1195      $insert['status'] = 'normal';
1196      $insert['template'] = $conf['default_template'];
1197      $insert['nb_image_line'] = $conf['nb_image_line'];
1198      $insert['nb_line_page'] = $conf['nb_line_page'];
1199      $insert['language'] = $conf['default_language'];
1200      $insert['recent_period'] = $conf['recent_period'];
1201      $insert['expand'] = boolean_to_string($conf['auto_expand']);
1202      $insert['show_nb_comments'] =
1203        boolean_to_string($conf['show_nb_comments']);
1204      $insert['maxwidth'] = $conf['default_maxwidth'];
1205      $insert['maxheight'] = $conf['default_maxheight'];
1206      $insert['registration_date'] = $dbnow;
1207
1208      array_push($inserts, $insert);
1209    }
1210
1211    mass_inserts(USER_INFOS_TABLE,
1212                 array_keys($inserts[0]),
1213                 $inserts);
1214  }
1215
1216  // users present in user related tables must be present in the base user
1217  // table
1218  $tables = array(
1219    USER_MAIL_NOTIFICATION_TABLE,
1220    USER_FEED_TABLE,
1221    USER_INFOS_TABLE,
1222    USER_ACCESS_TABLE,
1223    USER_CACHE_TABLE,
1224    USER_GROUP_TABLE
1225    );
1226 
1227  foreach ($tables as $table)
1228  {
1229    $query = '
1230SELECT user_id
1231  FROM '.$table.'
1232;';
1233    $to_delete = array_diff(
1234      array_from_query($query, 'user_id'),
1235      $base_users
1236      );
1237
1238    if (count($to_delete) > 0)
1239    {
1240      $query = '
1241DELETE
1242  FROM '.$table.'
1243  WHERE user_id in ('.implode(',', $to_delete).')
1244;';
1245      pwg_query($query);
1246    }
1247  }
1248}
1249
1250/**
1251 * updates categories.uppercats field based on categories.id +
1252 * categories.id_uppercat
1253 *
1254 * @return void
1255 */
1256function update_uppercats()
1257{
1258  $uppercat_ids = array();
1259
1260  $query = '
1261SELECT id, id_uppercat
1262  FROM '.CATEGORIES_TABLE.'
1263;';
1264  $result = pwg_query($query);
1265  while ($row = mysql_fetch_array($result))
1266  {
1267    $uppercat_ids[$row['id']] =
1268      !empty($row['id_uppercat']) ? $row['id_uppercat'] : 'NULL';
1269  }
1270
1271  // uppercats array associates a category id to the list of uppercats id.
1272  $uppercats = array();
1273
1274  foreach (array_keys($uppercat_ids) as $id)
1275  {
1276    $uppercats[$id] = array();
1277
1278    $uppercat = $id;
1279
1280    while ($uppercat != 'NULL')
1281    {
1282      array_push($uppercats[$id], $uppercat);
1283      $uppercat = $uppercat_ids[$uppercat];
1284    }
1285  }
1286
1287  $datas = array();
1288
1289  foreach ($uppercats as $id => $list)
1290  {
1291    array_push(
1292      $datas,
1293      array(
1294        'id' => $id,
1295        'uppercats' => implode(',', array_reverse($list))
1296        )
1297      );
1298  }
1299
1300  $fields = array('primary' => array('id'), 'update' => array('uppercats'));
1301  mass_updates(CATEGORIES_TABLE, $fields, $datas);
1302}
1303
1304/**
1305 * update images.path field
1306 *
1307 * @return void
1308 */
1309function update_path()
1310{
1311  $query = '
1312SELECT DISTINCT(storage_category_id)
1313  FROM '.IMAGES_TABLE.'
1314;';
1315  $cat_ids = array_from_query($query, 'storage_category_id');
1316  $fulldirs = get_fulldirs($cat_ids);
1317
1318  foreach ($cat_ids as $cat_id)
1319  {
1320    $query = '
1321UPDATE '.IMAGES_TABLE.'
1322  SET path = CONCAT(\''.$fulldirs[$cat_id].'\',\'/\',file)
1323  WHERE storage_category_id = '.$cat_id.'
1324;';
1325    pwg_query($query);
1326  }
1327}
1328
1329/**
1330 * update images.average_rate field
1331 * param int $element_id optional, otherwise applies to all
1332 * @return void
1333 */
1334function update_average_rate( $element_id=-1 )
1335{
1336  $query = '
1337SELECT element_id,
1338       ROUND(AVG(rate),2) AS average_rate
1339  FROM '.RATE_TABLE;
1340  if ( $element_id != -1 )
1341  {
1342    $query .= ' WHERE element_id=' . $element_id;
1343  }
1344  $query .= ' GROUP BY element_id;';
1345
1346  $result = pwg_query($query);
1347
1348  $datas = array();
1349
1350  while ($row = mysql_fetch_array($result))
1351  {
1352    array_push(
1353      $datas,
1354      array(
1355        'id' => $row['element_id'],
1356        'average_rate' => $row['average_rate']
1357        )
1358      );
1359  }
1360
1361  mass_updates(
1362    IMAGES_TABLE,
1363    array(
1364      'primary' => array('id'),
1365      'update' => array('average_rate')
1366      ),
1367    $datas
1368    );
1369
1370  $query='
1371SELECT id FROM '.IMAGES_TABLE .'
1372  LEFT JOIN '.RATE_TABLE.' ON id=element_id
1373  WHERE element_id IS NULL AND average_rate IS NOT NULL';
1374  if ( $element_id != -1 )
1375  {
1376    $query .= ' AND id=' . $element_id;
1377  }
1378  $to_update = array_from_query( $query, 'id');
1379
1380  if ( !empty($to_update) )
1381  {
1382    $query='
1383UPDATE '.IMAGES_TABLE .'
1384  SET average_rate=NULL
1385  WHERE id IN (' . implode(',',$to_update) . ')';
1386    pwg_query($query);
1387  }
1388}
1389
1390/**
1391 * change the parent category of the given categories. The categories are
1392 * supposed virtual.
1393 *
1394 * @param array category identifiers
1395 * @param int parent category identifier
1396 * @return void
1397 */
1398function move_categories($category_ids, $new_parent = -1)
1399{
1400  global $page;
1401
1402  if (count($category_ids) == 0)
1403  {
1404    return;
1405  }
1406
1407  $new_parent = $new_parent < 1 ? 'NULL' : $new_parent;
1408
1409  $categories = array();
1410
1411  $query = '
1412SELECT id, id_uppercat, status, uppercats
1413  FROM '.CATEGORIES_TABLE.'
1414  WHERE id IN ('.implode(',', $category_ids).')
1415;';
1416  $result = pwg_query($query);
1417  while ($row = mysql_fetch_array($result))
1418  {
1419    $categories[$row['id']] =
1420      array(
1421        'parent' => empty($row['id_uppercat']) ? 'NULL' : $row['id_uppercat'],
1422        'status' => $row['status'],
1423        'uppercats' => $row['uppercats']
1424        );
1425  }
1426
1427  // is the movement possible? The movement is impossible if you try to move
1428  // a category in a sub-category or itself
1429  if ('NULL' != $new_parent)
1430  {
1431    $query = '
1432SELECT uppercats
1433  FROM '.CATEGORIES_TABLE.'
1434  WHERE id = '.$new_parent.'
1435;';
1436    list($new_parent_uppercats) = mysql_fetch_row(pwg_query($query));
1437
1438    foreach ($categories as $category)
1439    {
1440      // technically, you can't move a category with uppercats 12,125,13,14
1441      // into a new parent category with uppercats 12,125,13,14,24
1442      if (preg_match('/^'.$category['uppercats'].'/', $new_parent_uppercats))
1443      {
1444        array_push(
1445          $page['errors'],
1446          l10n('You cannot move a category in its own sub category')
1447          );
1448        return;
1449      }
1450    }
1451  }
1452
1453  $tables =
1454    array(
1455      USER_ACCESS_TABLE => 'user_id',
1456      GROUP_ACCESS_TABLE => 'group_id'
1457      );
1458
1459  $query = '
1460UPDATE '.CATEGORIES_TABLE.'
1461  SET id_uppercat = '.$new_parent.'
1462  WHERE id IN ('.implode(',', $category_ids).')
1463;';
1464  pwg_query($query);
1465
1466  update_uppercats();
1467  ordering();
1468  update_global_rank();
1469
1470  // status and related permissions management
1471  if ('NULL' == $new_parent)
1472  {
1473    $parent_status = 'public';
1474  }
1475  else
1476  {
1477    $query = '
1478SELECT status
1479  FROM '.CATEGORIES_TABLE.'
1480  WHERE id = '.$new_parent.'
1481;';
1482    list($parent_status) = mysql_fetch_row(pwg_query($query));
1483  }
1484
1485  if ('private' == $parent_status)
1486  {
1487    foreach ($categories as $cat_id => $category)
1488    {
1489      switch ($category['status'])
1490      {
1491        case 'public' :
1492        {
1493          set_cat_status(array($cat_id), 'private');
1494          break;
1495        }
1496        case 'private' :
1497        {
1498          $subcats = get_subcat_ids(array($cat_id));
1499
1500          foreach ($tables as $table => $field)
1501          {
1502            $query = '
1503SELECT '.$field.'
1504  FROM '.$table.'
1505  WHERE cat_id = '.$cat_id.'
1506;';
1507            $category_access = array_from_query($query, $field);
1508
1509            $query = '
1510SELECT '.$field.'
1511  FROM '.$table.'
1512  WHERE cat_id = '.$new_parent.'
1513;';
1514            $parent_access = array_from_query($query, $field);
1515
1516            $to_delete = array_diff($parent_access, $category_access);
1517
1518            if (count($to_delete) > 0)
1519            {
1520              $query = '
1521DELETE FROM '.$table.'
1522  WHERE '.$field.' IN ('.implode(',', $to_delete).')
1523    AND cat_id IN ('.implode(',', $subcats).')
1524;';
1525              pwg_query($query);
1526            }
1527          }
1528          break;
1529        }
1530      }
1531    }
1532  }
1533
1534  array_push(
1535    $page['infos'],
1536    sprintf(
1537      l10n('%d categories moved'),
1538      count($categories)
1539      )
1540    );
1541}
1542
1543/**
1544 * create a virtual category
1545 *
1546 * @param string category name
1547 * @param int parent category id
1548 * @return array with ('info' and 'id') or ('error') key
1549 */
1550function create_virtual_category($category_name, $parent_id=null)
1551{
1552  global $conf;
1553
1554  // is the given category name only containing blank spaces ?
1555  if (preg_match('/^\s*$/', $category_name))
1556  {
1557    return array('error' => l10n('cat_error_name'));
1558  }
1559
1560  $parent_id = !empty($parent_id) ? $parent_id : 'NULL';
1561
1562  $query = '
1563SELECT MAX(rank)
1564  FROM '.CATEGORIES_TABLE.'
1565  WHERE id_uppercat '.(is_numeric($parent_id) ? '= '.$parent_id : 'IS NULL').'
1566;';
1567  list($current_rank) = mysql_fetch_array(pwg_query($query));
1568
1569  $insert = array(
1570    'name' => $category_name,
1571    'rank' => ++$current_rank,
1572    'commentable' => $conf['newcat_default_commentable'],
1573    'uploadable' => 'false',
1574    );
1575
1576  if ($parent_id != 'NULL')
1577  {
1578    $query = '
1579SELECT id, uppercats, global_rank, visible, status
1580  FROM '.CATEGORIES_TABLE.'
1581  WHERE id = '.$parent_id.'
1582;';
1583    $parent = mysql_fetch_array(pwg_query($query));
1584
1585    $insert{'id_uppercat'} = $parent{'id'};
1586    $insert{'global_rank'} = $parent{'global_rank'}.'.'.$insert{'rank'};
1587
1588    // at creation, must a category be visible or not ? Warning : if the
1589    // parent category is invisible, the category is automatically create
1590    // invisible. (invisible = locked)
1591    if ('false' == $parent['visible'])
1592    {
1593      $insert{'visible'} = 'false';
1594    }
1595    else
1596    {
1597      $insert{'visible'} = $conf['newcat_default_visible'];
1598    }
1599
1600    // at creation, must a category be public or private ? Warning : if the
1601    // parent category is private, the category is automatically create
1602    // private.
1603    if ('private' == $parent['status'])
1604    {
1605      $insert{'status'} = 'private';
1606    }
1607    else
1608    {
1609      $insert{'status'} = $conf['newcat_default_status'];
1610    }
1611  }
1612  else
1613  {
1614    $insert{'visible'} = $conf['newcat_default_visible'];
1615    $insert{'status'} = $conf['newcat_default_status'];
1616    $insert{'global_rank'} = $insert{'rank'};
1617  }
1618
1619  // we have then to add the virtual category
1620  mass_inserts(
1621    CATEGORIES_TABLE,
1622    array(
1623      'site_id', 'name', 'id_uppercat', 'rank', 'commentable',
1624      'uploadable', 'visible', 'status', 'global_rank',
1625      ),
1626    array($insert)
1627    );
1628
1629  $inserted_id = mysql_insert_id();
1630
1631  $query = '
1632UPDATE
1633  '.CATEGORIES_TABLE.'
1634  SET uppercats = \''.
1635    (isset($parent) ? $parent{'uppercats'}.',' : '').
1636    $inserted_id.
1637    '\'
1638  WHERE id = '.$inserted_id.'
1639;';
1640  pwg_query($query);
1641
1642  return array(
1643    'info' => l10n('cat_virtual_added'),
1644    'id'   => $inserted_id,
1645    );
1646}
1647
1648/**
1649 * Set tags to an image. Warning: given tags are all tags associated to the
1650 * image, not additionnal tags.
1651 *
1652 * @param array tag ids
1653 * @param int image id
1654 * @return void
1655 */
1656function set_tags($tags, $image_id)
1657{
1658  $query = '
1659DELETE
1660  FROM '.IMAGE_TAG_TABLE.'
1661  WHERE image_id = '.$image_id.'
1662;';
1663  pwg_query($query);
1664
1665  if (count($tags) > 0)
1666  {
1667    $inserts = array();
1668    foreach ($tags as $tag_id)
1669    {
1670      array_push(
1671        $inserts,
1672        array(
1673          'tag_id' => $tag_id,
1674          'image_id' => $image_id
1675          )
1676        );
1677    }
1678    mass_inserts(
1679      IMAGE_TAG_TABLE,
1680      array_keys($inserts[0]),
1681      $inserts
1682      );
1683  }
1684}
1685
1686/**
1687 * Add new tags to a set of images.
1688 *
1689 * @param array tag ids
1690 * @param array image ids
1691 * @return void
1692 */
1693function add_tags($tags, $images)
1694{
1695  if (count($tags) == 0 or count($tags) == 0)
1696  {
1697    return;
1698  }
1699 
1700  // we can't insert twice the same {image_id,tag_id} so we must first
1701  // delete lines we'll insert later
1702  $query = '
1703DELETE
1704  FROM '.IMAGE_TAG_TABLE.'
1705  WHERE image_id IN ('.implode(',', $images).')
1706    AND tag_id IN ('.implode(',', $tags).')
1707;';
1708  pwg_query($query);
1709
1710  $inserts = array();
1711  foreach ($images as $image_id)
1712  {
1713    foreach ($tags as $tag_id)
1714    {
1715      array_push(
1716        $inserts,
1717        array(
1718          'image_id' => $image_id,
1719          'tag_id' => $tag_id,
1720          )
1721        );
1722    }
1723  }
1724  mass_inserts(
1725    IMAGE_TAG_TABLE,
1726    array_keys($inserts[0]),
1727    $inserts
1728    );
1729}
1730
1731function tag_id_from_tag_name($tag_name)
1732{
1733  global $page;
1734
1735  if (isset($page['tag_id_from_tag_name_cache'][$tag_name]))
1736  {
1737    return $page['tag_id_from_tag_name_cache'][$tag_name];
1738  }
1739 
1740  if (function_exists('mysql_real_escape_string'))
1741  {
1742    $tag_name = mysql_real_escape_string($tag_name);
1743  }
1744  else
1745  {
1746    $tag_name = mysql_escape_string($tag_name);
1747  }
1748
1749  // does the tag already exist?
1750  $query = '
1751SELECT id
1752  FROM '.TAGS_TABLE.'
1753  WHERE name = \''.$tag_name.'\'
1754;';
1755  $existing_tags = array_from_query($query, 'id');
1756
1757  if (count($existing_tags) == 0)
1758  {
1759    mass_inserts(
1760      TAGS_TABLE,
1761      array('name', 'url_name'),
1762      array(
1763        array(
1764          'name' => $tag_name,
1765          'url_name' => str2url($tag_name),
1766          )
1767        )
1768      );
1769
1770    $page['tag_id_from_tag_name_cache'][$tag_name] = mysql_insert_id();
1771  }
1772  else
1773  {
1774    $page['tag_id_from_tag_name_cache'][$tag_name] = $existing_tags[0];
1775  }
1776
1777  return $page['tag_id_from_tag_name_cache'][$tag_name];
1778}
1779
1780function set_tags_of($tags_of)
1781{
1782  if (count($tags_of) > 0)
1783  {
1784    $query = '
1785DELETE
1786  FROM '.IMAGE_TAG_TABLE.'
1787  WHERE image_id IN ('.implode(',', array_keys($tags_of)).')
1788;';
1789    pwg_query($query);
1790
1791    $inserts = array();
1792   
1793    foreach ($tags_of as $image_id => $tag_ids)
1794    {
1795      foreach ($tag_ids as $tag_id)
1796      {
1797        array_push(
1798          $inserts,
1799          array(
1800            'image_id' => $image_id,
1801            'tag_id' => $tag_id,
1802            )
1803          );
1804      }
1805    }
1806
1807    mass_inserts(
1808      IMAGE_TAG_TABLE,
1809      array_keys($inserts[0]),
1810      $inserts
1811      );
1812  }
1813}
1814
1815/**
1816 * Do maintenance on all PWG tables
1817 *
1818 * @return nono
1819 */
1820function do_maintenance_all_tables()
1821{
1822  global $prefixeTable;
1823 
1824  $all_tables = array();
1825
1826  // List all tables
1827  $query = 'SHOW TABLES LIKE \''.$prefixeTable.'%\';';
1828  $result = pwg_query($query);
1829  while ($row = mysql_fetch_array($result))
1830  {
1831    array_push($all_tables, $row[0]);
1832  }
1833
1834  // Repair all tables
1835  $query = 'REPAIR TABLE '.implode(', ', $all_tables).';';
1836  pwg_query($query);
1837
1838  // Re-Order all tables
1839  foreach ($all_tables as $table_name)
1840  {
1841    $all_primary_key = array();
1842   
1843    $query = 'DESC '.$table_name.';';
1844    $result = pwg_query($query);
1845    while ($row = mysql_fetch_array($result))
1846    {
1847      if ($row['Key'] == 'PRI')
1848      {
1849        array_push($all_primary_key, $row['Field']);
1850      }
1851    }
1852   
1853    if (count($all_primary_key) != 0)
1854    {
1855      $query = 'ALTER TABLE '.$table_name.' ORDER BY '.implode(', ', $all_primary_key).';';
1856      pwg_query($query);
1857    }
1858  }
1859
1860  // Optimize all tables
1861  $query = 'OPTIMIZE TABLE '.implode(', ', $all_tables).';';
1862  pwg_query($query);
1863
1864}
1865
1866/**
1867 * Associate a list of images to a list of categories.
1868 *
1869 * The function will not duplicate links
1870 *
1871 * @param array images
1872 * @param array categories
1873 * @return void
1874 */
1875function associate_images_to_categories($images, $categories)
1876{
1877  if (count($images) == 0
1878      or count($categories) == 0)
1879  {
1880    return false;
1881  }
1882
1883  $query = '
1884DELETE
1885  FROM '.IMAGE_CATEGORY_TABLE.'
1886  WHERE image_id IN ('.implode(',', $images).')
1887    AND category_id IN ('.implode(',', $categories).')
1888;';
1889  pwg_query($query);
1890
1891  $inserts = array();
1892  foreach ($categories as $category_id)
1893  {
1894    foreach ($images as $image_id)
1895    {
1896      array_push(
1897        $inserts,
1898        array(
1899          'image_id' => $image_id,
1900          'category_id' => $category_id,
1901          )
1902        );
1903    }
1904  }
1905 
1906  mass_inserts(
1907    IMAGE_CATEGORY_TABLE,
1908    array_keys($inserts[0]),
1909    $inserts
1910    );
1911
1912  update_category($categories);
1913}
1914
1915/**
1916 * Associate images associated to a list of source categories to a list of
1917 * destination categories.
1918 *
1919 * @param array sources
1920 * @param array destinations
1921 * @return void
1922 */
1923function associate_categories_to_categories($sources, $destinations)
1924{
1925  if (count($sources) == 0)
1926  {
1927    return false;
1928  }
1929
1930  $query = '
1931SELECT image_id
1932  FROM '.IMAGE_CATEGORY_TABLE.'
1933  WHERE category_id IN ('.implode(',', $sources).')
1934;';
1935  $images = array_from_query($query, 'image_id');
1936
1937  associate_images_to_categories($images, $destinations);
1938}
1939?>
Note: See TracBrowser for help on using the repository browser.