]> git.mxchange.org Git - friendica-addons.git/blob - jappixmini/jappix/php/functions.php
Merge branch '3.6-release'
[friendica-addons.git] / jappixmini / jappix / php / functions.php
1 <?php
2
3 /*
4
5 Jappix - An open social platform
6 These are the PHP functions for Jappix
7
8 -------------------------------------------------
9
10 License: AGPL
11 Authors: Vanaryon, LinkMauve, Mathieui, olivierm
12 Last revision: 16/01/12
13
14 */
15
16 // The function to check if Jappix is already installed
17 function isInstalled() {
18         if(!file_exists(JAPPIX_BASE.'/store/conf/installed.xml'))
19                 return false;
20         
21         return true;
22 }
23
24 // The function to check if a static host is defined
25 function hasStatic() {
26         if(HOST_STATIC && (HOST_STATIC != '.'))
27                 return true;
28         
29         return false;
30 }
31
32 // The function to check if this is a static server
33 function isStatic() {
34         if(hasStatic() && (parse_url(HOST_STATIC, PHP_URL_HOST) == $_SERVER['HTTP_HOST']))
35                 return true;
36         
37         return false;
38 }
39
40 // The function to check if this is an upload server
41 function isUpload() {
42         if(HOST_UPLOAD && (parse_url(HOST_UPLOAD, PHP_URL_HOST) == $_SERVER['HTTP_HOST']))
43                 return true;
44         
45         return false;
46 }
47
48 // The function to get the users.xml file hashed name
49 function usersConfName() {
50         $conf_dir = JAPPIX_BASE.'/store/conf';
51         
52         // No conf folder?
53         if(!is_dir($conf_dir))
54                 return '';
55         
56         // Read the conf folder
57         $conf_scan = scandir($conf_dir.'/');
58         $conf_name = '';
59         
60         // Loop the XML files
61         foreach($conf_scan as $current) {
62                 if(preg_match('/(.+)(\.users\.xml)($)/', $current)) {
63                         $conf_name = $current;
64                         
65                         break;
66                 }
67         }
68         
69         // Return the users file name
70         return $conf_name;
71 }
72
73 // The function to write a XML file
74 function writeXML($type, $xmlns, $xml) {
75         // Generate the file path
76         $conf_path = JAPPIX_BASE.'/store/'.$type.'/';
77         $conf_name = $xmlns.'.xml';
78         
79         // Secured stored file?
80         if(($type == 'conf') && ($xmlns == 'users')) {
81                 // Get the secured file name
82                 $conf_secured = usersConfName();
83                 
84                 // Does this file exist?
85                 if($conf_secured)
86                         $conf_name = $conf_secured;
87                 else
88                         $conf_name = hash('sha256', rand(1, 99999999).time()).'.users.xml';
89         }
90         
91         // Generate the file complete path
92         $conf_file = $conf_path.$conf_name;
93         
94         // Write the installed marker
95         $gen_xml = '<?xml version="1.0" encoding="utf-8" ?>
96 <jappix xmlns="jappix:'.$type.':'.$xmlns.'">
97         '.trim($xml).'
98 </jappix>';
99         
100         file_put_contents($conf_file, $gen_xml);
101         
102         return true;
103 }
104
105 // The function to read a XML file
106 function readXML($type, $xmlns) {
107         // Generate the file path
108         $conf_path = JAPPIX_BASE.'/store/'.$type.'/';
109         $conf_name = $xmlns.'.xml';
110         
111         // Secured stored file?
112         if(($type == 'conf') && ($xmlns == 'users')) {
113                 // Get the secured file name
114                 $conf_secured = usersConfName();
115                 
116                 // Does this file exist?
117                 if($conf_secured)
118                         $conf_name = $conf_secured;
119         }
120         
121         // Generate the file complete path
122         $conf_file = $conf_path.$conf_name;
123         
124         if(file_exists($conf_file))
125                 return file_get_contents($conf_file);
126         
127         return false;
128 }
129
130 // The function to read remote URLs
131 function read_url($url) {
132         // Any cURL?
133         if(function_exists('curl_init')) {
134                 $ch = curl_init();
135                 curl_setopt($ch, CURLOPT_URL, $url);
136                 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
137                 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
138                 $data = curl_exec($ch);
139                 curl_close($ch);
140         }
141         
142         // Default method
143         else
144                 $data = @file_get_contents($url);
145         
146         return $data;
147 }
148
149 // The function to get the Jappix app. current version
150 function getVersion() {
151         $file = file_get_contents(JAPPIX_BASE.'/VERSION');
152         $version = trim($file);
153         
154         return $version;
155 }
156
157 // The function to detect the user's language
158 function checkLanguage() {
159         // If the user defined a language
160         if(isset($_GET['l']) && !empty($_GET['l'])) {
161                 // We define some stuffs
162                 $defined_lang = strtolower($_GET['l']);
163                 $lang_file = JAPPIX_BASE.'/lang/'.$defined_lang.'/LC_MESSAGES/main.mo';
164                 
165                 if($defined_lang == 'en')
166                         $lang_found = true;
167                 else
168                         $lang_found = file_exists($lang_file);
169                 
170                 // We check if the asked translation exists
171                 if($lang_found) {
172                         $lang = $defined_lang;
173                         
174                         // Write a cookie
175                         setcookie('jappix_locale', $lang, (time() + 31536000));
176                         
177                         return $lang;
178                 }
179         }
180         
181         // No language has been defined, but a cookie is stored
182         if(isset($_COOKIE['jappix_locale'])) {
183                 $check_cookie = $_COOKIE['jappix_locale'];
184                 
185                 // The cookie has a value, check this value
186                 if($check_cookie && (file_exists(JAPPIX_BASE.'/lang/'.$check_cookie.'/LC_MESSAGES/main.mo') || ($check_cookie == 'en')))
187                         return $check_cookie;
188         }
189         
190         // No cookie defined (or an unsupported value), naturally, we check the browser language
191         if(!isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
192                 return 'en';
193         
194         // We get the language of the browser
195         $nav_langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
196         $check_en = strtolower($nav_langs[0]);
197         
198         // We check if this is not english
199         if($check_en == 'en')
200                 return 'en';
201         
202         $order = array();
203         
204         foreach($nav_langs as $entry) {
205                 $indice = explode('=', $entry);
206                 $lang = strtolower(substr(trim($indice[0]), 0, 2));
207                 
208                 if(!isset($indice[1]) || !$indice[1])
209                         $indice = 1;
210                 else
211                         $indice = $indice[1];
212                 
213                 $order[$lang] = $indice;
214         }
215         
216         arsort($order);
217         
218         foreach($order as $nav_lang => $val) {
219                 $lang_found = file_exists(JAPPIX_BASE.'/lang/'.$nav_lang.'/LC_MESSAGES/main.mo');
220                 
221                 if($lang_found)
222                         return $nav_lang;
223         }
224         
225         // If Jappix doen't know that language, we include the english translation
226         return 'en';
227 }
228
229 // The function to convert a ISO language code to its full name
230 function getLanguageName($code) {
231         $code = strtolower($code);
232         
233         $known = array(
234                 'aa' => 'Afaraf',
235                 'ab' => 'Аҧсуа',
236                 'ae' => 'Avesta',
237                 'af' => 'Afrikaans',
238                 'ak' => 'Akan',
239                 'am' => 'አማርኛ',
240                 'an' => 'Aragonés',
241                 'ar' => 'العربية',
242                 'as' => 'অসমীয়া',
243                 'av' => 'авар мацӀ',
244                 'ay' => 'Aymar aru',
245                 'az' => 'Azərbaycan dili',
246                 'ba' => 'башҡорт теле',
247                 'be' => 'Беларуская',
248                 'bg' => 'български',
249                 'bh' => 'भोजपुरी',
250                 'bi' => 'Bislama',
251                 'bm' => 'Bamanankan',
252                 'bn' => 'বাংলা',
253                 'bo' => 'བོད་ཡིག',
254                 'br' => 'Brezhoneg',
255                 'bs' => 'Bosanski jezik',
256                 'ca' => 'Català',
257                 'ce' => 'нохчийн мотт',
258                 'ch' => 'Chamoru',
259                 'co' => 'Corsu',
260                 'cr' => 'ᓀᐦᐃᔭᐍᐏᐣ',
261                 'cs' => 'Česky',
262                 'cu' => 'Словѣньскъ',
263                 'cv' => 'чӑваш чӗлхи',
264                 'cy' => 'Cymraeg',
265                 'da' => 'Dansk',
266                 'de' => 'Deutsch',
267                 'dv' => 'ދިވެހި',
268                 'dz' => 'རྫོང་ཁ',
269                 'ee' => 'Ɛʋɛgbɛ',
270                 'el' => 'Ελληνικά',
271                 'en' => 'English',
272                 'eo' => 'Esperanto',
273                 'es' => 'Español',
274                 'et' => 'Eesti keel',
275                 'eu' => 'Euskara',
276                 'fa' => 'فارسی',
277                 'ff' => 'Fulfulde',
278                 'fi' => 'Suomen kieli',
279                 'fj' => 'Vosa Vakaviti',
280                 'fo' => 'Føroyskt',
281                 'fr' => 'Français',
282                 'fy' => 'Frysk',
283                 'ga' => 'Gaeilge',
284                 'gd' => 'Gàidhlig',
285                 'gl' => 'Galego',
286                 'gn' => 'Avañe\'ẽ',
287                 'gu' => 'ગુજરાતી',
288                 'gv' => 'Ghaelg',
289                 'ha' => 'هَوُسَ',
290                 'he' => 'עברית',
291                 'hi' => 'हिन्दी',
292                 'ho' => 'Hiri Motu',
293                 'hr' => 'Hrvatski',
294                 'ht' => 'Kreyòl ayisyen',
295                 'hu' => 'Magyar',
296                 'hy' => 'Հայերեն',
297                 'hz' => 'Otjiherero',
298                 'ia' => 'Interlingua',
299                 'id' => 'Bahasa',
300                 'ie' => 'Interlingue',
301                 'ig' => 'Igbo',
302                 'ii' => 'ꆇꉙ',
303                 'ik' => 'Iñupiaq',
304                 'io' => 'Ido',
305                 'is' => 'Íslenska',
306                 'it' => 'Italiano',
307                 'iu' => 'ᐃᓄᒃᑎᑐᑦ',
308                 'ja' => '日本語',
309                 'jv' => 'Basa Jawa',
310                 'ka' => 'ქართული',
311                 'kg' => 'KiKongo',
312                 'ki' => 'Gĩkũyũ',
313                 'kj' => 'Kuanyama',
314                 'kk' => 'Қазақ тілі',
315                 'kl' => 'Kalaallisut',
316                 'km' => 'ភាសាខ្មែរ',
317                 'kn' => 'ಕನ್ನಡ',
318                 'ko' => '한 국어',
319                 'kr' => 'Kanuri',
320                 'ks' => 'कश्मीरी',
321                 'ku' => 'Kurdî',
322                 'kv' => 'коми кыв',
323                 'kw' => 'Kernewek',
324                 'ky' => 'кыргыз тили',
325                 'la' => 'Latine',
326                 'lb' => 'Lëtzebuergesch',
327                 'lg' => 'Luganda',
328                 'li' => 'Limburgs',
329                 'ln' => 'Lingála',
330                 'lo' => 'ພາສາລາວ',
331                 'lt' => 'Lietuvių kalba',
332                 'lu' => 'cilubà',
333                 'lv' => 'Latviešu valoda',
334                 'mg' => 'Fiteny malagasy',
335                 'mh' => 'Kajin M̧ajeļ',
336                 'mi' => 'Te reo Māori',
337                 'mk' => 'македонски јазик',
338                 'ml' => 'മലയാളം',
339                 'mn' => 'Монгол',
340                 'mo' => 'лимба молдовеняскэ',
341                 'mr' => 'मराठी',
342                 'ms' => 'Bahasa Melayu',
343                 'mt' => 'Malti',
344                 'my' => 'ဗမာစာ',
345                 'na' => 'Ekakairũ Naoero',
346                 'nb' => 'Norsk bokmål',
347                 'nd' => 'isiNdebele',
348                 'ne' => 'नेपाली',
349                 'ng' => 'Owambo',
350                 'nl' => 'Nederlands',
351                 'nn' => 'Norsk nynorsk',
352                 'no' => 'Norsk',
353                 'nr' => 'Ndébélé',
354                 'nv' => 'Diné bizaad',
355                 'ny' => 'ChiCheŵa',
356                 'oc' => 'Occitan',
357                 'oj' => 'ᐊᓂᔑᓈᐯᒧᐎᓐ',
358                 'om' => 'Afaan Oromoo',
359                 'or' => 'ଓଡ଼ିଆ',
360                 'os' => 'Ирон æвзаг',
361                 'pa' => 'ਪੰਜਾਬੀ',
362                 'pi' => 'पािऴ',
363                 'pl' => 'Polski',
364                 'ps' => 'پښتو',
365                 'pt' => 'Português',
366                 'pt-br' => 'Brasileiro',
367                 'qu' => 'Runa Simi',
368                 'rm' => 'Rumantsch grischun',
369                 'rn' => 'kiRundi',
370                 'ro' => 'Română',
371                 'ru' => 'Русский',
372                 'rw' => 'Kinyarwanda',
373                 'sa' => 'संस्कृतम्',
374                 'sc' => 'sardu',
375                 'sd' => 'सिन्धी',
376                 'se' => 'Davvisámegiella',
377                 'sg' => 'Yângâ tî sängö',
378                 'sh' => 'Српскохрватски',
379                 'si' => 'සිංහල',
380                 'sk' => 'Slovenčina',
381                 'sl' => 'Slovenščina',
382                 'sm' => 'Gagana fa\'a Samoa',
383                 'sn' => 'chiShona',
384                 'so' => 'Soomaaliga',
385                 'sq' => 'Shqip',
386                 'sr' => 'српски језик',
387                 'ss' => 'SiSwati',
388                 'st' => 'seSotho',
389                 'su' => 'Basa Sunda',
390                 'sv' => 'Svenska',
391                 'sw' => 'Kiswahili',
392                 'ta' => 'தமிழ்',
393                 'te' => 'తెలుగు',
394                 'tg' => 'тоҷикӣ',
395                 'th' => 'ไทย',
396                 'ti' => 'ትግርኛ',
397                 'tk' => 'Türkmen',
398                 'tl' => 'Tagalog',
399                 'tn' => 'seTswana',
400                 'to' => 'faka Tonga',
401                 'tr' => 'Türkçe',
402                 'ts' => 'xiTsonga',
403                 'tt' => 'татарча',
404                 'tw' => 'Twi',
405                 'ty' => 'Reo Mā`ohi',
406                 'ug' => 'Uyƣurqə',
407                 'uk' => 'українська',
408                 'ur' => 'اردو',
409                 'uz' => 'O\'zbek',
410                 've' => 'tshiVenḓa',
411                 'vi' => 'Tiếng Việt',
412                 'vo' => 'Volapük',
413                 'wa' => 'Walon',
414                 'wo' => 'Wollof',
415                 'xh' => 'isiXhosa',
416                 'yi' => 'ייִדיש',
417                 'yo' => 'Yorùbá',
418                 'za' => 'Saɯ cueŋƅ',
419                 'zh' => '中文',
420                 'zu' => 'isiZulu'
421         );
422         
423         if(isset($known[$code]))
424                 return $known[$code];
425         
426         return null;
427 }
428
429 // The function to know if a language is right-to-left
430 function isRTL($code) {
431         switch($code) {
432                 // RTL language
433                 case 'ar':
434                 case 'he':
435                 case 'dv':
436                 case 'ur':
437                         $is_rtl = true;
438                         
439                         break;
440                 
441                 // LTR language
442                 default:
443                         $is_rtl = false;
444                         
445                         break;
446         }
447         
448         return $is_rtl;
449 }
450
451 // The function to set the good localized <html /> tag
452 function htmlTag($locale) {
453         // Initialize the tag
454         $html = '<html xml:lang="'.$locale.'" lang="'.$locale.'" dir="';
455         
456         // Set the good text direction (TODO)
457         /* if(isRTL($locale))
458                 $html .= 'rtl';
459         else
460                 $html .= 'ltr'; */
461         
462         $html .= 'ltr';
463         
464         // Close the tag
465         $html .= '">';
466         
467         echo($html);
468 }
469
470 // The function which generates the available locales list
471 function availableLocales($active_locale) {
472         // Initialize
473         $scan = scandir(JAPPIX_BASE.'/lang/');
474         $list = array();
475         
476         // Loop the available languages
477         foreach($scan as $current_id) {
478                 // Get the current language name
479                 $current_name = getLanguageName($current_id);
480                 
481                 // Not valid?
482                 if(($current_id == $active_locale) || ($current_name == null))
483                         continue;
484                 
485                 // Add this to the list
486                 $list[$current_id] = $current_name;
487         }
488         
489         return $list;
490 }
491
492 // The function which generates the language switcher hidden part
493 function languageSwitcher($active_locale) {
494         // Initialize
495         $keep_get = keepGet('l', false);
496         $list = availableLocales($active_locale);
497         $html = '';
498         
499         // Generate the HTML code
500         foreach($list as $current_id => $current_name)
501                 $html .= '<a href="./?l='.$current_id.$keep_get.'">'.htmlspecialchars($current_name).'</a>, ';
502         
503         // Output the HTML code
504         return $html;
505 }
506
507 // The function to generate a strong hash
508 function genStrongHash($string) {
509         // Initialize
510         $i = 0;
511         
512         // Loop to generate a incredibly strong hash (can be a bit slow)
513         while($i < 10) {
514                 $string = hash('sha256', $string);
515                 
516                 $i++;
517         }
518         
519         return $string;
520 }
521
522 // The function to generate the version hash
523 function genHash($version) {
524         // Get the configuration files path
525         $conf_path = JAPPIX_BASE.'/store/conf/';
526         $conf_main = $conf_path.'main.xml';
527         $conf_hosts = $conf_path.'hosts.xml';
528         $conf_background = $conf_path.'background.xml';
529         $logos_dir = JAPPIX_BASE.'/store/logos/';
530         
531         // Get the hash of the main configuration file
532         if(file_exists($conf_main))
533                 $hash_main = md5_file($conf_main);
534         else
535                 $hash_main = '0';
536         
537         // Get the hash of the main configuration file
538         if(file_exists($conf_hosts))
539                 $hash_hosts = md5_file($conf_hosts);
540         else
541                 $hash_hosts = '0';
542         
543         // Get the hash of the background configuration file
544         if(file_exists($conf_background))
545                 $hash_background = md5_file($conf_background);
546         else
547                 $hash_background = '0';
548         
549         // Get the hash of the logos folder
550         $hash_logos = '';
551         
552         if(is_dir($logos_dir)) {
553                 $logos_scan = scandir($logos_dir.'/');
554                 
555                 foreach($logos_scan as $logos_current) {
556                         if(getFileExt($logos_current) == 'png')
557                                 $hash_logos .= md5_file($logos_dir.$logos_current);
558                 }
559         }
560         
561         return md5($version.$hash_main.$hash_hosts.$hash_background.$hash_logos);
562 }
563
564 // The function to hide the error messages
565 function hideErrors() {
566         // Hide errors if not developer
567         if(!isDeveloper()) {
568                 ini_set('display_errors', 'off');
569                 ini_set('error_reporting', 0);
570         }
571         
572         // Developers need to get error reports!
573         else {
574                 ini_set('display_errors', 'on');
575                 ini_set('error_reporting', E_ALL);
576         }
577 }
578
579 // The function to check BOSH proxy is enabled
580 function BOSHProxy() {
581         if(BOSH_PROXY == 'on')
582                 return true;
583         
584         return false;
585 }
586
587 // The function to check compression is enabled
588 function hasCompression() {
589         if(COMPRESSION != 'off')
590                 return true;
591         
592         return false;
593 }
594
595 // The function to check compression is available with the current client
596 function canCompress() {
597         // Compression allowed by admin & browser?
598         if(hasCompression() && (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')))
599                 return true;
600         
601         return false;
602 }
603
604 // The function to check whether to show manager link or not
605 function showManagerLink() {
606         if(MANAGER_LINK != 'off')
607                 return true;
608         
609         return false;
610 }
611
612 // The function to check HTTPS storage is allowed
613 function httpsStorage() {
614         if(HTTPS_STORAGE == 'on')
615                 return true;
616         
617         return false;
618 }
619
620 // The function to check HTTPS storage must be forced
621 function httpsForce() {
622         if((HTTPS_FORCE == 'on') && sslCheck())
623                 return true;
624         
625         return false;
626 }
627
628 // The function to check we use HTTPS
629 function useHttps() {
630         if(isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on'))
631                 return true;
632         
633         return false;
634 }
635
636 // The function to compress the output pages
637 function compressThis() {
638         if(canCompress() && !isDeveloper())
639                 ob_start('ob_gzhandler');
640 }
641
642 // The function to choose one file get with get.php or a liste of resources
643 function multiFiles() {
644         if(MULTI_FILES == 'on')
645                 return true;
646         
647         return false;
648 }
649
650 function getFiles($h, $l, $t, $g, $f) {
651         // Define the good path to the Get API
652         if(hasStatic())
653                 $path_to = HOST_STATIC.'/';
654         else
655                 $path_to = JAPPIX_BASE.'/';
656                 
657         if(!multiFiles()) {
658                 $values = array();
659                 if ($h)
660                         $values[] = 'h='.$h;
661                 if ($l)
662                         $values[] = 'l='.$l;
663                 if ($t)
664                         $values[] = 't='.$t;
665                 if ($g)
666                         $values[] = 'g='.$g;
667                 if ($f)
668                         $values[] = 'f='.$f;
669                 
670                 return $path_to.'php/get.php?'.implode('&amp;', $values);
671         }
672         
673         if($g && !empty($g) && preg_match('/^(\S+)\.xml$/', $g) && preg_match('/^(css|js)$/', $t) && isSafe($g) && file_exists('xml/'.$g)) {
674                 $xml_data = file_get_contents('xml/'.$g);
675                 
676                 // Any data?
677                 if($xml_data) {
678                         $xml_read = new SimpleXMLElement($xml_data);
679                         $xml_parse = $xml_read->$t;
680                         
681                         // Files were added to the list before (with file var)?
682                         if($f)
683                                 $f .= '~'.$xml_parse;
684                         else
685                                 $f = $xml_parse;
686                 }
687         }
688         
689         // Explode the f string
690         if(strpos($f, '~') != false)
691                 $array = explode('~', $f);
692         else
693                 $array = array($f);
694         
695         $a = array();
696         foreach($array as $file)
697                 $a[] = $path_to.$t.'/'.$file;
698
699         if (count($a) == 1)
700                 return $a[0];
701
702         return $a;
703 }
704
705 function echoGetFiles($h, $l, $t, $g, $f) {
706         if ($t == 'css')
707                 $pattern = '<link rel="stylesheet" href="%s" type="text/css" media="all" />';
708         else if ($t == 'js')
709                 $pattern = '<script type="text/javascript" src="%s"></script>';
710         
711         $files = getFiles($h, $l, $t, $g, $f);
712
713         if (is_string($files))
714                 printf($pattern, $files);
715         else {
716                 $c = count($files)-1;
717                 for($i=0; $i<=$c; $i++) {
718                         if ($i)
719                                 echo '  ';
720                         printf($pattern, $files[$i]);
721                         if ($i != $c)
722                                 echo "\n";
723                 }
724         }
725 }
726
727 // The function to check if anonymous mode is authorized
728 function anonymousMode() {
729         if(isset($_GET['r']) && !empty($_GET['r']) && HOST_ANONYMOUS && (ANONYMOUS == 'on'))
730                 return true;
731         else
732                 return false;
733 }
734
735 // The function to quickly translate a string
736 function _e($string) {
737         echo T_gettext($string);
738 }
739
740 // The function to check the encrypted mode
741 function sslCheck() {
742         if(ENCRYPTION == 'on')
743                 return true;
744         else
745                 return false;
746 }
747
748 // The function to return the encrypted link
749 function sslLink() {
750         // Using HTTPS?
751         if(isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on'))
752                 $link = '<a class="home-images unencrypted" href="http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'">'.T_('Unencrypted').'</a>';
753         
754         // Using HTTP?
755         else
756                 $link = '<a class="home-images encrypted" href="https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'">'.T_('Encrypted').'</a>';
757         
758         return $link;
759 }
760
761 // The function to get the Jappix static URL
762 function staticURL() {
763         // Check for HTTPS
764         $protocol = isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
765         
766         // Full URL
767         $url = $protocol.'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
768         
769         return $url;
770 }
771
772 // The function to get the Jappix location (only from Get API!)
773 function staticLocation() {
774         // Filter the URL
775         return preg_replace('/((.+)\/)php\/get\.php(\S)+$/', '$1', staticURL());
776 }
777
778 // The function to include a translation file
779 function includeTranslation($locale, $domain) {
780         T_setlocale(LC_MESSAGES, $locale);
781         T_bindtextdomain($domain, JAPPIX_BASE.'/lang');
782         T_bind_textdomain_codeset($domain, 'UTF-8');
783         T_textdomain($domain);
784 }
785
786 // The function to check the cache presence
787 function hasCache($hash) {
788         if(file_exists(JAPPIX_BASE.'/store/cache/'.$hash.'.cache'))
789                 return true;
790         else
791                 return false;
792 }
793
794 // The function to check if developer mode is enabled
795 function isDeveloper() {
796         if(DEVELOPER == 'on')
797                 return true;
798         else
799                 return false;
800 }
801
802 // The function to get a file extension
803 function getFileExt($name) {
804         return strtolower(preg_replace('/^(.+)(\.)([^\.]+)$/i', '$3', $name));
805 }
806
807 // The function to get a file type
808 function getFileType($ext) {
809         switch($ext) {
810                 // Images
811                 case 'jpg':
812                 case 'jpeg':
813                 case 'png':
814                 case 'bmp':
815                 case 'gif':
816                 case 'tif':
817                 case 'svg':
818                 case 'psp':
819                 case 'xcf':
820                         $file_type = 'image';
821                         
822                         break;
823                 
824                 // Videos
825                 case 'ogv':
826                 case 'mkv':
827                 case 'avi':
828                 case 'mov':
829                 case 'mp4':
830                 case 'm4v':
831                 case 'wmv':
832                 case 'asf':
833                 case 'mpg':
834                 case 'mpeg':
835                 case 'ogm':
836                 case 'rmvb':
837                 case 'rmv':
838                 case 'qt':
839                 case 'flv':
840                 case 'ram':
841                 case '3gp':
842                 case 'avc':
843                         $file_type = 'video';
844                         
845                         break;
846                 
847                 // Sounds
848                 case 'oga':
849                 case 'ogg':
850                 case 'mka':
851                 case 'flac':
852                 case 'mp3':
853                 case 'wav':
854                 case 'm4a':
855                 case 'wma':
856                 case 'rmab':
857                 case 'rma':
858                 case 'bwf':
859                 case 'aiff':
860                 case 'caf':
861                 case 'cda':
862                 case 'atrac':
863                 case 'vqf':
864                 case 'au':
865                 case 'aac':
866                 case 'm3u':
867                 case 'mid':
868                 case 'mp2':
869                 case 'snd':
870                 case 'voc':
871                         $file_type = 'audio';
872                         
873                         break;
874                 
875                 // Documents
876                 case 'pdf':
877                 case 'odt':
878                 case 'ott':
879                 case 'sxw':
880                 case 'stw':
881                 case 'ots':
882                 case 'sxc':
883                 case 'stc':
884                 case 'sxi':
885                 case 'sti':
886                 case 'pot':
887                 case 'odp':
888                 case 'ods':
889                 case 'doc':
890                 case 'docx':
891                 case 'docm':
892                 case 'xls':
893                 case 'xlsx':
894                 case 'xlsm':
895                 case 'xlt':
896                 case 'ppt':
897                 case 'pptx':
898                 case 'pptm':
899                 case 'pps':
900                 case 'odg':
901                 case 'otp':
902                 case 'sxd':
903                 case 'std':
904                 case 'std':
905                 case 'rtf':
906                 case 'txt':
907                 case 'htm':
908                 case 'html':
909                 case 'shtml':
910                 case 'dhtml':
911                 case 'mshtml':
912                         $file_type = 'document';
913                         
914                         break;
915                 
916                 // Packages
917                 case 'tgz':
918                 case 'gz':
919                 case 'tar':
920                 case 'ar':
921                 case 'cbz':
922                 case 'jar':
923                 case 'tar.7z':
924                 case 'tar.bz2':
925                 case 'tar.gz':
926                 case 'tar.lzma':
927                 case 'tar.xz':
928                 case 'zip':
929                 case 'xz':
930                 case 'rar':
931                 case 'bz':
932                 case 'deb':
933                 case 'rpm':
934                 case '7z':
935                 case 'ace':
936                 case 'cab':
937                 case 'arj':
938                 case 'msi':
939                         $file_type = 'package';
940                         
941                         break;
942                 
943                 // Others
944                 default:
945                         $file_type = 'other';
946                         
947                         break;
948         }
949         
950         return $file_type;
951 }
952
953 // The function to get the MIME type of a file
954 function getFileMIME($path) {
955         $finfo = finfo_open(FILEINFO_MIME_TYPE);
956         $cmime = finfo_file($finfo, $path);
957         finfo_close($finfo);
958         
959         return $cmime;
960 }
961
962 // The function to keep the current GET vars
963 function keepGet($current, $no_get) {
964         // Get the HTTP GET vars
965         $request = $_SERVER['REQUEST_URI'];
966         
967         if(strrpos($request, '?') === false)
968                 $get = '';
969         
970         else {
971                 $uri = explode('?', $request);
972                 $get = $uri[1];
973         }
974         
975         // Remove the items we don't want here
976         $proper = str_replace('&', '&amp;', $get);
977         $proper = preg_replace('/((^)|(&amp;))(('.$current.'=)([^&]+))/i', '', $proper);
978         
979         // Nothing at the end?
980         if(!$proper)
981                 return '';
982         
983         // We have no defined GET var
984         if($no_get) {
985                 // Remove the first "&" if it appears
986                 if(preg_match('/^(&(amp;)?)/i', $proper))
987                         $proper = preg_replace('/^(&(amp;)?)/i', '', $proper);
988                 
989                 // Add the first "?"
990                 $proper = '?'.$proper;
991         }
992         
993         // Add a first "&" if there is no one and no defined GET var
994         else if(!$no_get && (substr($proper, 0, 1) != '&') && (substr($proper, 0, 5) != '&amp;'))
995                 $proper = '&amp;'.$proper;
996         
997         return $proper;
998 }
999
1000 // Escapes regex special characters for in-regex usage
1001 function escapeRegex($string) {
1002         return preg_replace('/[-[\]{}()*+?.,\\^$|#]/', '\\$&', $string);
1003 }
1004
1005 // Generates the security HTML code
1006 function securityHTML() {
1007         return '<!DOCTYPE html>
1008 <html xmlns="http://www.w3.org/1999/xhtml">
1009
1010 <head>
1011         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
1012         <title>Jappix - Forbidden</title>
1013 </head>
1014
1015 <body>
1016         <h1>Forbidden</h1>
1017         <h4>This is a private folder</h4>
1018 </body>
1019
1020 </html>';
1021 }
1022
1023 // Checks if a relative server path is safe
1024 function isSafe($path) {
1025         // Mhh, someone is about to nasty stuffs (previous folder, or executable scripts)
1026         if(preg_match('/\.\.\//', $path) || preg_match('/index\.html?$/', $path) || preg_match('/(\.)((php([0-9]+)?)|(aspx?)|(cgi)|(rb)|(py)|(pl)|(jsp)|(ssjs)|(lasso)|(dna)|(tpl)|(smx)|(cfm))$/i', $path))
1027                 return false;
1028         
1029         return true;
1030 }
1031
1032 // Set the good unity for a size in bytes
1033 function formatBytes($bytes, $precision = 2) {
1034         $units = array('B', 'KB', 'MB', 'GB', 'TB');
1035         
1036         $bytes = max($bytes, 0);
1037         $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
1038         $pow = min($pow, count($units) - 1);
1039         
1040         $bytes /= pow(1024, $pow);
1041         
1042         return round($bytes, $precision) . ' ' . $units[$pow];
1043 }
1044
1045 // Converts a human-readable bytes value to a computer one
1046 function humanToBytes($string) {
1047         // Values array
1048         $values = array(
1049                         'K' => '000',
1050                         'M' => '000000',
1051                         'G' => '000000000',
1052                         'T' => '000000000000',
1053                         'P' => '000000000000000',
1054                         'E' => '000000000000000000',
1055                         'Z' => '000000000000000000000',
1056                         'Y' => '000000000000000000000000'
1057                        );
1058         
1059         // Filter the string
1060         foreach($values as $key => $zero)
1061                 $string = str_replace($key, $zero, $string);
1062         
1063         // Converts the string into an integer
1064         $string = intval($string);
1065         
1066         return $string;
1067 }
1068
1069 // Get the maximum file upload size
1070 function uploadMaxSize() {
1071         // Not allowed to upload files?
1072         if(ini_get('file_uploads') != 1)
1073                 return 0;
1074         
1075         // Upload maximum file size
1076         $upload = humanToBytes(ini_get('upload_max_filesize'));
1077         
1078         // POST maximum size
1079         $post = humanToBytes(ini_get('post_max_size'));
1080         
1081         // Return the lowest value
1082         if($upload <= $post)
1083                 return $upload;
1084         
1085         return $post;
1086 }
1087
1088 // Normalizes special chars
1089 function normalizeChars($string) {
1090         $table = array(
1091                 'Š'=>'S', 'š'=>'s', 'Đ'=>'Dj', 'đ'=>'dj', 'Ž'=>'Z', 'ž'=>'z', 'Č'=>'C', 'č'=>'c', 'Ć'=>'C', 'ć'=>'c',
1092                 'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E',
1093                 'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O',
1094                 'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'Ss',
1095                 'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c', 'è'=>'e', 'é'=>'e',
1096                 'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o',
1097                 'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b',
1098                 'ÿ'=>'y', 'Ŕ'=>'R', 'ŕ'=>'r'
1099         );
1100         
1101         return strtr($string, $table);
1102 }
1103
1104 // Filters the XML special chars for the SVG drawer
1105 function filterSpecialXML($string) {
1106         // Strange thing: when $string = 'Mises à jour' -> bug! but 'Mise à jour' -> ok!
1107         $string = normalizeChars($string);
1108         
1109         // Encodes with HTML special chars
1110         $string = htmlspecialchars($string);
1111         
1112         return $string;
1113 }
1114
1115 // Writes the current visit in the total file
1116 function writeTotalVisit() {
1117         // Get the current time stamp
1118         $stamp = time();
1119         
1120         // Initialize the defaults
1121         $array = array(
1122                         'total' => 0,
1123                         'stamp' => $stamp
1124                       );
1125         
1126         // Try to read the saved data
1127         $total_data = readXML('access', 'total');
1128         
1129         // Get the XML file values
1130         if($total_data) {
1131                 // Initialize the visits reading
1132                 $read_xml = new SimpleXMLElement($total_data);
1133                 
1134                 // Loop the visit elements
1135                 foreach($read_xml->children() as $current_child)
1136                         $array[$current_child->getName()] = intval($current_child);
1137         }
1138         
1139         // Increment the total number of visits
1140         $array['total']++;
1141         
1142         // Generate the new XML data
1143         $total_xml = 
1144         '<total>'.$array['total'].'</total>
1145         <stamp>'.$array['stamp'].'</stamp>'
1146         ;
1147         
1148         // Re-write the new values
1149         writeXML('access', 'total', $total_xml);
1150 }
1151
1152 // Writes the current visit in the months file
1153 function writeMonthsVisit() {
1154         // Get the current month
1155         $month = intval(date('m'));
1156         
1157         // Define the stats array
1158         $array = array();
1159         
1160         // January to August period
1161         if($month <= 8) {
1162                 for($i = 1; $i <= 8; $i++)
1163                         $array['month_'.$i] = 0;
1164         }
1165         
1166         // August to September period
1167         else {
1168                 $i = 8;
1169                 $j = 1;
1170                 
1171                 while($j <= 3) {
1172                         // Last year months
1173                         if(($i >= 8) && ($i <= 12))
1174                                 $array['month_'.$i++] = 0;
1175                         
1176                         // First year months
1177                         else
1178                                 $array['month_'.$j++] = 0;
1179                 }
1180         }
1181         
1182         // Try to read the saved data
1183         $months_data = readXML('access', 'months');
1184         
1185         // Get the XML file values
1186         if($months_data) {
1187                 // Initialize the visits reading
1188                 $read_xml = new SimpleXMLElement($months_data);
1189                 
1190                 // Loop the visit elements
1191                 foreach($read_xml->children() as $current_child) {
1192                         $current_month = $current_child->getName();
1193                         
1194                         // Parse the current month id
1195                         $current_id = intval(preg_replace('/month_([0-9]+)/i', '$1', $current_month));
1196                         
1197                         // Is this month still valid?
1198                         if((($month <= 8) && ($current_id <= $month)) || (($month >= 8) && ($current_id >= 8) && ($current_id <= $month)))
1199                                 $array[$current_month] = intval($current_child);
1200                 }
1201         }
1202         
1203         // Increment the current month value
1204         $array['month_'.$month]++;
1205         
1206         // Generate the new XML data
1207         $months_xml = '';
1208         
1209         foreach($array as $array_key => $array_value)
1210                 $months_xml .= "\n".'   <'.$array_key.'>'.$array_value.'</'.$array_key.'>';
1211         
1212         // Re-write the new values
1213         writeXML('access', 'months', $months_xml);
1214 }
1215
1216 // Writes the current visit to the storage file
1217 function writeVisit() {
1218         // Write total visits
1219         writeTotalVisit();
1220         
1221         // Write months visits
1222         writeMonthsVisit();
1223 }
1224
1225 // Returns the default background array
1226 function defaultBackground() {
1227         // Define the default values
1228         $background_default = array(
1229                                 'type' => 'default',
1230                                 'image_file' => '',
1231                                 'image_repeat' => 'repeat-x',
1232                                 'image_horizontal' => 'center',
1233                                 'image_vertical' => 'top',
1234                                 'image_adapt' => 'off',
1235                                 'image_color' => '#cae1e9',
1236                                 'color_color' => '#cae1e9'
1237                               );
1238         
1239         return $background_default;
1240 }
1241
1242 // Reads the notice configuration
1243 function readNotice() {
1244         // Read the notice configuration XML
1245         $notice_data = readXML('conf', 'notice');
1246         
1247         // Define the default values
1248         $notice_default = array(
1249                                 'type' => 'none',
1250                                 'notice' => ''
1251                           );
1252         
1253         // Stored data array
1254         $notice_conf = array();
1255         
1256         // Read the stored values
1257         if($notice_data) {
1258                 // Initialize the notice configuration XML data
1259                 $notice_xml = new SimpleXMLElement($notice_data);
1260                 
1261                 // Loop the notice configuration elements
1262                 foreach($notice_xml->children() as $notice_child)
1263                         $notice_conf[$notice_child->getName()] = utf8_decode($notice_child);
1264         }
1265         
1266         // Checks no value is missing in the stored configuration
1267         foreach($notice_default as $notice_name => $notice_value) {
1268                 if(!isset($notice_conf[$notice_name]) || empty($notice_conf[$notice_name]))
1269                         $notice_conf[$notice_name] = $notice_default[$notice_name];
1270         }
1271         
1272         return $notice_conf;
1273 }
1274
1275 // The function to get the admin users
1276 function getUsers() {
1277         // Try to read the XML file
1278         $data = readXML('conf', 'users');
1279         $array = array();
1280         
1281         // Any data?
1282         if($data) {
1283                 $read = new SimpleXMLElement($data);
1284                 
1285                 // Check the submitted user exists
1286                 foreach($read->children() as $child) {
1287                         // Get the node attributes
1288                         $attributes = $child->attributes();
1289                         
1290                         // Push the attributes to the global array (converted into strings)
1291                         $array[$attributes['name'].''] = $attributes['password'].'';
1292                 }
1293         }
1294         
1295         return $array;
1296 }
1297
1298 // Manages users
1299 function manageUsers($action, $array) {
1300         // Try to read the old XML file
1301         $users_array = getUsers();
1302         
1303         // What must we do?
1304         switch($action) {
1305                 // Add some users
1306                 case 'add':
1307                         foreach($array as $array_user => $array_password)
1308                                 $users_array[$array_user] = genStrongHash($array_password);
1309                         
1310                         break;
1311                 
1312                 // Remove some users
1313                 case 'remove':
1314                         foreach($array as $array_user) {
1315                                 // Not the last user?
1316                                 if(count($users_array) > 1)
1317                                         unset($users_array[$array_user]);
1318                         }
1319                         
1320                         break;
1321         }
1322         
1323         // Regenerate the XML
1324         $users_xml = '';
1325         
1326         foreach($users_array as $users_name => $users_password)
1327                 $users_xml .= "\n".'    <user name="'.stripslashes(htmlspecialchars($users_name)).'" password="'.stripslashes($users_password).'" />';
1328         
1329         // Write the main configuration
1330         writeXML('conf', 'users', $users_xml);
1331 }
1332
1333 // Resize an image with GD
1334 function resizeImage($path, $ext, $width, $height) {
1335         // No GD?
1336         if(!function_exists('gd_info'))
1337                 return false;
1338         
1339         try {
1340                 // Initialize GD
1341                 switch($ext) {
1342                         case 'png':
1343                                 $img_resize = imagecreatefrompng($path);
1344                                 
1345                                 break;
1346                         
1347                         case 'gif':
1348                                 $img_resize = imagecreatefromgif($path);
1349                                 
1350                                 break;
1351                         
1352                         default:
1353                                 $img_resize = imagecreatefromjpeg($path);
1354                 }
1355                 
1356                 // Get the image size
1357                 $img_size = getimagesize($path);
1358                 $img_width = $img_size[0];
1359                 $img_height = $img_size[1];
1360         
1361                 // Necessary to change the image width
1362                 if($img_width > $width && ($img_width > $img_height)) {
1363                         // Process the new sizes
1364                         $new_width = $width;
1365                         $img_process = (($new_width * 100) / $img_width);
1366                         $new_height = (($img_height * $img_process) / 100);
1367                 }
1368         
1369                 // Necessary to change the image height
1370                 else if($img_height > $height && ($img_width < $img_height)) {
1371                         // Process the new sizes
1372                         $new_height = $height;
1373                         $img_process = (($new_height * 100) / $img_height);
1374                         $new_width = (($img_width * $img_process) / 100);
1375                 }
1376         
1377                 // Else, just use the old sizes
1378                 else {
1379                         $new_width = $img_width;
1380                         $new_height = $img_height;
1381                 }
1382         
1383                 // Create the new image
1384                 $new_img = imagecreatetruecolor($new_width, $new_height);
1385                 
1386                 // Must keep alpha pixels?
1387                 if(($ext == 'png') || ($ext == 'gif')){
1388                         imagealphablending($new_img, false);
1389                         imagesavealpha($new_img, true);
1390                         
1391                         // Set transparent pixels
1392                         $transparent = imagecolorallocatealpha($new_img, 255, 255, 255, 127);
1393                         imagefilledrectangle($new_img, 0, 0, $new_width, $new_height, $transparent);
1394                 }
1395                 
1396                 // Copy the new image
1397                 imagecopyresampled($new_img, $img_resize, 0, 0, 0, 0, $new_width, $new_height, $img_size[0], $img_size[1]);
1398         
1399                 // Destroy the old data
1400                 imagedestroy($img_resize);
1401                 unlink($path);
1402         
1403                 // Write the new image
1404                 switch($ext) {
1405                         case 'png':
1406                                 imagepng($new_img, $path);
1407                                 
1408                                 break;
1409                         
1410                         case 'gif':
1411                                 imagegif($new_img, $path);
1412                                 
1413                                 break;
1414                         
1415                         default:
1416                                 imagejpeg($new_img, $path, 85);
1417                 }
1418                 
1419                 return true;
1420         }
1421         
1422         catch(Exception $e) {
1423                 return false;
1424         }
1425 }
1426
1427 ?>