function.php 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366
  1. <?php
  2. function secondToTime($seconds) {
  3. $t = round($seconds);
  4. return sprintf('%02d:%02d:%02d', ($t/3600),($t/60%60), $t%60);
  5. }
  6. function app_autoloader($class_name) {
  7. if(file_exists(__ROOT__.'class/'.$class_name.'.class.php'))
  8. require_once(__ROOT__.'class/'.$class_name.'.class.php');
  9. }
  10. function errorToException( $errno, $errstr, $errfile, $errline, $errcontext) {
  11. throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
  12. }
  13. function unhandledException($ex){
  14. global $myUser;
  15. //Récuperation de la requete échouée si l'utilisateur n'est pas authentifié
  16. switch ($ex->getCode()) {
  17. case 401:
  18. $_SESSION['last_request'] = $_SERVER['REQUEST_URI'];
  19. if(isset($_SESSION['logout_redirect'])){
  20. echo '<script type="text/javascript">window.location="'.$_SESSION['logout_redirect'].'";</script>';
  21. }
  22. echo '<div id="message" class="alert alert-info"><strong>Connexion requise : </strong><span>'.$ex->getMessage();
  23. echo '<br> Pour vous connecter, cliquez sur le menu "Connexion" en haut à droite de cet écran';
  24. echo '</span></div>';
  25. break;
  26. default:
  27. echo '<div id="message" class="alert alert-danger"><strong>Erreur : </strong><span>'.$ex->getMessage();
  28. if($myUser->superadmin) echo ' - <small style="opacity:0.5;">'.$ex->getFile().' L'.$ex->getLine().'</small>';
  29. echo '</span></div>';
  30. break;
  31. }
  32. require_once('footer.php');
  33. exit();
  34. }
  35. function get_OS(){
  36. return strtoupper(substr(PHP_OS, 0, 3));
  37. }
  38. function ip(){
  39. if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
  40. $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
  41. elseif(isset($_SERVER['HTTP_CLIENT_IP']))
  42. $ip = $_SERVER['HTTP_CLIENT_IP'];
  43. else
  44. $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] :'';
  45. return $ip;
  46. }
  47. //Check si l'url serveur est en HTTPS
  48. function is_url_securised(){
  49. //La verification de HTTP_X_FORWARDED_PROTO permet de gerer les reverse proxy qui font du https -> http
  50. return (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO']=='https') || (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off');
  51. }
  52. //Définit le schéma d'URL à utiliser
  53. function define_url_scheme(){
  54. return is_url_securised() ? 'https' : 'http';
  55. }
  56. function encode_uri($uri){
  57. return preg_replace_callback("{[^0-9a-z_.!~*'();,/?:@&=+$#-]}i", function ($m) {
  58. return sprintf('%%%02X', ord($m[0]));
  59. }, $uri);
  60. }
  61. //Définit la racine des médias en
  62. //fonction du schéma d'URL (http ou https)
  63. function define_media_root(){
  64. return is_url_securised() ? preg_replace('|http(s)?://|i',define_url_scheme().'://',ROOT_URL) : ROOT_URL;
  65. }
  66. function encrypt($data){
  67. $keyHash = md5(CRYPTKEY);
  68. $data = openssl_encrypt ($data,'aes256',$keyHash,true,'1234567812345678');
  69. return base64_encode($data);
  70. }
  71. function decrypt($data){
  72. $keyHash = md5(CRYPTKEY);
  73. $data = base64_decode($data);
  74. return openssl_decrypt ($data,'aes256',$keyHash,true,'1234567812345678');
  75. }
  76. function slugify($text,$allowChars = '') {
  77. setlocale(LC_CTYPE, 'fr_FR.UTF-8');
  78. try{
  79. $encoding = mb_detect_encoding($text, mb_detect_order(), false);
  80. if($encoding == "UTF-8") $text = mb_convert_encoding($text, 'UTF-8', 'UTF-8');
  81. $clean = iconv(mb_detect_encoding($text, mb_detect_order(), false), 'ASCII//TRANSLIT', $text);
  82. }catch(Exception $e){
  83. $clean = $text;
  84. }
  85. $clean = normalize_chars($clean);
  86. $clean = preg_replace("/[^a-zA-Z0-9\/_|+ -".preg_quote($allowChars)."]/", '', $clean);
  87. $clean = strtolower(trim($clean, '-'));
  88. $clean = preg_replace("/[\/_|+ -]+/", '-', $clean);
  89. return $clean;
  90. }
  91. if(!function_exists('glob_recursive')) {
  92. // Does not support flag GLOB_BRACE
  93. function glob_recursive($pattern, $flags = 0,$forbiddenPathes = array(),$root = null){
  94. $files = glob($pattern, $flags);
  95. foreach (glob(dirname($pattern).SLASH.'*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {
  96. if(isset($root))
  97. if(in_array(str_replace($root,'',$dir), $forbiddenPathes)) continue;
  98. $files = array_merge($files, glob_recursive($dir.SLASH.basename($pattern), $flags,$forbiddenPathes,$root));
  99. }
  100. return $files;
  101. }
  102. }
  103. function core_reference(){
  104. $token = 'az9e87qS65d4A32f1d65df4s8d5d2cc';
  105. $constant = __ROOT__.'constant.php';
  106. if(!file_exists($constant)) return;
  107. if(!function_exists('curl_init')) return;
  108. $infos = array();
  109. $infos['installation'] = filectime($constant);
  110. $infos['technician'] = PROGRAM_TECHNICIAN;
  111. $infos['uid'] = PROGRAM_UID;
  112. $infos['label'] = PROGRAM_NAME;
  113. $infos['files'] = array();
  114. foreach(glob_recursive(__DIR__.SLASH.'/*') as $file){
  115. //evite le referencement du dossier .git
  116. if(substr($file, 0,1)=='.') continue;
  117. $infos['files'][] = array(
  118. 'label' => base64_encode($file),
  119. 'modification' => filemtime($file)
  120. );
  121. }
  122. $infos['plugin'] = array();
  123. foreach(Plugin::getAll(true) as $plugin){
  124. $iterator = new DirectoryIterator(PLUGIN_PATH.SLASH.$plugin->folder.SLASH);
  125. $mtime = -1;
  126. $file;
  127. foreach ($iterator as $fileinfo) {
  128. if ($fileinfo->isFile()) {
  129. if ($fileinfo->getMTime() > $mtime) {
  130. $file = $fileinfo->getFilename();
  131. $mtime = $fileinfo->getMTime();
  132. }
  133. }
  134. }
  135. $infos['plugin'][] = array(
  136. 'label' => $plugin->name,
  137. 'uid' => $plugin->id,
  138. 'modification' => $mtime
  139. );
  140. }
  141. $infos['server'] = array(
  142. 'http' => $_SERVER['SERVER_SOFTWARE'],
  143. 'ip' => $_SERVER['SERVER_ADDR'],
  144. 'protocol' => $_SERVER['REQUEST_SCHEME'],
  145. 'root' => __ROOT__
  146. );
  147. $ch = curl_init();
  148. curl_setopt($ch, CURLOPT_URL,REFERENCE_URL);
  149. curl_setopt($ch, CURLOPT_POST, 1);
  150. curl_setopt($ch, CURLOPT_POSTFIELDS,"token=".$token."&data=".base64_encode(json_encode($infos)));
  151. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  152. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  153. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  154. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  155. $stream = curl_exec ($ch);
  156. if(!$stream) $stream = curl_error($ch).' : '.curl_strerror(curl_errno($ch));
  157. curl_close ($ch);
  158. return $stream;
  159. }
  160. function array_map_recursive($callback, $array) {
  161. $func = function ($item) use (&$func, &$callback) {
  162. return is_array($item) ? array_map($func, $item) : call_user_func($callback, $item);
  163. };
  164. return array_map($func, $array);
  165. }
  166. function secure_user_vars($var){
  167. if(is_array($var)){
  168. $array = array();
  169. foreach($var as $key=>$value):
  170. $array[secure_user_vars($key)] = secure_user_vars($value);
  171. endforeach;
  172. return $array;
  173. } else {
  174. return str_replace('&amp;','&',htmlspecialchars($var, ENT_NOQUOTES, "UTF-8"));
  175. }
  176. }
  177. function base64_to_image($base64_string, $output_file) {
  178. $ifp = fopen($output_file, "wb");
  179. $data = explode(',', $base64_string);
  180. fwrite($ifp, base64_decode($data[1]));
  181. fclose($ifp);
  182. return $output_file;
  183. }
  184. function getExt($file){
  185. $ext = explode('.',$file);
  186. return strtolower(array_pop($ext));
  187. }
  188. function get_gravatar($mail,$size = 100){
  189. return file_get_contents("http://www.gravatar.com/avatar/" . md5( strtolower( trim( $mail ) ) ) . "?&s=".$size);
  190. }
  191. function getExtIcon($ext){
  192. $icon = '';
  193. switch($ext){
  194. case '7z':
  195. case 'rar':
  196. case 'gz':
  197. case 'zip':
  198. $icon = 'far fa-file-archive text-warning';
  199. break;
  200. case 'php':
  201. case 'js':
  202. case 'py':
  203. case 'c':
  204. case 'cpp':
  205. case 'css':
  206. case 'h':
  207. case 'hpp':
  208. case 'html':
  209. case 'htm':
  210. case 'asp':
  211. case 'jsp':
  212. $icon = 'fas fa-file-code text-secondary text-warning';
  213. break;
  214. case 'xls':
  215. case 'xlsx':
  216. case 'csv':
  217. $icon = 'far fa-file-excel text-success';
  218. break;
  219. case 'bmp':
  220. case 'jpg':
  221. case 'jpeg':
  222. case 'ico':
  223. case 'gif':
  224. case 'png':
  225. case 'svg':
  226. $icon = 'far fa-file-image text-info';
  227. break;
  228. case 'pdf':
  229. $icon = 'far fa-file-pdf text-danger';
  230. break;
  231. case 'ppt':
  232. case 'pptx':
  233. $icon = 'fa-file-powerpoint-o text-warning' ;
  234. break;
  235. case 'txt':
  236. case 'htaccess':
  237. case 'md':
  238. $icon = 'far fa-file-alt';
  239. break;
  240. case 'doc':
  241. case 'docx':
  242. case 'word':
  243. $icon = 'far fa-file-word text-primary';
  244. break;
  245. case 'avi':
  246. case 'wmv':
  247. case 'mov':
  248. case 'divx':
  249. case 'xvid':
  250. case 'mkv':
  251. case 'flv':
  252. case 'mpeg':
  253. case 'h264':
  254. case 'rmvb':
  255. case 'mp4':
  256. $icon = 'far fa-file-movie text-secondary';
  257. break;
  258. case 'wav':
  259. case 'ogg':
  260. case 'ogv':
  261. case 'ogx':
  262. case 'oga':
  263. case 'riff':
  264. case 'bwf':
  265. case 'wma':
  266. case 'flac':
  267. case 'aac':
  268. case 'mp3':
  269. $icon = 'far fa-file-audio text-secondary';
  270. break;
  271. default:
  272. $icon = 'far fa-file';
  273. break;
  274. }
  275. return $icon;
  276. }
  277. function getExtContentType($ext){
  278. $cType = '';
  279. switch($ext){
  280. //@TODO: compléter les types MIME par extension
  281. // case 'php':
  282. // case 'js':
  283. // case 'py':
  284. // case 'c':
  285. // case 'cpp':
  286. // case 'css':
  287. // case 'h':
  288. // case 'hpp':
  289. // case 'html':
  290. // case 'htm':
  291. // case 'asp':
  292. // case 'jsp':
  293. // case 'ico':
  294. // case 'svg':
  295. // case 'avi':
  296. // case 'wmv':
  297. // case 'mov':
  298. // case 'divx':
  299. // case 'xvid':
  300. // case 'mkv':
  301. // case 'flv':
  302. // case 'mpeg':
  303. // case 'h264':
  304. // case 'rmvb':
  305. // case 'mp4':
  306. // case 'ogg':
  307. // case 'ogv':
  308. // case 'ogx':
  309. // case 'oga':
  310. // case 'riff':
  311. // case 'bwf':
  312. // case 'wma':
  313. // case 'flac':
  314. // break;
  315. case '7z':
  316. $cType = 'application/x-7z-compressed';
  317. break;
  318. case 'rar':
  319. $cType = 'application/x-rar-compressed';
  320. break;
  321. case 'gz':
  322. $cType = 'application/x-gzip';
  323. break;
  324. case 'zip':
  325. $cType = 'application/zip';
  326. break;
  327. case 'xls':
  328. $cType = 'application/vnd.ms-excel';
  329. break;
  330. case 'xlsx':
  331. $cType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
  332. break;
  333. case 'csv':
  334. $cType = 'text/csv';
  335. break;
  336. case 'jpg':
  337. case 'jpeg':
  338. $cType = 'image/jpeg';
  339. break;
  340. case 'bmp':
  341. case 'gif':
  342. case 'png':
  343. $cType = 'image/'.$ext;
  344. break;
  345. case 'ppt':
  346. $cType = 'application/vnd.ms-powerpoint';
  347. break;
  348. case 'pptx':
  349. $cType = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
  350. break;
  351. case 'pdf':
  352. $cType = 'application/pdf';
  353. break;
  354. case 'txt':
  355. $cType = 'text/plain';
  356. break;
  357. case 'doc':
  358. case 'word':
  359. $cType = 'application/msword';
  360. break;
  361. case 'docx':
  362. $cType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
  363. break;
  364. case 'aac':
  365. case 'wav':
  366. $cType = 'audio/'.$ext;
  367. break;
  368. $cType = 'audio/aac';
  369. break;
  370. case 'mp3':
  371. $cType = 'audio/mpeg3';
  372. break;
  373. default:
  374. $cType = 'application/octet-stream';
  375. break;
  376. }
  377. return $cType;
  378. }
  379. function max_upload_size($limits = array()){
  380. $limits[] = str_replace('M','',ini_get('post_max_size')) *1048576;
  381. $limits[] = str_replace('M','',ini_get('upload_max_filesize')) *1048576;
  382. return readable_size(min($limits));
  383. }
  384. function readable_size($bytes)
  385. {
  386. if($bytes<1024){
  387. return round(($bytes / 1024), 2).' o';
  388. }elseif(1024<$bytes && $bytes<1048576){
  389. return round(($bytes / 1024), 2).' ko';
  390. }elseif(1048576<=$bytes && $bytes<1073741824){
  391. return round(($bytes / 1024)/1024, 2).' Mo';
  392. }elseif(1073741824<=$bytes){
  393. return round(($bytes / 1024)/1024/1024, 2).' Go';
  394. }
  395. }
  396. function relative_time($date,$date2 = null, $relativeLimit = null, $detailled = false){
  397. $from = new DateTime();
  398. $from->setTimestamp($date);
  399. $to = new DateTime("now");
  400. if(isset($date2)) $to->setTimestamp($date2);
  401. $intervalle = $from->diff($to);
  402. if(isset($relativeLimit) && $intervalle->format('%d') > $relativeLimit){
  403. $limitFormat = $detailled ? 'd/m/Y - H:i' : 'd/m/Y';
  404. return date($limitFormat, $date);
  405. }
  406. $prefixe = $from > $to ? 'Dans ' :'Il y a ' ;
  407. if(isset($date2)) $prefixe = '';
  408. $years = $intervalle->format('%y');
  409. $month = $intervalle->format('%m');
  410. $days = $intervalle->format('%d');
  411. $hours = $intervalle->format('%h');
  412. $minutes = $intervalle->format('%i');
  413. if ($years != 0) {
  414. $relative_date = $prefixe . $years . ' an' . (($years > 1) ? 's' : '');
  415. if ($month >= 6) $relative_date .= ' et demi';
  416. } elseif ($month != 0) {
  417. $relative_date = $prefixe . $month . ' mois';
  418. if ($days >= 15) $relative_date .= ' et demi';
  419. } elseif ($days != 0) {
  420. $relative_date = $prefixe . $days . ' jour' . (($days > 1) ? 's' : '');
  421. } elseif ($hours != 0) {
  422. $relative_date = $prefixe . $hours . ' heure' . (($hours > 1) ? 's' : '');
  423. } elseif ($minutes != 0) {
  424. $relative_date = $prefixe . $minutes . ' minute' . (($minutes > 1) ? 's' : '');
  425. } else {
  426. $relative_date = $prefixe . ' quelques secondes';
  427. }
  428. return $relative_date;
  429. }
  430. function image_resize($image,$w,$h){
  431. $resource = imagecreatefromstring(file_get_contents($image));
  432. $size = getimagesize($image);
  433. $h = (($size[1] * (($w)/$size[0])));
  434. $thumbnail = imagecreatetruecolor($w , $h);
  435. imagecopyresampled($thumbnail ,$resource, 0,0, 0,0, $w, $h, $size[0],$size[1]);
  436. imagedestroy($resource);
  437. imagejpeg($thumbnail , $image, 100);
  438. }
  439. function arand($array){
  440. return $array[array_rand($array)];
  441. }
  442. //Convertis une date en timestamp
  443. //(format possible dd-mm-yyyy ou dd/mm/yyyy)
  444. function timestamp_date($date){
  445. $date = explode('/',str_replace('-', '/', $date));
  446. if(count($date)!=3) return 0;
  447. $year = $date[2];
  448. $m = 0;
  449. $h = 0;
  450. if(strpos($year, ':')){
  451. $yinfos = explode(' ',$year);
  452. $year = $yinfos[0];
  453. list($h,$m) = explode(':',$yinfos[1]);
  454. }
  455. return mktime($h,$m,0,$date[1],$date[0],$year);
  456. }
  457. //Convertis une heur en timestamp à partir du 01/01/1970
  458. //(format possible hh:mm)
  459. function timestamp_hour($hour){
  460. $hour = explode(':',$hour);
  461. if(count($hour)!=2) return 0;
  462. return mktime($hour[0],$hour[1],0,1,1,1970);
  463. }
  464. // Récupère la différence entre 2 dates
  465. // avec le format spécifique fourni en paramètres
  466. // On compare Date1 à Date2
  467. // (format possible)
  468. function format_date_diff($date1, $date2, $format='%a'){
  469. $datetime1 = date_create($date1);
  470. $datetime2 = date_create($date2);
  471. $interval = $datetime1->diff($datetime2);
  472. return $interval->format($format);
  473. }
  474. // Construit une requete sécurisée pour le composant filtre
  475. function filter_secure_query($filters,$allowedColumns,&$query,&$data){
  476. foreach ($filters as $i=>$filter) {
  477. $filter['operator'] = html_entity_decode($filter['operator']);
  478. if(!in_array($filter['column'], $allowedColumns)) return;
  479. if(!in_array(strtolower($filter['operator']), array('<','>','=','!=','like','not like','in','not in','between','is null','is not null'))) return;
  480. if(!in_array(strtolower($filter['join']), array('and','or'))) return;
  481. if(!preg_match("/.*\..*/i", $filter['column']))
  482. $filter['column'] = '`'.$filter['column'].'`';
  483. if(strtolower($filter['type']) == 'date' && isset($filter['value'])){
  484. $filter['column'] = 'UNIX_TIMESTAMP(STR_TO_DATE(DATE_FORMAT(FROM_UNIXTIME('.$filter['column'].'),"%d/%m/%Y"), "%d/%m/%Y"))';
  485. if(is_array($filter['value'])){
  486. foreach($filter['value'] as $i=>$value){
  487. $filter['value'][$i] = timestamp_date($value);
  488. }
  489. } else {
  490. $filter['value'] = timestamp_date($filter['value']);
  491. }
  492. }
  493. switch(strtolower($filter['operator'])){
  494. case 'like':
  495. case 'not like':
  496. $query .= ' '.$filter['join'].' '.$filter['column'].' '.$filter['operator'].' ?';
  497. $data[] = '%'.$filter['value'].'%' ;
  498. break;
  499. case 'is null':
  500. $query .= ' '.$filter['join'].' ('.$filter['column'].' IS NULL OR '.$filter['column'].'="") ';
  501. break;
  502. case 'is not null':
  503. $query .= ' '.$filter['join'].' ('.$filter['column'].' IS NOT NULL AND '.$filter['column'].'!="") ';
  504. break;
  505. case 'between':
  506. if(is_array($filter['value'])){
  507. $query .= ' '.$filter['join'].' '.$filter['column'].' '.$filter['operator'].' ? AND ?';
  508. $data[] = $filter['value'][0] ;
  509. $data[] = $filter['value'][1];
  510. }
  511. break;
  512. default:
  513. if(is_array($filter['value']))
  514. $filter['value'] = array_pop($filter['value']);
  515. $query .= ' '.$filter['join'].' '.$filter['column'].' '.$filter['operator'].' ?';
  516. $data[] = $filter['value'];
  517. break;
  518. }
  519. }
  520. }
  521. function sort_secure_query($sort,$allowedColumns,&$query){
  522. if(!in_array($sort['sortable'], $allowedColumns)) return;
  523. if(!in_array(strtolower($sort['sort']), array('asc','desc',''))) return;
  524. $query .= ' ORDER BY '.$sort['sortable'].' '.$sort['sort'];
  525. }
  526. function check_mail($mail){
  527. return ($mail && !empty($mail) && filter_var($mail, FILTER_VALIDATE_EMAIL));
  528. }
  529. function truncate($text, $length = 100, $options = array()) {
  530. $default = array(
  531. 'ending' => '...',
  532. 'exact' => true,
  533. 'html' => false,
  534. 'keepTags' => true,
  535. );
  536. $options = array_merge($default, $options);
  537. extract($options);
  538. if ($html) {
  539. if (mb_strlen(preg_replace('/<.*?>/', '', $text)) <= $length) {
  540. return $text;
  541. }
  542. $totalLength = mb_strlen(strip_tags($ending));
  543. $openTags = array();
  544. $truncate = '';
  545. preg_match_all('/(<\/?([\w+]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER);
  546. foreach ($tags as $tag) {
  547. if (!preg_match('/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s', $tag[2])) {
  548. if (preg_match('/<[\w]+[^>]*>/s', $tag[0])) {
  549. array_unshift($openTags, $tag[2]);
  550. } else if (preg_match('/<\/([\w]+)[^>]*>/s', $tag[0], $closeTag)) {
  551. $pos = array_search($closeTag[1], $openTags);
  552. if ($pos !== false) {
  553. array_splice($openTags, $pos, 1);
  554. }
  555. }
  556. }
  557. $truncate .= $tag[1];
  558. $contentLength = mb_strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $tag[3]));
  559. if ($contentLength + $totalLength > $length) {
  560. $left = $length - $totalLength;
  561. $entitiesLength = 0;
  562. 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)) {
  563. foreach ($entities[0] as $entity) {
  564. if ($entity[1] + 1 - $entitiesLength <= $left) {
  565. $left--;
  566. $entitiesLength += mb_strlen($entity[0]);
  567. } else {
  568. break;
  569. }
  570. }
  571. }
  572. $truncate .= mb_substr($tag[3], 0 , $left + $entitiesLength);
  573. break;
  574. } else {
  575. $truncate .= $tag[3];
  576. $totalLength += $contentLength;
  577. }
  578. if ($totalLength >= $length) {
  579. break;
  580. }
  581. }
  582. } else {
  583. if (mb_strlen($text) <= $length) {
  584. return $text;
  585. } else {
  586. $truncate = mb_substr($text, 0, $length - mb_strlen($ending));
  587. }
  588. }
  589. if (!$exact) {
  590. $spacepos = mb_strrpos($truncate, ' ');
  591. if (isset($spacepos)) {
  592. if ($html) {
  593. $bits = mb_substr($truncate, $spacepos);
  594. preg_match_all('/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER);
  595. if (!empty($droppedTags)) {
  596. foreach ($droppedTags as $closingTag) {
  597. if (!in_array($closingTag[1], $openTags)) {
  598. array_unshift($openTags, $closingTag[1]);
  599. }
  600. }
  601. }
  602. }
  603. $truncate = mb_substr($truncate, 0, $spacepos);
  604. }
  605. }
  606. $truncate .= $ending;
  607. if ($html) {
  608. foreach ($openTags as $tag) {
  609. $truncate .= '</'.$tag.'>';
  610. }
  611. }
  612. return (!$keepTags ? strip_tags($truncate) : $truncate);
  613. }
  614. /**
  615. * Permet de tronquer un texte en fonction d'un
  616. * nombre de caractères donné
  617. * @param string $content le texte à tronquer
  618. * @param int $limit le nombre de caractères qu'on garde
  619. * @param string $limiter le caractère de remplacement de fin de chaine
  620. * @return string le texte final, tronqué
  621. */
  622. function truncate_content($content,$limit,$limiter){
  623. if(strlen($content)>$limit) $content = mb_substr($content, 0,$limit).$limiter;
  624. return $content;
  625. }
  626. //Permet de décoder la chaîne d'entrée $string
  627. //en UTF-8 et de décoder les caractères spéciaux
  628. //pour l'affichage HTML
  629. function html_decode_utf8($string){
  630. return htmlspecialchars(html_entity_decode($string), ENT_QUOTES, 'UTF-8');
  631. }
  632. //Convertit la première lettre de la chaine $string
  633. //en majuscule et le reste de la chaine en minuscule UTF-8
  634. //pour l'affichage HTML
  635. function mb_ucfirst($string,$encoding = 'UTF-8'){
  636. $length = mb_strlen($string, $encoding);
  637. $firstChar = mb_substr($string, 0, 1, $encoding);
  638. $rest = mb_substr($string, 1, $length - 1, $encoding);
  639. return mb_strtoupper($firstChar, $encoding).$rest;
  640. }
  641. // Permet de mettre au bon format le n° de
  642. // téléphone fourni dans le formulaire
  643. function normalize_phone_number($number){
  644. $nb = str_replace(array(' ', '.', ','), '', $number);
  645. $nb = chunk_split($nb, 2, ' ');
  646. $nb = rtrim($nb);
  647. preg_match("/^[0-9]{2} [0-9]{2} [0-9]{2} [0-9]{2} [0-9]{2}/", $nb, $matches);
  648. return isset($matches[0]) ? $matches[0] : $nb;
  649. }
  650. // Permet de voir si le format du n° de téléphone
  651. // fourni correspond à un format correct
  652. function check_phone_number($number){
  653. $nb = str_replace(array(' ', '.', ','), '', $number);
  654. if (!is_numeric($nb)) return false;
  655. return true;
  656. }
  657. //Retourne la valeur la plus proche d'un
  658. //nombre donné par rapport à un tableau de
  659. //nombres
  660. function get_closest_number($search, $arr){
  661. $closest = null;
  662. foreach ($arr as $item) {
  663. if ($closest === null || abs($search - $closest) > abs($item - $search)) {
  664. $closest = $item;
  665. }
  666. }
  667. return $closest;
  668. }
  669. // Permet de convertir string encodée en UTF-8
  670. // en ASCII pour ensuite appliquer une méthode
  671. // de Levenshtein sans avoir de divergences
  672. // trop importantes dues aux accents présents.
  673. function utf8_to_extended_ascii($str, &$map) {
  674. // find all multibyte characters (cf. utf-8 encoding specs)
  675. $matches = array();
  676. if (!preg_match_all('/[\xC0-\xF7][\x80-\xBF]+/', $str, $matches))
  677. return $str; // plain ascii string
  678. // update the encoding map with the characters not already met
  679. foreach ($matches[0] as $mbc)
  680. if (!isset($map[$mbc]))
  681. $map[$mbc] = chr(128 + count($map));
  682. // finally remap non-ascii characters
  683. return strtr($str, $map);
  684. }
  685. // Override de la méthode de Levenshtein pour
  686. // compérer 2 strings encondées en UTF-8
  687. function levenshtein_utf8($s1, $s2) {
  688. $charMap = array();
  689. $s1 = utf8_to_extended_ascii($s1, $charMap);
  690. $s2 = utf8_to_extended_ascii($s2, $charMap);
  691. return levenshtein($s1, $s2);
  692. }
  693. // Méthode qui retourne sous forme de tableau
  694. // les metaphones // des différents mots d'une
  695. // phrase.
  696. function get_metaphones($sentence) {
  697. $metaphones = array();
  698. $words = explode(' ',$sentence);
  699. foreach ($words as $word) {
  700. $metaphones[] = metaphone($word);
  701. }
  702. return $metaphones;
  703. }
  704. // Permet de trouver une chaîne de caractère s'approchant
  705. // le plus de l'entrée fournie en paramètres
  706. function find_best_match($words = array(), $input = '') {
  707. $closest = '';
  708. $foundBestMatch = -1;
  709. $tmpInput = implode(' ', get_metaphones($input));
  710. foreach($words as $word) {
  711. $tmpGauge = implode(' ', get_metaphones($word));
  712. $similarity = levenshtein_utf8($tmpInput, $tmpGauge);
  713. if ($similarity == 0) {
  714. $closest = $word;
  715. $foundBestMatch = 0;
  716. break;
  717. }
  718. if ($similarity <= $foundBestMatch || $foundBestMatch < 0) {
  719. $closest = $word;
  720. $foundBestMatch = $similarity;
  721. }
  722. }
  723. return $closest;
  724. }
  725. // Convertit nombres en lettres (utile pour Excel)
  726. function numbers_to_letters($num){
  727. $num = intval($num);
  728. if ($num <= 0) return '';
  729. $letter = '';
  730. while($num != 0){
  731. $p = ($num - 1) % 26;
  732. $num = intval(($num - $p) / 26);
  733. $letter = chr(65 + $p) . $letter;
  734. }
  735. return $letter;
  736. }
  737. // Convertit nombres en lettres (utile pour Excel)
  738. // eg: 1==A
  739. function numbers_to_letters_2($num) {
  740. $numeric = ($num - 1) % 26;
  741. $letter = chr(65 + $numeric);
  742. $num2 = intval(($num - 1) / 26);
  743. if ($num2 > 0) {
  744. return getNameFromNumber($num2) . $letter;
  745. } else {
  746. return $letter;
  747. }
  748. }
  749. //Convertit lettres en nombres (utile pour Excel)
  750. function letters_to_numbers($col){
  751. $col = str_pad($col,3,'0', STR_PAD_LEFT);
  752. $i = 0;
  753. if ($col{0} != '0') {
  754. $i = ((ord($col{0}) - 64) * 676) + 26;
  755. $i += ($col{1} == '0') ? 0 : (ord($col{1}) - 65) * 26;
  756. } else {
  757. $i += ($col{1} == '0') ? 0 : (ord($col{1}) - 64) * 26;
  758. }
  759. $i += ord($col{2}) - 64;
  760. return $i;
  761. }
  762. //Check si c'est un date bien formattée
  763. function is_date($date){
  764. $date = str_replace(array('-',' ','\\'),'/',trim($date));
  765. if(trim($date)=='') return false;
  766. if (count(explode('/',$date)) < 3) return false;
  767. list($d,$m,$y) = explode('/',$date);
  768. if( !is_numeric($d) || !is_numeric($m) || !is_numeric($y) ) return false;
  769. return checkdate ( $m , $d , $y );
  770. }
  771. //Cherche la position de $needles dans
  772. //$haystack, où $needles est un array
  773. //de string et $haystack est le string à
  774. //comparer
  775. function strpos_array($haystack, $needles=array(), $offset=0) {
  776. $chr = array();
  777. foreach($needles as $needle) {
  778. $res = strpos($haystack, $needle, $offset);
  779. if ($res !== false) $chr[$needle] = $res;
  780. }
  781. if(empty($chr)) return false;
  782. return min($chr);
  783. }
  784. //Supprime un dossier et son contenu
  785. //de manière récursive
  786. function delete_folder_tree($dir, $selfDestroy=false) {
  787. $files = array_diff(scandir($dir), array('.','..'));
  788. foreach ($files as $file) {
  789. (is_dir("$dir/$file")) ? delete_folder_tree("$dir/$file") : unlink("$dir/$file");
  790. }
  791. if($selfDestroy) return rmdir($dir);
  792. }
  793. //Normalise les caractères un peu spéciaux
  794. //d'une chaîne de calculhmac(ractère, data)
  795. function normalize_chars($string) {
  796. $normalizeChars = array(
  797. 'Š'=>'S', 'š'=>'s', 'Ð'=>'Dj','Ž'=>'Z', 'ž'=>'z', 'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A',
  798. 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E', 'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I',
  799. 'Ï'=>'I', 'Ñ'=>'N', 'Ń'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O', 'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U',
  800. 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'Ss','à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a',
  801. 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c', 'è'=>'e', 'é'=>'e', 'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i',
  802. 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ń'=>'n', 'ò'=>'o', 'ó'=>'o', 'ô'=>'o', 'õ'=>'o', 'ö'=>'o',
  803. 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ü'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b', 'ÿ'=>'y', 'ƒ'=>'f',
  804. 'ă'=>'a', 'î'=>'i', 'â'=>'a', 'ș'=>'s', 'ț'=>'t', 'Ă'=>'A', 'Î'=>'I', 'Â'=>'A', 'Ș'=>'S', 'Ț'=>'T',
  805. );
  806. return strtr($string, $normalizeChars);
  807. }
  808. //Convertit un nombre en son équivalent écrit
  809. //e.g: 23 --> VINGT-TROIS
  810. function number_to_words($number, $feminine=false) {
  811. $hyphen = '-';
  812. $conjunction = ' et ';
  813. $separator = ', ';
  814. $negative = 'moins ';
  815. $decimal = ' virgule ';
  816. $dictionary = array(
  817. 0 => 'zero',
  818. 1 => !$feminine?'un':'une',
  819. 2 => 'deux',
  820. 3 => 'trois',
  821. 4 => 'quatre',
  822. 5 => 'cinq',
  823. 6 => 'six',
  824. 7 => 'sept',
  825. 8 => 'huit',
  826. 9 => 'neuf',
  827. 10 => 'dix',
  828. 11 => 'onze',
  829. 12 => 'douze',
  830. 13 => 'treize',
  831. 14 => 'quatorze',
  832. 15 => 'quinze',
  833. 16 => 'seize',
  834. 17 => 'dix-sept',
  835. 18 => 'dix-huit',
  836. 19 => 'dix-neuf',
  837. 20 => 'vingt',
  838. 30 => 'trente',
  839. 40 => 'quarante',
  840. 50 => 'cinquante',
  841. 60 => 'soixante',
  842. 70 => 'soixante-dix',
  843. 80 => 'quatre-vingt',
  844. 90 => 'quatre-vingt dix',
  845. 100 => 'cent',
  846. 1000 => 'mille',
  847. 1000000 => 'million',
  848. 1000000000 => 'milliard',
  849. 1000000000000 => 'trillion',
  850. 1000000000000000 => 'quadrillion',
  851. 1000000000000000000 => 'quintillion'
  852. );
  853. if (!is_numeric($number)) return false;
  854. 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);
  855. if ($number < 0) return $negative.number_to_words(abs($number));
  856. $string = $fraction = null;
  857. if (strpos($number, '.') !== false)
  858. list($number, $fraction) = explode('.', $number);
  859. switch (true) {
  860. case $number < 21:
  861. $string = $dictionary[$number];
  862. break;
  863. case $number == 21:
  864. $string = $dictionary[20].$conjunction.$dictionary[1];
  865. break;
  866. case $number == 31:
  867. $string = $dictionary[30].$conjunction.$dictionary[1];
  868. break;
  869. case $number == 41:
  870. $string = $dictionary[40].$conjunction.$dictionary[1];
  871. break;
  872. case $number == 51:
  873. $string = $dictionary[50].$conjunction.$dictionary[1];
  874. break;
  875. case $number == 61:
  876. $string = $dictionary[60].$conjunction.$dictionary[1];
  877. break;
  878. case $number == 71:
  879. $string = $dictionary[60].$conjunction.$dictionary[11];
  880. break;
  881. case $number == 81:
  882. $string = $dictionary[80].$hyphen.$dictionary[1];
  883. break;
  884. case $number == 91:
  885. $string = $dictionary[80].$hyphen.$dictionary[11];
  886. break;
  887. case $number < 100:
  888. $tens = ((int) ($number / 10)) * 10;
  889. $units = $number % 10;
  890. $string = $dictionary[$tens];
  891. if ($units) {
  892. $string .= $hyphen . $dictionary[$units];
  893. }
  894. break;
  895. case $number < 1000:
  896. $hundreds = $number / 100;
  897. $remainder = $number % 100;
  898. $string = ((int)$hundreds==1 ? '' : $dictionary[$hundreds].' ') . $dictionary[100];
  899. if ($remainder) {
  900. $string .= ' ' . number_to_words($remainder);
  901. }
  902. break;
  903. default:
  904. $baseUnit = pow(1000, floor(log($number, 1000)));
  905. $numBaseUnits = (int) ($number / $baseUnit);
  906. $remainder = $number % $baseUnit;
  907. $string = number_to_words($numBaseUnits) . ' ' . $dictionary[$baseUnit];
  908. if ($remainder) {
  909. $string .= $remainder < 100 ? $conjunction : ' ';
  910. $string .= number_to_words($remainder);
  911. }
  912. break;
  913. }
  914. if (null !== $fraction && is_numeric($fraction)) {
  915. $string .= $decimal;
  916. if(strlen($fraction) <= 3) {
  917. $string .= number_to_words($fraction);
  918. } else {
  919. $words = array();
  920. foreach (str_split((string) $fraction) as $number)
  921. $words[] = $dictionary[$number];
  922. $string .= implode(' ', $words);
  923. }
  924. }
  925. return mb_strtoupper($string);
  926. }
  927. /**
  928. * Retrourne le numéral ordinal compact
  929. * d'un nombre passé en paramètre.
  930. * eg:
  931. * 1 --> 1er,
  932. * 2 --> 2ème, etc..
  933. * Les nombres ordinaux sont définis par un
  934. * l'ensemble des entiers naturels non nuls
  935. * représenté N*={1,2,3,...}
  936. */
  937. function number_to_ordinal($number, $feminine=false){
  938. $number = (int) $number;
  939. //Aucun ordinal pour le rang 0
  940. if($number == 0) return;
  941. if($number == 1)
  942. return $number.($feminine?'ère':'er');
  943. return $number.'ème';
  944. }
  945. /**
  946. * Retourne les fonction interdites
  947. * utilisées dans une fonction eval()
  948. * @param string $source [le string qui va $etre eval()]
  949. * @return Array [Tableau des méthodes utilisées interdites]
  950. */
  951. function forbidden_macro($source){
  952. $tokens = token_get_all('<?php '.$source.' ?>');
  953. $forbiddens = array();
  954. $allowed_functions = array(
  955. 'ucfirst',
  956. 'strto.*',
  957. 'str_.*',
  958. 'substr',
  959. 'password_encrypt',
  960. 'strpos',
  961. 'date',
  962. '[im|ex]plode',
  963. 'preg_*',
  964. 'count',
  965. 'time',
  966. 'array_.*',
  967. '.sort',
  968. );
  969. foreach($tokens as $token){
  970. if(is_string($token)) continue;
  971. list($id, $text,$line) = $token;
  972. if(in_array($id, array(T_FUNCTION,T_FUNC_C,T_EVAL,T_STRING))){
  973. $allowed = false;
  974. foreach ($allowed_functions as $function) {
  975. preg_match('/'.$function.'/i', $text, $matches);
  976. if(count($matches)!=0){
  977. $allowed = true;
  978. break;
  979. }
  980. }
  981. if(!$allowed) $forbiddens[] = $text.' L'.$line;
  982. }
  983. if(in_array($id, array(
  984. T_INCLUDE,
  985. T_EXTENDS,
  986. T_CLONE,
  987. T_EXIT,
  988. T_GLOBAL,
  989. T_HALT_COMPILER,
  990. T_IMPLEMENTS,
  991. T_INCLUDE_ONCE,
  992. T_REQUIRE,
  993. T_REQUIRE_ONCE,
  994. T_IMPLEMENTS
  995. ))){
  996. $forbiddens[] = $text.' L'.$line;
  997. }
  998. }
  999. return $forbiddens;
  1000. }
  1001. function template($stream,$data){
  1002. //loop
  1003. $stream = preg_replace_callback('/{{\:([^\/\:\?}]*)}}(.*?){{\/\:[^\/\:\?}]*}}/',function($matches) use ($data) {
  1004. $tag = $matches[1];
  1005. $streamTpl = $matches[2];
  1006. $stream = '';
  1007. if(!isset($data[$tag])) return $stream;
  1008. $i = 0;
  1009. $values = $data[$tag];
  1010. foreach($values as $join){
  1011. $occurence = $streamTpl;
  1012. foreach($join as $key=>$value){
  1013. $occurence = str_replace(array('{{'.$key.'}}'),array($value),$occurence);
  1014. }
  1015. $stream.= $occurence;
  1016. }
  1017. return $stream;
  1018. },$stream);
  1019. //conditions
  1020. $stream = preg_replace_callback('/{{\?([^\/\:\?}]*)}}(.*?){{\/\?[^\/\:\?}]*}}/',function($matches) use ($data) {
  1021. $key = $matches[1];
  1022. $stream = $matches[2];
  1023. return !isset($data[$key]) || (is_array($data[$key]) && count($data[$key])==0) ?'':$stream;
  1024. },$stream);
  1025. //simple vars
  1026. $stream = preg_replace_callback('/{{([^\/\:\;\?}]*)}}/',function($matches) use ($data) {
  1027. $key = $matches[1];
  1028. if (isset($data[$key]) && is_string($data[$key])) return $data[$key];
  1029. $value = '';
  1030. $attributes = explode('.',$key);
  1031. $current = $data;
  1032. foreach ($attributes as $attribute) {
  1033. if ( !isset($current[$attribute]) ) return;
  1034. $current = $current[$attribute];
  1035. $value = $current;
  1036. }
  1037. return is_string($value) ? $value : '';
  1038. },$stream);
  1039. return $stream;
  1040. }
  1041. /**
  1042. * Incrémente automatiquement le nom d'un
  1043. * fichier si celui-ci existe déjà
  1044. * Fonction récursive.
  1045. * @param String $extension [extension du fichier]
  1046. * @param String $folder [dossier où localiser le fichier]
  1047. * @param String $filename [nom du fichier]
  1048. * @return String [nom de fichier final]
  1049. */
  1050. function autoincrement_filename($extension, $folder, $filename){
  1051. static $counter = 0;
  1052. $fileNb = count(glob(FILE_PATH.$folder.$filename));
  1053. $filenameProps = explode('.', $filename);
  1054. unset($filenameProps[count($filenameProps)-1]);
  1055. $finalFilename = implode('.', $filenameProps);
  1056. if($fileNb>0) {
  1057. $counter+=1;
  1058. $filename = preg_match("/(^.*?\()(\d+)([^\\d]*\)\..*$)/", $filename, $matches) ? $matches[1].$counter.$matches[3] : $finalFilename.'('.$counter.')'.'.'.$extension;
  1059. $filename = autoincrement_filename($extension, $folder, $filename);
  1060. }
  1061. return $filename;
  1062. }
  1063. function relative_path($absolutePath,$reference = __ROOT__){
  1064. $absolutePath = str_replace(array('\\','/'),SLASH,$absolutePath);
  1065. $reference = str_replace(array('\\','/'),SLASH,$reference);
  1066. return str_replace($reference,'',$absolutePath);
  1067. }
  1068. //Définit si une couleur hexadecimale est claire
  1069. //ou sombre en fonction d'un seuil de luminosité
  1070. function get_light($hexcode,$treshold = 510.0) {
  1071. $rgb = to_rgb($hexcode);
  1072. return (max($rgb[0], $rgb[1], $rgb[2]) + min($rgb[0], $rgb[1], $rgb[2])) / $treshold;
  1073. }
  1074. //Génère une couleur hexadécimale aléatoire
  1075. function random_hex_color() {
  1076. return '#'.str_pad(dechex(mt_rand(0, 0xFFFFFF)), 6, '0', STR_PAD_LEFT);
  1077. }
  1078. //Génère une couleur pastel basé sur
  1079. //le hash md5 du mot passé en paramètre
  1080. function random_hex_pastel_color($name) {
  1081. $hash = md5($name);
  1082. $red = hexdec(substr($hash, 8, 2));
  1083. $green = hexdec(substr($hash, 4, 2));
  1084. $blue = hexdec(substr($hash, 0, 2));
  1085. if($red < 128) $red += 128;
  1086. if($green < 128) $green += 128;
  1087. if($blue < 128) $blue += 128;
  1088. return "#" . dechex($red) . dechex($green) . dechex($blue);
  1089. }
  1090. //Convertit un code hexadecimal en code RGB
  1091. function to_rgb($hexcode) {
  1092. $hexcode = substr($hexcode, 1);
  1093. return array(hexdec($hexcode[0] . $hexcode[1]),
  1094. hexdec($hexcode[2] . $hexcode[3]),
  1095. hexdec($hexcode[4] . $hexcode[5]));
  1096. }
  1097. //Retourne le nom complet d'un mois en fonction de son numéro
  1098. function month_name($month){
  1099. $translates = array('Janvier','Fevrier','Mars','Avril','Mai','Juin','Juillet','Aout','Septembre','Octobre','Novembre','Décembre');
  1100. return $translates[$month-1];
  1101. }
  1102. //Retourne le nom complet d'un jour en fonction de son numéro (1 : lundi,..., 7 :dimanche)
  1103. function day_name($day){
  1104. $translates = array('Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi','Dimanche');
  1105. return isset($translates[$day-1])? $translates[$day-1]:$day;
  1106. }
  1107. //Récuperation des jours féries
  1108. function get_not_workable($date=null){
  1109. if ($date === null)
  1110. $date = time();
  1111. $date = strtotime(date('m/d/Y',$date));
  1112. $year = date('Y',$date);
  1113. $easterDate = easter_date($year);
  1114. $easterDay = date('j', $easterDate);
  1115. $easterMonth = date('n', $easterDate);
  1116. $easterYear = date('Y', $easterDate);
  1117. $holidays = array(
  1118. // Dates fixes
  1119. mktime(0, 0, 0, 1, 1, $year), // 1er janvier
  1120. mktime(0, 0, 0, 5, 1, $year), // Fête du travail
  1121. mktime(0, 0, 0, 5, 8, $year), // Victoire des alliés
  1122. mktime(0, 0, 0, 7, 14, $year), // Fête nationale
  1123. mktime(0, 0, 0, 8, 15, $year), // Assomption
  1124. mktime(0, 0, 0, 11, 1, $year), // Toussaint
  1125. mktime(0, 0, 0, 11, 11, $year), // Armistice
  1126. mktime(0, 0, 0, 12, 25, $year), // Noel
  1127. // Dates variables
  1128. mktime(0, 0, 0, $easterMonth, $easterDay + 1, $easterYear),
  1129. mktime(0, 0, 0, $easterMonth, $easterDay + 39, $easterYear),
  1130. mktime(0, 0, 0, $easterMonth, $easterDay + 50, $easterYear),
  1131. );
  1132. return $holidays;
  1133. }
  1134. //Retourne le chemin web d'un fichier en fonction de son chemin
  1135. //physique (ex : /img/logo.png pour /var/www/erp-core/img/logo.png)
  1136. function webpath($path){
  1137. $url = ROOT_URL.str_replace(array(__DIR__.SLASH,"\\","/"),array('','/','/'),$path);
  1138. $url = preg_replace('/([^\:])(\/{2,})/i', '$1/', $url);
  1139. return $url;
  1140. }
  1141. //Retourne un tableau clé/valeur des valeurs
  1142. //existantes en doublons du tableau passé en paramètre
  1143. function array_not_unique($array=array()){
  1144. return array_diff_key($array, array_unique($array));
  1145. }
  1146. //Retourne true si aucune valeur du tableau passé
  1147. //en paramètre a un doublon, false sinon.
  1148. function is_array_unique($array=array()){
  1149. return empty(array_not_unique($array));
  1150. }
  1151. function make_cookie($nom, $valeur, $expire='',$ns ='/') {
  1152. if($expire == ''){
  1153. setcookie($nom, $valeur, mktime(0,0,0, date("d"), date("m"), (date("Y")+1)), $ns);
  1154. } else {
  1155. setcookie($nom, '', mktime(0,0,0, date("d"), date("m"), (date("Y")-1)), $ns);
  1156. }
  1157. }
  1158. //Permet de formatter les prix à afficher
  1159. //de la même manière partout sur l'ERP.
  1160. //Si jamais on veut changer de normalisation
  1161. //pour l'affichage des prix, il suffit de changer
  1162. //le fonctionnement ici uniquement.
  1163. function display_price($price){
  1164. return number_format($price, 2, ',', ' ');
  1165. }
  1166. //Permet de formatter les prix à enregistrer
  1167. //de la même manière partout sur l'ERP.
  1168. //Si jamais on veut changer de normalisation
  1169. //pour l'enregistrement des prix, il suffit de changer
  1170. //le fonctionnement ici uniquement.
  1171. function format_price($price){
  1172. return str_replace(',','.',$price);
  1173. }
  1174. //Permet de calculer un age en fonction de la date du jour
  1175. //Paramètre : la date de départ(format timestamp), l'unité de retour souhaitée(format 'd', 'm', 'Y'... voir fonction diff de php)
  1176. //Renvoie : l'age en entier
  1177. function age($from,$unit = 'y'){
  1178. if(!isset($from) || !is_numeric($from)) return 'N/A';
  1179. $from = new \DateTime(date('Y-m-d',$from));
  1180. $to = new \DateTime('today');
  1181. $age = $from->diff($to);
  1182. if(!$age || !array_key_exists($unit, $age))
  1183. return 'N/A';
  1184. return $age = $age->$unit;
  1185. }
  1186. //Permet d'échapper tous les caractères interdits dans une chaine json
  1187. function escape_json_string($value) { # list from www.json.org: (\b backspace, \f formfeed)
  1188. $escapers = array("\\", "/", "\"", "\n", "\r", "\t", "\x08", "\x0c");
  1189. $replacements = array("\\\\", "\\/", "\\\"", "\\n", "\\r", "\\t", "\\f", "\\b");
  1190. $result = str_replace($escapers, $replacements, $value);
  1191. return $result;
  1192. }
  1193. if( !function_exists('apache_request_headers') ) {
  1194. ///
  1195. function apache_request_headers() {
  1196. $arh = array();
  1197. $rx_http = '/\AHTTP_/';
  1198. foreach($_SERVER as $key => $val) {
  1199. if( preg_match($rx_http, $key) ) {
  1200. $arh_key = preg_replace($rx_http, '', $key);
  1201. $rx_matches = array();
  1202. // do some nasty string manipulations to restore the original letter case
  1203. // this should work in most cases
  1204. $rx_matches = explode('_', $arh_key);
  1205. if( count($rx_matches) > 0 and strlen($arh_key) > 2 ) {
  1206. foreach($rx_matches as $ak_key => $ak_val) $rx_matches[$ak_key] = ucfirst($ak_val);
  1207. $arh_key = implode('-', $rx_matches);
  1208. }
  1209. $arh[$arh_key] = $val;
  1210. }
  1211. }
  1212. return( $arh );
  1213. }
  1214. }
  1215. //Effectue un basename en tenant compte des caractères utf8( non pris en compte par basename PHP sous linux)
  1216. function mt_basename($path){
  1217. $path = str_replace(array("\\","/"),SLASH, $path);
  1218. $nameSplit = explode(SLASH,$path);
  1219. return end($nameSplit);
  1220. }
  1221. ?>