5 Jappix - An open social platform
6 These are the PHP functions for Jappix
8 -------------------------------------------------
11 Authors: Vanaryon, LinkMauve, Mathieui, olivierm
12 Last revision: 16/01/12
16 // The function to check if Jappix is already installed
17 function isInstalled() {
18 if(!file_exists(JAPPIX_BASE.'/store/conf/installed.xml'))
24 // The function to check if a static host is defined
25 function hasStatic() {
26 if(HOST_STATIC && (HOST_STATIC != '.'))
32 // The function to check if this is a static server
34 if(hasStatic() && (parse_url(HOST_STATIC, PHP_URL_HOST) == $_SERVER['HTTP_HOST']))
40 // The function to check if this is an upload server
42 if(HOST_UPLOAD && (parse_url(HOST_UPLOAD, PHP_URL_HOST) == $_SERVER['HTTP_HOST']))
48 // The function to get the users.xml file hashed name
49 function usersConfName() {
50 $conf_dir = JAPPIX_BASE.'/store/conf';
53 if(!is_dir($conf_dir))
56 // Read the conf folder
57 $conf_scan = scandir($conf_dir.'/');
61 foreach($conf_scan as $current) {
62 if(preg_match('/(.+)(\.users\.xml)($)/', $current)) {
63 $conf_name = $current;
69 // Return the users file name
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';
79 // Secured stored file?
80 if(($type == 'conf') && ($xmlns == 'users')) {
81 // Get the secured file name
82 $conf_secured = usersConfName();
84 // Does this file exist?
86 $conf_name = $conf_secured;
88 $conf_name = hash('sha256', rand(1, 99999999).time()).'.users.xml';
91 // Generate the file complete path
92 $conf_file = $conf_path.$conf_name;
94 // Write the installed marker
95 $gen_xml = '<?xml version="1.0" encoding="utf-8" ?>
96 <jappix xmlns="jappix:'.$type.':'.$xmlns.'">
100 file_put_contents($conf_file, $gen_xml);
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';
111 // Secured stored file?
112 if(($type == 'conf') && ($xmlns == 'users')) {
113 // Get the secured file name
114 $conf_secured = usersConfName();
116 // Does this file exist?
118 $conf_name = $conf_secured;
121 // Generate the file complete path
122 $conf_file = $conf_path.$conf_name;
124 if(file_exists($conf_file))
125 return file_get_contents($conf_file);
130 // The function to read remote URLs
131 function read_url($url) {
133 if(function_exists('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);
144 $data = @file_get_contents($url);
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);
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';
165 if($defined_lang == 'en')
168 $lang_found = file_exists($lang_file);
170 // We check if the asked translation exists
172 $lang = $defined_lang;
175 setcookie('jappix_locale', $lang, (time() + 31536000));
181 // No language has been defined, but a cookie is stored
182 if(isset($_COOKIE['jappix_locale'])) {
183 $check_cookie = $_COOKIE['jappix_locale'];
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;
190 // No cookie defined (or an unsupported value), naturally, we check the browser language
191 if(!isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
194 // We get the language of the browser
195 $nav_langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
196 $check_en = strtolower($nav_langs[0]);
198 // We check if this is not english
199 if($check_en == 'en')
204 foreach($nav_langs as $entry) {
205 $indice = explode('=', $entry);
206 $lang = strtolower(substr(trim($indice[0]), 0, 2));
208 if(!isset($indice[1]) || !$indice[1])
211 $indice = $indice[1];
213 $order[$lang] = $indice;
218 foreach($order as $nav_lang => $val) {
219 $lang_found = file_exists(JAPPIX_BASE.'/lang/'.$nav_lang.'/LC_MESSAGES/main.mo');
225 // If Jappix doen't know that language, we include the english translation
229 // The function to convert a ISO language code to its full name
230 function getLanguageName($code) {
231 $code = strtolower($code);
245 'az' => 'Azərbaycan dili',
246 'ba' => 'башҡорт теле',
247 'be' => 'Беларуская',
251 'bm' => 'Bamanankan',
255 'bs' => 'Bosanski jezik',
257 'ce' => 'нохчийн мотт',
262 'cu' => 'Словѣньскъ',
263 'cv' => 'чӑваш чӗлхи',
274 'et' => 'Eesti keel',
278 'fi' => 'Suomen kieli',
279 'fj' => 'Vosa Vakaviti',
294 'ht' => 'Kreyòl ayisyen',
297 'hz' => 'Otjiherero',
298 'ia' => 'Interlingua',
300 'ie' => 'Interlingue',
314 'kk' => 'Қазақ тілі',
315 'kl' => 'Kalaallisut',
324 'ky' => 'кыргыз тили',
326 'lb' => 'Lëtzebuergesch',
331 'lt' => 'Lietuvių kalba',
333 'lv' => 'Latviešu valoda',
334 'mg' => 'Fiteny malagasy',
335 'mh' => 'Kajin M̧ajeļ',
336 'mi' => 'Te reo Māori',
337 'mk' => 'македонски јазик',
340 'mo' => 'лимба молдовеняскэ',
342 'ms' => 'Bahasa Melayu',
345 'na' => 'Ekakairũ Naoero',
346 'nb' => 'Norsk bokmål',
347 'nd' => 'isiNdebele',
350 'nl' => 'Nederlands',
351 'nn' => 'Norsk nynorsk',
354 'nv' => 'Diné bizaad',
358 'om' => 'Afaan Oromoo',
360 'os' => 'Ирон æвзаг',
366 'pt-br' => 'Brasileiro',
368 'rm' => 'Rumantsch grischun',
372 'rw' => 'Kinyarwanda',
376 'se' => 'Davvisámegiella',
377 'sg' => 'Yângâ tî sängö',
378 'sh' => 'Српскохрватски',
380 'sk' => 'Slovenčina',
381 'sl' => 'Slovenščina',
382 'sm' => 'Gagana fa\'a Samoa',
384 'so' => 'Soomaaliga',
386 'sr' => 'српски језик',
389 'su' => 'Basa Sunda',
400 'to' => 'faka Tonga',
405 'ty' => 'Reo Mā`ohi',
407 'uk' => 'українська',
411 'vi' => 'Tiếng Việt',
423 if(isset($known[$code]))
424 return $known[$code];
429 // The function to know if a language is right-to-left
430 function isRTL($code) {
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="';
456 // Set the good text direction (TODO)
457 /* if(isRTL($locale))
470 // The function which generates the available locales list
471 function availableLocales($active_locale) {
473 $scan = scandir(JAPPIX_BASE.'/lang/');
476 // Loop the available languages
477 foreach($scan as $current_id) {
478 // Get the current language name
479 $current_name = getLanguageName($current_id);
482 if(($current_id == $active_locale) || ($current_name == null))
485 // Add this to the list
486 $list[$current_id] = $current_name;
492 // The function which generates the language switcher hidden part
493 function languageSwitcher($active_locale) {
495 $keep_get = keepGet('l', false);
496 $list = availableLocales($active_locale);
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>, ';
503 // Output the HTML code
507 // The function to generate a strong hash
508 function genStrongHash($string) {
512 // Loop to generate a incredibly strong hash (can be a bit slow)
514 $string = hash('sha256', $string);
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/';
531 // Get the hash of the main configuration file
532 if(file_exists($conf_main))
533 $hash_main = md5_file($conf_main);
537 // Get the hash of the main configuration file
538 if(file_exists($conf_hosts))
539 $hash_hosts = md5_file($conf_hosts);
543 // Get the hash of the background configuration file
544 if(file_exists($conf_background))
545 $hash_background = md5_file($conf_background);
547 $hash_background = '0';
549 // Get the hash of the logos folder
552 if(is_dir($logos_dir)) {
553 $logos_scan = scandir($logos_dir.'/');
555 foreach($logos_scan as $logos_current) {
556 if(getFileExt($logos_current) == 'png')
557 $hash_logos .= md5_file($logos_dir.$logos_current);
561 return md5($version.$hash_main.$hash_hosts.$hash_background.$hash_logos);
564 // The function to hide the error messages
565 function hideErrors() {
566 // Hide errors if not developer
568 ini_set('display_errors', 'off');
569 ini_set('error_reporting', 0);
572 // Developers need to get error reports!
574 ini_set('display_errors', 'on');
575 ini_set('error_reporting', E_ALL);
579 // The function to check BOSH proxy is enabled
580 function BOSHProxy() {
581 if(BOSH_PROXY == 'on')
587 // The function to check compression is enabled
588 function hasCompression() {
589 if(COMPRESSION != 'off')
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')))
604 // The function to check whether to show manager link or not
605 function showManagerLink() {
606 if(MANAGER_LINK != 'off')
612 // The function to check HTTPS storage is allowed
613 function httpsStorage() {
614 if(HTTPS_STORAGE == 'on')
620 // The function to check HTTPS storage must be forced
621 function httpsForce() {
622 if((HTTPS_FORCE == 'on') && sslCheck())
628 // The function to check we use HTTPS
629 function useHttps() {
630 if(isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on'))
636 // The function to compress the output pages
637 function compressThis() {
638 if(canCompress() && !isDeveloper())
639 ob_start('ob_gzhandler');
642 // The function to choose one file get with get.php or a liste of resources
643 function multiFiles() {
644 if(MULTI_FILES == 'on')
650 function getFiles($h, $l, $t, $g, $f) {
651 // Define the good path to the Get API
653 $path_to = HOST_STATIC.'/';
655 $path_to = JAPPIX_BASE.'/';
670 return $path_to.'php/get.php?'.implode('&', $values);
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);
678 $xml_read = new SimpleXMLElement($xml_data);
679 $xml_parse = $xml_read->$t;
681 // Files were added to the list before (with file var)?
683 $f .= '~'.$xml_parse;
689 // Explode the f string
690 if(strpos($f, '~') != false)
691 $array = explode('~', $f);
696 foreach($array as $file)
697 $a[] = $path_to.$t.'/'.$file;
705 function echoGetFiles($h, $l, $t, $g, $f) {
707 $pattern = '<link rel="stylesheet" href="%s" type="text/css" media="all" />';
709 $pattern = '<script type="text/javascript" src="%s"></script>';
711 $files = getFiles($h, $l, $t, $g, $f);
713 if (is_string($files))
714 printf($pattern, $files);
716 $c = count($files)-1;
717 for($i=0; $i<=$c; $i++) {
720 printf($pattern, $files[$i]);
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'))
735 // The function to quickly translate a string
736 function _e($string) {
737 echo T_gettext($string);
740 // The function to check the encrypted mode
741 function sslCheck() {
742 if(ENCRYPTION == 'on')
748 // The function to return the encrypted link
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>';
756 $link = '<a class="home-images encrypted" href="https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'">'.T_('Encrypted').'</a>';
761 // The function to get the Jappix static URL
762 function staticURL() {
764 $protocol = isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
767 $url = $protocol.'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
772 // The function to get the Jappix location (only from Get API!)
773 function staticLocation() {
775 return preg_replace('/((.+)\/)php\/get\.php(\S)+$/', '$1', staticURL());
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);
786 // The function to check the cache presence
787 function hasCache($hash) {
788 if(file_exists(JAPPIX_BASE.'/store/cache/'.$hash.'.cache'))
794 // The function to check if developer mode is enabled
795 function isDeveloper() {
796 if(DEVELOPER == 'on')
802 // The function to get a file extension
803 function getFileExt($name) {
804 return strtolower(preg_replace('/^(.+)(\.)([^\.]+)$/i', '$3', $name));
807 // The function to get a file type
808 function getFileType($ext) {
820 $file_type = 'image';
843 $file_type = 'video';
871 $file_type = 'audio';
912 $file_type = 'document';
939 $file_type = 'package';
945 $file_type = 'other';
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);
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'];
967 if(strrpos($request, '?') === false)
971 $uri = explode('?', $request);
975 // Remove the items we don't want here
976 $proper = str_replace('&', '&', $get);
977 $proper = preg_replace('/((^)|(&))(('.$current.'=)([^&]+))/i', '', $proper);
979 // Nothing at the end?
983 // We have no defined GET var
985 // Remove the first "&" if it appears
986 if(preg_match('/^(&(amp;)?)/i', $proper))
987 $proper = preg_replace('/^(&(amp;)?)/i', '', $proper);
990 $proper = '?'.$proper;
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) != '&'))
995 $proper = '&'.$proper;
1000 // Escapes regex special characters for in-regex usage
1001 function escapeRegex($string) {
1002 return preg_replace('/[-[\]{}()*+?.,\\^$|#]/', '\\$&', $string);
1005 // Generates the security HTML code
1006 function securityHTML() {
1007 return '<!DOCTYPE html>
1008 <html xmlns="http://www.w3.org/1999/xhtml">
1011 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
1012 <title>Jappix - Forbidden</title>
1017 <h4>This is a private folder</h4>
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))
1032 // Set the good unity for a size in bytes
1033 function formatBytes($bytes, $precision = 2) {
1034 $units = array('B', 'KB', 'MB', 'GB', 'TB');
1036 $bytes = max($bytes, 0);
1037 $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
1038 $pow = min($pow, count($units) - 1);
1040 $bytes /= pow(1024, $pow);
1042 return round($bytes, $precision) . ' ' . $units[$pow];
1045 // Converts a human-readable bytes value to a computer one
1046 function humanToBytes($string) {
1052 'T' => '000000000000',
1053 'P' => '000000000000000',
1054 'E' => '000000000000000000',
1055 'Z' => '000000000000000000000',
1056 'Y' => '000000000000000000000000'
1059 // Filter the string
1060 foreach($values as $key => $zero)
1061 $string = str_replace($key, $zero, $string);
1063 // Converts the string into an integer
1064 $string = intval($string);
1069 // Get the maximum file upload size
1070 function uploadMaxSize() {
1071 // Not allowed to upload files?
1072 if(ini_get('file_uploads') != 1)
1075 // Upload maximum file size
1076 $upload = humanToBytes(ini_get('upload_max_filesize'));
1078 // POST maximum size
1079 $post = humanToBytes(ini_get('post_max_size'));
1081 // Return the lowest value
1082 if($upload <= $post)
1088 // Normalizes special chars
1089 function normalizeChars($string) {
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'
1101 return strtr($string, $table);
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);
1109 // Encodes with HTML special chars
1110 $string = htmlspecialchars($string);
1115 // Writes the current visit in the total file
1116 function writeTotalVisit() {
1117 // Get the current time stamp
1120 // Initialize the defaults
1126 // Try to read the saved data
1127 $total_data = readXML('access', 'total');
1129 // Get the XML file values
1131 // Initialize the visits reading
1132 $read_xml = new SimpleXMLElement($total_data);
1134 // Loop the visit elements
1135 foreach($read_xml->children() as $current_child)
1136 $array[$current_child->getName()] = intval($current_child);
1139 // Increment the total number of visits
1142 // Generate the new XML data
1144 '<total>'.$array['total'].'</total>
1145 <stamp>'.$array['stamp'].'</stamp>'
1148 // Re-write the new values
1149 writeXML('access', 'total', $total_xml);
1152 // Writes the current visit in the months file
1153 function writeMonthsVisit() {
1154 // Get the current month
1155 $month = intval(date('m'));
1157 // Define the stats array
1160 // January to August period
1162 for($i = 1; $i <= 8; $i++)
1163 $array['month_'.$i] = 0;
1166 // August to September period
1173 if(($i >= 8) && ($i <= 12))
1174 $array['month_'.$i++] = 0;
1176 // First year months
1178 $array['month_'.$j++] = 0;
1182 // Try to read the saved data
1183 $months_data = readXML('access', 'months');
1185 // Get the XML file values
1187 // Initialize the visits reading
1188 $read_xml = new SimpleXMLElement($months_data);
1190 // Loop the visit elements
1191 foreach($read_xml->children() as $current_child) {
1192 $current_month = $current_child->getName();
1194 // Parse the current month id
1195 $current_id = intval(preg_replace('/month_([0-9]+)/i', '$1', $current_month));
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);
1203 // Increment the current month value
1204 $array['month_'.$month]++;
1206 // Generate the new XML data
1209 foreach($array as $array_key => $array_value)
1210 $months_xml .= "\n".' <'.$array_key.'>'.$array_value.'</'.$array_key.'>';
1212 // Re-write the new values
1213 writeXML('access', 'months', $months_xml);
1216 // Writes the current visit to the storage file
1217 function writeVisit() {
1218 // Write total visits
1221 // Write months visits
1225 // Returns the default background array
1226 function defaultBackground() {
1227 // Define the default values
1228 $background_default = array(
1229 'type' => 'default',
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'
1239 return $background_default;
1242 // Reads the notice configuration
1243 function readNotice() {
1244 // Read the notice configuration XML
1245 $notice_data = readXML('conf', 'notice');
1247 // Define the default values
1248 $notice_default = array(
1253 // Stored data array
1254 $notice_conf = array();
1256 // Read the stored values
1258 // Initialize the notice configuration XML data
1259 $notice_xml = new SimpleXMLElement($notice_data);
1261 // Loop the notice configuration elements
1262 foreach($notice_xml->children() as $notice_child)
1263 $notice_conf[$notice_child->getName()] = utf8_decode($notice_child);
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];
1272 return $notice_conf;
1275 // The function to get the admin users
1276 function getUsers() {
1277 // Try to read the XML file
1278 $data = readXML('conf', 'users');
1283 $read = new SimpleXMLElement($data);
1285 // Check the submitted user exists
1286 foreach($read->children() as $child) {
1287 // Get the node attributes
1288 $attributes = $child->attributes();
1290 // Push the attributes to the global array (converted into strings)
1291 $array[$attributes['name'].''] = $attributes['password'].'';
1299 function manageUsers($action, $array) {
1300 // Try to read the old XML file
1301 $users_array = getUsers();
1307 foreach($array as $array_user => $array_password)
1308 $users_array[$array_user] = genStrongHash($array_password);
1312 // Remove some users
1314 foreach($array as $array_user) {
1315 // Not the last user?
1316 if(count($users_array) > 1)
1317 unset($users_array[$array_user]);
1323 // Regenerate the XML
1326 foreach($users_array as $users_name => $users_password)
1327 $users_xml .= "\n".' <user name="'.stripslashes(htmlspecialchars($users_name)).'" password="'.stripslashes($users_password).'" />';
1329 // Write the main configuration
1330 writeXML('conf', 'users', $users_xml);
1333 // Resize an image with GD
1334 function resizeImage($path, $ext, $width, $height) {
1336 if(!function_exists('gd_info'))
1343 $img_resize = imagecreatefrompng($path);
1348 $img_resize = imagecreatefromgif($path);
1353 $img_resize = imagecreatefromjpeg($path);
1356 // Get the image size
1357 $img_size = getimagesize($path);
1358 $img_width = $img_size[0];
1359 $img_height = $img_size[1];
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);
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);
1377 // Else, just use the old sizes
1379 $new_width = $img_width;
1380 $new_height = $img_height;
1383 // Create the new image
1384 $new_img = imagecreatetruecolor($new_width, $new_height);
1386 // Must keep alpha pixels?
1387 if(($ext == 'png') || ($ext == 'gif')){
1388 imagealphablending($new_img, false);
1389 imagesavealpha($new_img, true);
1391 // Set transparent pixels
1392 $transparent = imagecolorallocatealpha($new_img, 255, 255, 255, 127);
1393 imagefilledrectangle($new_img, 0, 0, $new_width, $new_height, $transparent);
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]);
1399 // Destroy the old data
1400 imagedestroy($img_resize);
1403 // Write the new image
1406 imagepng($new_img, $path);
1411 imagegif($new_img, $path);
1416 imagejpeg($new_img, $path, 85);
1422 catch(Exception $e) {