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