120, "H"=>120, "M"=>1, "B"=>2, )); SDVA($ReminderSPat, array("/^(\\*|[:]?{$ReminderLogKeyword}[:])\\s*(=|~)(w?\\d\\d?)(?:\\/(\\d\\d?))?(?:\\/(\\d{4}))?\\s/m" =>'mu_remindernext' )); function mu_remindernext($m) { return ReminderNext($m[1].' '.$m[2], $m[3], $m[4], $m[5]); } SDV($RemindersLogs, array("\$SiteGroup.AllReminders")); $MarkupExpr['remtoday'] = 'Keep(str_replace("\'", "'", FmtReminder($args[0], "$args[0] today=$args[1] pastdays=0 futuredays=0 dayheaders=0 liststyle=0" ) ))'; function FmtToSec($f, $mtply=1) { global $Now; return intval(ltrim(PSFT($f, $Now), '0'))*$mtply; } function EasterJD($y) { $western = gregoriantojd(3, 21, $y); $eastern = juliantojd(3, 21, $y); $wadd = easter_days($y, CAL_EASTER_ALWAYS_GREGORIAN); $eadd = easter_days($y, CAL_EASTER_ALWAYS_JULIAN); return array('W'=>$western+$wadd, 'E'=>$eastern+$eadd); } function NthWeekdayMonthYear($nth, $dow, $month, $year) { if($nth>=1) { $first = strtotime("$year-$month-01"); $fdow = date('w', $first); $offset = ($dow - $fdow + 7) % 7; $firstweekday = strtotime("+$offset days", $first); } else { $last = strtotime("last day of $year-$month"); $ldow = date('w', $last); $offset = ($ldow - $dow + 7) % 7; $lastweekday = strtotime("-$offset days", $last); } if($nth == 1) $wday = $firstweekday; elseif($nth == 0) $wday = $lastweekday; elseif($nth>1) { $wday = strtotime("+" . ($nth-1) . " weeks", $firstweekday); } elseif($nth<0) { $wday = strtotime("$nth weeks", $lastweekday); } return PSFT('%m-%d', $wday); } function FmtReminder($pagename, $args, $content='') { global $Now, $InputValues, $ReminderPastDays, $ReminderFutureDays, $ReminderTable, $ReminderFmt, $ReminderLocale, $ReminderDayMonth, $ReminderDateFormat, $ReminderIncludeSuffix, $HTMLStylesFmt, $EnableReminderRefresh, $EnableReminderEmptyDays, $SiteAllReminders, $QualifyPatterns, $HTMLHeaderFmt, $ReminderWeeklyFix; if($EnableReminderRefresh) { $sec = 24*3600 - (FmtToSec('%H', 3600) + FmtToSec('%M', 60) + FmtToSec('%S'))+300; $HTMLHeaderFmt['refresh-reminder'] = ""; } $opt = ParseArgs($args); $TH = IsEnabled($opt['th'], $ReminderTable["H"]); $TW = IsEnabled($opt['tw'], $ReminderTable['W']); $TM = IsEnabled($opt['tm'], $ReminderTable['M']); $TB = IsEnabled($opt['tb'], $ReminderTable['B']); $drur = "div.remtable ul.reminder"; $HTMLStylesFmt['remtable'] = "$drur { font-size: 90%; line-height: 1.1em; } $drur li.date { position: relative; display: block; float: left; overflow: hidden; height: {$TH}px; width: {$TW}px; border: {$TB}px solid #ddd; margin-left: {$TM}px; } $drur li.date:hover { overflow: visible; z-index: 50;} $drur li.today { border: {$TB}px solid #a00; font-size: inherit; } $drur li.empty { border-color: #fff; background-color: #fff;}\n"; if(isset($opt['weeks'])) $HTMLStylesFmt['remtable'] .= "$drur li.w{$opt['weeks']} { clear: left;}\n"; $Tsptintf = "$drur li.w%d:first-child, $drur li.overdue + li.w%d {margin-left: %dpx;}\n"; for($i=1; $i<8; $i++) { $j = $i%7; $k = $i-1; $margin = $k*($TW+2*$TB+$TM); // $HTMLStylesFmt['remtable'] .= sprintf($Tsptintf, $j, $j, $margin); } $TodayNow = IsEnabled($opt['today'], PSFT('%Y-%m-%d', $Now)); $TodayNow2 = IsEnabled($opt['today'], PSFT('%Y%m%d', $Now)); if(! strpos($TodayNow, '-') ) $TodayNow = PSFT('%Y-%m-%d', strtotime($TodayNow) ); $dayheaders = IsEnabled($opt['dayheaders'], 1); $liststyle = IsEnabled($opt['liststyle'], 1); $expired = IsEnabled($opt['expired'], 1); $pastdays = IsEnabled($opt['pastdays'], $ReminderPastDays); $futuredays = IsEnabled($opt['futuredays'], $ReminderFutureDays); $locale = IsEnabled($opt['locale'], $ReminderLocale); $datefmt = IsEnabled($opt['datefmt'], $ReminderDateFormat); $emptydays = (@$opt['emptydays']>'')? $opt['emptydays'] : $EnableReminderEmptyDays; $df = explode('/', $ReminderDayMonth); $onemonth = intval(IsEnabled($opt['onemonth'], @$_REQUEST['onemonth'])); $CurrentYear = intval(date('Y')); $NextYear = $CurrentYear+1; $easterdays = array(); for($i=0; $i<3; $i++) { $easterdays[$i] = EasterJD($CurrentYear+$i); } $julianday = unixtojd(); if(@$opt[''][0]>'')$content .= "\n". IncludeText($pagename, $opt[''][0]); if($locale)setlocale(LC_TIME, $locale); $_DATES = array(); $lines = explode("\n", $content); $out = ""; if($ReminderIncludeSuffix) { $QP = array('/(REM)?$/m'=>'$1'.$ReminderIncludeSuffix) +$QualifyPatterns; $QualifyPatterns = $QP; } $restart=1; while($restart) { $restart=0; foreach($lines as $i=>$line) if(preg_match("/^#include (.*?)$/", $line, $m)) { array_splice($lines, count($lines), 0, explode("\n", IncludeText($pagename, PSS($m[1])))); $lines[$i]=''; $restart=1; } } if($ReminderIncludeSuffix) unset($QualifyPatterns['/(REM)?$/m']); foreach($lines as $line) { if(@$line[0]!='*') continue; $line = preg_replace_callback('/\\{(\\*|!?[-\\w.\\/\\x80-\\xff]*)(\\$:?\\w[-\\w]*)\\}/', "MarkupPageVar", $line); $line = preg_replace_callback('/\\{(\\(\\w+\\b.*?\\))\\}/', "MarkupMarkupExpression", $line); @list($when, $what) = explode(' ', preg_replace("/^\\* */", '', $line), 2); $md5 = md5($line); $time = 1500; $iso = false; if(preg_match('/\\b([012]?\\d)[h:]([0-5]\\d)?(\\s+[ap]m)?\\b/i', $what, $m) ) { $time = 60*intval(@$m[1])+intval(@$m[2]); if($time<720 && strpos(' '.strtolower($m[3]) , 'pm')) $time+=720; } # Weekly if( preg_match('/^w(\\d+)$/i', $when, $m)) for($i=0; $isprintf($ReminderFmt, $what, $when, $md5), 'time'=>$time); } # Monthly elseif(preg_match('/^(-?\\d+)$/i', $when, $m)&&$m[1]<32) $_DATES["m".intval($m[1])][] = array('what'=>sprintf($ReminderFmt, $what, $when, $md5), 'time'=>$time); # Sticky elseif( preg_match('/^(=|~)(\\d{4}-(\\d\\d-\\d\\d))$/i', $when, $iso)) { if($iso[2]< $TodayNow && $iso[1] == '=' ) { $_DATES['overdue'][] = sprintf($ReminderFmt, $what, $when, $md5); } else { $_DATES[ $iso[3] ][] = array('what'=>sprintf($ReminderFmt, $what, $when, $md5), 'time'=>$time); } } # Yearly reminders elseif(preg_match('/^(\\d+)\\/(\\d+)(?:\\/(\\d+))?$/i', $when, $m) || preg_match('/^(\\d{4})-?(\\d\\d)-?(\\d\\d)$/i', $when, $iso)) { if(@$iso[0]) { $x = array('m'=>intval($iso[2]), 'd'=>intval($iso[3])); $m = array(3=>$iso[1]); } else $x=array($df[0]=>intval($m[1]),$df[1]=>intval($m[2])); $st = PSFT('%m-%d', strtotime("2000-{$x['m']}-{$x['d']}")); $st2 = sprintf("%02d-%02d", $x['m'], $x['d']); if($st!=$st2) $_DATES['unknown'][] = sprintf($ReminderFmt, $what, $when, $md5); else $_DATES[ $st ][] = array('y'=>@$m[3],'what'=>sprintf($ReminderFmt, $what, $when, $md5), 'time'=>$time); } # Start date, custom interval in days, weeks elseif(preg_match('/^(\\d+)\\/(\\d+)\\/(\\d+)r(\\d+)([dw]?)$/i', $when, $n)) { $m = array_map('intval', $n); $x=array($df[0]=>$m[1], $df[1]=>$m[2], 'y'=>$m[3]); $jdstart = unixtojd(strtotime("{$x['y']}-{$x['m']}-{$x['d']}")); $rdays = $m[4]; if($n[5]=='w') $rdays*=7; $_DATES[ 'custominterval' ][] = array( 'start'=>$jdstart, 'interval'=>$rdays, 'what'=>sprintf($ReminderFmt, $what, $when, $md5), 'time'=>$time); } # Multiple days DateStart..DateEnd elseif(preg_match('/^(\\d{1,2})\\/(\\d{1,2})\\.\\.(\\d{1,2})\\/(\\d{1,2})(?:\\/(\\d{4}))?$/i', $when, $m)) { $x=array($df[0]=>intval($m[1]),$df[1]=>intval($m[2])); $x2=array($df[0]=>intval($m[3]),$df[1]=>intval($m[4])); $y = @$m[5]? $m[5] : 2000; $T1 = strtotime("$y-{$x['m']}-{$x['d']}"); $T2 = strtotime("$y-{$x2['m']}-{$x2['d']}"); if($T1>$T2) { if(@$m[5] || $x2['m']>2) $T1 = strtotime( ($y-1) ."-{$x['m']}-{$x['d']}"); else $T2 = strtotime( ($y+1) ."-{$x2['m']}-{$x2['d']}"); } if( PSFT('%m-%d', $T1)!=sprintf("%02d-%02d", $x['m'], $x['d']) || PSFT('%m-%d', $T2)!=sprintf("%02d-%02d", $x2['m'], $x2['d'])) { $_DATES['unknown'][] = "$what [$when] " .PSFT('%m-%d', $T1).'!='.sprintf("%02d-%02d", $x['m'], $x['d']) ." " .PSFT('%m-%d', $T2).'!='.sprintf("%02d-%02d", $x2['m'], $x2['d']); continue; } if(@$m[5] && PSFT('%Y-%m-%d', $T2)< $TodayNow) { $_DATES['overdue'][] = sprintf($ReminderFmt, $what, $when, $md5); continue; } $T0 = 0; for($i=0; $T0<$T2; $i++) { $T0 = strtotime("+$i days", $T1); $st = PSFT('%m-%d', $T0); $Mtime = $time==1500? 0: $time+1; $_DATES[ "M$st" ][] = array('what'=>sprintf($ReminderFmt, $what, $when, $md5), 'time'=>$Mtime); } } # Easter elseif(preg_match('/^([WE])E([-+]\\d+)([dw]?)$/', $when, $m)) { $days = intval($m[2]); if($m[3]=='w') $days *= 7; for($i=0; $isprintf($ReminderFmt, $what, $when, $md5), 'time'=>$time, 'year'=>$CurrentYear+$i ); } } # Nth Weekday of Month 4w4@11 Thanksgiving elseif(preg_match('/^(-?[012345])w([0-7])@(0?[1-9]|1[012])$/', $when, $m)) { $n = array_map('intval', $m); $dow = ($n[2]+7-$ReminderWeeklyFix)%7; for($i=0; $i<3; $i++) { $st = NthWeekdayMonthYear($n[1], $dow, $n[3], $CurrentYear+$i); $_DATES[$st][] = array( 'what'=>sprintf($ReminderFmt, $what, $when, $md5), 'time'=>$time, 'year'=>$CurrentYear+$i ); } } else $_DATES['unknown'][] = sprintf($ReminderFmt, $what, $when, $md5); } if($expired && isset($_DATES['overdue']) && count($_DATES['overdue']) ) { $out.="\n* %list reminder% %item date overdue% $[Expired]\n"; foreach($_DATES['overdue'] as $v)$out.="** $v\n"; } if($onemonth && $onemonth<13) { $y = $onemonth$jday) continue; $jdiff = $jday - $a['start']; if($jdiff % $a['interval'] === 0) { $out["** %item custom% {$a['what']}\n"] = $a['time']; } } } if(is_array($out) && count($out)>0) { asort($out); $ret = implode('', array_keys($out)); } if(!$liststyle) $ret = preg_replace("/%(list|item).*?%/", '', $ret); if($ret>'' || $emptydays) return ($dayheaders? "* %list reminder% %item date $class w$w%" . PSFT($datefmt, $T). "\n":'') .$ret; } array_unshift($EditFunctions, "ReminderLogAll"); function ReminderLogAll($pagename,&$page,&$new) { global $EnablePost, $RecentChangesFmt, $RemindersLogs, $ReminderSPat, $ReminderLogKeyword; if (!$EnablePost) return; $new['text'] = PPRA($ReminderSPat, $new['text']); if (!@$RemindersLogs[0]) return; $pslash = str_replace('.', '/', $pagename); $pslashE = preg_quote("[[$pslash]]"); $oldmatch = preg_match("/^:?{$ReminderLogKeyword}:.*$/m", strval(@$page['text'])); $newmatch = preg_match_all("/^:?{$ReminderLogKeyword}:(.*)$/m", $new['text'], $m, PREG_PATTERN_ORDER); if( $oldmatch || $newmatch ) { foreach((array)$RemindersLogs as $p) { $rcpage = ReadPage($p); if($oldmatch) $rcpage['text'] = preg_replace("!^\\*.* {$pslashE}\n!m", '', @$rcpage['text']); if($newmatch) foreach($m[1] as $v) $rcpage['text'] .= "* ". trim($v). " . . [[$pslash]]\n"; WritePage($p, $rcpage); } } } function ReminderNext($prefix, $a, $b=0, $y=0) { global $ReminderDayMonth, $Now; if($a[0]=='w') { $days = explode(' ', 'Sun Mon Tues Wednes Thurs Fri Satur'); $day = $days[ $a[1]%7 ]; return $prefix.PSFT("%Y-%m-%d", strtotime("{$day}day") )." "; } $df = explode('/', $ReminderDayMonth); $x[$df[0]]=$a; $x[$df[1]]=$b; if($a && $b && $y) return $prefix.PSFT("%Y-%m-%d", strtotime("$y-{$x['m']}-{$x['d']}") )." "; if($b==0) { $x['d'] = $a; $x['m'] = 0; } $delta = "years"; if($x['m']==0){$delta = "months"; $x['m'] = date('n');} if($y==0)$y =date('Y'); $Today = strtotime( PSFT("%Y-%m-%d")); $Then = strtotime("$y-{$x['m']}-{$x['d']}"); for($i=0; $i<13; $i++) { $Current = strtotime( "+$i $delta", $Then ); if($Today<=$Current) return $prefix.PSFT("%Y-%m-%d", $Current)." "; } }