xref: /webtrees/resources/views/admin/trees.phtml (revision 72cf66d48ef1f917238d9b0939a8aa33f257e274)
1<?php use Fisharebest\Webtrees\Auth; ?>
2<?php use Fisharebest\Webtrees\Database; ?>
3<?php use Fisharebest\Webtrees\I18N; ?>
4<?php use Fisharebest\Webtrees\Site; ?>
5<?php use Fisharebest\Webtrees\View; ?>
6
7<?php if (!empty($all_trees)): ?>
8    <?= view('components/breadcrumbs', ['links' => [route('admin-control-panel') => I18N::translate('Control panel'), $title]]) ?>
9<?php endif ?>
10
11<h1><?= $title ?></h1>
12
13<?php if (empty($all_trees)) : ?>
14    <div class="alert alert-info">
15        <?= I18N::translate('You need to create a family tree.') ?>
16    </div>
17<?php endif ?>
18
19<div id="accordion" role="tablist" aria-multiselectable="true">
20    <?php foreach ($all_trees as $managed_tree) : ?>
21        <?php if (Auth::isManager($managed_tree)) : ?>
22            <div class="card">
23                <div class="card-header" role="tab" id="card-tree-header-<?= $managed_tree->id() ?>">
24                    <h2 class="mb-0">
25                        <?= view('icons/tree') ?>
26                        <a data-toggle="collapse" data-parent="#accordion" href="#card-tree-content-<?= $managed_tree->id() ?>" <?= $managed_tree == $tree || $managed_tree->getPreference('imported') === '0' ? 'aria-expanded="true"' : '' ?> aria-controls="card-tree-content-<?= $managed_tree->id() ?>">
27                            <?= e($managed_tree->getName()) ?><?= e($managed_tree->getTitle()) ?>
28                        </a>
29                    </h2>
30                </div>
31                <div id="card-tree-content-<?= $managed_tree->id() ?>" class="collapse<?= $managed_tree == $tree || $managed_tree->getPreference('imported') === '0' ? ' show' : '' ?>" role="tabpanel" aria-labelledby="panel-tree-header-<?= $managed_tree->id() ?>">
32                    <div class="card-body">
33                        <?php $importing = Database::prepare("SELECT 1 FROM `##gedcom_chunk` WHERE gedcom_id = ? AND imported = '0' LIMIT 1")->execute([$managed_tree->id()])->fetchOne() ?>
34                        <?php if ($importing) : ?>
35                            <div id="import<?= $managed_tree->id() ?>" class="col-xs-12">
36                                <div class="progress">
37                                    <?= I18N::translate('Calculating…') ?>
38                                </div>
39                            </div>
40                            <?php View::push('javascript'); ?>
41                            <script>
42                $("#import<?= $managed_tree->id() ?>").load("<?= route('import', ['ged' => $managed_tree->getName()]) ?>", {});
43                            </script>
44                            <?php View::endpush() ?>
45                        <?php endif ?>
46                        <div class="row<?= $importing ? ' d-none' : '' ?>" id="actions<?= $managed_tree->id() ?>">
47                            <div class="col-sm-6 col-md-3">
48                                <h3>
49                                    <a href="<?= e(route('tree-page', ['ged' => $managed_tree->getName()])) ?>">
50                                        <?= I18N::translate('Family tree') ?>
51                                    </a>
52                                </h3>
53                                <ul class="fa-ul">
54                                    <!-- PREFERENCES -->
55                                    <li>
56                                        <span class="fa-li"><?= view('icons/preferences') ?></span>
57                                        <a href="<?= e(route('admin-trees-preferences', ['ged' => $managed_tree->getName()])) ?>">
58                                            <?= I18N::translate('Preferences') ?>
59                                            <span class="sr-only">
60                                        <?= e($managed_tree->getTitle()) ?>
61                                    </span>
62                                        </a>
63                                    </li>
64                                    <!-- PRIVACY -->
65                                    <li>
66                                        <span class="fa-li"><?= view('icons/lock') ?></span>
67                                        <a href="<?= e(route('tree-privacy', ['ged' => $managed_tree->getName()])) ?>">
68                                            <?= I18N::translate('Privacy') ?>
69                                            <span class="sr-only">
70                                        <?= e($managed_tree->getTitle()) ?>
71                                    </span>
72                                        </a>
73                                    </li>
74                                    <!-- HOME PAGE BLOCKS-->
75                                    <li>
76                                        <span class="fa-li"><?= view('icons/block') ?></span>
77                                        <a href="<?= e(route('tree-page-edit', ['ged' => $managed_tree->getName()])) ?>">
78                                            <?= I18N::translate('Change the “Home page” blocks') ?>
79                                            <span class="sr-only">
80                                        <?= e($managed_tree->getTitle()) ?>
81                                    </span>
82                                        </a>
83                                    </li>
84                                    <!-- DELETE -->
85                                    <li>
86                                        <span class="fa-li"><?= view('icons/delete') ?></span>
87                                        <a href="#" data-confirm="<?= I18N::translate('Are you sure you want to delete “%s”?', e($managed_tree->getTitle())) ?>" onclick="if (confirm(this.dataset.confirm)) { document.delete_form<?= $managed_tree->id() ?>.submit(); } return false;">
88                                            <?= I18N::translate('Delete') ?>
89                                            <span class="sr-only">
90                                                <?= e($managed_tree->getTitle()) ?>
91                                            </span>
92                                        </a>
93                                        <form name="delete_form<?= $managed_tree->id() ?>" method="post" action="<?= route('admin-trees-delete', ['ged' => $managed_tree->getName()]) ?>">
94                                            <?= csrf_field() ?>
95                                            <!-- A11Y - forms need submit buttons, but they look ugly here -->
96                                            <button class="sr-only" data-confirm="<?= I18N::translate('Are you sure you want to delete “%s”?', e($managed_tree->getTitle())) ?>" onclick="return confirm(this.dataset.confirm)" type="submit">
97                                                <?= I18N::translate('Delete') ?>
98                                            </button>
99                                        </form>
100                                    </li>
101                                    <!-- SET AS DEFAULT -->
102                                    <?php if (count($all_trees) > 1) : ?>
103                                        <li>
104                                            <span class="fa-li"><?= view('icons/favorite') ?></span>
105                                            <?php if ($managed_tree->getName() === Site::getPreference('DEFAULT_GEDCOM')) : ?>
106                                                <?= I18N::translate('Default family tree') ?>
107                                            <?php else : ?>
108                                                <a href="#" onclick="document.defaultform<?= $managed_tree->id() ?>.submit();">
109                                                    <?= I18N::translate('Set as default') ?>
110                                                    <span class="sr-only"><?= e($managed_tree->getTitle()) ?></span>
111                                                </a>
112                                                <form name="defaultform<?= $managed_tree->id() ?>" method="post" action="<?= route('admin-trees-default', ['ged' => $managed_tree->getName()]) ?>">
113                                                    <?= csrf_field() ?>
114                                                    <!-- A11Y - forms need submit buttons, but they look ugly here -->
115                                                    <button class="sr-only" type="submit">
116                                                        <?= I18N::translate('Set as default') ?>
117                                                    </button>
118                                                </form>
119                                            <?php endif ?>
120                                        </li>
121                                    <?php endif ?>
122                                </ul>
123                            </div>
124                            <div class="col-sm-6 col-md-3">
125                                <h3>
126                                    <?= /* I18N: Individuals, sources, dates, places, etc. */ I18N::translate('Genealogy data') ?>
127                                </h3>
128                                <ul class="fa-ul">
129                                    <!-- FIND DUPLICATES -->
130                                    <li>
131                                        <span class="fa-li"><?= view('icons/copy') ?></span>
132                                        <a href="<?= e(route('admin-trees-duplicates', ['ged' => $managed_tree->getName()])) ?>">
133                                            <?= I18N::translate('Find duplicates') ?>
134                                            <span class="sr-only">
135                                              <?= e($managed_tree->getTitle()) ?>
136                                            </span>
137                                        </a>
138                                    </li>
139                                    <!-- MERGE -->
140                                    <li>
141                                        <span class="fa-li"><?= view('icons/merge') ?></span>
142                                        <a href="<?= e(route('merge-records', ['ged' => $managed_tree->getName()])) ?>">
143                                            <?= I18N::translate('Merge records') ?>
144                                            <span class="sr-only">
145                                                <?= e($managed_tree->getTitle()) ?>
146                                          </span>
147                                        </a>
148                                    </li>
149                                    <!-- UPDATE PLACE NAMES -->
150                                    <li>
151                                        <span class="fa-li"><?= view('icons/location') ?></span>
152                                        <a href="<?= e(route('admin-trees-places', ['ged' => $managed_tree->getName()])) ?>">
153                                            <?= I18N::translate('Update place names') ?>
154                                            <span class="sr-only">
155                                                <?= e($managed_tree->getTitle()) ?>
156                                            </span>
157                                        </a>
158                                    </li>
159                                    <!-- CHECK FOR ERRORS -->
160                                    <li>
161                                        <span class="fa-li"><?= view('icons/warning') ?></span>
162                                        <a href="<?= e(route('admin-trees-check', ['ged' => $managed_tree->getName()])) ?>">
163                                            <?= I18N::translate('Check for errors') ?>
164                                            <span class="sr-only">
165                                                <?= e($managed_tree->getTitle()) ?>
166                                            </span>
167                                        </a>
168                                    </li>
169                                    <!-- UNCONNECTED INDIVIDUALS -->
170                                    <li>
171                                        <span class="fa-li"><?= view('icons/unlink') ?></span>
172                                        <a href="<?= e(route('admin-trees-unconnected', ['ged' => $managed_tree->getName()])) ?>">
173                                            <?= I18N::translate('Find unrelated individuals') ?>
174                                            <span class="sr-only">
175                                                <?= e($managed_tree->getTitle()) ?>
176                                            </span>
177                                        </a>
178                                    </li>
179                                    <!-- RENUMBER -->
180                                    <li>
181                                        <span class="fa-li"><?= view('icons/sort') ?></span>
182                                        <a href="<?= e(route('admin-trees-renumber', ['ged' => $managed_tree->getName()])) ?>">
183                                            <?= I18N::translate('Renumber') ?>
184                                            <span class="sr-only">
185                                        <?= e($managed_tree->getTitle()) ?>
186                                    </span>
187                                        </a>
188                                    </li>
189                                    <!-- CHANGES -->
190                                    <li>
191                                        <span class="fa-li"><?= view('icons/edit') ?></span>
192                                        <a href="<?= route('admin-changes-log', ['ged' => $managed_tree->getName()]) ?>">
193                                            <?= I18N::translate('Changes log') ?>
194                                            <span class="sr-only">
195                                                <?= e($managed_tree->getTitle()) ?>
196                                            </span>
197                                        </a>
198                                    </li>
199                                </ul>
200                            </div>
201                            <div class="clearfix visible-sm-block"></div>
202                            <div class="col-sm-6 col-md-3">
203                                <h3>
204                                    <?= I18N::translate('Add unlinked records') ?>
205                                </h3>
206                                <ul class="fa-ul">
207                                    <!-- UNLINKED INDIVIDUAL -->
208                                    <li>
209                                        <span class="fa-li"><?= view('icons/individual') ?></span>
210                                        <a href="<?= e(route('add-unlinked-individual', ['ged' => $managed_tree->getName()])) ?>">
211                                            <?= I18N::translate('Individual') ?>
212                                            <span class="sr-only">
213                                                <?= e($managed_tree->getTitle()) ?>
214                                            </span>
215                                        </a>
216                                    </li>
217                                    <!-- UNLINKED SOURCE -->
218                                    <li>
219                                        <span class="fa-li"><?= view('icons/source') ?></span>
220                                        <a href="#" data-href="<?= e(route('create-source', ['ged' => $managed_tree->getName()])) ?>" data-target="#wt-ajax-modal" data-toggle="modal">
221                                            <?= I18N::translate('Source') ?>
222                                            <span class="sr-only">
223                                                <?= e($managed_tree->getTitle()) ?>
224                                            </span>
225                                        </a>
226                                    </li>
227                                    <!-- UNLINKED REPOSITORY -->
228                                    <li>
229                                        <span class="fa-li"><?= view('icons/repository') ?></span>
230                                        <a href="#" data-href="<?= e(route('create-repository', ['ged' => $managed_tree->getName()])) ?>" data-target="#wt-ajax-modal" data-toggle="modal">
231                                            <?= I18N::translate('Repository') ?>
232                                            <span class="sr-only">
233                                                <?= e($managed_tree->getTitle()) ?>
234                                            </span>
235                                        </a>
236                                    </li>
237                                    <!-- UNLINKED MEDIA OBJECT -->
238                                    <li>
239                                        <span class="fa-li"><?= view('icons/media') ?></span>
240                                        <a href="#" data-href="<?= e(route('create-media-object', ['ged' => $managed_tree->getName()])) ?>" data-target="#wt-ajax-modal" data-toggle="modal">
241
242                                            <?= I18N::translate('Media object') ?>
243                                            <span class="sr-only">
244                                                <?= e($managed_tree->getTitle()) ?>
245                                            </span>
246                                        </a>
247                                    </li>
248                                    <!-- UNLINKED NOTE -->
249                                    <li>
250                                        <span class="fa-li"><?= view('icons/note') ?></span>
251                                        <a href="#" data-href="<?= e(route('create-note-object', ['ged' => $managed_tree->getName()])) ?>" data-target="#wt-ajax-modal" data-toggle="modal">
252                                            <span class="sr-only">
253                                                <?= e($managed_tree->getTitle()) ?>
254                                            </span>
255                                            <?= I18N::translate('Shared note') ?>
256                                        </a>
257                                    </li>
258                                    <!-- UNLINKED SUBMITTER -->
259                                    <li>
260                                        <span class="fa-li"><?= view('icons/submitter') ?></span>
261                                        <a href="#" data-href="<?= e(route('create-submitter', ['ged' => $managed_tree->getName()])) ?>" data-target="#wt-ajax-modal" data-toggle="modal">
262                                            <span class="sr-only">
263                                                <?= e($managed_tree->getTitle()) ?>
264                                            </span>
265                                            <?= I18N::translate('Submitter') ?>
266                                        </a>
267                                    </li>
268                                </ul>
269                            </div>
270                            <div class="col-sm-6 col-md-3">
271                                <h3>
272                                    <?= I18N::translate('GEDCOM file') ?>
273                                </h3>
274                                <ul class="fa-ul">
275                                    <!-- DOWNLOAD/Export -->
276                                    <li>
277                                        <span class="fa-li"><?= view('icons/download') ?></span>
278                                        <a href="<?= e(route('admin-trees-export', ['ged' => $managed_tree->getName()])) ?>">
279                                            <?= I18N::translate('Export') ?>
280                                            <span class="sr-only">
281                                        <?= e($managed_tree->getTitle()) ?>
282                                    </span>
283                                        </a>
284                                    </li>
285                                    <!-- UPLOAD/IMPORT -->
286                                    <li>
287                                        <span class="fa-li"><?= view('icons/upload') ?></span>
288                                        <a href="<?= e(route('admin-trees-import', ['ged' => $managed_tree->getName()])) ?>">
289                                            <?= I18N::translate('Import') ?>
290                                            <span class="sr-only">
291                                        <?= e($managed_tree->getTitle()) ?>
292                                    </span>
293                                        </a>
294                                    </li>
295                                </ul>
296                            </div>
297                        </div>
298                    </div>
299                </div>
300            </div>
301        <?php endif ?>
302    <?php endforeach ?>
303
304    <?php if (Auth::isAdmin()) : ?>
305        <div class="card">
306            <div class="card-header" id="card-tree-create-header">
307                <h2 class="mb-0">
308            <?= view('icons/add') ?>
309                    <a data-toggle="collapse" data-parent="#accordion" href="#card-tree-create-content" aria-controls="card-tree-create-content">
310                        <?= I18N::translate('Create a family tree') ?>
311                    </a>
312                </h2>
313            </div>
314            <div id="card-tree-create-content" class="collapse<?= empty($all_trees) ? ' show' : '' ?>" role="tabpanel" aria-labelledby="card-tree-create-header">
315                <div class="card-body">
316                    <form class="form-horizontal" method="post" action="<?= e(route('admin-trees-create')) ?>">
317                        <?= csrf_field() ?>
318                        <div class="row form-group">
319                            <label for="tree_title" class="col-sm-2 col-form-label">
320                                <?= I18N::translate('Family tree title') ?>
321                            </label>
322                            <div class="col-sm-10">
323                                <input class="form-control" id="tree_title" maxlength="255" name="tree_title" required type="text" placeholder="<?= $default_tree_title ?>">
324                            </div>
325                        </div>
326                        <div class="row form-group">
327                            <label for="tree_name" class="col-sm-2 col-form-label">
328                                <?= I18N::translate('URL') ?>
329                            </label>
330                            <div class="col-sm-10">
331                                <div class="input-group" dir="ltr">
332                                    <div class="input-group-prepend">
333                                    <span class="input-group-text">
334                                        <?= WT_BASE_URL ?>?ged=
335                                    </span>
336                                    </div>
337                                    <input class="form-control" id="tree_name" maxlength="31" name="tree_name" pattern="[^&lt;&gt;&amp;&quot;#^$*?{}()\[\]/\\]*" required type="text" value="<?= $default_tree_name ?>">
338                                </div>
339                                <p class="small text-muted">
340                                    <?= I18N::translate('Avoid spaces and punctuation. A family name might be a good choice.') ?>
341                                </p>
342                            </div>
343                        </div>
344                        <div class="row form-group">
345                            <div class="offset-sm-2 col-sm-10">
346                                <button type="submit" class="btn btn-primary">
347                                    <?= view('icons/save') ?>
348                                    <?= /* I18N: A button label. */ I18N::translate('create') ?>
349                                </button>
350                                <p class="small text-muted">
351                                    <?= I18N::translate('After creating the family tree, you will be able to import data from a GEDCOM file.') ?>
352                                </p>
353                            </div>
354                        </div>
355                    </form>
356                </div>
357            </div>
358        </div>
359    <?php endif ?>
360
361    <!-- display link to PhpGedView-WT transfer wizard on first visit to this page, before any GEDCOM is loaded -->
362    <?php if (empty($all_trees) && count($all_users) === 1) : ?>
363        <div class="card">
364            <div class="card-header" id="card-pgv-wizard-header">
365                <h2 class="mb-0">
366                    <?= view('icons/wizard') ?>
367                    <a data-toggle="collapse" data-parent="#accordion" href="#card-pgv-wizard-content" aria-controls="card-pgv-wizard-content">
368                        <?= I18N::translate('PhpGedView to webtrees transfer wizard') ?>
369                    </a>
370                </h2>
371            </div>
372            <div id="card-pgv-wizard-content" class="collapse show" role="tabpanel" aria-labelledby="card-pgv-wizard-header">
373                <div class="card-body">
374                    <p>
375                        <?= I18N::translate('The PhpGedView to webtrees wizard is an automated process to assist administrators make the move from a PhpGedView installation to a new webtrees one. It will transfer all PhpGedView GEDCOM and other database information directly to your new webtrees database. The following requirements are necessary:') ?>
376                    </p>
377                    <ul>
378                        <li>
379                            <?= I18N::translate('webtrees’ database must be on the same server as PhpGedView’s') ?>
380                        </li>
381                        <li>
382                            <?= /* I18N: %s is a number */ I18N::translate('PhpGedView must be version 4.2.3, or any SVN up to #%s', I18N::digits(7101)) ?>
383                        </li>
384                        <li>
385                            <?= I18N::translate('All changes in PhpGedView must be accepted') ?>
386                        </li>
387                        <li>
388                            <?= I18N::translate('All existing PhpGedView users must have distinct email addresses') ?>
389                        </li>
390                    </ul>
391                    <p>
392                        <?= I18N::translate('<b>Important note:</b> The transfer wizard is not able to assist with moving media items. You will need to set up and move or copy your media configuration and objects separately after the transfer wizard is finished.') ?>
393                    </p>
394                    <p>
395                        <a href="<?= route('phpgedview-wizard') ?>">
396                            <?= I18N::translate('PhpGedView to webtrees transfer wizard') ?>
397                        </a>
398                    </p>
399                </div>
400            </div>
401        </div>
402    <?php endif ?>
403
404    <!-- BULK LOAD/SYNCHRONISE GEDCOM FILES -->
405    <?php if (count($gedcom_files) >= $multiple_tree_threshold) : ?>
406        <div class="card">
407            <div class="card-header" id="card-tree-create-header">
408                <h2 class="mb-0">
409                    <?= view('icons/sync') ?>
410                    <a data-toggle="collapse" data-parent="#accordion" href="#synchronize-gedcom-files">
411                        <?= I18N::translate('Synchronize family trees with GEDCOM files') ?>
412                    </a>
413                </h2>
414            </div>
415
416            <div id="synchronize-gedcom-files" class="panel-collapse collapse">
417                <div class="card-body">
418                    <p>
419                        <?= I18N::translate('Create, update, and delete a family tree for every GEDCOM file in the data folder.') ?>
420                    </p>
421                    <form method="post" class="form form-horizontal" action="<?= e(route('admin-trees-sync', ['ged' => $tree->getName()])) ?>">
422                        <?= csrf_field() ?>
423                        <button type="submit" class="btn btn-danger">
424                <?= view('icons/save') ?>
425                            <?= /* I18N: A button label. */ I18N::translate('continue') ?>
426                        </button>
427                        <p class="small text-muted">
428                            <?= I18N::translate('Caution! This may take a long time. Be patient.') ?>
429                        </p>
430                    </form>
431                </div>
432            </div>
433        </div>
434    <?php endif ?>
435</div>
436
437<?= view('modals/ajax') ?>
438