?$~i'; //John D. $rxEML = '~(^|\s)([^@\s]{2,40})@((?:[^@\s\.]{2,30}\.)*[^@\s\.]{2,30}).(\w{2,6})(?:\s*\[([^<>\[]+?)\])?(\.|\s|<|$)~im'; //jd@skyweb.com [title] $rxELink = "~]+>([^<>]+)~i"; //... $rxULink = '~]*?href=["\'](https?://([^|<>\s]{5,}))["\'][^|<>]*?>([^|<>]*?)~i'; //title $rxURL = '~(^|\s)(https?://)([^\s\[\<$]{5,}[^.\s\[\<$])(?:\s*\[([^<>\[]+?)\])?(\.|\s|<|$)~im'; //http://www.mysite.xxx [title] $rxCalURL = '~^(https?://)?((?:[\w-:]+\.)+[a-z]{2,15}(?:[/?#:][^<>\s\[]*)?|localhost(?::[0-9]{1,3})?|(?:[0-9]{1,3}\.){3}[0-9]{1,3})(/[^<>\s\[]+)*/?$~i'; //http://XXX/mycal/calendar.php (XXX = www.mysite.xxx | localhost:70 | ip address) $rxIMGTags = '~~i'; // $rxIMG = '~(?:^|\s)(([^\s/.]*/)*([^\s/.]+\.(?:gif|jpg|png)))(?:\.|\s|$)~i'; //thumbnails/mynail.gif (or .jpg, or .png) $attType = '|.pdf|.jpg|.gif|.png|.ogg|.mp4|.webm|.wma|.wav|.avi|.mpg|.mov|.wmv'; //attachement file types /*---------- TOOLBOX FUNCTIONS ----------*/ function mbtrunc($string,$length) { //multi-byte utf-8 truncate on char boundary if (strlen($string) <= $length) { return $string; } $ordNext = ord($string[$length]); if ($ordNext <= 127 or $ordNext >= 194) { return substr($string,0,$length); } //next byte is single byte or 1st byte of mb for ($i = ($length - 1); $i >= 0; $i--) { if (ord($string[$i]) <= 127) { return substr($string,0,$i+1); } //single byte if (ord($string[$i]) >= 194) { return substr($string,0,$i); } //1st byte of mb } return ''; //empty } function eol2txt($string) { //replace \n\r characters to {nl}{cr} return preg_replace(array("~\n~","~\r~"),array("{nl}","{cr}"),$string); } //Time formatting function ITtoDT($time,$format = '') { //convert hh:mm(:ss) to display time global $set; if (!$time) { return ''; } if (!$format) { $format = $set['timeFormat']; } $ampm = stripos($format,'a') !== false; if ($ampm and substr($time,0,2) =='24') { $time = '12'.substr($time,2); } $phpFormat = str_replace(array('H','h','m'),array(($ampm ? 'h' : 'H'),($ampm ? 'g' : 'G'),'i'),$format); return date($phpFormat,strtotime($time)); } function DTtoIT($time,$format = '') { //convert Display Time to ISO Time hh:mm global $set; $time = trim($time); if (!$time) { return ''; } if (!$format) { $format = $set['timeFormat']; } $ampm = stripos($format,'a') !== false; $regEx = $ampm ? '(0{0,1}[0-9]|1[0-2])[:.][0-5][0-9]\s*(a|A|p|P)(m|M)' : '(0{0,1}[0-9]|1[0-9]|2[0-4])[:.][0-5][0-9]([:.][0-5][0-9]){0,1}'; if (!preg_match("%^".$regEx."$%",$time)) { return false; } $tStamp = strtotime($time); return ($tStamp < 1) ? false : date("H:i", $tStamp); } //Date formatting function IDtoDD($date,$format = '') { //convert ISO date (yyyy mm dd) to display date global $set; if (!$date) { return ''; } if (!$format) { $format = $set['dateFormat']; } return str_replace(array('y','m','d'),array(substr($date,0,4),substr($date,5,2),substr($date,8,2)),$format); } function IDTtoDDT($dateTime) { //convert ISO date+time (yyyy mm dd hh:mm:ss) to display date global $xx; $date = substr($dateTime,0,10); if (!$date) { return ''; } $time = substr($dateTime,11,5); $dD = IDtoDD($date); $dT = ITtoDT($time); return $dD.($dT ? " {$xx['at_time']} {$dT}" : ''); } function DDtoID($date,$format = '') { //validate display date and convert to ISO date (yyyy-mm-dd) global $set; $date = trim($date); if (!$date) { return ''; } if (!$format) { $format = $set['dateFormat']; } $indexY = strpos($format,'y') / 2; $indexM = strpos($format,'m') / 2; $indexD = strpos($format,'d') / 2; $split = preg_split('%[^\d]%',$date); if ($split[$indexY] < 1900 or $split[$indexY] > 2099) { return false; } //year out of range if (!checkdate(intval($split[$indexM]),intval($split[$indexD]),intval($split[$indexY]))) { return false; } //invalid date return $split[$indexY]."-".str_pad($split[$indexM], 2, "0", STR_PAD_LEFT)."-".str_pad($split[$indexD], 2, "0", STR_PAD_LEFT); } function makeD($date,$formatNr,$x3 = '') { //make long date global $set, $months, $months_m, $wkDays, $wkDays_l; $y = substr($date, 0, 4); $m = ltrim(substr($date, 5, 2),"0"); $d = ltrim(substr($date, 8, 2),"0"); if ($formatNr > 3) { $wdNr = date("N", mktime(12,0,0,$m,$d,$y)); $wkDay = $x3 ? $wkDays_l[$wdNr] : $wkDays[$wdNr]; } $month = $x3 ? $months_m[$m - 1] : $months[$m - 1]; switch ($formatNr) { case 1: //Dec... 9 / 9 dec... return str_replace(array('d','M'),array($d,$month),$set['MdFormat']); case 2: //Dec... 9, 2018 / 9 dec... 2018 return str_replace(array('d','y','M'),array($d,$y,$month),$set['MdyFormat']); case 3: //Dec... 2018 / dec... 2018 return str_replace(array('y','M'),array($y,$month),$set['MyFormat']); case 4: //Mon..., Dec... 9 / mon 9 dec return str_replace(array('d','M','WD'),array($d,$month,$wkDay),$set['DMdFormat']); case 5: //Mon..., Dec... 9, 2018 / mon... 9 dec... 2018 return str_replace(array('d','y','M','WD'),array($d,$y,$month,$wkDay),$set['DMdyFormat']); } } function makeFullDT($iso,$sda,$eda,$sti,$eti) { //make full date/time global $xx; $fullDT = $iso ? IDtoDD($sda) : $sda; if ($sti) { $fullDT .= " {$xx['at_time']} ".($iso ? ITtoDT($sti) : $sti); } if ($eda or $eti) { $fullDT .= ' -'; } if ($eda) { $fullDT .= ' '.($iso ? IDtoDD($eda) : $eda).($eti ? " {$xx['at_time']}" : ''); } if ($eti) { $fullDT .= ' '.($iso ? ITtoDT($eti) : $eti); } if (!$sti and !$eti) { $fullDT .= " {$xx['vws_all_day']}"; } return $fullDT; } function makeHovT(&$evt) { //make hover box time switch ($evt['mde']) { //multi-day event? case 0: return ITtoDT($evt['sti']).($evt['eti'] ? ' - '.ITtoDT($evt['eti']) : ''); //no case 1: return (($evt['sti'] != '00:00' and $evt['sti'] != '') ? ITtoDT($evt['sti']) : '•').'···'; //first case 2: return '···'; //in between case 3: return '···'.(($evt['eti'] < '23:59' and $evt['eti'] != '') ? ITtoDT($evt['eti']) : '•'); //last } } function repeatText($type,$interval,$period,$rmonth,$until) { //make repeat text global $xx, $months, $wkDays; switch ($type) { case -1: $repTxt = "{$xx['evt_repeat_not_supported']}"; break; case 0: $repTxt = ''; break; case 1: $repTxt = $xx['evt_repeat_on'].' '.$interval.' '.$xx['evt_period1_'.$period]; break; case 2: $repTxt = $xx['evt_repeat_on'].' '.$xx['evt_interval2_'.$interval].' '.$wkDays[$period].' '.$xx['of'].' '.($rmonth ? $months[$rmonth-1] : $xx['evt_each_month']); } if ($type > 0 and $until) { $repTxt .= " {$xx['evt_until']} ".IDtoDD($until); } return $repTxt; } function makeE(&$evt,$template,$type,$glue,$show = '12345678') { //make event body using template global $set, $usr, $xx; if (!$set['xField1Public'] and $usr['ID'] == 1) { $show = str_replace('4','',$show); } //exclude xField 1 if (!$set['xField2Public'] and $usr['ID'] == 1) { $show = str_replace('5','',$show); } //exclude xField 2 $eArray = array(); if ($type == 'br') { //type br foreach (str_split($template) as $fieldNr) { if (strpos($show,$fieldNr) === false) { continue; } switch ($fieldNr) { case '1': if ($evt['ven']) { $eArray[] = "{$xx['evt_venue']}: {$evt['ven']}"; } break; case '2': $eArray[] = "{$xx['evt_category']}: {$evt['cnm']}".($evt['snm'] ? " - {$evt['snm']}" : ''); break; case '3': if ($evt['des']) { $eArray[] = $evt['des']; } break; case '4': if ($evt['xf1']) { $eArray[] = ($set['xField1Label'] ? "{$set['xField1Label']}: " : '').$evt['xf1']; } break; case '5': if ($evt['xf2']) { $eArray[] = ($set['xField2Label'] ? "{$set['xField2Label']}: " : '').$evt['xf2']; } break; case '6': if ($evt['nom'] >= 0) { $eArray[] = "{$xx['vws_notify']}: {$evt['nom']} {$xx['vws_days']}"; } break; if ($evt['nos'] >= 0) { $eArray[] = "{$xx['vws_notify']}: {$evt['nos']} {$xx['vws_days']}"; } break; case '7': $eArray[] = "{$xx['vws_added']}: ".IDTtoDDT($evt['adt'])." ({$evt['una']})"; if ($evt['mdt'] and $evt['edr']) { $eArray[] = "{$xx['vws_edited']}: ".IDTtoDDT($evt['mdt'])." ({$evt['edr']})"; } break; case '8': // if ($evt['att']) { $eArray[] = $xx['evt_attachments'].': '.trim(preg_replace('%;\d{14}%',', ',$evt['att']),', '); } if ($evt['att']) { $attachments = array(); foreach(explode(';',trim($evt['att'],';')) as $attachment) { $attachments[] = "".substr($attachment,14).""; } $eArray[] = $xx['evt_attachments'].': '.implode(', ',$attachments); } } } } else { //type td foreach (str_split($template) as $fieldNr) { if (strpos($show,$fieldNr) === false) { continue; } switch ($fieldNr) { case '1': if ($evt['ven']) { $eArray[] = "{$xx['evt_venue']}:{$evt['ven']}"; } break; case '2': $eArray[] = "{$xx['evt_category']}:{$evt['cnm']}".($evt['snm'] ? " - {$evt['snm']}" : '').""; break; case '3': if ($evt['des']) { $eArray[] = "{$xx['evt_description']}:{$evt['des']}"; } break; case '4': if ($evt['xf1']) { $eArray[] = "{$set['xField1Label']}:{$evt['xf1']}"; } break; case '5': if ($evt['xf2']) { $eArray[] = "{$set['xField2Label']}:{$evt['xf2']}"; } break; case '6': if ($evt['nom'] >= 0) { $eArray[] = "{$xx['vws_notify']}:{$evt['nom']} {$xx['vws_days']}"; } break; if ($evt['nos'] >= 0) { $eArray[] = "{$xx['vws_notify']}:{$evt['nos']} {$xx['vws_days']}"; } break; case '7': $eArray[] = "{$xx['vws_added']}:".IDTtoDDT($evt['adt'])." ({$evt['una']})"; if ($evt['mdt'] and $evt['edr']) { $eArray[] = "{$xx['vws_edited']}:".IDTtoDDT($evt['mdt'])." ({$evt['edr']})"; } break; case '8': if ($evt['att']) { $label = $xx['evt_attachments'].':'; foreach(explode(';',trim($evt['att'],';')) as $attachment) { $eArray[] = "{$label}".substr($attachment,14).""; $label = ''; } } } } } return implode($glue,$eArray); } //get calendar base URL (used at install) function calBaseUrl() { $baseUrl = 'http'.(!empty($_SERVER['HTTPS']) ? 's' : '').'://'.$_SERVER['SERVER_NAME']; if ($_SERVER["SERVER_PORT"] != '80') { $baseUrl .= ':'.$_SERVER['SERVER_PORT']; } $baseUrl .= rtrim(dirname($_SERVER["PHP_SELF"]),'/').'/'; // add calendar directory return $baseUrl; } //get calendar root URL function calRootUrl() { global $set; $rootUrl = strpos($set['calendarUrl'],'?') !== false ? strstr($set['calendarUrl'],'?',true) : $set['calendarUrl']; $rootUrl = strpos($rootUrl,'/index.php') !== false ? strstr($rootUrl,'/index.php',true) : $rootUrl; return rtrim($rootUrl,'/').'/'; } //add URL, IMG and EML links function addUrlImgEmlTags($html,$uie='xxx') { global $set, $rxURL, $rxIMG, $rxEML, $xx; if ($uie[0] == 'x') { //create URL links $html = preg_replace_callback($rxURL,function ($m) { return "{$m[1]}".(!empty($m[4])?$m[4]:$m[3])."{$m[5]}"; },$html); } if ($uie[1] == 'x') { //create image links $html = preg_replace_callback($rxIMG,function ($m) { return " {$m[3]}"; },$html); } if ($uie[2] == 'x') { //create email links $html = preg_replace_callback($rxEML,function ($m) { global $tit, $xx; return "{$m[1]}".(!empty($m[5])?$m[5]:$xx['vws_send_mail'])."{$m[6]}"; },$html); } return $html; } //remove URL, IMG and EML links function remUrlImgEmlTags($html,$uie='xxx') { global $rxULink, $rxIMGTags, $rxELink; if ($uie[0] == 'x') { //remove URL links $html = preg_replace_callback($rxULink,function ($m) { return $m[1].($m[2]!=$m[3]?" [".$m[3]."]":""); },$html); } if ($uie[1] == 'x') { //remove image links $html = preg_replace($rxIMGTags,"$1 ",$html); } if ($uie[2] == 'x') { //remove email links $html = preg_replace($rxELink,"$1@$2.$3 [$4]",$html); } return $html; } //chunk split unicode string function chunk_split_unicode($str,$len,$eol) { $chunks = array_chunk(preg_split('%%u',$str,-1,PREG_SPLIT_NO_EMPTY),$len); $str = ''; foreach ($chunks as $chunk) { $str .= implode($chunk).$eol; } return rtrim($str); } //transliterate text string (e.g. file name) function translit($text,$strict=false) { setlocale(LC_CTYPE,'en_US'); $transText = iconv('UTF-8','ASCII//TRANSLIT',$text); if ($strict) { return str_replace(array(' ','/','\\','?','%','*',':',';','{','}',"'",'"'),'_',$transText); } else { return $transText; } } //Validate index.php vars function validVars() { $passed = true; foreach ($_GET as $key => $value) { switch ($key) { case 'cal': $passed = preg_match('~^\w{1,20}?$~',$value); break; case 'cP': $passed = preg_match('~^(\d{1,3}|up)$~',$value); break; case 'cG': $passed = (is_array($value) and ctype_digit(implode($value))); break; case 'cU': $passed = (is_array($value) and ctype_digit(implode($value))); break; case 'cC': $passed = (is_array($value) and ctype_digit(implode($value))); break; case 'cL': $passed = empty($value) ? true : preg_match('~^[a-zA-Z]{1,12}$~',$value); break; case 'cD': $passed = empty($value) ? true : preg_match('~^\d{4}-\d{2}-\d{2}$~',$value); break; case 'hdr': $passed = preg_match('~^(0|1|-1|-2)$~',$value); break; default: if (is_string($value)) $_GET[$key] = htmlspecialchars(strip_tags(trim($value)),ENT_QUOTES,'UTF-8'); } if (!$passed) { logMessage('luxcal',2,'Access denied. Invalid GET variable ('.$key.'='.htmlspecialchars($value,ENT_QUOTES,'UTF-8').')'); exit('not permitted (index.php - invalid var: '.$key.')'); } } if (!empty($_POST)) { //validate POST vars $error = empty($_POST['lcI']) ? 'No PT' : ($_POST['lcI'] == 'i' ? '' : (empty($_SESSION['lcI']) ? 'No ST' : ($_SESSION['lcI'] != $_POST['lcI'] ? 'invalid PT' : ''))); if ($error) { logMessage('luxcal',2,"Access denied. Spoofed form submission detected.\nForm input keys:\n- ".implode("\n- ",array_keys($_POST))); unset($_SESSION['lcI']); exit("not permitted (CSRF)
{$error}"); } foreach ($_POST as $key => $value) { if (is_string($value)) { $_POST[$key] = strip_tags(trim($value),'
'); } } } } //Log message function logMessage($logName,$level,$logMsg,$script='-') { global $set; if ($level < 2 or ($level == 2 and $set['logWarnings']) or ($level == 3 and $set['logNotices'])) { date_default_timezone_set(@date_default_timezone_get()); $levels = array(1 => 'ERROR','WARNING','NOTICE'); if ($script == '-') { $script = $_SERVER['PHP_SELF']; } $intro = $level ? "\n".date('Y.m.d H:i:s')." {$levels[$level]} Script: ".htmlentities($script) : ''; //new message file_put_contents("./logs/{$logName}.log", "{$intro} - {$logMsg}", FILE_APPEND); } } //Save session data to cookie LCAL_ function saveLastSel($calID,$bake = 1) { global $set, $opt; if (!empty($_SESSION)) { $lastSet = array('cP' => $opt['cP'],'cG' => $opt['cG'],'cU' => $opt['cU'],'cC' => $opt['cC'],'cL' => $opt['cL']); setcookie('LCAL_'.$calID, serialize($lastSet), time()+(86400 * $set['cookieExp']*$bake)); //keep data for 'cookieExp' days } } //Load session data from cookie LCAL_ function loadLastSel($calID) { $lastSet = isset($_COOKIE['LCAL_'.$calID]) ? @unserialize($_COOKIE['LCAL_'.$calID]) : false; if ($lastSet) { $_SESSION['cP'] = $lastSet['cP']; $_SESSION['cG'] = isset($lastSet['cG']) ? $lastSet['cG'] : array(0); //cG in cookie as of V4.3 $_SESSION['cU'] = $lastSet['cU']; $_SESSION['cC'] = $lastSet['cC']; $_SESSION['cL'] = $lastSet['cL']; } } //Check for mobile browser (returns 0: not mobile, 1: tablet or 2: mobile small screen size) function isMobile() { $userAgent = !empty($_SERVER['HTTP_USER_AGENT']) ? strtolower($_SERVER['HTTP_USER_AGENT']) : ''; $mobileAgents = array( 'w3c ','acs-','alav','alca','amoi','audi','avan','benq','bird','blac', 'blaz','brew','cell','cldc','cmd-','dang','doco','eric','hipt','inno', 'ipaq','java','jigs','kddi','keji','leno','lg-c','lg-d','lg-g','lge-', 'maui','maxo','midp','mits','mmef','mobi','mot-','moto','mwbp','nec-', 'newt','noki','oper','palm','pana','pant','phil','play','port','prox', 'qwap','sage','sams','sany','sch-','sec-','send','seri','sgh-','shar', 'sie-','siem','smal','smar','sony','sph-','symb','t-mo','teli','tim-', 'tosh','tsm-','upg1','upsi','vk-v','voda','wap-','wapa','wapi','wapp', 'wapr','webc','winw','winw','xda','xda-' ); if (preg_match('%(tablet|ipad|playbook)|(android(?!.*(mobi|opera mini)))%', $userAgent)) { return 1; //mobile but tablet } if (preg_match('%(symbian|midp|mobile|phone|ipod|android)%',$userAgent)) { return 2; //mobile } elseif ((!empty($_SERVER['HTTP_ACCEPT'])) and (strpos(strtolower($_SERVER['HTTP_ACCEPT']),'application/vnd.wap.xhtml+xml') !== false)) { return 2; //mobile } elseif (in_array((substr($userAgent,0,4)),$mobileAgents)) { return 2; //mobile } return 0; } ?>