diff options
Diffstat (limited to 'include/functions.inc.php')
-rw-r--r-- | include/functions.inc.php | 1029 |
1 files changed, 720 insertions, 309 deletions
diff --git a/include/functions.inc.php b/include/functions.inc.php index bcbab6ad1..219f6dcce 100644 --- a/include/functions.inc.php +++ b/include/functions.inc.php @@ -1,8 +1,8 @@ -<?php +<?php // +-----------------------------------------------------------------------+ // | Piwigo - a PHP based photo gallery | // +-----------------------------------------------------------------------+ -// | Copyright(C) 2008-2013 Piwigo Team http://piwigo.org | +// | Copyright(C) 2008-2014 Piwigo Team http://piwigo.org | // | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net | // | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick | // +-----------------------------------------------------------------------+ @@ -21,6 +21,10 @@ // | USA. | // +-----------------------------------------------------------------------+ +/** + * @package functions\___ + */ + include_once( PHPWG_ROOT_PATH .'include/functions_plugins.inc.php' ); include_once( PHPWG_ROOT_PATH .'include/functions_user.inc.php' ); include_once( PHPWG_ROOT_PATH .'include/functions_cookie.inc.php' ); @@ -32,13 +36,13 @@ include_once( PHPWG_ROOT_PATH .'include/functions_url.inc.php' ); include_once( PHPWG_ROOT_PATH .'include/derivative_params.inc.php'); include_once( PHPWG_ROOT_PATH .'include/derivative_std_params.inc.php'); include_once( PHPWG_ROOT_PATH .'include/derivative.inc.php'); -require_once( PHPWG_ROOT_PATH .'include/smarty/libs/Smarty.class.php'); include_once( PHPWG_ROOT_PATH .'include/template.class.php'); -//----------------------------------------------------------- generic functions /** - * stupidly returns the current microsecond since Unix epoch + * returns the current microsecond since Unix epoch + * + * @return int */ function micro_seconds() { @@ -48,95 +52,74 @@ function micro_seconds() return $t2; } -// The function get_moment returns a float value coresponding to the number -// of seconds since the unix epoch (1st January 1970) and the microseconds -// are precised : e.g. 1052343429.89276600 +/** + * returns a float value coresponding to the number of seconds since + * the unix epoch (1st January 1970) and the microseconds are precised + * e.g. 1052343429.89276600 + * + * @return float + */ function get_moment() { return microtime(true); } -// The function get_elapsed_time returns the number of seconds (with 3 -// decimals precision) between the start time and the end time given. -function get_elapsed_time( $start, $end ) -{ - return number_format( $end - $start, 3, '.', ' ').' s'; -} - -// - The replace_space function replaces space and '-' characters -// by their HTML equivalent &nbsb; and − -// - The function does not replace characters in HTML tags -// - This function was created because IE5 does not respect the -// CSS "white-space: nowrap;" property unless space and minus -// characters are replaced like this function does. -// - Example : -// <div class="foo">My friend</div> -// ( 01234567891111111111222222222233 ) -// ( 0123456789012345678901 ) -// becomes : -// <div class="foo">My friend</div> -function replace_space( $string ) -{ - //return $string; - $return_string = ''; - // $remaining is the rest of the string where to replace spaces characters - $remaining = $string; - // $start represents the position of the next '<' character - // $end represents the position of the next '>' character - ; // -> 0 - $end = strpos ( $remaining, '>' ); // -> 16 - // as long as a '<' and his friend '>' are found, we loop - while ( ($start=strpos( $remaining, '<' )) !==false - and ($end=strpos( $remaining, '>' )) !== false ) - { - // $treatment is the part of the string to treat - // In the first loop of our example, this variable is empty, but in the - // second loop, it equals 'My friend' - $treatment = substr ( $remaining, 0, $start ); - // Replacement of ' ' by his equivalent ' ' - $treatment = str_replace( ' ', ' ', $treatment ); - $treatment = str_replace( '-', '−', $treatment ); - // composing the string to return by adding the treated string and the - // following HTML tag -> 'My friend</div>' - $return_string.= $treatment.substr( $remaining, $start, $end-$start+1 ); - // the remaining string is deplaced to the part after the '>' of this - // loop - $remaining = substr ( $remaining, $end + 1, strlen( $remaining ) ); - } - $treatment = str_replace( ' ', ' ', $remaining ); - $treatment = str_replace( '-', '−', $treatment ); - $return_string.= $treatment; - - return $return_string; -} - -// get_extension returns the part of the string after the last "." +/** + * returns the number of seconds (with 3 decimals precision) + * between the start time and the end time given + * + * @param float $start + * @param float $end + * @return string "$TIME s" + */ +function get_elapsed_time($start, $end) +{ + return number_format($end - $start, 3, '.', ' ').' s'; +} + +/** + * returns the part of the string after the last "." + * + * @param string $filename + * @return string + */ function get_extension( $filename ) { return substr( strrchr( $filename, '.' ), 1, strlen ( $filename ) ); } -// get_filename_wo_extension returns the part of the string before the last -// ".". -// get_filename_wo_extension( 'test.tar.gz' ) -> 'test.tar' +/** + * returns the part of the string before the last ".". + * get_filename_wo_extension( 'test.tar.gz' ) = 'test.tar' + * + * @param string $filename + * @return string + */ function get_filename_wo_extension( $filename ) { $pos = strrpos( $filename, '.' ); return ($pos===false) ? $filename : substr( $filename, 0, $pos); } +/** no option for mkgetdir() */ define('MKGETDIR_NONE', 0); +/** sets mkgetdir() recursive */ define('MKGETDIR_RECURSIVE', 1); +/** sets mkgetdir() exit script on error */ define('MKGETDIR_DIE_ON_ERROR', 2); +/** sets mkgetdir() add a index.htm file */ define('MKGETDIR_PROTECT_INDEX', 4); +/** sets mkgetdir() add a .htaccess file*/ define('MKGETDIR_PROTECT_HTACCESS', 8); -define('MKGETDIR_DEFAULT', 7); +/** default options for mkgetdir() = MKGETDIR_RECURSIVE | MKGETDIR_DIE_ON_ERROR | MKGETDIR_PROTECT_INDEX */ +define('MKGETDIR_DEFAULT', MKGETDIR_RECURSIVE | MKGETDIR_DIE_ON_ERROR | MKGETDIR_PROTECT_INDEX); + /** - * creates directory if not exists; ensures that directory is writable - * @param: - * string $dir - * int $flags combination of MKGETDIR_xxx - * @return bool false on error else true + * creates directory if not exists and ensures that directory is writable + * + * @param string $dir + * @param int $flags combination of MKGETDIR_xxx + * @return bool */ function mkgetdir($dir, $flags=MKGETDIR_DEFAULT) { @@ -174,19 +157,17 @@ function mkgetdir($dir, $flags=MKGETDIR_DEFAULT) return true; } -/* Returns true if the string appears to be encoded in UTF-8. (from wordpress) - * @param string Str +/** + * finds out if a string is in ASCII, UTF-8 or other encoding + * + * @param string $str + * @return int *0* if _$str_ is ASCII, *1* if UTF-8, *-1* otherwise */ -function seems_utf8($Str) { - // OBSOLETE !!! - return qualify_utf8($Str) >= 0; -} - -/* returns 0 if $str is Ascii, 1 if utf-8, -1 otherwise */ function qualify_utf8($Str) { $ret = 0; - for ($i=0; $i<strlen($Str); $i++) { + for ($i=0; $i<strlen($Str); $i++) + { if (ord($Str[$i]) < 0x80) continue; # 0bbbbbbb $ret = 1; if ((ord($Str[$i]) & 0xE0) == 0xC0) $n=1; # 110bbbbb @@ -195,7 +176,8 @@ function qualify_utf8($Str) elseif ((ord($Str[$i]) & 0xFC) == 0xF8) $n=4; # 111110bb elseif ((ord($Str[$i]) & 0xFE) == 0xFC) $n=5; # 1111110b else return -1; # Does not match any model - for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ? + for ($j=0; $j<$n; $j++) + { # n bytes matching 10bbbbbb follow ? if ((++$i == strlen($Str)) || ((ord($Str[$i]) & 0xC0) != 0x80)) return -1; } @@ -203,16 +185,22 @@ function qualify_utf8($Str) return $ret; } -/* Remove accents from a UTF-8 or ISO-859-1 string (from wordpress) - * @param string sstring - an UTF-8 or ISO-8859-1 string +/** + * Remove accents from a UTF-8 or ISO-8859-1 string (from wordpress) + * + * @param string $string + * @return string */ function remove_accents($string) { $utf = qualify_utf8($string); if ( $utf == 0 ) + { return $string; // ascii + } - if ( $utf > 0 ) { + if ( $utf > 0 ) + { $chars = array( // Decompositions for Latin-1 Supplement "\xc3\x80"=>'A', "\xc3\x81"=>'A', @@ -316,7 +304,9 @@ function remove_accents($string) "\xc2\xa3"=>''); $string = strtr($string, $chars); - } else { + } + else + { // Assume ISO-8859-1 if not UTF-8 $chars['in'] = chr(128).chr(131).chr(138).chr(142).chr(154).chr(158) .chr(159).chr(162).chr(165).chr(181).chr(192).chr(193).chr(194) @@ -342,6 +332,12 @@ function remove_accents($string) if (function_exists('mb_strtolower') && defined('PWG_CHARSET')) { + /** + * removes accents from a string and converts it to lower case + * + * @param string $term + * @return string + */ function transliterate($term) { return remove_accents( mb_strtolower($term, PWG_CHARSET) ); @@ -349,18 +345,19 @@ if (function_exists('mb_strtolower') && defined('PWG_CHARSET')) } else { + /** + * @ignore + */ function transliterate($term) { return remove_accents( strtolower($term) ); } } - - /** * simplify a string to insert it into an URL * - * @param string + * @param string $str * @return string */ function str2url($str) @@ -378,12 +375,10 @@ function str2url($str) return $res; } -//-------------------------------------------- Piwigo specific functions - /** * returns an array with a list of {language_code => language_name} * - * @returns array + * @return string[] */ function get_languages() { @@ -406,6 +401,13 @@ SELECT id, name return $languages; } +/** + * log the visit into history table + * + * @param int $image_id + * @param string $image_type + * @return bool + */ function pwg_log($image_id = null, $image_type = null) { global $conf, $user, $page; @@ -464,122 +466,255 @@ INSERT INTO '.HISTORY_TABLE.' return true; } -// format_date returns a formatted date for display. The date given in -// argument must be an american format (2003-09-15). By option, you can show the time. -// The output is internationalized. -// -// format_date( "2003-09-15", true ) -> "Monday 15 September 2003 21:52" -function format_date($date, $show_time = false, $show_day_name = true) +/** + * Computes the difference between two dates. + * returns a DateInterval object or a stdClass with the same attributes + * http://stephenharris.info/date-intervals-in-php-5-2 + * + * @param DateTime $date1 + * @param DateTime $date2 + * @return DateInterval|stdClass + */ +function dateDiff($date1, $date2) { - global $lang; - - if (strpos($date, '0') == 0) + if (version_compare(PHP_VERSION, '5.3.0') >= 0) { - return l10n('N/A'); + return $date1->diff($date2); } - - $ymdhms = array(); - $tok = strtok( $date, '- :'); - while ($tok !== false) + + $diff = new stdClass(); + + //Make sure $date1 is ealier + $diff->invert = $date2 < $date1; + if ($diff->invert) { - $ymdhms[] = $tok; - $tok = strtok('- :'); + list($date1, $date2) = array($date2, $date1); } + + //Calculate R values + $R = ($date1 <= $date2 ? '+' : '-'); + $r = ($date1 <= $date2 ? '' : '-'); - if ( count($ymdhms)<3 ) - { - return false; - } + //Calculate total days + $diff->days = round(abs($date1->format('U') - $date2->format('U'))/86400); - $formated_date = ''; - // before 1970, Microsoft Windows can't mktime - if ($ymdhms[0] >= 1970 and $ymdhms[1] != 0 and $ymdhms[2] != 0) + //A leap year work around - consistent with DateInterval + $leap_year = $date1->format('m-d') == '02-29'; + if ($leap_year) { - // we ask midday because Windows think it's prior to midnight with a - // zero and refuse to work - $formated_date.= $lang['day'][date('w', mktime(12,0,0,$ymdhms[1],$ymdhms[2],$ymdhms[0]))]; + $date1->modify('-1 day'); } - if ($ymdhms[2] != 0) + //Years, months, days, hours + $periods = array('years'=>-1, 'months'=>-1, 'days'=>-1, 'hours'=>-1); + + foreach ($periods as $period => &$i) { - $formated_date.= ' '.$ymdhms[2]; + if ($period == 'days' && $leap_year) + { + $date1->modify('+1 day'); + } + + while ($date1 <= $date2 ) + { + $date1->modify('+1 '.$period); + $i++; + } + + //Reset date and record increments + $date1->modify('-1 '.$period); } + + list($diff->y, $diff->m, $diff->d, $diff->h) = array_values($periods); - if ($ymdhms[1] != 0) + //Minutes, seconds + $diff->s = round(abs($date1->format('U') - $date2->format('U'))); + $diff->i = floor($diff->s/60); + $diff->s = $diff->s - $diff->i*60; + + return $diff; +} + +/** + * converts a string into a DateTime object + * + * @param int|string timestamp or datetime string + * @param string $format input format respecting date() syntax + * @return DateTime|false + */ +function str2DateTime($original, $format=null) +{ + if ( !empty($format) && version_compare(PHP_VERSION, '5.3.0') >= 0 )// from known date format { - $formated_date.= ' '.$lang['month'][(int)$ymdhms[1]]; + return DateTime::createFromFormat('!'.$format, $original); // ! char to reset fields to UNIX epoch } - - $formated_date.= ' '.$ymdhms[0]; - if ($show_time and count($ymdhms)>=5 ) + else { - $formated_date.= ' '.$ymdhms[3].':'.$ymdhms[4]; + $date = new DateTime(); + + $t = trim($original, '0123456789'); + if (empty($t)) // from timestamp + { + $date->setTimestamp($original); + } + else // from unknown date format (assuming something like Y-m-d H:i:s) + { + $ymdhms = array(); + $tok = strtok($original, '- :/'); + while ($tok !== false) + { + $ymdhms[] = $tok; + $tok = strtok('- :/'); + } + + if (count($ymdhms)<3) return false; + if (!isset($ymdhms[3])) $ymdhms[3] = 0; + if (!isset($ymdhms[4])) $ymdhms[4] = 0; + if (!isset($ymdhms[5])) $ymdhms[5] = 0; + + $date->setDate($ymdhms[0], $ymdhms[1], $ymdhms[2]); + $date->setTime($ymdhms[3], $ymdhms[4], $ymdhms[5]); + } + + return $date; } - return $formated_date; } /** - * Works out the time since the entry post, takes a an argument in unix time or datetime + * returns a formatted and localized date for display + * + * @param int|string timestamp or datetime string + * @param bool $show_time + * @param bool $show_day_name + * @param string $format input format respecting date() syntax + * @return string */ -function time_since($original, $stop = 'minute') +function format_date($original, $show_time=false, $show_day_name=true, $format=null) { - if (!is_int($original)) + global $lang; + + $date = str2DateTime($original, $format); + + if (!$date) + { + return l10n('N/A'); + } + + $print = ''; + if ($show_day_name) { - $ymdhms = array(); - $tok = strtok($original, '- :'); - while ($tok !== false) + $print.= $lang['day'][ $date->format('w') ].' '; + } + + $print.= $date->format('j'); + $print.= ' '.$lang['month'][ $date->format('n') ]; + $print.= ' '.$date->format('Y'); + + if ($show_time) + { + $temp = $date->format('H:i'); + if ($temp != '00:00') { - $ymdhms[] = $tok; - $tok = strtok('- :'); + $print.= ' '.$temp; } - - if ($ymdhms[0] < 1970) return false; - if (!isset($ymdhms[3])) $ymdhms[3] = 12; - if (!isset($ymdhms[4])) $ymdhms[4] = 0; - if (!isset($ymdhms[5])) $ymdhms[5] = 0; - $original = mktime($ymdhms[3],$ymdhms[4],$ymdhms[5],$ymdhms[1],$ymdhms[2],$ymdhms[0]); } - // array of time period chunks - $chunks = array( - 'year' => 60 * 60 * 24 * 365, - 'month' => 60 * 60 * 24 * 30, - 'week' => 60 * 60 * 24 * 7, - 'day' => 60 * 60 * 24, - 'hour' => 60 * 60, - 'minute' => 60, - 'second' => 1, - ); + return trim($print); +} - $today = time(); /* Current unix time */ - $since = abs($today - $original); +/** + * Works out the time since the given date + * + * @param int|string timestamp or datetime string + * @param string $stop year,month,week,day,hour,minute,second + * @param string $format input format respecting date() syntax + * @param bool $with_text append "ago" or "in the future" + * @param bool $with_weeks + * @return string + */ +function time_since($original, $stop='minute', $format=null, $with_text=true, $with_week=true) +{ + $date = str2DateTime($original, $format); - $print = null; - foreach ($chunks as $name => $seconds) + if (!$date) + { + return l10n('N/A'); + } + + $now = new DateTime(); + $diff = dateDiff($now, $date); + + $chunks = array( + 'year' => $diff->y, + 'month' => $diff->m, + 'week' => 0, + 'day' => $diff->d, + 'hour' => $diff->h, + 'minute' => $diff->i, + 'second' => $diff->s, + ); + + // DateInterval does not contain the number of weeks + if ($with_week) + { + $chunks['week'] = (int)floor($chunks['day']/7); + $chunks['day'] = $chunks['day'] - $chunks['week']*7; + } + + $j = array_search($stop, array_keys($chunks)); + + $print = ''; $i=0; + foreach ($chunks as $name => $value) { - if (($count = floor($since / $seconds)) != 0) + if ($value != 0) { - $print.= l10n_dec('%d '.$name, '%d '.$name.'s', $count); - $since-= $count*$seconds; + $print.= ' '.l10n_dec('%d '.$name, '%d '.$name.'s', $value); } - if (!empty($print) and $chunks[$name] <= $chunks[$stop]) + if (!empty($print) && $i >= $j) { break; } + $i++; } - - if ($today > $original) - { - $print = sprintf(l10n('%s ago'), $print); - } - else + + $print = trim($print); + + if ($with_text) { - $print = sprintf(l10n('%s in the future'), $print); + if ($diff->invert) + { + $print = l10n('%s ago', $print); + } + else + { + $print = l10n('%s in the future', $print); + } } return $print; } +/** + * transform a date string from a format to another (MySQL to d/M/Y for instance) + * + * @param string $original + * @param string $format_in respecting date() syntax + * @param string $format_out respecting date() syntax + * @param string $default if _$original_ is empty + * @return string + */ +function transform_date($original, $format_in, $format_out, $default=null) +{ + if (empty($original)) return $default; + $date = str2DateTime($original, $format_in); + return $date->format($format_out); +} + +/** + * append a variable to _$debug_ global + * + * @param string $string + */ function pwg_debug( $string ) { global $debug,$t2,$page; @@ -595,9 +730,8 @@ function pwg_debug( $string ) } /** - * Redirects to the given URL (HTTP method) - * - * Note : once this function called, the execution doesn't go further + * Redirects to the given URL (HTTP method). + * once this function called, the execution doesn't go further * (presence of an exit() instruction. * * @param string $url @@ -618,14 +752,13 @@ function redirect_http( $url ) } /** - * Redirects to the given URL (HTML method) - * - * Note : once this function called, the execution doesn't go further + * Redirects to the given URL (HTML method). + * once this function called, the execution doesn't go further * (presence of an exit() instruction. * * @param string $url - * @param string $title_msg - * @param integer $refreh_time + * @param string $msg + * @param integer $refresh_time * @return void */ function redirect_html( $url , $msg = '', $refresh_time = 0) @@ -669,14 +802,13 @@ function redirect_html( $url , $msg = '', $refresh_time = 0) } /** - * Redirects to the given URL (Switch to HTTP method or HTML method) - * - * Note : once this function called, the execution doesn't go further + * Redirects to the given URL (automatically choose HTTP or HTML method). + * once this function called, the execution doesn't go further * (presence of an exit() instruction. * * @param string $url - * @param string $title_msg - * @param integer $refreh_time + * @param string $msg + * @param integer $refresh_time * @return void */ function redirect( $url , $msg = '', $refresh_time = 0) @@ -698,50 +830,10 @@ function redirect( $url , $msg = '', $refresh_time = 0) } /** - * returns $_SERVER['QUERY_STRING'] whitout keys given in parameters - * - * @param array $rejects - * @param boolean $escape - if true escape & to & (for html) - * @returns string - */ -function get_query_string_diff($rejects=array(), $escape=true) -{ - if (empty($_SERVER['QUERY_STRING'])) - { - return ''; - } - - $query_string = ''; - - $str = $_SERVER['QUERY_STRING']; - parse_str($str, $vars); - - $is_first = true; - foreach ($vars as $key => $value) - { - if (!in_array($key, $rejects)) - { - $query_string.= $is_first ? '?' : ($escape ? '&' : '&' ); - $is_first = false; - $query_string.= $key.'='.$value; - } - } - - return $query_string; -} - -function url_is_remote($url) -{ - if ( strncmp($url, 'http://', 7)==0 - or strncmp($url, 'https://', 8)==0 ) - { - return true; - } - return false; -} - -/** * returns available themes + * + * @param bool $show_mobile + * @return array */ function get_pwg_themes($show_mobile=false) { @@ -779,6 +871,12 @@ SELECT return $themes; } +/** + * check if a theme is installed (directory exsists) + * + * @param string $theme_id + * @return bool + */ function check_theme_installed($theme_id) { global $conf; @@ -786,7 +884,13 @@ function check_theme_installed($theme_id) return file_exists($conf['themes_dir'].'/'.$theme_id.'/'.'themeconf.inc.php'); } -/** Transforms an original path to its pwg representative */ +/** + * Transforms an original path to its pwg representative + * + * @param string $path + * @param string $representative_ext + * @return string + */ function original_to_representative($path, $representative_ext) { $pos = strrpos($path, '/'); @@ -796,8 +900,10 @@ function original_to_representative($path, $representative_ext) } /** - * @param element_info array containing element information from db; - * at least 'id', 'path' should be present + * get the full path of an image + * + * @param array $element_info element information from db (at least 'path') + * @return string */ function get_element_path($element_info) { @@ -811,10 +917,9 @@ function get_element_path($element_info) /** - * fill the current user caddie with given elements, if not already in - * caddie + * fill the current user caddie with given elements, if not already in caddie * - * @param array elements_id + * @param int[] $elements_id */ function fill_caddie($elements_id) { @@ -833,8 +938,10 @@ SELECT element_id foreach ($caddiables as $caddiable) { - array_push($datas, array('element_id' => $caddiable, - 'user_id' => $user['id'])); + $datas[] = array( + 'element_id' => $caddiable, + 'user_id' => $user['id'], + ); } if (count($caddiables) > 0) @@ -844,9 +951,10 @@ SELECT element_id } /** - * returns the element name from its filename + * returns the element name from its filename. + * removes file extension and replace underscores by spaces * - * @param string filename + * @param string $filename * @return string name */ function get_name_from_file($filename) @@ -855,10 +963,12 @@ function get_name_from_file($filename) } /** - * returns the corresponding value from $lang if existing. Else, the key is - * returned + * translation function. + * returns the corresponding value from _$lang_ if existing else the key is returned + * if more than one parameter is provided sprintf is applied * - * @param string key + * @param string $key + * @param mixed $args,... optional arguments * @return string */ function l10n($key) @@ -869,23 +979,30 @@ function l10n($key) { if ($conf['debug_l10n'] and !isset($lang[$key]) and !empty($key)) { - trigger_error('[l10n] language key "'.$key.'" is not defined', E_USER_WARNING); + trigger_error('[l10n] language key "'. $key .'" not defined', E_USER_WARNING); } $val = $key; } + + if (func_num_args() > 1) + { + $args = func_get_args(); + $val = vsprintf($val, array_slice($args, 1)); + } + return $val; } /** - * returns the prinft value for strings including %d - * return is concorded with decimal value (singular, plural) + * returns the printf value for strings including %d + * returned value is concorded with decimal value (singular, plural) * - * @param singular string key - * @param plural string key - * @param decimal value + * @param string $singular_key + * @param string $plural_key + * @param int $decimal * @return string */ -function l10n_dec($singular_fmt_key, $plural_fmt_key, $decimal) +function l10n_dec($singular_key, $plural_key, $decimal) { global $lang_info; @@ -893,20 +1010,20 @@ function l10n_dec($singular_fmt_key, $plural_fmt_key, $decimal) sprintf( l10n(( (($decimal > 1) or ($decimal == 0 and $lang_info['zero_plural'])) - ? $plural_fmt_key - : $singular_fmt_key + ? $plural_key + : $singular_key )), $decimal); } -/* +/** * returns a single element to use with l10n_args * - * @param string key: translation key - * @param mixed args: arguments to use on sprintf($key, args) + * @param string $key translation key + * @param mixed $args arguments to use on sprintf($key, args) * if args is a array, each values are used on sprintf * @return string */ -function get_l10n_args($key, $args) +function get_l10n_args($key, $args='') { if (is_array($args)) { @@ -919,11 +1036,13 @@ function get_l10n_args($key, $args) return array('key_args' => $key_arg); } -/* - * returns a string formated with l10n elements +/** + * returns a string formated with l10n elements. + * it is usefull to "prepare" a text and translate it later + * @see get_l10n_args() * - * @param array $key_args: l10n_args element or array of l10n_args elements - * @param string $sep: used when translated elements are concatened + * @param array $key_args one l10n_args element or array of l10n_args elements + * @param string $sep used when translated elements are concatened * @return string */ function l10n_args($key_args, $sep = "\n") @@ -961,10 +1080,9 @@ function l10n_args($key_args, $sep = "\n") } /** - * returns the corresponding value from $themeconf if existing. Else, the - * key is returned + * returns the corresponding value from $themeconf if existing or an empty string * - * @param string key + * @param string $key * @return string */ function get_themeconf($key) @@ -990,12 +1108,15 @@ SELECT '.$conf['user_fields']['email'].' ;'; list($email) = pwg_db_fetch_row(pwg_query($query)); + $email = trigger_event('get_webmaster_mail_address', $email); + return $email; } /** * Add configuration parameters from database to global $conf array * + * @param string $condition SQL condition * @return void */ function load_conf_from_db($condition = '') @@ -1028,8 +1149,16 @@ SELECT param, value } $conf[ $row['param'] ] = $val; } + + trigger_action('load_conf', $condition); } +/** + * Add or update a config parameter + * + * @param string $param + * @param string $value + */ function conf_update_param($param, $value) { $query = ' @@ -1063,11 +1192,43 @@ UPDATE '.CONFIG_TABLE.' } /** - * Prepends and appends a string at each value of the given array. + * Delete one or more config parameters + * @since 2.6 + * + * @param string|string[] $params + */ +function conf_delete_param($params) +{ + global $conf; + + if (!is_array($params)) + { + $params = array($params); + } + if (empty($params)) + { + return; + } + + $query = ' +DELETE FROM '.CONFIG_TABLE.' + WHERE param IN(\''. implode('\',\'', $params) .'\') +;'; + pwg_query($query); + + foreach ($params as $param) + { + unset($conf[$param]); + } +} + +/** + * Prepends and appends strings at each value of the given array. * - * @param array - * @param string prefix to each array values - * @param string suffix to each array values + * @param array $array + * @param string $prepend_str + * @param string $append_str + * @return array */ function prepend_append_array_items($array, $prepend_str, $append_str) { @@ -1080,9 +1241,72 @@ function prepend_append_array_items($array, $prepend_str, $append_str) } /** - * creates an hashed based on a query, this function is a very common - * pattern used here. Among the selected columns fetched, choose one to be - * the key, another one to be the value. + * Builds an data array from a SQL query. + * Depending on $key_name and $value_name it can return : + * + * - an array of arrays of all fields (key=null, value=null) + * array( + * array('id'=>1, 'name'=>'DSC8956', ...), + * array('id'=>2, 'name'=>'DSC8957', ...), + * ... + * ) + * + * - an array of a single field (key=null, value='...') + * array('DSC8956', 'DSC8957', ...) + * + * - an associative array of array of all fields (key='...', value=null) + * array( + * 'DSC8956' => array('id'=>1, 'name'=>'DSC8956', ...), + * 'DSC8957' => array('id'=>2, 'name'=>'DSC8957', ...), + * ... + * ) + * + * - an associative array of a single field (key='...', value='...') + * array( + * 'DSC8956' => 1, + * 'DSC8957' => 2, + * ... + * ) + * + * @since 2.6 + * + * @param string $query + * @param string $key_name + * @param string $value_name + * @return array + */ +function query2array($query, $key_name=null, $value_name=null) +{ + $result = pwg_query($query); + $data = array(); + + while ($row = pwg_db_fetch_assoc($result)) + { + if (isset($value_name)) + { + $value = $row[ $value_name ]; + } + else + { + $value = $row; + } + if (isset($key_name)) + { + $data[ $row[$key_name] ] = $value; + } + else + { + $data[] = $value; + } + } + + return $data; +} + +/** + * creates an simple hashmap based on a SQL query. + * choose one to be the key, another one to be the value. + * @deprecated 2.6 * * @param string $query * @param string $keyname @@ -1103,9 +1327,9 @@ function simple_hash_from_query($query, $keyname, $valuename) } /** - * creates an hashed based on a query, this function is a very common - * pattern used here. The key is given as parameter, the value is an associative - * array. + * creates an associative array based on a SQL query. + * choose one to be the key + * @deprecated 2.6 * * @param string $query * @param string $keyname @@ -1123,13 +1347,42 @@ function hash_from_query($query, $keyname) } /** - * Return basename of the current script - * Lower case convertion is applied on return value - * Return value is without file extention ".php" + * creates a numeric array based on a SQL query. + * if _$fieldname_ is empty the returned value will be an array of arrays + * if _$fieldname_ is provided the returned value will be a one dimension array + * @deprecated 2.6 * - * @param void + * @param string $query + * @param string $fieldname + * @return array + */ +function array_from_query($query, $fieldname=false) +{ + $array = array(); + + $result = pwg_query($query); + if (false === $fieldname) + { + while ($row = pwg_db_fetch_assoc($result)) + { + $array[] = $row; + } + } + else + { + while ($row = pwg_db_fetch_assoc($result)) + { + $array[] = $row[$fieldname]; + } + } + return $array; +} + +/** + * Return the basename of the current script. + * The lowercase case filename of the current script without extension * - * @return script basename + * @return string */ function script_basename() { @@ -1153,12 +1406,10 @@ function script_basename() } /** - * Return value for the current page define on $conf['filter_pages'] - * Îf value is not defined, default value are returned - * - * @param value name + * Return $conf['filter_pages'] value for the current page * - * @return filter page value + * @param string $value_name + * @return mixed */ function get_filter_page_value($value_name) { @@ -1181,7 +1432,8 @@ function get_filter_page_value($value_name) } /** - * returns the character set of data sent to browsers / received from forms + * return the character set used by Piwigo + * @return string */ function get_pwg_charset() { @@ -1194,27 +1446,58 @@ function get_pwg_charset() } /** + * returns the parent (fallback) language of a language. + * if _$lang_id_ is null it applies to the current language + * @since 2.6 + * + * @param string $lang_id + * @return string|null + */ +function get_parent_language($lang_id=null) +{ + if (empty($lang_id)) + { + global $lang_info; + return !empty($lang_info['parent']) ? $lang_info['parent'] : null; + } + else + { + $f = PHPWG_ROOT_PATH.'language/'.$lang_id.'/common.lang.php'; + if (file_exists($f)) + { + include($f); + return !empty($lang_info['parent']) ? $lang_info['parent'] : null; + } + } + return null; +} + +/** * includes a language file or returns the content of a language file - * availability of the file * - * in descending order of preference: + * tries to load in descending order: * param language, user language, default language - * Piwigo default language. * - * @param string filename - * @param string dirname + * @param string $filename + * @param string $dirname * @param mixed options can contain - * language - language to load (if empty uses user language) - * return - if true the file content is returned otherwise the file is evaluated as php - * target_charset - - * no_fallback - the language must be respected - * local - if true, get local language file - * @return boolean success status or a string if options['return'] is true + * @option string language - language to load + * @option bool return - if true the file content is returned + * @option bool no_fallback - if true do not load default language + * @option bool local - if true load file from local directory + * @return boolean|string */ -function load_language($filename, $dirname = '', - $options = array() ) +function load_language($filename, $dirname = '', $options = array()) { - global $user; + global $user, $language_files; + + if ( !empty($dirname) and !empty($filename) ) + { + if ( empty($language_files[$dirname]) or !in_array($filename,$language_files[$dirname]) ) + { + $language_files[$dirname][] = $filename; + } + } if (! @$options['return'] ) { @@ -1235,6 +1518,10 @@ function load_language($filename, $dirname = '', { $languages[] = $user['language']; } + if ( ($parent = get_parent_language()) != null) + { + $languages[] = $parent; + } if ( ! @$options['no_fallback'] ) { if ( defined('PHPWG_INSTALLED') ) @@ -1286,7 +1573,7 @@ function load_language($filename, $dirname = '', $parent_language = !empty($load_lang_info['parent']) ? $load_lang_info['parent'] : ( !empty($lang_info['parent']) ? $lang_info['parent'] : null ); - if (!empty($parent_language)) + if (!empty($parent_language) and $parent_language != $selected_language) { @include(str_replace($selected_language, $parent_language, $source_file)); } @@ -1334,9 +1621,10 @@ function load_language($filename, $dirname = '', /** * converts a string from a character set to another character set - * @param string str the string to be converted - * @param string source_charset the character set in which the string is encoded - * @param string dest_charset the destination character set + * + * @param string $str + * @param string $source_charset + * @param string $dest_charset */ function convert_charset($str, $source_charset, $dest_charset) { @@ -1358,13 +1646,13 @@ function convert_charset($str, $source_charset, $dest_charset) { return mb_convert_encoding( $str, $dest_charset, $source_charset ); } - return $str; //??? + return $str; // TODO } /** * makes sure a index.htm protects the directory from browser file listing * - * @param string dir directory + * @param string $dir */ function secure_directory($dir) { @@ -1378,7 +1666,9 @@ function secure_directory($dir) /** * returns a "secret key" that is to be sent back when a user posts a form * - * @param int valid_after_seconds - key validity start time from now + * @param int $valid_after_seconds - key validity start time from now + * @param string $aditionnal_data_to_hash + * @return string */ function get_ephemeral_key($valid_after_seconds, $aditionnal_data_to_hash = '') { @@ -1391,6 +1681,13 @@ function get_ephemeral_key($valid_after_seconds, $aditionnal_data_to_hash = '') $conf['secret_key']); } +/** + * verify a key sent back with a form + * + * @param string $key + * @param string $aditionnal_data_to_hash + * @return bool + */ function verify_ephemeral_key($key, $aditionnal_data_to_hash = '') { global $conf; @@ -1411,6 +1708,14 @@ function verify_ephemeral_key($key, $aditionnal_data_to_hash = '') /** * return an array which will be sent to template to display navigation bar + * + * @param string $url base url of all links + * @param int $nb_elements + * @param int $start + * @param int $nb_element_page + * @param bool $clean_url + * @param string $param_name + * @return array */ function create_navigation_bar($url, $nb_element, $start, $nb_element_page, $clean_url = false, $param_name='start') { @@ -1460,12 +1765,17 @@ function create_navigation_bar($url, $nb_element, $start, $nb_element_page, $cle $navbar['pages'][$i] = $url.$start_str.(($i - 1) * $nb_element_page); } $navbar['pages'][$maximum] = $url_start.$last; + $navbar['NB_PAGE']=$maximum; } return $navbar; } /** * return an array which will be sent to template to display recent icon + * + * @param string $date + * @param bool $is_child_date + * @return array */ function get_icon($date, $is_child_date = false) { @@ -1478,8 +1788,8 @@ function get_icon($date, $is_child_date = false) if (!isset($cache['get_icon']['title'])) { - $cache['get_icon']['title'] = sprintf( - l10n('photos posted during the last %d days'), + $cache['get_icon']['title'] = l10n( + 'photos posted during the last %d days', $user['recent_period'] ); } @@ -1506,7 +1816,7 @@ function get_icon($date, $is_child_date = false) } /** - * check token comming from form posted or get params to prevent csrf attacks + * check token comming from form posted or get params to prevent csrf attacks. * if pwg_token is empty action doesn't require token * else pwg_token is compare to server token * @@ -1522,9 +1832,16 @@ function check_pwg_token() } } else + { bad_request('missing token'); + } } +/** + * get pwg_token used to prevent csrf attacks + * + * @return string + */ function get_pwg_token() { global $conf; @@ -1536,14 +1853,13 @@ function get_pwg_token() * breaks the script execution if the given value doesn't match the given * pattern. This should happen only during hacking attempts. * - * @param string param_name - * @param array param_array - * @param boolean is_array - * @param string pattern - * - * @return void + * @param string $param_name + * @param array $param_array + * @param boolean $is_array + * @param string $pattern + * @param boolean $mandatory */ -function check_input_parameter($param_name, $param_array, $is_array, $pattern) +function check_input_parameter($param_name, $param_array, $is_array, $pattern, $mandatory=false) { $param_value = null; if (isset($param_array[$param_name])) @@ -1554,6 +1870,10 @@ function check_input_parameter($param_name, $param_array, $is_array, $pattern) // it's ok if the input parameter is null if (empty($param_value)) { + if ($mandatory) + { + fatal_error('[Hacking attempt] the input parameter "'.$param_name.'" is not valid'); + } return true; } @@ -1581,7 +1901,11 @@ function check_input_parameter($param_name, $param_array, $is_array, $pattern) } } - +/** + * get localized privacy level values + * + * @return string[] + */ function get_privacy_level_options() { global $conf; @@ -1600,7 +1924,7 @@ function get_privacy_level_options() { $label .= ', '; } - $label .= l10n( sprintf('Level %d',$level) ); + $label .= l10n( sprintf('Level %d', $level) ); } $options[$level] = $label; } @@ -1610,6 +1934,9 @@ function get_privacy_level_options() /** * return the branch from the version. For example version 2.2.4 is for branch 2.2 + * + * @param string $version + * @return string */ function get_branch_from_version($version) { @@ -1618,6 +1945,8 @@ function get_branch_from_version($version) /** * return the device type: mobile, tablet or desktop + * + * @return string */ function get_device() { @@ -1647,6 +1976,8 @@ function get_device() /** * return true if mobile theme should be loaded + * + * @return bool */ function mobile_theme() { @@ -1678,6 +2009,9 @@ function mobile_theme() /** * check url format + * + * @param string $url + * @return bool */ function url_check_format($url) { @@ -1694,6 +2028,9 @@ function url_check_format($url) /** * check email format + * + * @param string $mail_address + * @return bool */ function email_check_format($mail_address) { @@ -1710,4 +2047,78 @@ function email_check_format($mail_address) return (bool)preg_match($regex, $mail_address); } } + +/** + * returns the number of available comments for the connected user + * + * @return int + */ +function get_nb_available_comments() +{ + global $user; + if (!isset($user['nb_available_comments'])) + { + $where = array(); + if ( !is_admin() ) + $where[] = 'validated=\'true\''; + $where[] = get_sql_condition_FandF + ( + array + ( + 'forbidden_categories' => 'category_id', + 'visible_categories' => 'category_id', + 'visible_images' => 'ic.image_id' + ), + '', true + ); + + $query = ' +SELECT COUNT(DISTINCT(com.id)) + FROM '.IMAGE_CATEGORY_TABLE.' AS ic + INNER JOIN '.COMMENTS_TABLE.' AS com + ON ic.image_id = com.image_id + WHERE '.implode(' + AND ', $where); + list($user['nb_available_comments']) = pwg_db_fetch_row(pwg_query($query)); + + single_update(USER_CACHE_TABLE, + array('nb_available_comments'=>$user['nb_available_comments']), + array('user_id'=>$user['id']) + ); + } + return $user['nb_available_comments']; +} + +/** + * Compare two versions with version_compare after having converted + * single chars to their decimal values. + * Needed because version_compare does not understand versions like '2.5.c'. + * @since 2.6 + * + * @param string $a + * @param string $b + * @param string $op + */ +function safe_version_compare($a, $b, $op=null) +{ + $replace_chars = create_function('$m', 'return ord(strtolower($m[1]));'); + + // add dot before groups of letters (version_compare does the same thing) + $a = preg_replace('#([0-9]+)([a-z]+)#i', '$1.$2', $a); + $b = preg_replace('#([0-9]+)([a-z]+)#i', '$1.$2', $b); + + // apply ord() to any single letter + $a = preg_replace_callback('#\b([a-z]{1})\b#i', $replace_chars, $a); + $b = preg_replace_callback('#\b([a-z]{1})\b#i', $replace_chars, $b); + + if (empty($op)) + { + return version_compare($a, $b); + } + else + { + return version_compare($a, $b, $op); + } +} + ?>
\ No newline at end of file |