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