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

Last change on this file since 2646 was 2646, checked in by plg, 16 years ago

bug fixed: remove useless mysql_real_escape because web api already process
all input parameters.

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