Exemplo n.º 1
0
function format_fam_table($datalist)
{
    global $GEDCOM, $SHOW_LAST_CHANGE, $SEARCH_SPIDER, $controller;
    $table_id = 'table-fam-' . Uuid::uuid4();
    // lists requires a unique ID in case there are multiple lists per page
    $controller->addExternalJavascript(WT_JQUERY_DATATABLES_URL)->addInlineJavascript('
			jQuery.fn.dataTableExt.oSort["unicode-asc" ]=function(a,b) {return a.replace(/<[^<]*>/, "").localeCompare(b.replace(/<[^<]*>/, ""))};
			jQuery.fn.dataTableExt.oSort["unicode-desc"]=function(a,b) {return b.replace(/<[^<]*>/, "").localeCompare(a.replace(/<[^<]*>/, ""))};
			jQuery("#' . $table_id . '").dataTable( {
				dom: \'<"H"<"filtersH_' . $table_id . '"><"dt-clear">pf<"dt-clear">irl>t<"F"pl<"dt-clear"><"filtersF_' . $table_id . '">>\',
				' . WT_I18N::datatablesI18N() . ',
				jQueryUI: true,
				autoWidth: false,
				processing: true,
				retrieve: true,
				columns: [
					/*  0 husb givn */ {dataSort: 2},
					/*  1 husb surn */ {dataSort: 3},
					/*  2 GIVN,SURN */ {type: "unicode", visible: false},
					/*  3 SURN,GIVN */ {type: "unicode", visible: false},
					/*  4 age       */ {dataSort: 5, class: "center"},
					/*  5 AGE       */ {type: "num", visible: false},
					/*  6 wife givn */ {dataSort: 8},
					/*  7 wife surn */ {dataSort: 9},
					/*  8 GIVN,SURN */ {type: "unicode", visible: false},
					/*  9 SURN,GIVN */ {type: "unicode", visible: false},
					/* 10 age       */ {dataSort: 11, class: "center"},
					/* 11 AGE       */ {type: "num", visible: false},
					/* 12 marr date */ {dataSort: 13},
					/* 13 MARR:DATE */ {visible: false},
					/* 14 anniv     */ {dataSort: 13, class: "center"},
					/* 15 marr plac */ {type: "unicode"},
					/* 16 children  */ {dataSort: 17, class: "center"},
					/* 17 NCHI      */ {type: "num", visible: false},
					/* 18 CHAN      */ {dataSort: 19, visible: ' . ($SHOW_LAST_CHANGE ? 'true' : 'false') . '},
					/* 19 CHAN_sort */ {visible: false},
					/* 20 MARR      */ {visible: false},
					/* 21 DEAT      */ {visible: false},
					/* 22 TREE      */ {visible: false}
				],
				sorting: [[1, "asc"]],
				displayLength: 20,
				pagingType: "full_numbers"
		   });

			jQuery("#' . $table_id . '")
			/* Hide/show parents */
			.on("click", ".btn-toggle-parents", function() {
				jQuery(this).toggleClass("ui-state-active");
				jQuery(".parents", jQuery(this).closest("table").DataTable().rows().nodes()).slideToggle();
			})
			/* Hide/show statistics */
			.on("click",  ".btn-toggle-statistics", function() {
				jQuery(this).toggleClass("ui-state-active");
				jQuery("#fam_list_table-charts_' . $table_id . '").slideToggle();
			})
			/* Filter buttons in table header */
			.on("click", "button[data-filter-column]", function() {
				var btn = $(this);
				// De-activate the other buttons in this button group
				btn.siblings().removeClass("ui-state-active");
				// Apply (or clear) this filter
				var col = jQuery("#' . $table_id . '").DataTable().column(btn.data("filter-column"));
				if (btn.hasClass("ui-state-active")) {
					btn.removeClass("ui-state-active");
					col.search("").draw();
				} else {
					btn.addClass("ui-state-active");
					col.search(btn.data("filter-value")).draw();
				}
			});

			jQuery(".fam-list").css("visibility", "visible");
			jQuery(".loading-image").css("display", "none");
	');
    $stats = new WT_Stats($GEDCOM);
    $max_age = max($stats->oldestMarriageMaleAge(), $stats->oldestMarriageFemaleAge()) + 1;
    //-- init chart data
    for ($age = 0; $age <= $max_age; $age++) {
        $marr_by_age[$age] = '';
    }
    for ($year = 1550; $year < 2030; $year += 10) {
        $birt_by_decade[$year] = '';
        $marr_by_decade[$year] = '';
    }
    $html = '
		<div class="loading-image">&nbsp;</div>
		<div class="fam-list">
			<table id="' . $table_id . '">
				<thead>
					<tr>
						<th colspan="23">
							<div class="btn-toolbar">
								<div class="btn-group">
									<button
										type="button"
										data-filter-column="21"
										data-filter-value="N"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show individuals who are alive or couples where both partners are alive.') . '"
									>
										' . WT_I18N::translate('Both alive') . '
									</button>
									<button
										type="button"
										data-filter-column="21"
										data-filter-value="W"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show couples where only the female partner is deceased.') . '"
									>
										' . WT_I18N::translate('Widower') . '
									</button>
									<button
										type="button"
										data-filter-column="21"
										data-filter-value="H"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show couples where only the male partner is deceased.') . '"
									>
										' . WT_I18N::translate('Widow') . '
									</button>
									<button
										type="button"
										data-filter-column="21"
										data-filter-value="Y"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show individuals who are dead or couples where both partners are deceased.') . '"
									>
										' . WT_I18N::translate('Both dead') . '
									</button>
								</div>
								<div class="btn-group">
									<button
										type="button"
										data-filter-column="22"
										data-filter-value="R"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show “roots” couples or individuals.  These individuals may also be called “patriarchs”.  They are individuals who have no parents recorded in the database.') . '"
									>
										' . WT_I18N::translate('Roots') . '
									</button>
									<button
										type="button"
										data-filter-column="22"
										data-filter-value="L"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show “leaves” couples or individuals.  These are individuals who are alive but have no children recorded in the database.') . '"
									>
										' . WT_I18N::translate('Leaves') . '
									</button>
								</div>
								<div class="btn-group">
									<button
										type="button"
										data-filter-column="20"
										data-filter-value="U"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show couples with an unknown marriage date.') . '"
									>
										' . WT_Gedcom_Tag::getLabel('MARR') . '
									</button>
									<button
										type="button"
										data-filter-column="20"
										data-filter-value="YES"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show couples who married more than 100 years ago.') . '"
									>
										' . WT_Gedcom_Tag::getLabel('MARR') . '&gt;100
									</button>
									<button
										type="button"
										data-filter-column="20"
										data-filter-value="Y100"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show couples who married within the last 100 years.') . '"
									>
										' . WT_Gedcom_Tag::getLabel('MARR') . '&lt;=100
									</button>
									<button
										type="button"
										data-filter-column="20"
										data-filter-value="D"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show divorced couples.') . '"
									>
										' . WT_Gedcom_Tag::getLabel('DIV') . '
									</button>
									<button
										type="button"
										data-filter-column="20"
										data-filter-value="M"
										class="ui-state-default"
										title="' . WT_I18N::translate('Show couples where either partner married more than once.') . '"
									>
										' . WT_I18N::translate('Multiple marriages') . '
									</button>
								</div>
							</div>
						</th>
					</tr>
					<tr>
						<th>' . WT_Gedcom_Tag::getLabel('GIVN') . '</th>
						<th>' . WT_Gedcom_Tag::getLabel('SURN') . '</th>
						<th>HUSB:GIVN_SURN</th>
						<th>HUSB:SURN_GIVN</th>
						<th>' . WT_Gedcom_Tag::getLabel('AGE') . '</th>
						<th>AGE</th>
						<th>' . WT_Gedcom_Tag::getLabel('GIVN') . '</th>
						<th>' . WT_Gedcom_Tag::getLabel('SURN') . '</th>
						<th>WIFE:GIVN_SURN</th>
						<th>WIFE:SURN_GIVN</th>
						<th>' . WT_Gedcom_Tag::getLabel('AGE') . '</th>
						<th>AGE</th>
						<th>' . WT_Gedcom_Tag::getLabel('MARR') . '</th>
						<th>MARR:DATE</th>
						<th><i class="icon-reminder" title="' . WT_I18N::translate('Anniversary') . '"></i></th>
						<th>' . WT_Gedcom_Tag::getLabel('PLAC') . '</th>
						<th><i class="icon-children" title="' . WT_I18N::translate('Children') . '"></i></th>
					<th>NCHI</th>
					<th' . ($SHOW_LAST_CHANGE ? '' : '') . '>' . WT_Gedcom_Tag::getLabel('CHAN') . '</th>
					<th' . ($SHOW_LAST_CHANGE ? '' : '') . '>CHAN</th>
					<th>MARR</th>
					<th>DEAT</th>
					<th>TREE</th>
				</tr>
			</thead>
			<tfoot>
				<tr>
					<th colspan="23">
						<div class="btn-toolbar">
							<div class="btn-group">
								<button type="button" class="ui-state-default btn-toggle-parents">
									' . WT_I18N::translate('Show parents') . '
								</button>
								<button type="button" class="ui-state-default btn-toggle-statistics">
									' . WT_I18N::translate('Show statistics charts') . '
								</button>
							</div>
						</div>
					</th>
				</tr>
			</tfoot>
			<tbody>';
    $d100y = new WT_Date(date('Y') - 100);
    // 100 years ago
    foreach ($datalist as $family) {
        //-- Retrieve husband and wife
        $husb = $family->getHusband();
        if (is_null($husb)) {
            $husb = new WT_Individual('H', '0 @H@ INDI', null, WT_GED_ID);
        }
        $wife = $family->getWife();
        if (is_null($wife)) {
            $wife = new WT_Individual('W', '0 @W@ INDI', null, WT_GED_ID);
        }
        if (!$family->canShow()) {
            continue;
        }
        if ($family->isNew()) {
            $class = ' class="new"';
        } elseif ($family->isOld()) {
            $class = ' class="old"';
        } else {
            $class = '';
        }
        $html .= '<tr' . $class . '>';
        //-- Husband name(s)
        $html .= '<td colspan="2">';
        foreach ($husb->getAllNames() as $num => $name) {
            if ($name['type'] == 'NAME') {
                $title = '';
            } else {
                $title = 'title="' . strip_tags(WT_Gedcom_Tag::getLabel($name['type'], $husb)) . '"';
            }
            if ($num == $husb->getPrimaryName()) {
                $class = ' class="name2"';
                $sex_image = $husb->getSexImage();
                list($surn, $givn) = explode(',', $name['sort']);
            } else {
                $class = '';
                $sex_image = '';
            }
            // Only show married names if they are the name we are filtering by.
            if ($name['type'] != '_MARNM' || $num == $husb->getPrimaryName()) {
                $html .= '<a ' . $title . ' href="' . $family->getHtmlUrl() . '"' . $class . '>' . highlight_search_hits($name['full']) . '</a>' . $sex_image . '<br>';
            }
        }
        // Husband parents
        $html .= $husb->getPrimaryParentsNames('parents details1', 'none');
        $html .= '</td>';
        // Dummy column to match colspan in header
        $html .= '<td style="display:none;"></td>';
        //-- Husb GIVN
        // Use "AAAA" as a separator (instead of ",") as Javascript.localeCompare() ignores
        // punctuation and "ANN,ROACH" would sort after "ANNE,ROACH", instead of before it.
        // Similarly, @N.N. would sort as NN.
        $html .= '<td>' . WT_Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)) . 'AAAA' . WT_Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)) . '</td>';
        $html .= '<td>' . WT_Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)) . 'AAAA' . WT_Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)) . '</td>';
        $mdate = $family->getMarriageDate();
        //-- Husband age
        $hdate = $husb->getBirthDate();
        if ($hdate->isOK() && $mdate->isOK()) {
            if ($hdate->gregorianYear() >= 1550 && $hdate->gregorianYear() < 2030) {
                $birt_by_decade[(int) ($hdate->gregorianYear() / 10) * 10] .= $husb->getSex();
            }
            $hage = WT_Date::getAge($hdate, $mdate, 0);
            if ($hage >= 0 && $hage <= $max_age) {
                $marr_by_age[$hage] .= $husb->getSex();
            }
        }
        $html .= '<td>' . WT_Date::getAge($hdate, $mdate, 2) . '</td><td>' . WT_Date::getAge($hdate, $mdate, 1) . '</td>';
        //-- Wife name(s)
        $html .= '<td colspan="2">';
        foreach ($wife->getAllNames() as $num => $name) {
            if ($name['type'] == 'NAME') {
                $title = '';
            } else {
                $title = 'title="' . strip_tags(WT_Gedcom_Tag::getLabel($name['type'], $wife)) . '"';
            }
            if ($num == $wife->getPrimaryName()) {
                $class = ' class="name2"';
                $sex_image = $wife->getSexImage();
                list($surn, $givn) = explode(',', $name['sort']);
            } else {
                $class = '';
                $sex_image = '';
            }
            // Only show married names if they are the name we are filtering by.
            if ($name['type'] != '_MARNM' || $num == $wife->getPrimaryName()) {
                $html .= '<a ' . $title . ' href="' . $family->getHtmlUrl() . '"' . $class . '>' . highlight_search_hits($name['full']) . '</a>' . $sex_image . '<br>';
            }
        }
        // Wife parents
        $html .= $wife->getPrimaryParentsNames('parents details1', 'none');
        $html .= '</td>';
        // Dummy column to match colspan in header
        $html .= '<td style="display:none;"></td>';
        //-- Wife GIVN
        //-- Husb GIVN
        // Use "AAAA" as a separator (instead of ",") as Javascript.localeCompare() ignores
        // punctuation and "ANN,ROACH" would sort after "ANNE,ROACH", instead of before it.
        // Similarly, @N.N. would sort as NN.
        $html .= '<td>' . WT_Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)) . 'AAAA' . WT_Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)) . '</td>';
        $html .= '<td>' . WT_Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)) . 'AAAA' . WT_Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)) . '</td>';
        $mdate = $family->getMarriageDate();
        //-- Wife age
        $wdate = $wife->getBirthDate();
        if ($wdate->isOK() && $mdate->isOK()) {
            if ($wdate->gregorianYear() >= 1550 && $wdate->gregorianYear() < 2030) {
                $birt_by_decade[(int) ($wdate->gregorianYear() / 10) * 10] .= $wife->getSex();
            }
            $wage = WT_Date::getAge($wdate, $mdate, 0);
            if ($wage >= 0 && $wage <= $max_age) {
                $marr_by_age[$wage] .= $wife->getSex();
            }
        }
        $html .= '<td>' . WT_Date::getAge($wdate, $mdate, 2) . '</td><td>' . WT_Date::getAge($wdate, $mdate, 1) . '</td>';
        //-- Marriage date
        $html .= '<td>';
        if ($marriage_dates = $family->getAllMarriageDates()) {
            foreach ($marriage_dates as $n => $marriage_date) {
                if ($n) {
                    $html .= '<br>';
                }
                $html .= '<div>' . $marriage_date->Display(!$SEARCH_SPIDER) . '</div>';
            }
            if ($marriage_dates[0]->gregorianYear() >= 1550 && $marriage_dates[0]->gregorianYear() < 2030) {
                $marr_by_decade[(int) ($marriage_dates[0]->gregorianYear() / 10) * 10] .= $husb->getSex() . $wife->getSex();
            }
        } elseif ($family->getFacts('_NMR')) {
            $html .= WT_I18N::translate('no');
        } elseif ($family->getFacts('MARR')) {
            $html .= WT_I18N::translate('yes');
        } else {
            $html .= '&nbsp;';
        }
        $html .= '</td>';
        //-- Event date (sortable)hidden by datatables code
        $html .= '<td>';
        if ($marriage_dates) {
            $html .= $marriage_date->JD();
        } else {
            $html .= 0;
        }
        $html .= '</td>';
        //-- Marriage anniversary
        $html .= '<td>' . WT_Date::getAge($mdate, null, 2) . '</td>';
        //-- Marriage place
        $html .= '<td>';
        foreach ($family->getAllMarriagePlaces() as $n => $marriage_place) {
            $tmp = new WT_Place($marriage_place, WT_GED_ID);
            if ($n) {
                $html .= '<br>';
            }
            if ($SEARCH_SPIDER) {
                $html .= $tmp->getShortName();
            } else {
                $html .= '<a href="' . $tmp->getURL() . '" title="' . strip_tags($tmp->getFullName()) . '">';
                $html .= highlight_search_hits($tmp->getShortName()) . '</a>';
            }
        }
        $html .= '</td>';
        //-- Number of children
        $nchi = $family->getNumberOfChildren();
        $html .= '<td>' . WT_I18N::number($nchi) . '</td><td>' . $nchi . '</td>';
        //-- Last change
        if ($SHOW_LAST_CHANGE) {
            $html .= '<td>' . $family->LastChangeTimestamp() . '</td>';
        } else {
            $html .= '<td>&nbsp;</td>';
        }
        //-- Last change hidden sort column
        if ($SHOW_LAST_CHANGE) {
            $html .= '<td>' . $family->LastChangeTimestamp(true) . '</td>';
        } else {
            $html .= '<td>&nbsp;</td>';
        }
        //-- Sorting by marriage date
        $html .= '<td>';
        if (!$family->canShow() || !$mdate->isOK()) {
            $html .= 'U';
        } else {
            if (WT_Date::Compare($mdate, $d100y) > 0) {
                $html .= 'Y100';
            } else {
                $html .= 'YES';
            }
        }
        if ($family->getFacts(WT_EVENTS_DIV)) {
            $html .= 'D';
        }
        if (count($husb->getSpouseFamilies()) > 1 || count($wife->getSpouseFamilies()) > 1) {
            $html .= 'M';
        }
        $html .= '</td>';
        //-- Sorting alive/dead
        $html .= '<td>';
        if ($husb->isDead() && $wife->isDead()) {
            $html .= 'Y';
        }
        if ($husb->isDead() && !$wife->isDead()) {
            if ($wife->getSex() == 'F') {
                $html .= 'H';
            }
            if ($wife->getSex() == 'M') {
                $html .= 'W';
            }
            // male partners
        }
        if (!$husb->isDead() && $wife->isDead()) {
            if ($husb->getSex() == 'M') {
                $html .= 'W';
            }
            if ($husb->getSex() == 'F') {
                $html .= 'H';
            }
            // female partners
        }
        if (!$husb->isDead() && !$wife->isDead()) {
            $html .= 'N';
        }
        $html .= '</td>';
        //-- Roots or Leaves
        $html .= '<td>';
        if (!$husb->getChildFamilies() && !$wife->getChildFamilies()) {
            $html .= 'R';
        } elseif (!$husb->isDead() && !$wife->isDead() && $family->getNumberOfChildren() < 1) {
            $html .= 'L';
        } else {
            $html .= '&nbsp;';
        }
        $html .= '</td>
		</tr>';
    }
    $html .= '
				</tbody>
			</table>
			<div id="fam_list_table-charts_' . $table_id . '" style="display:none">
				<table class="list-charts">
					<tr>
						<td>
							' . print_chart_by_decade($birt_by_decade, WT_I18N::translate('Decade of birth')) . '
						</td>
						<td>
							' . print_chart_by_decade($marr_by_decade, WT_I18N::translate('Decade of marriage')) . '
						</td>
					</tr>
					<tr>
						<td colspan="2">
							' . print_chart_by_age($marr_by_age, WT_I18N::translate('Age in year of marriage')) . '
						</td>
					</tr>
				</table>
			</div>
		</div>';
    return $html;
}
Exemplo n.º 2
0
/**
 * Format age of parents in HTML
 *
 * @param WT_Individual $person child
 * @param WT_Date       $birth_date
 *
 * @return string HTML
 */
