xref: /webtrees/resources/views/admin/control-panel.phtml (revision 8898179db9ee9ab76e7912468223d7b1fdcddfbc)
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                    <li>
79                        <span class="fa-li"><?= view('icons/preferences') ?></span>
80                        <a href="<?= e(route('admin-site-languages')) ?>">
81                            <?= I18N::translate('Languages') ?>
82                        </a>
83                    </li>
84                </ul>
85            </div>
86            <div class="col-sm-6">
87                <ul class="fa-ul">
88                    <li>
89                        <span class="fa-li"><?= view('icons/preferences') ?></span>
90                        <a href="<?= e(route('admin-site-logs')) ?>">
91                            <?= I18N::translate('Website logs') ?>
92                        </a>
93                    </li>
94                    <li>
95                        <span class="fa-li"><?= view('icons/preferences') ?></span>
96                        <a href="<?= e(route('admin-clean-data')) ?>">
97                            <?= I18N::translate('Clean up data folder') ?>
98                        </a>
99                    </li>
100                    <li>
101                        <span class="fa-li"><?= view('icons/preferences') ?></span>
102                        <a href="<?= e(route('admin-site-information')) ?>">
103                            <?= I18N::translate('Server information') ?>
104                        </a>
105                    </li>
106                </ul>
107            </div>
108        </div>
109    </div>
110</div>
111
112<!-- FAMILY TREES -->
113<div class="card mb-4 <?= array_sum($changes) ? 'card-outline-danger' : '' ?>">
114    <div class="card-header">
115        <h2 class="mb-0">
116            <?= I18N::translate('Family trees') ?>
117            <span class="badge badge-secondary">
118                    <?= I18N::number(count($all_trees)) ?>
119                </span>
120        </h2>
121    </div>
122    <div class="card-body">
123        <table class="table table-sm">
124            <caption class="sr-only">
125                <?= I18N::translate('Family trees') ?>
126            </caption>
127            <thead>
128                <tr>
129                    <th><?= I18N::translate('Family tree') ?></th>
130                    <th>
131                        <span class="sr-only"><?= I18N::translate('Manage family trees') ?></span>
132                    </th>
133                    <th class="text-right"><?= I18N::translate('Pending changes') ?></th>
134                    <th class="d-none d-sm-table-cell text-right"><?= I18N::translate('Individuals') ?></th>
135                    <th class="d-none d-lg-table-cell text-right"><?= I18N::translate('Families') ?></th>
136                    <th class="d-none d-sm-table-cell text-right"><?= I18N::translate('Sources') ?></th>
137                    <th class="d-none d-lg-table-cell text-right"><?= I18N::translate('Repositories') ?></th>
138                    <th class="d-none d-sm-table-cell text-right"><?= I18N::translate('Media') ?></th>
139                    <th class="d-none d-lg-table-cell text-right"><?= I18N::translate('Notes') ?></th>
140                </tr>
141            </thead>
142            <tbody>
143                <?= view('admin/control-panel-tree-list', [
144                    'all_trees'    => $all_trees,
145                    'changes'      => $changes,
146                    'individuals'  => $individuals,
147                    'families'     => $families,
148                    'sources'      => $sources,
149                    'repositories' => $repositories,
150                    'media'        => $media,
151                    'notes'        => $notes,
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-6">
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                <h3>
387                    <?= I18N::translate('Home page') ?>
388                </h3>
389
390                <ul class="fa-ul">
391                    <li>
392                        <span class="fa-li"><?= view('icons/block') ?></span>
393                        <a href="<?= e(route('blocks')) ?>">
394                            <?= I18N::translate('Blocks') ?>
395                        </a>
396                        <?= view('components/badge', ['count' => $block_modules_enabled->count(), 'total' => $block_modules_disabled->count(), 'context' => 'primary']) ?>
397                    </li>
398                </ul>
399            </div>
400
401            <div class="col-sm-6">
402                <h3>
403                    <?= I18N::translate('Individual page') ?>
404                </h3>
405
406                <ul class="fa-ul">
407                    <li>
408                        <span class="fa-li"><?= view('icons/tab') ?></span>
409                        <a href="<?= e(route('tabs')) ?>">
410                            <?= I18N::translate('Tabs') ?>
411                            <?= view('components/badge', ['count' => $tab_modules_enabled->count(), 'total' => $tab_modules_disabled->count(), 'context' => 'primary']) ?>
412                        </a>
413                    </li>
414                    <li>
415                        <span class="fa-li"><?= view('icons/sidebar') ?></span>
416                        <a href="<?= e(route('sidebars')) ?>">
417                            <?= I18N::translate('Sidebars') ?>
418                        </a>
419                        <?= view('components/badge', ['count' => $sidebar_modules_enabled->count(), 'total' => $sidebar_modules_disabled->count(), 'context' => 'primary']) ?>
420                    </li>
421                    <li>
422                        <span class="fa-li"><?= view('icons/history') ?></span>
423                        <a href="<?= e(route('history')) ?>">
424                            <?= I18N::translate('Historic events') ?>
425                        </a>
426                        <?= view('components/badge', ['count' => $history_modules_enabled->count(), 'total' => $history_modules_disabled->count(), 'context' => 'primary']) ?>
427                    </li>
428                </ul>
429
430                <h3>
431                    <?= I18N::translate('Other') ?>
432                </h3>
433
434                <ul class="fa-ul">
435                    <?php foreach ($other_modules as $module) : ?>
436                        <li>
437                            <span class="fa-li"><?= view('icons/module') ?></span>
438                            <?php if ($module->isEnabled() && $module instanceof ModuleConfigInterface): ?>
439                                <a href="<?= e($module->getConfigLink()) ?>">
440                                    <?= $module->title() ?>
441                                    <span class="fa"><?= view('icons/preferences') ?></span>
442                                </a>
443                            <?php elseif ($module->isEnabled()) : ?>
444                                <?= $module->title() ?>
445                            <?php else : ?>
446                                <del class="text-muted"><?= $module->title() ?></del>
447                            <?php endif ?>
448                            <?php if ($module instanceof ModuleCustomInterface): ?>
449                                <?= view('admin/custom-module-info', ['module' => $module]) ?>
450                            <?php endif ?>
451                        </li>
452                    <?php endforeach ?>
453                </ul>
454            </div>
455        </div>
456    </div>
457</div>
458
459<!-- MEDIA -->
460<div class="card mb-4">
461    <div class="card-header">
462        <h2 class="mb-0">
463            <?= I18N::translate('Media') ?>
464        </h2>
465    </div>
466    <div class="card-body">
467        <ul class="fa-ul">
468            <li>
469                <span class="fa-li"><?= view('icons/preferences') ?></span>
470                <a href="<?= e(route('admin-media')) ?>">
471                    <?= I18N::translate('Manage media') ?>
472                </a>
473            </li>
474            <li>
475                <span class="fa-li"><?= view('icons/preferences') ?></span>
476                <a href="<?= e(route('admin-media-upload')) ?>">
477                    <?= I18N::translate('Upload media files') ?>
478                </a>
479            </li>
480            <li>
481                <span class="fa-li"><?= view('icons/preferences') ?></span>
482                <a href="<?= e(route('admin-fix-level-0-media')) ?>">
483                    <?= I18N::translate('Link media objects to facts and events') ?>
484                </a>
485            </li>
486            <li>
487                <span class="fa-li"><?= view('icons/preferences') ?></span>
488                <a href="<?= e(route('admin-webtrees1-thumbs')) ?>">
489                    <?= I18N::translate('Import custom thumbnails from webtrees version 1') ?>
490                </a>
491            </li>
492        </ul>
493    </div>
494</div>
495
496<!-- MAPS -->
497<div class="card mb-4">
498    <div class="card-header">
499        <h2 class="mb-0">
500            <?= I18N::translate('Map') ?>
501        </h2>
502    </div>
503    <div class="card-body">
504        <div class="row">
505            <div class="col-sm-6">
506                <ul class="fa-ul">
507                    <li>
508                        <span class="fa-li"><?= view('icons/location') ?></span>
509                        <a href="<?= e(route('map-data')) ?>">
510                            <?= I18N::translate('Geographic data') ?>
511                        </a>
512                    </li>
513                </ul>
514            </div>
515            <div class="col-sm-6">
516                <ul class="fa-ul">
517                    <li>
518                        <span class="fa-li"><?= view('icons/map') ?></span>
519                        <a href="<?= e(route('map-provider')) ?>">
520                            <?= I18N::translate('Map provider') ?>
521                        </a>
522                    </li>
523                </ul>
524            </div>
525        </div>
526    </div>
527</div>
528
529<!-- OLD FILES -->
530<?php if (!empty($files_to_delete)) : ?>
531    <div class="card mb-4 card-outline-danger">
532        <div class="card-header">
533            <h2 class="mb-0">
534                <?= I18N::translate('Old files found') ?>
535            </h2>
536        </div>
537        <div class="card-body">
538            <p>
539                <?= I18N::translate('Files have been found from a previous version of webtrees. Old files can sometimes be a security risk. You should delete them.') ?>
540            </p>
541            <ul class="list-unstyled">
542                <?php foreach ($files_to_delete as $file_to_delete) : ?>
543                    <li dir="ltr">
544                        <code><?= e($file_to_delete) ?></code>
545                    </li>
546                <?php endforeach ?>
547            </ul>
548        </div>
549    </div>
550<?php endif ?>
551