setPageTitle(WT_I18N::translate('Anniversary calendar')); $controller->pageHeader(); $cal = WT_Filter::get('cal', '@#D[A-Z ]+@'); $day = WT_Filter::get('day', '\d\d?'); $month = WT_Filter::get('month', '[A-Z]{3,5}'); $year = WT_Filter::get('year', '\d{1,4}(?: B\.C\.)?|\d\d\d\d\/\d\d|\d+(-\d+|[?]+)?'); $action = WT_Filter::get('action', 'year|today|calendar', 'today'); $filterev = WT_Filter::get('filterev', 'all|bdm|' . WT_REGEX_TAG, 'bdm'); $filterof = WT_Filter::get('filterof', 'all|living|recent', 'all'); $filtersx = WT_Filter::get('filtersx', '[MF]'); if ($cal.$day.$month.$year=='') { // No date specified? Use the most likely calendar switch (WT_LOCALE) { case 'fa': $cal='@#DJALALI@'; break; case 'ar': $cal='@#DHIJRI@'; break; case 'he': $cal='@#DHEBREW@'; break; default: $cal='@#DGREGORIAN@'; break; } } // Create a WT_Date_Calendar from the parameters // We cannot display new-style/old-style years, so convert to new style if (preg_match('/^(\d\d)\d\d\/(\d\d)$/', $year, $match)) { $year=$match[1].$match[2]; } // advanced-year "year range" if (preg_match('/^(\d+)-(\d+)$/', $year, $match)) { if (strlen($match[1]) > strlen($match[2])) { $match[2]=substr($match[1], 0, strlen($match[1])-strlen($match[2])).$match[2]; } $ged_date=new WT_Date("FROM {$cal} {$match[1]} TO {$cal} {$match[2]}"); $action='year'; } else { // advanced-year "decade/century wildcard" if (preg_match('/^(\d+)(\?+)$/', $year, $match)) { $y1=$match[1].str_replace('?', '0', $match[2]); $y2=$match[1].str_replace('?', '9', $match[2]); $ged_date=new WT_Date("FROM {$cal} {$y1} TO {$cal} {$y2}"); $action='year'; } else { if ($year<0) $year=(-$year)." B.C."; // need BC to parse date $ged_date=new WT_Date("{$cal} {$day} {$month} {$year}"); $year=$ged_date->date1->y; // need negative year for year entry field. } } $cal_date=&$ged_date->date1; // Invalid month? Pick a sensible one. if ($cal_date instanceof WT_Date_Jewish && $cal_date->m==7 && $cal_date->y!=0 && !$cal_date->isLeapYear()) $cal_date->m=6; // Fill in any missing bits with todays date $today=$cal_date->today(); if ($cal_date->d==0) $cal_date->d=$today->d; if ($cal_date->m==0) $cal_date->m=$today->m; if ($cal_date->y==0) $cal_date->y=$today->y; $cal_date->setJdFromYmd(); if ($year==0) $year=$cal_date->y; // Extract values from date $days_in_month=$cal_date->daysInMonth(); $days_in_week=$cal_date->daysInWeek(); $cal_month=$cal_date->format('%O'); $today_month=$today->format('%O'); // Invalid dates? Go to monthly view, where they'll be found. if ($cal_date->d>$days_in_month && $action=='today') $action='calendar'; echo '
'; // Calendar form echo '
'; echo ""; echo "d}\">"; echo ""; echo "y}\">"; echo ""; echo ""; echo ""; echo ""; echo ''; echo ''; // Day selector echo ''; // Month selector echo ''; echo ''; // Year selector echo ''; echo ' '; // Filtering options echo ''; echo ''; echo '

'; // All further uses of $cal are to generate URLs $cal=rawurlencode($cal); switch ($action) { case 'today': echo WT_I18N::translate('On this day…').'
'.$ged_date->Display(false); break; case 'calendar': echo WT_I18N::translate('In this month…').'
'.$ged_date->Display(false, '%F %Y'); break; case 'year': echo WT_I18N::translate('In this year…').'
'.$ged_date->Display(false, '%Y'); break; } echo '

'; echo WT_I18N::translate('Day'), ''; for ($d=1; $d<=$days_in_month; $d++) { // Format the day number using the calendar $tmp=new WT_Date($cal_date->format("%@ {$d} %O %E")); $d_fmt=$tmp->date1->format('%j'); if ($d==$cal_date->d) echo "{$d_fmt}"; else echo "y}&filterev={$filterev}&filterof={$filterof}&filtersx={$filtersx}&action={$action}"."\">{$d_fmt}"; echo ' | '; } $tmp=new WT_Date($today->format('%@ %A %O %E')); // Need a WT_Date object to get localisation echo "d}&month={$today_month}&year={$today->y}&filterev={$filterev}&filterof={$filterof}&filtersx={$filtersx}&action={$action}\">".$tmp->Display(false, NULL, array()).''; echo '
'; echo WT_I18N::translate('Month'), ''; for ($n=1; $n<=$cal_date->monthsInYear(); ++$n) { $month_name=$cal_date->monthNameNominativeCase($n, $cal_date->isLeapYear()); $m = array_search($n, $cal_date::$MONTH_ABBREV); if ($m=='ADS' && $cal_date instanceof WT_Date_Jewish && !$cal_date->isLeapYear()) { // No month 7 in Jewish leap years. continue; } if ($n==$cal_date->m) $month_name="{$month_name}"; echo "d}&month={$m}&year={$cal_date->y}&filterev={$filterev}&filterof={$filterof}&filtersx={$filtersx}&action={$action}\">{$month_name}"; echo ' | '; } echo "d, $today->daysInMonth())."&month={$today_month}&year={$today->y}&filterev={$filterev}&filterof={$filterof}&filtersx={$filtersx}&action={$action}\">".$today->format('%F %Y').'
'; echo WT_I18N::translate('Year'), ''; echo "d}&month={$cal_month}&year=".($cal_date->y==1?-1:$cal_date->y-1)."&filterev={$filterev}&filterof={$filterof}&filtersx={$filtersx}&action={$action}\">-1"; echo " "; echo "d}&month={$cal_month}&year=".($cal_date->y==-1?1:$cal_date->y+1)."&filterev={$filterev}&filterof={$filterof}&filtersx={$filtersx}&action={$action}\">+1"; echo " | d}&month={$cal_month}&year={$today->y}&filterev={$filterev}&filterof={$filterof}&filtersx={$filtersx}&action={$action}\">".$today->format('%Y').""; echo help_link('annivers_year_select'); echo ''; echo WT_I18N::translate('Show'), ''; echo ''; echo '   '; if ($filtersx=="") { echo ''; echo ' | '; } else { echo ''; echo ''; echo ' | '; } if ($filtersx=="M") { echo ' | '; } else { echo ' | '; } if ($filtersx=="F") echo ''; else { echo ''; } echo '   '; echo ""; echo ''; echo '
'; echo ""; // Day/Month/Year and calendar selector echo '"; echo "
'; if ($action=='today') { echo '', WT_I18N::translate('View day'), ''; } else { echo "d}&month={$cal_month}&year={$cal_date->y}&filterev={$filterev}&filterof={$filterof}&filtersx={$filtersx}&action=today\">", WT_I18N::translate('View day'), ""; } if ($action=='calendar') { echo ' | ', WT_I18N::translate('View month'), ''; } else { echo " | d}&month={$cal_month}&year={$cal_date->y}&filterev={$filterev}&filterof={$filterof}&filtersx={$filtersx}&action=calendar\">", WT_I18N::translate('View month'), ""; } if ($action=='year') { echo ' | ', WT_I18N::translate('View year'), ''; } else { echo " | d}&month={$cal_month}&year={$cal_date->y}&filterev={$filterev}&filterof={$filterof}&filtersx={$filtersx}&action=year\">", WT_I18N::translate('View year'), ""; } echo ''; $n=0; foreach (array( 'gregorian'=>WT_Date_Gregorian::calendarName(), 'julian' =>WT_Date_Julian::calendarName(), 'jewish' =>WT_Date_Jewish::calendarName(), 'french' =>WT_Date_French::calendarName(), 'hijri' =>WT_Date_Hijri::calendarName(), 'jalali' =>WT_Date_Jalali::calendarName(), ) as $newcal=>$cal_name) { $tmp=$cal_date->convertToCalendar($newcal); if ($tmp->inValidRange()) { if ($n++) { echo ' | '; } if (get_class($tmp)==get_class($cal_date)) { echo "{$cal_name}"; } else { $newcalesc=urlencode($tmp->format('%@')); $tmpmonth=$tmp->format('%O'); echo "d}&month={$tmpmonth}&year={$tmp->y}&filterev={$filterev}&filterof={$filterof}&filtersx={$filtersx}&action={$action}\">{$cal_name}"; } } } echo "
"; // Convert event filter option to a list of gedcom event codes if ($filterev=='all') { $events=''; } else { if ($filterev=='bdm') { $events='BIRT MARR DEAT'; } else { $events=$filterev; } } // Fetch data for day/month/year views switch ($action) { case 'today': $found_facts=apply_filter(get_anniversary_events($cal_date->minJD, $events), $filterof, $filtersx); break; case 'calendar': $cal_date->d = 0; $cal_date->setJdFromYmd(); // Make a separate list for each day. Unspecified/invalid days go in day 0. $found_facts = array(); for ($d = 0; $d <= $days_in_month; ++$d) { $found_facts[$d] = array(); } // Fetch events for each day for ($jd = $cal_date->minJD; $jd <= $cal_date->maxJD; ++$jd) foreach (apply_filter(get_anniversary_events($jd, $events), $filterof, $filtersx) as $fact) { $d = $jd - $cal_date->minJD + 1; if (array_key_exists($d, $found_facts)) { $found_facts[$d][]=$fact; } else { $found_facts[0][]=$fact; } } break; case 'year': $cal_date->m=0; $cal_date->setJdFromYmd(); $found_facts=apply_filter(get_calendar_events($ged_date->MinJD(), $ged_date->MaxJD(), $events), $filterof, $filtersx); // Eliminate duplicates (e.g. BET JUL 1900 AND SEP 1900 will appear twice in 1900) $found_facts = array_unique($found_facts); break; } // Group the facts by family/individual switch ($action) { case 'year': case 'today': $indis=array(); $fams=array(); foreach ($found_facts as $fact) { $record = $fact->getParent(); $xref = $record->getXref(); if ($record instanceof WT_Individual) { if (empty($indis[$xref])) { $indis[$xref] = calendar_fact_text($fact, true); } else { $indis[$xref] .= '
' . calendar_fact_text($fact, true); } } elseif ($record instanceof WT_Family) { if (empty($indis[$xref])) { $fams[$xref] = calendar_fact_text($fact, true); } else { $fams[$xref] .= '
' . calendar_fact_text($fact, true); } } } break; case 'calendar': $cal_facts=array(); foreach ($found_facts as $d=>$facts) { $cal_facts[$d]=array(); foreach ($facts as $fact) { $xref=$fact->getParent()->getXref(); if (empty($cal_facts[$d][$xref])) $cal_facts[$d][$xref]=calendar_fact_text($fact, false); else $cal_facts[$d][$xref].='
'.calendar_fact_text($fact, false); } } break; } switch ($action) { case 'year': case 'today': echo ''; // Table headings echo ''; echo ''; echo ''; // Table rows $males=0; $females=0; $numfams=0; echo ''; echo ''; echo ""; // Table footers echo ''; echo ''; echo '
', WT_I18N::translate('Individuals'), '', WT_I18N::translate('Families'), '
'; // Avoid an empty unordered list $content = calendar_list_text($indis, '
  • ', '
  • ', true); if ($content) { echo '
      ', $content, '
    '; } echo '
    '; // Avoid an empty unordered list $content = calendar_list_text($fams, '
  • ', '
  • ', true); if ($content) { echo '
      ', $content, '
    '; } echo '
    ', WT_I18N::translate('Total individuals: %s', count($indis)); echo '
    '; echo ' ', $males, '    '; echo ' ', $females, '    '; if (count($indis)!=$males+$females) { echo ' ', count($indis)-$males-$females; } echo '
    ', WT_I18N::translate('Total families: %s', count($fams)), '
    '; break; case 'calendar': // We use JD%7 = 0/Mon...6/Sun. Config files use 0/Sun...6/Sat. Add 6 to convert. $week_start=($WEEK_START+6)%$days_in_week; // The french calendar has a 10-day week, but our config only lets us choose // mon-sun as a start day. Force french calendars to start on primidi if ($days_in_week==10) { $week_start=0; } echo ""; for ($week_day=0; $week_day<$days_in_week; ++$week_day) { $day_name=$cal_date->dayNames(($week_day+$week_start) % $days_in_week); echo ""; } echo ""; // Print days 1-n of the month... // ...but extend to cover "empty" days before/after the month to make whole weeks. // e.g. instead of 1 -> 30 (=30 days), we might have -1 -> 33 (=35 days) $start_d=1-($cal_date->minJD-$week_start) % $days_in_week; $end_d=$days_in_month+($days_in_week-($cal_date->maxJD-$week_start+1) % $days_in_week) % $days_in_week; // Make sure that there is an empty box for any leap/missing days if ($start_d==1 && $end_d==$days_in_month && count($found_facts[0])>0) $end_d+=$days_in_week; for ($d=$start_d; $d<=$end_d; ++$d) { if (($d+$cal_date->minJD-$week_start) % $days_in_week==1) echo ""; echo "'; if (($d+$cal_date->minJD-$week_start) % $days_in_week==0) { echo ''; } } echo '
    {$day_name}
    "; if ($d<1 || $d>$days_in_month) if (count($cal_facts[0])>0) { echo '', WT_I18N::translate('Day not set'), '
    '; echo '
    '; echo calendar_list_text($cal_facts[0], '', '', false); echo '
    '; $cal_facts[0]=array(); } else echo ' '; else { // Format the day number using the calendar $tmp=new WT_Date($cal_date->format("%@ {$d} %O %E")); $d_fmt=$tmp->date1->format('%j'); if ($d==$today->d && $cal_date->m==$today->m) echo "{$d_fmt}"; else echo "{$d_fmt}"; // Show a converted date foreach (explode('_and_', $CALENDAR_FORMAT) as $convcal) { switch ($convcal) { case 'french': $alt_date = new WT_Date_French($cal_date->minJD + $d - 1); break; case 'gregorian': $alt_date = new WT_Date_Gregorian($cal_date->minJD + $d - 1); break; case 'jewish': $alt_date = new WT_Date_Jewish($cal_date->minJD + $d - 1); break; case 'julian': $alt_date = new WT_Date_Julian($cal_date->minJD + $d - 1); break; case 'hijri': $alt_date = new WT_Date_Hijri($cal_date->minJD + $d - 1); break; case 'jalali': $alt_date = new WT_Date_Jalali($cal_date->minJD + $d - 1); break; default: break 2; } if (get_class($alt_date)!=get_class($cal_date)) { echo "".$alt_date->format("%j %M").""; // Just show the first conversion break; } } echo '
    '; echo calendar_list_text($cal_facts[$d], '', '', false); echo '
    '; } echo '
    '; break; } echo '
    '; //close "calendar-page" ///////////////////////////////////////////////////////////////////////////////// // Filter a list of anniversaries ///////////////////////////////////////////////////////////////////////////////// function apply_filter($facts, $filterof, $filtersx) { $filtered = array(); $hundred_years = WT_CLIENT_JD - 36525; foreach ($facts as $fact) { $record = $fact->getParent(); if ($filtersx) { // Filter on sex if ($record instanceof WT_Individual && $filtersx != $record->getSex()) { continue; } // Can't display families if the sex filter is on. if ($record instanceof WT_Family) { continue; } } // Filter living individuals if ($filterof == 'living') { if ($record instanceof WT_Individual && $record->isDead()) { continue; } if ($record instanceof WT_Family) { $husb = $record->getHusband(); $wife = $record->getWife(); if ($husb && $husb->isDead() || $wife && $wife->isDead()) { continue; } } } // Filter on recent events if ($filterof == 'recent' && $fact->getDate()->MaxJD()<$hundred_years) { continue; } $filtered[] = $fact; } return $filtered; } //////////////////////////////////////////////////////////////////////////////// // Format an anniversary display. //////////////////////////////////////////////////////////////////////////////// function calendar_fact_text(WT_Fact $fact, $show_places) { $text = $fact->getLabel().' — '.$fact->getDate()->Display(true, "", array()); if ($fact->anniv) { $text .= ' (' . WT_I18N::translate('%s year anniversary', $fact->anniv) . ')'; } if ($show_places && $fact->getAttribute('PLAC')) { $text .= ' — ' . $fact->getAttribute('PLAC'); } return $text; } //////////////////////////////////////////////////////////////////////////////// // Format a list of facts for display //////////////////////////////////////////////////////////////////////////////// function calendar_list_text($list, $tag1, $tag2, $show_sex_symbols) { global $males, $females; $html = ''; foreach ($list as $id=>$facts) { $tmp = WT_GedcomRecord::GetInstance($id); $html .= $tag1 . '' . $tmp->getFullName() . ' '; if ($show_sex_symbols && $tmp instanceof WT_Individual) switch ($tmp->getSex()) { case 'M': $html .= ''; ++$males; break; case 'F': $html .= ''; ++$females; break; default: $html .= ''; break; } $html .= '
    ' . $facts . '
    ' . $tag2; } return $html; }