function format_parents_age(WT_Individual $person, WT_Date $birth_date)
{
    $html = '';
    $families = $person->getChildFamilies();
    // Multiple sets of parents (e.g. adoption) cause complications, so ignore.
    if ($birth_date->isOK() && count($families) == 1) {
        $family = current($families);
        foreach ($family->getSpouses() as $parent) {
            if ($parent->getBirthDate()->isOK()) {
                $sex = $parent->getSexImage();
                $age = WT_Date::getAge($parent->getBirthDate(), $birth_date, 2);
                $deatdate = $parent->getDeathDate();
                switch ($parent->getSex()) {
                    case 'F':
                        // Highlight mothers who die in childbirth or shortly afterwards
                        if ($deatdate->isOK() && $deatdate->MinJD() < $birth_date->MinJD() + 90) {
                            $html .= ' <span title="' . WT_Gedcom_Tag::getLabel('_DEAT_PARE', $parent) . '" class="parentdeath">' . $sex . $age . '</span>';
                        } else {
                            $html .= ' <span title="' . WT_I18N::translate('Mother’s age') . '">' . $sex . $age . '</span>';
                        }
                        break;
                    case 'M':
                        // Highlight fathers who die before the birth
                        if ($deatdate->isOK() && $deatdate->MinJD() < $birth_date->MinJD()) {
                            $html .= ' <span title="' . WT_Gedcom_Tag::getLabel('_DEAT_PARE', $parent) . '" class="parentdeath">' . $sex . $age . '</span>';
                        } else {
                            $html .= ' <span title="' . WT_I18N::translate('Father’s age') . '">' . $sex . $age . '</span>';
                        }
                        break;
                    default:
                        $html .= ' <span title="' . WT_I18N::translate('Parent’s age') . '">' . $sex . $age . '</span>';
                        break;
                }
            }
        }
        if ($html) {
            $html = '<span class="age">' . $html . '</span>';
        }
    }
    return $html;
}