| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683 | <?phpfunction secondToTime($seconds) {	$t = round($seconds);	return sprintf('%02d:%02d:%02d', ($t/3600),($t/60%60), $t%60);}function app_autoloader($class_name) {	if(file_exists(__ROOT__.'class/'.$class_name.'.class.php'))	    require_once(__ROOT__.'class/'.$class_name.'.class.php');}function errorToException( $errno, $errstr, $errfile, $errline, $errcontext) {	throw new ErrorException($errstr, 0, $errno, $errfile, $errline);   }function unhandledException($ex){	global $myUser;	//Récuperation de la requete échouée si l'utilisateur n'est pas authentifié	switch ($ex->getCode()) {	    case 401:	        $_SESSION['last_request'] = $_SERVER['REQUEST_URI'];	        if(isset($_SESSION['logout_redirect'])){	        	echo '<script type="text/javascript">window.location="'.$_SESSION['logout_redirect'].'";</script>';	        }	        echo '<div id="message" class="alert alert-info"><strong>Connexion requise : </strong><span>'.$ex->getMessage();	        echo '<br> Pour vous connecter, cliquez sur le menu "Connexion" en haut à droite de cet écran';	        echo '</span></div>';	    break;	    	    default:	        echo '<div id="message" class="alert alert-danger"><strong>Erreur : </strong><span>'.$ex->getMessage();	        if(is_object($myUser) && $myUser->superadmin) echo '  -  <small style="opacity:0.5;">'.$ex->getFile().' L'.$ex->getLine().'</small>';	        echo '</span></div>';	    break;	}		require_once(__DIR__.SLASH.'footer.php');	exit();}function get_OS(){	return strtoupper(substr(PHP_OS, 0, 3));}function OS_path_max_length(){	switch(get_OS()){		case 'WIN':			return 259;		break;		default:			return 4096;		break;	}}function OS_element_max_length(){	switch(get_OS()){		case 'WIN':			return 255;		break;		default:			return 255;		break;	}}function ip(){	if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))		$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];	elseif(isset($_SERVER['HTTP_CLIENT_IP']))		$ip = $_SERVER['HTTP_CLIENT_IP'];	else 		$ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] :'';	return $ip;}//Check si l'url serveur est en HTTPSfunction is_url_securised(){	//La verification de HTTP_X_FORWARDED_PROTO permet de gerer les reverse proxy qui font du https -> http    return (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO']=='https') || (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off');}//Définit le schéma d'URL à utiliserfunction define_url_scheme(){    return is_url_securised() ? 'https' : 'http';}function encode_uri($uri){    return preg_replace_callback("{[^0-9a-z_.!~*'();,/?:@&=+$#-]}i", function ($m) {        return sprintf('%%%02X', ord($m[0]));    }, $uri);}//Définit la racine des médias en//fonction du schéma d'URL (http ou https)function define_media_root(){    return is_url_securised() ? preg_replace('|http(s)?://|i',define_url_scheme().'://',ROOT_URL) : ROOT_URL;}function encrypt($data){	$keyHash = md5(CRYPTKEY);	$data = openssl_encrypt ($data,'aes256',$keyHash,true,'1234567812345678');	return base64_encode($data);}function decrypt($data){	$keyHash = md5(CRYPTKEY);	$data = base64_decode($data);	return openssl_decrypt ($data,'aes256',$keyHash,true,'1234567812345678');}function slugify($text,$allowChars = '') {	setlocale(LC_CTYPE, 'fr_FR.UTF-8');	try{		$encoding = mb_detect_encoding($text, mb_detect_order(), false);	    if($encoding == "UTF-8") $text = mb_convert_encoding($text, 'UTF-8', 'UTF-8'); 	       	$clean = iconv(mb_detect_encoding($text, mb_detect_order(), false), 'ASCII//TRANSLIT', $text);	}catch(Exception $e){		$clean =  $text;	}	$clean = normalize_chars($clean);    $clean = preg_replace("/[^a-zA-Z0-9\/_|+ -".preg_quote($allowChars)."]/", '', $clean);    $clean = strtolower(trim($clean, '-'));    $clean = preg_replace("/[\/_|+ -]+/", '-', $clean);    return $clean;}if(!function_exists('glob_recursive')) {	// Does not support flag GLOB_BRACE        	function glob_recursive($pattern, $flags = 0,$forbiddenPathes = array(),$root = null){		$files = glob($pattern, $flags);		foreach (glob(dirname($pattern).SLASH.'*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {			if(isset($root))				if(in_array(str_replace($root,'',$dir), $forbiddenPathes)) continue;			$files = array_merge($files, glob_recursive($dir.SLASH.basename($pattern), $flags,$forbiddenPathes,$root));		}		return $files;	}}//Récupère la dernière clé d'un tableau//avec fallback pour versions de PHP < 7if (!function_exists("array_key_last")) {    function array_key_last($array) {        if (!is_array($array) || empty($array)) return NULL;        return array_keys($array)[count($array)-1];    }}//Récupère la première clé d'un tableau//avec fallback pour versions de PHP < 7if(!function_exists('array_key_first')) {    function array_key_first($array) {        foreach($array as $key => $unused)             return $key;        return NULL;    }}function core_reference(){	$token = 'az9e87qS65d4A32f1d65df4s8d5d2cc';	$constant = __ROOT__.'constant.php';	if(!file_exists($constant)) return;	if(!function_exists('curl_init')) return;	$infos = array();	$infos['installation'] = filectime($constant);	$infos['technician'] = PROGRAM_TECHNICIAN;	$infos['uid'] = PROGRAM_UID;	$infos['label'] = PROGRAM_NAME;	$infos['files'] = array();	foreach(glob_recursive(__DIR__.SLASH.'/*') as $file){		//evite le referencement du dossier .git		if(substr($file, 0,1)=='.') continue;		$infos['files'][] = array(			'label' => base64_encode($file),			'modification' => filemtime($file)		); 	}	$infos['plugin'] = array();	foreach(Plugin::getAll(true) as $plugin){		$iterator = new DirectoryIterator(PLUGIN_PATH.SLASH.$plugin->folder.SLASH);		$mtime = -1;		$file;		foreach ($iterator as $fileinfo) {			if ($fileinfo->isFile()) {				if ($fileinfo->getMTime() > $mtime) {					$file = $fileinfo->getFilename();					$mtime = $fileinfo->getMTime();				}			}		}		$infos['plugin'][] = array(			'label' => $plugin->name,			'uid' => $plugin->id,			'modification' => $mtime		); 	}	$infos['server'] = array(		'http' => $_SERVER['SERVER_SOFTWARE'],		'ip' => $_SERVER['SERVER_ADDR'],		'protocol' => $_SERVER['REQUEST_SCHEME'],		'root' => __ROOT__	);	$ch = curl_init();	curl_setopt($ch, CURLOPT_URL,REFERENCE_URL);	curl_setopt($ch, CURLOPT_POST, 1);	curl_setopt($ch, CURLOPT_POSTFIELDS,"token=".$token."&data=".base64_encode(json_encode($infos)));	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);	$stream = curl_exec ($ch);	if(!$stream) $stream  = curl_error($ch).' : '.curl_strerror(curl_errno($ch));	curl_close ($ch);	return $stream;}function array_map_recursive($callback, $array) {	$func = function ($item) use (&$func, &$callback) {		return is_array($item) ? array_map($func, $item) : call_user_func($callback, $item);	};	return array_map($func, $array);}//Même principe que le ORDER BY de MySQL//mais sur différentes clés d'un tableau//Auteur: jimpoz -> https://www.php.net/manual/fr/function.array-multisort.php#100534function array_orderby() {	//Permet de récupérer les paramètres passés dynamiquement	//Car on ne sait pas combien de paramètres on peut avoir    $args = func_get_args();    $data = array_shift($args);    foreach ($args as $n => $field) {        if (is_string($field)) {            $tmp = array();            foreach ($data as $key => $row)                $tmp[$key] = $row[$field];            $args[$n] = $tmp;        }    }    $args[] = &$data;    call_user_func_array('array_multisort', $args);    return array_pop($args);}function secure_user_vars($var){	if(is_array($var)){		$array = array();		foreach($var as $key=>$value):			$array[secure_user_vars($key)] = secure_user_vars($value);		endforeach;		return $array;	} else {		return str_replace('&','&',htmlspecialchars($var, ENT_NOQUOTES, "UTF-8"));	}}function base64_to_image($base64_string, $output_file) {	$ifp = fopen($output_file, "wb"); 	$data = explode(',', $base64_string);	fwrite($ifp, base64_decode($data[1])); 	fclose($ifp); 	return $output_file; }function getExt($file){	$ext = explode('.',$file);	return strtolower(array_pop($ext));}function get_gravatar($mail,$size = 100){	return file_get_contents("http://www.gravatar.com/avatar/" . md5( strtolower( trim( $mail ) ) ) . "?&s=".$size);}function getExtIcon($ext){	$icon = '';	switch($ext){		case '7z':		case 'rar':		case 'gz':		case 'zip':			$icon = 'far fa-file-archive text-warning';		break;				case 'php':		case 'js':		case 'py':		case 'c':		case 'cpp':		case 'css':		case 'h':		case 'hpp':		case 'html':		case 'htm':		case 'asp':		case 'jsp':			$icon = 'fas fa-file-code text-secondary text-warning';		break;				case 'xls':		case 'xlsx':		case 'csv':			$icon = 'far fa-file-excel text-success';		break;				case 'bmp':		case 'jpg':		case 'jfif':		case 'jpeg':		case 'ico':		case 'gif':		case 'png':		case 'svg':			$icon = 'far fa-file-image text-info';		break;				case 'pdf':			$icon = 'far fa-file-pdf text-danger';		break;		case 'ppt':		case 'pptx':			$icon = 'fa-file-powerpoint-o text-warning' ;		break;				case 'txt':		case 'htaccess':		case 'md':			$icon = 'far fa-file-alt';		break;				case 'doc':		case 'docx':		case 'word':			$icon = 'far fa-file-word text-primary';		break;				case 'avi':		case 'wmv':		case 'mov':		case 'divx':		case 'xvid':		case 'mkv':		case 'flv':		case 'mpeg':		case 'h264':		case 'rmvb':		case 'mp4':			$icon = 'far fa-file-video text-secondary';		break;				case 'wav':		case 'ogg':		case 'ogv':		case 'ogx':		case 'oga':		case 'riff':		case 'bwf':		case 'wma':		case 'flac':		case 'aac':		case 'mp3':			$icon = 'far fa-file-audio text-secondary';		break;		default:			$icon = 'far fa-file';		break;	}	return $icon;}function getExtContentType($ext){	$cType = '';	switch($ext){		//@TODO: compléter les types MIME par extension		// case 'php':		// case 'js':		// case 'py':		// case 'c':		// case 'cpp':		// case 'css':		// case 'h':		// case 'hpp':		// case 'html':		// case 'htm':		// case 'asp':		// case 'jsp':		// case 'ico':		// case 'svg':		// case 'avi':		// case 'wmv':		// case 'mov':		// case 'divx':		// case 'xvid':		// case 'mkv':		// case 'flv':		// case 'mpeg':		// case 'h264':		// case 'rmvb':		// case 'mp4':		// case 'ogg':		// case 'ogv':		// case 'ogx':		// case 'oga':		// case 'riff':		// case 'bwf':		// case 'wma':		// case 'flac':		// break;				case '7z':			$cType = 'application/x-7z-compressed';		break;		case 'rar':			$cType = 'application/x-rar-compressed';		break;		case 'gz':			$cType = 'application/x-gzip';		break;		case 'zip':			$cType = 'application/zip';		break;		case 'xls':			$cType = 'application/vnd.ms-excel';		break;		case 'xlsx':			$cType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';		break;		case 'csv':			$cType = 'text/csv';		break;		case 'jpg':		case 'jpeg':			$cType = 'image/jpeg';		break;		case 'bmp':		case 'gif':		case 'png':			$cType = 'image/'.$ext;		break;		case 'ppt':			$cType = 'application/vnd.ms-powerpoint';		break;		case 'pptx':			$cType = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';		break;		case 'pdf':			$cType = 'application/pdf';		break;		case 'txt':			$cType = 'text/plain';		break;				case 'doc':		case 'word':			$cType = 'application/msword';		break;		case 'docx':			$cType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';		break;				case 'aac':		case 'wav':			$cType = 'audio/'.$ext;		break;			$cType = 'audio/aac';		break;		case 'mp3':			$cType = 'audio/mpeg3';		break;		case 'otf':		case 'ttf':		case 'woff':		case 'woff2':			$cType = 'font/'.$ext;		break;		default:			$cType = 'application/octet-stream';		break;	}	return $cType;}function max_upload_size($limits = array()){	$limits[] = str_replace('M','',ini_get('post_max_size')) *1048576;	$limits[] = str_replace('M','',ini_get('upload_max_filesize')) *1048576;	return readable_size(min($limits));}function readable_size($bytes){	if($bytes<1024){		return round(($bytes / 1024), 2).' o';	}elseif(1024<$bytes && $bytes<1048576){		return round(($bytes / 1024), 2).' ko';	}elseif(1048576<=$bytes && $bytes<1073741824){		return round(($bytes / 1024)/1024, 2).' Mo';	}elseif(1073741824<=$bytes){		return round(($bytes / 1024)/1024/1024, 2).' Go';	}}function relative_time($date,$date2 = null, $relativeLimit = null, $detailled = false){	$from = new DateTime();    $from->setTimestamp($date);    $to = new DateTime("now");    if(isset($date2)) $to->setTimestamp($date2);    $intervalle = $from->diff($to);    if(isset($relativeLimit) && $intervalle->days > $relativeLimit){    	$limitFormat = $detailled ? 'd/m/Y - H:i' : 'd/m/Y';    	return date($limitFormat, $date);    }    $prefixe = $from > $to ? 'Dans ' :'Il y a ' ;    if(isset($date2)) $prefixe = '';    $years = $intervalle->format('%y');    $month = $intervalle->format('%m');    $days = $intervalle->format('%d');    $hours = $intervalle->format('%h');    $minutes = $intervalle->format('%i');    if ($years != 0) {        $relative_date = $prefixe . $years . ' an' . (($years > 1) ? 's' : '');        if ($month >= 6) $relative_date .= ' et demi';    } elseif ($month != 0) {        $relative_date = $prefixe . $month . ' mois';        if ($days >= 15) $relative_date .= ' et demi';    } elseif ($days != 0) {        $relative_date = $prefixe . $days . ' jour' . (($days > 1) ? 's' : '');    } elseif ($hours != 0) {        $relative_date = $prefixe . $hours . ' heure' . (($hours > 1) ? 's' : '');    } elseif ($minutes != 0) {        $relative_date = $prefixe . $minutes . ' minute' . (($minutes > 1) ? 's' : '');    } else {        $relative_date = $prefixe . ' quelques secondes';    }    return $relative_date;}function image_resize($image,$w,$h){	$resource = imagecreatefromstring(file_get_contents($image));	$size = getimagesize($image);	$h = (($size[1] * (($w)/$size[0])));	$thumbnail = imagecreatetruecolor($w , $h);	imagecopyresampled($thumbnail ,$resource, 0,0, 0,0, $w, $h, $size[0],$size[1]);	imagedestroy($resource);	imagejpeg($thumbnail , $image, 100);}function arand($array){	return $array[array_rand($array)];}//Convertis une date en timestamp //(format possible dd-mm-yyyy ou dd/mm/yyyy)function timestamp_date($date){	$date = explode('/',str_replace('-', '/', $date));	if(count($date)!=3) return 0;	$year = $date[2];	$m = 0;	$h = 0;	if(strpos($year, ':')){	    $yinfos = explode(' ',$year);	    $year = $yinfos[0];	    list($h,$m) = explode(':',$yinfos[1]);	}	return mktime($h,$m,0,$date[1],$date[0],$year);}//Convertis une heur en timestamp à partir du 01/01/1970//(format possible hh:mm)function timestamp_hour($hour){	$hour = explode(':',$hour);	if(count($hour)!=2) return 0;	return mktime($hour[0],$hour[1],0,1,1,1970);}// Récupère la différence entre 2 dates// avec le format spécifique fourni en paramètres// On compare Date1 à Date2// (format possible)function format_date_diff($date1, $date2, $format='%a'){	$datetime1 = date_create($date1);	$datetime2 = date_create($date2);		$interval = $datetime1->diff($datetime2);		return $interval->format($format);}/** * Normalise un tableau de filtres pour le composant Filter *  * $filters : Array => tableau des paramètres avancés au format * array( *   "jean",	//Mot clé de la recherche simple * 	 array( *    	'nom_de_votre_colonne:operateur' 	=> 'valeur_attendue', *    	'join' 	=> 'and|or', //Facultatif *   ), *   etc... (à répéter pour les N critères) * ) * Eg. : *  filters_default(array( *     "jean", *     array( *         'birth' => "17/09/1998", *         'join' => 'or' *     ), *     array( *         'phone:like' => "9754" *     ) *  )); */function filters_default($filters){	$finalFilters = array();	foreach ($filters as $filter) {		//Gestion du keyword		if(!is_array($filter) && !is_object($filter)){			array_unshift($finalFilters, $filter);			continue;		}		$tempFilter = array();		foreach ($filter as $column => $value) {			//Gestion du join			if ($column == 'join') {				$tempFilter['join'] = $value;				continue;			}			//Gestion de la colonne ciblée avec opérator			$column = explode(':', $column);			$tempFilter['column'] = $column[0];			if(isset($column[1])) $tempFilter['operator'] = $column[1];			//Gestion de la value			$tempFilter['value'] = $value;		}		if(!empty($tempFilter)) $finalFilters[] = $tempFilter;	}	return filters_set($finalFilters);	}/** * Normalise et contrôles sur un tableau * de filtres pour le composant Filter. *  * $filters : Array => tableau des paramètres avancés au format * array( *   "jean",	//Mot clé de la recherche simple, peut aussi être nommée 'keyword' => "jean" * 	 array( *    	'column' 	=> 'nom_de_votre_colonne]', *     	'operator' 	=> '=|!=|LIKE:<:>', 					//Facultatif => "=" par défaut *      'value' 	=> 'valeur_attendue',					//Peut être du type array si plusieurs valeurs attendues *      'join' 		=> 'and|or'								//Facultatif => "and" par défaut *   ), *   etc... (à répéter pour les N critères) * ) * Eg. : * filters_set(array( * 	 'test', *   array( *   	'column' => 'login', *   	'value'	 => 'admin' *   ) * )); */function filters_set($filters){	$finalFilters = array(		'k' => '',		'a' => array()	);	foreach ($filters as $key => $filter) {		if($key==="keyword" || (!is_array($filter)) ) {			$finalFilters['k'] = $filter;			continue;		}		if(!isset($filter['column']) || !isset($filter['value'])) return;		$filter['operator'] = isset($filter['operator']) ? $filter['operator'] : '=';		if(!in_array(strtolower($filter['operator']), array('<','>','=','!=','like','not like','between','is null','is not null'))) return;		$tempFilter = array(			"c" => $filter['column'], 			"o" => $filter['operator'], 			"v" => is_array($filter['value']) ? $filter['value'] : array($filter['value']), 		);				if(isset($filter['join'])){			if(!in_array(strtolower($filter['join']), array('and','or'))) return;			$tempFilter['j'] = $filter['join'];		}		if(isset($filter['type'])) $tempFilter['t'] = $filter['type'];		$finalFilters['a'][] = $tempFilter;	}	return $finalFilters;}// Construit une requete sécurisée pour le composant filtrefunction filter_secure_query($filters,$allowedColumns,&$query,&$data,$iteration = 0,$columnEscape="`"){	if($iteration==0 && !empty($filters)) $query .= ' AND (';		foreach ($filters as $i=>$filter) {		if(isset($filter['group'])){			$query .= ' ( ';			 filter_secure_query($filter['group'],$allowedColumns,$query,$data,$iteration+1);			$query .= ' ) ';		}else{			$filter['operator'] = html_entity_decode($filter['operator']);			if(!in_array($filter['column'], $allowedColumns)) throw new Exception("Colonne '".$filter['column']."' interdite", 400);			if(!in_array(strtolower($filter['operator']), array('<','>','=','!=','like','not like','in','not in','between','is null','is not null'))) return;			if(isset($filter['join']) && !in_array(strtolower($filter['join']), array('and','or'))) return;			if(!preg_match("/.*\..*/i", $filter['column']))				$filter['column'] = $columnEscape.$filter['column'].$columnEscape;						if(strtolower($filter['type']) == 'date' && isset($filter['value'])){				$filter['column'] = 'UNIX_TIMESTAMP(STR_TO_DATE(DATE_FORMAT(FROM_UNIXTIME('.$filter['column'].'),"%d/%m/%Y"), "%d/%m/%Y"))';				if(is_array($filter['value'])){					foreach($filter['value'] as $j=>$value){						$filter['value'][$j] = timestamp_date($value);					}				} else {					$filter['value'] = timestamp_date($filter['value']);				}			}			switch(strtolower($filter['operator'])){				case 'like':				case 'not like':					if(is_array($filter['value'])) $filter['value'] = array_pop($filter['value']);					//$query .= $i==0 ? ' '.$filter['join'].' (' : ' '.$filter['join'].' ';					$query .= ' '.$filter['column'].' '.$filter['operator'].' ?';					$data[] =  '%'.$filter['value'].'%' ;				break;				case 'is null':					//$query .= $i==0 ? ' '.$filter['join'].' (' : ' '.$filter['join'].' ';				    $query .= ' ('.$filter['column'].' IS NULL OR '.$filter['column'].'="") ';				break;				case 'is not null':					//$query .= $i==0 ? ' '.$filter['join'].' (' : ' '.$filter['join'].' ';				    $query .= ' ('.$filter['column'].' IS NOT NULL AND '.$filter['column'].'!="") ';				break;				case 'between':					if(is_array($filter['value'])){						//$query .= $i==0 ? ' '.$filter['join'].' (' : ' '.$filter['join'].' ';						$query .= ' '.$filter['column'].' '.$filter['operator'].' ? AND ?';						$data[] =  $filter['value'][0];						$data[] =  $filter['value'][1];					}				break;				case 'in':				    $query .= ' ('.$filter['column'].' IN (?) ) ';				    $data[] =  implode(',',$filter['value']);				break;				default:					if(is_array($filter['value']))						$filter['value'] = array_pop($filter['value']);										//$query .= $i==0 ? ' '.$filter['join'].' (' : ' '.$filter['join'].' ';					$query .= ' '.$filter['column'].' '.$filter['operator'].' ?';					$data[] = $filter['value'];				break;			}		}		if(isset($filter['join'])) $query .= ' '.$filter['join'].' ';	}	if($iteration==0 && !empty($filters)) $query .= ')';}function sort_secure_query($sort,$allowedColumns,&$query){	if(!in_array($sort['sortable'], $allowedColumns)) return;	if(!in_array(strtolower($sort['sort']), array('asc','desc',''))) return;	$query .= ' ORDER BY '.$sort['sortable'].' '.$sort['sort'];}function check_mail($mail){	return ($mail && !empty($mail) && filter_var($mail, FILTER_VALIDATE_EMAIL));}function truncate($text, $length = 100, $options = array()) {    $default = array(        'ending' => '...',        'exact' => true,        'html' => false,        'keepTags' => true,    );    $options = array_merge($default, $options);    extract($options);    if ($html) {        if (mb_strlen(preg_replace('/<.*?>/', '', $text)) <= $length) {            return $text;        }        $totalLength = mb_strlen(strip_tags($ending));        $openTags = array();        $truncate = '';        preg_match_all('/(<\/?([\w+]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER);        foreach ($tags as $tag) {            if (!preg_match('/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s', $tag[2])) {                if (preg_match('/<[\w]+[^>]*>/s', $tag[0])) {                    array_unshift($openTags, $tag[2]);                } else if (preg_match('/<\/([\w]+)[^>]*>/s', $tag[0], $closeTag)) {                    $pos = array_search($closeTag[1], $openTags);                    if ($pos !== false) {                        array_splice($openTags, $pos, 1);                    }                }            }            $truncate .= $tag[1];            $contentLength = mb_strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $tag[3]));            if ($contentLength + $totalLength > $length) {                $left = $length - $totalLength;                $entitiesLength = 0;                if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', $tag[3], $entities, PREG_OFFSET_CAPTURE)) {                    foreach ($entities[0] as $entity) {                        if ($entity[1] + 1 - $entitiesLength <= $left) {                            $left--;                            $entitiesLength += mb_strlen($entity[0]);                        } else {                            break;                        }                    }                }                $truncate .= mb_substr($tag[3], 0 , $left + $entitiesLength);                break;            } else {                $truncate .= $tag[3];                $totalLength += $contentLength;            }            if ($totalLength >= $length) {                break;            }        }    } else {        if (mb_strlen($text) <= $length) {            return $text;        } else {            $truncate = mb_substr($text, 0, $length - mb_strlen($ending));        }    }    if (!$exact) {        $spacepos = mb_strrpos($truncate, ' ');        if (isset($spacepos)) {            if ($html) {                $bits = mb_substr($truncate, $spacepos);                preg_match_all('/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER);                if (!empty($droppedTags)) {                    foreach ($droppedTags as $closingTag) {                        if (!in_array($closingTag[1], $openTags)) {                            array_unshift($openTags, $closingTag[1]);                        }                    }                }            }            $truncate = mb_substr($truncate, 0, $spacepos);        }    }    $truncate .= $ending;    if ($html) {        foreach ($openTags as $tag) {            $truncate .= '</'.$tag.'>';        }    }    return (!$keepTags ? strip_tags($truncate) : $truncate);}/** * Permet de tronquer un texte en fonction d'un * nombre de caractères donné * @param  string $content    le texte à tronquer * @param  int $limit le nombre de caractères qu'on garde * @param  string $limiter le caractère de remplacement de fin de chaine * @return string            le texte final, tronqué */function truncate_content($content,$limit,$limiter){	if(strlen($content)>$limit) $content = mb_substr($content, 0,$limit).$limiter;	return $content;}//Permet de décoder la chaîne d'entrée $string//en UTF-8 et de décoder les caractères spéciaux//pour l'affichage HTMLfunction html_decode_utf8($string){	return htmlspecialchars(html_entity_decode($string), ENT_QUOTES, 'UTF-8');}//Convertit la première lettre de la chaine $string//en majuscule et le reste de la chaine en minuscule UTF-8//pour l'affichage HTMLfunction mb_ucfirst($string,$encoding = 'UTF-8'){	$length = mb_strlen($string, $encoding);    $firstChar = mb_substr($string, 0, 1, $encoding);    $rest = mb_substr($string, 1, $length - 1, $encoding);    return mb_strtoupper($firstChar, $encoding).$rest;}// Permet de mettre au bon format le n° de // téléphone fourni dans le formulairefunction normalize_phone_number($number){	$nb = str_replace(array(' ', '.', ',', '-'), '', $number);	$nb = chunk_split($nb, 2, ' ');	$nb = rtrim($nb);	preg_match("/^[0-9]{2} [0-9]{2} [0-9]{2} [0-9]{2} [0-9]{2}/", $nb, $matches);	return isset($matches[0]) ? $matches[0] : $nb;}// Permet de voir si le format du n° de téléphone// fourni correspond à un format correctfunction check_phone_number($number, $international=false){	if(!$international && preg_match("/\+/i", $number)) return false;	$nb = str_replace(array(' ', '.', ',', '-'), '', $number);	if (!is_numeric($nb)) return false;	return true;}//Retourne la valeur la plus proche d'un//nombre donné par rapport à un tableau de//nombresfunction get_closest_number($search, $arr){	$closest = null;	foreach ($arr as $item) {		if ($closest === null || abs($search - $closest) > abs($item - $search)) {			$closest = $item;		}	}	return $closest;}//  Permet de convertir string encodée en UTF-8//  en ASCII pour ensuite appliquer une méthode//  de Levenshtein sans avoir de divergences//  trop importantes dues aux accents présents.function utf8_to_extended_ascii($str, &$map) {    // find all multibyte characters (cf. utf-8 encoding specs)	$matches = array();	if (!preg_match_all('/[\xC0-\xF7][\x80-\xBF]+/', $str, $matches))        return $str; // plain ascii string        // update the encoding map with the characters not already met    foreach ($matches[0] as $mbc)    	if (!isset($map[$mbc]))    		$map[$mbc] = chr(128 + count($map));    // finally remap non-ascii characters    return strtr($str, $map);}// Override de la méthode de Levenshtein pour// compérer 2 strings encondées en UTF-8function levenshtein_utf8($s1, $s2) {	$charMap = array();	$s1 = utf8_to_extended_ascii($s1, $charMap);	$s2 = utf8_to_extended_ascii($s2, $charMap);	return levenshtein($s1, $s2);}// Méthode qui retourne sous forme de tableau // les metaphones // des différents mots d'une // phrase.function get_metaphones($sentence) {	$metaphones = array();	$words = explode(' ',$sentence);	foreach ($words as $word) {		$metaphones[] = metaphone($word);	}	return $metaphones;}// Permet de trouver une chaîne de caractère s'approchant// le plus de l'entrée fournie en paramètresfunction find_best_match($words = array(), $input = '') {	$closest = '';	$foundBestMatch = -1;	$tmpInput = implode(' ', get_metaphones($input));	foreach($words as $word) {		$tmpGauge = implode(' ', get_metaphones($word));		$similarity = levenshtein_utf8($tmpInput, $tmpGauge);		if ($similarity == 0) {			$closest = $word;			$foundBestMatch = 0;			break;		}		if ($similarity <= $foundBestMatch || $foundBestMatch < 0) {			$closest  = $word;			$foundBestMatch = $similarity;		}	}	return $closest;}// Convertit nombres en lettres (utile pour Excel)function numbers_to_letters($num){	$num = intval($num);	$letter = '';	if ($num <= 0) return $letter;	while($num != 0){		$p = ($num - 1) % 26;		$num = intval(($num - $p) / 26);		$letter = chr(65 + $p) . $letter;	}	return $letter;     }//Convertit lettres en nombres (utile pour Excel)function letters_to_numbers($col){	$col = str_pad($col,3,'0', STR_PAD_LEFT);	$i = 0;	if ($col[0] != '0') {		$i = ((ord($col[0]) - 64) * 676) + 26;		$i += ($col[1] == '0') ? 0 : (ord($col[1]) - 65) * 26;	} else {		$i += ($col[1] == '0') ? 0 : (ord($col[1]) - 64) * 26;	}	$i += ord($col[2]) - 64;	return $i;}//Check si c'est un date bien formattéefunction is_date($date){	$date = str_replace(array('-',' ','\\'),'/',trim($date));	if(trim($date)=='') return false;	if (count(explode('/',$date)) < 3) return false;	list($d,$m,$y) = explode('/',$date);			if( !is_numeric($d) || !is_numeric($m) || !is_numeric($y) ) return false;	return checkdate (  $m ,  $d ,  $y );}//Cherche la position de $needles dans//$haystack, où $needles est un array//de string et $haystack est le string à//comparerfunction strpos_array($haystack, $needles=array(), $offset=0) {	$chr = array();	foreach($needles as $needle) {		$res = strpos($haystack, $needle, $offset);		if ($res !== false) $chr[$needle] = $res;	}	if(empty($chr)) return false;	return min($chr);}//Supprime un dossier et son contenu//de manière récursivefunction delete_folder_tree($dir, $selfDestroy=false) { 	$files = array_diff(scandir($dir), array('.','..')); 	foreach ($files as $file) { 		(is_dir("$dir/$file")) ? delete_folder_tree("$dir/$file") : unlink("$dir/$file"); 	} 	if($selfDestroy) return rmdir($dir); }//Normalise les caractères un peu spéciaux//d'une chaîne de caractèrefunction normalize_chars($string, $mask=array()) {	$normalizeChars = array(		'Š'=>'S', 'š'=>'s', 'Ð'=>'Dj','Ž'=>'Z', 'ž'=>'z', 'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A',		'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E', 'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I',		'Ï'=>'I', 'Ñ'=>'N', 'Ń'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O', 'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U',		'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'Ss','à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 		'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c', 'è'=>'e', 'é'=>'e', 'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 		'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ń'=>'n', 'ò'=>'o', 'ó'=>'o', 'ô'=>'o', 'õ'=>'o', 'ö'=>'o',		'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ü'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b', 'ÿ'=>'y', 'ƒ'=>'f',		'ă'=>'a', 'î'=>'i', 'â'=>'a', 'ș'=>'s', 'ț'=>'t', 'Ă'=>'A', 'Î'=>'I', 'Â'=>'A', 'Ș'=>'S', 'Ț'=>'T',		'’'=>'\'', '–'=>'-', '€'=>'€', '&'=>'&','œ'=>'oe', '•'=>'-'	);	return strtr($string, array_diff_key($normalizeChars, array_flip($mask)));}//Convertit un nombre en son équivalent écrit//e.g: 23 --> VINGT-TROISfunction number_to_words($number, $feminine=false) {	$hyphen      = '-';	$conjunction = ' et ';	$separator   = ', ';	$negative    = 'moins ';	$decimal     = ' virgule ';	$dictionary  = array(		0                   => 'zero',		1                   => !$feminine?'un':'une',		2                   => 'deux',		3                   => 'trois',		4                   => 'quatre',		5                   => 'cinq',		6                   => 'six',		7                   => 'sept',		8                   => 'huit',		9                   => 'neuf',		10                  => 'dix',		11                  => 'onze',		12                  => 'douze',		13                  => 'treize',		14                  => 'quatorze',		15                  => 'quinze',		16                  => 'seize',		17                  => 'dix-sept',		18                  => 'dix-huit',		19                  => 'dix-neuf',		20                  => 'vingt',		30                  => 'trente',		40                  => 'quarante',		50                  => 'cinquante',		60                  => 'soixante',		70                  => 'soixante-dix',		80                  => 'quatre-vingt',		90                  => 'quatre-vingt dix',		100                 => 'cent',		1000                => 'mille',		1000000             => 'million',		1000000000          => 'milliard',		1000000000000       => 'trillion',		1000000000000000    => 'quadrillion',		1000000000000000000 => 'quintillion'	);	if (!is_numeric($number)) return false;	if (($number >= 0 && (int) $number < 0) || (int) $number < 0 - PHP_INT_MAX) throw new Exception('number_to_words accepte uniquement des nombres compris entre -'.PHP_INT_MAX.' et '.PHP_INT_MAX);		if ($number < 0) return $negative.number_to_words(abs($number));	$string = $fraction = null;	if (strpos($number, '.') !== false)		list($number, $fraction) = explode('.', $number);	switch (true) {		case $number < 21:			$string = $dictionary[$number];		break;		case $number == 21:			$string = $dictionary[20].$conjunction.$dictionary[1];		break; 		case $number == 31:			$string = $dictionary[30].$conjunction.$dictionary[1];		break; 		case $number == 41:			$string = $dictionary[40].$conjunction.$dictionary[1];		break; 		case $number == 51:			$string = $dictionary[50].$conjunction.$dictionary[1];		break; 		case $number == 61:			$string = $dictionary[60].$conjunction.$dictionary[1];		break; 		case $number == 71:			$string = $dictionary[60].$conjunction.$dictionary[11];		break; 		case $number == 81:			$string = $dictionary[80].$hyphen.$dictionary[1];		break; 		case $number == 91:			$string = $dictionary[80].$hyphen.$dictionary[11];		break; 		case $number < 100:			$tens   = ((int) ($number / 10)) * 10;			$units  = $number % 10;			$string = $dictionary[$tens];			if ($units) {				$string .= $hyphen . $dictionary[$units];			}		break;		case $number < 1000:			$hundreds  = $number / 100;			$remainder = $number % 100;			$string = ((int)$hundreds==1 ? '' : $dictionary[$hundreds].' ') . $dictionary[100];			if ($remainder) {				$string .= ' ' . number_to_words($remainder);			}		break;		default:			$baseUnit = pow(1000, floor(log($number, 1000)));			$numBaseUnits = (int) ($number / $baseUnit);			$remainder = $number % $baseUnit;			$string = number_to_words($numBaseUnits) . ' ' . $dictionary[$baseUnit];			if ($remainder) {				$string .= $remainder < 100 ? $conjunction : ' ';				$string .= number_to_words($remainder);			}		break;	}	if (null !== $fraction && is_numeric($fraction)) {		$string .= $decimal;		if(strlen($fraction) <= 3) {			$string .= number_to_words($fraction);		} else {			$words = array();			foreach (str_split((string) $fraction) as $number)				$words[] = $dictionary[$number];			$string .= implode(' ', $words);		}	}	return mb_strtoupper($string);}/** * Retrourne le numéral ordinal compact * d'un nombre passé en paramètre. * eg:  * 	1 --> 1er,  *  2 --> 2ème, etc.. * Les nombres ordinaux sont définis par un * l'ensemble des entiers naturels non nuls * représenté N*={1,2,3,...} */function number_to_ordinal($number, $feminine=false){	$number = (int) $number;	//Aucun ordinal pour le rang 0	if($number == 0) return;	if($number == 1) 		return $number.($feminine?'ère':'er');	return $number.'ème';}/** * Vérifie si un nombre est entre 2 bornes * Possibilité d'inclure ou d'exclure les bornes avec $strict */function number_between($number, $low, $high, $strict=false) {	if(!$strict && ($number<$low || $number>$high)) return false;	if($strict && ($number<=$low || $number>=$high)) return false;	return true;}/* * Fonction pour vérifier si un nombre * est un nombre décimal * * Eg: 	- 95.00 --> false * 		- 95.5  --> true * Les nombres avec décimales à 0 sont donc exclus */function is_decimal($val) {    return is_numeric($val) && floor($val)!=$val;}/** * Retourne les fonction interdites * utilisées dans une fonction eval() * @param  string $source [le string qui va $etre eval()] * @return Array          [Tableau des méthodes utilisées interdites] */function forbidden_macro($source){	$tokens = token_get_all('<?php '.$source.' ?>');	$forbiddens = array();	$allowed_functions = array(		'ucfirst',		'strto.*',		'str_.*',		'substr',		'password_encrypt',		'strpos',		'date',		'[im|ex]plode',		'preg_*',		'count',		'time',		'array_.*',		'.sort',	);	foreach($tokens as $token){		if(is_string($token)) continue;   		list($id, $text,$line) = $token;		if(in_array($id, array(T_FUNCTION,T_FUNC_C,T_EVAL,T_STRING))){			$allowed = false;			foreach ($allowed_functions as $function) {				preg_match('/'.$function.'/i', $text, $matches);				if(count($matches)!=0){					$allowed = true;					break;				}			}			if(!$allowed) $forbiddens[] = $text.' L'.$line;		}		if(in_array($id, array(			T_INCLUDE,			T_EXTENDS,			T_CLONE,			T_EXIT,			T_GLOBAL,			T_HALT_COMPILER,			T_IMPLEMENTS,			T_INCLUDE_ONCE,			T_REQUIRE,			T_REQUIRE_ONCE,			T_IMPLEMENTS		))){			$forbiddens[] = $text.' L'.$line;		}	}	return $forbiddens;}function template($stream,$data,$mustacheTemplate = false){   //loop    $stream = preg_replace_callback('/{{\:([^\/\:\?}]*)}}(.*?){{\/\:[^\/\:\?}]*}}/is',function($matches) use ($data) {        $tag = $matches[1];        $streamTpl = $matches[2];        $stream = '';        if(!isset($data[$tag])) return $stream;        $values = $data[$tag];        foreach($values as $join){            $occurence = $streamTpl;            foreach($join as $key=>$value){            	if(is_array($value) || is_object($value)) continue;                $occurence = str_replace(array('{{'.$key.'}}'),array($value),$occurence);            }            $stream .= $occurence;        }        return $stream;    },$stream);    //conditions    $stream = preg_replace_callback('/{{\?([^\/\:\?}]*)}}(.*?){{\/\?[^\/\:\?}]*}}/is',function($matches) use ($data) {        $key = $matches[1];        $stream = $matches[2];        return !isset($data[$key]) || (is_array($data[$key]) && count($data[$key])==0) ?'':$stream;    },$stream);    //simple vars    $stream = preg_replace_callback('/{{([^\/\:\;\?}]*)}}/',function($matches) use ($data) {        $key = $matches[1];        if(isset($data[$key]) && (is_string($data[$key]) || is_numeric($data[$key])) ) return $data[$key];        $value = '';        $attributes = explode('.',$key);        $current = $data;        foreach ($attributes as $attribute) {        	if ( !isset($current[$attribute]) ) return;        	$current = $current[$attribute];        	$value = $current;        }        return $value;    },$stream);       return $stream;}/** * Auteur: Anonymous * Lien: https://www.php.net/manual/en/features.file-upload.post-method.php#120686 *  * Normalise le tableau de fichier récupérés * pour une utilisation plus efficace et intuitive *  * Exemple de format initial pour 2 fichiers dans $_FILES : * Array (    [name] => Array (        [0] => foo.txt        [1] => bar.txt    ),    [type] => Array(        [0] => text/plain        [1] => text/plain    ),    [tmp_name] => Array(        [0] => /tmp/phpYzdqkD        [1] => /tmp/phpeEwEWG    ),    [error] => Array(        [0] => 0        [1] => 0    ),    [size] => Array(        [0] => 123        [1] => 456    ) * ) *  * Exemple de format de retour pour 2 fichiers : * Array(    [0] => Array(        [name] => foo.txt        [type] => text/plain        [tmp_name] => /tmp/phpYzdqkD        [error] => 0        [size] => 123    ),    [1] => Array(        [name] => bar.txt        [type] => text/plain        [tmp_name] => /tmp/phpeEwEWG        [error] => 0        [size] => 456    )) * @param  Array &$file_post [tableau de fichiers $_FILES] * @return Array             [le tableau ré-arrangé] */function normalize_php_files() {    $function = function($files, $fixedFiles=array(), $path=array()) use (&$function) {        foreach ($files as $key => $value) {            $temp = $path;            $temp[] = $key;                   if(is_array($value)) {                $fixedFiles = $function($value, $fixedFiles, $temp);            } else {                $next = array_splice($temp, 1, 1);                $temp = array_merge($temp, $next);                $new = &$fixedFiles;                               foreach ($temp as $key)                    $new = &$new[$key];                $new = $value;            }        }        return $fixedFiles;    };    return $function($_FILES);}/** * Incrémente automatiquement le nom d'un * fichier si celui-ci existe déjà * Fonction récursive. * @param  String $extension [extension du fichier] * @param  String $folder    [dossier où localiser le fichier] * @param  String $filename  [nom du fichier] * @return String            [nom de fichier final] */function autoincrement_filename($extension, $folder, $filename){	static $counter = 0;	$fileNb = count(glob(FILE_PATH.$folder.$filename));	$filenameProps = explode('.', $filename);		unset($filenameProps[count($filenameProps)-1]);	$finalFilename = implode('.', $filenameProps);	if($fileNb>0) {		$counter+=1;		$filename = preg_match("/(^.*?\()(\d+)([^\\d]*\)\..*$)/", $filename, $matches) ? $matches[1].$counter.$matches[3] : $finalFilename.'('.$counter.')'.'.'.$extension;		$filename = autoincrement_filename($extension, $folder, $filename);	}	return $filename;}function relative_path($absolutePath,$reference = __ROOT__){	$absolutePath = str_replace(array('\\','/'),SLASH,$absolutePath);	$reference = str_replace(array('\\','/'),SLASH,$reference);	return str_replace($reference,'',$absolutePath);}//Définit si une couleur hexadecimale est claire//ou sombre en fonction d'un seuil de luminositéfunction get_light($hexcode,$treshold = 510.0) {	$rgb = to_rgb($hexcode);	return (max($rgb[0], $rgb[1], $rgb[2]) + min($rgb[0], $rgb[1], $rgb[2])) / $treshold; }//Génère une couleur hexadécimale aléatoirefunction random_hex_color() {    return '#'.str_pad(dechex(mt_rand(0, 0xFFFFFF)), 6, '0', STR_PAD_LEFT);}//Génère une couleur pastel basé sur //le hash md5 du mot passé en paramètrefunction random_hex_pastel_color($name) {    $hash = md5($name);    $red = hexdec(substr($hash, 8, 2));    $green = hexdec(substr($hash, 4, 2));    $blue = hexdec(substr($hash, 0, 2));    if($red < 128) $red += 128;    if($green < 128) $green += 128;    if($blue < 128) $blue += 128;    return "#" . dechex($red) . dechex($green) . dechex($blue);}//Convertit un code hexadecimal en code RGBfunction to_rgb($hexcode) {	$hexcode = substr($hexcode, 1);	    	return array(hexdec($hexcode[0] . $hexcode[1]),		hexdec($hexcode[2] . $hexcode[3]),		hexdec($hexcode[4] . $hexcode[5]));    }//Retourne le nom complet d'un mois en fonction de son numérofunction month_name($month){	$translates = array('Janvier','Fevrier','Mars','Avril','Mai','Juin','Juillet','Aout','Septembre','Octobre','Novembre','Décembre');	return $translates[$month-1];}//Retourne le nom complet d'un jour en fonction de son numéro (1 : lundi,..., 7 :dimanche)function day_name($day){    $translates = array('Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi','Dimanche');    return isset($translates[$day-1])? $translates[$day-1]:$day;}//Convertit un timestamp dans un format //agréable et complet : ex Mardi 18 Avril 2019function complete_date($time=null){	if(!isset($time)) $time = time();	return day_name(date('N',$time)).' '.date('d',$time).' '.month_name(date('m',$time)).' '.date('Y',$time);}//Récuperation des jours fériesfunction get_not_workable($date=null){	if ($date === null)		$date = time();	$date = strtotime(date('m/d/Y',$date));	$year = date('Y',$date);	$easterDate  = easter_date($year);	$easterDay   = date('j', $easterDate);	$easterMonth = date('n', $easterDate);	$easterYear  = date('Y', $easterDate);	$holidays = array(	    // Dates fixes	    mktime(0, 0, 0, 1,  1,  $year),  // 1er janvier	    mktime(0, 0, 0, 5,  1,  $year),  // Fête du travail	    mktime(0, 0, 0, 5,  8,  $year),  // Victoire des alliés	    mktime(0, 0, 0, 7,  14, $year),  // Fête nationale	    mktime(0, 0, 0, 8,  15, $year),  // Assomption	    mktime(0, 0, 0, 11, 1,  $year),  // Toussaint	    mktime(0, 0, 0, 11, 11, $year),  // Armistice	    mktime(0, 0, 0, 12, 25, $year),  // Noel	    // Dates variables	    mktime(0, 0, 0, $easterMonth, $easterDay + 1,  $easterYear),	    mktime(0, 0, 0, $easterMonth, $easterDay + 39, $easterYear),	    mktime(0, 0, 0, $easterMonth, $easterDay + 50, $easterYear),	);	return $holidays;}//Retourne le chemin web d'un fichier en fonction de son chemin //physique (ex : /img/logo.png pour /var/www/erp-core/img/logo.png)function webpath($path){    $url = ROOT_URL.str_replace(array(__DIR__.SLASH,"\\","/"),array('','/','/'),$path);    $url = preg_replace('/([^\:])(\/{2,})/i', '$1/', $url);    return $url;}//Retourne un tableau clé/valeur des valeurs//existantes en doublons du tableau passé en paramètrefunction array_not_unique($array=array()){	return array_diff_key($array, array_unique($array));}//Retourne true si aucune valeur du tableau passé//en paramètre a un doublon, false sinon. function is_array_unique($array=array()){	return empty(array_not_unique($array));}function make_cookie($nom, $valeur, $expire='',$ns ='/') {	if($expire == ''){		setcookie($nom, $valeur, mktime(0,0,0, date("d"), date("m"), (date("Y")+1)), $ns);	} else {		setcookie($nom, '', mktime(0,0,0, date("d"), date("m"), (date("Y")-1)), $ns);	}}//Permet de formatter les prix à afficher//de la même manière partout sur l'ERP.//Si jamais on veut changer de normalisation//pour l'affichage des prix, il suffit de changer//le fonctionnement ici uniquement.function display_price($price){	return number_format($price, 2, ',', ' ');}//Permet de formatter les prix à enregistrer//de la même manière partout sur l'ERP.//Si jamais on veut changer de normalisation//pour l'enregistrement des prix, il suffit de changer//le fonctionnement ici uniquement.function format_price($price){	return str_replace(',','.',$price);}//Permet de calculer un age en fonction de la date du jour//Paramètre : la date de départ(format timestamp), l'unité de retour souhaitée(format 'd', 'm', 'Y'... voir fonction diff de php)//Renvoie : l'age en entierfunction age($from,$unit = 'y'){	if(!isset($from) || !is_numeric($from)) return 'N/A';	$from = new \DateTime(date('Y-m-d',$from));	$to = new \DateTime('today');	$age = $from->diff($to);	if(!$age || !array_key_exists($unit, $age))		return 'N/A';	return $age = $age->$unit;}//Permet d'échapper tous les caractères interdits dans une chaine jsonfunction escape_json_string($value) { # list from www.json.org: (\b backspace, \f formfeed)    $escapers = array("\\", "/", "\"", "\n", "\r", "\t", "\x08", "\x0c");    $replacements = array("\\\\", "\\/", "\\\"", "\\n", "\\r", "\\t", "\\f", "\\b");    $result = str_replace($escapers, $replacements, $value);    return $result;}if( !function_exists('apache_request_headers') ) {	///	function apache_request_headers() {	  $arh = array();	  $rx_http = '/\AHTTP_/';	  foreach($_SERVER as $key => $val) {	    if( preg_match($rx_http, $key) ) {	      $arh_key = preg_replace($rx_http, '', $key);	      $rx_matches = array();	      // do some nasty string manipulations to restore the original letter case	      // this should work in most cases	      $rx_matches = explode('_', $arh_key);	      if( count($rx_matches) > 0 and strlen($arh_key) > 2 ) {	        foreach($rx_matches as $ak_key => $ak_val) $rx_matches[$ak_key] = ucfirst($ak_val);	        $arh_key = implode('-', $rx_matches);	      }	      $arh[$arh_key] = $val;	    }	  }	  return( $arh );	}}if(!function_exists('apache_get_version')){    function apache_get_version(){        if(!isset($_SERVER['SERVER_SOFTWARE']) || strlen($_SERVER['SERVER_SOFTWARE']) == 0){            return false;        }        return $_SERVER["SERVER_SOFTWARE"];    }}//Effectue un basename en tenant compte des caractères//utf8( non pris en compte par basename PHP sous linux)function mt_basename($path){	$path = str_replace(array("\\","/"),SLASH, $path);	$nameSplit = explode(SLASH,$path);	return end($nameSplit);}//filtre les balises dangeureuses (script,link..) dans les contenus wysiwyg function wysiwyg_filter($html){		$html = preg_replace('#<(script|link)(.*?)>(.*?)</(script|link)>#is', '', $html);	$html = preg_replace('#<(script|link)([^>]*?)>#is', '', $html);	return $html;}function display_format_price($price) {	return display_price(format_price($price));}?>
 |