Linux multi-monitor fullscreen support
[ryzomcore.git] / web / public_php / api / common / utils.php
blob12895535ed6060d5bad6a1856336420b43556e1b
1 <?php
3 /* Copyright (C) 2009 Winch Gate Property Limited
5 * This file is part of ryzom_api.
6 * ryzom_api is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * ryzom_api is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with ryzom_api. If not, see <http://www.gnu.org/licenses/>.
20 include_once('logger.php');
21 include_once('dfm.php');
23 define('SERVER', 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']);
25 function stripslashes_deep($value)
27 $value = is_array($value) ?
28 array_map('stripslashes_deep', $value) :
29 stripslashes($value);
31 return $value;
34 if (ini_get('magic_quotes_gpc') == 1) {
35 $_POST = stripslashes_deep($_POST);
36 $_GET = stripslashes_deep($_GET);
39 // Always use this function to get param because in game, the param can be pass by _GET or by _POST
40 function ryzom_get_param($var, $default='')
42 if (isset($_POST[$var]))
43 return $_POST[$var];
44 else
45 if (isset($_GET[$var]))
46 return $_GET[$var];
47 else
48 return $default;
51 function parse_query($var)
53 $var = parse_url($var);
54 $arr = array();
55 if (isset($var['query'])) {
56 $var = html_entity_decode($var['query']);
57 $var = explode('&', $var);
59 foreach($var as $val) {
60 $x = explode('=', $val);
61 if (count($x) > 1)
62 $arr[$x[0]] = urldecode($x[1]);
63 else
64 $arr[$x[0]] = '';
66 unset($val, $x, $var);
68 return $arr;
71 function ryzom_get_params()
73 if (!isset($GLOBALS['URL_PARAMS']))
74 $GLOBALS['URL_PARAMS'] = parse_query($_SERVER['REQUEST_URI']);
75 return $GLOBALS['URL_PARAMS'];
78 function ryzom_unset_url_param($name) {
79 if (!isset($GLOBALS['URL_PARAMS']))
80 $GLOBALS['URL_PARAMS'] = parse_query($_SERVER['REQUEST_URI']);
81 unset($GLOBALS['URL_PARAMS'][$name]);
82 return $GLOBALS['URL_PARAMS'];
85 if (!function_exists('http_build_query')) {
86 function http_build_query($data, $prefix='', $sep='', $key='') {
87 $ret = array();
88 foreach ((array)$data as $k => $v) {
89 if (is_int($k) && $prefix != null) {
90 $k = urlencode($prefix . $k);
92 if ((!empty($key)) || ($key === 0)) $k = $key.'['.urlencode($k).']';
93 if (is_array($v) || is_object($v)) {
94 array_push($ret, http_build_query($v, '', $sep, $k));
95 } else {
96 array_push($ret, $k.'='.urlencode($v));
99 if (empty($sep)) $sep = ini_get('arg_separator.output');
100 return implode($sep, $ret);
104 if(!function_exists('_url')){
105 function _url($base_params=null, $add_params=array()){
106 if ($base_params !== null)
107 return SERVER.'?'.http_build_query(array_merge($base_params, $add_params));
108 else
109 return SERVER;
114 if(!function_exists('_h')){
115 function _h($s){
116 return htmlspecialchars($s, ENT_QUOTES, 'UTF-8');
120 if(!function_exists('_i')){
121 function _i($img, $alt=''){
122 if (substr($img, strlen($img)-4) == '.tga') // img from client texture : ig only
123 return $img;
125 if (is_file(RYAPI_PATH.'/data/icons/'.$img.'.png'))
126 $img = RYAPI_URL.'/data/icons/'.$img.'.png';
127 else if (is_file(RYAPP_PATH.'/data/icons/'.$img.'.png'))
128 $img = RYAPP_URL.'/data/icons/'.$img.'.png';
129 else
130 $img = 'view_remove';
132 if ($alt)
133 return '<img src="'.$img.'" title="'.$alt.'" alt="'.utf8_decode($alt).'" />';
134 else
135 return '<img src="'.$img.'" />';
140 if(!function_exists('_l')){
141 function _l($text, $base_params=array(), $add_params=array())
143 return '<a href="'.SERVER.'?'.http_build_query(array_merge($base_params, $add_params)).'">'.$text.'</a>';
147 if(!function_exists('_b')){
148 function _b($text, $base_params=array(), $add_params=array())
150 return '<a href="'.SERVER.'?'.http_build_query(array_merge($base_params, $add_params)).'" class="ryzom-ui-button">'.$text.'</a>';
154 /***
156 * Translation utilities
158 * ***/
160 function translation_exists($id) {
161 global $user, $ryzom_texts;
162 return isset($ryzom_texts[$id]) && isset($ryzom_texts[$id][$user['lang']]);
165 // Translate the $id in the selected language
166 function get_translation($id, $lang, $args=array()) {
167 global $ryzom_texts, $user;
168 if(!isset($ryzom_texts[$id])) return '{'.$id.'}';
169 if(empty($ryzom_texts[$id][$lang])){
170 if(isset($ryzom_texts[$id]['en'])) return @vsprintf($ryzom_texts[$id]['en'], $args);
171 return '{'.$id.'['.$lang.']}';
173 return @vsprintf($ryzom_texts[$id][$lang], $args);
177 // Translate the $id in the user language
178 function _t($id, $args=array()) {
179 global $ryzom_texts, $user;
181 $a = '';
182 if ($args) {
183 if (is_array($args)) {
184 $a = array();
185 foreach ($args as $arg)
186 $a[] = strval($arg);
187 $a = ' '.implode(', ', $a);
188 } else
189 $a = ' '.strval($args);
191 if(!isset($ryzom_texts[$id])) return '{'.$id.$a.'}';
192 if(empty($ryzom_texts[$id][$user['lang']])){
193 if(!empty($ryzom_texts[$id]['en'])) return @vsprintf($ryzom_texts[$id]['en'], $args);
194 if(!empty($ryzom_texts[$id]['fr'])) return '{'.$id.$a.'}';
195 if(!empty($ryzom_texts[$id]['de'])) return '{'.$id.$a.'}';
196 return '{'.$id.'['.$user['lang'].']'.$a.'}';
198 return @vsprintf($ryzom_texts[$id][$user['lang']], $args);
201 /***
203 * Ryzom time
205 * ***/
207 function ryzom_timer($timestamp) {
208 $d = intval($timestamp / 86400);
209 $timestamp = $timestamp % 86400;
210 $h = intval($timestamp / 3600);
211 $timestamp = $timestamp % 3600;
212 $m = intval($timestamp / 60);
213 $s = $timestamp % 60;
214 if ($d>1)
215 return sprintf('%d'._t('days').' %02d:%02d:%02d', $d, $h, $m, $s);
216 else if ($d)
217 return sprintf('%d'._t('day').' %02d:%02d:%02d', $d, $h, $m, $s);
218 else
219 return sprintf("%02d:%02d:%02d", $h, $m, $s);
222 // Get a human and translated readable time, for example "3 days ago"
223 function ryzom_relative_time($timestamp) {
224 global $ryzom_periods, $user;
225 $difference = time() - $timestamp;
226 $lengths = array("60","60","24","7","4.35","12","10");
228 if ($difference >= 0) { // this was in the past
229 $ending = _t('ago');
230 } else { // this was in the future
231 $difference = -$difference;
232 $ending = _t('to_go');
234 for($j = 0,$m=count($lengths); $j<$m && $difference >= $lengths[$j]; $j++)
235 $difference /= $lengths[$j];
236 // round hours as '1.2 hours to go'
237 $difference = round($difference, ($j == 2) ? 1 : 0);
239 $form = ($difference == 1) ? 'singular' : 'plural';
241 // Handle exceptions
242 // French uses singular form if difference = 0
243 if ($user['lang'] == 'fr' && ($difference == 0)) {
244 $form = 'singular';
246 // Russian has a different plural form for plurals of 2 through 4
247 if ($user['lang'] == 'ru' && ($form == 'plural')) {
248 if ($difference < 5) {
249 $form = '2-4';
253 if(!empty($ryzom_periods[$user['lang']][$form][$j]))
254 $final = $ryzom_periods[$user['lang']][$form][$j];
255 else
256 $final = $ryzom_periods['en'][$form][$j];
257 $text = _t('date_format', array($difference, $final, $ending));
258 return $text;
261 // Get a human and translated absolute date
262 function ryzom_absolute_time($timestamp) {
263 global $user, $ryzom_daysofweek, $ryzom_monthnames;
264 $day_of_month = date("j", $timestamp);
265 $dow = date("w", $timestamp);
266 $month = date("n", $timestamp);
267 $day_of_week = $ryzom_daysofweek[$user['lang']][$dow];
268 $month_str = $ryzom_monthnames[$user['lang']][$month-1];
269 $text = _t("absolute_date_format", array($day_of_month, $day_of_week, $month_str, $month, date("m", $timestamp), date("d", $timestamp)));
270 return $text;
274 /***
276 * Ryzom utilities
279 * ***/
281 function ryzom_generate_password($length=8, $level=2, $oneofeach=false) {
282 $validchars[1] = "0123456789abcdfghjkmnpqrstvwxyz";
283 $validchars[2] = "0123456789abcdfghjkmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
284 $validchars[3] = "0123456789_!@#$%&*()-=+/abcdfghjkmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_!@#$%&*()-=+/";
286 $password = "";
287 $counter = 0;
289 while ($counter < $length) {
290 $actChar = substr($validchars[$level], rand(0, strlen($validchars[$level])-1), 1);
292 // if $oneofeach then All character must be different (slower)
293 if (!$oneofeach || !strstr($password, $actChar)) {
294 $password .= $actChar;
295 $counter++;
299 return $password;
303 function file_get_contents_cached($fn, $cache_time=300) {
304 global $ryzom_bench_text;
306 $lfn = 'tmp/'.strtr($fn, ':/.?&=', '____________');
308 // get the new file from internet every $cache_time (default=5min)
309 if (file_exists($lfn) && filesize($lfn) > 0 && time() < filemtime($lfn) + $cache_time) {
310 $content = file_get_contents($lfn);
311 } else {
312 $content = file_get_contents($fn);
313 if ($content != '') file_put_contents($lfn, $content);
315 return $content;
318 function ryzom_redirect($url, $group='', $extra_lua='') {
319 global $user;
320 $lua = $extra_lua."\n";
321 if ($user['ig']) {
322 if (!$group)
323 $lua .= 'getUI(__CURRENT_WINDOW__):browse("'.str_replace('&', '&amp;', $url).'")';
324 else {
325 if (substr($group, 0, 3) == 'ui:')
326 $lua .= 'getUI("'.$group.'"):browse("'.str_replace('&', '&amp;', $url).'")';
327 else
328 $lua .= 'getUI("ui:interface:'.$group.':content:html"):browse("'.str_replace('&', '&amp;', $url).'")';
330 echo '<lua>'.$lua.'</lua>';
331 die();
332 } else {
333 header('Location: '.$url);
334 die();
338 /***
340 * Debug tools
342 * ***/
344 function alert($var, $value=NULL, $level=1) {
345 p($var, $value, '#FF7777', $level);
348 define('pNULL', '§$£¤*µ%ù²&#!;,;:.?/?.<>');
350 function p($var, $value=pNULL, $color='#FFFF00', $level=0) {
351 ob_start();
352 debug_print_backtrace();
353 $bt = ob_get_contents();
354 ob_end_clean();
355 $bt = explode("\n#",$bt);
356 if (isset($bt[$level]))
357 $bt1 = explode('[', $bt[$level]);
358 else
359 $bt1 = array('');
361 if (isset($bt[$level+1]))
362 $bt2 = explode('[', $bt[$level+1]);
363 else
364 $bt2 = array('');
366 $c = '';
367 if ($value !== pNULL) {
368 $c .= '<font color="#FFFFFF">'.$var.' : </font>';
369 $var = $value;
371 $c .= '<font color="#AAFFFF">'.substr(str_replace("\n", "", $bt2[count($bt2)-1]), 0, -1).' =&gt; '.substr(str_replace("\n", "", $bt1[count($bt1)-1]), 0, -1)."</font> ";
372 ryLogger::getInstance()->addPrint($c);
373 ob_start();
374 var_dump($var);
375 ryLogger::getInstance()->addPrint(_h(ob_get_contents()), $color);
376 ob_end_clean();
380 /***
382 * Lua tools
384 * ***/
386 class ryLua {
388 static private $lua = array();
389 static private $luaend = array();
390 static private $indent;
391 static private $indentend;
392 static private $linkTargetId = 0;
394 static function add($code, $indent=NULL) {
395 if ($indent !== NULL)
396 self::$indent += $indent;
397 $tabs = str_repeat(" ", self::$indent);
398 $a = $tabs.str_replace("\n", "\n ".$tabs, $code);
399 self::$lua[] = $a;
402 static function addEnd($code, $indent=NULL) {
403 if ($indent !== NULL)
404 self::$indentend += $indent;
405 $tabs = str_repeat(" ", self::$indentend);
406 $a = $tabs.str_replace("\n", "\n ".$tabs, $code);
407 self::$luaend[] = $a;
411 static function get($ig) {
412 ryLogger::getInstance()->addPrint(implode("\n", self::$lua), '#FF00FF');
413 $ret = ($ig)?"<lua>\n".implode("\n", self::$lua)."\n</lua>":'';
414 self::$lua = array();
415 return $ret;
418 static function getEnd($ig) {
419 ryLogger::getInstance()->addPrint(implode("\n", self::$luaend), '#FF55FF');
420 $ret = ($ig)?"<lua>\n".implode("\n", self::$luaend)."\n</lua>":'';
421 self::$luaend = array();
422 return $ret;
425 static function text($text) {
426 return str_replace('"', '\"', $text);
429 static function url($base_params=null, $add_params=array()) {
430 return str_replace('&', '&amp;', _url($base_params, $add_params));
434 function openLink($text, $target='webig', $base_params=array(), $add_params=array(), $urllua='', $runlua='')
436 $url = self::url($base_params, $add_params);
437 if ($target == "help_browser")
438 $url .= "&amp;ignore=";
439 $id = ryzom_generate_password(8).strval(time()).strval(self::$linkTargetId++);
440 $lua = <<< END
441 function openLink{$id}()
442 runAH(nil, "browse", "name=ui:interface:{$target}:content:html|url={$url}"{$urllua})
443 {$runlua}
445 END;
446 self::add($lua);
447 if (RYZOM_IG)
448 return '<a href="ah:lua&openLink'.$id.'()">'.$text.'</a>';
449 return $text;
452 static function link($id, $luacode, $text) {
453 $lua = <<<END
454 function runLua{$id}()
455 {$luacode}
457 END;
458 self::add($lua);
459 if (RYZOM_IG)
460 return '<a href="ah:lua&runLua'.$id.'()">'.$text.'</a>';
461 return $text;