public static function repositoryTable($repositories)
{
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_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 = 'REPO' GROUP BY l_to, l_file")->fetchAssoc();
$html = '';
$table_id = 'table-repo-' . 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: [
/* Name */ { type: "text" },
/* Sources */ { type: "num" },
/* Last change */ { 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(".repo-list").css("visibility", "visible");
jQuery(".loading-image").css("display", "none");
');
$html .= '<div class="loading-image"></div>';
$html .= '<div class="repo-list">';
$html .= '<table id="' . $table_id . '"><thead><tr>';
$html .= '<th>' . I18N::translate('Repository name') . '</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 ($repositories as $repository) {
if (!$repository->canShow()) {
continue;
}
if ($repository->isPendingAddtion()) {
$class = ' class="new"';
} elseif ($repository->isPendingDeletion()) {
$class = ' class="old"';
} else {
$class = '';
}
$html .= '<tr' . $class . '>';
// Repository name(s)
$html .= '<td data-sort="' . Filter::escapeHtml($repository->getSortName()) . '">';
foreach ($repository->getAllNames() as $n => $name) {
if ($n) {
$html .= '<br>';
}
if ($n == $repository->getPrimaryName()) {
$html .= '<a class="name2" href="' . $repository->getHtmlUrl() . '">' . FunctionsPrint::highlightSearchHits($name['full']) . '</a>';
} else {
$html .= '<a href="' . $repository->getHtmlUrl() . '">' . FunctionsPrint::highlightSearchHits($name['full']) . '</a>';
}
}
$html .= '</td>';
$key = $repository->getXref() . '@' . $repository->getTree()->getTreeId();
// 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="' . $repository->lastChangeTimestamp(true) . '">' . $repository->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($repository->getFullName()))) . "', '" . $repository->getXref() . '\');"><span class="link_text">' . I18N::translate('Delete') . '</span></a></td>';
$html .= '</tr>';
}
$html .= '</tbody></table></div>';
return $html;
}