Ejemplo n.º 1
0
    /**
     * {@inhericDoc}
     * @see \MyArtJaub\Webtrees\Mvc\View\AbstractView::renderContent()
     */
    protected function renderContent()
    {
        if ($this->data->get('has_sosa', false)) {
            $table_id = $this->data->get('table_id');
            ?>
   
        
        <div id="sosa-indi-list" class="sosa-list">
        	<table id="<?php 
            echo $table_id;
            ?>
">
				<thead>
    				<tr>
    					<th colspan="22">
    						<div class="btn-toolbar">
    							<div class="btn-group">
    								<button
    									class="ui-state-default"
    									data-filter-column="18"
    									data-filter-value="M"
    									title="<?php 
            echo I18N::translate('Show only males.');
            ?>
"
    									type="button"
    								><?php 
            echo Individual::sexImage('M', 'large');
            ?>
    								</button>
    								<button
    									class="ui-state-default"
    									data-filter-column="18"
    									data-filter-value="F"
    									title="<?php 
            echo I18N::translate('Show only females.');
            ?>
"
    									type="button"
    								>
    									<?php 
            echo Individual::sexImage('F', 'large');
            ?>
    								</button>
    								<button
    									class="ui-state-default"
    									data-filter-column="18"
    									data-filter-value="U"
    									title="<?php 
            echo I18N::translate('Show only individuals for whom the gender is not known.');
            ?>
"
    									type="button"
    								>
    									<?php 
            echo Individual::sexImage('U', 'large');
            ?>
    								</button>
    							</div>
    							<div class="btn-group">
    								<button
    									class="ui-state-default"
    									data-filter-column="20"
    									data-filter-value="N"
    									title="<?php 
            echo I18N::translate('Show individuals who are alive or couples where both partners are alive.');
            ?>
"
    									type="button"
    								>
    									<?php 
            echo I18N::translate('Alive');
            ?>
    								</button>
    								<button
    									class="ui-state-default"
    									data-filter-column="20"
    									data-filter-value="Y"
    									title="<?php 
            echo I18N::translate('Show individuals who are dead or couples where both partners are deceased.');
            ?>
"
    									type="button"
    								>
    									<?php 
            echo I18N::translate('Dead');
            ?>
    								</button>
    								<button
    									class="ui-state-default"
    									data-filter-column="20"
    									data-filter-value="YES"
    									title="<?php 
            echo I18N::translate('Show individuals who died more than 100 years ago.');
            ?>
"
    									type="button"
    								><?php 
            echo GedcomTag::getLabel('DEAT');
            ?>
&gt;100
    								</button>
    								<button
    									class="ui-state-default"
    									data-filter-column="20"
    									data-filter-value="Y100"
    									title="<?php 
            echo I18N::translate('Show individuals who died within the last 100 years.');
            ?>
"
    									type="button"
    								><?php 
            echo GedcomTag::getLabel('DEAT');
            ?>
&lt;=100
    								</button>
    							</div>
    							<div class="btn-group">
    								<button
    									class="ui-state-default"
    									data-filter-column="19"
    									data-filter-value="YES"
    									title="<?php 
            echo I18N::translate('Show individuals born more than 100 years ago.');
            ?>
"
    									type="button"
    								><?php 
            echo GedcomTag::getLabel('BIRT');
            ?>
&gt;100
    								</button>
    								<button
    									class="ui-state-default"
    									data-filter-column="19"
    									data-filter-value="Y100"
    									title="<?php 
            echo I18N::translate('Show individuals born within the last 100 years.');
            ?>
"
    									type="button"
    								><?php 
            echo GedcomTag::getLabel('BIRT');
            ?>
&lt;=100
    								</button>
    							</div>
    							<div class="btn-group">
    								<button
    									class="ui-state-default"
    									data-filter-column="21"
    									data-filter-value="R"
    									title="<?php 
            echo 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.');
            ?>
"
    									type="button"
    								>
    									<?php 
            echo I18N::translate('Roots');
            ?>
    								</button>
    								<button
    									class="ui-state-default"
    									data-filter-column="21"
    									data-filter-value="L"
    									title="<?php 
            echo I18N::translate('Show “leaves” couples or individuals.  These are individuals who are alive but have no children recorded in the database.');
            ?>
"
    									type="button"
    								>
    									<?php 
            echo I18N::translate('Leaves');
            ?>
    								</button>
    							</div>
    						</div>
    					</th>
    				</tr>
					<tr>
						<th><?php 
            echo I18N::translate('Sosa');
            ?>
</th>
						<th><?php 
            echo GedcomTag::getLabel('INDI');
            ?>
</th>
						<th><?php 
            echo GedcomTag::getLabel('GIVN');
            ?>
</th>
						<th><?php 
            echo GedcomTag::getLabel('SURN');
            ?>
</th>
						<th>GIVN</th>
						<th>SURN</th>
						<th><?php 
            echo GedcomTag::getLabel('BIRT');
            ?>
</th>
						<th>SORT_BIRT</th>
						<th><?php 
            echo GedcomTag::getLabel('PLAC');
            ?>
</th>
						<?php 
            if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) {
                ?>
						<th><i class="icon-source" title="<?php 
                echo I18N::translate('Sourced birth');
                ?>
" border="0"></i></th>
						<th>SORT_BIRTSC</th>
						<?php 
            } else {
                ?>
						<th></th>
						<th></th>
						<?php 
            }
            ?>
						<th><?php 
            echo GedcomTag::getLabel('DEAT');
            ?>
</th>
						<th>SORT_DEAT</th>
						<th><?php 
            echo GedcomTag::getLabel('AGE');
            ?>
</th>
						<th>AGE</th>
						<th><?php 
            echo GedcomTag::getLabel('PLAC');
            ?>
</th>
						<?php 
            if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) {
                ?>
						<th><i class="icon-source" title="<?php 
                echo I18N::translate('Sourced death');
                ?>
" border="0"></i></th>
						<th>SORT_DEATSC</th>
						<?php 
            } else {
                ?>
						<th></th>
						<th></th>
						<?php 
            }
            ?>
						<th>SEX</th>
						<th>BIRT</th>
						<th>DEAT</th>
						<th>TREE</th>
					</tr>
				</thead>
			<tbody>
			
			<?php 
            foreach ($this->data->get('sosa_list') as $sosa => $person) {
                /** @var \Fisharebest\Webtrees\Individual $person */
                if ($person->isPendingAddtion()) {
                    $class = ' class="new"';
                } elseif ($person->isPendingDeletion()) {
                    $class = ' class="old"';
                } else {
                    $class = '';
                }
                $dperson = new \MyArtJaub\Webtrees\Individual($person);
                ?>
			
        		<tr <?php 
                echo $class;
                ?>
>
        			<td class="transparent"><?php 
                echo $sosa;
                ?>
</td>
        			<td class="transparent"><?php 
                echo $person->getXref();
                ?>
</td>
        			<td colspan="2">
        			<?php 
                foreach ($person->getAllNames() as $num => $name) {
                    if ($name['type'] == 'NAME') {
                        $title = '';
                    } else {
                        $title = 'title="' . strip_tags(GedcomTag::getLabel($name['type'], $person)) . '"';
                    }
                    if ($num == $person->getPrimaryName()) {
                        $class = ' class="name2"';
                        $sex_image = $person->getSexImage();
                        list($surn, $givn) = explode(',', $name['sort']);
                    } else {
                        $class = '';
                        $sex_image = '';
                    }
                    ?>
        				<a <?php 
                    echo $title . ' ' . $class;
                    ?>
 href="<?php 
                    echo $person->getHtmlUrl();
                    ?>
">
        					<?php 
                    echo \Fisharebest\Webtrees\Functions\FunctionsPrint::highlightSearchHits($name['full']);
                    ?>
        				</a>
        				<?php 
                    echo $sex_image . FunctionsPrint::formatSosaNumbers($dperson->getSosaNumbers(), 1, 'smaller');
                    ?>
        				<br/>
            		<?php 
                }
                echo $person->getPrimaryParentsNames('parents details1', 'none');
                ?>
            		</td>
            		<td style="display:none;"></td>
            		<td>
            			<?php 
                echo Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)) . 'AAAA' . Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn));
                ?>
            		</td>
            		<td>
            			<?php 
                echo Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)) . 'AAAA' . Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn));
                ?>
            		</td>
            		<td>
            		<?php 
                if ($birth_dates = $person->getAllBirthDates()) {
                    foreach ($birth_dates as $num => $birth_date) {
                        if ($num) {
                            ?>
<br/><?php 
                        }
                        ?>
    						<?php 
                        echo $birth_date->display(true);
                    }
                } else {
                    $birth_date = new Date('');
                    if ($person->getTree()->getPreference('SHOW_EST_LIST_DATES')) {
                        $birth_date = $person->getEstimatedBirthDate();
                        echo $birth_date->display(true);
                    } else {
                        echo '&nbsp;';
                    }
                    $birth_dates[0] = new Date('');
                }
                ?>
            		</td>
            		<td><?php 
                echo $birth_date->julianDay();
                ?>
