1<?php 2 3use Fisharebest\Webtrees\Http\RequestHandlers\CreateTreePage; 4use Fisharebest\Webtrees\I18N; 5use Fisharebest\Webtrees\Module\ModuleConfigInterface; 6use Fisharebest\Webtrees\Module\ModuleCustomInterface; 7use Fisharebest\Webtrees\Webtrees; 8use Illuminate\Support\Collection; 9 10/** 11 * @var string $latest_version 12 * @var string $title 13 * @var Collection $server_errors 14 * @var Collection $server_warnings 15 */ 16 17?> 18 19<h1><?= $title ?></h1> 20 21<!-- WEBSITE / WEBTREES --> 22<div class="card mb-4"> 23 <div class="card-header"> 24 <h2 class="mb-0"> 25 <?= I18N::translate('Website') ?> 26 <span class="badge badge-secondary" dir="ltr"> 27 <?= e(Webtrees::VERSION) ?> 28 </span> 29 </h2> 30 </div> 31 <div class="card-body"> 32 <?php foreach ($server_errors as $server_error) : ?> 33 <p class="alert alert-danger"><?= $server_error ?></p> 34 <?php endforeach ?> 35 36 <?php foreach ($server_warnings as $server_warning) : ?> 37 <p class="alert alert-warning"><?= $server_warning ?></p> 38 <?php endforeach ?> 39 40 <p class="card-text"> 41 <?= /* I18N: %s is a URL/link to the project website */ 42 I18N::translate('Support and documentation can be found at %s.', '<a href="https://webtrees.net/">webtrees.net</a>') ?> 43 </p> 44 <p class="card-text "> 45 <?php if ($latest_version === '') : ?> 46 <?= I18N::translate('No upgrade information is available.') ?> 47 <?php elseif (version_compare(Webtrees::VERSION, $latest_version) < 0) : ?> 48 <?= I18N::translate('A new version of webtrees is available.') ?> 49 <a href="<?= e(route('upgrade')) ?>" class="error"> 50 <?= /* I18N: %s is a version number */ 51 I18N::translate('Upgrade to webtrees %s.', e($latest_version)) ?> 52 </a> 53 <?php else : ?> 54 <?= I18N::translate('This is the latest version of webtrees. No upgrade is available.') ?> 55 <?php endif ?> 56 </p> 57 58 <div class="row"> 59 <div class="col-sm-6"> 60 <ul class="fa-ul"> 61 <li> 62 <span class="fa-li"><?= view('icons/preferences') ?></span> 63 <a href="<?= e(route('admin-site-preferences')) ?>"> 64 <?= I18N::translate('Website preferences') ?> 65 </a> 66 </li> 67 <li> 68 <span class="fa-li"><?= view('icons/preferences') ?></span> 69 <a href="<?= e(route('admin-site-mail')) ?>"> 70 <?= I18N::translate('Sending email') ?> 71 </a> 72 </li> 73 <li> 74 <span class="fa-li"><?= view('icons/preferences') ?></span> 75 <a href="<?= e(route('admin-site-registration')) ?>"> 76 <?= I18N::translate('Sign-in and registration') ?> 77 </a> 78 </li> 79 </ul> 80 </div> 81 <div class="col-sm-6"> 82 <ul class="fa-ul"> 83 <li> 84 <span class="fa-li"><?= view('icons/preferences') ?></span> 85 <a href="<?= e(route('admin-site-logs')) ?>"> 86 <?= I18N::translate('Website logs') ?> 87 </a> 88 </li> 89 <li> 90 <span class="fa-li"><?= view('icons/preferences') ?></span> 91 <a href="<?= e(route('admin-clean-data')) ?>"> 92 <?= I18N::translate('Clean up data folder') ?> 93 </a> 94 </li> 95 <li> 96 <span class="fa-li"><?= view('icons/preferences') ?></span> 97 <a href="<?= e(route('admin-site-information')) ?>"> 98 <?= I18N::translate('Server information') ?> 99 </a> 100 </li> 101 </ul> 102 </div> 103 </div> 104 </div> 105</div> 106 107<!-- FAMILY TREES --> 108<div class="card mb-4 <?= array_sum($changes) ? 'card-outline-danger' : '' ?>"> 109 <div class="card-header"> 110 <h2 class="mb-0"> 111 <?= I18N::translate('Family trees') ?> 112 <span class="badge badge-secondary"> 113 <?= I18N::number(count($all_trees)) ?> 114 </span> 115 </h2> 116 </div> 117 <div class="card-body"> 118 <ul class="fa-ul"> 119 <li> 120 <span class="fa-li"><?= view('icons/add') ?></span> 121 <a href="<?= e(route(CreateTreePage::class)) ?>"> 122 <?= I18N::translate('Create a family tree') ?> 123 </a> 124 </li> 125 <li> 126 <span class="fa-li"><?= view('icons/block') ?></span> 127 <a href="<?= e(route('tree-page-default-edit')) ?>"> 128 <?= I18N::translate('Set the default blocks for new family trees') ?> 129 </a> 130 </li> 131 <?php if (count($all_trees) > 1) : ?> 132 <li> 133 <span class="fa-li"><?= view('icons/merge') ?></span> 134 <a href="<?= e(route('admin-trees-merge')) ?>"> 135 <?= I18N::translate('Merge family trees') ?> 136 </a> 137 </li> 138 <?php endif ?> 139 </ul> 140 141 <table class="table table-sm"> 142 <caption class="sr-only"> 143 <?= I18N::translate('Family trees') ?> 144 </caption> 145 <thead> 146 <tr> 147 <th><?= I18N::translate('Family tree') ?></th> 148 <th> 149 <span class="sr-only"><?= I18N::translate('Manage family trees') ?></span> 150 </th> 151 <th><?= I18N::translate('Pending changes') ?></th> 152 <th class="d-none d-sm-table-cell"><?= I18N::translate('Individuals') ?></th> 153 <th class="d-none d-lg-table-cell"><?= I18N::translate('Families') ?></th> 154 <th class="d-none d-sm-table-cell"><?= I18N::translate('Sources') ?></th> 155 <th class="d-none d-lg-table-cell"><?= I18N::translate('Repositories') ?></th> 156 <th class="d-none d-sm-table-cell"><?= I18N::translate('Media') ?></th> 157 <th class="d-none d-lg-table-cell"><?= I18N::translate('Notes') ?></th> 158 </tr> 159 </thead> 160 <tbody> 161 <?= view('admin/control-panel-tree-list', [ 162 'all_trees' => $all_trees, 163 'changes' => $changes, 164 'families' => $families, 165 'individuals' => $individuals, 166 'media' => $media, 167 'notes' => $notes, 168 'repositories' => $repositories, 169 'sources' => $sources, 170 'family_list_module' => $family_list_module, 171 'individual_list_module' => $individual_list_module, 172 'media_list_module' => $media_list_module, 173 'note_list_module' => $note_list_module, 174 'repository_list_module' => $repository_list_module, 175 'source_list_module' => $source_list_module, 176 ]) ?> 177 </tbody> 178 <tfoot> 179 <tr> 180 <th scope="row"> 181 <?= I18N::translate('Total') ?> 182 </th> 183 <td></td> 184 <td class="align-digits"> 185 <?= I18N::number(array_sum($changes)) ?> 186 </td> 187 <td class="d-none d-sm-table-cell align-digits"> 188 <?= I18N::number($individuals->sum()) ?> 189 </td> 190 <td class="d-none d-lg-table-cell align-digits"> 191 <?= I18N::number($families->sum()) ?> 192 </td> 193 <td class="d-none d-sm-table-cell align-digits"> 194 <?= I18N::number($sources->sum()) ?> 195 </td> 196 <td class="d-none d-lg-table-cell align-digits"> 197 <?= I18N::number($repositories->sum()) ?> 198 </td> 199 <td class="d-none d-sm-table-cell align-digits"> 200 <?= I18N::number($media->sum()) ?> 201 </td> 202 <td class="d-none d-lg-table-cell align-digits"> 203 <?= I18N::number($notes->sum()) ?> 204 </td> 205 </tr> 206 </tfoot> 207 </table> 208 </div> 209</div> 210 211<!-- USERS --> 212<div class="card mb-4 <?= $unapproved || $unverified ? 'card-outline-danger' : '' ?>"> 213 <div class="card-header"> 214 <h2 class="mb-0"> 215 <?= I18N::translate('Users') ?> 216 <span class="badge badge-secondary"> 217 <?= I18N::number(count($all_users)) ?> 218 </span> 219 </h2> 220 </div> 221 <div class="card-body"> 222 <dl class="row"> 223 <?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) : ?> 224 <?php if (!empty($list)) : ?> 225 <dt class="col-sm-3"> 226 <?= $label ?> 227 </dt> 228 <dd class="col-sm-9"> 229 <?php foreach ($list as $n => $user) : ?> 230 <?= $n ? I18N::$list_separator : '' ?> 231 <a href="<?= e(route('admin-users-edit', ['user_id' => $user->id()])) ?>" dir="auto"> 232 <?= e($user->realName()) ?> 233 </a> 234 <?php endforeach ?> 235 </dd> 236 <?php endif ?> 237 <?php endforeach ?> 238 </dl> 239 240 <div class="row"> 241 <div class="col-sm-6"> 242 <ul class="fa-ul"> 243 <li> 244 <span class="fa-li"><?= view('icons/preferences') ?></span> 245 <a href="<?= e(route('admin-users')) ?>"> 246 <?= I18N::translate('User administration') ?> 247 </a> 248 </li> 249 <li> 250 <span class="fa-li"><?= view('icons/preferences') ?></span> 251 <a href="<?= e(route('admin-users-create')) ?>"> 252 <?= I18N::translate('Add a user') ?> 253 </a> 254 </li> 255 <li> 256 <span class="fa-li"><?= view('icons/preferences') ?></span> 257 <a href="<?= e(route('admin-users-cleanup')) ?>"> 258 <?= I18N::translate('Delete inactive users') ?> 259 </a> 260 </li> 261 <li> 262 <span class="fa-li"><?= view('icons/preferences') ?></span> 263 <a href="<?= e(route('user-page-default-edit')) ?>"> 264 <?= I18N::translate('Set the default blocks for new users') ?> 265 </a> 266 </li> 267 </ul> 268 </div> 269 <div class="col-sm-6"> 270 <ul class="fa-ul"> 271 <li> 272 <span class="fa-li"><?= view('icons/email') ?></span> 273 <a href="<?= e(route('broadcast', ['to' => 'all'])) ?>"> 274 <?= I18N::translate('Send a message to all users') ?> 275 </a> 276 </li> 277 <li> 278 <span class="fa-li"><?= view('icons/email') ?></span> 279 <a href="<?= e(route('broadcast', ['to' => 'never_logged'])) ?>"> 280 <?= I18N::translate('Send a message to users who have never signed in') ?> 281 </a> 282 </li> 283 <li> 284 <span class="fa-li"><?= view('icons/email') ?></span> 285 <a href="<?= e(route('broadcast', ['to' => 'last_6mo'])) ?>"> 286 <?= I18N::translate('Send a message to users who have not signed in for 6 months') ?> 287 </a> 288 </li> 289 </ul> 290 </div> 291 </div> 292 </div> 293</div> 294 295<!-- MODULES --> 296<div class="card mb-4"> 297 <div class="card-header"> 298 <h2 class="mb-0"> 299 <?= I18N::translate('Modules') ?> 300 <?= view('components/badge', ['count' => $all_modules_enabled->count(), 'total' => $all_modules_disabled->count(), 'context' => 'secondary']) ?> 301 </h2> 302 </div> 303 304 <div class="card-body"> 305 <ul class="fa-ul"> 306 <li> 307 <span class="fa-li"><?= view('icons/module') ?></span> 308 <a href="<?= e(route('modules')) ?>"> 309 <?= I18N::translate('All modules') ?> 310 </a> 311 <?= view('components/badge', ['count' => $all_modules_enabled->count(), 'total' => $all_modules_disabled->count(), 'context' => 'primary']) ?> 312 </li> 313 </ul> 314 315 <div class="row"> 316 <div class="col-sm-4"> 317 <h3> 318 <?= I18N::translate('Genealogy') ?> 319 </h3> 320 321 <ul class="fa-ul"> 322 <li> 323 <span class="fa-li"><?= view('icons/menu') ?></span> 324 <a href="<?= e(route('menus')) ?>"> 325 <?= I18N::translate('Menus') ?> 326 </a> 327 <?= view('components/badge', ['count' => $menu_modules_enabled->count(), 'total' => $menu_modules_disabled->count(), 'context' => 'primary']) ?> 328 </li> 329 <li> 330 <span class="fa-li"><?= view('icons/chart') ?></span> 331 <a href="<?= e(route('charts')) ?>"> 332 <?= I18N::translate('Charts') ?> 333 </a> 334 <?= view('components/badge', ['count' => $chart_modules_enabled->count(), 'total' => $chart_modules_disabled->count(), 'context' => 'primary']) ?> 335 </li> 336 <li> 337 <span class="fa-li"><?= view('icons/list') ?></span> 338 <a href="<?= e(route('lists')) ?>"> 339 <?= I18N::translate('Lists') ?> 340 </a> 341 <?= view('components/badge', ['count' => $list_modules_enabled->count(), 'total' => $list_modules_disabled->count(), 'context' => 'primary']) ?> 342 </li> 343 <li> 344 <span class="fa-li"><?= view('icons/report') ?></span> 345 <a href="<?= e(route('reports')) ?>"> 346 <?= I18N::translate('Reports') ?> 347 </a> 348 <?= view('components/badge', ['count' => $report_modules_enabled->count(), 'total' => $report_modules_disabled->count(), 'context' => 'primary']) ?> 349 </li> 350 </ul> 351 352 <h3> 353 <?= I18N::translate('Website') ?> 354 </h3> 355 356 <ul class="fa-ul"> 357 <li> 358 <span class="fa-li"><?= view('icons/footer') ?></span> 359 <a href="<?= e(route('footers')) ?>"> 360 <?= I18N::translate('Footers') ?> 361 </a> 362 <?= view('components/badge', ['count' => $footer_modules_enabled->count(), 'total' => $footer_modules_disabled->count(), 'context' => 'primary']) ?> 363 </li> 364 <li> 365 <span class="fa-li"><?= view('icons/analytics') ?></span> 366 <a href="<?= e(route('analytics')) ?>"> 367 <?= I18N::translate('Tracking and analytics') ?> 368 </a> 369 <?= view('components/badge', ['count' => $analytics_modules_enabled->count(), 'total' => $analytics_modules_disabled->count(), 'context' => 'primary']) ?> 370 </li> 371 <li> 372 <span class="fa-li"><?= view('icons/theme') ?></span> 373 <a href="<?= e(route('themes')) ?>"> 374 <?= I18N::translate('Themes') ?> 375 </a> 376 <?= view('components/badge', ['count' => $theme_modules_enabled->count(), 'total' => $theme_modules_disabled->count(), 'context' => 'primary']) ?> 377 </li> 378 <li> 379 <span class="fa-li"><?= view('icons/language') ?></span> 380 <a href="<?= e(route('languages')) ?>"> 381 <?= I18N::translate('Languages') ?> 382 </a> 383 <?= view('components/badge', ['count' => $language_modules_enabled->count(), 'total' => $language_modules_disabled->count(), 'context' => 'primary']) ?> 384 </li> 385 </ul> 386 387 </div> 388 389 <div class="col-sm-4"> 390 391 <h3> 392 <?= I18N::translate('Home page') ?> 393 </h3> 394 395 <ul class="fa-ul"> 396 <li> 397 <span class="fa-li"><?= view('icons/block') ?></span> 398 <a href="<?= e(route('blocks')) ?>"> 399 <?= I18N::translate('Blocks') ?> 400 </a> 401 <?= view('components/badge', ['count' => $block_modules_enabled->count(), 'total' => $block_modules_disabled->count(), 'context' => 'primary']) ?> 402 </li> 403 </ul> 404 405 <h3> 406 <?= I18N::translate('Individual page') ?> 407 </h3> 408 409 <ul class="fa-ul"> 410 <li> 411 <span class="fa-li"><?= view('icons/tab') ?></span> 412 <a href="<?= e(route('tabs')) ?>"> 413 <?= I18N::translate('Tabs') ?> 414 <?= view('components/badge', ['count' => $tab_modules_enabled->count(), 'total' => $tab_modules_disabled->count(), 'context' => 'primary']) ?> 415 </a> 416 </li> 417 <li> 418 <span class="fa-li"><?= view('icons/sidebar') ?></span> 419 <a href="<?= e(route('sidebars')) ?>"> 420 <?= I18N::translate('Sidebars') ?> 421 </a> 422 <?= view('components/badge', ['count' => $sidebar_modules_enabled->count(), 'total' => $sidebar_modules_disabled->count(), 'context' => 'primary']) ?> 423 </li> 424 <li> 425 <span class="fa-li"><?= view('icons/history') ?></span> 426 <a href="<?= e(route('history')) ?>"> 427 <?= I18N::translate('Historic events') ?> 428 </a> 429 <?= view('components/badge', ['count' => $history_modules_enabled->count(), 'total' => $history_modules_disabled->count(), 'context' => 'primary']) ?> 430 </li> 431 </ul> 432 433 </div> 434 435 <div class="col-sm-4"> 436 437 <h3> 438 <?= I18N::translate('Other') ?> 439 </h3> 440 441 <ul class="fa-ul"> 442 <?php foreach ($other_modules as $module) : ?> 443 <li> 444 <span class="fa-li"><?= view('icons/module') ?></span> 445 446 <?php if ($module->isEnabled()): ?> 447 <?php if ($module instanceof ModuleConfigInterface): ?> 448 <a href="<?= e($module->getConfigLink()) ?>"> 449 <?= $module->title() ?> 450 <span class="fa"><?= view('icons/preferences') ?></span> 451 </a> 452 <?php else : ?> 453 <?= $module->title() ?> 454 <?php endif ?> 455 <?php else : ?> 456 <span class="text-muted"> 457 <span class="fa-li"><?= view('icons/module') ?></span> 458 <?= $module->title() ?> 459 <?php if ($module instanceof ModuleConfigInterface): ?> 460 <span class="fa"><?= view('icons/preferences') ?></span> 461 <?php endif ?> 462 </span> 463 </span> 464 <?php endif ?> 465 466 <?php if ($module instanceof ModuleCustomInterface): ?> 467 <?= view('admin/custom-module-info', ['module' => $module]) ?> 468 <?php endif ?> 469 </li> 470 <?php endforeach ?> 471 </ul> 472 </div> 473 </div> 474 </div> 475</div> 476 477<!-- MEDIA --> 478<div class="card mb-4"> 479 <div class="card-header"> 480 <h2 class="mb-0"> 481 <?= I18N::translate('Media') ?> 482 </h2> 483 </div> 484 <div class="card-body"> 485 <ul class="fa-ul"> 486 <li> 487 <span class="fa-li"><?= view('icons/preferences') ?></span> 488 <a href="<?= e(route('admin-media')) ?>"> 489 <?= I18N::translate('Manage media') ?> 490 </a> 491 </li> 492 <li> 493 <span class="fa-li"><?= view('icons/preferences') ?></span> 494 <a href="<?= e(route('admin-media-upload')) ?>"> 495 <?= I18N::translate('Upload media files') ?> 496 </a> 497 </li> 498 <li> 499 <span class="fa-li"><?= view('icons/preferences') ?></span> 500 <a href="<?= e(route('admin-fix-level-0-media')) ?>"> 501 <?= I18N::translate('Link media objects to facts and events') ?> 502 </a> 503 </li> 504 <li> 505 <span class="fa-li"><?= view('icons/preferences') ?></span> 506 <a href="<?= e(route('admin-webtrees1-thumbs')) ?>"> 507 <?= I18N::translate('Import custom thumbnails from webtrees version 1') ?> 508 </a> 509 </li> 510 </ul> 511 </div> 512</div> 513 514<!-- MAPS --> 515<div class="card mb-4"> 516 <div class="card-header"> 517 <h2 class="mb-0"> 518 <?= I18N::translate('Map') ?> 519 </h2> 520 </div> 521 <div class="card-body"> 522 <div class="row"> 523 <div class="col-sm-6"> 524 <ul class="fa-ul"> 525 <li> 526 <span class="fa-li"><?= view('icons/location') ?></span> 527 <a href="<?= e(route('map-data')) ?>"> 528 <?= I18N::translate('Geographic data') ?> 529 </a> 530 </li> 531 </ul> 532 </div> 533 <div class="col-sm-6"> 534 <ul class="fa-ul"> 535 <li> 536 <span class="fa-li"><?= view('icons/map') ?></span> 537 <a href="<?= e(route('map-provider')) ?>"> 538 <?= I18N::translate('Map provider') ?> 539 </a> 540 </li> 541 </ul> 542 </div> 543 </div> 544 </div> 545</div> 546 547<!-- OLD FILES --> 548<?php if (!empty($files_to_delete)) : ?> 549 <div class="card mb-4 card-outline-danger"> 550 <div class="card-header"> 551 <h2 class="mb-0"> 552 <?= I18N::translate('Old files found') ?> 553 </h2> 554 </div> 555 <div class="card-body"> 556 <p> 557 <?= I18N::translate('Files have been found from a previous version of webtrees. Old files can sometimes be a security risk. You should delete them.') ?> 558 </p> 559 <ul class="list-unstyled"> 560 <?php foreach ($files_to_delete as $file_to_delete) : ?> 561 <li dir="ltr"> 562 <code><?= e($file_to_delete) ?></code> 563 </li> 564 <?php endforeach ?> 565 </ul> 566 </div> 567 </div> 568<?php endif ?> 569