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

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

Feature 1244 resolved
Replace all mysql functions in core code by ones independant of database engine

Fix small php code synxtax : hash must be accessed with [ ] and not { }.

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