</td>
        			<td>
        			<?php 
                foreach ($person->getAllBirthPlaces() as $n => $birth_place) {
                    $tmp = new \Fisharebest\Webtrees\Place($birth_place, $person->getTree());
                    if ($n) {
                        ?>
<br><?php 
                    }
                    ?>
        				<a href="'<?php 
                    echo $tmp->getURL();
                    ?>
" title="<?php 
                    echo strip_tags($tmp->getFullName());
                    ?>
">
        					<?php 
                    echo \Fisharebest\Webtrees\Functions\FunctionsPrint::highlightSearchHits($tmp->getShortName());
                    ?>
        				</a>
        			<?php 
                }
                ?>
        			</td>
        			<?php 
                if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) {
                    $isBSourced = $dperson->isBirthSourced();
                    ?>
				   	<td><?php 
                    echo FunctionsPrint::formatIsSourcedIcon('E', $isBSourced, 'BIRT', 1, 'medium');
                    ?>
</td>
					<td><?php 
                    echo $isBSourced;
                    ?>
</td>
					<?php 
                } else {
                    ?>
					<td>&nbsp;</td>
					<td></td>
					<?php 
                }
                ?>
					<td>
					<?php 
                if ($death_dates = $person->getAllDeathDates()) {
                    foreach ($death_dates as $num => $death_date) {
                        if ($num) {
                            ?>
<br/><?php 
                        }
                        ?>
					 		<?php 
                        echo $death_date->display(true);
                    }
                } else {
                    $death_date = $person->getEstimatedDeathDate();
                    if ($person->getTree()->getPreference('SHOW_EST_LIST_DATES') && $death_date->minimumJulianDay() < WT_CLIENT_JD) {
                        echo $death_date->display(true);
                    } elseif ($person->isDead()) {
                        echo I18N::translate('yes');
                        $death_date = new Date('');
                    } else {
                        echo '&nbsp;';
                        $death_date = new Date('');
                    }
                    $death_dates[0] = new Date('');
                }
                ?>
			         </td>
			         <td><?php 
                echo $death_date->julianDay();
                ?>
</td>
			         <td><?php 
                echo Date::getAge($birth_dates[0], $death_dates[0], 2);
                ?>
</td>
			         <td><?php 
                echo Date::getAge($birth_dates[0], $death_dates[0], 1);
                ?>
</td>
			         <td>
        			 <?php 
                foreach ($person->getAllDeathPlaces() as $n => $death_place) {
                    $tmp = new Place($death_place, $person->getTree());
                    if ($n) {
                        ?>
<br><?php 
                    }
                    ?>
        				<a href="'<?php 
                    echo $tmp->getURL();
                    ?>
" title="<?php 
                    echo strip_tags($tmp->getFullName());
                    ?>
">
        					<?php 
                    echo \Fisharebest\Webtrees\Functions\FunctionsPrint::highlightSearchHits($tmp->getShortName());
                    ?>
        				</a>
        			<?php 
                }
                ?>
        			</td>
        			<?php 
                if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) {
                    $isDSourced = $dperson->isDeathSourced();
                    ?>
				   	<td><?php 
                    echo FunctionsPrint::formatIsSourcedIcon('E', $isDSourced, 'DEAT', 1, 'medium');
                    ?>
</td>
					<td><?php 
                    echo $isDSourced;
                    ?>
</td>
					<?php 
                } else {
                    ?>
					<td>&nbsp;</td>
					<td></td>
					<?php 
                }
                ?>
					<td><?php 
                echo $person->getSex();
                ?>
</td>
					<td>
					<?php 
                if (!$person->canShow() || Date::compare($birth_date, new Date(date('Y') - 100)) > 0) {
                    echo 'Y100';
                } else {
                    echo 'YES';
                }
                ?>
        			</td>
        			<td>
        			<?php 
                if (Date::compare($death_dates[0], new Date(date('Y') - 100)) > 0) {
                    echo 'Y100';
                } elseif ($death_dates[0]->minimumJulianDay() || $person->isDead()) {
                    echo 'YES';
                } else {
                    echo 'N';
                }
                ?>
			         </td>
			         <td>
					<?php 
                if (!$person->getChildFamilies()) {
                    echo 'R';
                } elseif (!$person->isDead() && $person->getNumberOfChildren() < 1) {
                    echo 'L';
                } else {
                    echo '&nbsp;';
                }
                ?>
					</td>
				</tr>
        	<?php 
            }
            ?>
        	</tbody>
        	<tfoot>
				<tr>
					<th class="ui-state-default" colspan="22">
						<div class="center">
							<?php 
            echo I18N::translate('Number of Sosa ancestors: %1$s known / %2$s theoretical (%3$s)', I18N::number($this->data->get('sosa_count')), I18N::number($this->data->get('sosa_theo')), I18N::percentage($this->data->get('sosa_ratio'), 2));
            ?>
							<?php 
            if ($this->data->get('sosa_hidden') > 0) {
                echo '[' . I18N::translate('%s hidden', I18N::number($this->data->get('sosa_hidden'))) . ']';
            }
            ?>
						</div>
					</th>
				</tr>
				<tr>
					<th colspan="22">
						<div class="btn-toolbar">
							<div class="btn-group">
								<button type="button" class="ui-state-default btn-toggle-parents">
									<?php 
            echo I18N::translate('Show parents');
            ?>
								</button>
								<button id="btn-toggle-statistics-<?php 
            echo $table_id;
            ?>
" type="button" class="ui-state-default btn-toggle-statistics">
									<?php 
            echo I18N::translate('Show statistics charts');
            ?>
								</button>
							</div>
						</div>
					</th>
				</tr>
			</tfoot>
        	</table>
				<div id="indi_list_table-charts_<?php 
            echo $table_id;
            ?>
