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