public static function noteTable($notes)
{
global $WT_TREE, $controller;
// Count the number of linked records. These numbers include private records.
// It is not good to bypass privacy, but many servers do not have the resources
// to process privacy for every record in the tree
$count_individuals = Database::prepare("SELECT CONCAT(l_to, '@', l_file), COUNT(*) FROM `##individuals` JOIN `##link` ON l_from = i_id AND l_file = i_file AND l_type = 'NOTE' GROUP BY l_to, l_file")->fetchAssoc();
$count_families = Database::prepare("SELECT CONCAT(l_to, '@', l_file), COUNT(*) FROM `##families` JOIN `##link` ON l_from = f_id AND l_file = f_file AND l_type = 'NOTE' GROUP BY l_to, l_file")->fetchAssoc();
$count_media = Database::prepare("SELECT CONCAT(l_to, '@', l_file), COUNT(*) FROM `##media` JOIN `##link` ON l_from = m_id AND l_file = m_file AND l_type = 'NOTE' GROUP BY l_to, l_file")->fetchAssoc();
$count_sources = Database::prepare("SELECT CONCAT(l_to, '@', l_file), COUNT(*) FROM `##sources` JOIN `##link` ON l_from = s_id AND l_file = s_file AND l_type = 'NOTE' GROUP BY l_to, l_file")->fetchAssoc();
$html = '';
$table_id = 'table-note-' . 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"pf<"dt-clear">irl>t<"F"pl>\',
' . I18N::datatablesI18N() . ',
jQueryUI: true,
autoWidth: false,
processing: true,
columns: [
/* Title */ { type: "text" },
/* Individuals */ { type: "num" },
/* Families */ { type: "num" },
/* Media objects */ { type: "num" },
/* Sources */ { type: "num" },
/* Last change */ { type: "num", visible: ' . ($WT_TREE->getPreference('SHOW_LAST_CHANGE') ? 'true' : 'false') . ' },
/* Delete */ { visible: ' . (Auth::isManager($WT_TREE) ? 'true' : 'false') . ', sortable: false }
],
displayLength: 20,
pagingType: "full_numbers"
});
jQuery(".note-list").css("visibility", "visible");
jQuery(".loading-image").css("display", "none");
');
$html .= '<div class="loading-image"></div>';
$html .= '<div class="note-list">';
$html .= '<table id="' . $table_id . '"><thead><tr>';
$html .= '<th>' . GedcomTag::getLabel('TITL') . '</th>';
$html .= '<th>' . I18N::translate('Individuals') . '</th>';
$html .= '<th>' . I18N::translate('Families') . '</th>';
$html .= '<th>' . I18N::translate('Media objects') . '</th>';
$html .= '<th>' . I18N::translate('Sources') . '</th>';
$html .= '<th>' . GedcomTag::getLabel('CHAN') . '</th>';
$html .= '<th>' . I18N::translate('Delete') . '</th>';
$html .= '</tr></thead>';
$html .= '<tbody>';
foreach ($notes as $note) {
if (!$note->canShow()) {
continue;
}
if ($note->isPendingAddtion()) {
$class = ' class="new"';
} elseif ($note->isPendingDeletion()) {
$class = ' class="old"';
} else {
$class = '';
}
$html .= '<tr' . $class . '>';
// Count of linked notes
$html .= '<td data-sort="' . Filter::escapeHtml($note->getSortName()) . '"><a class="name2" href="' . $note->getHtmlUrl() . '">' . FunctionsPrint::highlightSearchHits($note->getFullName()) . '</a></td>';
$key = $note->getXref() . '@' . $note->getTree()->getTreeId();
// Count of linked individuals
$num = array_key_exists($key, $count_individuals) ? $count_individuals[$key] : 0;
$html .= '<td class="center" data-sort="' . $num . '">' . I18N::number($num) . '</td>';
// Count of linked families
$num = array_key_exists($key, $count_families) ? $count_families[$key] : 0;
$html .= '<td class="center" data-sort="' . $num . '">' . I18N::number($num) . '</td>';
// Count of linked media objects
$num = array_key_exists($key, $count_media) ? $count_media[$key] : 0;
$html .= '<td class="center" data-sort="' . $num . '">' . I18N::number($num) . '</td>';
// Count of linked sources
$num = array_key_exists($key, $count_sources) ? $count_sources[$key] : 0;
$html .= '<td class="center" data-sort="' . $num . '">' . I18N::number($num) . '</td>';
// Last change
$html .= '<td data-sort="' . $note->lastChangeTimestamp(true) . '">' . $note->lastChangeTimestamp() . '</td>';
// Delete
$html .= '<td><a href="#" title="' . I18N::translate('Delete') . '" class="deleteicon" onclick="return delete_record(\'' . I18N::translate('Are you sure you want to delete “%s”?', Filter::escapeJs(Filter::unescapeHtml($note->getFullName()))) . "', '" . $note->getXref() . '\');"><span class="link_text">' . I18N::translate('Delete') . '</span></a></td>';
$html .= '</tr>';
}
$html .= '</tbody></table></div>';
return $html;
}