source: trunk/include/functions.inc.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: 41.3 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_once( PHPWG_ROOT_PATH .'include/functions_user.inc.php' );
25include_once( PHPWG_ROOT_PATH .'include/functions_cookie.inc.php' );
26include_once( PHPWG_ROOT_PATH .'include/functions_session.inc.php' );
27include_once( PHPWG_ROOT_PATH .'include/functions_category.inc.php' );
28include_once( PHPWG_ROOT_PATH .'include/functions_xml.inc.php' );
29include_once( PHPWG_ROOT_PATH .'include/functions_html.inc.php' );
30include_once( PHPWG_ROOT_PATH .'include/functions_tag.inc.php' );
31include_once( PHPWG_ROOT_PATH .'include/functions_url.inc.php' );
32include_once( PHPWG_ROOT_PATH .'include/functions_plugins.inc.php' );
33
34//----------------------------------------------------------- generic functions
35
36/**
37 * returns an array containing the possible values of an enum field
38 *
39 * @param string tablename
40 * @param string fieldname
41 */
42function get_enums($table, $field)
43{
44  // retrieving the properties of the table. Each line represents a field :
45  // columns are 'Field', 'Type'
46  $result = pwg_query('desc '.$table);
47  while ($row = pwg_db_fetch_assoc($result))
48  {
49    // we are only interested in the the field given in parameter for the
50    // function
51    if ($row['Field'] == $field)
52    {
53      // retrieving possible values of the enum field
54      // enum('blue','green','black')
55      $options = explode(',', substr($row['Type'], 5, -1));
56      foreach ($options as $i => $option)
57      {
58        $options[$i] = str_replace("'", '',$option);
59      }
60    }
61  }
62  pwg_db_free_result($result);
63  return $options;
64}
65
66// get_boolean transforms a string to a boolean value. If the string is
67// "false" (case insensitive), then the boolean value false is returned. In
68// any other case, true is returned.
69function get_boolean( $string )
70{
71  $boolean = true;
72  if ( 'false' == strtolower($string) )
73  {
74    $boolean = false;
75  }
76  return $boolean;
77}
78
79/**
80 * returns boolean string 'true' or 'false' if the given var is boolean
81 *
82 * @param mixed $var
83 * @return mixed
84 */
85function boolean_to_string($var)
86{
87  if (is_bool($var))
88  {
89    return $var ? 'true' : 'false';
90  }
91  else
92  {
93    return $var;
94  }
95}
96
97// The function get_moment returns a float value coresponding to the number
98// of seconds since the unix epoch (1st January 1970) and the microseconds
99// are precised : e.g. 1052343429.89276600
100function get_moment()
101{
102  $t1 = explode( ' ', microtime() );
103  $t2 = explode( '.', $t1[0] );
104  $t2 = $t1[1].'.'.$t2[1];
105  return $t2;
106}
107
108// The function get_elapsed_time returns the number of seconds (with 3
109// decimals precision) between the start time and the end time given.
110function get_elapsed_time( $start, $end )
111{
112  return number_format( $end - $start, 3, '.', ' ').' s';
113}
114
115// - The replace_space function replaces space and '-' characters
116//   by their HTML equivalent  &nbsb; and &minus;
117// - The function does not replace characters in HTML tags
118// - This function was created because IE5 does not respect the
119//   CSS "white-space: nowrap;" property unless space and minus
120//   characters are replaced like this function does.
121// - Example :
122//                 <div class="foo">My friend</div>
123//               ( 01234567891111111111222222222233 )
124//               (           0123456789012345678901 )
125// becomes :
126//             <div class="foo">My&nbsp;friend</div>
127function replace_space( $string )
128{
129  //return $string;
130  $return_string = '';
131  // $remaining is the rest of the string where to replace spaces characters
132  $remaining = $string;
133  // $start represents the position of the next '<' character
134  // $end   represents the position of the next '>' character
135  ; // -> 0
136  $end   = strpos ( $remaining, '>' ); // -> 16
137  // as long as a '<' and his friend '>' are found, we loop
138  while ( ($start=strpos( $remaining, '<' )) !==false
139        and ($end=strpos( $remaining, '>' )) !== false )
140  {
141    // $treatment is the part of the string to treat
142    // In the first loop of our example, this variable is empty, but in the
143    // second loop, it equals 'My friend'
144    $treatment = substr ( $remaining, 0, $start );
145    // Replacement of ' ' by his equivalent '&nbsp;'
146    $treatment = str_replace( ' ', '&nbsp;', $treatment );
147    $treatment = str_replace( '-', '&minus;', $treatment );
148    // composing the string to return by adding the treated string and the
149    // following HTML tag -> 'My&nbsp;friend</div>'
150    $return_string.= $treatment.substr( $remaining, $start, $end-$start+1 );
151    // the remaining string is deplaced to the part after the '>' of this
152    // loop
153    $remaining = substr ( $remaining, $end + 1, strlen( $remaining ) );
154  }
155  $treatment = str_replace( ' ', '&nbsp;', $remaining );
156  $treatment = str_replace( '-', '&minus;', $treatment );
157  $return_string.= $treatment;
158
159  return $return_string;
160}
161
162// get_extension returns the part of the string after the last "."
163function get_extension( $filename )
164{
165  return substr( strrchr( $filename, '.' ), 1, strlen ( $filename ) );
166}
167
168// get_filename_wo_extension returns the part of the string before the last
169// ".".
170// get_filename_wo_extension( 'test.tar.gz' ) -> 'test.tar'
171function get_filename_wo_extension( $filename )
172{
173  $pos = strrpos( $filename, '.' );
174  return ($pos===false) ? $filename : substr( $filename, 0, $pos);
175}
176
177/**
178 * returns an array contening sub-directories, excluding ".svn"
179 *
180 * @param string $dir
181 * @return array
182 */
183function get_dirs($directory)
184{
185  $sub_dirs = array();
186  if ($opendir = opendir($directory))
187  {
188    while ($file = readdir($opendir))
189    {
190      if ($file != '.'
191          and $file != '..'
192          and is_dir($directory.'/'.$file)
193          and $file != '.svn')
194      {
195        array_push($sub_dirs, $file);
196      }
197    }
198    closedir($opendir);
199  }
200  return $sub_dirs;
201}
202
203define('MKGETDIR_NONE', 0);
204define('MKGETDIR_RECURSIVE', 1);
205define('MKGETDIR_DIE_ON_ERROR', 2);
206define('MKGETDIR_PROTECT_INDEX', 4);
207define('MKGETDIR_PROTECT_HTACCESS', 8);
208define('MKGETDIR_DEFAULT', 7);
209/**
210 * creates directory if not exists; ensures that directory is writable
211 * @param:
212 *  string $dir
213 *  int $flags combination of MKGETDIR_xxx
214 * @return bool false on error else true
215 */
216function mkgetdir($dir, $flags=MKGETDIR_DEFAULT)
217{
218  if ( !is_dir($dir) )
219  {
220    $umask = umask(0);
221    $mkd = @mkdir($dir, 0755, ($flags&MKGETDIR_RECURSIVE) ? true:false );
222    umask($umask);
223    if ($mkd==false)
224    {
225      !($flags&MKGETDIR_DIE_ON_ERROR) or fatal_error( "$dir ".l10n('no_write_access'));
226      return false;
227    }
228    if( $flags&MKGETDIR_PROTECT_HTACCESS )
229    {
230      $file = $dir.'/.htaccess';
231      file_exists($file) or @file_put_contents( $file, 'deny from all' );
232    }
233    if( $flags&MKGETDIR_PROTECT_INDEX )
234    {
235      $file = $dir.'/index.htm';
236      file_exists($file) or @file_put_contents( $file, 'Not allowed!' );
237    }
238  }
239  if ( !is_writable($dir) )
240  {
241    !($flags&MKGETDIR_DIE_ON_ERROR) or fatal_error( "$dir ".l10n('no_write_access'));
242    return false;
243  }
244  return true;
245}
246
247/**
248 * returns thumbnail directory name of input diretoty name
249 * make thumbnail directory is necessary
250 * set error messages on array messages
251 *
252 * @param:
253 *  string $dirname
254 *  arrayy $errors
255 * @return bool false on error else string directory name
256 */
257function mkget_thumbnail_dir($dirname, &$errors)
258{
259  global $conf;
260
261  $tndir = $dirname.'/'.$conf['dir_thumbnail'];
262  if (! mkgetdir($tndir, MKGETDIR_NONE) )
263  {
264    array_push($errors,
265          '['.$dirname.'] : '.l10n('no_write_access'));
266    return false;
267  }
268  return $tndir;
269}
270
271/* Returns true if the string appears to be encoded in UTF-8. (from wordpress)
272 * @param string Str
273 */
274function seems_utf8($Str) { # by bmorel at ssi dot fr
275  for ($i=0; $i<strlen($Str); $i++) {
276    if (ord($Str[$i]) < 0x80) continue; # 0bbbbbbb
277    elseif ((ord($Str[$i]) & 0xE0) == 0xC0) $n=1; # 110bbbbb
278    elseif ((ord($Str[$i]) & 0xF0) == 0xE0) $n=2; # 1110bbbb
279    elseif ((ord($Str[$i]) & 0xF8) == 0xF0) $n=3; # 11110bbb
280    elseif ((ord($Str[$i]) & 0xFC) == 0xF8) $n=4; # 111110bb
281    elseif ((ord($Str[$i]) & 0xFE) == 0xFC) $n=5; # 1111110b
282    else return false; # Does not match any model
283    for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ?
284      if ((++$i == strlen($Str)) || ((ord($Str[$i]) & 0xC0) != 0x80))
285      return false;
286    }
287  }
288  return true;
289}
290
291/* Remove accents from a UTF-8 or ISO-859-1 string (from wordpress)
292 * @param string sstring - an UTF-8 or ISO-8859-1 string
293 */
294function remove_accents($string)
295{
296  if ( !preg_match('/[\x80-\xff]/', $string) )
297    return $string;
298
299  if (seems_utf8($string)) {
300    $chars = array(
301    // Decompositions for Latin-1 Supplement
302    chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
303    chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
304    chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
305    chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
306    chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
307    chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
308    chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
309    chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
310    chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
311    chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
312    chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
313    chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
314    chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
315    chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
316    chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
317    chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
318    chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
319    chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
320    chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
321    chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
322    chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
323    chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
324    chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
325    chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
326    chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
327    chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
328    chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
329    chr(195).chr(191) => 'y',
330    // Decompositions for Latin Extended-A
331    chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
332    chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
333    chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
334    chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
335    chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
336    chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
337    chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
338    chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
339    chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
340    chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
341    chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
342    chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
343    chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
344    chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
345    chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
346    chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
347    chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
348    chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
349    chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
350    chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
351    chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
352    chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
353    chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
354    chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
355    chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
356    chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij',
357    chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
358    chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
359    chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
360    chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
361    chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
362    chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
363    chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
364    chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
365    chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
366    chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
367    chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
368    chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
369    chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
370    chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
371    chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
372    chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
373    chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
374    chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
375    chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
376    chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
377    chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
378    chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
379    chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
380    chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
381    chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
382    chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
383    chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
384    chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
385    chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
386    chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
387    chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
388    chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
389    chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
390    chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
391    chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
392    chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
393    chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
394    chr(197).chr(190) => 'z', chr(197).chr(191) => 's',
395    // Euro Sign
396    chr(226).chr(130).chr(172) => 'E',
397    // GBP (Pound) Sign
398    chr(194).chr(163) => '');
399
400    $string = strtr($string, $chars);
401  } else {
402    // Assume ISO-8859-1 if not UTF-8
403    $chars['in'] = chr(128).chr(131).chr(138).chr(142).chr(154).chr(158)
404      .chr(159).chr(162).chr(165).chr(181).chr(192).chr(193).chr(194)
405      .chr(195).chr(196).chr(197).chr(199).chr(200).chr(201).chr(202)
406      .chr(203).chr(204).chr(205).chr(206).chr(207).chr(209).chr(210)
407      .chr(211).chr(212).chr(213).chr(214).chr(216).chr(217).chr(218)
408      .chr(219).chr(220).chr(221).chr(224).chr(225).chr(226).chr(227)
409      .chr(228).chr(229).chr(231).chr(232).chr(233).chr(234).chr(235)
410      .chr(236).chr(237).chr(238).chr(239).chr(241).chr(242).chr(243)
411      .chr(244).chr(245).chr(246).chr(248).chr(249).chr(250).chr(251)
412      .chr(252).chr(253).chr(255);
413
414    $chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy";
415
416    $string = strtr($string, $chars['in'], $chars['out']);
417    $double_chars['in'] = array(chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254));
418    $double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th');
419    $string = str_replace($double_chars['in'], $double_chars['out'], $string);
420  }
421
422  return $string;
423}
424
425/**
426 * simplify a string to insert it into an URL
427 *
428 * @param string
429 * @return string
430 */
431function str2url($str)
432{
433  $str = remove_accents($str);
434  $str = preg_replace('/[^a-z0-9_\s\'\:\/\[\],-]/','',strtolower($str));
435  $str = preg_replace('/[\s\'\:\/\[\],-]+/',' ',trim($str));
436  $res = str_replace(' ','_',$str);
437
438  return $res;
439}
440
441//-------------------------------------------- Piwigo specific functions
442
443/**
444 * returns an array with a list of {language_code => language_name}
445 *
446 * @returns array
447 */
448function get_languages($target_charset = null)
449{
450  if ( empty($target_charset) )
451  {
452    $target_charset = get_pwg_charset();
453  }
454  $target_charset = strtolower($target_charset);
455
456  $dir = opendir(PHPWG_ROOT_PATH.'language');
457  $languages = array();
458
459  while ($file = readdir($dir))
460  {
461    $path = PHPWG_ROOT_PATH.'language/'.$file;
462    if (!is_link($path) and file_exists($path.'/iso.txt'))
463    {
464      list($language_name) = @file($path.'/iso.txt');
465
466      $langdef = explode('.',$file);
467      if (count($langdef)>1) // (langCode,encoding)
468      {
469        $langdef[1] = strtolower($langdef[1]);
470
471        if (
472          $target_charset==$langdef[1]
473         or
474          ($target_charset=='utf-8' and $langdef[1]=='iso-8859-1')
475         or
476          ($target_charset=='iso-8859-1' and
477          in_array( substr($langdef[0],2), array('en','fr','de','es','it','nl')))
478        )
479        {
480          $language_name = convert_charset($language_name,
481              $langdef[1], $target_charset);
482          $languages[ $langdef[0] ] = $language_name;
483        }
484        else
485          continue; // the language encoding is not compatible with our charset
486      }
487      else
488      { // UTF-8
489        $language_name = convert_charset($language_name,
490              'utf-8', $target_charset);
491        $languages[$file] = $language_name;
492      }
493    }
494  }
495  closedir($dir);
496  @asort($languages);
497
498  return $languages;
499}
500
501function pwg_log($image_id = null, $image_type = null)
502{
503  global $conf, $user, $page;
504
505  $do_log = $conf['log'];
506  if (is_admin())
507  {
508    $do_log = $conf['history_admin'];
509  }
510  if (is_a_guest())
511  {
512    $do_log = $conf['history_guest'];
513  }
514
515  $do_log = trigger_event('pwg_log_allowed', $do_log, $image_id, $image_type);
516
517  if (!$do_log)
518  {
519    return false;
520  }
521
522  $tags_string = null;
523  if ('tags'==@$page['section'])
524  {
525    $tags_string = implode(',', $page['tag_ids']);
526  }
527
528  $query = '
529INSERT INTO '.HISTORY_TABLE.'
530  (
531    date,
532    time,
533    user_id,
534    IP,
535    section,
536    category_id,
537    image_id,
538    image_type,
539    tag_ids
540  )
541  VALUES
542  (
543    CURDATE(),
544    CURTIME(),
545    '.$user['id'].',
546    \''.$_SERVER['REMOTE_ADDR'].'\',
547    '.(isset($page['section']) ? "'".$page['section']."'" : 'NULL').',
548    '.(isset($page['category']['id']) ? $page['category']['id'] : 'NULL').',
549    '.(isset($image_id) ? $image_id : 'NULL').',
550    '.(isset($image_type) ? "'".$image_type."'" : 'NULL').',
551    '.(isset($tags_string) ? "'".$tags_string."'" : 'NULL').'
552  )
553;';
554  pwg_query($query);
555
556  return true;
557}
558
559// format_date returns a formatted date for display. The date given in
560// argument must be an american format (2003-09-15). By option, you can show the time.
561// The output is internationalized.
562//
563// format_date( "2003-09-15", true ) -> "Monday 15 September 2003 21:52"
564function format_date($date, $show_time = false)
565{
566  global $lang;
567
568  $ymdhms = array();
569  $tok = strtok( $date, '- :');
570  while ($tok !== false)
571  {
572    $ymdhms[] = $tok;
573    $tok = strtok('- :');
574  }
575
576  if ( count($ymdhms)<3 )
577  {
578    return false;
579  }
580
581  $formated_date = '';
582  // before 1970, Microsoft Windows can't mktime
583  if ($ymdhms[0] >= 1970)
584  {
585    // we ask midday because Windows think it's prior to midnight with a
586    // zero and refuse to work
587    $formated_date.= $lang['day'][date('w', mktime(12,0,0,$ymdhms[1],$ymdhms[2],$ymdhms[0]))];
588  }
589  $formated_date.= ' '.$ymdhms[2];
590  $formated_date.= ' '.$lang['month'][(int)$ymdhms[1]];
591  $formated_date.= ' '.$ymdhms[0];
592  if ($show_time and count($ymdhms)>=5 )
593  {
594    $formated_date.= ' '.$ymdhms[3].':'.$ymdhms[4];
595  }
596  return $formated_date;
597}
598
599function pwg_debug( $string )
600{
601  global $debug,$t2,$page;
602
603  $now = explode( ' ', microtime() );
604  $now2 = explode( '.', $now[0] );
605  $now2 = $now[1].'.'.$now2[1];
606  $time = number_format( $now2 - $t2, 3, '.', ' ').' s';
607  $debug .= '<p>';
608  $debug.= '['.$time.', ';
609  $debug.= $page['count_queries'].' queries] : '.$string;
610  $debug.= "</p>\n";
611}
612
613/**
614 * Redirects to the given URL (HTTP method)
615 *
616 * Note : once this function called, the execution doesn't go further
617 * (presence of an exit() instruction.
618 *
619 * @param string $url
620 * @return void
621 */
622function redirect_http( $url )
623{
624  if (ob_get_length () !== FALSE)
625  {
626    ob_clean();
627  }
628  // default url is on html format
629  $url = html_entity_decode($url);
630  header('Request-URI: '.$url);
631  header('Content-Location: '.$url);
632  header('Location: '.$url);
633  exit();
634}
635
636/**
637 * Redirects to the given URL (HTML method)
638 *
639 * Note : once this function called, the execution doesn't go further
640 * (presence of an exit() instruction.
641 *
642 * @param string $url
643 * @param string $title_msg
644 * @param integer $refreh_time
645 * @return void
646 */
647function redirect_html( $url , $msg = '', $refresh_time = 0)
648{
649  global $user, $template, $lang_info, $conf, $lang, $t2, $page, $debug;
650
651  if (!isset($lang_info))
652  {
653    $user = build_user( $conf['guest_id'], true);
654    load_language('common.lang');
655    trigger_action('loading_lang');
656    load_language('local.lang', '', array('no_fallback'=>true) );
657    list($tmpl, $thm) = explode('/', get_default_template());
658    $template = new Template(PHPWG_ROOT_PATH.'template/'.$tmpl, $thm);
659  }
660  else
661  {
662    $template = new Template(PHPWG_ROOT_PATH.'template/'.$user['template'], $user['theme']);
663  }
664
665  if (empty($msg))
666  {
667    $msg = nl2br(l10n('redirect_msg'));
668  }
669
670  $refresh = $refresh_time;
671  $url_link = $url;
672  $title = 'redirection';
673
674  $template->set_filenames( array( 'redirect' => 'redirect.tpl' ) );
675
676  include( PHPWG_ROOT_PATH.'include/page_header.php' );
677
678  $template->set_filenames( array( 'redirect' => 'redirect.tpl' ) );
679  $template->assign('REDIRECT_MSG', $msg);
680
681  $template->parse('redirect');
682
683  include( PHPWG_ROOT_PATH.'include/page_tail.php' );
684
685  exit();
686}
687
688/**
689 * Redirects to the given URL (Switch to HTTP method or HTML method)
690 *
691 * Note : once this function called, the execution doesn't go further
692 * (presence of an exit() instruction.
693 *
694 * @param string $url
695 * @param string $title_msg
696 * @param integer $refreh_time
697 * @return void
698 */
699function redirect( $url , $msg = '', $refresh_time = 0)
700{
701  global $conf;
702
703  // with RefeshTime <> 0, only html must be used
704  if ($conf['default_redirect_method']=='http'
705      and $refresh_time==0
706      and !headers_sent()
707    )
708  {
709    redirect_http($url);
710  }
711  else
712  {
713    redirect_html($url, $msg, $refresh_time);
714  }
715}
716
717/**
718 * returns $_SERVER['QUERY_STRING'] whitout keys given in parameters
719 *
720 * @param array $rejects
721 * @param boolean $escape - if true escape & to &amp; (for html)
722 * @returns string
723 */
724function get_query_string_diff($rejects=array(), $escape=true)
725{
726  $query_string = '';
727
728  $str = $_SERVER['QUERY_STRING'];
729  parse_str($str, $vars);
730
731  $is_first = true;
732  foreach ($vars as $key => $value)
733  {
734    if (!in_array($key, $rejects))
735    {
736      $query_string.= $is_first ? '?' : ($escape ? '&amp;' : '&' );
737      $is_first = false;
738      $query_string.= $key.'='.$value;
739    }
740  }
741
742  return $query_string;
743}
744
745function url_is_remote($url)
746{
747  if ( strncmp($url, 'http://', 7)==0
748    or strncmp($url, 'https://', 8)==0 )
749  {
750    return true;
751  }
752  return false;
753}
754
755/**
756 * returns available template/theme
757 */
758function get_pwg_themes()
759{
760  global $conf;
761  $themes = array();
762
763  $template_dir = PHPWG_ROOT_PATH.'template';
764
765  foreach (get_dirs($template_dir) as $template)
766  {
767    foreach (get_dirs($template_dir.'/'.$template.'/theme') as $theme)
768    {
769      if ( ($template.'/'.$theme) != $conf['admin_layout'] )
770      array_push($themes, $template.'/'.$theme);
771    }
772  }
773
774  return $themes;
775}
776
777/* Returns the PATH to the thumbnail to be displayed. If the element does not
778 * have a thumbnail, the default mime image path is returned. The PATH can be
779 * used in the php script, but not sent to the browser.
780 * @param array element_info assoc array containing element info from db
781 * at least 'path', 'tn_ext' and 'id' should be present
782 */
783function get_thumbnail_path($element_info)
784{
785  $path = get_thumbnail_location($element_info);
786  if ( !url_is_remote($path) )
787  {
788    $path = PHPWG_ROOT_PATH.$path;
789  }
790  return $path;
791}
792
793/* Returns the URL of the thumbnail to be displayed. If the element does not
794 * have a thumbnail, the default mime image url is returned. The URL can be
795 * sent to the browser, but not used in the php script.
796 * @param array element_info assoc array containing element info from db
797 * at least 'path', 'tn_ext' and 'id' should be present
798 */
799function get_thumbnail_url($element_info)
800{
801  $path = get_thumbnail_location($element_info);
802  if ( !url_is_remote($path) )
803  {
804    $path = embellish_url(get_root_url().$path);
805  }
806
807  // plugins want another url ?
808  $path = trigger_event('get_thumbnail_url', $path, $element_info);
809  return $path;
810}
811
812/* returns the relative path of the thumnail with regards to to the root
813of piwigo (not the current page!).This function is not intended to be
814called directly from code.*/
815function get_thumbnail_location($element_info)
816{
817  global $conf;
818  if ( !empty( $element_info['tn_ext'] ) )
819  {
820    $path = substr_replace(
821      get_filename_wo_extension($element_info['path']),
822      '/'.$conf['dir_thumbnail'].'/'.$conf['prefix_thumbnail'],
823      strrpos($element_info['path'],'/'),
824      1
825      );
826    $path.= '.'.$element_info['tn_ext'];
827  }
828  else
829  {
830    $path = get_themeconf('mime_icon_dir')
831        .strtolower(get_extension($element_info['path'])).'.png';
832  }
833
834  // plugins want another location ?
835  $path = trigger_event( 'get_thumbnail_location', $path, $element_info);
836  return $path;
837}
838
839/* returns the title of the thumnail */
840function get_thumbnail_title($element_info)
841{
842  // message in title for the thumbnail
843  if (isset($element_info['file']))
844  {
845    $thumbnail_title = $element_info['file'];
846  }
847  else
848  {
849    $thumbnail_title = '';
850  }
851
852  if (!empty($element_info['filesize']))
853  {
854    $thumbnail_title .= ' : '.sprintf(l10n('%d Kb'), $element_info['filesize']);
855  }
856
857  return $thumbnail_title;
858}
859
860/**
861 * fill the current user caddie with given elements, if not already in
862 * caddie
863 *
864 * @param array elements_id
865 */
866function fill_caddie($elements_id)
867{
868  global $user;
869
870  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
871
872  $query = '
873SELECT element_id
874  FROM '.CADDIE_TABLE.'
875  WHERE user_id = '.$user['id'].'
876;';
877  $in_caddie = array_from_query($query, 'element_id');
878
879  $caddiables = array_diff($elements_id, $in_caddie);
880
881  $datas = array();
882
883  foreach ($caddiables as $caddiable)
884  {
885    array_push($datas, array('element_id' => $caddiable,
886                             'user_id' => $user['id']));
887  }
888
889  if (count($caddiables) > 0)
890  {
891    mass_inserts(CADDIE_TABLE, array('element_id','user_id'), $datas);
892  }
893}
894
895/**
896 * returns the element name from its filename
897 *
898 * @param string filename
899 * @return string name
900 */
901function get_name_from_file($filename)
902{
903  return str_replace('_',' ',get_filename_wo_extension($filename));
904}
905
906/**
907 * returns the corresponding value from $lang if existing. Else, the key is
908 * returned
909 *
910 * @param string key
911 * @return string
912 */
913function l10n($key)
914{
915  global $lang, $conf;
916
917  if ($conf['debug_l10n'] and !isset($lang[$key]) and !empty($key))
918  {
919    trigger_error('[l10n] language key "'.$key.'" is not defined', E_USER_WARNING);
920  }
921
922  return isset($lang[$key]) ? $lang[$key] : $key;
923}
924
925/**
926 * returns the prinft value for strings including %d
927 * return is concorded with decimal value (singular, plural)
928 *
929 * @param singular string key
930 * @param plural string key
931 * @param decimal value
932 * @return string
933 */
934function l10n_dec($singular_fmt_key, $plural_fmt_key, $decimal)
935{
936  global $lang_info;
937
938  return
939    sprintf(
940      l10n((
941        (($decimal > 1) or ($decimal == 0 and $lang_info['zero_plural']))
942          ? $plural_fmt_key
943          : $singular_fmt_key
944        )), $decimal);
945}
946/*
947 * returns a single element to use with l10n_args
948 *
949 * @param string key: translation key
950 * @param array/string/../number args:
951 *   arguments to use on sprintf($key, args)
952 *   if args is a array, each values are used on sprintf
953 * @return string
954 */
955function get_l10n_args($key, $args)
956{
957  if (is_array($args))
958  {
959    $key_arg = array_merge(array($key), $args);
960  }
961  else
962  {
963    $key_arg = array($key,  $args);
964  }
965  return array('key_args' => $key_arg);
966}
967
968/*
969 * returns a string with formated with l10n_args elements
970 *
971 * @param element/array $key_args: element or array of l10n_args elements
972 * @param $sep: if $key_args is array,
973 *   separator is used when translated l10n_args elements are concated
974 * @return string
975 */
976function l10n_args($key_args, $sep = "\n")
977{
978  if (is_array($key_args))
979  {
980    foreach ($key_args as $key => $element)
981    {
982      if (isset($result))
983      {
984        $result .= $sep;
985      }
986      else
987      {
988        $result = '';
989      }
990
991      if ($key === 'key_args')
992      {
993        array_unshift($element, l10n(array_shift($element)));
994        $result .= call_user_func_array('sprintf', $element);
995      }
996      else
997      {
998        $result .= l10n_args($element, $sep);
999      }
1000    }
1001  }
1002  else
1003  {
1004    fatal_error('l10n_args: Invalid arguments');
1005  }
1006
1007  return $result;
1008}
1009
1010/**
1011 * returns the corresponding value from $themeconf if existing. Else, the
1012 * key is returned
1013 *
1014 * @param string key
1015 * @return string
1016 */
1017function get_themeconf($key)
1018{
1019  global $template;
1020
1021  return $template->get_themeconf($key);
1022}
1023
1024/**
1025 * Returns webmaster mail address depending on $conf['webmaster_id']
1026 *
1027 * @return string
1028 */
1029function get_webmaster_mail_address()
1030{
1031  global $conf;
1032
1033  $query = '
1034SELECT '.$conf['user_fields']['email'].'
1035  FROM '.USERS_TABLE.'
1036  WHERE '.$conf['user_fields']['id'].' = '.$conf['webmaster_id'].'
1037;';
1038  list($email) = pwg_db_fetch_row(pwg_query($query));
1039
1040  return $email;
1041}
1042
1043/**
1044 * Add configuration parameters from database to global $conf array
1045 *
1046 * @return void
1047 */
1048function load_conf_from_db($condition = '')
1049{
1050  global $conf;
1051
1052  $query = '
1053SELECT param, value
1054 FROM '.CONFIG_TABLE.'
1055 '.(!empty($condition) ? 'WHERE '.$condition : '').'
1056;';
1057  $result = pwg_query($query);
1058
1059  if ((pwg_db_num_rows($result) == 0) and !empty($condition))
1060  {
1061    fatal_error('No configuration data');
1062  }
1063
1064  while ($row = pwg_db_fetch_assoc($result))
1065  {
1066    $conf[ $row['param'] ] = isset($row['value']) ? $row['value'] : '';
1067
1068    // If the field is true or false, the variable is transformed into a
1069    // boolean value.
1070    if ($conf[$row['param']] == 'true' or $conf[$row['param']] == 'false')
1071    {
1072      $conf[ $row['param'] ] = get_boolean($conf[ $row['param'] ]);
1073    }
1074  }
1075}
1076
1077/**
1078 * Prepends and appends a string at each value of the given array.
1079 *
1080 * @param array
1081 * @param string prefix to each array values
1082 * @param string suffix to each array values
1083 */
1084function prepend_append_array_items($array, $prepend_str, $append_str)
1085{
1086  array_walk(
1087    $array,
1088    create_function('&$s', '$s = "'.$prepend_str.'".$s."'.$append_str.'";')
1089    );
1090
1091  return $array;
1092}
1093
1094/**
1095 * creates an hashed based on a query, this function is a very common
1096 * pattern used here. Among the selected columns fetched, choose one to be
1097 * the key, another one to be the value.
1098 *
1099 * @param string $query
1100 * @param string $keyname
1101 * @param string $valuename
1102 * @return array
1103 */
1104function simple_hash_from_query($query, $keyname, $valuename)
1105{
1106  $array = array();
1107
1108  $result = pwg_query($query);
1109  while ($row = pwg_db_fetch_assoc($result))
1110  {
1111    $array[ $row[$keyname] ] = $row[$valuename];
1112  }
1113
1114  return $array;
1115}
1116
1117/**
1118 * creates an hashed based on a query, this function is a very common
1119 * pattern used here. The key is given as parameter, the value is an associative
1120 * array.
1121 *
1122 * @param string $query
1123 * @param string $keyname
1124 * @return array
1125 */
1126function hash_from_query($query, $keyname)
1127{
1128  $array = array();
1129  $result = pwg_query($query);
1130  while ($row = pwg_db_fetch_assoc($result))
1131  {
1132    $array[ $row[$keyname] ] = $row;
1133  }
1134  return $array;
1135}
1136
1137/**
1138 * Return basename of the current script
1139 * Lower case convertion is applied on return value
1140 * Return value is without file extention ".php"
1141 *
1142 * @param void
1143 *
1144 * @return script basename
1145 */
1146function script_basename()
1147{
1148  global $conf;
1149
1150  foreach (array('SCRIPT_NAME', 'SCRIPT_FILENAME', 'PHP_SELF') as $value)
1151  {
1152    if (!empty($_SERVER[$value]))
1153    {
1154      $filename = strtolower($_SERVER[$value]);
1155      if ($conf['php_extension_in_urls'] and get_extension($filename)!=='php')
1156        continue;
1157      $basename = basename($filename, '.php');
1158      if (!empty($basename))
1159      {
1160        return $basename;
1161      }
1162    }
1163  }
1164  return '';
1165}
1166
1167/**
1168 * Return value for the current page define on $conf['filter_pages']
1169 * Îf value is not defined, default value are returned
1170 *
1171 * @param value name
1172 *
1173 * @return filter page value
1174 */
1175function get_filter_page_value($value_name)
1176{
1177  global $conf;
1178
1179  $page_name = script_basename();
1180
1181  if (isset($conf['filter_pages'][$page_name][$value_name]))
1182  {
1183    return $conf['filter_pages'][$page_name][$value_name];
1184  }
1185  else if (isset($conf['filter_pages']['default'][$value_name]))
1186  {
1187    return $conf['filter_pages']['default'][$value_name];
1188  }
1189  else
1190  {
1191    return null;
1192  }
1193}
1194
1195/**
1196 * returns the character set of data sent to browsers / received from forms
1197 */
1198function get_pwg_charset()
1199{
1200  defined('PWG_CHARSET') or fatal_error('PWG_CHARSET undefined');
1201  return PWG_CHARSET;
1202}
1203
1204/**
1205 * includes a language file or returns the content of a language file
1206 * availability of the file
1207 *
1208 * in descending order of preference:
1209 *   param language, user language, default language
1210 * Piwigo default language.
1211 *
1212 * @param string filename
1213 * @param string dirname
1214 * @param mixed options can contain
1215 *     language - language to load (if empty uses user language)
1216 *     return - if true the file content is returned otherwise the file is evaluated as php
1217 *     target_charset -
1218 *     no_fallback - the language must be respected
1219 * @return boolean success status or a string if options['return'] is true
1220 */
1221function load_language($filename, $dirname = '',
1222    $options = array() )
1223{
1224  global $user;
1225
1226  if (! @$options['return'] )
1227  {
1228    $filename .= '.php'; //MAYBE to do .. load .po and .mo localization files
1229  }
1230  if (empty($dirname))
1231  {
1232    $dirname = PHPWG_ROOT_PATH;
1233  }
1234  $dirname .= 'language/';
1235
1236  $languages = array();
1237  if ( !empty($options['language']) )
1238  {
1239    $languages[] = $options['language'];
1240  }
1241  if ( !empty($user['language']) )
1242  {
1243    $languages[] = $user['language'];
1244  }
1245  if ( ! @$options['no_fallback'] )
1246  {
1247    if ( defined('PHPWG_INSTALLED') )
1248    {
1249      $languages[] = get_default_language();
1250    }
1251    $languages[] = PHPWG_DEFAULT_LANGUAGE;
1252  }
1253
1254  $languages = array_unique($languages);
1255
1256  if ( empty($options['target_charset']) )
1257  {
1258    $target_charset = get_pwg_charset();
1259  }
1260  else
1261  {
1262    $target_charset = $options['target_charset'];
1263  }
1264  $target_charset = strtolower($target_charset);
1265  $source_charset = '';
1266  $source_file    = '';
1267  foreach ($languages as $language)
1268  {
1269    $dir = $dirname.$language;
1270
1271    if ($target_charset!='utf-8')
1272    {
1273      // exact charset match - no conversion required
1274      $f = $dir.'.'.$target_charset.'/'.$filename;
1275      if (file_exists($f))
1276      {
1277        $source_file = $f;
1278        break;
1279      }
1280    }
1281
1282    // UTF-8 ?
1283    $f = $dir.'/'.$filename;
1284    if (file_exists($f))
1285    {
1286      $source_charset = 'utf-8';
1287      $source_file = $f;
1288      break;
1289    }
1290  }
1291
1292  if ( !empty($source_file) )
1293  {
1294    if (! @$options['return'] )
1295    {
1296      @include($source_file);
1297      $load_lang = @$lang;
1298      $load_lang_info = @$lang_info;
1299
1300      global $lang, $lang_info;
1301      if ( !isset($lang) ) $lang=array();
1302      if ( !isset($lang_info) ) $lang_info=array();
1303
1304      if ( !empty($source_charset) and $source_charset!=$target_charset)
1305      {
1306        if ( is_array($load_lang) )
1307        {
1308          foreach ($load_lang as $k => $v)
1309          {
1310            if ( is_array($v) )
1311            {
1312              $func = create_function('$v', 'return convert_charset($v, "'.$source_charset.'","'.$target_charset.'");' );
1313              $lang[$k] = array_map($func, $v);
1314            }
1315            else
1316              $lang[$k] = convert_charset($v, $source_charset, $target_charset);
1317          }
1318        }
1319        if ( is_array($load_lang_info) )
1320        {
1321          foreach ($load_lang_info as $k => $v)
1322          {
1323            $lang_info[$k] = convert_charset($v, $source_charset, $target_charset);
1324          }
1325        }
1326      }
1327      else
1328      {
1329        $lang = array_merge( $lang, (array)$load_lang );
1330        $lang_info = array_merge( $lang_info, (array)$load_lang_info );
1331      }
1332      return true;
1333    }
1334    else
1335    {
1336      $content = @file_get_contents($source_file);
1337      if ( !empty($source_charset) and $source_charset!=$target_charset)
1338      {
1339        $content = convert_charset($content, $source_charset, $target_charset);
1340      }
1341      return $content;
1342    }
1343  }
1344  return false;
1345}
1346
1347/**
1348 * converts a string from a character set to another character set
1349 * @param string str the string to be converted
1350 * @param string source_charset the character set in which the string is encoded
1351 * @param string dest_charset the destination character set
1352 */
1353function convert_charset($str, $source_charset, $dest_charset)
1354{
1355  if ($source_charset==$dest_charset)
1356    return $str;
1357  if ($source_charset=='iso-8859-1' and $dest_charset=='utf-8')
1358  {
1359    return utf8_encode($str);
1360  }
1361  if ($source_charset=='utf-8' and $dest_charset=='iso-8859-1')
1362  {
1363    return utf8_decode($str);
1364  }
1365  if (function_exists('iconv'))
1366  {
1367    return iconv($source_charset, $dest_charset, $str);
1368  }
1369  if (function_exists('mb_convert_encoding'))
1370  {
1371    return mb_convert_encoding( $str, $dest_charset, $source_charset );
1372  }
1373  return $str; //???
1374}
1375
1376/**
1377 * makes sure a index.htm protects the directory from browser file listing
1378 *
1379 * @param string dir directory
1380 */
1381function secure_directory($dir)
1382{
1383  $file = $dir.'/index.htm';
1384  if (!file_exists($file))
1385  {
1386    @file_put_contents($file, 'Not allowed!');
1387  }
1388}
1389
1390/**
1391 * returns a "secret key" that is to be sent back when a user enters a comment
1392 *
1393 * @param int image_id
1394 */
1395function get_comment_post_key($image_id)
1396{
1397  global $conf;
1398
1399  $time = time();
1400
1401  return sprintf(
1402    '%s:%s',
1403    $time,
1404    hash_hmac(
1405      'md5',
1406      $time.':'.$image_id,
1407      $conf['secret_key']
1408      )
1409    );
1410}
1411
1412/**
1413 * return an array which will be sent to template to display navigation bar
1414 */
1415function create_navigation_bar($url, $nb_element, $start, $nb_element_page, $clean_url = false)
1416{
1417  global $conf;
1418
1419  $navbar = array();
1420  $pages_around = $conf['paginate_pages_around'];
1421  $start_str = $clean_url ? '/start-' : (strpos($url, '?')===false ? '?':'&amp;').'start=';
1422
1423  if (!isset($start) or !is_numeric($start) or (is_numeric($start) and $start < 0))
1424  {
1425    $start = 0;
1426  }
1427
1428  // navigation bar useful only if more than one page to display !
1429  if ($nb_element > $nb_element_page)
1430  {
1431    $cur_page = ceil($start / $nb_element_page) + 1;
1432    $maximum = ceil($nb_element / $nb_element_page);
1433    $previous = $start - $nb_element_page;
1434    $next = $start + $nb_element_page;
1435    $last = ($maximum - 1) * $nb_element_page;
1436
1437    $navbar['CURRENT_PAGE'] = $cur_page;
1438
1439    // link to first page and previous page?
1440    if ($cur_page != 1)
1441    {
1442      $navbar['URL_FIRST'] = $url;
1443      $navbar['URL_PREV'] = $url.($previous > 0 ? $start_str.$previous : '');
1444    }
1445    // link on next page and last page?
1446    if ($cur_page != $maximum)
1447    {
1448      $navbar['URL_NEXT'] = $url.$start_str.$next;
1449      $navbar['URL_LAST'] = $url.$start_str.$last;
1450    }
1451
1452    // pages to display
1453    $navbar['pages'] = array();
1454    $navbar['pages'][1] = $url;
1455    $navbar['pages'][$maximum] = $url.$start_str.$last;
1456
1457    for ($i = max($cur_page - $pages_around , 2), $stop = min($cur_page + $pages_around + 1, $maximum);
1458         $i < $stop; $i++)
1459    {
1460      $navbar['pages'][$i] = $url.$start_str.(($i - 1) * $nb_element_page);
1461    }
1462    ksort($navbar['pages']);
1463  }
1464  return $navbar;
1465}
1466
1467/**
1468 * return an array which will be sent to template to display recent icon
1469 */
1470function get_icon($date, $is_child_date = false)
1471{
1472  global $cache, $user;
1473
1474  if (empty($date))
1475  {
1476    return false;
1477  }
1478
1479  if (!isset($cache['get_icon']['title']))
1480  {
1481    $cache['get_icon']['title'] = sprintf(
1482      l10n('elements posted during the last %d days'),
1483      $user['recent_period']
1484      );
1485  }
1486
1487  $icon = array(
1488    'TITLE' => $cache['get_icon']['title'],
1489    'IS_CHILD_DATE' => $is_child_date,
1490    );
1491
1492  if (isset($cache['get_icon'][$date]))
1493  {
1494    return $cache['get_icon'][$date] ? $icon : array();
1495  }
1496
1497  if (!isset($cache['get_icon']['sql_recent_date']))
1498  {
1499    // Use MySql date in order to standardize all recent "actions/queries"
1500    list($cache['get_icon']['sql_recent_date']) =
1501      pwg_db_fetch_row(pwg_query('select SUBDATE(
1502      CURRENT_DATE,INTERVAL '.$user['recent_period'].' DAY)'));
1503  }
1504
1505  $cache['get_icon'][$date] = $date > $cache['get_icon']['sql_recent_date'];
1506
1507  return $cache['get_icon'][$date] ? $icon : array();
1508}
1509?>
Note: See TracBrowser for help on using the repository browser.