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