0) { $asCleaningFunc = array_fill(1, count($oData), $sCleaningFunc); $asKeys = array_map(array('self', 'cleanData'), array_keys($oData), $asCleaningFunc); $asValues = array_map(array('self', 'cleanData'), $oData, $asCleaningFunc); return array_combine($asKeys, $asValues); } } public static function fixGlobalVars($argv) { //Add CLI arguments if(defined('STDIN')) mb_parse_str(implode('&', array_slice($argv, 1)), $_GET); $_REQUEST = array_merge($_GET, $_REQUEST); } public static function array_map_encapsulate($oData, $sChar) { if(is_array($oData)) { $asChar = array_fill(1, count($oData), $sChar); return array_combine(array_keys($oData), array_map(array('self', 'array_map_encapsulate'), $oData, $asChar)); } else { return $sChar.$oData.$sChar; } } public static function capitalizeWords($acText, $sCharList = '') { //Use ucwords if no delimiters are given if($sCharList=='') { return Toolbox::mb_ucwords($acText); } // Go through all characters $capitalizeNext = true; $max = mb_strlen($acText); for ($i = 0; $i < $max; $i++) { if(mb_strpos($sCharList, $acText[$i]) !== false) { $capitalizeNext = true; } elseif($capitalizeNext) { $capitalizeNext = false; $acText[$i] = mb_strtoupper($acText[$i]); } } return $acText; } /** * * @param String $sFromName * @param String $sSubject * @param String $sMessage * @param String $sTo * @param Array $asCc array(name => email) * @param Boolean $bSelfMail * @return mixed */ public function sendMail($sFromName, $sSubject, $sMessage, $sTo, $asCc=array(), $bSelfMail=true) { $asForm = array('api_key'=>Settings::MAIL_API_KEY, 'app'=>'Wedding', 'from_name'=>$sFromName, 'subject'=>$sSubject, 'msg'=>$sMessage, 'to_email'=>$sTo, 'cc_email'=>self::jsonConvert($asCc), 'self'=>$bSelfMail); $oCurl = curl_init(); curl_setopt($oCurl, CURLOPT_URL, Settings::MAIL_SCRIPT); curl_setopt($oCurl, CURLOPT_POST, true); curl_setopt($oCurl, CURLOPT_HEADER, false); curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, true); curl_setopt($oCurl, CURLOPT_POSTFIELDS, $asForm); $iResult = curl_exec($oCurl); curl_close($oCurl); return $iResult; } public static function jsonExport($asData) { header('Content-type: application/json'); //return htmlspecialchars(json_encode($asData), ENT_NOQUOTES); return self::jsonConvert($asData); } public static function jsonConvert($asData) { return json_encode($asData); } public static function getMimeType($sPath, $bSubTypeOnly=false) { //Retrieving file Content Type if(file_exists($sPath)) //Local { $oFileInfo = new finfo(FILEINFO_MIME); $sMimetype = $oFileInfo->file($sPath); } else //Remote { //get_headers($sUrl, 1) $oCurl = curl_init($sPath); curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, true); curl_setopt($oCurl, CURLOPT_FOLLOWLOCATION, true); curl_setopt($oCurl, CURLOPT_HEADER, true); //curl_setopt($oCurl, CURLOPT_NOBODY, true); curl_setopt($oCurl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false); curl_exec($oCurl); $sMimetype = curl_getinfo($oCurl, CURLINFO_CONTENT_TYPE); curl_close($oCurl); } //Only sub type (after /) if($bSubTypeOnly) { preg_match('`\/(?P\w+)(\;|$)`ui', mb_strtolower($sMimetype), $asMatch); $sMimetype = $asMatch['type']; } return $sMimetype; } public static function isAnimatedGif($sFilePath) { if(!($oFile = @fopen($sFilePath, 'rb'))) return false; $iCount = 0; while (!feof($oFile) && $iCount < 2) { $sChunk = fread($oFile, 1024 * 100); //read 100kb at a time $iCount += preg_match_all('#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $sChunk, $asMatches); } fclose($oFile); return $iCount > 1; } public static function createThumbnail($sInPath, $iMaxWidth, $iMaxHeight=0, $sOutPath='', $bDeleteIn=false, $asImageExts=array('jpg', 'jpeg', 'gif', 'png'), $bCrop=false) { $asResult = array('error'=>''); //Look up the file type to choose the image creator $sImageExt = self::getMimeType($sInPath, true); $sImageExt = ($sImageExt=='jpg')?'jpeg':$sImageExt; //New Destination folder $asInInfo = pathinfo($sInPath); $asOutInfo = pathinfo($sOutPath); if($sOutPath=='') $sOutPath = $sInPath; elseif(mb_substr($sOutPath, -1)=='/') $sOutPath .= mb_strtolower($asInInfo['basename']); //folder only, keep original name elseif(!array_key_exists('extension', $asOutInfo)) $sOutPath .= '.'.$sImageExt; //folder + filename, but getting ext from file info //New sizes if(!in_array($sImageExt, $asImageExts) && !empty($asImageExts)) $asResult['error'] = 'Wrong file type: '.$sImageExt; elseif($iMaxWidth==0 && $iMaxHeight==0) $asResult['error'] = 'At least one dimension must be resized (width and/or height)'; else { list($iWidth, $iHeight) = getimagesize($sInPath); //Limit on only 1 parameter if($iMaxWidth==0) $iMaxWidth = $iWidth * $iMaxHeight / $iHeight; elseif($iMaxHeight==0) $iMaxHeight = $iHeight * $iMaxWidth / $iWidth; if($iWidth > $iMaxWidth || $iHeight > $iMaxHeight) { $dResizeDeltaWidth = $iWidth - $iMaxWidth; $dResizeDeltaHeight = $iHeight - $iMaxHeight; $iPosLeft = $iPosTop = 0; $iThumbWidth = $iMaxWidth; $iThumbHeight = $iMaxHeight; //Max up the lowest value between height and width and crop the other if($bCrop) { if($dResizeDeltaWidth > $dResizeDeltaHeight) //Crop width { $iResizedHeight = $iMaxHeight; $iResizedWidth = ($iResizedHeight / $iHeight) * $iWidth; $iPosLeft = ($iResizedWidth - $iMaxWidth)/2*(-1); } else { $iResizedWidth = $iMaxWidth; $iResizedHeight = ($iResizedWidth / $iWidth) * $iHeight; $iPosTop = ($iResizedHeight - $iMaxHeight)/2*(-1); } } else //Just resize { if($dResizeDeltaWidth > $dResizeDeltaHeight) { $iResizedWidth = $iMaxWidth; $iResizedHeight = ($iResizedWidth / $iWidth) * $iHeight; } else { $iResizedHeight = $iMaxHeight; $iResizedWidth = ($iResizedHeight / $iHeight) * $iWidth; } $iThumbWidth = $iResizedWidth; $iThumbHeight = $iResizedHeight; } if($sImageExt=='gif' && self::isAnimatedGif($sInPath)) { $sContent = file_get_contents($sInPath); $sBigGifPath = uniqid().$sOutPath.'.big'; $sCoalescePath = uniqid().$sOutPath.'.coalesce'; if(file_put_contents($sBigGifPath, $sContent)===false) $asResult['error'] = 'Unable to create temporary thumbnail : '.$sBigGifPath; system('convert '.$sBigGifPath.' -coalesce '.$sCoalescePath); system('convert -size '.$iWidth.'x'.$iHeight.' '.$sCoalescePath.' -resize '.$iResizedWidth.'x'.$iResizedHeight.' '.$sOutPath); unlink($sBigGifPath); unlink($sCoalescePath); } else { //create image from source $oSource = call_user_func('imagecreatefrom'.$sImageExt, $sInPath); //Resize $oThumb = imagecreatetruecolor($iThumbWidth, $iThumbHeight); imagecopyresampled($oThumb, $oSource, $iPosLeft, $iPosTop, 0, 0, $iResizedWidth, $iResizedHeight, $iWidth, $iHeight); //Save if(file_exists($sOutPath)) unlink($sOutPath); if(!call_user_func_array('image'.$sImageExt, array($oThumb, $sOutPath))) { $asResult['error'] = 'Unable to create thumbnail : '.$sOutPath; } } } elseif($sInPath != $sOutPath) { $iResizedWidth = $iWidth; $iResizedHeight = $iHeight; if(!copy($sInPath, $sOutPath)) $asResult['error'] = 'Copy failed from '.$sInPath.' to '.$sOutPath; } $asResult['width'] = $iResizedWidth; $asResult['height'] = $iResizedHeight; $asResult['out'] = $sOutPath; } if($bDeleteIn && $asResult['error'] == '' && $sInPath != $sOutPath) unlink($sInPath); return $asResult; } public static function utf8_compliant($sText) { if(strlen($sText) == 0) return true; return (preg_match('/^.{1}/us', $sText, $ar) == 1); } public static function mb_ucwords($sText) { return mb_convert_case($sText, MB_CASE_TITLE, "UTF-8"); } public static function mb_ucfirst($sText) { $sLength = mb_strlen($sText); $sFirstChar = mb_substr($sText, 0, 1); $sThen = mb_substr($sText, 1, $sLength - 1); return mb_strtoupper($sFirstChar).$sThen; } public static function file_get_contents_utf8($oFile) { $sContent = file_get_contents($oFile); return mb_convert_encoding($sContent, 'UTF-8', mb_detect_encoding($sContent, 'UTF-8, ISO-8859-1', true)); } public static function rgbToHex($R, $G, $B) { $R = dechex($R); if(strlen($R)<2) $R='0'.$R; $G = dechex($G); if(strlen($G)<2) $G='0'.$G; $B = dechex($B); if(strlen($B)<2) $B='0'.$B; return $R.$G.$B; } public static function setCookie($sCookieName, $sCookieValue, $iDays) { $iTimeLimit = time()+60*60*24*$iDays; setcookie($sCookieName, $sCookieValue, $iTimeLimit); } public static function fixEOL($sText) { //Normalize line endings //Convert all line-endings to UNIX format $sText = str_replace("\r\n", "\n", $sText); //Windows $sText = str_replace("\r", "\n", $sText); //Mac // Don't allow out-of-control blank lines $sText = preg_replace("/\n{2,}/", "\n\n", $sText); return $sText; } /** * Return relative time description * FIXME shitty implementation of i18n * @param int $oTime Time (strtotime) * @param string $sLang Language (en/fr) * @return string Relative Time */ public static function getDateTimeDesc($oTime, $sLang='en') { $iTimeStamp = is_numeric($oTime)?$oTime:strtotime($oTime); $sCurTimeStamp = time(); switch ($sLang) { case 'en': $asWeekDays = array('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'satursday', 'sunday'); $asMonths = array('january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'); break; case 'fr': $asWeekDays = array('lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche'); $asMonths = array('janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'); break; } $sSep = '|'; $sFormat = 'Y'.$sSep.'n'.$sSep.'W'.$sSep.'N'.$sSep.'j'.$sSep.'G'; list($sYear, $sMonth, $sWeek, $sWeekDay, $sDay, $sHour) = explode($sSep, date($sFormat, $iTimeStamp)); list($sCurYear, $sCurMonth, $sCurWeek, $sCurWeekDay, $sCurDay, $sCurHour) = explode($sSep, date($sFormat, $sCurTimeStamp)); $sDesc = ''; switch ($sLang) { case 'en': if($iTimeStamp>$sCurTimeStamp) $sDesc = 'in the future'; elseif($sCurTimeStamp-$iTimeStamp<60) $sDesc = 'a few seconds ago'; elseif($sCurTimeStamp-$iTimeStamp<60*10) $sDesc = 'a few minutes ago'; elseif($sCurTimeStamp-$iTimeStamp<60*20) $sDesc = '15 minutes ago'; elseif($sCurTimeStamp-$iTimeStamp<60*50) $sDesc = 'half an hour ago'; elseif($sCurTimeStamp-$iTimeStamp<60*60*2) $sDesc = 'an hour ago'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24 && $sDay==$sCurDay) $sDesc = 'at '.$sHour.' o\'clock'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24) $sDesc = 'yesterday'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*7 && $sWeek==$sCurWeek) $sDesc = $asWeekDays[$sWeekDay-1]; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*7) $sDesc = 'last '.$asWeekDays[$sWeekDay-1]; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*9) $sDesc = 'a week ago'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*12) $sDesc = '10 days ago'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*16) $sDesc = '2 weeks ago'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*23) $sDesc = '3 weeks ago'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*31 && $sMonth==$sCurMonth) $sDesc = 'on '.$asMonths[$sMonth-1].', '.$sDay; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*30*2 && $sMonth==($sCurMonth-1)) $sDesc = 'last month'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*365 && $sYear==$sCurYear) $sDesc = 'in '.$asMonths[$sMonth-1]; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*365) $sDesc = 'in '.$asMonths[$sMonth-1].' '.$sYear; elseif($sYear==($sCurYear-1)) $sDesc = 'last year'; else $sDesc = 'in '.$sYear; break; case 'fr': if($iTimeStamp>$sCurTimeStamp) $sDesc = 'dans le futur'; elseif($sCurTimeStamp-$iTimeStamp<60) $sDesc = 'il y a quelques secondes'; elseif($sCurTimeStamp-$iTimeStamp<60*10) $sDesc = 'il y a quelques minutes'; elseif($sCurTimeStamp-$iTimeStamp<60*20) $sDesc = 'il y a un quart d\'heure'; elseif($sCurTimeStamp-$iTimeStamp<60*50) $sDesc = 'il y a une demi-heure'; elseif($sCurTimeStamp-$iTimeStamp<60*60*2) $sDesc = 'il y a une heure'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24 && $sDay==$sCurDay) $sDesc = 'à '.$sHour.'h'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24) $sDesc = 'hier'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*7 && $sWeek==$sCurWeek) $sDesc = $asWeekDays[$sWeekDay-1]; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*7) $sDesc = $asWeekDays[$sWeekDay-1].' dernier'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*9) $sDesc = 'il y a une semaine'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*12) $sDesc = 'il y a 10 jours'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*16) $sDesc = 'il y a 2 semaines'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*23) $sDesc = 'il y a 3 semaines'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*31 && $sMonth==$sCurMonth) $sDesc = 'le '.$sDay.' '.$asMonths[$sMonth-1]; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*30*2 && $sMonth==($sCurMonth-1)) $sDesc = 'le mois dernier'; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*365 && $sYear==$sCurYear) $sDesc = 'en '.$asMonths[$sMonth-1]; elseif($sCurTimeStamp-$iTimeStamp<60*60*24*365) $sDesc = 'en '.$asMonths[$sMonth-1].' '.$sYear; elseif($sYear==($sCurYear-1)) $sDesc = 'l\'année dernière'; else $sDesc = 'en '.$sYear; break; } //return self::mb_ucfirst($sDesc); return $sDesc; } /** * Worpress function to remove accents * https://core.trac.wordpress.org/browser/trunk/src/wp-includes/formatting.php * @param String $string * @return String */ public static function remove_accents($string) { if(!preg_match('/[\x80-\xff]/', $string)) return $string; if (true || seems_utf8($string)) { $chars = array( // Decompositions for Latin-1 Supplement chr(194).chr(170) => 'a', chr(194).chr(186) => 'o', chr(195).chr(128) => 'A', chr(195).chr(129) => 'A', chr(195).chr(130) => 'A', chr(195).chr(131) => 'A', chr(195).chr(132) => 'A', chr(195).chr(133) => 'A', chr(195).chr(134) => 'AE',chr(195).chr(135) => 'C', chr(195).chr(136) => 'E', chr(195).chr(137) => 'E', chr(195).chr(138) => 'E', chr(195).chr(139) => 'E', chr(195).chr(140) => 'I', chr(195).chr(141) => 'I', chr(195).chr(142) => 'I', chr(195).chr(143) => 'I', chr(195).chr(144) => 'D', chr(195).chr(145) => 'N', chr(195).chr(146) => 'O', chr(195).chr(147) => 'O', chr(195).chr(148) => 'O', chr(195).chr(149) => 'O', chr(195).chr(150) => 'O', chr(195).chr(153) => 'U', chr(195).chr(154) => 'U', chr(195).chr(155) => 'U', chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y', chr(195).chr(158) => 'TH',chr(195).chr(159) => 's', chr(195).chr(160) => 'a', chr(195).chr(161) => 'a', chr(195).chr(162) => 'a', chr(195).chr(163) => 'a', chr(195).chr(164) => 'a', chr(195).chr(165) => 'a', chr(195).chr(166) => 'ae',chr(195).chr(167) => 'c', chr(195).chr(168) => 'e', chr(195).chr(169) => 'e', chr(195).chr(170) => 'e', chr(195).chr(171) => 'e', chr(195).chr(172) => 'i', chr(195).chr(173) => 'i', chr(195).chr(174) => 'i', chr(195).chr(175) => 'i', chr(195).chr(176) => 'd', chr(195).chr(177) => 'n', chr(195).chr(178) => 'o', chr(195).chr(179) => 'o', chr(195).chr(180) => 'o', chr(195).chr(181) => 'o', chr(195).chr(182) => 'o', chr(195).chr(184) => 'o', chr(195).chr(185) => 'u', chr(195).chr(186) => 'u', chr(195).chr(187) => 'u', chr(195).chr(188) => 'u', chr(195).chr(189) => 'y', chr(195).chr(190) => 'th', chr(195).chr(191) => 'y', chr(195).chr(152) => 'O', // Decompositions for Latin Extended-A chr(196).chr(128) => 'A', chr(196).chr(129) => 'a', chr(196).chr(130) => 'A', chr(196).chr(131) => 'a', chr(196).chr(132) => 'A', chr(196).chr(133) => 'a', chr(196).chr(134) => 'C', chr(196).chr(135) => 'c', chr(196).chr(136) => 'C', chr(196).chr(137) => 'c', chr(196).chr(138) => 'C', chr(196).chr(139) => 'c', chr(196).chr(140) => 'C', chr(196).chr(141) => 'c', chr(196).chr(142) => 'D', chr(196).chr(143) => 'd', chr(196).chr(144) => 'D', chr(196).chr(145) => 'd', chr(196).chr(146) => 'E', chr(196).chr(147) => 'e', chr(196).chr(148) => 'E', chr(196).chr(149) => 'e', chr(196).chr(150) => 'E', chr(196).chr(151) => 'e', chr(196).chr(152) => 'E', chr(196).chr(153) => 'e', chr(196).chr(154) => 'E', chr(196).chr(155) => 'e', chr(196).chr(156) => 'G', chr(196).chr(157) => 'g', chr(196).chr(158) => 'G', chr(196).chr(159) => 'g', chr(196).chr(160) => 'G', chr(196).chr(161) => 'g', chr(196).chr(162) => 'G', chr(196).chr(163) => 'g', chr(196).chr(164) => 'H', chr(196).chr(165) => 'h', chr(196).chr(166) => 'H', chr(196).chr(167) => 'h', chr(196).chr(168) => 'I', chr(196).chr(169) => 'i', chr(196).chr(170) => 'I', chr(196).chr(171) => 'i', chr(196).chr(172) => 'I', chr(196).chr(173) => 'i', chr(196).chr(174) => 'I', chr(196).chr(175) => 'i', chr(196).chr(176) => 'I', chr(196).chr(177) => 'i', chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij', chr(196).chr(180) => 'J', chr(196).chr(181) => 'j', chr(196).chr(182) => 'K', chr(196).chr(183) => 'k', chr(196).chr(184) => 'k', chr(196).chr(185) => 'L', chr(196).chr(186) => 'l', chr(196).chr(187) => 'L', chr(196).chr(188) => 'l', chr(196).chr(189) => 'L', chr(196).chr(190) => 'l', chr(196).chr(191) => 'L', chr(197).chr(128) => 'l', chr(197).chr(129) => 'L', chr(197).chr(130) => 'l', chr(197).chr(131) => 'N', chr(197).chr(132) => 'n', chr(197).chr(133) => 'N', chr(197).chr(134) => 'n', chr(197).chr(135) => 'N', chr(197).chr(136) => 'n', chr(197).chr(137) => 'N', chr(197).chr(138) => 'n', chr(197).chr(139) => 'N', chr(197).chr(140) => 'O', chr(197).chr(141) => 'o', chr(197).chr(142) => 'O', chr(197).chr(143) => 'o', chr(197).chr(144) => 'O', chr(197).chr(145) => 'o', chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe', chr(197).chr(148) => 'R',chr(197).chr(149) => 'r', chr(197).chr(150) => 'R',chr(197).chr(151) => 'r', chr(197).chr(152) => 'R',chr(197).chr(153) => 'r', chr(197).chr(154) => 'S',chr(197).chr(155) => 's', chr(197).chr(156) => 'S',chr(197).chr(157) => 's', chr(197).chr(158) => 'S',chr(197).chr(159) => 's', chr(197).chr(160) => 'S', chr(197).chr(161) => 's', chr(197).chr(162) => 'T', chr(197).chr(163) => 't', chr(197).chr(164) => 'T', chr(197).chr(165) => 't', chr(197).chr(166) => 'T', chr(197).chr(167) => 't', chr(197).chr(168) => 'U', chr(197).chr(169) => 'u', chr(197).chr(170) => 'U', chr(197).chr(171) => 'u', chr(197).chr(172) => 'U', chr(197).chr(173) => 'u', chr(197).chr(174) => 'U', chr(197).chr(175) => 'u', chr(197).chr(176) => 'U', chr(197).chr(177) => 'u', chr(197).chr(178) => 'U', chr(197).chr(179) => 'u', chr(197).chr(180) => 'W', chr(197).chr(181) => 'w', chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y', chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z', chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z', chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z', chr(197).chr(190) => 'z', chr(197).chr(191) => 's', // Decompositions for Latin Extended-B chr(200).chr(152) => 'S', chr(200).chr(153) => 's', chr(200).chr(154) => 'T', chr(200).chr(155) => 't', // Euro Sign chr(226).chr(130).chr(172) => 'E', // GBP (Pound) Sign chr(194).chr(163) => '', // Vowels with diacritic (Vietnamese) // unmarked chr(198).chr(160) => 'O', chr(198).chr(161) => 'o', chr(198).chr(175) => 'U', chr(198).chr(176) => 'u', // grave accent chr(225).chr(186).chr(166) => 'A', chr(225).chr(186).chr(167) => 'a', chr(225).chr(186).chr(176) => 'A', chr(225).chr(186).chr(177) => 'a', chr(225).chr(187).chr(128) => 'E', chr(225).chr(187).chr(129) => 'e', chr(225).chr(187).chr(146) => 'O', chr(225).chr(187).chr(147) => 'o', chr(225).chr(187).chr(156) => 'O', chr(225).chr(187).chr(157) => 'o', chr(225).chr(187).chr(170) => 'U', chr(225).chr(187).chr(171) => 'u', chr(225).chr(187).chr(178) => 'Y', chr(225).chr(187).chr(179) => 'y', // hook chr(225).chr(186).chr(162) => 'A', chr(225).chr(186).chr(163) => 'a', chr(225).chr(186).chr(168) => 'A', chr(225).chr(186).chr(169) => 'a', chr(225).chr(186).chr(178) => 'A', chr(225).chr(186).chr(179) => 'a', chr(225).chr(186).chr(186) => 'E', chr(225).chr(186).chr(187) => 'e', chr(225).chr(187).chr(130) => 'E', chr(225).chr(187).chr(131) => 'e', chr(225).chr(187).chr(136) => 'I', chr(225).chr(187).chr(137) => 'i', chr(225).chr(187).chr(142) => 'O', chr(225).chr(187).chr(143) => 'o', chr(225).chr(187).chr(148) => 'O', chr(225).chr(187).chr(149) => 'o', chr(225).chr(187).chr(158) => 'O', chr(225).chr(187).chr(159) => 'o', chr(225).chr(187).chr(166) => 'U', chr(225).chr(187).chr(167) => 'u', chr(225).chr(187).chr(172) => 'U', chr(225).chr(187).chr(173) => 'u', chr(225).chr(187).chr(182) => 'Y', chr(225).chr(187).chr(183) => 'y', // tilde chr(225).chr(186).chr(170) => 'A', chr(225).chr(186).chr(171) => 'a', chr(225).chr(186).chr(180) => 'A', chr(225).chr(186).chr(181) => 'a', chr(225).chr(186).chr(188) => 'E', chr(225).chr(186).chr(189) => 'e', chr(225).chr(187).chr(132) => 'E', chr(225).chr(187).chr(133) => 'e', chr(225).chr(187).chr(150) => 'O', chr(225).chr(187).chr(151) => 'o', chr(225).chr(187).chr(160) => 'O', chr(225).chr(187).chr(161) => 'o', chr(225).chr(187).chr(174) => 'U', chr(225).chr(187).chr(175) => 'u', chr(225).chr(187).chr(184) => 'Y', chr(225).chr(187).chr(185) => 'y', // acute accent chr(225).chr(186).chr(164) => 'A', chr(225).chr(186).chr(165) => 'a', chr(225).chr(186).chr(174) => 'A', chr(225).chr(186).chr(175) => 'a', chr(225).chr(186).chr(190) => 'E', chr(225).chr(186).chr(191) => 'e', chr(225).chr(187).chr(144) => 'O', chr(225).chr(187).chr(145) => 'o', chr(225).chr(187).chr(154) => 'O', chr(225).chr(187).chr(155) => 'o', chr(225).chr(187).chr(168) => 'U', chr(225).chr(187).chr(169) => 'u', // dot below chr(225).chr(186).chr(160) => 'A', chr(225).chr(186).chr(161) => 'a', chr(225).chr(186).chr(172) => 'A', chr(225).chr(186).chr(173) => 'a', chr(225).chr(186).chr(182) => 'A', chr(225).chr(186).chr(183) => 'a', chr(225).chr(186).chr(184) => 'E', chr(225).chr(186).chr(185) => 'e', chr(225).chr(187).chr(134) => 'E', chr(225).chr(187).chr(135) => 'e', chr(225).chr(187).chr(138) => 'I', chr(225).chr(187).chr(139) => 'i', chr(225).chr(187).chr(140) => 'O', chr(225).chr(187).chr(141) => 'o', chr(225).chr(187).chr(152) => 'O', chr(225).chr(187).chr(153) => 'o', chr(225).chr(187).chr(162) => 'O', chr(225).chr(187).chr(163) => 'o', chr(225).chr(187).chr(164) => 'U', chr(225).chr(187).chr(165) => 'u', chr(225).chr(187).chr(176) => 'U', chr(225).chr(187).chr(177) => 'u', chr(225).chr(187).chr(180) => 'Y', chr(225).chr(187).chr(181) => 'y', // Vowels with diacritic (Chinese, Hanyu Pinyin) chr(201).chr(145) => 'a', // macron chr(199).chr(149) => 'U', chr(199).chr(150) => 'u', // acute accent chr(199).chr(151) => 'U', chr(199).chr(152) => 'u', // caron chr(199).chr(141) => 'A', chr(199).chr(142) => 'a', chr(199).chr(143) => 'I', chr(199).chr(144) => 'i', chr(199).chr(145) => 'O', chr(199).chr(146) => 'o', chr(199).chr(147) => 'U', chr(199).chr(148) => 'u', chr(199).chr(153) => 'U', chr(199).chr(154) => 'u', // grave accent chr(199).chr(155) => 'U', chr(199).chr(156) => 'u', ); /* // Used for locale-specific rules $locale = get_locale(); if ( 'de_DE' == $locale ) { $chars[ chr(195).chr(132) ] = 'Ae'; $chars[ chr(195).chr(164) ] = 'ae'; $chars[ chr(195).chr(150) ] = 'Oe'; $chars[ chr(195).chr(182) ] = 'oe'; $chars[ chr(195).chr(156) ] = 'Ue'; $chars[ chr(195).chr(188) ] = 'ue'; $chars[ chr(195).chr(159) ] = 'ss'; } elseif ( 'da_DK' === $locale ) { $chars[ chr(195).chr(134) ] = 'Ae'; $chars[ chr(195).chr(166) ] = 'ae'; $chars[ chr(195).chr(152) ] = 'Oe'; $chars[ chr(195).chr(184) ] = 'oe'; $chars[ chr(195).chr(133) ] = 'Aa'; $chars[ chr(195).chr(165) ] = 'aa'; } */ $string = strtr($string, $chars); } else { $chars = array(); // Assume ISO-8859-1 if not UTF-8 $chars['in'] = chr(128).chr(131).chr(138).chr(142).chr(154).chr(158) .chr(159).chr(162).chr(165).chr(181).chr(192).chr(193).chr(194) .chr(195).chr(196).chr(197).chr(199).chr(200).chr(201).chr(202) .chr(203).chr(204).chr(205).chr(206).chr(207).chr(209).chr(210) .chr(211).chr(212).chr(213).chr(214).chr(216).chr(217).chr(218) .chr(219).chr(220).chr(221).chr(224).chr(225).chr(226).chr(227) .chr(228).chr(229).chr(231).chr(232).chr(233).chr(234).chr(235) .chr(236).chr(237).chr(238).chr(239).chr(241).chr(242).chr(243) .chr(244).chr(245).chr(246).chr(248).chr(249).chr(250).chr(251) .chr(252).chr(253).chr(255); $chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy"; $string = strtr($string, $chars['in'], $chars['out']); $double_chars = array(); $double_chars['in'] = array(chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254)); $double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th'); $string = str_replace($double_chars['in'], $double_chars['out'], $string); } return $string; } } ?>