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