1<?php 2 3use Fisharebest\Webtrees\Http\RequestHandlers\BroadcastPage; 4use Fisharebest\Webtrees\Http\RequestHandlers\CleanDataFolder; 5use Fisharebest\Webtrees\Http\RequestHandlers\ControlPanel; 6use Fisharebest\Webtrees\Http\RequestHandlers\CreateTreePage; 7use Fisharebest\Webtrees\Http\RequestHandlers\EmailPreferencesPage; 8use Fisharebest\Webtrees\Http\RequestHandlers\FixLevel0MediaPage; 9use Fisharebest\Webtrees\Http\RequestHandlers\ImportThumbnailsPage; 10use Fisharebest\Webtrees\Http\RequestHandlers\ManageMediaPage; 11use Fisharebest\Webtrees\Http\RequestHandlers\ManageTrees; 12use Fisharebest\Webtrees\Http\RequestHandlers\MapDataList; 13use Fisharebest\Webtrees\Http\RequestHandlers\MergeTreesPage; 14use Fisharebest\Webtrees\Http\RequestHandlers\ModulesAllPage; 15use Fisharebest\Webtrees\Http\RequestHandlers\ModulesAnalyticsPage; 16use Fisharebest\Webtrees\Http\RequestHandlers\ModulesBlocksPage; 17use Fisharebest\Webtrees\Http\RequestHandlers\ModulesChartsPage; 18use Fisharebest\Webtrees\Http\RequestHandlers\ModulesCustomTagsPage; 19use Fisharebest\Webtrees\Http\RequestHandlers\ModulesDataFixesPage; 20use Fisharebest\Webtrees\Http\RequestHandlers\ModulesFootersPage; 21use Fisharebest\Webtrees\Http\RequestHandlers\ModulesHistoricEventsPage; 22use Fisharebest\Webtrees\Http\RequestHandlers\ModulesLanguagesPage; 23use Fisharebest\Webtrees\Http\RequestHandlers\ModulesListsPage; 24use Fisharebest\Webtrees\Http\RequestHandlers\ModulesMapAutocompletePage; 25use Fisharebest\Webtrees\Http\RequestHandlers\ModulesMapGeoLocationsPage; 26use Fisharebest\Webtrees\Http\RequestHandlers\ModulesMapLinksPage; 27use Fisharebest\Webtrees\Http\RequestHandlers\ModulesMapProvidersPage; 28use Fisharebest\Webtrees\Http\RequestHandlers\ModulesMenusPage; 29use Fisharebest\Webtrees\Http\RequestHandlers\ModulesReportsPage; 30use Fisharebest\Webtrees\Http\RequestHandlers\ModulesSharesPage; 31use Fisharebest\Webtrees\Http\RequestHandlers\ModulesSidebarsPage; 32use Fisharebest\Webtrees\Http\RequestHandlers\ModulesTabsPage; 33use Fisharebest\Webtrees\Http\RequestHandlers\ModulesThemesPage; 34use Fisharebest\Webtrees\Http\RequestHandlers\PendingChanges; 35use Fisharebest\Webtrees\Http\RequestHandlers\PhpInformation; 36use Fisharebest\Webtrees\Http\RequestHandlers\SiteLogsPage; 37use Fisharebest\Webtrees\Http\RequestHandlers\SitePreferencesPage; 38use Fisharebest\Webtrees\Http\RequestHandlers\SiteRegistrationPage; 39use Fisharebest\Webtrees\Http\RequestHandlers\SiteTagsPage; 40use Fisharebest\Webtrees\Http\RequestHandlers\TreePageDefaultEdit; 41use Fisharebest\Webtrees\Http\RequestHandlers\UpgradeWizardPage; 42use Fisharebest\Webtrees\Http\RequestHandlers\UploadMediaPage; 43use Fisharebest\Webtrees\Http\RequestHandlers\UserAddPage; 44use Fisharebest\Webtrees\Http\RequestHandlers\UserEditPage; 45use Fisharebest\Webtrees\Http\RequestHandlers\UserListPage; 46use Fisharebest\Webtrees\Http\RequestHandlers\UserPageDefaultEdit; 47use Fisharebest\Webtrees\Http\RequestHandlers\UsersCleanupPage; 48use Fisharebest\Webtrees\I18N; 49use Fisharebest\Webtrees\Module\FamilyListModule; 50use Fisharebest\Webtrees\Module\IndividualListModule; 51use Fisharebest\Webtrees\Module\MediaListModule; 52use Fisharebest\Webtrees\Module\ModuleAnalyticsInterface; 53use Fisharebest\Webtrees\Module\ModuleBlockInterface; 54use Fisharebest\Webtrees\Module\ModuleChartInterface; 55use Fisharebest\Webtrees\Module\ModuleConfigInterface; 56use Fisharebest\Webtrees\Module\ModuleCustomInterface; 57use Fisharebest\Webtrees\Module\ModuleCustomTagsInterface; 58use Fisharebest\Webtrees\Module\ModuleDataFixInterface; 59use Fisharebest\Webtrees\Module\ModuleFooterInterface; 60use Fisharebest\Webtrees\Module\ModuleHistoricEventsInterface; 61use Fisharebest\Webtrees\Module\ModuleInterface; 62use Fisharebest\Webtrees\Module\ModuleLanguageInterface; 63use Fisharebest\Webtrees\Module\ModuleListInterface; 64use Fisharebest\Webtrees\Module\ModuleMapAutocompleteInterface; 65use Fisharebest\Webtrees\Module\ModuleMapGeoLocationInterface; 66use Fisharebest\Webtrees\Module\ModuleMapLinkInterface; 67use Fisharebest\Webtrees\Module\ModuleMapProviderInterface; 68use Fisharebest\Webtrees\Module\ModuleMenuInterface; 69use Fisharebest\Webtrees\Module\ModuleReportInterface; 70use Fisharebest\Webtrees\Module\ModuleShareInterface; 71use Fisharebest\Webtrees\Module\ModuleSidebarInterface; 72use Fisharebest\Webtrees\Module\ModuleTabInterface; 73use Fisharebest\Webtrees\Module\ModuleThemeInterface; 74use Fisharebest\Webtrees\Module\NoteListModule; 75use Fisharebest\Webtrees\Module\RepositoryListModule; 76use Fisharebest\Webtrees\Module\SourceListModule; 77use Fisharebest\Webtrees\Module\SubmitterListModule; 78use Fisharebest\Webtrees\Tree; 79use Fisharebest\Webtrees\User; 80use Fisharebest\Webtrees\Webtrees; 81use Illuminate\Support\Collection; 82 83/** 84 * @var Collection<int,User> $administrators 85 * @var Collection<int,ModuleInterface> $all_modules_disabled 86 * @var Collection<int,ModuleInterface> $all_modules_enabled 87 * @var Collection<int,Tree> $all_trees 88 * @var Collection<int,User> $all_users 89 * @var Collection<int,ModuleAnalyticsInterface> $analytics_modules_disabled 90 * @var Collection<int,ModuleAnalyticsInterface> $analytics_modules_enabled 91 * @var Collection<int,ModuleBlockInterface> $block_modules_disabled 92 * @var Collection<int,ModuleBlockInterface> $block_modules_enabled 93 * @var array<string,int> $changes 94 * @var Collection<int,ModuleChartInterface> $chart_modules_disabled 95 * @var Collection<int,ModuleChartInterface> $chart_modules_enabled 96 * @var Collection<int,ModuleCustomInterface> $custom_updates 97 * @var Collection<int,ModuleCustomTagsInterface> $custom_tags_modules_disabled 98 * @var Collection<int,ModuleCustomTagsInterface> $custom_tags_modules_enabled 99 * @var Collection<int,ModuleDataFixInterface> $data_fix_modules_disabled 100 * @var Collection<int,ModuleDataFixInterface> $data_fix_modules_enabled 101 * @var Collection<array-key,int> $families 102 * @var FamilyListModule|null $family_list_module 103 * @var Collection<int,ModuleFooterInterface> $footer_modules_disabled 104 * @var Collection<int,ModuleFooterInterface> $footer_modules_enabled 105 * @var Collection<int,ModuleHistoricEventsInterface> $history_modules_disabled 106 * @var Collection<int,ModuleHistoricEventsInterface> $history_modules_enabled 107 * @var Collection<array-key,int> $individuals 108 * @var IndividualListModule|null $individual_list_module 109 * @var Collection<int,ModuleLanguageInterface> $language_modules_disabled 110 * @var Collection<int,ModuleLanguageInterface> $language_modules_enabled 111 * @var string $latest_version 112 * @var Collection<int,ModuleListInterface> $list_modules_disabled 113 * @var Collection<int,ModuleListInterface> $list_modules_enabled 114 * @var Collection<int,ModuleMapLinkInterface> $map_link_modules_disabled 115 * @var Collection<int,ModuleMapLinkInterface> $map_link_modules_enabled 116 * @var Collection<int,ModuleMapAutocompleteInterface> $map_autocomplete_modules_disabled 117 * @var Collection<int,ModuleMapAutocompleteInterface> $map_autocomplete_modules_enabled 118 * @var Collection<int,ModuleMapProviderInterface> $map_provider_modules_disabled 119 * @var Collection<int,ModuleMapProviderInterface> $map_provider_modules_enabled 120 * @var Collection<int,ModuleMapGeoLocationInterface> $map_search_modules_disabled 121 * @var Collection<int,ModuleMapGeoLocationInterface> $map_search_modules_enabled 122 * @var Collection<int,User> $managers 123 * @var Collection<array-key,int> $media 124 * @var MediaListModule|null $media_list_module 125 * @var Collection<int,ModuleMenuInterface> $menu_modules_disabled 126 * @var Collection<int,ModuleMenuInterface> $menu_modules_enabled 127 * @var Collection<int,User> $moderators 128 * @var Collection<array-key,int> $notes 129 * @var NoteListModule|null $note_list_module 130 * @var Collection<int,ModuleInterface> $other_modules 131 * @var array<string,string> $recipients 132 * @var Collection<int,ModuleReportInterface> $report_modules_disabled 133 * @var Collection<int,ModuleReportInterface> $report_modules_enabled 134 * @var Collection<array-key,int> $repositories 135 * @var RepositoryListModule|null $repository_list_module 136 * @var Collection<int,string> $server_errors 137 * @var Collection<int,string> $server_warnings 138 * @var bool $show_synchronize 139 * @var Collection<int,ModuleShareInterface> $share_modules_disabled 140 * @var Collection<int,ModuleShareInterface> $share_modules_enabled 141 * @var Collection<int,ModuleSidebarInterface> $sidebar_modules_disabled 142 * @var Collection<int,ModuleSidebarInterface> $sidebar_modules_enabled 143 * @var Collection<array-key,int> $sources 144 * @var SourceListModule|null $source_list_module 145 * @var Collection<array-key,int> $submitters 146 * @var SubmitterListModule|null $submitter_list_module 147 * @var Collection<int,ModuleTabInterface> $tab_modules_disabled 148 * @var Collection<int,ModuleTabInterface> $tab_modules_enabled 149 * @var Collection<int,ModuleThemeInterface> $theme_modules_disabled 150 * @var Collection<int,ModuleThemeInterface> $theme_modules_enabled 151 * @var string $title 152 * @var Collection<int,User> $unapproved 153 * @var Collection<int,User> $unverified 154 */ 155 156?> 157 158<h1><?= $title ?></h1> 159 160<!-- WEBSITE / WEBTREES --> 161<div class="card mb-4"> 162 <div class="card-header"> 163 <h2 class="mb-0"> 164 <?= I18N::translate('Website') ?> 165 <span class="badge bg-secondary" dir="ltr"> 166 <?= e(Webtrees::VERSION) ?> 167 </span> 168 </h2> 169 </div> 170 <div class="card-body"> 171 <?php foreach ($server_errors as $server_error) : ?> 172 <p class="alert alert-danger"><?= $server_error ?></p> 173 <?php endforeach ?> 174 175 <?php foreach ($server_warnings as $server_warning) : ?> 176 <p class="alert alert-warning"><?= $server_warning ?></p> 177 <?php endforeach ?> 178 179 <p class="card-text"> 180 <?= /* I18N: %s is a URL/link to the project website */ 181 I18N::translate('Support and documentation can be found at %s.', '<a href="https://webtrees.net/">webtrees.net</a>') ?> 182 </p> 183 184 <?php if ($latest_version === '') : ?> 185 <p class="card-text"> 186 <?= I18N::translate('No upgrade information is available.') ?> 187 </p> 188 <?php elseif (version_compare(Webtrees::VERSION, $latest_version) < 0) : ?> 189 <p class="card-text alert alert-info"> 190 <?= I18N::translate('A new version of webtrees is available.') ?> 191 <a href="<?= e(route(UpgradeWizardPage::class)) ?>" class="alert-link"> 192 <?= /* I18N: %s is a version number */ 193 I18N::translate('Upgrade to webtrees %s.', e($latest_version)) ?> 194 </a> 195 </p> 196 <?php else : ?> 197 <p class="card-text"> 198 <?= I18N::translate('This is the latest version of webtrees. No upgrade is available.') ?> 199 </p> 200 <?php endif ?> 201 202 <?php foreach ($custom_updates as $module) : ?> 203 <div class="alert alert-info"> 204 <?= view('icons/information') ?> 205 <?= I18N::translate('An upgrade is available.') ?> 206 <br> 207 <?= $module->title() ?> — <?= e($module->customModuleVersion()) ?> — <?= e($module->customModuleLatestVersion()) ?> 208 <?php if ($module->customModuleSupportUrl() !== '') : ?> 209 <br> 210 <?= I18N::translate('For more information, see %s.', '<a href="' . e($module->customModuleSupportUrl()) . '">' . e($module->customModuleSupportUrl()) . '</a>') ?> 211 <?php endif ?> 212 </div> 213 <?php endforeach ?> 214 215 <div class="row"> 216 <div class="col-sm"> 217 <ul class="fa-ul mx-0"> 218 <li> 219 <span class="fa-li"><?= view('icons/preferences') ?></span> 220 <a href="<?= e(route(SitePreferencesPage::class)) ?>"> 221 <?= I18N::translate('Website preferences') ?> 222 </a> 223 </li> 224 <li> 225 <span class="fa-li"><?= view('icons/email') ?></span> 226 <a href="<?= e(route(EmailPreferencesPage::class)) ?>"> 227 <?= I18N::translate('Sending email') ?> 228 </a> 229 </li> 230 <li> 231 <span class="fa-li"><?= view('icons/user') ?></span> 232 <a href="<?= e(route(SiteRegistrationPage::class)) ?>"> 233 <?= I18N::translate('Sign-in and registration') ?> 234 </a> 235 </li> 236 </ul> 237 </div> 238 <div class="col-sm"> 239 <ul class="fa-ul mx-0"> 240 <li> 241 <span class="fa-li"><?= view('icons/list') ?></span> 242 <a href="<?= e(route(SiteLogsPage::class)) ?>"> 243 <?= I18N::translate('Website logs') ?> 244 </a> 245 </li> 246 <li> 247 <span class="fa-li"><?= view('icons/delete') ?></span> 248 <a href="<?= e(route(CleanDataFolder::class)) ?>"> 249 <?= I18N::translate('Clean up data folder') ?> 250 </a> 251 </li> 252 <li> 253 <span class="fa-li"><?= view('icons/help') ?></span> 254 <a href="<?= e(route(PhpInformation::class)) ?>"> 255 <?= I18N::translate('Server information') ?> 256 </a> 257 </li> 258 </ul> 259 </div> 260 <div class="col-sm"> 261 <ul class="fa-ul mx-0"> 262 <li> 263 <span class="fa-li"><?= view('icons/tag') ?></span> 264 <a href="<?= e(route(SiteTagsPage::class)) ?>"> 265 <?= I18N::translate('GEDCOM tags') ?> 266 </a> 267 </li> 268 </ul> 269 </div> 270 </div> 271 </div> 272</div> 273 274<!-- FAMILY TREES --> 275<div class="card mb-4 <?= array_sum($changes) ? 'card-outline-danger' : '' ?>"> 276 <div class="card-header"> 277 <h2 class="mb-0"> 278 <?= I18N::translate('Family trees') ?> 279 <span class="badge bg-secondary"> 280 <?= I18N::number($all_trees->count()) ?> 281 </span> 282 </h2> 283 </div> 284 285 <div class="card-body"> 286 <?php if ($all_trees->isEmpty()) : ?> 287 <p class="alert alert-info"> 288 <?= I18N::translate('You need to create a family tree.') ?> 289 </p> 290 <?php endif ?> 291 292 <ul class="fa-ul mx-0"> 293 <li> 294 <span class="fa-li"><?= view('icons/add') ?></span> 295 <a href="<?= e(route(CreateTreePage::class)) ?>"> 296 <?= I18N::translate('Create a family tree') ?> 297 </a> 298 </li> 299 <li> 300 <span class="fa-li"><?= view('icons/block') ?></span> 301 <a href="<?= e(route(TreePageDefaultEdit::class)) ?>"> 302 <?= I18N::translate('Set the default blocks for new family trees') ?> 303 </a> 304 </li> 305 <?php if (count($all_trees) > 1) : ?> 306 <li> 307 <span class="fa-li"><?= view('icons/merge') ?></span> 308 <a href="<?= e(route(MergeTreesPage::class)) ?>"> 309 <?= I18N::translate('Merge family trees') ?> 310 </a> 311 </li> 312 <?php endif ?> 313 </ul> 314 315 <table class="table table-sm"> 316 <caption class="visually-hidden"> 317 <?= I18N::translate('Family trees') ?> 318 </caption> 319 320 <thead> 321 <tr> 322 <th><?= I18N::translate('Family tree') ?></th> 323 <th class="align-digits"><?= I18N::translate('Pending changes') ?></th> 324 <th class="d-none d-sm-table-cell align-digits"><?= I18N::translate('Individuals') ?></th> 325 <th class="d-none d-lg-table-cell align-digits"><?= I18N::translate('Families') ?></th> 326 <th class="d-none d-sm-table-cell align-digits"><?= I18N::translate('Sources') ?></th> 327 <th class="d-none d-lg-table-cell align-digits"><?= I18N::translate('Repositories') ?></th> 328 <th class="d-none d-sm-table-cell align-digits"><?= I18N::translate('Media') ?></th> 329 <th class="d-none d-lg-table-cell align-digits"><?= I18N::translate('Notes') ?></th> 330 <th class="d-none d-lg-table-cell align-digits"><?= I18N::translate('Submitters') ?></th> 331 </tr> 332 </thead> 333 334 <tbody> 335 <?php foreach ($all_trees as $tree) : ?> 336 <tr class="<?= $changes[$tree->id()] ? 'danger' : '' ?>"> 337 <th scope="row"> 338 <?= view('icons/preferences') ?> 339 <a href="<?= e(route(ManageTrees::class, ['tree' => $tree->name()])) ?>"> 340 <?= e($tree->name()) ?> 341 - 342 <?= e($tree->title()) ?> 343 </a> 344 </th> 345 <td style="text-align: right;"> 346 <?php if ($changes[$tree->id()]) : ?> 347 <a href="<?= e(route(PendingChanges::class, ['tree' => $tree->name(), 'url' => route(ControlPanel::class)])) ?>"> 348 <?= I18N::number($changes[$tree->id()]) ?> 349 <span class="visually-hidden"><?= I18N::translate('Pending changes') ?> <?= e($tree->title()) ?></span> 350 </a> 351 <?php else : ?> 352 - 353 <?php endif ?> 354 </td> 355 <td class="d-none d-sm-table-cell align-digits"> 356 <?php if ($individuals[$tree->id()] > 0) : ?> 357 <?php if ($individual_list_module instanceof IndividualListModule) : ?> 358 <a href="<?= e($individual_list_module->listUrl($tree)) ?>"><?= I18N::number($individuals[$tree->id()]) ?></a> 359 <?php else : ?> 360 <?= I18N::number($individuals[$tree->id()]) ?> 361 <?php endif ?> 362 <?php else : ?> 363 - 364 <?php endif ?> 365 </td> 366 <td class="d-none d-lg-table-cell align-digits"> 367 <?php if ($families[$tree->id()] > 0) : ?> 368 <?php if ($family_list_module instanceof FamilyListModule) : ?> 369 <a href="<?= e($family_list_module->listUrl($tree)) ?>"><?= I18N::number($families[$tree->id()]) ?></a> 370 <?php else : ?> 371 <?= I18N::number($families[$tree->id()]) ?> 372 <?php endif ?> 373 <?php else : ?> 374 - 375 <?php endif ?> 376 </td> 377 <td class="d-none d-sm-table-cell align-digits"> 378 <?php if ($sources[$tree->id()] > 0) : ?> 379 <?php if ($source_list_module instanceof SourceListModule) : ?> 380 <a href="<?= e($source_list_module->listUrl($tree)) ?>"><?= I18N::number($sources[$tree->id()]) ?></a> 381 <?php else : ?> 382 <?= I18N::number($sources[$tree->id()]) ?> 383 <?php endif ?> 384 <?php else : ?> 385 - 386 <?php endif ?> 387 </td> 388 <td class="d-none d-lg-table-cell align-digits"> 389 <?php if ($repositories[$tree->id()] > 0) : ?> 390 <?php if ($repository_list_module instanceof RepositoryListModule) : ?> 391 <a href="<?= e($repository_list_module->listUrl($tree)) ?>"><?= I18N::number($repositories[$tree->id()]) ?></a> 392 <?php else : ?> 393 <?= I18N::number($repositories[$tree->id()]) ?> 394 <?php endif ?> 395 <?php else : ?> 396 - 397 <?php endif ?> 398 </td> 399 <td class="d-none d-sm-table-cell align-digits"> 400 <?php if ($media[$tree->id()] > 0) : ?> 401 <?php if ($media_list_module instanceof MediaListModule) : ?> 402 <a href="<?= e($media_list_module->listUrl($tree)) ?>"><?= I18N::number($media[$tree->id()]) ?></a> 403 <?php else : ?> 404 <?= I18N::number($media[$tree->id()]) ?> 405 <?php endif ?> 406 <?php else : ?> 407 - 408 <?php endif ?> 409 </td> 410 <td class="d-none d-lg-table-cell align-digits"> 411 <?php if ($notes[$tree->id()] > 0) : ?> 412 <?php if ($note_list_module instanceof NoteListModule) : ?> 413 <a href="<?= e($note_list_module->listUrl($tree)) ?>"><?= I18N::number($notes[$tree->id()]) ?></a> 414 <?php else : ?> 415 <?= I18N::number($notes[$tree->id()]) ?> 416 <?php endif ?> 417 <?php else : ?> 418 - 419 <?php endif ?> 420 </td> 421 <td class="d-none d-lg-table-cell align-digits"> 422 <?php if ($submitters[$tree->id()] > 0) : ?> 423 <?php if ($submitter_list_module instanceof SubmitterListModule) : ?> 424 <a href="<?= e($submitter_list_module->listUrl($tree)) ?>"><?= I18N::number($submitters[$tree->id()]) ?></a> 425 <?php else : ?> 426 <?= I18N::number($submitters[$tree->id()]) ?> 427 <?php endif ?> 428 <?php else : ?> 429 - 430 <?php endif ?> 431 </td> 432 </tr> 433 <?php endforeach ?> 434 </tbody> 435 436 <tfoot> 437 <tr> 438 <th scope="row"> 439 <?= I18N::translate('Total') ?> 440 </th> 441 <td class="align-digits"> 442 <?= I18N::number(array_sum($changes)) ?> 443 </td> 444 <td class="d-none d-sm-table-cell align-digits"> 445 <?= I18N::number($individuals->sum()) ?> 446 </td> 447 <td class="d-none d-lg-table-cell align-digits"> 448 <?= I18N::number($families->sum()) ?> 449 </td> 450 <td class="d-none d-sm-table-cell align-digits"> 451 <?= I18N::number($sources->sum()) ?> 452 </td> 453 <td class="d-none d-lg-table-cell align-digits"> 454 <?= I18N::number($repositories->sum()) ?> 455 </td> 456 <td class="d-none d-sm-table-cell align-digits"> 457 <?= I18N::number($media->sum()) ?> 458 </td> 459 <td class="d-none d-lg-table-cell align-digits"> 460 <?= I18N::number($notes->sum()) ?> 461 </td> 462 <td class="d-none d-lg-table-cell align-digits"> 463 <?= I18N::number($submitters->sum()) ?> 464 </td> 465 </tr> 466 </tfoot> 467 </table> 468 </div> 469</div> 470 471<?php if ($show_synchronize): ?> 472 <?= view('admin/synchronize-trees') ?> 473<?php endif ?> 474 475<!-- USERS --> 476<div class="card mb-4 <?= $unapproved || $unverified ? 'card-outline-danger' : '' ?>"> 477 <div class="card-header"> 478 <h2 class="mb-0"> 479 <?= I18N::translate('Users') ?> 480 <span class="badge bg-secondary"> 481 <?= I18N::number(count($all_users)) ?> 482 </span> 483 </h2> 484 </div> 485 <div class="card-body"> 486 <dl class="row"> 487 <?php foreach ([I18N::translate('Administrators') => $administrators, I18N::translate('Managers') => $managers, I18N::translate('Moderators') => $moderators, I18N::translate('Not verified by the user') => $unverified, I18N::translate('Not approved by an administrator') => $unapproved] as $label => $list) : ?> 488 <?php if (!empty($list)) : ?> 489 <dt class="col-sm-6"> 490 <?= $label ?> 491 </dt> 492 <dd class="col-sm-6"> 493 <?php foreach ($list as $n => $user) : ?> 494 <?= $n ? I18N::$list_separator : '' ?> 495 <a href="<?= e(route(UserEditPage::class, ['user_id' => $user->id()])) ?>" dir="auto"> 496 <?= e($user->realName()) ?> 497 </a> 498 <?php endforeach ?> 499 <?php if ($list->isEmpty()) : ?> 500 — 501 <?php endif ?> 502 </dd> 503 <?php endif ?> 504 <?php endforeach ?> 505 </dl> 506 507 <div class="row"> 508 <div class="col-sm-6"> 509 <ul class="fa-ul mx-0"> 510 <li> 511 <span class="fa-li"><?= view('icons/preferences') ?></span> 512 <a href="<?= e(route(UserListPage::class)) ?>"> 513 <?= I18N::translate('User administration') ?> 514 </a> 515 </li> 516 <li> 517 <span class="fa-li"><?= view('icons/add') ?></span> 518 <a href="<?= e(route(UserAddPage::class)) ?>"> 519 <?= I18N::translate('Add a user') ?> 520 </a> 521 </li> 522 <li> 523 <span class="fa-li"><?= view('icons/delete') ?></span> 524 <a href="<?= e(route(UsersCleanupPage::class)) ?>"> 525 <?= I18N::translate('Delete inactive users') ?> 526 </a> 527 </li> 528 <li> 529 <span class="fa-li"><?= view('icons/block') ?></span> 530 <a href="<?= e(route(UserPageDefaultEdit::class)) ?>"> 531 <?= I18N::translate('Set the default blocks for new users') ?> 532 </a> 533 </li> 534 </ul> 535 </div> 536 <div class="col-sm-6"> 537 <ul class="fa-ul mx-0"> 538 <?php foreach ($recipients as $to => $recipient) : ?> 539 <li> 540 <span class="fa-li"><?= view('icons/email') ?></span> 541 <a href="<?= e(route(BroadcastPage::class, ['to' => $to])) ?>"> 542 <?= $recipient ?> 543 </a> 544 </li> 545 <?php endforeach ?> 546 </ul> 547 </div> 548 </div> 549 </div> 550</div> 551 552<!-- MODULES --> 553<div class="card mb-4"> 554 <div class="card-header"> 555 <h2 class="mb-0"> 556 <?= I18N::translate('Modules') ?> 557 <?= view('components/badge', ['count' => $all_modules_enabled->count(), 'total' => $all_modules_disabled->count(), 'context' => 'secondary']) ?> 558 </h2> 559 </div> 560 561 <div class="card-body"> 562 <ul class="fa-ul mx-0"> 563 <li> 564 <span class="fa-li"><?= view('icons/module') ?></span> 565 <a href="<?= e(route(ModulesAllPage::class)) ?>"> 566 <?= I18N::translate('All modules') ?> 567 </a> 568 <?= view('components/badge', ['count' => $all_modules_enabled->count(), 'total' => $all_modules_disabled->count(), 'context' => 'primary']) ?> 569 </li> 570 </ul> 571 572 <div class="row"> 573 <div class="col-sm-4"> 574 <h3> 575 <?= I18N::translate('Website') ?> 576 </h3> 577 578 <ul class="fa-ul mx-0"> 579 <li> 580 <span class="fa-li"><?= view('icons/footer') ?></span> 581 <a href="<?= e(route(ModulesFootersPage::class)) ?>"> 582 <?= I18N::translate('Footers') ?> 583 </a> 584 <?= view('components/badge', ['count' => $footer_modules_enabled->count(), 'total' => $footer_modules_disabled->count(), 'context' => 'primary']) ?> 585 </li> 586 <li> 587 <span class="fa-li"><?= view('icons/analytics') ?></span> 588 <a href="<?= e(route(ModulesAnalyticsPage::class)) ?>"> 589 <?= I18N::translate('Tracking and analytics') ?> 590 </a> 591 <?= view('components/badge', ['count' => $analytics_modules_enabled->count(), 'total' => $analytics_modules_disabled->count(), 'context' => 'primary']) ?> 592 </li> 593 <li> 594 <span class="fa-li"><?= view('icons/theme') ?></span> 595 <a href="<?= e(route(ModulesThemesPage::class)) ?>"> 596 <?= I18N::translate('Themes') ?> 597 </a> 598 <?= view('components/badge', ['count' => $theme_modules_enabled->count(), 'total' => $theme_modules_disabled->count(), 'context' => 'primary']) ?> 599 </li> 600 <li> 601 <span class="fa-li"><?= view('icons/language') ?></span> 602 <a href="<?= e(route(ModulesLanguagesPage::class)) ?>"> 603 <?= I18N::translate('Languages') ?> 604 </a> 605 <?= view('components/badge', ['count' => $language_modules_enabled->count(), 'total' => $language_modules_disabled->count(), 'context' => 'primary']) ?> 606 </li> 607 </ul> 608 609 <h3> 610 <?= I18N::translate('Home page') ?> 611 </h3> 612 613 <ul class="fa-ul mx-0"> 614 <li> 615 <span class="fa-li"><?= view('icons/block') ?></span> 616 <a href="<?= e(route(ModulesBlocksPage::class)) ?>"> 617 <?= I18N::translate('Blocks') ?> 618 </a> 619 <?= view('components/badge', ['count' => $block_modules_enabled->count(), 'total' => $block_modules_disabled->count(), 'context' => 'primary']) ?> 620 </li> 621 </ul> 622 623 <h3> 624 <?= I18N::translate('Geographic data') ?> 625 </h3> 626 627 <ul class="fa-ul mx-0"> 628 <li> 629 <span class="fa-li"><?= view('icons/search') ?></span> 630 <a href="<?= e(route(ModulesMapAutocompletePage::class)) ?>"> 631 <?= /* I18N: Automatic suggestions when you type */ I18N::translate('Autocomplete') ?> 632 </a> 633 <?= view('components/badge', ['count' => $map_autocomplete_modules_enabled->count(), 'total' => $map_autocomplete_modules_disabled->count(), 'context' => 'primary']) ?> 634 </li> 635 <li> 636 <span class="fa-li"><?= view('icons/search-location') ?></span> 637 <a href="<?= e(route(ModulesMapGeoLocationsPage::class)) ?>"> 638 <?= /* I18N: find latitude/longitude for a place */ I18N::translate('Geolocation') ?> 639 </a> 640 <?= view('components/badge', ['count' => $map_search_modules_enabled->count(), 'total' => $map_search_modules_disabled->count(), 'context' => 'primary']) ?> 641 </li> 642 <li> 643 <span class="fa-li"><?= view('icons/location') ?></span> 644 <a href="<?= e(route(ModulesMapLinksPage::class)) ?>"> 645 <?= /* I18N: Links to maps */ I18N::translate('Map links') ?> 646 </a> 647 <?= view('components/badge', ['count' => $map_link_modules_enabled->count(), 'total' => $map_link_modules_disabled->count(), 'context' => 'primary']) ?> 648 </li> 649 <li> 650 <span class="fa-li"><?= view('icons/map') ?></span> 651 <a href="<?= e(route(ModulesMapProvidersPage::class)) ?>"> 652 <?= I18N::translate('Map providers') ?> 653 </a> 654 <?= view('components/badge', ['count' => $map_provider_modules_enabled->count(), 'total' => $map_provider_modules_disabled->count(), 'context' => 'primary']) ?> 655 </li> 656 </ul> 657 </div> 658 659 <div class="col-sm-4"> 660 <h3> 661 <?= I18N::translate('Genealogy') ?> 662 </h3> 663 664 <ul class="fa-ul mx-0"> 665 <li> 666 <span class="fa-li"><?= view('icons/menu') ?></span> 667 <a href="<?= e(route(ModulesMenusPage::class)) ?>"> 668 <?= I18N::translate('Menus') ?> 669 </a> 670 <?= view('components/badge', ['count' => $menu_modules_enabled->count(), 'total' => $menu_modules_disabled->count(), 'context' => 'primary']) ?> 671 </li> 672 <li> 673 <span class="fa-li"><?= view('icons/chart') ?></span> 674 <a href="<?= e(route(ModulesChartsPage::class)) ?>"> 675 <?= I18N::translate('Charts') ?> 676 </a> 677 <?= view('components/badge', ['count' => $chart_modules_enabled->count(), 'total' => $chart_modules_disabled->count(), 'context' => 'primary']) ?> 678 </li> 679 <li> 680 <span class="fa-li"><?= view('icons/list') ?></span> 681 <a href="<?= e(route(ModulesListsPage::class)) ?>"> 682 <?= I18N::translate('Lists') ?> 683 </a> 684 <?= view('components/badge', ['count' => $list_modules_enabled->count(), 'total' => $list_modules_disabled->count(), 'context' => 'primary']) ?> 685 </li> 686 <li> 687 <span class="fa-li"><?= view('icons/report') ?></span> 688 <a href="<?= e(route(ModulesReportsPage::class)) ?>"> 689 <?= I18N::translate('Reports') ?> 690 </a> 691 <?= view('components/badge', ['count' => $report_modules_enabled->count(), 'total' => $report_modules_disabled->count(), 'context' => 'primary']) ?> 692 </li> 693 <li> 694 <span class="fa-li"><?= view('icons/data-fix') ?></span> 695 <a href="<?= e(route(ModulesDataFixesPage::class)) ?>"> 696 <?= I18N::translate('Data fixes') ?> 697 </a> 698 <?= view('components/badge', ['count' => $data_fix_modules_enabled->count(), 'total' => $data_fix_modules_disabled->count(), 'context' => 'primary']) ?> 699 </li> 700 <li> 701 <span class="fa-li"><?= view('icons/tag') ?></span> 702 <a href="<?= e(route(ModulesCustomTagsPage::class)) ?>"> 703 <?= I18N::translate('Custom GEDCOM tags') ?> 704 </a> 705 <?= view('components/badge', ['count' => $custom_tags_modules_enabled->count(), 'total' => $custom_tags_modules_disabled->count(), 'context' => 'primary']) ?> 706 </li> 707 </ul> 708 709 <h3> 710 <?= I18N::translate('Individual page') ?> 711 </h3> 712 713 <ul class="fa-ul mx-0"> 714 <li> 715 <span class="fa-li"><?= view('icons/tab') ?></span> 716 <a href="<?= e(route(ModulesTabsPage::class)) ?>"> 717 <?= I18N::translate('Tabs') ?> 718 <?= view('components/badge', ['count' => $tab_modules_enabled->count(), 'total' => $tab_modules_disabled->count(), 'context' => 'primary']) ?> 719 </a> 720 </li> 721 <li> 722 <span class="fa-li"><?= view('icons/sidebar') ?></span> 723 <a href="<?= e(route(ModulesSidebarsPage::class)) ?>"> 724 <?= I18N::translate('Sidebars') ?> 725 </a> 726 <?= view('components/badge', ['count' => $sidebar_modules_enabled->count(), 'total' => $sidebar_modules_disabled->count(), 'context' => 'primary']) ?> 727 </li> 728 <li> 729 <span class="fa-li"><?= view('icons/history') ?></span> 730 <a href="<?= e(route(ModulesHistoricEventsPage::class)) ?>"> 731 <?= I18N::translate('Historic events') ?> 732 </a> 733 <?= view('components/badge', ['count' => $history_modules_enabled->count(), 'total' => $history_modules_disabled->count(), 'context' => 'primary']) ?> 734 </li> 735 <li> 736 <span class="fa-li"><?= view('icons/share') ?></span> 737 <a href="<?= e(route(ModulesSharesPage::class)) ?>"> 738 <?= /* I18N: plural noun - things that can be shared */ I18N::translate('Shares') ?> 739 </a> 740 <?= view('components/badge', ['count' => $share_modules_enabled->count(), 'total' => $share_modules_disabled->count(), 'context' => 'primary']) ?> 741 </li> 742 </ul> 743 </div> 744 745 <div class="col-sm-4"> 746 747 <h3> 748 <?= I18N::translate('Other') ?> 749 </h3> 750 751 <ul class="fa-ul mx-0"> 752 <?php foreach ($other_modules as $module) : ?> 753 <li> 754 <?php if ($module->isEnabled()) : ?> 755 <span class="fa-li"><?= view('icons/module') ?></span> 756 <?php if ($module instanceof ModuleConfigInterface) : ?> 757 <a href="<?= e($module->getConfigLink()) ?>"> 758 <?= $module->title() ?> 759 <?= view('icons/preferences') ?> 760 </a> 761 <?php else : ?> 762 <?= $module->title() ?> 763 <?php endif ?> 764 <?php else : ?> 765 <span class="text-muted"> 766 <span class="fa-li"><?= view('icons/module') ?></span> 767 <?= $module->title() ?> 768 <?php if ($module instanceof ModuleConfigInterface) : ?> 769 <?= view('icons/preferences') ?> 770 <?php endif ?> 771 </span> 772 <?php endif ?> 773 774 <?php if ($module instanceof ModuleCustomInterface) : ?> 775 <?= view('admin/custom-module-info', ['module' => $module]) ?> 776 <?php endif ?> 777 </li> 778 <?php endforeach ?> 779 </ul> 780 </div> 781 </div> 782 </div> 783</div> 784 785<!-- MEDIA --> 786<div class="card mb-4"> 787 <div class="card-header"> 788 <h2 class="mb-0"> 789 <?= I18N::translate('Media') ?> 790 </h2> 791 </div> 792 <div class="card-body"> 793 <ul class="fa-ul mx-0"> 794 <li> 795 <span class="fa-li"><?= view('icons/preferences') ?></span> 796 <a href="<?= e(route(ManageMediaPage::class)) ?>"> 797 <?= I18N::translate('Manage media') ?> 798 </a> 799 </li> 800 <li> 801 <span class="fa-li"><?= view('icons/upload') ?></span> 802 <a href="<?= e(route(UploadMediaPage::class)) ?>"> 803 <?= I18N::translate('Upload media files') ?> 804 </a> 805 </li> 806 <li> 807 <span class="fa-li"><?= view('icons/link') ?></span> 808 <a href="<?= e(route(FixLevel0MediaPage::class)) ?>"> 809 <?= I18N::translate('Link media objects to facts and events') ?> 810 </a> 811 </li> 812 <li> 813 <span class="fa-li"><?= view('icons/upload') ?></span> 814 <a href="<?= e(route(ImportThumbnailsPage::class)) ?>"> 815 <?= I18N::translate('Import custom thumbnails from webtrees version 1') ?> 816 </a> 817 </li> 818 </ul> 819 </div> 820</div> 821 822<!-- MAPS --> 823<div class="card mb-4"> 824 <div class="card-header"> 825 <h2 class="mb-0"> 826 <?= I18N::translate('Map') ?> 827 </h2> 828 </div> 829 <div class="card-body"> 830 <div class="row"> 831 <div class="col-sm-12"> 832 <ul class="fa-ul mx-0"> 833 <li> 834 <span class="fa-li"><?= view('icons/location') ?></span> 835 <a href="<?= e(route(MapDataList::class)) ?>"> 836 <?= I18N::translate('Geographic data') ?> 837 </a> 838 </li> 839 </ul> 840 </div> 841 </div> 842 </div> 843</div> 844 845<!-- OLD FILES --> 846<?php if (!empty($files_to_delete)) : ?> 847 <div class="card mb-4 card-outline-danger"> 848 <div class="card-header"> 849 <h2 class="mb-0"> 850 <?= I18N::translate('Old files found') ?> 851 </h2> 852 </div> 853 <div class="card-body"> 854 <p> 855 <?= I18N::translate('Files have been found from a previous version of webtrees. Old files can sometimes be a security risk. You should delete them.') ?> 856 </p> 857 <ul class="list-unstyled"> 858 <?php foreach ($files_to_delete as $file_to_delete) : ?> 859 <li dir="ltr"> 860 <code><?= e($file_to_delete) ?></code> 861 </li> 862 <?php endforeach ?> 863 </ul> 864 </div> 865 </div> 866<?php endif ?> 867