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

Last change on this file since 2065 was 2065, checked in by rub, 17 years ago

Resolved issue 0000725: Check integrity

Replace actual test (exif) by a new dynamic system of check integrity.
Anomalies are listed with automatic correction if it's possible.

It's a proposition of new feature!

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