" style="display:none">
					<table class="list-charts">
						<tr>
							<td><?php 
            echo $this->data->get('chart_births');
            ?>
</td>
							<td><?php 
            echo $this->data->get('chart_deaths');
            ?>
</td>
						</tr>
						<tr>
							<td colspan="2"><?php 
            echo $this->data->get('chart_ages');
            ?>
</td>
						</tr>
					</table>
				</div>
			</div>
		<?php 
        }
    }
Ejemplo n.º 2
0
 /**
  * Create part of an individual box
  *
  * @param Individual $individual
  *
  * @return string
  */
 protected function individualBoxSexSymbol(Individual $individual)
 {
     if ($individual->getTree()->getPreference('PEDIGREE_SHOW_GENDER')) {
         return $individual->sexImage('large');
     } else {
         return '';
     }
 }
Ejemplo n.º 3
0
    /**
     * {@inhericDoc}
     * @see \MyArtJaub\Webtrees\Mvc\View\AbstractView::renderContent()
     */
    protected function renderContent()
    {
        ?>
            <div id="maj-sosa-missing-page" class="center">
    			<h2><?php 
        echo $this->data->get('title');
        ?>
</h2>
    			
    			<?php 
        if ($this->data->get('is_setup')) {
            $this->renderSosaHeader();
            if ($this->data->get('has_missing', false)) {
                $table_id = $this->data->get('table_id');
                ?>
    			<div id="sosa-indi-missing" class="smissing-list">
                	<table id="<?php 
                echo $table_id;
                ?>
">
        				<thead>     
            				<tr>
    							<th colspan="16">
    								<div class="btn-toolbar">
    									<div class="btn-group">
    										<button
    											class="ui-state-default"
    											data-filter-column="15"
    											data-filter-value="M"
    											title="<?php 
                I18N::translate('Show only males.');
                ?>
"
    											type="button"
    										>
    										<?php 
                echo Individual::sexImage('M', 'large');
                ?>
    										</button>
    										<button
    											class="ui-state-default"
    											data-filter-column="15"
    											data-filter-value="F"
    											title="<?php 
                I18N::translate('Show only females.');
                ?>
"
    											type="button"
    										>
    										<?php 
                echo Individual::sexImage('F', 'large');
                ?>
    										</button>
    										<button
    											class="ui-state-default"
    											data-filter-column="15"
    											data-filter-value="U"
    											title="<?php 
                I18N::translate('Show only individuals for whom the gender is not known.');
                ?>
"
    											type="button"
    										>
    										<?php 
                echo Individual::sexImage('U', 'large');
                ?>
    										</button>
    									</div>
    								</div>
    							</th>
    						</tr>       				
        					<tr>
        						<th><?php 
                echo I18N::translate('Sosa');
                ?>
</th>
        						<th><?php 
                echo GedcomTag::getLabel('INDI');
                ?>
</th>
        						<th><?php 
                echo GedcomTag::getLabel('GIVN');
                ?>
</th>
        						<th><?php 
                echo GedcomTag::getLabel('SURN');
                ?>
</th>
        						<th>GIVN</th>
        						<th>SURN</th>
        						<?php 
                if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) {
                    ?>
        						<th><i class="icon-source" title="<?php 
                    echo I18N::translate('Sourced individual');
                    ?>
" border="0"></i></th>
        						<th>SORT_BIRTSC</th>
        						<?php 
                } else {
                    ?>
        						<th></th>
        						<th></th>
        						<?php 
                }
                ?>
        						<th><?php 
                echo Functions::getRelationshipNameFromPath('fat');
                ?>
</th>
								<th><?php 
                echo Functions::getRelationshipNameFromPath('mot');
                ?>
</th>        						
        						<th><?php 
                echo GedcomTag::getLabel('BIRT');
                ?>
</th>
        						<th>SORT_BIRT</th>
        						<th><?php 
                echo GedcomTag::getLabel('PLAC');
                ?>
</th>
        						<?php 
                if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) {
                    ?>
        						<th><i class="icon-source" title="<?php 
                    echo I18N::translate('Sourced birth');
                    ?>
" border="0"></i></th>
        						<th>SORT_BIRTSC</th>
        						<?php 
                } else {
                    ?>
        						<th></th>
        						<th></th>
        						<?php 
                }
                ?>
        						<th>SEX</th>
        					</tr>
        				</thead>
        			<tbody>
        			
        			<?php 
                foreach ($this->data->get('missing_list') as $missing_tab) {
                    $person = $missing_tab['indi'];
                    /** @var \Fisharebest\Webtrees\Individual $person */
                    if ($person->isPendingAddtion()) {
                        $class = ' class="new"';
                    } elseif ($person->isPendingDeletion()) {
                        $class = ' class="old"';
                    } else {
                        $class = '';
                    }
                    $dperson = new \MyArtJaub\Webtrees\Individual($person);
                    ?>
			
                		<tr <?php 
                    echo $class;
                    ?>
>
                			<td class="transparent"><?php 
                    echo $missing_tab['sosa'];
                    ?>
</td>
                			<td class="transparent"><?php 
                    echo $person->getXref();
                    ?>
</td>
                			<td colspan="2">
                			<?php 
                    foreach ($person->getAllNames() as $num => $name) {
                        if ($name['type'] == 'NAME') {
                            $title = '';
                        } else {
                            $title = 'title="' . strip_tags(GedcomTag::getLabel($name['type'], $person)) . '"';
                        }
                        if ($num == $person->getPrimaryName()) {
                            $class = ' class="name2"';
                            $sex_image = $person->getSexImage();
                            list($surn, $givn) = explode(',', $name['sort']);
                        } else {
                            $class = '';
                            $sex_image = '';
                        }
                        ?>
                				<a <?php 
                        echo $title . ' ' . $class;
                        ?>
 href="<?php 
                        echo $person->getHtmlUrl();
                        ?>
">
                					<?php 
                        echo \Fisharebest\Webtrees\Functions\FunctionsPrint::highlightSearchHits($name['full']);
                        ?>
                				</a>
                				<?php 
                        echo $sex_image . FunctionsPrint::formatSosaNumbers($dperson->getSosaNumbers(), 1, 'smaller');
                        ?>
                				<br/>
                    		<?php 
                    }
                    echo $person->getPrimaryParentsNames('parents details1', 'none');
                    ?>
                    		</td>
                    		<td style="display:none;"></td>
                    		<td>
                    			<?php 
                    echo Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)) . 'AAAA' . Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn));
                    ?>
                    		</td>
                    		<td>
                    			<?php 
                    echo Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)) . 'AAAA' . Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn));
                    ?>
                    		</td>                    		
                			<?php 
                    if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) {
                        $isISourced = $dperson->isSourced();
                        ?>
        				   	<td><?php 
                        echo FunctionsPrint::formatIsSourcedIcon('R', $isISourced, 'INDI', 1, 'medium');
                        ?>
</td>
        					<td><?php 
                        echo $isISourced;
                        ?>
</td>
        					<?php 
                    } else {
                        ?>
        					<td>&nbsp;</td>
        					<td></td>
        					<?php 
                    }
                    ?>
        					<td><?php 
                    echo $missing_tab['has_father'] ? '&nbsp;' : 'X';
                    ?>
</td>
        					<td><?php 
                    echo $missing_tab['has_mother'] ? '&nbsp;' : 'X';
                    ?>
