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

Last change on this file since 4492 was 4492, checked in by nikrou, 14 years ago

Bug 1328 add function to check token

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