</td>
        					<td>
                    		<?php 
                    if ($birth_dates = $person->getAllBirthDates()) {
                        foreach ($birth_dates as $num => $birth_date) {
                            if ($num) {
                                ?>
<br/><?php 
                            }
                            ?>
            						<?php 
                            echo $birth_date->display(true);
                        }
                    } else {
                        $birth_date = new Date('');
                        if ($person->getTree()->getPreference('SHOW_EST_LIST_DATES')) {
                            $birth_date = $person->getEstimatedBirthDate();
                            echo $birth_date->display(true);
                        } else {
                            echo '&nbsp;';
                        }
                        $birth_dates[0] = new Date('');
                    }
                    ?>
                    		</td>
                    		<td><?php 
                    echo $birth_date->julianDay();
                    ?>
</td>
                			<td>
                			<?php 
                    foreach ($person->getAllBirthPlaces() as $n => $birth_place) {
                        $tmp = new \Fisharebest\Webtrees\Place($birth_place, $person->getTree());
                        if ($n) {
                            ?>
<br><?php 
                        }
                        ?>
                				<a href="'<?php 
                        echo $tmp->getURL();
                        ?>
" title="<?php 
                        echo strip_tags($tmp->getFullName());
                        ?>
">
                					<?php 
                        echo \Fisharebest\Webtrees\Functions\FunctionsPrint::highlightSearchHits($tmp->getShortName());
                        ?>
                				</a>
                			<?php 
                    }
                    ?>
                			</td>
        					<?php 
                    if (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME)) {
                        $isBSourced = $dperson->isBirthSourced();
                        ?>
        				   	<td><?php 
                        echo FunctionsPrint::formatIsSourcedIcon('E', $isBSourced, 'BIRT', 1, 'medium');
                        ?>
</td>
        					<td><?php 
                        echo $isBSourced;
                        ?>
</td>
        					<?php 
                    } else {
                        ?>
        					<td>&nbsp;</td>
        					<td></td>
        					<?php 
                    }
                    ?>
        					<td><?php 
                    echo $person->getSex();
                    ?>
</td>
        				</tr>
                	<?php 
                }
                ?>
                	</tbody>
                	<tfoot>
						<tr>
							<td class="ui-state-default" colspan="16">
								<div class="center">
									<?php 
                echo I18N::translate('Number of different missing ancestors: %s', I18N::number($this->data->get('missing_diff_count')));
                ?>
									<?php 
                if ($this->data->get('missing_hidden') > 0) {
                    echo ' [' . I18N::translate('%s hidden', I18N::number($this->data->get('missing_hidden'))) . ']';
                }
                ?>
									<?php 
                echo ' - ' . I18N::translate('Generation complete at %s', I18N::percentage($this->data->get('perc_sosa'), 2));
                ?>
									<?php 
                echo ' [' . I18N::translate('Potential %s', I18N::percentage($this->data->get('perc_sosa_potential'), 2)) . ']';
                ?>
								</div>
							</td>
						</tr>
					</tfoot>
                </table>
    			 <?php 
            } else {
                if ($this->data->get('generation', 0) > 0) {
                    ?>
 
    			<p><?php 
                    echo I18N::translate('No ancestors are missing for this generation. Generation complete at %s.', I18N::percentage($this->data->get('perc_sosa'), 2));
                    ?>
</p>
    			    <?php 
                }
            }
        } else {
            ?>
    			<p class="warning"><?php 
            echo I18N::translate('The list could not be displayed. Reasons might be:');
            ?>
<br/>
    				<ul>
    					<li><?php 
            echo I18N::translate('No Sosa root individual has been defined.');
            ?>
</li>
    					<li><?php 
            echo I18N::translate('The Sosa ancestors have not been computed yet.');
            ?>
</li>
    					<li><?php 
            echo I18N::translate('No generation were found.');
            ?>
</li>
    				</ul>
    			</p>
    			<?php 
        }
        ?>
    		</div> 
    		<?php 
    }
Ejemplo n.º 4
0
    /**
     * Print a table of individuals
     *
     * @param Individual[] $datalist
     * @param string $option
     *
     * @return string
     */
    public static function individualTable($datalist, $option = '')
    {
        global $controller, $WT_TREE;
        $table_id = 'table-indi-' . Uuid::uuid4();
        // lists requires a unique ID in case there are multiple lists per page
        $controller->addExternalJavascript(WT_JQUERY_DATATABLES_JS_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.fn.dataTableExt.oSort["num-html-asc" ]=function(a,b) {a=parseFloat(a.replace(/<[^<]*>/, "")); b=parseFloat(b.replace(/<[^<]*>/, "")); return (a<b) ? -1 : (a>b ? 1 : 0);};
				jQuery.fn.dataTableExt.oSort["num-html-desc"]=function(a,b) {a=parseFloat(a.replace(/<[^<]*>/, "")); b=parseFloat(b.replace(/<[^<]*>/, "")); return (a>b) ? -1 : (a<b ? 1 : 0);};
				jQuery("#' . $table_id . '").dataTable( {
					dom: \'<"H"<"filtersH_' . $table_id . '">T<"dt-clear">pf<"dt-clear">irl>t<"F"pl<"dt-clear"><"filtersF_' . $table_id . '">>\',
					' . I18N::datatablesI18N() . ',
					jQueryUI: true,
					autoWidth: false,
					processing: true,
					retrieve: true,
					columns: [
						/*  0 givn      */ { dataSort: 2 },
						/*  1 surn      */ { dataSort: 3 },
						/*  2 GIVN,SURN */ { type: "unicode", visible: false },
						/*  3 SURN,GIVN */ { type: "unicode", visible: false },
						/*  4 sosa      */ { dataSort: 5, class: "center", visible: ' . ($option == 'sosa' ? 'true' : 'false') . ' },
						/*  5 SOSA      */ { type: "num", visible: false },
						/*  6 birt date */ { dataSort: 7 },
						/*  7 BIRT:DATE */ { visible: false },
						/*  8 anniv     */ { dataSort: 7, class: "center" },
						/*  9 birt plac */ { type: "unicode" },
						/* 10 children  */ { dataSort: 11, class: "center" },
						/* 11 children  */ { type: "num", visible: false },
						/* 12 deat date */ { dataSort: 13 },
						/* 13 DEAT:DATE */ { visible: false },
						/* 14 anniv     */ { dataSort: 13, class: "center" },
						/* 15 age       */ { dataSort: 16, class: "center" },
						/* 16 AGE       */ { type: "num", visible: false },
						/* 17 deat plac */ { type: "unicode" },
						/* 18 CHAN      */ { dataSort: 19, visible: ' . ($WT_TREE->getPreference('SHOW_LAST_CHANGE') ? 'true' : 'false') . ' },
						/* 19 CHAN_sort */ { visible: false },
						/* 20 SEX       */ { visible: false },
						/* 21 BIRT      */ { visible: false },
						/* 22 DEAT      */ { visible: false },
						/* 23 TREE      */ { visible: false }
					],
					sorting: [[' . ($option == 'sosa' ? '4, "asc"' : '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("#indi_list_table-charts_' . $table_id . '").slideToggle();
				})
				/* Filter buttons in table header */
				.on("click", "button[data-filter-column]", function() {
					var btn = jQuery(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(".indi-list").css("visibility", "visible");
				jQuery(".loading-image").css("display", "none");
			');
        $stats = new Stats($WT_TREE);
        // Bad data can cause "longest life" to be huge, blowing memory limits
        $max_age = min($WT_TREE->getPreference('MAX_ALIVE_AGE'), $stats->LongestLifeAge()) + 1;
        // Inititialise chart data
        $deat_by_age = array();
        for ($age = 0; $age <= $max_age; $age++) {
            $deat_by_age[$age] = '';
        }
        $birt_by_decade = array();
        $deat_by_decade = array();
        for ($year = 1550; $year < 2030; $year += 10) {
            $birt_by_decade[$year] = '';
            $deat_by_decade[$year] = '';
        }
        $html = '
			<div class="loading-image">&nbsp;</div>
			<div class="indi-list">
				<table id="' . $table_id . '">
					<thead>
						<tr>
							<th colspan="24">
								<div class="btn-toolbar">
									<div class="btn-group">
										<button
											class="ui-state-default"
											data-filter-column="20"
											data-filter-value="M"
											title="' . I18N::translate('Show only males.') . '"
											type="button"
										>
										  ' . Individual::sexImage('M', 'large') . '
										</button>
										<button
											class="ui-state-default"
											data-filter-column="20"
											data-filter-value="F"
											title="' . I18N::translate('Show only females.') . '"
											type="button"
										>
											' . Individual::sexImage('F', 'large') . '
										</button>
										<button
											class="ui-state-default"
											data-filter-column="20"
											data-filter-value="U"
											title="' . I18N::translate('Show only individuals for whom the gender is not known.') . '"
											type="button"
										>
											' . Individual::sexImage('U', 'large') . '
										</button>
									</div>
									<div class="btn-group">
										<button
											class="ui-state-default"
											data-filter-column="22"
											data-filter-value="N"
											title="' . I18N::translate('Show individuals who are alive or couples where both partners are alive.') . '"
											type="button"
										>
											' . I18N::translate('Alive') . '
										</button>
										<button
											class="ui-state-default"
											data-filter-column="22"
											data-filter-value="Y"
											title="' . I18N::translate('Show individuals who are dead or couples where both partners are deceased.') . '"
											type="button"
										>
											' . I18N::translate('Dead') . '
										</button>
										<button
											class="ui-state-default"
											data-filter-column="22"
											data-filter-value="YES"
											title="' . I18N::translate('Show individuals who died more than 100 years ago.') . '"
											type="button"
										>
											' . GedcomTag::getLabel('DEAT') . '&gt;100
										</button>
										<button
											class="ui-state-default"
											data-filter-column="22"
											data-filter-value="Y100"
											title="' . I18N::translate('Show individuals who died within the last 100 years.') . '"
											type="button"
										>
											' . GedcomTag::getLabel('DEAT') . '&lt;=100
										</button>
									</div>
									<div class="btn-group">
										<button
											class="ui-state-default"
											data-filter-column="21"
											data-filter-value="YES"
											title="' . I18N::translate('Show individuals born more than 100 years ago.') . '"
											type="button"
										>
											' . GedcomTag::getLabel('BIRT') . '&gt;100
										</button>
										<button
											class="ui-state-default"
											data-filter-column="21"
											data-filter-value="Y100"
											title="' . I18N::translate('Show individuals born within the last 100 years.') . '"
											type="button"
										>
											' . GedcomTag::getLabel('BIRT') . '&lt;=100
										</button>
									</div>
									<div class="btn-group">
										<button
											class="ui-state-default"
											data-filter-column="23"
											data-filter-value="R"
											title="' . 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.') . '"
											type="button"
										>
											' . I18N::translate('Roots') . '
										</button>
										<button
											class="ui-state-default"
											data-filter-column="23"
											data-filter-value="L"
											title="' . I18N::translate('Show “leaves” couples or individuals.  These are individuals who are alive but have no children recorded in the database.') . '"
											type="button"
										>
											' . I18N::translate('Leaves') . '
										</button>
									</div>
								</div>
							</th>
						</tr>
						<tr>
							<th>' . GedcomTag::getLabel('GIVN') . '</th>
							<th>' . GedcomTag::getLabel('SURN') . '</th>
							<th>GIVN</th>
							<th>SURN</th>
							<th>' . I18N::translate('Sosa') . '</th>
							<th>SOSA</th>
							<th>' . GedcomTag::getLabel('BIRT') . '</th>
							<th>SORT_BIRT</th>
							<th><i class="icon-reminder" title="' . I18N::translate('Anniversary') . '"></i></th>
							<th>' . GedcomTag::getLabel('PLAC') . '</th>
							<th><i class="icon-children" title="' . I18N::translate('Children') . '"></i></th>
							<th>NCHI</th>
							<th>' . GedcomTag::getLabel('DEAT') . '</th>
							<th>SORT_DEAT</th>
							<th><i class="icon-reminder" title="' . I18N::translate('Anniversary') . '"></i></th>
							<th>' . GedcomTag::getLabel('AGE') . '</th>
							<th>AGE</th>
							<th>' . GedcomTag::getLabel('PLAC') . '</th>
							<th>' . GedcomTag::getLabel('CHAN') . '</th>
							<th>CHAN</th>
							<th>SEX</th>
							<th>BIRT</th>
							<th>DEAT</th>
							<th>TREE</th>
						</tr>
					</thead>
					<tfoot>
						<tr>
							<th colspan="24">
								<div class="btn-toolbar">
									<div class="btn-group">
										<button type="button" class="ui-state-default btn-toggle-parents">
											' . I18N::translate('Show parents') . '
										</button>
										<button type="button" class="ui-state-default btn-toggle-statistics">
											' . I18N::translate('Show statistics charts') . '
										</button>
									</div>
								</div>
							</th>
						</tr>
					</tfoot>
					<tbody>';
        $d100y = new Date(date('Y') - 100);
        // 100 years ago
        $unique_indis = array();
        // Don't double-count indis with multiple names.
        foreach ($datalist as $key => $person) {
            if (!$person->canShowName()) {
                continue;
            }
            if ($person->isPendingAddtion()) {
                $class = ' class="new"';
            } elseif ($person->isPendingDeletion()) {
                $class = ' class="old"';
            } else {
                $class = '';
            }
            $html .= '<tr' . $class . '>';
            //-- Indi name(s)
            $html .= '<td colspan="2">';
            foreach ($person->getAllNames() as $num => $name) {
                if ($name['type'] == 'NAME') {
                    $title = '';
                } else {
                    $title = 'title="' . strip_tags(GedcomTag::getLabel($name['type'], $person)) . '"';
                }
                if ($num == $person->getPrimaryName()) {
                    $class = ' class="name2"';
                    $sex_image = $person->getSexImage();
                    list($surn, $givn) = explode(',', $name['sort']);
                } else {
                    $class = '';
                    $sex_image = '';
                }
                $html .= '<a ' . $title . ' href="' . $person->getHtmlUrl() . '"' . $class . '>' . FunctionsPrint::highlightSearchHits($name['full']) . '</a>' . $sex_image . '<br>';
            }
            // Indi parents
            $html .= $person->getPrimaryParentsNames('parents details1', 'none');
            $html .= '</td>';
            // Dummy column to match colspan in header
            $html .= '<td style="display:none;"></td>';
            //-- GIVN/SURN
            // 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>' . Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)) . 'AAAA' . Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)) . '</td>';
            $html .= '<td>' . Filter::escapeHtml(str_replace('@N.N.', 'AAAA', $surn)) . 'AAAA' . Filter::escapeHtml(str_replace('@P.N.', 'AAAA', $givn)) . '</td>';
            //-- SOSA
            if ($option == 'sosa') {
                $html .= '<td><a href="../../relationship.php?pid1=' . $datalist[1] . '&amp;pid2=' . $person->getXref() . '" title="' . I18N::translate('Relationships') . '">' . I18N::number($key) . '</a></td><td>' . $key . '</td>';
            } else {
                $html .= '<td></td><td>0</td>';
            }
            //-- Birth date
            $html .= '<td>';
            if ($birth_dates = $person->getAllBirthDates()) {
                foreach ($birth_dates as $num => $birth_date) {
                    if ($num) {
                        $html .= '<br>';
                    }
                    $html .= $birth_date->display(true);
                }
                if ($birth_dates[0]->gregorianYear() >= 1550 && $birth_dates[0]->gregorianYear() < 2030 && !isset($unique_indis[$person->getXref()])) {
                    $birt_by_decade[(int) ($birth_dates[0]->gregorianYear() / 10) * 10] .= $person->getSex();
                }
            } else {
                $birth_date = $person->getEstimatedBirthDate();
                if ($person->getTree()->getPreference('SHOW_EST_LIST_DATES')) {
                    $html .= $birth_date->display(true);
                } else {
                    $html .= '&nbsp;';
                }
                $birth_dates[0] = new Date('');
            }
            $html .= '</td>';
            //-- Event date (sortable)hidden by datatables code
            $html .= '<td>' . $birth_date->julianDay() . '</td>';
            //-- Birth anniversary
            $html .= '<td>' . Date::getAge($birth_dates[0], null, 2) . '</td>';
            //-- Birth place
            $html .= '<td>';
            foreach ($person->getAllBirthPlaces() as $n => $birth_place) {
                $tmp = new Place($birth_place, $person->getTree());
                if ($n) {
                    $html .= '<br>';
                }
                $html .= '<a href="' . $tmp->getURL() . '" title="' . strip_tags($tmp->getFullName()) . '">';
                $html .= FunctionsPrint::highlightSearchHits($tmp->getShortName()) . '</a>';
            }
            $html .= '</td>';
            //-- Number of children
            $nchi = $person->getNumberOfChildren();
            $html .= '<td>' . I18N::number($nchi) . '</td><td>' . $nchi . '</td>';
            //-- Death date
            $html .= '<td>';
            if ($death_dates = $person->getAllDeathDates()) {
                foreach ($death_dates as $num => $death_date) {
                    if ($num) {
                        $html .= '<br>';
                    }
                    $html .= $death_date->display(true);
                }
                if ($death_dates[0]->gregorianYear() >= 1550 && $death_dates[0]->gregorianYear() < 2030 && !isset($unique_indis[$person->getXref()])) {
                    $deat_by_decade[(int) ($death_dates[0]->gregorianYear() / 10) * 10] .= $person->getSex();
                }
            } else {
                $death_date = $person->getEstimatedDeathDate();
                // Estimated death dates are a fixed number of years after the birth date.
                // Don't show estimates in the future.
                if ($person->getTree()->getPreference('SHOW_EST_LIST_DATES') && $death_date->minimumJulianDay() < WT_CLIENT_JD) {
                    $html .= $death_date->display(true);
                } elseif ($person->isDead()) {
                    $html .= I18N::translate('yes');
                } else {
                    $html .= '&nbsp;';
                }
                $death_dates[0] = new Date('');
            }
            $html .= '</td>';
            //-- Event date (sortable)hidden by datatables code
            $html .= '<td>' . $death_date->julianDay() . '</td>';
            //-- Death anniversary
            $html .= '<td>' . Date::getAge($death_dates[0], null, 2) . '</td>';
            //-- Age at death
            $age = Date::getAge($birth_dates[0], $death_dates[0], 0);
            if (!isset($unique_indis[$person->getXref()]) && $age >= 0 && $age <= $max_age) {
                $deat_by_age[$age] .= $person->getSex();
            }
            // Need both display and sortable age
            $html .= '<td>' . Date::getAge($birth_dates[0], $death_dates[0], 2) . '</td><td>' . Date::getAge($birth_dates[0], $death_dates[0], 1) . '</td>';
            //-- Death place
            $html .= '<td>';
            foreach ($person->getAllDeathPlaces() as $n => $death_place) {
                $tmp = new Place($death_place, $person->getTree());
                if ($n) {
                    $html .= '<br>';
                }
                $html .= '<a href="' . $tmp->getURL() . '" title="' . strip_tags($tmp->getFullName()) . '">';
                $html .= FunctionsPrint::highlightSearchHits($tmp->getShortName()) . '</a>';
            }
            $html .= '</td>';
            //-- Last change
            $html .= '<td>' . $person->lastChangeTimestamp() . '</td>';
            $html .= '<td>' . $person->lastChangeTimestamp(true) . '</td>';
            //-- Sorting by gender
            $html .= '<td>' . $person->getSex() . '</td>';
            //-- Filtering by birth date
            $html .= '<td>';
            if (!$person->canShow() || Date::compare($birth_date, $d100y) > 0) {
                $html .= 'Y100';
            } else {
                $html .= 'YES';
            }
            $html .= '</td>';
            //-- Filtering by death date
            $html .= '<td>';
            // Died in last 100 years?  Died?  Not dead?
            if (Date::compare($death_dates[0], $d100y) > 0) {
                $html .= 'Y100';
            } elseif ($death_dates[0]->minimumJulianDay() || $person->isDead()) {
                $html .= 'YES';
            } else {
                $html .= 'N';
            }
            $html .= '</td>';
            //-- Roots or Leaves ?
            $html .= '<td>';
            if (!$person->getChildFamilies()) {
                $html .= 'R';
            } elseif (!$person->isDead() && $person->getNumberOfChildren() < 1) {
                $html .= 'L';
            } else {
                $html .= '&nbsp;';
            }
            $html .= '</td>';
            $html .= '</tr>';
            $unique_indis[$person->getXref()] = true;
        }
        $html .= '
					</tbody>
				</table>
				<div id="indi_list_table-charts_' . $table_id . '" style="display:none">
					<table class="list-charts">
						<tr>
							<td>
								' . self::chartByDecade($birt_by_decade, I18N::translate('Decade of birth')) . '
							</td>
							<td>
								' . self::chartByDecade($deat_by_decade, I18N::translate('Decade of death')) . '
							</td>
						</tr>
						<tr>
							<td colspan="2">
								' . self::chartByAge($deat_by_age, I18N::translate('Age related to death year')) . '
							</td>
						</tr>
					</table>
				</div>
			</div>';
        return $html;
    }
Ejemplo n.º 5
0
    /**
     * Print a table of individuals
     *
     * @param Individual[] $indiviudals
     * @param string       $option
     *
     * @return string
     */
    public static function individualTable($indiviudals, $option = '')
    {
        global $controller, $WT_TREE;
        $table_id = 'table-indi-' . Uuid::uuid4();
        // lists requires a unique ID in case there are multiple lists per page
        $controller->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)->addInlineJavascript('
				jQuery.fn.dataTableExt.oSort["text-asc"] = textCompareAsc;
				jQuery.fn.dataTableExt.oSort["text-desc"] = textCompareDesc;
				jQuery("#' . $table_id . '").dataTable( {
					dom: \'<"H"<"filtersH_' . $table_id . '">T<"dt-clear">pf<"dt-clear">irl>t<"F"pl<"dt-clear"><"filtersF_' . $table_id . '">>\',
					' . I18N::datatablesI18N() . ',
					jQueryUI: true,
					autoWidth: false,
					processing: true,
					retrieve: true,
					columns: [
						/* Given names  */ { type: "text" },
						/* Surnames     */ { type: "text" },
						/* SOSA numnber */ { type: "num", visible: ' . ($option == 'sosa' ? 'true' : 'false') . ' },
						/* Birth date   */ { type: "num" },
						/* Anniversary  */ { type: "num" },
						/* Birthplace   */ { type: "text" },
						/* Children     */ { type: "num" },
						/* Deate date   */ { type: "num" },
						/* Anniversary  */ { type: "num" },
						/* Age          */ { type: "num" },
						/* Death place  */ { type: "text" },
						/* Last change  */ { visible: ' . ($WT_TREE->getPreference('SHOW_LAST_CHANGE') ? 'true' : 'false') . ' },
						/* Filter sex   */ { sortable: false },
						/* Filter birth */ { sortable: false },
						/* Filter death */ { sortable: false },
						/* Filter tree  */ { sortable: false }
					],
					sorting: [[' . ($option == 'sosa' ? '4, "asc"' : '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("#indi_list_table-charts_' . $table_id . '").slideToggle();
				})
				/* Filter buttons in table header */
				.on("click", "button[data-filter-column]", function() {
					var btn = jQuery(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(".indi-list").css("visibility", "visible");
				jQuery(".loading-image").css("display", "none");
			');
        $stats = new Stats($WT_TREE);
        // Bad data can cause "longest life" to be huge, blowing memory limits
        $max_age = min($WT_TREE->getPreference('MAX_ALIVE_AGE'), $stats->longestLifeAge()) + 1;
        // Inititialise chart data
        $deat_by_age = array();
        for ($age = 0; $age <= $max_age; $age++) {
            $deat_by_age[$age] = '';
        }
        $birt_by_decade = array();
        $deat_by_decade = array();
        for ($year = 1550; $year < 2030; $year += 10) {
            $birt_by_decade[$year] = '';
            $deat_by_decade[$year] = '';
        }
        $html = '
			<div class="loading-image"></div>
			<div class="indi-list">
				<table id="' . $table_id . '">
					<thead>
						<tr>
							<th colspan="16">
								<div class="btn-toolbar">
									<div class="btn-group">
										<button
											class="ui-state-default"
											data-filter-column="12"
											data-filter-value="M"
											title="' . I18N::translate('Show only males.') . '"
											type="button"
										>
										  ' . Individual::sexImage('M', 'large') . '
										</button>
										<button
											class="ui-state-default"
											data-filter-column="12"
											data-filter-value="F"
											title="' . I18N::translate('Show only females.') . '"
											type="button"
										>
											' . Individual::sexImage('F', 'large') . '
										</button>
										<button
											class="ui-state-default"
											data-filter-column="12"
											data-filter-value="U"
											title="' . I18N::translate('Show only individuals for whom the gender is not known.') . '"
											type="button"
										>
											' . Individual::sexImage('U', 'large') . '
										</button>
									</div>
									<div class="btn-group">
										<button
											class="ui-state-default"
											data-filter-column="14"
											data-filter-value="N"
											title="' . I18N::translate('Show individuals who are alive or couples where both partners are alive.') . '"
											type="button"
										>
											' . I18N::translate('Alive') . '
										</button>
										<button
											class="ui-state-default"
											data-filter-column="14"
											data-filter-value="Y"
											title="' . I18N::translate('Show individuals who are dead or couples where both partners are dead.') . '"
											type="button"
										>
											' . I18N::translate('Dead') . '
										</button>
										<button
											class="ui-state-default"
											data-filter-column="14"
											data-filter-value="YES"
											title="' . I18N::translate('Show individuals who died more than 100 years ago.') . '"
											type="button"
										>
											' . GedcomTag::getLabel('DEAT') . '&gt;100
										</button>
										<button
											class="ui-state-default"
											data-filter-column="14"
											data-filter-value="Y100"
											title="' . I18N::translate('Show individuals who died within the last 100 years.') . '"
											type="button"
										>
											' . GedcomTag::getLabel('DEAT') . '&lt;=100
										</button>
									</div>
									<div class="btn-group">
										<button
											class="ui-state-default"
											data-filter-column="13"
											data-filter-value="YES"
											title="' . I18N::translate('Show individuals born more than 100 years ago.') . '"
											type="button"
										>
											' . GedcomTag::getLabel('BIRT') . '&gt;100
										</button>
										<button
											class="ui-state-default"
											data-filter-column="13"
											data-filter-value="Y100"
											title="' . I18N::translate('Show individuals born within the last 100 years.') . '"
											type="button"
										>
											' . GedcomTag::getLabel('BIRT') . '&lt;=100
										</button>
									</div>
									<div class="btn-group">
										<button
											class="ui-state-default"
											data-filter-column="15"
											data-filter-value="R"
											title="' . 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.') . '"
											type="button"
										>
											' . I18N::translate('Roots') . '
										</button>
										<button
											class="ui-state-default"
											data-filter-column="15"
											data-filter-value="L"
											title="' . I18N::translate('Show “leaves” couples or individuals. These are individuals who are alive but have no children recorded in the database.') . '"
											type="button"
										>
											' . I18N::translate('Leaves') . '
										</button>
									</div>
								</div>
							</th>
						</tr>
						<tr>
							<th>' . GedcomTag::getLabel('GIVN') . '</th>
							<th>' . GedcomTag::getLabel('SURN') . '</th>
							<th>' . I18N::translate('Sosa') . '</th>
							<th>' . GedcomTag::getLabel('BIRT') . '</th>
							<th><i class="icon-reminder" title="' . I18N::translate('Anniversary') . '"></i></th>
							<th>' . GedcomTag::getLabel('PLAC') . '</th>
							<th><i class="icon-children" title="' . I18N::translate('Children') . '"></i></th>
							<th>' . GedcomTag::getLabel('DEAT') . '</th>
							<th><i class="icon-reminder" title="' . I18N::translate('Anniversary') . '"></i></th>
							<th>' . GedcomTag::getLabel('AGE') . '</th>
							<th>' . GedcomTag::getLabel('PLAC') . '</th>
							<th>' . GedcomTag::getLabel('CHAN') . '</th>
							<th hidden></th>
							<th hidden></th>
							<th hidden></th>
							<th hidden></th>
						</tr>
					</thead>
					<tfoot>
						<tr>
							<th colspan="16">
								<div class="btn-toolbar">
									<div class="btn-group">
										<button type="button" class="ui-state-default btn-toggle-parents">
											' . I18N::translate('Show parents') . '
										</button>
										<button type="button" class="ui-state-default btn-toggle-statistics">
											' . I18N::translate('Show statistics charts') . '
										</button>
									</div>
								</div>
							</th>
						</tr>
					</tfoot>
					<tbody>';
        $hundred_years_ago = new Date(date('Y') - 100);
        $unique_indis = array();
        // Don't double-count indis with multiple names.
        foreach ($indiviudals as $key => $individual) {
            if (!$individual->canShowName()) {
                continue;
            }
            if ($individual->isPendingAddtion()) {
                $class = ' class="new"';
            } elseif ($individual->isPendingDeletion()) {
                $class = ' class="old"';
            } else {
                $class = '';
            }
            $html .= '<tr' . $class . '>';
            // Extract Given names and Surnames for sorting
            list($surn_givn, $givn_surn) = self::sortableNames($individual);
            $html .= '<td colspan="2" data-sort="' . Filter::escapeHtml($givn_surn) . '">';
            foreach ($individual->getAllNames() as $num => $name) {
                if ($name['type'] == 'NAME') {
                    $title = '';
                } else {
                    $title = 'title="' . strip_tags(GedcomTag::getLabel($name['type'], $individual)) . '"';
                }
                if ($num == $individual->getPrimaryName()) {
                    $class = ' class="name2"';
                    $sex_image = $individual->getSexImage();
                } else {
                    $class = '';
                    $sex_image = '';
                }
                $html .= '<a ' . $title . ' href="' . $individual->getHtmlUrl() . '"' . $class . '>' . FunctionsPrint::highlightSearchHits($name['full']) . '</a>' . $sex_image . '<br>';
            }
            $html .= $individual->getPrimaryParentsNames('parents details1', 'none');
            $html .= '</td>';
            // Hidden column for sortable name
            $html .= '<td hidden data-sort="' . Filter::escapeHtml($surn_givn) . '"></td>';
            // SOSA
            $html .= '<td class="center" data-sort="' . $key . '"><a href="relationship.php?pid1=' . $indiviudals[1] . '&amp;pid2=' . $individual->getXref() . '" title="' . I18N::translate('Relationships') . '">' . I18N::number($key) . '</a></td>';
            // Birth date
            $birth_dates = $individual->getAllBirthDates();
            $html .= '<td data-sort="' . $individual->getEstimatedBirthDate()->julianDay() . '">';
            foreach ($birth_dates as $n => $birth_date) {
                if ($n > 0) {
                    $html .= '<br>';
                }
                $html .= $birth_date->display(true);
            }
            $html .= '</td>';
            // Birth anniversary
            if (isset($birth_dates[0]) && $birth_dates[0]->gregorianYear() >= 1550 && $birth_dates[0]->gregorianYear() < 2030 && !isset($unique_indis[$individual->getXref()])) {
                $birt_by_decade[(int) ($birth_dates[0]->gregorianYear() / 10) * 10] .= $individual->getSex();
                $anniversary = Date::getAge($birth_dates[0], null, 2);
            } else {
                $anniversary = '';
            }
            $html .= '<td class="center" data-sort="' . -$individual->getEstimatedBirthDate()->julianDay() . '">' . $anniversary . '</td>';
            // Birth place
            $html .= '<td>';
            foreach ($individual->getAllBirthPlaces() as $n => $birth_place) {
                $tmp = new Place($birth_place, $individual->getTree());
                if ($n > 0) {
                    $html .= '<br>';
                }
                $html .= '<a href="' . $tmp->getURL() . '" title="' . strip_tags($tmp->getFullName()) . '">';
                $html .= FunctionsPrint::highlightSearchHits($tmp->getShortName()) . '</a>';
            }
            $html .= '</td>';
            // Number of children
            $number_of_children = $individual->getNumberOfChildren();
            $html .= '<td class="center" data-sort="' . $number_of_children . '">' . I18N::number($number_of_children) . '</td>';
            // Death date
            $death_dates = $individual->getAllDeathDates();
            $html .= '<td data-sort="' . $individual->getEstimatedDeathDate()->julianDay() . '">';
            foreach ($death_dates as $num => $death_date) {
                if ($num) {
                    $html .= '<br>';
                }
                $html .= $death_date->display(true);
            }
            $html .= '</td>';
            // Death anniversary
            if (isset($death_dates[0]) && $death_dates[0]->gregorianYear() >= 1550 && $death_dates[0]->gregorianYear() < 2030 && !isset($unique_indis[$individual->getXref()])) {
                $birt_by_decade[(int) ($death_dates[0]->gregorianYear() / 10) * 10] .= $individual->getSex();
                $anniversary = Date::getAge($death_dates[0], null, 2);
            } else {
                $anniversary = '';
            }
            $html .= '<td class="center" data-sort="' . -$individual->getEstimatedDeathDate()->julianDay() . '">' . $anniversary . '</td>';
            // Age at death
            if (isset($birth_dates[0]) && isset($death_dates[0])) {
                $age_at_death = Date::getAge($birth_dates[0], $death_dates[0], 0);
                $age_at_death_sort = Date::getAge($birth_dates[0], $death_dates[0], 2);
                if (!isset($unique_indis[$individual->getXref()]) && $age >= 0 && $age <= $max_age) {
                    $deat_by_age[$age_at_death] .= $individual->getSex();
                }
            } else {
                $age_at_death = '';
                $age_at_death_sort = PHP_INT_MAX;
            }
            $html .= '<td class="center" data-sort="' . $age_at_death_sort . '">' . $age_at_death . '</td>';
            // Death place
            $html .= '<td>';
            foreach ($individual->getAllDeathPlaces() as $n => $death_place) {
                $tmp = new Place($death_place, $individual->getTree());
                if ($n > 0) {
                    $html .= '<br>';
                }
                $html .= '<a href="' . $tmp->getURL() . '" title="' . strip_tags($tmp->getFullName()) . '">';
                $html .= FunctionsPrint::highlightSearchHits($tmp->getShortName()) . '</a>';
            }
            $html .= '</td>';
            // Last change
            $html .= '<td data-sort="' . $individual->lastChangeTimestamp(true) . '">' . $individual->lastChangeTimestamp() . '</td>';
            // Filter by sex
            $html .= '<td hidden>' . $individual->getSex() . '</td>';
            // Filter by birth date
            $html .= '<td hidden>';
            if (!$individual->canShow() || Date::compare($individual->getEstimatedBirthDate(), $hundred_years_ago) > 0) {
                $html .= 'Y100';
            } else {
                $html .= 'YES';
            }
            $html .= '</td>';
            // Filter by death date
            $html .= '<td hidden>';
            // Died in last 100 years? Died? Not dead?
            if (isset($death_dates[0]) && Date::compare($death_dates[0], $hundred_years_ago) > 0) {
                $html .= 'Y100';
            } elseif ($individual->isDead()) {
                $html .= 'YES';
            } else {
                $html .= 'N';
            }
            $html .= '</td>';
            // Filter by roots/leaves
            $html .= '<td hidden>';
            if (!$individual->getChildFamilies()) {
                $html .= 'R';
            } elseif (!$individual->isDead() && $individual->getNumberOfChildren() < 1) {
                $html .= 'L';
                $html .= '&nbsp;';
            }
            $html .= '</td>';
            $html .= '</tr>';
            $unique_indis[$individual->getXref()] = true;
        }
        $html .= '
					</tbody>
				</table>
				<div id="indi_list_table-charts_' . $table_id . '" style="display:none">
					<table class="list-charts">
						<tr>
							<td>
								' . self::chartByDecade($birt_by_decade, I18N::translate('Decade of birth')) . '
							</td>
							<td>
								' . self::chartByDecade($deat_by_decade, I18N::translate('Decade of death')) . '
							</td>
						</tr>
						<tr>
							<td colspan="2">
								' . self::chartByAge($deat_by_age, I18N::translate('Age related to death year')) . '
							</td>
						</tr>
					</table>
				</div>
			</div>';
        return $html;
    }