1
|
|
|
<?php |
|
|
|
|
2
|
|
|
/** |
3
|
|
|
* webtrees: online genealogy |
4
|
|
|
* Copyright (C) 2017 webtrees development team |
5
|
|
|
* This program is free software: you can redistribute it and/or modify |
6
|
|
|
* it under the terms of the GNU General Public License as published by |
7
|
|
|
* the Free Software Foundation, either version 3 of the License, or |
8
|
|
|
* (at your option) any later version. |
9
|
|
|
* This program is distributed in the hope that it will be useful, |
10
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
11
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12
|
|
|
* GNU General Public License for more details. |
13
|
|
|
* You should have received a copy of the GNU General Public License |
14
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
15
|
|
|
*/ |
16
|
|
|
|
17
|
|
|
namespace Fisharebest\Webtrees; |
18
|
|
|
|
19
|
|
|
use ErrorException; |
20
|
|
|
use Fisharebest\Webtrees\Controller\PageController; |
21
|
|
|
use Fisharebest\Webtrees\Functions\Functions; |
22
|
|
|
use Fisharebest\Webtrees\Functions\FunctionsDb; |
23
|
|
|
use Fisharebest\Webtrees\Functions\FunctionsEdit; |
24
|
|
|
use Fisharebest\Webtrees\Functions\FunctionsImport; |
25
|
|
|
use Fisharebest\Webtrees\Functions\FunctionsPrint; |
26
|
|
|
use Fisharebest\Webtrees\GedcomCode\GedcomCodeName; |
27
|
|
|
use Fisharebest\Webtrees\GedcomCode\GedcomCodePedi; |
28
|
|
|
use Fisharebest\Webtrees\Module\CensusAssistantModule; |
29
|
|
|
|
30
|
|
|
require 'includes/session.php'; |
31
|
|
|
|
32
|
|
|
$action = Filter::post('action', null, Filter::get('action')); |
33
|
|
|
|
34
|
|
|
$controller = new PageController; |
35
|
|
|
$controller |
36
|
|
|
->restrictAccess(Auth::isEditor($controller->tree())) |
37
|
|
|
->addInlineJavascript('var locale_date_format="' . preg_replace('/[^DMY]/', '', str_replace(['j', 'F'], ['D', 'M'], I18N::dateFormat())) . '";'); |
38
|
|
|
|
39
|
|
|
switch ($action) { |
40
|
|
|
case 'editraw': |
41
|
|
|
////////////////////////////////////////////////////////////////////////////// |
42
|
|
|
// Edit a GEDCOM record |
43
|
|
|
////////////////////////////////////////////////////////////////////////////// |
44
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
45
|
|
|
|
46
|
|
|
$record = GedcomRecord::getInstance($xref, $controller->tree()); |
47
|
|
|
check_record_access($record); |
48
|
|
|
|
49
|
|
|
$controller |
50
|
|
|
->setPageTitle($record->getFullName() . ' - ' . I18N::translate('Edit the raw GEDCOM')) |
51
|
|
|
->pageHeader() |
52
|
|
|
->addInlineJavascript('$("#raw-gedcom-list").sortable({opacity: 0.7, cursor: "move", axis: "y"});'); |
53
|
|
|
|
54
|
|
|
?> |
55
|
|
|
<h2><?= $controller->getPageTitle() ?></h2> |
56
|
|
|
|
57
|
|
|
<form method="post"> |
58
|
|
|
<input type="hidden" name="ged" value="<?= $controller->tree()->getNameHtml() ?>"> |
59
|
|
|
<input type="hidden" name="action" value="updateraw"> |
60
|
|
|
<input type="hidden" name="xref" value="<?= $xref ?>"> |
61
|
|
|
<?= Filter::getCsrf() ?> |
62
|
|
|
<p class="text-muted small"> |
63
|
|
|
<?= I18N::translate('This page allows you to bypass the usual forms, and edit the underlying data directly. It is an advanced option, and you should not use it unless you understand the GEDCOM format. If you make a mistake here, it can be difficult to fix.') ?> |
64
|
|
|
<?= /* I18N: %s is a URL */ |
65
|
|
|
I18N::translate('You can download a copy of the GEDCOM specification from %s.', '<a href="https://wiki.webtrees.net/w/images-en/Ged551-5.pdf">https://wiki.webtrees.net/w/images-en/Ged551-5.pdf</a>') ?> |
66
|
|
|
</p> |
67
|
|
|
<ul id="raw-gedcom-list"> |
68
|
|
|
<li><textarea class="form-control" readonly |
69
|
|
|
rows="1"><?= '0 @' . $record->getXref() . '@ ' . $record::RECORD_TYPE ?></textarea></li> |
|
|
|
|
70
|
|
|
<?php foreach ($record->getFacts() as $fact): ?> |
71
|
|
|
<?php if (!$fact->isPendingDeletion()): ?> |
72
|
|
|
<li> |
73
|
|
|
<div style="cursor:move;"> |
74
|
|
|
<?= $fact->summary() ?> |
75
|
|
|
</div> |
76
|
|
|
<input type="hidden" name="fact_id[]" value="<?= $fact->getFactId() ?>"> |
77
|
|
|
<textarea name="fact[]" dir="ltr" rows="<?= preg_match_all('/\n/', $fact->getGedcom()) ?>" |
78
|
|
|
style="width:100%;"><?= Html::escape($fact->getGedcom()) ?></textarea> |
79
|
|
|
</li> |
80
|
|
|
<?php endif ?> |
81
|
|
|
<?php endforeach ?> |
82
|
|
|
<li> |
83
|
|
|
<div style="cursor:move;"> |
84
|
|
|
<b><i><?= I18N::translate('Add a fact') ?></i></b> |
85
|
|
|
</div> |
86
|
|
|
<input type="hidden" name="fact_id[]" value=""> |
87
|
|
|
<textarea name="fact[]" dir="ltr" rows="2" style="width:100%;"></textarea> |
88
|
|
|
</li> |
89
|
|
|
</ul> |
90
|
|
|
<div class="row form-group"> |
91
|
|
|
<div class="col-sm-9 offset-sm-3"> |
92
|
|
|
<button class="btn btn-primary" type="submit"> |
93
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
94
|
|
|
<?= /* I18N: A button label. */ |
95
|
|
|
I18N::translate('save') ?> |
96
|
|
|
</button> |
97
|
|
|
<a class="btn btn-secondary" href="<?= $record->getHtmlUrl() ?>"> |
98
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
99
|
|
|
<?= /* I18N: A button label. */ |
100
|
|
|
I18N::translate('cancel') ?> |
101
|
|
|
</a> |
102
|
|
|
</div> |
103
|
|
|
</div> |
104
|
|
|
</form> |
105
|
|
|
<?php |
106
|
|
|
break; |
107
|
|
|
|
108
|
|
|
case 'updateraw': |
109
|
|
|
////////////////////////////////////////////////////////////////////////////// |
110
|
|
|
// Save an updated GEDCOM record |
111
|
|
|
////////////////////////////////////////////////////////////////////////////// |
112
|
|
|
$xref = Filter::post('xref', WT_REGEX_XREF); |
113
|
|
|
$facts = Filter::postArray('fact'); |
114
|
|
|
$fact_ids = Filter::postArray('fact_id'); |
115
|
|
|
|
116
|
|
|
if (!Filter::checkCsrf()) { |
117
|
|
|
header('Location: edit_interface.php?action=editraw&xref=' . $xref); |
118
|
|
|
break; |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
$record = GedcomRecord::getInstance($xref, $controller->tree()); |
122
|
|
|
check_record_access($record); |
123
|
|
|
|
124
|
|
|
$gedcom = '0 @' . $record->getXref() . '@ ' . $record::RECORD_TYPE; |
125
|
|
|
|
126
|
|
|
// Retain any private facts |
127
|
|
|
foreach ($record->getFacts(null, false, Auth::PRIV_HIDE) as $fact) { |
128
|
|
|
if (!in_array($fact->getFactId(), $fact_ids) && !$fact->isPendingDeletion()) { |
129
|
|
|
$gedcom .= "\n" . $fact->getGedcom(); |
130
|
|
|
} |
131
|
|
|
} |
132
|
|
|
// Append the new facts |
133
|
|
|
foreach ($facts as $fact) { |
134
|
|
|
$gedcom .= "\n" . $fact; |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
// Cleanup the client’s bad editing? |
138
|
|
|
$gedcom = preg_replace('/[\r\n]+/', "\n", $gedcom); // Empty lines |
139
|
|
|
$gedcom = trim($gedcom); // Leading/trailing spaces |
140
|
|
|
|
141
|
|
|
$record->updateRecord($gedcom, false); |
142
|
|
|
|
143
|
|
|
header('Location: ' . $record->getRawUrl()); |
144
|
|
|
break; |
145
|
|
|
|
146
|
|
|
case 'editrawfact': |
147
|
|
|
////////////////////////////////////////////////////////////////////////////// |
148
|
|
|
// Edit a GEDCOM fact |
149
|
|
|
////////////////////////////////////////////////////////////////////////////// |
150
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
151
|
|
|
$fact_id = Filter::get('fact_id'); |
152
|
|
|
|
153
|
|
|
$record = GedcomRecord::getInstance($xref, $controller->tree()); |
154
|
|
|
check_record_access($record); |
155
|
|
|
|
156
|
|
|
// Find the fact to edit |
157
|
|
|
$edit_fact = null; |
158
|
|
View Code Duplication |
foreach ($record->getFacts() as $fact) { |
159
|
|
|
if ($fact->getFactId() === $fact_id && $fact->canEdit()) { |
160
|
|
|
$edit_fact = $fact; |
161
|
|
|
break; |
162
|
|
|
} |
163
|
|
|
} |
164
|
|
|
if (!$edit_fact) { |
165
|
|
|
header('Location: ' . $record->getRawUrl()); |
166
|
|
|
break; |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
$controller |
170
|
|
|
->setPageTitle($record->getFullName() . ' - ' . I18N::translate('Edit the raw GEDCOM')) |
171
|
|
|
->pageHeader(); |
172
|
|
|
|
173
|
|
|
// How many lines to use in the edit control? |
174
|
|
|
$rows = count(explode("\n", $edit_fact->getGedcom())) + 2; |
175
|
|
|
|
176
|
|
|
?> |
177
|
|
|
<h2><?= $controller->getPageTitle() ?></h2> |
178
|
|
|
|
179
|
|
|
<form method="post"> |
180
|
|
|
<input type="hidden" name="ged" value="<?= $controller->tree()->getNameHtml() ?>"> |
181
|
|
|
<input type="hidden" name="action" value="updaterawfact"> |
182
|
|
|
<input type="hidden" name="xref" value="<?= $xref ?>"> |
183
|
|
|
<input type="hidden" name="fact_id" value="<?= $fact_id ?>"> |
184
|
|
|
<?= Filter::getCsrf() ?> |
185
|
|
|
<p class="text-muted small"> |
186
|
|
|
<?= I18N::translate('This page allows you to bypass the usual forms, and edit the underlying data directly. It is an advanced option, and you should not use it unless you understand the GEDCOM format. If you make a mistake here, it can be difficult to fix.') ?> |
187
|
|
|
<?= /* I18N: %s is a URL */ |
188
|
|
|
I18N::translate('You can download a copy of the GEDCOM specification from %s.', '<a href="https://wiki.webtrees.net/w/images-en/Ged551-5.pdf">https://wiki.webtrees.net/w/images-en/Ged551-5.pdf</a>') ?> |
189
|
|
|
</p> |
190
|
|
|
<div class="row form-group"> |
191
|
|
|
<label class="col-sm-3 col-form-label" for="gedcom"> |
192
|
|
|
<?= GedcomTag::getLabel($edit_fact->getTag()) ?> |
193
|
|
|
</label> |
194
|
|
|
<div class="col-sm-9"> |
195
|
|
|
<textarea autofocus class="form-control" rows="<?= $rows ?>" name="gedcom" id="gedcom" |
196
|
|
|
dir="ltr"><?= Html::escape($edit_fact->getGedcom()) ?></textarea> |
197
|
|
|
</div> |
198
|
|
|
</div> |
199
|
|
|
<?= keep_chan($record) ?> |
200
|
|
|
<div class="row form-group"> |
201
|
|
|
<div class="col-sm-9 offset-sm-3"> |
202
|
|
|
<button class="btn btn-primary" type="submit"> |
203
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
204
|
|
|
<?= /* I18N: A button label. */ |
205
|
|
|
I18N::translate('save') ?> |
206
|
|
|
</button> |
207
|
|
|
<a class="btn btn-secondary" href="<?= $record->getHtmlUrl() ?>"> |
208
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
209
|
|
|
<?= /* I18N: A button label. */ |
210
|
|
|
I18N::translate('cancel') ?> |
211
|
|
|
</a> |
212
|
|
|
</div> |
213
|
|
|
</div> |
214
|
|
|
</form> |
215
|
|
|
<?php |
216
|
|
|
break; |
217
|
|
|
|
218
|
|
|
case 'updaterawfact': |
219
|
|
|
////////////////////////////////////////////////////////////////////////////// |
220
|
|
|
// Save an updated GEDCOM fact |
221
|
|
|
////////////////////////////////////////////////////////////////////////////// |
222
|
|
|
$xref = Filter::post('xref', WT_REGEX_XREF); |
223
|
|
|
$fact_id = Filter::post('fact_id'); |
224
|
|
|
$gedcom = Filter::post('gedcom'); |
225
|
|
|
$keep_chan = Filter::postBool('keep_chan'); |
226
|
|
|
|
227
|
|
|
if (!Filter::checkCsrf()) { |
228
|
|
|
header('Location: edit_interface.php?action=editrawfact&xref=' . $xref . '&fact_id=' . $fact_id); |
229
|
|
|
break; |
230
|
|
|
} |
231
|
|
|
|
232
|
|
|
$record = GedcomRecord::getInstance($xref, $controller->tree()); |
233
|
|
|
check_record_access($record); |
234
|
|
|
|
235
|
|
|
// Find the fact to edit |
236
|
|
|
foreach ($record->getFacts() as $fact) { |
237
|
|
|
if ($fact->getFactId() === $fact_id && $fact->canEdit()) { |
238
|
|
|
// Cleanup the client’s bad editing? |
239
|
|
|
$gedcom = preg_replace('/[\r\n]+/', "\n", $gedcom); // Empty lines |
240
|
|
|
$gedcom = trim($gedcom); // Leading/trailing spaces |
241
|
|
|
|
242
|
|
|
$record->updateFact($fact_id, $gedcom, !$keep_chan); |
243
|
|
|
break; |
244
|
|
|
} |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
header('Location: ' . $record->getRawUrl()); |
248
|
|
|
break; |
249
|
|
|
|
250
|
|
|
case 'edit': |
251
|
|
|
////////////////////////////////////////////////////////////////////////////// |
252
|
|
|
// Edit a fact |
253
|
|
|
////////////////////////////////////////////////////////////////////////////// |
254
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
255
|
|
|
$fact_id = Filter::get('fact_id'); |
256
|
|
|
|
257
|
|
|
$record = GedcomRecord::getInstance($xref, $controller->tree()); |
258
|
|
|
check_record_access($record); |
259
|
|
|
|
260
|
|
|
// Find the fact to edit |
261
|
|
|
$edit_fact = null; |
262
|
|
View Code Duplication |
foreach ($record->getFacts() as $fact) { |
263
|
|
|
if ($fact->getFactId() === $fact_id && $fact->canEdit()) { |
264
|
|
|
$edit_fact = $fact; |
265
|
|
|
break; |
266
|
|
|
} |
267
|
|
|
} |
268
|
|
|
if (!$edit_fact) { |
269
|
|
|
header('Location: ' . $record->getRawUrl()); |
270
|
|
|
break; |
271
|
|
|
} |
272
|
|
|
|
273
|
|
|
$controller |
274
|
|
|
->setPageTitle($record->getFullName() . ' - ' . GedcomTag::getLabel($edit_fact->getTag())) |
275
|
|
|
->pageHeader(); |
276
|
|
|
|
277
|
|
|
echo '<h2>', $controller->getPageTitle(), '</h2>'; |
278
|
|
|
FunctionsPrint::initializeCalendarPopup(); |
279
|
|
|
echo '<form name="editform" method="post" enctype="multipart/form-data">'; |
280
|
|
|
echo '<input type="hidden" name="ged" value="', $controller->tree()->getNameHtml(), '">'; |
281
|
|
|
echo '<input type="hidden" name="action" value="update">'; |
282
|
|
|
echo '<input type="hidden" name="fact_id" value="', $fact_id, '">'; |
283
|
|
|
echo '<input type="hidden" name="xref" value="', $xref, '">'; |
284
|
|
|
echo '<input type="hidden" name="prev_action" value="edit">'; |
285
|
|
|
echo Filter::getCsrf(); |
286
|
|
|
FunctionsEdit::createEditForm($edit_fact); |
287
|
|
|
echo keep_chan($record); |
288
|
|
|
|
289
|
|
|
$level1type = $edit_fact->getTag(); |
290
|
|
|
switch ($record::RECORD_TYPE) { |
291
|
|
|
case 'REPO': |
292
|
|
|
// REPO:NAME facts may take a NOTE (but the REPO record may not). |
293
|
|
|
if ($level1type === 'NAME') { |
294
|
|
|
FunctionsEdit::printAddLayer('NOTE'); |
295
|
|
|
FunctionsEdit::printAddLayer('SHARED_NOTE'); |
296
|
|
|
} |
297
|
|
|
break; |
298
|
|
|
case 'FAM': |
299
|
|
|
case 'INDI': |
300
|
|
|
// FAM and INDI records have real facts. They can take NOTE/SOUR/OBJE/etc. |
301
|
|
|
if ($level1type !== 'SEX' && $level1type !== 'NOTE' && $level1type !== 'ALIA') { |
302
|
|
|
if ($level1type !== 'SOUR') { |
303
|
|
|
FunctionsEdit::printAddLayer('SOUR'); |
304
|
|
|
} |
305
|
|
|
if ($level1type !== 'OBJE') { |
306
|
|
|
FunctionsEdit::printAddLayer('OBJE'); |
307
|
|
|
} |
308
|
|
|
FunctionsEdit::printAddLayer('NOTE'); |
309
|
|
|
FunctionsEdit::printAddLayer('SHARED_NOTE', 2, $level1type); |
310
|
|
|
if ($level1type !== 'ASSO' && $level1type !== 'NOTE' && $level1type !== 'SOUR') { |
311
|
|
|
FunctionsEdit::printAddLayer('ASSO'); |
312
|
|
|
} |
313
|
|
|
// allow to add godfather and godmother for CHR fact or best man and bridesmaid for MARR fact in one window |
314
|
|
|
if (in_array($level1type, Config::twoAssociates())) { |
315
|
|
|
FunctionsEdit::printAddLayer('ASSO2'); |
316
|
|
|
} |
317
|
|
|
if ($level1type !== 'SOUR') { |
318
|
|
|
FunctionsEdit::printAddLayer('RESN'); |
319
|
|
|
} |
320
|
|
|
} |
321
|
|
|
break; |
322
|
|
|
default: |
323
|
|
|
// Other types of record do not have these lower-level records |
324
|
|
|
break; |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
?> |
328
|
|
|
<div class="row form-group"> |
329
|
|
|
<div class="col-sm-9 offset-sm-3"> |
330
|
|
|
<button class="btn btn-primary" type="submit"> |
331
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
332
|
|
|
<?= /* I18N: A button label. */ |
333
|
|
|
I18N::translate('save') ?> |
334
|
|
|
</button> |
335
|
|
|
<a class="btn btn-secondary" href="<?= $record->getHtmlUrl() ?>"> |
336
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
337
|
|
|
<?= /* I18N: A button label. */ |
338
|
|
|
I18N::translate('cancel') ?> |
339
|
|
|
</a> |
340
|
|
View Code Duplication |
<?php if (Auth::isAdmin() || $controller->tree()->getPreference('SHOW_GEDCOM_RECORD')): ?> |
341
|
|
|
<a class="btn btn-link" |
342
|
|
|
href="edit_interface.php?action=editrawfact&xref=<?= $xref ?>&fact_id=<?= $fact_id ?>&ged=<?= $controller->tree()->getNameUrl() ?>"> |
343
|
|
|
<?= I18N::translate('Edit the raw GEDCOM') ?> |
344
|
|
|
</a> |
345
|
|
|
<?php endif; ?> |
346
|
|
|
</div> |
347
|
|
|
</div> |
348
|
|
|
|
349
|
|
|
</form> |
350
|
|
|
<?php |
351
|
|
|
echo View::make('modals/create-family', ['tree' => $controller->tree()]); |
352
|
|
|
echo View::make('modals/create-media', ['tree' => $controller->tree(), 'max_upload_size' => '???', 'unused_files' => []]); |
353
|
|
|
echo View::make('modals/create-note', ['tree' => $controller->tree()]); |
354
|
|
|
echo View::make('modals/create-repository', ['tree' => $controller->tree()]); |
355
|
|
|
echo View::make('modals/create-source', ['tree' => $controller->tree()]); |
356
|
|
|
echo View::make('modals/create-submitter', ['tree' => $controller->tree()]); |
357
|
|
|
echo View::make('modals/on-screen-keyboard'); |
358
|
|
|
break; |
359
|
|
|
|
360
|
|
|
case 'add': |
361
|
|
|
////////////////////////////////////////////////////////////////////////////// |
362
|
|
|
// Add a new fact |
363
|
|
|
////////////////////////////////////////////////////////////////////////////// |
364
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
365
|
|
|
$fact = Filter::get('fact', WT_REGEX_TAG); |
366
|
|
|
|
367
|
|
|
$record = GedcomRecord::getInstance($xref, $controller->tree()); |
368
|
|
|
check_record_access($record); |
369
|
|
|
|
370
|
|
|
$controller |
371
|
|
|
->setPageTitle($record->getFullName() . ' - ' . GedcomTag::getLabel($fact, $record)) |
372
|
|
|
->pageHeader(); |
373
|
|
|
|
374
|
|
|
$level0type = $record::RECORD_TYPE; |
375
|
|
|
|
376
|
|
|
echo '<h2>', $controller->getPageTitle(), '</h2>'; |
377
|
|
|
|
378
|
|
|
FunctionsPrint::initializeCalendarPopup(); |
379
|
|
|
echo '<form name="addform" method="post" enctype="multipart/form-data">'; |
380
|
|
|
echo '<input type="hidden" name="ged" value="', $controller->tree()->getNameHtml(), '">'; |
381
|
|
|
echo '<input type="hidden" name="action" value="update">'; |
382
|
|
|
echo '<input type="hidden" name="xref" value="', $xref, '">'; |
383
|
|
|
echo '<input type="hidden" name="prev_action" value="add">'; |
384
|
|
|
echo '<input type="hidden" name="fact_type" value="' . $fact . '">'; |
385
|
|
|
echo Filter::getCsrf(); |
386
|
|
|
FunctionsEdit::createAddForm($fact); |
387
|
|
|
echo keep_chan($record); |
388
|
|
|
|
389
|
|
|
// Genealogical facts (e.g. for INDI and FAM records) can have 2 SOUR/NOTE/OBJE/ASSO/RESN ... |
390
|
|
|
if ($level0type === 'INDI' || $level0type === 'FAM') { |
391
|
|
|
// ... but not facts which are simply links to other records |
392
|
|
|
if ($fact !== 'OBJE' && $fact !== 'NOTE' && $fact !== 'SHARED_NOTE' && $fact !== 'REPO' && $fact !== 'SOUR' && $fact !== 'SUBM' && $fact !== 'ASSO' && $fact !== 'ALIA') { |
393
|
|
|
FunctionsEdit::printAddLayer('SOUR'); |
394
|
|
|
FunctionsEdit::printAddLayer('OBJE'); |
395
|
|
|
// Don’t add notes to notes! |
396
|
|
|
if ($fact !== 'NOTE') { |
397
|
|
|
FunctionsEdit::printAddLayer('NOTE'); |
398
|
|
|
FunctionsEdit::printAddLayer('SHARED_NOTE', 2, $fact); |
399
|
|
|
} |
400
|
|
|
FunctionsEdit::printAddLayer('ASSO'); |
401
|
|
|
// allow to add godfather and godmother for CHR fact or best man and bridesmaid for MARR fact in one window |
402
|
|
|
if (in_array($fact, Config::twoAssociates())) { |
403
|
|
|
FunctionsEdit::printAddLayer('ASSO2'); |
404
|
|
|
} |
405
|
|
|
FunctionsEdit::printAddLayer('RESN'); |
406
|
|
|
} |
407
|
|
|
} |
408
|
|
|
?> |
409
|
|
|
<div class="row form-group"> |
410
|
|
|
<div class="col-sm-9 offset-sm-3"> |
411
|
|
|
<button class="btn btn-primary" type="submit"> |
412
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
413
|
|
|
<?= /* I18N: A button label. */ |
414
|
|
|
I18N::translate('save') ?> |
415
|
|
|
</button> |
416
|
|
|
<a class="btn btn-secondary" href="<?= $record->getHtmlUrl() ?>"> |
417
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
418
|
|
|
<?= /* I18N: A button label. */ |
419
|
|
|
I18N::translate('cancel') ?> |
420
|
|
|
</a> |
421
|
|
|
</div> |
422
|
|
|
</div> |
423
|
|
|
</form> |
424
|
|
|
<?php |
425
|
|
|
echo View::make('modals/create-family', ['tree' => $controller->tree()]); |
426
|
|
|
echo View::make('modals/create-media', ['tree' => $controller->tree(), 'max_upload_size' => '???', 'unused_files' => []]); |
427
|
|
|
echo View::make('modals/create-note', ['tree' => $controller->tree()]); |
428
|
|
|
echo View::make('modals/create-repository', ['tree' => $controller->tree()]); |
429
|
|
|
echo View::make('modals/create-source', ['tree' => $controller->tree()]); |
430
|
|
|
echo View::make('modals/create-submitter', ['tree' => $controller->tree()]); |
431
|
|
|
echo View::make('modals/on-screen-keyboard'); |
432
|
|
|
|
433
|
|
|
break; |
434
|
|
|
|
435
|
|
|
case 'update': |
436
|
|
|
////////////////////////////////////////////////////////////////////////////// |
437
|
|
|
// Save a new/updated fact |
438
|
|
|
////////////////////////////////////////////////////////////////////////////// |
439
|
|
|
$xref = Filter::post('xref', WT_REGEX_XREF); |
440
|
|
|
$fact_id = Filter::post('fact_id'); |
441
|
|
|
$keep_chan = Filter::postBool('keep_chan'); |
442
|
|
|
|
443
|
|
|
if (!Filter::checkCsrf()) { |
444
|
|
|
$prev_action = Filter::post('prev_action', 'add|edit|addname|editname'); |
445
|
|
|
$fact_type = Filter::post('fact_type', WT_REGEX_TAG); |
446
|
|
|
header('Location: edit_interface.php?action=' . $prev_action . '&xref=' . $xref . '&fact_id=' . $fact_id . '&fact=' . $fact_type); |
447
|
|
|
break; |
448
|
|
|
} |
449
|
|
|
|
450
|
|
|
$record = GedcomRecord::getInstance($xref, $controller->tree()); |
451
|
|
|
check_record_access($record); |
452
|
|
|
|
453
|
|
|
// Arrays for each GEDCOM line |
454
|
|
|
$glevels = Filter::postArray('glevels', '[0-9]'); |
455
|
|
|
$tag = Filter::postArray('tag', WT_REGEX_TAG); |
456
|
|
|
$text = Filter::postArray('text'); |
457
|
|
|
$islink = Filter::postArray('islink', '[01]'); |
458
|
|
|
|
459
|
|
|
// If the fact has a DATE or PLAC, then delete any value of Y |
460
|
|
|
if ($text[0] === 'Y') { |
461
|
|
|
foreach ($tag as $n => $value) { |
462
|
|
|
if ($glevels[$n] == 2 && ($value === 'DATE' || $value === 'PLAC') && $text[$n] !== '') { |
463
|
|
|
$text[0] = ''; |
464
|
|
|
break; |
465
|
|
|
} |
466
|
|
|
} |
467
|
|
|
} |
468
|
|
|
|
469
|
|
|
$newged = ''; |
470
|
|
|
if (!empty($_POST['NAME'])) { |
471
|
|
|
$newged .= "\n1 NAME " . $_POST['NAME']; |
472
|
|
|
$name_facts = ['TYPE', 'NPFX', 'GIVN', 'NICK', 'SPFX', 'SURN', 'NSFX']; |
473
|
|
|
foreach ($name_facts as $name_fact) { |
474
|
|
|
if (!empty($_POST[$name_fact])) { |
475
|
|
|
$newged .= "\n2 " . $name_fact . ' ' . $_POST[$name_fact]; |
476
|
|
|
} |
477
|
|
|
} |
478
|
|
|
} |
479
|
|
|
|
480
|
|
|
if (isset($_POST['NOTE'])) { |
481
|
|
|
$NOTE = $_POST['NOTE']; |
482
|
|
|
} |
483
|
|
|
if (!empty($NOTE)) { |
484
|
|
|
$tempnote = preg_split('/\r?\n/', trim($NOTE) . "\n"); // make sure only one line ending on the end |
485
|
|
|
$title[] = '0 @' . $xref . '@ NOTE ' . array_shift($tempnote); |
486
|
|
|
foreach ($tempnote as &$line) { |
487
|
|
|
$line = trim('1 CONT ' . $line, ' '); |
488
|
|
|
} |
489
|
|
|
} |
490
|
|
|
|
491
|
|
|
$newged = FunctionsEdit::handleUpdates($newged); |
492
|
|
|
|
493
|
|
|
// Add new names after existing names |
494
|
|
|
if (!empty($_POST['NAME'])) { |
495
|
|
|
preg_match_all('/[_0-9A-Z]+/', $controller->tree()->getPreference('ADVANCED_NAME_FACTS'), $match); |
496
|
|
|
$name_facts = array_unique(array_merge(['_MARNM'], $match[0])); |
497
|
|
|
foreach ($name_facts as $name_fact) { |
498
|
|
|
// Ignore advanced facts that duplicate standard facts. |
499
|
|
|
if (!in_array($name_fact, ['TYPE', 'NPFX', 'GIVN', 'NICK', 'SPFX', 'SURN', 'NSFX']) && !empty($_POST[$name_fact])) { |
500
|
|
|
$newged .= "\n2 " . $name_fact . ' ' . $_POST[$name_fact]; |
501
|
|
|
} |
502
|
|
|
} |
503
|
|
|
} |
504
|
|
|
|
505
|
|
|
$newged = substr($newged, 1); // Remove leading newline |
506
|
|
|
|
507
|
|
|
/** @var CensusAssistantModule $census_assistant */ |
508
|
|
|
$census_assistant = Module::getModuleByName('GEDFact_assistant'); |
509
|
|
|
if ($census_assistant !== null && $record instanceof Individual) { |
510
|
|
|
$newged = $census_assistant->updateCensusAssistant($record, $fact_id, $newged, $keep_chan); |
511
|
|
|
} |
512
|
|
|
|
513
|
|
|
$record->updateFact($fact_id, $newged, !$keep_chan); |
514
|
|
|
|
515
|
|
|
// For the GEDFact_assistant module |
516
|
|
|
$pid_array = Filter::post('pid_array'); |
517
|
|
|
if ($pid_array) { |
518
|
|
|
foreach (explode(',', $pid_array) as $pid) { |
519
|
|
|
if ($pid !== $xref) { |
520
|
|
|
$indi = Individual::getInstance($pid, $controller->tree()); |
521
|
|
|
if ($indi && $indi->canEdit()) { |
522
|
|
|
$indi->updateFact($fact_id, $newged, !$keep_chan); |
523
|
|
|
} |
524
|
|
|
} |
525
|
|
|
} |
526
|
|
|
} |
527
|
|
|
|
528
|
|
|
header('Location: ' . $record->getRawUrl()); |
529
|
|
|
break; |
530
|
|
|
|
531
|
|
|
case 'media-edit': |
532
|
|
|
////////////////////////////////////////////////////////////////////////////// |
533
|
|
|
// Edit a media object |
534
|
|
|
////////////////////////////////////////////////////////////////////////////// |
535
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
536
|
|
|
$fact_id = Filter::get('fact_id'); |
537
|
|
|
|
538
|
|
|
$record = GedcomRecord::getInstance($xref, $controller->tree()); |
539
|
|
|
check_record_access($record); |
540
|
|
|
|
541
|
|
|
// Find the fact to edit |
542
|
|
|
$edit_fact = null; |
543
|
|
|
foreach ($record->getFacts() as $fact) { |
544
|
|
|
if ($fact->getFactId() === $fact_id && $fact->canEdit()) { |
545
|
|
|
$edit_fact = $fact; |
546
|
|
|
break; |
547
|
|
|
} |
548
|
|
|
} |
549
|
|
|
if (!$edit_fact) { |
550
|
|
|
header('Location: ' . $record->getRawUrl()); |
551
|
|
|
break; |
552
|
|
|
} |
553
|
|
|
|
554
|
|
|
$controller |
555
|
|
|
->setPageTitle($record->getFullName() . ' - ' . I18N::translate('edit')) |
556
|
|
|
->pageHeader(); |
557
|
|
|
|
558
|
|
|
// Other systems generate various structures for media objects... |
559
|
|
|
// Extract them from wherever they might be |
560
|
|
|
$FILE = ''; |
561
|
|
|
$TITL = ''; |
562
|
|
|
$TYPE = ''; |
563
|
|
|
if (preg_match('/^\d FILE (.+)/m', $edit_fact->getGedcom(), $match)) { |
564
|
|
|
$FILE = $match[1]; |
565
|
|
|
} |
566
|
|
|
if (preg_match('/^\d TITL (.+)/m', $edit_fact->getGedcom(), $match)) { |
567
|
|
|
$TITL = $match[1]; |
568
|
|
|
} |
569
|
|
|
if (preg_match('/^\d TYPE (.+)/m', $edit_fact->getGedcom(), $match)) { |
570
|
|
|
$TYPE = $match[1]; |
571
|
|
|
} |
572
|
|
|
|
573
|
|
|
$auto_file = ''; |
574
|
|
|
$old_file = $record->getServerFilename('main'); |
|
|
|
|
575
|
|
|
if (file_exists($old_file)) { |
576
|
|
|
$old_base = strtolower(pathinfo($old_file, PATHINFO_BASENAME)); |
577
|
|
|
$old_format = strtolower(pathinfo($old_file, PATHINFO_EXTENSION)); |
578
|
|
|
$old_format = strtr($old_format, ['jpg' => 'jpeg']); |
579
|
|
|
|
580
|
|
|
$sha1 = sha1_file($old_file); |
581
|
|
|
if ($old_base !== $sha1 . '.' . $old_format) { |
582
|
|
|
$auto_file = $sha1 . '.' . $old_format; |
583
|
|
|
} |
584
|
|
|
} |
585
|
|
|
|
586
|
|
|
|
587
|
|
|
?> |
588
|
|
|
<h2><?= $controller->getPageTitle() ?></h2> |
589
|
|
|
<form method="post" enctype="multipart/form-data"> |
590
|
|
|
<input type="hidden" name="ged" value="<?= $controller->tree()->getNameHtml() ?>"> |
591
|
|
|
<input type="hidden" name="action" value="media-save"> |
592
|
|
|
<input type="hidden" name="xref" value="<?= $xref ?>"> |
593
|
|
|
<input type="hidden" name="fact_id" value="<?= $edit_fact->getFactId() ?>"> |
594
|
|
|
<?= Filter::getCsrf() ?> |
595
|
|
|
|
596
|
|
|
<div class="row form-group"> |
597
|
|
|
<div class="col-sm-9 offset-sm-3"> |
598
|
|
|
<?= $record->displayImage(400, 200, '', []) ?> |
599
|
|
|
</div> |
600
|
|
|
</div> |
601
|
|
|
|
602
|
|
|
<div class="form-group row"> |
603
|
|
|
<label class="col-form-label col-sm-3" for="file"> |
604
|
|
|
<?= I18N::translate('Media file to upload') ?> |
605
|
|
|
</label> |
606
|
|
|
<div class="col-sm-9"> |
607
|
|
|
<input type="file" class="form-control" id="file" name="file"> |
608
|
|
|
</div> |
609
|
|
|
</div> |
610
|
|
|
|
611
|
|
|
<div class="form-group row"> |
612
|
|
|
<label class="col-sm-3 col-form-label" for="TITL"> |
613
|
|
|
<?= I18N::translate('Title') ?> |
614
|
|
|
</label> |
615
|
|
|
<div class="col-sm-9"> |
616
|
|
|
<input type="text" id="TITL" name="TITL" class="form-control" value="<?= Html::escape($TITL) ?>"> |
617
|
|
|
</div> |
618
|
|
|
</div> |
619
|
|
|
|
620
|
|
|
<div class="form-group row"> |
621
|
|
|
<label class="col-sm-3 col-form-label" for="FILE"> |
622
|
|
|
<?= I18N::translate('Filename on server') ?> |
623
|
|
|
</label> |
624
|
|
|
<div class="col-sm-9"> |
625
|
|
|
<input type="text" id="FILE" name="FILE" class="form-control" value="<?= Html::escape($FILE) ?>" required> |
626
|
|
|
|
627
|
|
View Code Duplication |
<?php if ($auto_file !== ''): ?> |
628
|
|
|
<a href="#" class="btn btn-link" title="<?= Html::escape($auto_file) ?>" |
629
|
|
|
onclick="document.querySelector('#FILE').value='<?= Html::escape($auto_file) ?>'; document.querySelector('#FILE').focus(); return false;"> |
630
|
|
|
<?= I18N::translate('Create a unique filename') ?> |
631
|
|
|
</a> |
632
|
|
|
<?php endif ?> |
633
|
|
|
</div> |
634
|
|
|
</div> |
635
|
|
|
|
636
|
|
|
<div class="form-group row"> |
637
|
|
|
<label class="col-sm-3 col-form-label" for="TYPE"> |
638
|
|
|
<?= I18N::translate('Type') ?> |
639
|
|
|
</label> |
640
|
|
|
<div class="col-sm-9"> |
641
|
|
|
<?= Bootstrap4::select(['' => ''] + GedcomTag::getFileFormTypes() + [$TYPE => $TYPE], $TYPE, ['id' => 'TYPE', 'name' => 'TYPE']) ?> |
642
|
|
|
</div> |
643
|
|
|
</div> |
644
|
|
|
|
645
|
|
|
<?= keep_chan($record) ?> |
646
|
|
|
|
647
|
|
|
<div class="row form-group"> |
648
|
|
|
<div class="col-sm-9 offset-sm-3"> |
649
|
|
|
<button class="btn btn-primary" type="submit"> |
650
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
651
|
|
|
<?= /* I18N: A button label. */ |
652
|
|
|
I18N::translate('save') ?> |
653
|
|
|
</button> |
654
|
|
|
<a class="btn btn-secondary" href="<?= $record->getHtmlUrl() ?>"> |
655
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
656
|
|
|
<?= /* I18N: A button label. */ |
657
|
|
|
I18N::translate('cancel') ?> |
658
|
|
|
</a> |
659
|
|
|
</div> |
660
|
|
|
</div> |
661
|
|
|
</form> |
662
|
|
|
<?php |
663
|
|
|
|
664
|
|
|
break; |
665
|
|
|
|
666
|
|
|
case 'media-save': |
667
|
|
|
////////////////////////////////////////////////////////////////////////////// |
668
|
|
|
// Save an updated media object |
669
|
|
|
////////////////////////////////////////////////////////////////////////////// |
670
|
|
|
$xref = Filter::post('xref', WT_REGEX_XREF); |
671
|
|
|
$fact_id = Filter::post('fact_id'); |
672
|
|
|
$keep_chan = Filter::postBool('keep_chan'); |
673
|
|
|
$FILE = Filter::post('FILE'); |
674
|
|
|
$TITL = Filter::post('TITL'); |
675
|
|
|
$TYPE = Filter::post('TYPE'); |
676
|
|
|
|
677
|
|
|
$FILE = str_replace('\\', '/', $FILE); |
678
|
|
|
|
679
|
|
|
$record = GedcomRecord::getInstance($xref, $controller->tree()); |
680
|
|
|
check_record_access($record); |
681
|
|
|
|
682
|
|
|
// Find the fact to edit |
683
|
|
|
$edit_fact = null; |
684
|
|
|
foreach ($record->getFacts() as $fact) { |
685
|
|
|
if ($fact->getFactId() === $fact_id && $fact->canEdit()) { |
686
|
|
|
$edit_fact = $fact; |
687
|
|
|
break; |
688
|
|
|
} |
689
|
|
|
} |
690
|
|
|
if ($edit_fact === null) { |
691
|
|
|
header('Location: ' . $record->getRawUrl()); |
692
|
|
|
break; |
693
|
|
|
} |
694
|
|
|
|
695
|
|
|
// Find the old filename. If this has changed, we need to move it. |
696
|
|
|
// Other systems generate various structures for media objects... |
697
|
|
|
// Extract them from wherever they might be |
698
|
|
|
if (preg_match('/^\d FILE (.+)/m', $edit_fact->getGedcom(), $match)) { |
699
|
|
|
$OLD_FILE = $match[1]; |
700
|
|
|
} else { |
701
|
|
|
header('Location: ' . $record->getRawUrl()); |
702
|
|
|
break; |
703
|
|
|
} |
704
|
|
|
|
705
|
|
|
$FORM = strtolower(pathinfo($FILE, PATHINFO_EXTENSION)); |
706
|
|
|
$FORM = strtr($FORM, ['jpg' => 'jpeg']); |
707
|
|
|
|
708
|
|
|
$gedcom = '1 FILE ' . $FILE . "\n2 FORM " . $FORM; |
709
|
|
|
if ($TYPE !== '') { |
710
|
|
|
$gedcom .= "\n3 TYPE " . $TYPE; |
711
|
|
|
} |
712
|
|
|
if ($TITL !== '') { |
713
|
|
|
$gedcom .= "\n2 TITL " . $TITL; |
714
|
|
|
} |
715
|
|
|
|
716
|
|
|
$old_server_file = $record->getServerFilename('main'); |
|
|
|
|
717
|
|
|
$old_server_thumb = $record->getServerFilename('thumb'); |
|
|
|
|
718
|
|
|
$old_external = $record->isExternal(); |
|
|
|
|
719
|
|
|
|
720
|
|
|
// Replacement files? |
721
|
|
|
if (!empty($_FILES['file']) && is_uploaded_file($_FILES['file']['tmp_name'])) { |
722
|
|
|
if (move_uploaded_file($_FILES['file']['tmp_name'], $old_server_file)) { |
723
|
|
|
File::delete($old_server_thumb); |
724
|
|
|
$old_external = false; |
725
|
|
|
} else { |
726
|
|
|
FlashMessages::addMessage( |
727
|
|
|
I18N::translate('There was an error uploading your file.') . |
728
|
|
|
'<br>' . |
729
|
|
|
Functions::fileUploadErrorText($_FILES['file']['error']) |
730
|
|
|
); |
731
|
|
|
} |
732
|
|
|
} |
733
|
|
|
|
734
|
|
|
$tmp_record = new Media('xxx', "0 @xxx@ OBJE\n1 FILE " . $FILE, null, $record->getTree()); |
735
|
|
|
|
736
|
|
|
$new_server_file = $tmp_record->getServerFilename('main'); |
|
|
|
|
737
|
|
|
$new_external = $tmp_record->isExternal(); |
|
|
|
|
738
|
|
|
|
739
|
|
|
// External URLs cannot be renamed to local files, and vice versa. |
740
|
|
View Code Duplication |
if ($old_external !== $new_external) { |
741
|
|
|
FlashMessages::addMessage(I18N::translate('This file is linked to another family tree on this server. It cannot be deleted, moved, or renamed until these links have been removed.'), 'danger'); |
742
|
|
|
|
743
|
|
|
header('Location: ' . $record->getRawUrl()); |
744
|
|
|
break; |
745
|
|
|
} |
746
|
|
|
|
747
|
|
|
if (!$record->isExternal() && strpos($FILE, '../') !== false) { |
|
|
|
|
748
|
|
|
FlashMessages::addMessage('Folder names are not allowed to include “../”', 'danger'); |
749
|
|
|
|
750
|
|
|
header('Location: ' . $record->getRawUrl()); |
751
|
|
|
break; |
752
|
|
|
} |
753
|
|
|
|
754
|
|
|
if (!$record->isExternal() && FunctionsDb::isMediaUsedInOtherTree($record->getFilename(), $record->getTree()->getTreeId())) { |
|
|
|
|
755
|
|
|
FlashMessages::addMessage(I18N::translate('This file is linked to another family tree on this server. It cannot be deleted, moved, or renamed until these links have been removed.'), 'danger'); |
756
|
|
|
|
757
|
|
|
header('Location: ' . $record->getRawUrl()); |
758
|
|
|
break; |
759
|
|
|
} |
760
|
|
|
|
761
|
|
|
// If we have renamed a local file, then also move the files on disk (if we can). |
762
|
|
|
if ($OLD_FILE !== $FILE) { |
763
|
|
|
// Managers can create new media paths (subfolders). Users must use existing folders. |
764
|
|
|
foreach ([dirname($new_server_file)] as $dir) { |
765
|
|
|
if (!is_dir($dir)) { |
766
|
|
|
if (Auth::isManager($record->getTree()) && File::mkdir($dir)) { |
767
|
|
|
FlashMessages::addMessage(I18N::translate('The folder %s has been created.', Html::filename($dir)), 'info'); |
768
|
|
View Code Duplication |
} else { |
769
|
|
|
FlashMessages::addMessage(I18N::translate('The folder %s does not exist, and it could not be created.', Html::filename($dir)), 'danger'); |
770
|
|
|
|
771
|
|
|
header('Location: ' . $record->getRawUrl()); |
772
|
|
|
} |
773
|
|
|
} |
774
|
|
|
} |
775
|
|
|
|
776
|
|
|
if (!file_exists($old_server_file)) { |
777
|
|
|
FlashMessages::addMessage(I18N::translate('The media file %s does not exist.', Html::filename($OLD_FILE)), 'warning'); |
778
|
|
|
} |
779
|
|
|
if (!file_exists($new_server_file) || sha1_file($old_server_file) === sha1_file($new_server_file)) { |
780
|
|
|
try { |
781
|
|
|
rename($old_server_file, $new_server_file); |
782
|
|
|
FlashMessages::addMessage(I18N::translate('The media file %1$s has been renamed to %2$s.', Html::filename($OLD_FILE), Html::filename($FILE)), 'info'); |
783
|
|
|
} catch (ErrorException $ex) { |
784
|
|
|
DebugBar::addThrowable($ex); |
|
|
|
|
785
|
|
|
|
786
|
|
|
FlashMessages::addMessage(I18N::translate('The media file %1$s could not be renamed to %2$s.', Html::filename($OLD_FILE), Html::filename($FILE)), 'danger'); |
787
|
|
|
} |
788
|
|
|
} |
789
|
|
|
if (!file_exists($new_server_file)) { |
790
|
|
|
FlashMessages::addMessage(I18N::translate('The media file %s does not exist.', Html::filename($FILE)), 'warning'); |
791
|
|
|
} |
792
|
|
|
} |
793
|
|
|
|
794
|
|
|
$record->updateFact($fact_id, $gedcom, !$keep_chan); |
795
|
|
|
|
796
|
|
|
if ($OLD_FILE !== $FILE) { |
797
|
|
|
// Accept the change, to avoid breaking links, etc. |
798
|
|
|
FunctionsImport::acceptAllChanges($record->getXref(), $record->getTree()->getTreeId()); |
799
|
|
|
} |
800
|
|
|
|
801
|
|
|
header('Location: ' . $record->getRawUrl()); |
802
|
|
|
break; |
803
|
|
|
|
804
|
|
|
case 'add_child_to_family': |
805
|
|
|
////////////////////////////////////////////////////////////////////////////// |
806
|
|
|
// Add a child to an existing family |
807
|
|
|
////////////////////////////////////////////////////////////////////////////// |
808
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
809
|
|
|
$gender = Filter::get('gender', '[MFU]', 'U'); |
810
|
|
|
|
811
|
|
|
$family = Family::getInstance($xref, $controller->tree()); |
812
|
|
|
check_record_access($family); |
813
|
|
|
|
814
|
|
|
$controller |
815
|
|
|
->setPageTitle($family->getFullName() . ' - ' . I18N::translate('Add a child')) |
816
|
|
|
->pageHeader(); |
817
|
|
|
|
818
|
|
|
print_indi_form('add_child_to_family_action', null, $family, null, 'CHIL', $gender); |
819
|
|
|
break; |
820
|
|
|
|
821
|
|
|
case 'add_child_to_family_action': |
822
|
|
|
////////////////////////////////////////////////////////////////////////////// |
823
|
|
|
// Add a child to an existing family |
824
|
|
|
////////////////////////////////////////////////////////////////////////////// |
825
|
|
|
$xref = Filter::post('xref', WT_REGEX_XREF); |
826
|
|
|
$PEDI = Filter::post('PEDI'); |
827
|
|
|
$keep_chan = Filter::postBool('keep_chan'); |
828
|
|
|
$glevels = Filter::postArray('glevels', '[0-9]'); |
829
|
|
|
$tag = Filter::postArray('tag', WT_REGEX_TAG); |
830
|
|
|
$text = Filter::postArray('text'); |
831
|
|
|
$islink = Filter::postArray('islink', '[01]'); |
832
|
|
|
|
833
|
|
View Code Duplication |
if (!Filter::checkCsrf()) { |
834
|
|
|
$gender = Filter::get('gender', '[MFU]', 'U'); |
835
|
|
|
header('Location: edit_interface.php?action=add_child_to_family&xref=' . $xref . '&gender=' . $gender); |
836
|
|
|
break; |
837
|
|
|
} |
838
|
|
|
|
839
|
|
|
$family = Family::getInstance($xref, $controller->tree()); |
840
|
|
|
check_record_access($family); |
841
|
|
|
|
842
|
|
|
FunctionsEdit::splitSource(); |
843
|
|
|
$gedrec = '0 @REF@ INDI'; |
844
|
|
|
$gedrec .= FunctionsEdit::addNewName(); |
845
|
|
|
$gedrec .= FunctionsEdit::addNewSex(); |
846
|
|
View Code Duplication |
if (preg_match_all('/([A-Z0-9_]+)/', $controller->tree()->getPreference('QUICK_REQUIRED_FACTS'), $matches)) { |
847
|
|
|
foreach ($matches[1] as $match) { |
848
|
|
|
$gedrec .= FunctionsEdit::addNewFact($match); |
849
|
|
|
} |
850
|
|
|
} |
851
|
|
|
$gedrec .= "\n" . GedcomCodePedi::createNewFamcPedi($PEDI, $xref); |
852
|
|
|
if (Filter::postBool('SOUR_INDI')) { |
853
|
|
|
$gedrec = FunctionsEdit::handleUpdates($gedrec); |
854
|
|
|
} else { |
855
|
|
|
$gedrec = FunctionsEdit::updateRest($gedrec); |
856
|
|
|
} |
857
|
|
|
|
858
|
|
|
// Create the new child |
859
|
|
|
$new_child = $family->getTree()->createRecord($gedrec); |
860
|
|
|
|
861
|
|
|
// Insert new child at the right place |
862
|
|
|
$done = false; |
863
|
|
|
foreach ($family->getFacts('CHIL') as $fact) { |
864
|
|
|
$old_child = $fact->getTarget(); |
865
|
|
|
if ($old_child && Date::compare($new_child->getEstimatedBirthDate(), $old_child->getEstimatedBirthDate()) < 0) { |
866
|
|
|
// Insert before this child |
867
|
|
|
$family->updateFact($fact->getFactId(), '1 CHIL @' . $new_child->getXref() . "@\n" . $fact->getGedcom(), !$keep_chan); |
868
|
|
|
$done = true; |
869
|
|
|
break; |
870
|
|
|
} |
871
|
|
|
} |
872
|
|
|
if (!$done) { |
873
|
|
|
// Append child at end |
874
|
|
|
$family->createFact('1 CHIL @' . $new_child->getXref() . '@', !$keep_chan); |
875
|
|
|
} |
876
|
|
|
|
877
|
|
View Code Duplication |
if (Filter::post('goto') === 'new') { |
878
|
|
|
header('Location: ' . $new_child->getRawUrl()); |
879
|
|
|
} else { |
880
|
|
|
header('Location: ' . $family->getRawUrl()); |
881
|
|
|
} |
882
|
|
|
break; |
883
|
|
|
|
884
|
|
View Code Duplication |
case 'add_child_to_individual': |
885
|
|
|
////////////////////////////////////////////////////////////////////////////// |
886
|
|
|
// Add a child to an existing individual (creating a one-parent family) |
887
|
|
|
////////////////////////////////////////////////////////////////////////////// |
888
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
889
|
|
|
|
890
|
|
|
$person = Individual::getInstance($xref, $controller->tree()); |
891
|
|
|
check_record_access($person); |
892
|
|
|
|
893
|
|
|
$controller |
894
|
|
|
->setPageTitle($person->getFullName() . ' - ' . I18N::translate('Add a child to create a one-parent family')) |
895
|
|
|
->pageHeader(); |
896
|
|
|
|
897
|
|
|
print_indi_form('add_child_to_individual_action', $person, null, null, 'CHIL', 'U'); |
898
|
|
|
break; |
899
|
|
|
|
900
|
|
|
case 'add_child_to_individual_action': |
901
|
|
|
////////////////////////////////////////////////////////////////////////////// |
902
|
|
|
// Add a child to an existing individual (creating a one-parent family) |
903
|
|
|
////////////////////////////////////////////////////////////////////////////// |
904
|
|
|
$xref = Filter::post('xref', WT_REGEX_XREF); |
905
|
|
|
$PEDI = Filter::post('PEDI'); |
906
|
|
|
$glevels = Filter::postArray('glevels', '[0-9]'); |
907
|
|
|
$tag = Filter::postArray('tag', WT_REGEX_TAG); |
908
|
|
|
$text = Filter::postArray('text'); |
909
|
|
|
$islink = Filter::postArray('islink', '[01]'); |
910
|
|
|
|
911
|
|
|
if (!Filter::checkCsrf()) { |
912
|
|
|
header('Location: edit_interface.php?action=add_child_to_individual&xref=' . $xref); |
913
|
|
|
break; |
914
|
|
|
} |
915
|
|
|
|
916
|
|
|
$person = Individual::getInstance($xref, $controller->tree()); |
917
|
|
|
check_record_access($person); |
918
|
|
|
|
919
|
|
|
// Create a family |
920
|
|
|
if ($person->getSex() === 'F') { |
921
|
|
|
$gedcom = "0 @NEW@ FAM\n1 WIFE @" . $person->getXref() . '@'; |
922
|
|
|
} else { |
923
|
|
|
$gedcom = "0 @NEW@ FAM\n1 HUSB @" . $person->getXref() . '@'; |
924
|
|
|
} |
925
|
|
|
$family = $person->getTree()->createRecord($gedcom); |
926
|
|
|
|
927
|
|
|
// Link the parent to the family |
928
|
|
|
$person->createFact('1 FAMS @' . $family->getXref() . '@', true); |
929
|
|
|
|
930
|
|
|
// Create a child |
931
|
|
|
FunctionsEdit::splitSource(); // separate SOUR record from the rest |
932
|
|
|
|
933
|
|
|
$gedcom = '0 @NEW@ INDI'; |
934
|
|
|
$gedcom .= FunctionsEdit::addNewName(); |
935
|
|
|
$gedcom .= FunctionsEdit::addNewSex(); |
936
|
|
|
$gedcom .= "\n" . GedcomCodePedi::createNewFamcPedi($PEDI, $family->getXref()); |
937
|
|
View Code Duplication |
if (preg_match_all('/([A-Z0-9_]+)/', $controller->tree()->getPreference('QUICK_REQUIRED_FACTS'), $matches)) { |
938
|
|
|
foreach ($matches[1] as $match) { |
939
|
|
|
$gedcom .= FunctionsEdit::addNewFact($match); |
940
|
|
|
} |
941
|
|
|
} |
942
|
|
|
if (Filter::postBool('SOUR_INDI')) { |
943
|
|
|
$gedcom = FunctionsEdit::handleUpdates($gedcom); |
944
|
|
|
} else { |
945
|
|
|
$gedcom = FunctionsEdit::updateRest($gedcom); |
946
|
|
|
} |
947
|
|
|
|
948
|
|
|
$child = $person->getTree()->createRecord($gedcom); |
949
|
|
|
|
950
|
|
|
// Link the family to the child |
951
|
|
|
$family->createFact('1 CHIL @' . $child->getXref() . '@', true); |
952
|
|
|
|
953
|
|
View Code Duplication |
if (Filter::post('goto') === 'new') { |
954
|
|
|
header('Location: ' . $child->getRawUrl()); |
955
|
|
|
} else { |
956
|
|
|
header('Location: ' . $person->getRawUrl()); |
957
|
|
|
} |
958
|
|
|
break; |
959
|
|
|
|
960
|
|
View Code Duplication |
case 'add_parent_to_individual': |
961
|
|
|
////////////////////////////////////////////////////////////////////////////// |
962
|
|
|
// Add a new parent to an existing individual (creating a one-parent family) |
963
|
|
|
////////////////////////////////////////////////////////////////////////////// |
964
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
965
|
|
|
$gender = Filter::get('gender', '[MF]', 'U'); |
966
|
|
|
|
967
|
|
|
$individual = Individual::getInstance($xref, $controller->tree()); |
968
|
|
|
check_record_access($individual); |
969
|
|
|
|
970
|
|
|
if ($gender === 'F') { |
971
|
|
|
$controller->setPageTitle(I18N::translate('Add a mother')); |
972
|
|
|
$famtag = 'WIFE'; |
973
|
|
|
} else { |
974
|
|
|
$controller->setPageTitle(I18N::translate('Add a father')); |
975
|
|
|
$famtag = 'HUSB'; |
976
|
|
|
} |
977
|
|
|
$controller->pageHeader(); |
978
|
|
|
|
979
|
|
|
print_indi_form('add_parent_to_individual_action', $individual, null, null, $famtag, $gender); |
980
|
|
|
break; |
981
|
|
|
|
982
|
|
|
case 'add_parent_to_individual_action': |
983
|
|
|
////////////////////////////////////////////////////////////////////////////// |
984
|
|
|
// Add a new parent to an existing individual (creating a one-parent family) |
985
|
|
|
////////////////////////////////////////////////////////////////////////////// |
986
|
|
|
$xref = Filter::post('xref', WT_REGEX_XREF); |
987
|
|
|
$PEDI = Filter::post('PEDI'); |
988
|
|
|
$glevels = Filter::postArray('glevels', '[0-9]'); |
989
|
|
|
$tag = Filter::postArray('tag', WT_REGEX_TAG); |
990
|
|
|
$text = Filter::postArray('text'); |
991
|
|
|
$islink = Filter::postArray('islink', '[01]'); |
992
|
|
|
|
993
|
|
View Code Duplication |
if (!Filter::checkCsrf()) { |
994
|
|
|
$gender = Filter::get('gender', '[MFU]', 'U'); |
995
|
|
|
header('Location: edit_interface.php?action=add_parent_to_individual&xref=' . $xref . '&gender=' . $gender); |
996
|
|
|
break; |
997
|
|
|
} |
998
|
|
|
|
999
|
|
|
$person = Individual::getInstance($xref, $controller->tree()); |
1000
|
|
|
check_record_access($person); |
1001
|
|
|
|
1002
|
|
|
// Create a new family |
1003
|
|
|
$gedcom = "0 @NEW@ FAM\n1 CHIL @" . $person->getXref() . '@'; |
1004
|
|
|
$family = $person->getTree()->createRecord($gedcom); |
1005
|
|
|
|
1006
|
|
|
// Link the child to the family |
1007
|
|
|
$person->createFact('1 FAMC @' . $family->getXref() . '@', true); |
1008
|
|
|
|
1009
|
|
|
// Create a child |
1010
|
|
|
FunctionsEdit::splitSource(); // separate SOUR record from the rest |
1011
|
|
|
|
1012
|
|
|
$gedcom = '0 @NEW@ INDI'; |
1013
|
|
|
$gedcom .= FunctionsEdit::addNewName(); |
1014
|
|
|
$gedcom .= FunctionsEdit::addNewSex(); |
1015
|
|
View Code Duplication |
if (preg_match_all('/([A-Z0-9_]+)/', $controller->tree()->getPreference('QUICK_REQUIRED_FACTS'), $matches)) { |
1016
|
|
|
foreach ($matches[1] as $match) { |
1017
|
|
|
$gedcom .= FunctionsEdit::addNewFact($match); |
1018
|
|
|
} |
1019
|
|
|
} |
1020
|
|
|
if (Filter::postBool('SOUR_INDI')) { |
1021
|
|
|
$gedcom = FunctionsEdit::handleUpdates($gedcom); |
1022
|
|
|
} else { |
1023
|
|
|
$gedcom = FunctionsEdit::updateRest($gedcom); |
1024
|
|
|
} |
1025
|
|
|
$gedcom .= "\n1 FAMS @" . $family->getXref() . '@'; |
1026
|
|
|
|
1027
|
|
|
$parent = $person->getTree()->createRecord($gedcom); |
1028
|
|
|
|
1029
|
|
|
// Link the family to the child |
1030
|
|
|
if ($parent->getSex() === 'F') { |
1031
|
|
|
$family->createFact('1 WIFE @' . $parent->getXref() . '@', true); |
1032
|
|
|
} else { |
1033
|
|
|
$family->createFact('1 HUSB @' . $parent->getXref() . '@', true); |
1034
|
|
|
} |
1035
|
|
|
|
1036
|
|
View Code Duplication |
if (Filter::post('goto') === 'new') { |
1037
|
|
|
header('Location: ' . $parent->getRawUrl()); |
1038
|
|
|
} else { |
1039
|
|
|
header('Location: ' . $person->getRawUrl()); |
1040
|
|
|
} |
1041
|
|
|
break; |
1042
|
|
|
|
1043
|
|
|
case 'add_unlinked_indi': |
1044
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1045
|
|
|
// Add a new, unlinked individual |
1046
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1047
|
|
|
$controller |
1048
|
|
|
->restrictAccess(Auth::isManager($controller->tree())) |
1049
|
|
|
->setPageTitle(I18N::translate('Create an individual')) |
1050
|
|
|
->pageHeader(); |
1051
|
|
|
|
1052
|
|
|
print_indi_form('add_unlinked_indi_action', null, null, null, null, null); |
1053
|
|
|
break; |
1054
|
|
|
|
1055
|
|
|
case 'add_unlinked_indi_action': |
1056
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1057
|
|
|
// Add a new, unlinked individual |
1058
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1059
|
|
|
$glevels = Filter::postArray('glevels', '[0-9]'); |
1060
|
|
|
$tag = Filter::postArray('tag', WT_REGEX_TAG); |
1061
|
|
|
$text = Filter::postArray('text'); |
1062
|
|
|
$islink = Filter::postArray('islink', '[01]'); |
1063
|
|
|
|
1064
|
|
|
if (!Filter::checkCsrf()) { |
1065
|
|
|
header('Location: edit_interface.php?action=add_unlinked_indi'); |
1066
|
|
|
break; |
1067
|
|
|
} |
1068
|
|
|
|
1069
|
|
|
$controller->restrictAccess(Auth::isManager($controller->tree())); |
1070
|
|
|
|
1071
|
|
|
FunctionsEdit::splitSource(); |
1072
|
|
|
$gedrec = '0 @REF@ INDI'; |
1073
|
|
|
$gedrec .= FunctionsEdit::addNewName(); |
1074
|
|
|
$gedrec .= FunctionsEdit::addNewSex(); |
1075
|
|
View Code Duplication |
if (preg_match_all('/([A-Z0-9_]+)/', $controller->tree()->getPreference('QUICK_REQUIRED_FACTS'), $matches)) { |
1076
|
|
|
foreach ($matches[1] as $match) { |
1077
|
|
|
$gedrec .= FunctionsEdit::addNewFact($match); |
1078
|
|
|
} |
1079
|
|
|
} |
1080
|
|
|
if (Filter::postBool('SOUR_INDI')) { |
1081
|
|
|
$gedrec = FunctionsEdit::handleUpdates($gedrec); |
1082
|
|
|
} else { |
1083
|
|
|
$gedrec = FunctionsEdit::updateRest($gedrec); |
1084
|
|
|
} |
1085
|
|
|
|
1086
|
|
|
$new_indi = $controller->tree()->createRecord($gedrec); |
1087
|
|
|
|
1088
|
|
|
if (Filter::post('goto') === 'new') { |
1089
|
|
|
header('Location: ' . $new_indi->getRawUrl()); |
1090
|
|
|
} else { |
1091
|
|
|
header('Location: admin_trees_manage.php'); |
1092
|
|
|
} |
1093
|
|
|
break; |
1094
|
|
|
|
1095
|
|
View Code Duplication |
case 'add_spouse_to_individual': |
1096
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1097
|
|
|
// Add a spouse to an existing individual (creating a new family) |
1098
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1099
|
|
|
$sex = Filter::get('sex', 'M|F', 'F'); |
1100
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
1101
|
|
|
|
1102
|
|
|
$individual = Individual::getInstance($xref, $controller->tree()); |
1103
|
|
|
check_record_access($individual); |
1104
|
|
|
|
1105
|
|
|
if ($sex === 'F') { |
1106
|
|
|
$controller->setPageTitle(I18N::translate('Add a wife')); |
1107
|
|
|
$famtag = 'WIFE'; |
1108
|
|
|
} else { |
1109
|
|
|
$controller->setPageTitle(I18N::translate('Add a husband')); |
1110
|
|
|
$famtag = 'HUSB'; |
1111
|
|
|
} |
1112
|
|
|
$controller->pageHeader(); |
1113
|
|
|
|
1114
|
|
|
print_indi_form('add_spouse_to_individual_action', $individual, null, null, $famtag, $sex); |
1115
|
|
|
break; |
1116
|
|
|
|
1117
|
|
|
case 'add_spouse_to_individual_action': |
1118
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1119
|
|
|
// Add a spouse to an existing individual (creating a new family) |
1120
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1121
|
|
|
$xref = Filter::post('xref'); // Add a spouse to this individual |
1122
|
|
|
$sex = Filter::post('SEX', '[MFU]', 'U'); |
1123
|
|
|
$glevels = Filter::postArray('glevels', '[0-9]'); |
1124
|
|
|
$tag = Filter::postArray('tag', WT_REGEX_TAG); |
1125
|
|
|
$text = Filter::postArray('text'); |
1126
|
|
|
$islink = Filter::postArray('islink', '[01]'); |
1127
|
|
|
|
1128
|
|
|
if (!Filter::checkCsrf()) { |
1129
|
|
|
header('Location: edit_interface.php?action=add_spouse_to_individual&xref=' . $xref . '&sex=' . $sex); |
1130
|
|
|
|
1131
|
|
|
break; |
1132
|
|
|
} |
1133
|
|
|
|
1134
|
|
|
$person = Individual::getInstance($xref, $controller->tree()); |
1135
|
|
|
check_record_access($person); |
1136
|
|
|
|
1137
|
|
|
FunctionsEdit::splitSource(); |
1138
|
|
|
$indi_gedcom = '0 @REF@ INDI'; |
1139
|
|
|
$indi_gedcom .= FunctionsEdit::addNewName(); |
1140
|
|
|
$indi_gedcom .= FunctionsEdit::addNewSex(); |
1141
|
|
View Code Duplication |
if (preg_match_all('/([A-Z0-9_]+)/', $controller->tree()->getPreference('QUICK_REQUIRED_FACTS'), $matches)) { |
1142
|
|
|
foreach ($matches[1] as $match) { |
1143
|
|
|
$indi_gedcom .= FunctionsEdit::addNewFact($match); |
1144
|
|
|
} |
1145
|
|
|
} |
1146
|
|
|
if (Filter::postBool('SOUR_INDI')) { |
1147
|
|
|
$indi_gedcom = FunctionsEdit::handleUpdates($indi_gedcom); |
1148
|
|
|
} else { |
1149
|
|
|
$indi_gedcom = FunctionsEdit::updateRest($indi_gedcom); |
1150
|
|
|
} |
1151
|
|
|
|
1152
|
|
|
$fam_gedcom = ''; |
1153
|
|
View Code Duplication |
if (preg_match_all('/([A-Z0-9_]+)/', $controller->tree()->getPreference('QUICK_REQUIRED_FAMFACTS'), $matches)) { |
1154
|
|
|
foreach ($matches[1] as $match) { |
1155
|
|
|
$fam_gedcom .= FunctionsEdit::addNewFact($match); |
1156
|
|
|
} |
1157
|
|
|
} |
1158
|
|
|
if (Filter::postBool('SOUR_FAM')) { |
1159
|
|
|
$fam_gedcom = FunctionsEdit::handleUpdates($fam_gedcom); |
1160
|
|
|
} else { |
1161
|
|
|
$fam_gedcom = FunctionsEdit::updateRest($fam_gedcom); |
1162
|
|
|
} |
1163
|
|
|
|
1164
|
|
|
// Create the new spouse |
1165
|
|
|
$spouse = $person->getTree()->createRecord($indi_gedcom); |
1166
|
|
|
// Create a new family |
1167
|
|
|
if ($sex === 'F') { |
1168
|
|
|
$family = $spouse->getTree()->createRecord("0 @NEW@ FAM\n1 WIFE @" . $spouse->getXref() . "@\n1 HUSB @" . $person->getXref() . '@' . $fam_gedcom); |
1169
|
|
|
} else { |
1170
|
|
|
$family = $spouse->getTree()->createRecord("0 @NEW@ FAM\n1 HUSB @" . $spouse->getXref() . "@\n1 WIFE @" . $person->getXref() . '@' . $fam_gedcom); |
1171
|
|
|
} |
1172
|
|
|
// Link the spouses to the family |
1173
|
|
|
$spouse->createFact('1 FAMS @' . $family->getXref() . '@', true); |
1174
|
|
|
$person->createFact('1 FAMS @' . $family->getXref() . '@', true); |
1175
|
|
|
|
1176
|
|
View Code Duplication |
if (Filter::post('goto') === 'new') { |
1177
|
|
|
header('Location: ' . $spouse->getRawUrl()); |
1178
|
|
|
} else { |
1179
|
|
|
header('Location: ' . $person->getRawUrl()); |
1180
|
|
|
} |
1181
|
|
|
break; |
1182
|
|
|
|
1183
|
|
View Code Duplication |
case 'add_spouse_to_family': |
1184
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1185
|
|
|
// Add a spouse to an existing family |
1186
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1187
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
1188
|
|
|
$famtag = Filter::get('famtag', 'HUSB|WIFE'); |
1189
|
|
|
|
1190
|
|
|
$family = Family::getInstance($xref, $controller->tree()); |
1191
|
|
|
check_record_access($family); |
1192
|
|
|
|
1193
|
|
|
if ($famtag === 'WIFE') { |
1194
|
|
|
$controller->setPageTitle(I18N::translate('Add a wife')); |
1195
|
|
|
$sex = 'F'; |
1196
|
|
|
} else { |
1197
|
|
|
$controller->setPageTitle(I18N::translate('Add a husband')); |
1198
|
|
|
$sex = 'M'; |
1199
|
|
|
} |
1200
|
|
|
$controller->pageHeader(); |
1201
|
|
|
|
1202
|
|
|
print_indi_form('add_spouse_to_family_action', null, $family, null, $famtag, $sex); |
1203
|
|
|
break; |
1204
|
|
|
|
1205
|
|
|
case 'add_spouse_to_family_action': |
1206
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1207
|
|
|
// Add a spouse to an existing family |
1208
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1209
|
|
|
$xref = Filter::post('xref', WT_REGEX_XREF); |
1210
|
|
|
$glevels = Filter::postArray('glevels', '[0-9]'); |
1211
|
|
|
$tag = Filter::postArray('tag', WT_REGEX_TAG); |
1212
|
|
|
$text = Filter::postArray('text'); |
1213
|
|
|
$islink = Filter::postArray('islink', '[01]'); |
1214
|
|
|
|
1215
|
|
|
$family = Family::getInstance($xref, $controller->tree()); |
1216
|
|
|
check_record_access($family); |
1217
|
|
|
|
1218
|
|
View Code Duplication |
if (!Filter::checkCsrf()) { |
1219
|
|
|
$famtag = Filter::get('famtag', 'HUSB|WIFE'); |
1220
|
|
|
header('Location: edit_interface.php?action=add_spouse_to_family&xref=' . $xref . '&famtag=' . $famtag); |
1221
|
|
|
|
1222
|
|
|
break; |
1223
|
|
|
} |
1224
|
|
|
|
1225
|
|
|
// Create the new spouse |
1226
|
|
|
FunctionsEdit::splitSource(); // separate SOUR record from the rest |
1227
|
|
|
|
1228
|
|
|
$gedrec = '0 @REF@ INDI'; |
1229
|
|
|
$gedrec .= FunctionsEdit::addNewName(); |
1230
|
|
|
$gedrec .= FunctionsEdit::addNewSex(); |
1231
|
|
View Code Duplication |
if (preg_match_all('/([A-Z0-9_]+)/', $controller->tree()->getPreference('QUICK_REQUIRED_FACTS'), $matches)) { |
1232
|
|
|
foreach ($matches[1] as $match) { |
1233
|
|
|
$gedrec .= FunctionsEdit::addNewFact($match); |
1234
|
|
|
} |
1235
|
|
|
} |
1236
|
|
|
|
1237
|
|
|
if (Filter::postBool('SOUR_INDI')) { |
1238
|
|
|
$gedrec = FunctionsEdit::handleUpdates($gedrec); |
1239
|
|
|
} else { |
1240
|
|
|
$gedrec = FunctionsEdit::updateRest($gedrec); |
1241
|
|
|
} |
1242
|
|
|
$gedrec .= "\n1 FAMS @" . $family->getXref() . '@'; |
1243
|
|
|
$spouse = $family->getTree()->createRecord($gedrec); |
1244
|
|
|
|
1245
|
|
|
// Update the existing family - add marriage, etc |
1246
|
|
|
if ($family->getFirstFact('HUSB')) { |
1247
|
|
|
$family->createFact('1 WIFE @' . $spouse->getXref() . '@', true); |
1248
|
|
|
} else { |
1249
|
|
|
$family->createFact('1 HUSB @' . $spouse->getXref() . '@', true); |
1250
|
|
|
} |
1251
|
|
|
$famrec = ''; |
1252
|
|
View Code Duplication |
if (preg_match_all('/([A-Z0-9_]+)/', $controller->tree()->getPreference('QUICK_REQUIRED_FAMFACTS'), $matches)) { |
1253
|
|
|
foreach ($matches[1] as $match) { |
1254
|
|
|
$famrec .= FunctionsEdit::addNewFact($match); |
1255
|
|
|
} |
1256
|
|
|
} |
1257
|
|
|
if (Filter::postBool('SOUR_FAM')) { |
1258
|
|
|
$famrec = FunctionsEdit::handleUpdates($famrec); |
1259
|
|
|
} else { |
1260
|
|
|
$famrec = FunctionsEdit::updateRest($famrec); |
1261
|
|
|
} |
1262
|
|
|
$family->createFact(trim($famrec), true); // trim leading \n |
1263
|
|
|
|
1264
|
|
View Code Duplication |
if (Filter::post('goto') === 'new') { |
1265
|
|
|
header('Location: ' . $spouse->getRawUrl()); |
1266
|
|
|
} else { |
1267
|
|
|
header('Location: ' . $family->getRawUrl()); |
1268
|
|
|
} |
1269
|
|
|
break; |
1270
|
|
|
|
1271
|
|
|
case 'addfamlink': |
1272
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1273
|
|
|
// Link an individual to an existing family, as a child |
1274
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1275
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
1276
|
|
|
|
1277
|
|
|
$person = Individual::getInstance($xref, $controller->tree()); |
1278
|
|
|
check_record_access($person); |
1279
|
|
|
|
1280
|
|
|
$controller |
1281
|
|
|
->setPageTitle($person->getFullName() . ' - ' . I18N::translate('Link this individual to an existing family as a child')) |
1282
|
|
|
->pageHeader(); |
1283
|
|
|
|
1284
|
|
|
?> |
1285
|
|
|
<h2><?= $controller->getPageTitle() ?></h2> |
1286
|
|
|
<form method="post" name="addchildform"> |
1287
|
|
|
<input type="hidden" name="ged" value="<?= $controller->tree()->getNameHtml() ?>"> |
1288
|
|
|
<input type="hidden" name="action" value="linkfamaction"> |
1289
|
|
|
<input type="hidden" name="xref" value="<?= $person->getXref() ?>"> |
|
|
|
|
1290
|
|
|
<?= Filter::getCsrf() ?> |
1291
|
|
|
|
1292
|
|
|
<div class="row form-group"> |
1293
|
|
|
<label class="col-sm-3 col-form-label" for="famid"> |
1294
|
|
|
<?= I18N::translate('Family') ?> |
1295
|
|
|
</label> |
1296
|
|
|
<div class="col-sm-9"> |
1297
|
|
|
<?= FunctionsEdit::formControlFamily(null, ['id' => 'famid', 'name' => 'famid']) ?> |
1298
|
|
|
</div> |
1299
|
|
|
</div> |
1300
|
|
|
|
1301
|
|
|
<div class="row form-group"> |
1302
|
|
|
<label class="col-sm-3 col-form-label" for="PEDI"> |
1303
|
|
|
<?= I18N::translate('Pedigree') ?> |
1304
|
|
|
</label> |
1305
|
|
|
<div class="col-sm-9"> |
1306
|
|
|
<?= Bootstrap4::select(GedcomCodePedi::getValues($person), '', ['id' => 'PEDI', 'name' => 'PEDI']) ?> |
1307
|
|
|
<p class="small text-muted"> |
1308
|
|
|
<?= I18N::translate('A child may have more than one set of parents. The relationship between the child and the parents can be biological, legal, or based on local culture and tradition. If no pedigree is specified, then a biological relationship will be assumed.') ?> |
1309
|
|
|
</p> |
1310
|
|
|
</div> |
1311
|
|
|
</div> |
1312
|
|
|
|
1313
|
|
|
<?= keep_chan($person) ?> |
1314
|
|
|
|
1315
|
|
|
<div class="row form-group"> |
1316
|
|
|
<div class="col-sm-9 offset-sm-3"> |
1317
|
|
|
<button class="btn btn-primary" type="submit"> |
1318
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
1319
|
|
|
<?= /* I18N: A button label. */ |
1320
|
|
|
I18N::translate('save') ?> |
1321
|
|
|
</button> |
1322
|
|
|
<a class="btn btn-secondary" href="<?= $person->getHtmlUrl() ?>"> |
1323
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
1324
|
|
|
<?= /* I18N: A button label. */ |
1325
|
|
|
I18N::translate('cancel') ?> |
1326
|
|
|
</a> |
1327
|
|
|
</div> |
1328
|
|
|
</div> |
1329
|
|
|
</form> |
1330
|
|
|
<?php |
1331
|
|
|
break; |
1332
|
|
|
|
1333
|
|
|
case 'linkfamaction': |
1334
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1335
|
|
|
// Link an individual to an existing family, as a child |
1336
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1337
|
|
|
$xref = Filter::post('xref', WT_REGEX_XREF); |
1338
|
|
|
$famid = Filter::post('famid', WT_REGEX_XREF); |
1339
|
|
|
$PEDI = Filter::post('PEDI'); |
1340
|
|
|
|
1341
|
|
|
if (!Filter::checkCsrf()) { |
1342
|
|
|
header('Location: edit_interface.php?action=addfamlink&xref=' . $xref); |
1343
|
|
|
break; |
1344
|
|
|
} |
1345
|
|
|
|
1346
|
|
|
$person = Individual::getInstance($xref, $controller->tree()); |
1347
|
|
|
$family = Family::getInstance($famid, $controller->tree()); |
1348
|
|
|
check_record_access($person); |
1349
|
|
|
check_record_access($family); |
1350
|
|
|
|
1351
|
|
|
// Replace any existing child->family link (we may be changing the PEDI); |
1352
|
|
|
$fact_id = null; |
1353
|
|
|
foreach ($person->getFacts('FAMC') as $fact) { |
1354
|
|
|
if ($family === $fact->getTarget()) { |
1355
|
|
|
$fact_id = $fact->getFactId(); |
1356
|
|
|
break; |
1357
|
|
|
} |
1358
|
|
|
} |
1359
|
|
|
|
1360
|
|
|
$gedcom = GedcomCodePedi::createNewFamcPedi($PEDI, $famid); |
1361
|
|
|
$person->updateFact($fact_id, $gedcom, true); |
1362
|
|
|
|
1363
|
|
|
// Only set the family->child link if it does not already exist |
1364
|
|
|
$edit_fact = null; |
1365
|
|
|
foreach ($family->getFacts('CHIL') as $fact) { |
1366
|
|
|
if ($person === $fact->getTarget()) { |
1367
|
|
|
$edit_fact = $fact; |
1368
|
|
|
break; |
1369
|
|
|
} |
1370
|
|
|
} |
1371
|
|
|
if (!$edit_fact) { |
1372
|
|
|
$family->createFact('1 CHIL @' . $person->getXref() . '@', true); |
1373
|
|
|
} |
1374
|
|
|
|
1375
|
|
|
header('Location: ' . $person->getRawUrl()); |
1376
|
|
|
break; |
1377
|
|
|
|
1378
|
|
|
case 'linkspouse': |
1379
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1380
|
|
|
// Link and individual to an existing individual as a spouse |
1381
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1382
|
|
|
$famtag = Filter::get('famtag', 'HUSB|WIFE'); |
1383
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
1384
|
|
|
|
1385
|
|
|
$person = Individual::getInstance($xref, $controller->tree()); |
1386
|
|
|
check_record_access($person); |
1387
|
|
|
|
1388
|
|
|
if ($person->getSex() === 'F') { |
1389
|
|
|
$controller->setPageTitle($person->getFullName() . ' - ' . I18N::translate('Add a husband using an existing individual')); |
1390
|
|
|
$label = I18N::translate('Husband'); |
1391
|
|
|
} else { |
1392
|
|
|
$controller->setPageTitle($person->getFullName() . ' - ' . I18N::translate('Add a wife using an existing individual')); |
1393
|
|
|
$label = I18N::translate('Wife'); |
1394
|
|
|
} |
1395
|
|
|
|
1396
|
|
|
$controller->pageHeader(); |
1397
|
|
|
FunctionsPrint::initializeCalendarPopup(); |
1398
|
|
|
|
1399
|
|
|
?> |
1400
|
|
|
<h2><?= $controller->getPageTitle() ?></h2> |
1401
|
|
|
|
1402
|
|
|
<form method="post" name="addchildform"> |
1403
|
|
|
<input type="hidden" name="ged" value="<?= $controller->tree()->getNameHtml() ?>"> |
1404
|
|
|
<input type="hidden" name="action" value="linkspouseaction"> |
1405
|
|
|
<input type="hidden" name="xref" value="<?= $person->getXref() ?>"> |
|
|
|
|
1406
|
|
|
<input type="hidden" name="famtag" value="<?= $famtag ?>"> |
1407
|
|
|
<?= Filter::getCsrf() ?> |
1408
|
|
|
<div class="form-group row"> |
1409
|
|
|
<label class="col-sm-3 col-form-label" for="spouse"> |
1410
|
|
|
<?= $label ?> |
1411
|
|
|
</label> |
1412
|
|
|
<div class="col-sm-9"> |
1413
|
|
|
<?= FunctionsEdit::formControlIndividual(null, ['id' => 'spouse', 'name' => 'spid']) ?> |
1414
|
|
|
</div> |
1415
|
|
|
</div> |
1416
|
|
|
|
1417
|
|
|
<?= FunctionsEdit::addSimpleTag('0 MARR Y') ?> |
1418
|
|
|
<?= FunctionsEdit::addSimpleTag('0 DATE', 'MARR') ?> |
1419
|
|
|
<?= FunctionsEdit::addSimpleTag('0 PLAC', 'MARR') ?> |
1420
|
|
|
|
1421
|
|
|
<div class="row form-group"> |
1422
|
|
|
<div class="col-sm-9 offset-sm-3"> |
1423
|
|
|
<button class="btn btn-primary" type="submit"> |
1424
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
1425
|
|
|
<?= /* I18N: A button label. */ I18N::translate('save') ?> |
1426
|
|
|
</button> |
1427
|
|
|
<a class="btn btn-secondary" href="<?= $person->getHtmlUrl() ?>"> |
1428
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
1429
|
|
|
<?= /* I18N: A button label. */ I18N::translate('cancel') ?> |
1430
|
|
|
</a> |
1431
|
|
|
</div> |
1432
|
|
|
</div> |
1433
|
|
|
</form> |
1434
|
|
|
<?php |
1435
|
|
|
break; |
1436
|
|
|
|
1437
|
|
|
case 'linkspouseaction': |
1438
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1439
|
|
|
// Link and individual to an existing individual as a spouse |
1440
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1441
|
|
|
$xref = Filter::post('xref', WT_REGEX_XREF); |
1442
|
|
|
$spid = Filter::post('spid', WT_REGEX_XREF); |
1443
|
|
|
$famtag = Filter::post('famtag', 'HUSB|WIFE'); |
1444
|
|
|
$glevels = Filter::postArray('glevels', '[0-9]'); |
1445
|
|
|
$tag = Filter::postArray('tag', WT_REGEX_TAG); |
1446
|
|
|
$text = Filter::postArray('text'); |
1447
|
|
|
$islink = Filter::postArray('islink', '[01]'); |
1448
|
|
|
|
1449
|
|
View Code Duplication |
if (!Filter::checkCsrf()) { |
1450
|
|
|
$famtag = Filter::get('famtag', 'HUSB|WIFE'); |
1451
|
|
|
header('Location: edit_interface.php?action=linkspouse&xref=' . $xref . '&famtag=' . $famtag); |
1452
|
|
|
|
1453
|
|
|
break; |
1454
|
|
|
} |
1455
|
|
|
|
1456
|
|
|
$person = Individual::getInstance($xref, $controller->tree()); |
1457
|
|
|
$spouse = Individual::getInstance($spid, $controller->tree()); |
1458
|
|
|
check_record_access($person); |
1459
|
|
|
check_record_access($spouse); |
1460
|
|
|
|
1461
|
|
|
if ($person->getSex() === 'F') { |
1462
|
|
|
$controller->setPageTitle($person->getFullName() . ' - ' . I18N::translate('Add a husband using an existing individual')); |
1463
|
|
|
} else { |
1464
|
|
|
$controller->setPageTitle($person->getFullName() . ' - ' . I18N::translate('Add a wife using an existing individual')); |
1465
|
|
|
} |
1466
|
|
|
|
1467
|
|
|
if ($person->getSex() === 'M') { |
1468
|
|
|
$gedcom = "0 @new@ FAM\n1 HUSB @" . $person->getXref() . "@\n1 WIFE @" . $spouse->getXref() . '@'; |
1469
|
|
|
} else { |
1470
|
|
|
$gedcom = "0 @new@ FAM\n1 HUSB @" . $spouse->getXref() . "@\n1 WIFE @" . $person->getXref() . '@'; |
1471
|
|
|
} |
1472
|
|
|
FunctionsEdit::splitSource(); |
1473
|
|
|
$gedcom .= FunctionsEdit::addNewFact('MARR'); |
1474
|
|
|
|
1475
|
|
|
if (Filter::postBool('SOUR_FAM') || count($tagSOUR) > 0) { |
1476
|
|
|
// before adding 2 SOUR it needs to add 1 MARR Y first |
1477
|
|
|
if (FunctionsEdit::addNewFact('MARR') === '') { |
1478
|
|
|
$gedcom .= "\n1 MARR Y"; |
1479
|
|
|
} |
1480
|
|
|
$gedcom = FunctionsEdit::handleUpdates($gedcom); |
1481
|
|
|
} else { |
1482
|
|
|
// before adding level 2 facts it needs to add 1 MARR Y first |
1483
|
|
|
if (FunctionsEdit::addNewFact('MARR') === '') { |
1484
|
|
|
$gedcom .= "\n1 MARR Y"; |
1485
|
|
|
} |
1486
|
|
|
$gedcom = FunctionsEdit::updateRest($gedcom); |
1487
|
|
|
} |
1488
|
|
|
|
1489
|
|
|
$family = $person->getTree()->createRecord($gedcom); |
1490
|
|
|
$person->createFact('1 FAMS @' . $family->getXref() . '@', true); |
1491
|
|
|
$spouse->createFact('1 FAMS @' . $family->getXref() . '@', true); |
1492
|
|
|
|
1493
|
|
|
header('Location: ' . $person->getRawUrl()); |
1494
|
|
|
break; |
1495
|
|
|
|
1496
|
|
|
case 'addnewsource': |
1497
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1498
|
|
|
// Create a new source record |
1499
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1500
|
|
|
$controller |
1501
|
|
|
->setPageTitle(I18N::translate('Create a source')) |
1502
|
|
|
->pageHeader(); |
1503
|
|
|
|
1504
|
|
|
?> |
1505
|
|
|
<h2><?= $controller->getPageTitle() ?></h2> |
1506
|
|
|
<form method="post"> |
1507
|
|
|
<input type="hidden" name="ged" value="<?= $controller->tree()->getNameHtml() ?>"> |
1508
|
|
|
<input type="hidden" name="action" value="addsourceaction"> |
1509
|
|
|
<?= Filter::getCsrf() ?> |
1510
|
|
|
<table class="table wt-facts-table"> |
1511
|
|
|
<tr> |
1512
|
|
|
<th scope="row"><?= I18N::translate('Title') ?></td> |
1513
|
|
|
<td><input type="text" data-autocomplete-type="SOUR_TITL" name="TITL" id="TITL" |
1514
|
|
|
required> <?= FunctionsPrint::printSpecialCharacterLink('TITL') ?></td> |
1515
|
|
|
</tr> |
1516
|
|
|
<tr> |
1517
|
|
|
<th scope="row"><?= I18N::translate('Abbreviation') ?></td> |
1518
|
|
|
<td><input type="text" name="ABBR" id="ABBR" |
1519
|
|
|
maxlength="255"> <?= FunctionsPrint::printSpecialCharacterLink('ABBR') ?> |
1520
|
|
|
</td> |
1521
|
|
|
</tr> |
1522
|
|
View Code Duplication |
<?php if (strstr($controller->tree()->getPreference('ADVANCED_NAME_FACTS'), '_HEB') !== false) { ?> |
1523
|
|
|
<tr> |
1524
|
|
|
<th scope="row"><?= GedcomTag::getLabel('_HEB') ?></th> |
1525
|
|
|
<td><input type="text" name="_HEB" id="_HEB" value="" size="60"> |
1526
|
|
|
<?= FunctionsPrint::printSpecialCharacterLink('_HEB') ?></td> |
1527
|
|
|
</tr> |
1528
|
|
|
<?php } ?> |
1529
|
|
View Code Duplication |
<?php if (strstr($controller->tree()->getPreference('ADVANCED_NAME_FACTS'), 'ROMN') !== false) { ?> |
1530
|
|
|
<tr> |
1531
|
|
|
<th scope="row"> |
1532
|
|
|
<?= GedcomTag::getLabel('ROMN') ?></th> |
1533
|
|
|
<td><input type="text" name="ROMN" id="ROMN" value="" |
1534
|
|
|
size="60"> <?= FunctionsPrint::printSpecialCharacterLink('ROMN') ?></td> |
1535
|
|
|
</tr> |
1536
|
|
|
<?php } ?> |
1537
|
|
|
<tr> |
1538
|
|
|
<th scope="row"><?= I18N::translate('Author') ?></th> |
1539
|
|
|
<td><input type="text" name="AUTH" id="AUTH" value="" size="40" |
1540
|
|
|
maxlength="255"> <?= FunctionsPrint::printSpecialCharacterLink('AUTH') ?> |
1541
|
|
|
</td> |
1542
|
|
|
</tr> |
1543
|
|
|
<tr> |
1544
|
|
|
<th scope="row"><?= GedcomTag::getLabel('PUBL') ?></th> |
1545
|
|
|
<td><textarea name="PUBL" id="PUBL" rows="5" |
1546
|
|
|
cols="60"></textarea><br><?= FunctionsPrint::printSpecialCharacterLink('PUBL') ?> |
1547
|
|
|
</td> |
1548
|
|
|
</tr> |
1549
|
|
|
<tr> |
1550
|
|
|
<th scope="row"><?= I18N::translate('Repository') ?></th> |
1551
|
|
|
<td><input type="text" data-autocomplete-type="REPO" name="REPO" id="REPO" value="" |
1552
|
|
|
size="10"></td> |
1553
|
|
|
</tr> |
1554
|
|
|
<tr> |
1555
|
|
|
<th scope="row"><?= I18N::translate('Call number') ?></th> |
1556
|
|
|
<td><input type="text" name="CALN" id="CALN" value=""></td> |
1557
|
|
|
</tr> |
1558
|
|
|
<?= keep_chan() ?> |
1559
|
|
|
</table> |
1560
|
|
|
<a href="#" onclick="return expand_layer('events');"><i id="events_img" class="icon-plus"></i> |
1561
|
|
|
<?= I18N::translate('Associate events with this source') ?></a> |
1562
|
|
|
<div id="events" style="display: none;"> |
1563
|
|
|
<table class="table wt-facts-table"> |
1564
|
|
|
<tr> |
1565
|
|
|
<th scope="row"> |
1566
|
|
|
<label for="source-events"> |
1567
|
|
|
<?= I18N::translate('Select events'), FunctionsPrint::helpLink('edit_SOUR_EVEN') ?> |
1568
|
|
|
</label> |
1569
|
|
|
</th> |
1570
|
|
|
<td> |
1571
|
|
|
<select id="source-events" name="EVEN[]" multiple="multiple" size="5"> |
1572
|
|
|
<?php |
1573
|
|
|
$parts = explode(',', $controller->tree()->getPreference('INDI_FACTS_ADD')); |
1574
|
|
|
foreach ($parts as $key) { |
1575
|
|
|
?> |
1576
|
|
|
<option value="<?= $key ?>"><?= GedcomTag::getLabel($key) ?></option> |
|
|
|
|
1577
|
|
|
<?php |
1578
|
|
|
} |
1579
|
|
|
$parts = explode(',', $controller->tree()->getPreference('FAM_FACTS_ADD')); |
1580
|
|
|
foreach ($parts as $key) { |
1581
|
|
|
?> |
1582
|
|
|
<option value="<?= $key ?>"><?= GedcomTag::getLabel($key) ?></option> |
|
|
|
|
1583
|
|
|
<?php |
1584
|
|
|
} |
1585
|
|
|
?> |
1586
|
|
|
</select></td> |
1587
|
|
|
</tr> |
1588
|
|
|
<?= FunctionsEdit::addSimpleTag('0 DATE', 'EVEN') ?> |
1589
|
|
|
<?= FunctionsEdit::addSimpleTag('0 PLAC', 'EVEN') ?> |
1590
|
|
|
<?= FunctionsEdit::addSimpleTag('0 AGNC') ?> |
1591
|
|
|
</table> |
1592
|
|
|
</div> |
1593
|
|
|
|
1594
|
|
|
<div class="row form-group"> |
1595
|
|
|
<div class="col-sm-9 offset-sm-3"> |
1596
|
|
|
<button class="btn btn-primary" type="submit"> |
1597
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
1598
|
|
|
<?= /* I18N: A button label. */ |
1599
|
|
|
I18N::translate('save') ?> |
1600
|
|
|
</button> |
1601
|
|
|
<a class="btn btn-secondary" href="sourcelist.php?ged=<?= $controller->tree()->getNameHtml() ?>"> |
1602
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
1603
|
|
|
<?= /* I18N: A button label. */ |
1604
|
|
|
I18N::translate('cancel') ?> |
1605
|
|
|
</a> |
1606
|
|
|
</div> |
1607
|
|
|
</div> |
1608
|
|
|
</form> |
1609
|
|
|
<?php |
1610
|
|
|
break; |
1611
|
|
|
|
1612
|
|
|
case 'addsourceaction': |
1613
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1614
|
|
|
// Create a new source record |
1615
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1616
|
|
|
if (!Filter::checkCsrf()) { |
1617
|
|
|
header('Location: edit_interface.php?action=addnewsource&ged=' . $controller->tree()->getNameUrl()); |
1618
|
|
|
break; |
1619
|
|
|
} |
1620
|
|
|
|
1621
|
|
|
$newgedrec = '0 @XREF@ SOUR'; |
1622
|
|
|
$ABBR = Filter::post('ABBR'); |
1623
|
|
|
if ($ABBR) { |
1624
|
|
|
$newgedrec .= "\n1 ABBR " . $ABBR; |
1625
|
|
|
} |
1626
|
|
|
$TITL = Filter::post('TITL'); |
1627
|
|
View Code Duplication |
if ($TITL) { |
1628
|
|
|
$newgedrec .= "\n1 TITL " . $TITL; |
1629
|
|
|
$_HEB = Filter::post('_HEB'); |
1630
|
|
|
if ($_HEB) { |
1631
|
|
|
$newgedrec .= "\n2 _HEB " . $_HEB; |
1632
|
|
|
} |
1633
|
|
|
$ROMN = Filter::post('ROMN'); |
1634
|
|
|
if ($ROMN) { |
1635
|
|
|
$newgedrec .= "\n2 ROMN " . $ROMN; |
1636
|
|
|
} |
1637
|
|
|
} |
1638
|
|
|
$AUTH = Filter::post('AUTH'); |
1639
|
|
|
if ($AUTH) { |
1640
|
|
|
$newgedrec .= "\n1 AUTH " . $AUTH; |
1641
|
|
|
} |
1642
|
|
|
$PUBL = Filter::post('PUBL'); |
1643
|
|
|
if ($PUBL) { |
1644
|
|
|
$newgedrec .= "\n1 PUBL " . preg_replace('/\r?\n/', "\n2 CONT ", $PUBL); |
1645
|
|
|
} |
1646
|
|
|
$REPO = Filter::post('REPO', WT_REGEX_XREF); |
1647
|
|
|
if ($REPO) { |
1648
|
|
|
$newgedrec .= "\n1 REPO @" . $REPO . '@'; |
1649
|
|
|
$CALN = Filter::post('CALN'); |
1650
|
|
|
if ($CALN) { |
1651
|
|
|
$newgedrec .= "\n2 CALN " . $CALN; |
1652
|
|
|
} |
1653
|
|
|
} |
1654
|
|
|
$EVEN = Filter::postArray('EVEN', WT_REGEX_TAG); |
1655
|
|
|
if ($EVEN) { |
|
|
|
|
1656
|
|
|
$newgedrec .= "\n1 DATA"; |
1657
|
|
|
$newgedrec .= "\n2 EVEN " . implode(',', $EVEN); |
1658
|
|
|
$EVEN_DATE = Filter::post('EVEN_DATE'); |
1659
|
|
|
if ($EVEN_DATE) { |
1660
|
|
|
$newgedrec .= "\n3 EVEN_DATE " . $EVEN_DATE; |
1661
|
|
|
} |
1662
|
|
|
$EVEN_PLAC = Filter::post('EVEN_PLAC'); |
1663
|
|
|
if ($EVEN_PLAC) { |
1664
|
|
|
$newgedrec .= "\n3 EVEN_PLAC " . $EVEN_PLAC; |
1665
|
|
|
} |
1666
|
|
|
$AGNC = Filter::post('AGNC'); |
1667
|
|
|
if ($AGNC) { |
1668
|
|
|
$newgedrec .= "\n2 AGNC " . $AGNC; |
1669
|
|
|
} |
1670
|
|
|
} |
1671
|
|
|
|
1672
|
|
|
$record = $controller->tree()->createRecord($newgedrec); |
1673
|
|
|
|
1674
|
|
|
header('Location: ' . $record->getRawUrl()); |
1675
|
|
|
break; |
1676
|
|
|
|
1677
|
|
|
case 'addnewnote': |
1678
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1679
|
|
|
// Create a new note record |
1680
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1681
|
|
|
$controller |
1682
|
|
|
->setPageTitle(I18N::translate('Create a shared note')) |
1683
|
|
|
->pageHeader(); |
1684
|
|
|
|
1685
|
|
|
?> |
1686
|
|
|
<h2><?= $controller->getPageTitle() ?></h2> |
1687
|
|
|
|
1688
|
|
|
<form method="post"> |
1689
|
|
|
<input type="hidden" name="ged" value="<?= $controller->tree()->getNameHtml() ?>"> |
1690
|
|
|
<input type="hidden" name="action" value="addnoteaction"> |
1691
|
|
|
<input type="hidden" name="noteid" value="newnote"> |
1692
|
|
|
<?= Filter::getCsrf() ?> |
1693
|
|
|
<?php |
1694
|
|
|
echo '<table class="table wt-facts-table">'; |
1695
|
|
|
echo '<tr>'; |
1696
|
|
|
echo '<th scope="row">'; |
1697
|
|
|
echo I18N::translate('Shared note'); |
1698
|
|
|
echo '</th>'; |
1699
|
|
|
echo '<td><textarea name="NOTE" id="NOTE" rows="10" required></textarea>'; |
1700
|
|
|
echo FunctionsPrint::printSpecialCharacterLink('NOTE'); |
1701
|
|
|
echo '</td>'; |
1702
|
|
|
echo '</tr>'; |
1703
|
|
|
echo keep_chan(); |
1704
|
|
|
echo '</table>'; |
1705
|
|
|
?> |
1706
|
|
|
<div class="row form-group"> |
1707
|
|
|
<div class="col-sm-9 offset-sm-3"> |
1708
|
|
|
<button class="btn btn-primary" type="submit"> |
1709
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
1710
|
|
|
<?= /* I18N: A button label. */ |
1711
|
|
|
I18N::translate('save') ?> |
1712
|
|
|
</button> |
1713
|
|
|
<a class="btn btn-secondary" href="index.php?ctype=ged&ged=<?= $controller->tree()->getNameHtml() ?>"> |
1714
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
1715
|
|
|
<?= /* I18N: A button label. */ |
1716
|
|
|
I18N::translate('cancel') ?> |
1717
|
|
|
</a> |
1718
|
|
|
</div> |
1719
|
|
|
</div> |
1720
|
|
|
</form> |
1721
|
|
|
<?php |
1722
|
|
|
break; |
1723
|
|
|
|
1724
|
|
|
case 'addnoteaction': |
1725
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1726
|
|
|
// Create a new note record |
1727
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1728
|
|
|
if (!Filter::checkCsrf()) { |
1729
|
|
|
header('Location: edit_interface.php?action=addnewnote'); |
1730
|
|
|
break; |
1731
|
|
|
} |
1732
|
|
|
|
1733
|
|
|
$gedrec = '0 @XREF@ NOTE ' . preg_replace("/\r?\n/", "\n1 CONT ", Filter::post('NOTE')); |
1734
|
|
|
|
1735
|
|
|
$record = $controller->tree()->createRecord($gedrec); |
1736
|
|
|
break; |
1737
|
|
|
|
1738
|
|
|
case 'addmedia_links': |
1739
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1740
|
|
|
// |
1741
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1742
|
|
|
$pid = Filter::get('pid', WT_REGEX_XREF); |
1743
|
|
|
|
1744
|
|
|
$person = Individual::getInstance($pid, $controller->tree()); |
1745
|
|
|
check_record_access($person); |
1746
|
|
|
|
1747
|
|
|
$controller |
1748
|
|
|
->setPageTitle(I18N::translate('Family navigator') . ' — ' . $person->getFullName()) |
1749
|
|
|
->pageHeader(); |
1750
|
|
|
|
1751
|
|
|
?> |
1752
|
|
|
<h2><?= $controller->getPageTitle() ?></h2> |
1753
|
|
|
|
1754
|
|
|
<form method="post" action="edit_interface.php?xref=<?= $person->getXref() ?>" onsubmit="findindi()"> |
|
|
|
|
1755
|
|
|
<input type="hidden" name="ged" value="<?= $controller->tree()->getNameHtml() ?>"> |
1756
|
|
|
<input type="hidden" name="action" value="addmedia_links"> |
1757
|
|
|
<input type="hidden" name="noteid" value="newnote"> |
1758
|
|
|
<?= Filter::getCsrf() ?> |
1759
|
|
|
<?php require WT_ROOT . WT_MODULES_DIR . 'GEDFact_assistant/MEDIA_ctrl.php' ?> |
1760
|
|
|
</form> |
1761
|
|
|
<?php |
1762
|
|
|
break; |
1763
|
|
|
|
1764
|
|
|
case 'editnote': |
1765
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1766
|
|
|
// Edit a note record |
1767
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1768
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
1769
|
|
|
|
1770
|
|
|
$note = Note::getInstance($xref, $controller->tree()); |
1771
|
|
|
check_record_access($note); |
1772
|
|
|
|
1773
|
|
|
$controller |
1774
|
|
|
->setPageTitle(I18N::translate('Edit the shared note')) |
1775
|
|
|
->pageHeader(); |
1776
|
|
|
|
1777
|
|
|
?> |
1778
|
|
|
<h2><?= $controller->getPageTitle() ?></h2> |
1779
|
|
|
|
1780
|
|
|
<form method="post"> |
1781
|
|
|
<input type="hidden" name="ged" value="<?= $controller->tree()->getNameHtml() ?>"> |
1782
|
|
|
<input type="hidden" name="action" value="editnoteaction"> |
1783
|
|
|
<input type="hidden" name="xref" value="<?= $xref ?>"> |
1784
|
|
|
<?= Filter::getCsrf() ?> |
1785
|
|
|
<table class="table wt-facts-table"> |
1786
|
|
|
<tr> |
1787
|
|
|
<th scope="row"><?= I18N::translate('Shared note') ?></th> |
1788
|
|
|
<td> |
1789
|
|
|
<textarea name="NOTE" id="NOTE" rows="15" cols="90"><?= Html::escape($note->getNote()) ?></textarea> |
1790
|
|
|
<br> |
1791
|
|
|
<?= FunctionsPrint::printSpecialCharacterLink('NOTE') ?> |
1792
|
|
|
</td> |
1793
|
|
|
</tr> |
1794
|
|
|
<?= keep_chan($note) ?> |
1795
|
|
|
</table> |
1796
|
|
|
<div class="row form-group"> |
1797
|
|
|
<div class="col-sm-9 offset-sm-3"> |
1798
|
|
|
<button class="btn btn-primary" type="submit"> |
1799
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
1800
|
|
|
<?= /* I18N: A button label. */ |
1801
|
|
|
I18N::translate('save') ?> |
1802
|
|
|
</button> |
1803
|
|
|
<a class="btn btn-secondary" href="<?= $note->getHtmlUrl() ?>"> |
1804
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
1805
|
|
|
<?= /* I18N: A button label. */ |
1806
|
|
|
I18N::translate('cancel') ?> |
1807
|
|
|
</a> |
1808
|
|
|
</div> |
1809
|
|
|
</div> |
1810
|
|
|
</form> |
1811
|
|
|
<?php |
1812
|
|
|
break; |
1813
|
|
|
|
1814
|
|
|
case 'editnoteaction': |
1815
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1816
|
|
|
// Edit a note record |
1817
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1818
|
|
|
$xref = Filter::post('xref', WT_REGEX_XREF); |
1819
|
|
|
$keep_chan = Filter::postBool('keep_chan'); |
1820
|
|
|
$note = Filter::post('NOTE'); |
1821
|
|
|
|
1822
|
|
|
if (!Filter::checkCsrf()) { |
1823
|
|
|
header('Location: edit_interface.php?action=editnote&xref=' . $xref); |
1824
|
|
|
break; |
1825
|
|
|
} |
1826
|
|
|
|
1827
|
|
|
$record = Note::getInstance($xref, $controller->tree()); |
1828
|
|
|
check_record_access($record); |
1829
|
|
|
|
1830
|
|
|
// We have user-supplied data in a replacement string - escape it against backreferences |
1831
|
|
|
$note = str_replace(['\\', '$'], ['\\\\', '\\$'], $note); |
1832
|
|
|
|
1833
|
|
|
$gedrec = preg_replace( |
1834
|
|
|
'/^0 @' . $record->getXref() . '@ NOTE.*(\n1 CONT.*)*/', |
|
|
|
|
1835
|
|
|
'0 @' . $record->getXref() . '@ NOTE ' . preg_replace("/\r?\n/", "\n1 CONT ", $note), |
|
|
|
|
1836
|
|
|
$record->getGedcom() |
1837
|
|
|
); |
1838
|
|
|
|
1839
|
|
|
$record->updateRecord($gedrec, !$keep_chan); |
1840
|
|
|
|
1841
|
|
|
header('Location: ' . $record->getRawUrl()); |
1842
|
|
|
break; |
1843
|
|
|
|
1844
|
|
|
case 'addnewrepository': |
1845
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1846
|
|
|
// Create a new repository |
1847
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1848
|
|
|
$controller |
1849
|
|
|
->setPageTitle(I18N::translate('Create a repository')) |
1850
|
|
|
->pageHeader(); |
1851
|
|
|
|
1852
|
|
|
?> |
1853
|
|
|
<h2><?= $controller->getPageTitle() ?></h2> |
1854
|
|
|
|
1855
|
|
|
<form method="post"> |
1856
|
|
|
<input type="hidden" name="ged" value="<?= $controller->tree()->getNameHtml() ?>"> |
1857
|
|
|
<input type="hidden" name="action" value="addrepoaction"> |
1858
|
|
|
<input type="hidden" name="xref" value="newrepo"> |
1859
|
|
|
<?= Filter::getCsrf() ?> |
1860
|
|
|
<table class="table wt-facts-table"> |
1861
|
|
|
<tr> |
1862
|
|
|
<th scope="row"><?= I18N::translate('Repository name') ?></th> |
1863
|
|
|
<td><input type="text" name="REPO_NAME" id="REPO_NAME" required |
1864
|
|
|
maxlength="255"> <?= FunctionsPrint::printSpecialCharacterLink('REPO_NAME') ?> |
1865
|
|
|
</td> |
1866
|
|
|
</tr> |
1867
|
|
View Code Duplication |
<?php if (strstr($controller->tree()->getPreference('ADVANCED_NAME_FACTS'), '_HEB') !== false) { ?> |
1868
|
|
|
<tr> |
1869
|
|
|
<th scope="row"><?= GedcomTag::getLabel('_HEB') ?></th> |
1870
|
|
|
<td><input type="text" name="_HEB" id="_HEB" value="" size="40" |
1871
|
|
|
maxlength="255"> <?= FunctionsPrint::printSpecialCharacterLink('_HEB') ?> |
1872
|
|
|
</td> |
1873
|
|
|
</tr> |
1874
|
|
|
<?php } ?> |
1875
|
|
View Code Duplication |
<?php if (strstr($controller->tree()->getPreference('ADVANCED_NAME_FACTS'), 'ROMN') !== false) { ?> |
1876
|
|
|
<tr> |
1877
|
|
|
<th scope="row"><?= GedcomTag::getLabel('ROMN') ?></th> |
1878
|
|
|
<td><input type="text" name="ROMN" id="ROMN" value="" size="40" |
1879
|
|
|
maxlength="255"> <?= FunctionsPrint::printSpecialCharacterLink('ROMN') ?> |
1880
|
|
|
</td> |
1881
|
|
|
</tr> |
1882
|
|
|
<?php } ?> |
1883
|
|
|
<tr> |
1884
|
|
|
<th scope="row"><?= GedcomTag::getLabel('ADDR') ?></th> |
1885
|
|
|
<td><textarea name="ADDR" id="ADDR" rows="5" |
1886
|
|
|
cols="60"></textarea><?= FunctionsPrint::printSpecialCharacterLink('ADDR') ?> |
1887
|
|
|
</td> |
1888
|
|
|
</tr> |
1889
|
|
|
<tr> |
1890
|
|
|
<th scope="row"><?= GedcomTag::getLabel('PHON') ?></th> |
1891
|
|
|
<td><input type="text" name="PHON" id="PHON" value="" size="40" maxlength="255"></td> |
1892
|
|
|
</tr> |
1893
|
|
|
<tr> |
1894
|
|
|
<th scope="row"><?= GedcomTag::getLabel('EMAIL') ?></th> |
1895
|
|
|
<td><input type="text" name="EMAIL" id="EMAIL" value="" size="40" maxlength="255"></td> |
1896
|
|
|
</tr> |
1897
|
|
|
<tr> |
1898
|
|
|
<th scope="row"><?= GedcomTag::getLabel('WWW') ?></th> |
1899
|
|
|
<td><input type="text" name="WWW" id="WWW" value="" size="40" maxlength="255"></td> |
1900
|
|
|
</tr> |
1901
|
|
|
</table> |
1902
|
|
|
|
1903
|
|
|
<div class="row form-group"> |
1904
|
|
|
<div class="col-sm-9 offset-sm-3"> |
1905
|
|
|
<button class="btn btn-primary" type="submit"> |
1906
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
1907
|
|
|
<?= /* I18N: A button label. */ |
1908
|
|
|
I18N::translate('save') ?> |
1909
|
|
|
</button> |
1910
|
|
|
<a class="btn btn-secondary" href="sourcelist.php?ged=<?= $controller->tree()->getNameHtml() ?>"> |
1911
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
1912
|
|
|
<?= /* I18N: A button label. */ |
1913
|
|
|
I18N::translate('cancel') ?> |
1914
|
|
|
</a> |
1915
|
|
|
</div> |
1916
|
|
|
</div> |
1917
|
|
|
</form> |
1918
|
|
|
<?php |
1919
|
|
|
break; |
1920
|
|
|
|
1921
|
|
|
case 'addrepoaction': |
1922
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1923
|
|
|
// Create a new repository |
1924
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1925
|
|
|
if (!Filter::checkCsrf()) { |
1926
|
|
|
header('Location: edit_interface.php?action=addnewrepository&ged=' . $controller->tree()->getNameUrl()); |
1927
|
|
|
break; |
1928
|
|
|
} |
1929
|
|
|
|
1930
|
|
|
$gedrec = '0 @XREF@ REPO'; |
1931
|
|
|
$REPO_NAME = Filter::post('REPO_NAME'); |
1932
|
|
View Code Duplication |
if ($REPO_NAME) { |
1933
|
|
|
$gedrec .= "\n1 NAME " . $REPO_NAME; |
1934
|
|
|
$_HEB = Filter::post('_HEB'); |
1935
|
|
|
if ($_HEB) { |
1936
|
|
|
$gedrec .= "\n2 _HEB " . $_HEB; |
1937
|
|
|
} |
1938
|
|
|
$ROMN = Filter::post('ROMN'); |
1939
|
|
|
if ($ROMN) { |
1940
|
|
|
$gedrec .= "\n2 ROMN " . $ROMN; |
1941
|
|
|
} |
1942
|
|
|
} |
1943
|
|
|
$ADDR = Filter::post('ADDR'); |
1944
|
|
|
if ($ADDR) { |
1945
|
|
|
$gedrec .= "\n1 ADDR " . preg_replace('/\r?\n/', "\n2 CONT ", $ADDR); |
1946
|
|
|
} |
1947
|
|
|
$PHON = Filter::post('PHON'); |
1948
|
|
|
if ($PHON) { |
1949
|
|
|
$gedrec .= "\n1 PHON " . $PHON; |
1950
|
|
|
} |
1951
|
|
|
$FAX = Filter::post('FAX'); |
1952
|
|
|
if ($FAX) { |
1953
|
|
|
$gedrec .= "\n1 FAX " . $FAX; |
1954
|
|
|
} |
1955
|
|
|
$EMAIL = Filter::post('EMAIL'); |
1956
|
|
|
if ($EMAIL) { |
1957
|
|
|
$gedrec .= "\n1 EMAIL " . $EMAIL; |
1958
|
|
|
} |
1959
|
|
|
$WWW = Filter::post('WWW'); |
1960
|
|
|
if ($WWW) { |
1961
|
|
|
$gedrec .= "\n1 WWW " . $WWW; |
1962
|
|
|
} |
1963
|
|
|
|
1964
|
|
|
$record = $controller->tree()->createRecord($gedrec); |
1965
|
|
|
header('Location: ' . $record->getRawUrl()); |
1966
|
|
|
break; |
1967
|
|
|
|
1968
|
|
|
case 'add-media-link': |
1969
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1970
|
|
|
// Link a media object to a record. |
1971
|
|
|
////////////////////////////////////////////////////////////////////////////// |
1972
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
1973
|
|
|
$record = GedcomRecord::getInstance($xref, $controller->tree()); |
1974
|
|
|
check_record_access($record); |
1975
|
|
|
|
1976
|
|
|
$controller |
1977
|
|
|
->setPageTitle($record->getFullName() . ' — ' . I18N::translate('Add a media object')) |
1978
|
|
|
->pageHeader(); |
1979
|
|
|
|
1980
|
|
|
?> |
1981
|
|
|
<h2><?= $controller->getPageTitle() ?></h2> |
1982
|
|
|
|
1983
|
|
|
<form method="post"> |
1984
|
|
|
<input type="hidden" name="ged" value="<?= $record->getTree()->getNameHtml() ?>"> |
1985
|
|
|
<input type="hidden" name="xref" value="<?= $record->getXref() ?>"> |
|
|
|
|
1986
|
|
|
<input type="hidden" name="action" value="save-media-link"> |
1987
|
|
|
<?= Filter::getCsrf() ?> |
1988
|
|
|
|
1989
|
|
|
<div class="row form-group"> |
1990
|
|
|
<label class="col-sm-3 col-form-label" for="media-xref"> |
1991
|
|
|
<?= I18N::translate('Media object') ?> |
1992
|
|
|
</label> |
1993
|
|
|
<div class="col-sm-9"> |
1994
|
|
|
<div class="input-group"> |
1995
|
|
|
<?php if ($record->getTree()->getPreference('MEDIA_UPLOAD') >= Auth::accessLevel($record->getTree())): ?> |
1996
|
|
|
<span class="input-group-btn"> |
1997
|
|
|
<button class="btn btn-secondary" type="button" data-toggle="modal" data-target="#modal-create-media-object" data-element-id="media-xref" title="<?= I18N::translate('Create a media object') ?>"> |
1998
|
|
|
<i class="fa fa-plus"></i> |
1999
|
|
|
</button> |
2000
|
|
|
</span> |
2001
|
|
|
<?php endif ?> |
2002
|
|
|
<?= FunctionsEdit::formControlMediaObject(null, ['id' => 'media-xref', 'name' => 'media-xref', 'data-element-id' => 'media-xref']) ?> |
2003
|
|
|
</div> |
2004
|
|
|
</div> |
2005
|
|
|
</div> |
2006
|
|
|
|
2007
|
|
|
<div class="row form-group"> |
2008
|
|
|
<div class="col-sm-9 offset-sm-3"> |
2009
|
|
|
<button class="btn btn-primary" type="submit"> |
2010
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
2011
|
|
|
<?= /* I18N: A button label. */ |
2012
|
|
|
I18N::translate('save') ?> |
2013
|
|
|
</button> |
2014
|
|
|
<a class="btn btn-secondary" href="<?= $record->getHtmlUrl() ?>"> |
2015
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
2016
|
|
|
<?= /* I18N: A button label. */ |
2017
|
|
|
I18N::translate('cancel') ?> |
2018
|
|
|
</a> |
2019
|
|
|
</div> |
2020
|
|
|
</div> |
2021
|
|
|
</form> |
2022
|
|
|
<?= View::make('modals/create-media', ['tree' => $controller->tree(), 'max_upload_size' => '???', 'unused_files' => []]) ?> |
2023
|
|
|
<?php |
2024
|
|
|
break; |
2025
|
|
|
|
2026
|
|
|
case 'save-media-link': |
2027
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2028
|
|
|
// Link a media object to a record. |
2029
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2030
|
|
|
if (!Filter::checkCsrf()) { |
2031
|
|
|
header('Location: edit_interface.php?action=addnewrepository&ged=' . $controller->tree()->getNameUrl()); |
2032
|
|
|
break; |
2033
|
|
|
} |
2034
|
|
|
$xref = Filter::post('xref', WT_REGEX_XREF); |
2035
|
|
|
$media_xref = Filter::post('media-xref', WT_REGEX_XREF); |
2036
|
|
|
$record = GedcomRecord::getInstance($xref, $controller->tree()); |
2037
|
|
|
check_record_access($record); |
2038
|
|
|
|
2039
|
|
|
$gedcom = '1 OBJE @' . $media_xref . '@'; |
2040
|
|
|
|
2041
|
|
|
$record->createFact($gedcom, true); |
2042
|
|
|
|
2043
|
|
|
header('Location: ' . $record->getRawUrl()); |
2044
|
|
|
break; |
2045
|
|
|
|
2046
|
|
|
case 'editname': |
2047
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2048
|
|
|
// |
2049
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2050
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
2051
|
|
|
$fact_id = Filter::get('fact_id'); |
2052
|
|
|
|
2053
|
|
|
$person = Individual::getInstance($xref, $controller->tree()); |
2054
|
|
|
check_record_access($person); |
2055
|
|
|
|
2056
|
|
|
// Find the fact to edit |
2057
|
|
|
$name_fact = null; |
2058
|
|
|
foreach ($person->getFacts() as $fact) { |
2059
|
|
|
if ($fact->getFactId() === $fact_id && $fact->canEdit()) { |
2060
|
|
|
$name_fact = $fact; |
2061
|
|
|
} |
2062
|
|
|
} |
2063
|
|
|
if (!$name_fact) { |
2064
|
|
|
header('Location: ' . $person->getRawUrl()); |
2065
|
|
|
break; |
2066
|
|
|
} |
2067
|
|
|
|
2068
|
|
|
$controller |
2069
|
|
|
->setPageTitle(I18N::translate('Edit the name')) |
2070
|
|
|
->pageHeader(); |
2071
|
|
|
|
2072
|
|
|
print_indi_form('update', $person, null, $name_fact, '', $person->getSex()); |
2073
|
|
|
break; |
2074
|
|
|
|
2075
|
|
View Code Duplication |
case 'addname': |
2076
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2077
|
|
|
// |
2078
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2079
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
2080
|
|
|
|
2081
|
|
|
$individual = Individual::getInstance($xref, $controller->tree()); |
2082
|
|
|
check_record_access($individual); |
2083
|
|
|
|
2084
|
|
|
$controller |
2085
|
|
|
->setPageTitle($individual->getFullName() . ' — ' . I18N::translate('Add a name')) |
2086
|
|
|
->pageHeader(); |
2087
|
|
|
|
2088
|
|
|
print_indi_form('update', $individual, null, null, '', $individual->getSex()); |
2089
|
|
|
break; |
2090
|
|
|
|
2091
|
|
|
case 'changefamily': |
2092
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2093
|
|
|
// Change the members of a family record |
2094
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2095
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
2096
|
|
|
|
2097
|
|
|
$family = Family::getInstance($xref, $controller->tree()); |
2098
|
|
|
check_record_access($family); |
2099
|
|
|
|
2100
|
|
|
$controller |
2101
|
|
|
->setPageTitle(I18N::translate('Change family members') . ' – ' . $family->getFullName()) |
2102
|
|
|
->pageHeader(); |
2103
|
|
|
|
2104
|
|
|
$father = $family->getHusband(); |
2105
|
|
|
$mother = $family->getWife(); |
2106
|
|
|
$children = $family->getChildren(); |
2107
|
|
|
?> |
2108
|
|
|
<h2><?= $controller->getPageTitle() ?></h2> |
2109
|
|
|
|
2110
|
|
|
<div id="changefam"> |
2111
|
|
|
<form name="changefamform" method="post"> |
2112
|
|
|
<input type="hidden" name="ged" value="<?= $controller->tree()->getNameHtml() ?>"> |
2113
|
|
|
<input type="hidden" name="action" value="changefamily_update"> |
2114
|
|
|
<input type="hidden" name="xref" value="<?= $xref ?>"> |
2115
|
|
|
<?= Filter::getCsrf() ?> |
2116
|
|
|
<table> |
2117
|
|
|
<tr> |
2118
|
|
View Code Duplication |
<?php if ($father) { ?> |
2119
|
|
|
<td class="descriptionbox"> |
2120
|
|
|
<b> |
2121
|
|
|
<?php |
2122
|
|
|
switch ($father->getSex()) { |
2123
|
|
|
case 'M': |
2124
|
|
|
echo I18N::translate('husband'); |
2125
|
|
|
break; |
2126
|
|
|
case 'F': |
2127
|
|
|
echo I18N::translate('wife'); |
2128
|
|
|
break; |
2129
|
|
|
default: |
2130
|
|
|
echo I18N::translate('spouse'); |
2131
|
|
|
break; |
2132
|
|
|
} |
2133
|
|
|
?> |
2134
|
|
|
</b> |
2135
|
|
|
<input type="hidden" name="HUSB" value="<?= $father->getXref() ?>"> |
|
|
|
|
2136
|
|
|
</td> |
2137
|
|
|
<td id="HUSBName" class="optionbox"><?= $father->getFullName() ?> |
2138
|
|
|
</td> |
2139
|
|
|
<?php } else { ?> |
2140
|
|
|
<td class="descriptionbox"> |
2141
|
|
|
<b><?= I18N::translate('spouse') ?></b> |
2142
|
|
|
<input type="hidden" name="HUSB" value=""> |
2143
|
|
|
</td> |
2144
|
|
|
<td id="HUSBName" class="optionbox"> |
2145
|
|
|
</td> |
2146
|
|
|
<?php } ?> |
2147
|
|
|
<td class="optionbox"> |
2148
|
|
|
<a href="#" id="husbrem" style="display: <?= is_null($father) ? 'none' : 'block' ?>;" |
2149
|
|
|
onclick="document.changefamform.HUSB.value=''; document.getElementById('HUSBName').innerHTML=''; this.style.display='none'; return false;"> |
2150
|
|
|
<?= I18N::translate('Remove') ?> |
2151
|
|
|
</a> |
2152
|
|
|
</td> |
2153
|
|
|
<td class="optionbox"> |
2154
|
|
|
</td> |
2155
|
|
|
</tr> |
2156
|
|
|
<tr> |
2157
|
|
View Code Duplication |
<?php if ($mother) { ?> |
2158
|
|
|
<td class="descriptionbox"> |
2159
|
|
|
<b> |
2160
|
|
|
<?php |
2161
|
|
|
switch ($mother->getSex()) { |
2162
|
|
|
case 'M': |
2163
|
|
|
echo I18N::translate('husband'); |
2164
|
|
|
break; |
2165
|
|
|
case 'F': |
2166
|
|
|
echo I18N::translate('wife'); |
2167
|
|
|
break; |
2168
|
|
|
default: |
2169
|
|
|
echo I18N::translate('spouse'); |
2170
|
|
|
break; |
2171
|
|
|
} |
2172
|
|
|
?> |
2173
|
|
|
</b> |
2174
|
|
|
<input type="hidden" name="WIFE" value="<?= $mother->getXref() ?>"> |
|
|
|
|
2175
|
|
|
</td> |
2176
|
|
|
<td id="WIFEName" class="optionbox"> |
2177
|
|
|
<?= $mother->getFullName() ?> |
2178
|
|
|
</td> |
2179
|
|
|
<?php } else { ?> |
2180
|
|
|
<td class="descriptionbox"> |
2181
|
|
|
<b><?= I18N::translate('spouse') ?></b> |
2182
|
|
|
<input type="hidden" name="WIFE" value=""> |
2183
|
|
|
</td> |
2184
|
|
|
<td id="WIFEName" class="optionbox"> |
2185
|
|
|
</td> |
2186
|
|
|
<?php } ?> |
2187
|
|
|
<td class="optionbox"> |
2188
|
|
|
<a href="#" id="wiferem" style="display: <?= is_null($mother) ? 'none' : 'block' ?>;" |
2189
|
|
|
onclick="document.changefamform.WIFE.value=''; document.getElementById('WIFEName').innerHTML=''; this.style.display='none'; return false;"> |
2190
|
|
|
<?= I18N::translate('Remove') ?> |
2191
|
|
|
</a> |
2192
|
|
|
</td> |
2193
|
|
|
<td class="optionbox"> |
2194
|
|
|
</td> |
2195
|
|
|
</tr> |
2196
|
|
|
<?php $i = 0; |
2197
|
|
|
foreach ($children as $child) { ?> |
2198
|
|
|
<tr> |
2199
|
|
|
<td class="descriptionbox"> |
2200
|
|
|
<b> |
2201
|
|
|
<?php |
2202
|
|
|
switch ($child->getSex()) { |
2203
|
|
|
case 'M': |
2204
|
|
|
echo I18N::translate('son'); |
2205
|
|
|
break; |
2206
|
|
|
case 'F': |
2207
|
|
|
echo I18N::translate('daughter'); |
2208
|
|
|
break; |
2209
|
|
|
default: |
2210
|
|
|
echo I18N::translate('child'); |
2211
|
|
|
break; |
2212
|
|
|
} |
2213
|
|
|
?> |
2214
|
|
|
</b> |
2215
|
|
|
<input type="hidden" name="CHIL<?= $i ?>" value="<?= $child->getXref() ?>"> |
|
|
|
|
2216
|
|
|
</td> |
2217
|
|
|
<td id="CHILName<?= $i ?>" class="optionbox"><?= $child->getFullName() ?> |
2218
|
|
|
</td> |
2219
|
|
|
<td class="optionbox"> |
2220
|
|
|
<a href="#" id="childrem<?= $i ?>" style="display: block;" |
2221
|
|
|
onclick="document.changefamform.CHIL<?= $i ?>.value=''; document.getElementById('CHILName<?= $i ?>').innerHTML=''; this.style.display='none'; return false;"> |
2222
|
|
|
<?= I18N::translate('Remove') ?> |
2223
|
|
|
</a> |
2224
|
|
|
</td> |
2225
|
|
|
<td class="optionbox"> |
2226
|
|
|
</td> |
2227
|
|
|
</tr> |
2228
|
|
|
<?php $i++; |
2229
|
|
|
} ?> |
2230
|
|
|
<tr> |
2231
|
|
|
<td class="descriptionbox"> |
2232
|
|
|
<b><?= I18N::translate('child') ?></b> |
2233
|
|
|
<input type="hidden" name="CHIL<?= $i ?>" value=""> |
2234
|
|
|
</td> |
2235
|
|
|
<td id="CHILName<?= $i ?>" class="optionbox"> |
2236
|
|
|
</td> |
2237
|
|
|
<td colspan="2" class="optionbox child"> |
2238
|
|
|
<a href="#" id="childrem<?= $i ?>" style="display: none;" |
2239
|
|
|
onclick="document.changefamform.CHIL<?= $i ?>.value=''; document.getElementById('CHILName<?= $i ?>').innerHTML=''; this.style.display='none'; return false;"> |
2240
|
|
|
<?= I18N::translate('Remove') ?> |
2241
|
|
|
</a> |
2242
|
|
|
</td> |
2243
|
|
|
</tr> |
2244
|
|
|
</table> |
2245
|
|
|
<div class="row form-group"> |
2246
|
|
|
<div class="col-sm-9 offset-sm-3"> |
2247
|
|
|
<button class="btn btn-primary" type="submit"> |
2248
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
2249
|
|
|
<?= /* I18N: A button label. */ |
2250
|
|
|
I18N::translate('save') ?> |
2251
|
|
|
</button> |
2252
|
|
|
<a class="btn btn-secondary" href="<?= $family->getHtmlUrl() ?>"> |
2253
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
2254
|
|
|
<?= /* I18N: A button label. */ |
2255
|
|
|
I18N::translate('cancel') ?> |
2256
|
|
|
</a> |
2257
|
|
|
</div> |
2258
|
|
|
</div> |
2259
|
|
|
</form> |
2260
|
|
|
</div> |
2261
|
|
|
<?php |
2262
|
|
|
break; |
2263
|
|
|
|
2264
|
|
|
case 'changefamily_update': |
2265
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2266
|
|
|
// Change the members of a family record |
2267
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2268
|
|
|
$xref = Filter::post('xref', WT_REGEX_XREF); |
2269
|
|
|
$HUSB = Filter::post('HUSB', WT_REGEX_XREF); |
2270
|
|
|
$WIFE = Filter::post('WIFE', WT_REGEX_XREF); |
2271
|
|
|
$keep_chan = Filter::postBool('keep_chan'); |
2272
|
|
|
|
2273
|
|
|
if (!Filter::checkCsrf()) { |
2274
|
|
|
header('Location: edit_interface.php?action=changefamily&xref=' . $xref); |
2275
|
|
|
break; |
2276
|
|
|
} |
2277
|
|
|
|
2278
|
|
|
$CHIL = []; |
2279
|
|
|
for ($i = 0; isset($_POST['CHIL' . $i]); ++$i) { |
2280
|
|
|
$CHIL[] = Filter::post('CHIL' . $i, WT_REGEX_XREF); |
2281
|
|
|
} |
2282
|
|
|
|
2283
|
|
|
$family = Family::getInstance($xref, $controller->tree()); |
2284
|
|
|
check_record_access($family); |
2285
|
|
|
|
2286
|
|
|
// Current family members |
2287
|
|
|
$old_father = $family->getHusband(); |
2288
|
|
|
$old_mother = $family->getWife(); |
2289
|
|
|
$old_children = $family->getChildren(); |
2290
|
|
|
|
2291
|
|
|
// New family members |
2292
|
|
|
$new_father = Individual::getInstance($HUSB, $controller->tree()); |
2293
|
|
|
$new_mother = Individual::getInstance($WIFE, $controller->tree()); |
2294
|
|
|
$new_children = []; |
2295
|
|
|
foreach ($CHIL as $child) { |
2296
|
|
|
$new_children[] = Individual::getInstance($child, $controller->tree()); |
2297
|
|
|
} |
2298
|
|
|
|
2299
|
|
View Code Duplication |
if ($old_father !== $new_father) { |
2300
|
|
|
if ($old_father) { |
2301
|
|
|
// Remove old FAMS link |
2302
|
|
|
foreach ($old_father->getFacts('FAMS') as $fact) { |
2303
|
|
|
if ($fact->getTarget() === $family) { |
2304
|
|
|
$old_father->deleteFact($fact->getFactId(), !$keep_chan); |
2305
|
|
|
} |
2306
|
|
|
} |
2307
|
|
|
// Remove old HUSB link |
2308
|
|
|
foreach ($family->getFacts('HUSB|WIFE') as $fact) { |
2309
|
|
|
if ($fact->getTarget() === $old_father) { |
2310
|
|
|
$family->deleteFact($fact->getFactId(), !$keep_chan); |
2311
|
|
|
} |
2312
|
|
|
} |
2313
|
|
|
} |
2314
|
|
|
if ($new_father) { |
2315
|
|
|
// Add new FAMS link |
2316
|
|
|
$new_father->createFact('1 FAMS @' . $family->getXref() . '@', !$keep_chan); |
2317
|
|
|
// Add new HUSB link |
2318
|
|
|
$family->createFact('1 HUSB @' . $new_father->getXref() . '@', !$keep_chan); |
2319
|
|
|
} |
2320
|
|
|
} |
2321
|
|
|
|
2322
|
|
View Code Duplication |
if ($old_mother !== $new_mother) { |
2323
|
|
|
if ($old_mother) { |
2324
|
|
|
// Remove old FAMS link |
2325
|
|
|
foreach ($old_mother->getFacts('FAMS') as $fact) { |
2326
|
|
|
if ($fact->getTarget() === $family) { |
2327
|
|
|
$old_mother->deleteFact($fact->getFactId(), !$keep_chan); |
2328
|
|
|
} |
2329
|
|
|
} |
2330
|
|
|
// Remove old WIFE link |
2331
|
|
|
foreach ($family->getFacts('HUSB|WIFE') as $fact) { |
2332
|
|
|
if ($fact->getTarget() === $old_mother) { |
2333
|
|
|
$family->deleteFact($fact->getFactId(), !$keep_chan); |
2334
|
|
|
} |
2335
|
|
|
} |
2336
|
|
|
} |
2337
|
|
|
if ($new_mother) { |
2338
|
|
|
// Add new FAMS link |
2339
|
|
|
$new_mother->createFact('1 FAMS @' . $family->getXref() . '@', !$keep_chan); |
2340
|
|
|
// Add new WIFE link |
2341
|
|
|
$family->createFact('1 WIFE @' . $new_mother->getXref() . '@', !$keep_chan); |
2342
|
|
|
} |
2343
|
|
|
} |
2344
|
|
|
|
2345
|
|
|
foreach ($old_children as $old_child) { |
2346
|
|
|
if ($old_child && !in_array($old_child, $new_children)) { |
2347
|
|
|
// Remove old FAMC link |
2348
|
|
|
foreach ($old_child->getFacts('FAMC') as $fact) { |
2349
|
|
|
if ($fact->getTarget() === $family) { |
2350
|
|
|
$old_child->deleteFact($fact->getFactId(), !$keep_chan); |
2351
|
|
|
} |
2352
|
|
|
} |
2353
|
|
|
// Remove old CHIL link |
2354
|
|
|
foreach ($family->getFacts('CHIL') as $fact) { |
2355
|
|
|
if ($fact->getTarget() === $old_child) { |
2356
|
|
|
$family->deleteFact($fact->getFactId(), !$keep_chan); |
2357
|
|
|
} |
2358
|
|
|
} |
2359
|
|
|
} |
2360
|
|
|
} |
2361
|
|
|
|
2362
|
|
|
foreach ($new_children as $new_child) { |
2363
|
|
|
if ($new_child && !in_array($new_child, $old_children)) { |
2364
|
|
|
// Add new FAMC link |
2365
|
|
|
$new_child->createFact('1 FAMC @' . $family->getXref() . '@', !$keep_chan); |
2366
|
|
|
// Add new CHIL link |
2367
|
|
|
$family->createFact('1 CHIL @' . $new_child->getXref() . '@', !$keep_chan); |
2368
|
|
|
} |
2369
|
|
|
} |
2370
|
|
|
|
2371
|
|
|
header('Location: ' . $family->getRawUrl()); |
2372
|
|
|
break; |
2373
|
|
|
|
2374
|
|
|
case 'reorder-media': |
2375
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2376
|
|
|
// Change the order of media objects within an individual record |
2377
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2378
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
2379
|
|
|
|
2380
|
|
|
$individual = Individual::getInstance($xref, $controller->tree()); |
2381
|
|
|
check_record_access($individual); |
2382
|
|
|
|
2383
|
|
|
$controller |
2384
|
|
|
->addExternalJavascript(WT_SORTABLE_JS_URL) |
2385
|
|
|
->addInlineJavascript('new Sortable(document.querySelector(".wt-sortable-list"), {});') |
2386
|
|
|
->setPageTitle($individual->getFullName() . ' — ' . I18N::translate('Re-order media')) |
2387
|
|
|
->pageHeader(); |
2388
|
|
|
|
2389
|
|
|
?> |
2390
|
|
|
<h2><?= $controller->getPageTitle() ?></h2> |
2391
|
|
|
|
2392
|
|
|
<form name="reorder_form" method="post"> |
2393
|
|
|
<input type="hidden" name="ged" value="<?= $controller->tree()->getNameHtml() ?>"> |
2394
|
|
|
<input type="hidden" name="action" value="reorder-media-save"> |
2395
|
|
|
<input type="hidden" name="xref" value="<?= $xref ?>"> |
2396
|
|
|
<?= Filter::getCsrf() ?> |
2397
|
|
|
<div class="wt-sortable-list"> |
2398
|
|
|
<?php foreach ($individual->getFacts('OBJE') as $fact): ?> |
2399
|
|
|
<div class="card mb-2 wt-sortable-item"> |
2400
|
|
|
<input type="hidden" name="order[]" value="<?= $fact->getFactId() ?>"> |
2401
|
|
|
<h3 class="card-header"> |
2402
|
|
|
<?= FontAwesome::semanticIcon('drag-handle', '') ?> |
2403
|
|
|
<?= $fact->getTarget()->getFullName() ?> |
2404
|
|
|
</h3> |
2405
|
|
|
<div class="card-body"> |
2406
|
|
|
<?= $fact->getTarget()->displayImage(100, 100, "contain") ?> |
2407
|
|
|
</div> |
2408
|
|
|
</div> |
2409
|
|
|
<?php endforeach ?> |
2410
|
|
|
</div> |
2411
|
|
|
|
2412
|
|
|
<p class="text-center"> |
2413
|
|
|
<button class="btn btn-primary" type="submit"> |
2414
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
2415
|
|
|
<?= /* I18N: A button label. */ |
2416
|
|
|
I18N::translate('save') ?> |
2417
|
|
|
</button> |
2418
|
|
|
<a class="btn btn-secondary" href="<?= $individual->getHtmlUrl() ?>"> |
2419
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
2420
|
|
|
<?= /* I18N: A button label. */ I18N::translate('cancel') ?> |
2421
|
|
|
</a> |
2422
|
|
|
</p> |
2423
|
|
|
</form> |
2424
|
|
|
<?php |
2425
|
|
|
break; |
2426
|
|
|
|
2427
|
|
View Code Duplication |
case 'reorder-media-save': |
2428
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2429
|
|
|
// Change the order of media objects within an individual record |
2430
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2431
|
|
|
$xref = Filter::post('xref', WT_REGEX_XREF); |
2432
|
|
|
$order = Filter::post('order'); |
2433
|
|
|
|
2434
|
|
|
if (!Filter::checkCsrf()) { |
2435
|
|
|
header('Location: edit_interface.php?action=reorder-names&xref=' . $xref); |
2436
|
|
|
break; |
2437
|
|
|
} |
2438
|
|
|
|
2439
|
|
|
$individual = Individual::getInstance($xref, $controller->tree()); |
2440
|
|
|
check_record_access($individual); |
2441
|
|
|
|
2442
|
|
|
$dummy_facts = ['0 @' . $individual->getXref() . '@ INDI']; |
2443
|
|
|
$sort_facts = []; |
2444
|
|
|
$keep_facts = []; |
2445
|
|
|
|
2446
|
|
|
// Split facts into CHIL and other |
2447
|
|
|
foreach ($individual->getFacts() as $fact) { |
2448
|
|
|
if ($fact->getTag() === 'OBJE') { |
2449
|
|
|
$sort_facts[$fact->getFactId()] = $fact->getGedcom(); |
2450
|
|
|
} else { |
2451
|
|
|
$keep_facts[] = $fact->getGedcom(); |
2452
|
|
|
} |
2453
|
|
|
} |
2454
|
|
|
|
2455
|
|
|
// Sort the facts |
2456
|
|
|
$order = (array) $order; |
2457
|
|
|
uksort($sort_facts, function ($x, $y) use ($order) { |
2458
|
|
|
return array_search($x, $order) - array_search($y, $order); |
2459
|
|
|
}); |
2460
|
|
|
|
2461
|
|
|
// Merge the facts |
2462
|
|
|
$gedcom = implode("\n", array_merge($dummy_facts, $sort_facts, $keep_facts)); |
2463
|
|
|
|
2464
|
|
|
$individual->updateRecord($gedcom, false); |
2465
|
|
|
|
2466
|
|
|
header('Location: ' . $individual->getRawUrl()); |
2467
|
|
|
break; |
2468
|
|
|
|
2469
|
|
|
case 'reorder-names': |
2470
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2471
|
|
|
// Change the order of name records within an individual record |
2472
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2473
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
2474
|
|
|
|
2475
|
|
|
$individual = Individual::getInstance($xref, $controller->tree()); |
2476
|
|
|
check_record_access($individual); |
2477
|
|
|
|
2478
|
|
|
$controller |
2479
|
|
|
->addExternalJavascript(WT_SORTABLE_JS_URL) |
2480
|
|
|
->addInlineJavascript('new Sortable(document.querySelector(".wt-sortable-list"), {});') |
2481
|
|
|
->setPageTitle($individual->getFullName() . ' — ' . I18N::translate('Re-order names')) |
2482
|
|
|
->pageHeader(); |
2483
|
|
|
|
2484
|
|
|
?> |
2485
|
|
|
<h2><?= $controller->getPageTitle() ?></h2> |
2486
|
|
|
|
2487
|
|
|
<form name="reorder_form" method="post"> |
2488
|
|
|
<input type="hidden" name="ged" value="<?= $controller->tree()->getNameHtml() ?>"> |
2489
|
|
|
<input type="hidden" name="action" value="reorder-names-save"> |
2490
|
|
|
<input type="hidden" name="xref" value="<?= $xref ?>"> |
2491
|
|
|
<?= Filter::getCsrf() ?> |
2492
|
|
|
<div class="wt-sortable-list"> |
2493
|
|
|
<?php foreach ($individual->getFacts('NAME|TITL') as $fact): ?> |
2494
|
|
|
<div class="card mb-2 wt-sortable-item"> |
2495
|
|
|
<input type="hidden" name="order[]" value="<?= $fact->getFactId() ?>"> |
2496
|
|
|
<h3 class="card-header"> |
2497
|
|
|
<?= FontAwesome::semanticIcon('drag-handle', '') ?> |
2498
|
|
|
<?= $fact->getValue() ?> |
2499
|
|
|
</h3> |
2500
|
|
|
<div class="card-body"> |
2501
|
|
|
<?= GedcomTag::getLabelValue('TYPE', GedcomCodeName::getValue($fact->getAttribute('TYPE'), $fact->getParent())) ?> |
2502
|
|
|
</div> |
2503
|
|
|
</div> |
2504
|
|
|
<?php endforeach ?> |
2505
|
|
|
</div> |
2506
|
|
|
|
2507
|
|
|
<p class="text-center"> |
2508
|
|
|
<button class="btn btn-primary" type="submit"> |
2509
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
2510
|
|
|
<?= /* I18N: A button label. */ |
2511
|
|
|
I18N::translate('save') ?> |
2512
|
|
|
</button> |
2513
|
|
|
<a class="btn btn-secondary" href="<?= $individual->getHtmlUrl() ?>"> |
2514
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
2515
|
|
|
<?= /* I18N: A button label. */ I18N::translate('cancel') ?> |
2516
|
|
|
</a> |
2517
|
|
|
</p> |
2518
|
|
|
</form> |
2519
|
|
|
<?php |
2520
|
|
|
break; |
2521
|
|
|
|
2522
|
|
View Code Duplication |
case 'reorder-names-save': |
2523
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2524
|
|
|
// Change the order of name/title facts within an individual record |
2525
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2526
|
|
|
$xref = Filter::post('xref', WT_REGEX_XREF); |
2527
|
|
|
$order = Filter::post('order'); |
2528
|
|
|
|
2529
|
|
|
if (!Filter::checkCsrf()) { |
2530
|
|
|
header('Location: edit_interface.php?action=reorder-names&xref=' . $xref); |
2531
|
|
|
break; |
2532
|
|
|
} |
2533
|
|
|
|
2534
|
|
|
$individual = Individual::getInstance($xref, $controller->tree()); |
2535
|
|
|
check_record_access($individual); |
2536
|
|
|
|
2537
|
|
|
$dummy_facts = ['0 @' . $individual->getXref() . '@ INDI']; |
2538
|
|
|
$sort_facts = []; |
2539
|
|
|
$keep_facts = []; |
2540
|
|
|
|
2541
|
|
|
// Split facts into NAME/TITL and other |
2542
|
|
|
foreach ($individual->getFacts() as $fact) { |
2543
|
|
|
if ($fact->getTag() === 'NAME' || $fact->getTag() === 'TITL') { |
2544
|
|
|
$sort_facts[$fact->getFactId()] = $fact->getGedcom(); |
2545
|
|
|
} else { |
2546
|
|
|
$keep_facts[] = $fact->getGedcom(); |
2547
|
|
|
} |
2548
|
|
|
} |
2549
|
|
|
|
2550
|
|
|
// Sort the facts |
2551
|
|
|
$order = (array) $order; |
2552
|
|
|
uksort($sort_facts, function ($x, $y) use ($order) { |
2553
|
|
|
return array_search($x, $order) - array_search($y, $order); |
2554
|
|
|
}); |
2555
|
|
|
|
2556
|
|
|
// Merge the facts |
2557
|
|
|
$gedcom = implode("\n", array_merge($dummy_facts, $sort_facts, $keep_facts)); |
2558
|
|
|
|
2559
|
|
|
$individual->updateRecord($gedcom, false); |
2560
|
|
|
|
2561
|
|
|
header('Location: ' . $individual->getRawUrl()); |
2562
|
|
|
break; |
2563
|
|
|
|
2564
|
|
View Code Duplication |
case 'reorder-children': |
2565
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2566
|
|
|
// Change the order of children within a family record |
2567
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2568
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
2569
|
|
|
|
2570
|
|
|
$family = Family::getInstance($xref, $controller->tree()); |
2571
|
|
|
check_record_access($family); |
2572
|
|
|
|
2573
|
|
|
$controller |
2574
|
|
|
->addExternalJavascript(WT_SORTABLE_JS_URL) |
2575
|
|
|
->addInlineJavascript('new Sortable(document.querySelector(".wt-sortable-list"), {});') |
2576
|
|
|
->addInlineJavascript('$("#btn-default-order").on("click", function() { $(".wt-sortable-list li").sort(function(x, y) { return Math.sign(x.dataset.sortbydate - y.dataset.sortbydate); }).appendTo(".wt-sortable-list"); });') |
2577
|
|
|
->setPageTitle($family->getFullName() . ' — ' . I18N::translate('Re-order children')) |
2578
|
|
|
->pageHeader(); |
2579
|
|
|
|
2580
|
|
|
?> |
2581
|
|
|
<h2><?= $controller->getPageTitle() ?></h2> |
2582
|
|
|
|
2583
|
|
|
<form name="reorder_form" method="post"> |
2584
|
|
|
<input type="hidden" name="ged" value="<?= $controller->tree()->getNameHtml() ?>"> |
2585
|
|
|
<input type="hidden" name="action" value="reorder-children-save"> |
2586
|
|
|
<input type="hidden" name="xref" value="<?= $xref ?>"> |
2587
|
|
|
<?= Filter::getCsrf() ?> |
2588
|
|
|
<div class="wt-sortable-list"> |
2589
|
|
|
<?php foreach ($family->getFacts('CHIL') as $fact): ?> |
2590
|
|
|
<div class="card mb-2 wt-sortable-item" data-sortbydate="<?= $fact->getTarget()->getBirthDate()->julianDay() ?>"> |
2591
|
|
|
<input type="hidden" name="order[]" value="<?= $fact->getFactId() ?>"> |
2592
|
|
|
<h3 class="card-header"> |
2593
|
|
|
<?= FontAwesome::semanticIcon('drag-handle', '') ?> |
2594
|
|
|
<?= $fact->getTarget()->getFullName() ?> |
2595
|
|
|
</h3> |
2596
|
|
|
<div class="card-body"> |
2597
|
|
|
<?= $fact->getTarget()->formatFirstMajorFact(WT_EVENTS_BIRT, 2) ?> |
2598
|
|
|
<?= $fact->getTarget()->formatFirstMajorFact(WT_EVENTS_DEAT, 2) ?> |
2599
|
|
|
</div> |
2600
|
|
|
</div> |
2601
|
|
|
<?php endforeach ?> |
2602
|
|
|
</div> |
2603
|
|
|
|
2604
|
|
|
<p class="text-center"> |
2605
|
|
|
<button class="btn btn-primary" type="submit"> |
2606
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
2607
|
|
|
<?= /* I18N: A button label. */ |
2608
|
|
|
I18N::translate('save') ?> |
2609
|
|
|
</button> |
2610
|
|
|
<button class="btn btn-secondary" id="btn-default-order" type="button"> |
2611
|
|
|
<?= FontAwesome::decorativeIcon('sort') ?> |
2612
|
|
|
<?= /* I18N: A button label. */ I18N::translate('sort by date of birth') ?> |
2613
|
|
|
</button> |
2614
|
|
|
<a class="btn btn-secondary" href="<?= $family->getHtmlUrl() ?>"> |
2615
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
2616
|
|
|
<?= /* I18N: A button label. */ I18N::translate('cancel') ?> |
2617
|
|
|
</a> |
2618
|
|
|
</p> |
2619
|
|
|
</form> |
2620
|
|
|
<?php |
2621
|
|
|
break; |
2622
|
|
|
|
2623
|
|
View Code Duplication |
case 'reorder-children-save': |
2624
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2625
|
|
|
// Change the order of FAMC records within a FAM record |
2626
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2627
|
|
|
$xref = Filter::post('xref', WT_REGEX_XREF); |
2628
|
|
|
$order = Filter::post('order'); |
2629
|
|
|
|
2630
|
|
|
if (!Filter::checkCsrf()) { |
2631
|
|
|
header('Location: edit_interface.php?action=reorder-spouses&xref=' . $xref); |
2632
|
|
|
break; |
2633
|
|
|
} |
2634
|
|
|
|
2635
|
|
|
$family = Family::getInstance($xref, $controller->tree()); |
2636
|
|
|
check_record_access($family); |
2637
|
|
|
|
2638
|
|
|
$dummy_facts = ['0 @' . $family->getXref() . '@ FAM']; |
2639
|
|
|
$sort_facts = []; |
2640
|
|
|
$keep_facts = []; |
2641
|
|
|
|
2642
|
|
|
// Split facts into CHIL and other |
2643
|
|
|
foreach ($family->getFacts() as $fact) { |
2644
|
|
|
if ($fact->getTag() === 'CHIL') { |
2645
|
|
|
$sort_facts[$fact->getFactId()] = $fact->getGedcom(); |
2646
|
|
|
} else { |
2647
|
|
|
$keep_facts[] = $fact->getGedcom(); |
2648
|
|
|
} |
2649
|
|
|
} |
2650
|
|
|
|
2651
|
|
|
// Sort the facts |
2652
|
|
|
$order = (array) $order; |
2653
|
|
|
uksort($sort_facts, function ($x, $y) use ($order) { |
2654
|
|
|
return array_search($x, $order) - array_search($y, $order); |
2655
|
|
|
}); |
2656
|
|
|
|
2657
|
|
|
// Merge the facts |
2658
|
|
|
$gedcom = implode("\n", array_merge($dummy_facts, $sort_facts, $keep_facts)); |
2659
|
|
|
|
2660
|
|
|
$family->updateRecord($gedcom, false); |
2661
|
|
|
|
2662
|
|
|
header('Location: ' . $family->getRawUrl()); |
2663
|
|
|
break; |
2664
|
|
|
|
2665
|
|
View Code Duplication |
case 'reorder-spouses': |
2666
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2667
|
|
|
// Change the order of FAMS records within an INDI record |
2668
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2669
|
|
|
$xref = Filter::get('xref', WT_REGEX_XREF); |
2670
|
|
|
|
2671
|
|
|
$person = Individual::getInstance($xref, $controller->tree()); |
2672
|
|
|
check_record_access($person); |
2673
|
|
|
|
2674
|
|
|
$controller |
2675
|
|
|
->addExternalJavascript(WT_SORTABLE_JS_URL) |
2676
|
|
|
->addInlineJavascript('new Sortable(document.querySelector(".wt-sortable-list"), {});') |
2677
|
|
|
->addInlineJavascript('$("#btn-default-order").on("click", function() { $(".wt-sortable-list li").sort(function(x, y) { return Math.sign(x.dataset.sortbydate - y.dataset.sortbydate); }).appendTo(".wt-sortable-list"); });') |
2678
|
|
|
->setPageTitle($person->getFullName() . ' — ' . I18N::translate('Re-order families')) |
2679
|
|
|
->pageHeader(); |
2680
|
|
|
|
2681
|
|
|
?> |
2682
|
|
|
<h2><?= $controller->getPageTitle() ?></h2> |
2683
|
|
|
|
2684
|
|
|
<form name="reorder_form" method="post"> |
2685
|
|
|
<input type="hidden" name="ged" value="<?= $controller->tree()->getNameHtml() ?>"> |
2686
|
|
|
<input type="hidden" name="action" value="reorder-spouses-save"> |
2687
|
|
|
<input type="hidden" name="xref" value="<?= $xref ?>"> |
2688
|
|
|
<?= Filter::getCsrf() ?> |
2689
|
|
|
<div class="wt-sortable-list"> |
2690
|
|
|
<?php foreach ($person->getFacts('FAMS') as $fact): ?> |
2691
|
|
|
<div class="card mb-2 wt-sortable-item" data-sortbydate="<?= $fact->getTarget()->getMarriageDate()->julianDay() ?>"> |
2692
|
|
|
<input type="hidden" name="order[]" value="<?= $fact->getFactId() ?>"> |
2693
|
|
|
<h3 class="card-header"> |
2694
|
|
|
<?= FontAwesome::semanticIcon('drag-handle', '') ?> |
2695
|
|
|
<?= $fact->getTarget()->getFullName() ?> |
2696
|
|
|
</h3> |
2697
|
|
|
<div class="card-body"> |
2698
|
|
|
<?= $fact->getTarget()->formatFirstMajorFact(WT_EVENTS_MARR, 2) ?> |
2699
|
|
|
<?= $fact->getTarget()->formatFirstMajorFact(WT_EVENTS_DIV, 2) ?> |
2700
|
|
|
</div> |
2701
|
|
|
</div> |
2702
|
|
|
<?php endforeach ?> |
2703
|
|
|
</div> |
2704
|
|
|
|
2705
|
|
|
<p class="text-center"> |
2706
|
|
|
<button class="btn btn-primary" type="submit"> |
2707
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
2708
|
|
|
<?= /* I18N: A button label. */ |
2709
|
|
|
I18N::translate('save') ?> |
2710
|
|
|
</button> |
2711
|
|
|
<button class="btn btn-secondary" id="btn-default-order" type="button"> |
2712
|
|
|
<?= FontAwesome::decorativeIcon('sort') ?> |
2713
|
|
|
<?= /* I18N: A button label. */ I18N::translate('sort by date of marriage') ?> |
2714
|
|
|
</button> |
2715
|
|
|
<a class="btn btn-secondary" href="<?= $person->getHtmlUrl() ?>"> |
2716
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
2717
|
|
|
<?= /* I18N: A button label. */ I18N::translate('cancel') ?> |
2718
|
|
|
</a> |
2719
|
|
|
</p> |
2720
|
|
|
</form> |
2721
|
|
|
<?php |
2722
|
|
|
break; |
2723
|
|
|
|
2724
|
|
View Code Duplication |
case 'reorder-spouses-save': |
2725
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2726
|
|
|
// Change the order of FAMS records within an INDI record |
2727
|
|
|
////////////////////////////////////////////////////////////////////////////// |
2728
|
|
|
$xref = Filter::post('xref', WT_REGEX_XREF); |
2729
|
|
|
$order = Filter::post('order'); |
2730
|
|
|
|
2731
|
|
|
if (!Filter::checkCsrf()) { |
2732
|
|
|
header('Location: edit_interface.php?action=reorder-spouses&xref=' . $xref); |
2733
|
|
|
break; |
2734
|
|
|
} |
2735
|
|
|
|
2736
|
|
|
$individual = Individual::getInstance($xref, $controller->tree()); |
2737
|
|
|
check_record_access($individual); |
2738
|
|
|
|
2739
|
|
|
$dummy_facts = ['0 @' . $individual->getXref() . '@ INDI']; |
2740
|
|
|
$sort_facts = []; |
2741
|
|
|
$keep_facts = []; |
2742
|
|
|
|
2743
|
|
|
// Split facts into FAMS and other |
2744
|
|
|
foreach ($individual->getFacts() as $fact) { |
2745
|
|
|
if ($fact->getTag() === 'FAMS') { |
2746
|
|
|
$sort_facts[$fact->getFactId()] = $fact->getGedcom(); |
2747
|
|
|
} else { |
2748
|
|
|
$keep_facts[] = $fact->getGedcom(); |
2749
|
|
|
} |
2750
|
|
|
} |
2751
|
|
|
|
2752
|
|
|
// Sort the facts |
2753
|
|
|
$order = (array) $order; |
2754
|
|
|
uksort($sort_facts, function ($x, $y) use ($order) { |
2755
|
|
|
return array_search($x, $order) - array_search($y, $order); |
2756
|
|
|
}); |
2757
|
|
|
|
2758
|
|
|
// Merge the facts |
2759
|
|
|
$gedcom = implode("\n", array_merge($dummy_facts, $sort_facts, $keep_facts)); |
2760
|
|
|
|
2761
|
|
|
$individual->updateRecord($gedcom, false); |
2762
|
|
|
|
2763
|
|
|
header('Location: ' . $individual->getRawUrl()); |
2764
|
|
|
break; |
2765
|
|
|
} |
2766
|
|
|
|
2767
|
|
|
/** |
2768
|
|
|
* Show an option to preserve the existing CHAN record when editing. |
2769
|
|
|
* |
2770
|
|
|
* @param GedcomRecord $record |
2771
|
|
|
* |
2772
|
|
|
* @return string |
2773
|
|
|
*/ |
2774
|
|
|
function keep_chan(GedcomRecord $record = null) { |
2775
|
|
|
global $controller; |
|
|
|
|
2776
|
|
|
|
2777
|
|
|
if (Auth::isAdmin()) { |
2778
|
|
|
if ($record) { |
2779
|
|
|
$details |
2780
|
|
|
= GedcomTag::getLabelValue('DATE', $record->lastChangeTimestamp()) . |
2781
|
|
|
GedcomTag::getLabelValue('_WT_USER', Html::escape($record->lastChangeUser())); |
2782
|
|
|
} else { |
2783
|
|
|
$details = ''; |
2784
|
|
|
} |
2785
|
|
|
|
2786
|
|
|
return |
2787
|
|
|
'<div class="form-group row"><label class="col-sm-3 col-form-label" for="keep_chan">' . |
2788
|
|
|
I18N::translate('Last change') . |
2789
|
|
|
'</label><div class="col-sm-9">' . |
2790
|
|
|
Bootstrap4::checkbox(I18N::translate('Keep the existing “last change” information'), true, ['name' => 'keep_chan', 'checked' => (bool) $controller->tree()->getPreference('NO_UPDATE_CHAN')]) . |
|
|
|
|
2791
|
|
|
$details . |
2792
|
|
|
'</div></div>'; |
2793
|
|
|
} else { |
2794
|
|
|
return ''; |
2795
|
|
|
} |
2796
|
|
|
} |
2797
|
|
|
|
2798
|
|
|
/** |
2799
|
|
|
* Print a form to add an individual or edit an individual’s name |
2800
|
|
|
* |
2801
|
|
|
* @param string $nextaction |
2802
|
|
|
* @param Individual $person |
2803
|
|
|
* @param Family $family |
2804
|
|
|
* @param Fact $name_fact |
2805
|
|
|
* @param string $famtag |
2806
|
|
|
* @param string $gender |
2807
|
|
|
*/ |
2808
|
|
|
function print_indi_form($nextaction, Individual $person = null, Family $family = null, Fact $name_fact = null, $famtag = 'CHIL', $gender = 'U') { |
2809
|
|
|
global $bdm, $controller; |
|
|
|
|
2810
|
|
|
|
2811
|
|
|
if ($person) { |
2812
|
|
|
$xref = $person->getXref(); |
2813
|
|
|
} elseif ($family) { |
2814
|
|
|
$xref = $family->getXref(); |
2815
|
|
|
} else { |
2816
|
|
|
$xref = 'new'; |
2817
|
|
|
} |
2818
|
|
|
|
2819
|
|
|
// Different cultures do surnames differently |
2820
|
|
|
$surname_tradition = SurnameTradition::create($controller->tree()->getPreference('SURNAME_TRADITION')); |
2821
|
|
|
|
2822
|
|
|
if ($name_fact !== null) { |
2823
|
|
|
// Editing an existing name |
2824
|
|
|
$name_fact_id = $name_fact->getFactId(); |
2825
|
|
|
$namerec = $name_fact->getGedcom(); |
2826
|
|
|
$name_fields = [ |
2827
|
|
|
'NAME' => $name_fact->getValue(), |
2828
|
|
|
'TYPE' => $name_fact->getAttribute('TYPE'), |
2829
|
|
|
'NPFX' => $name_fact->getAttribute('NPFX'), |
2830
|
|
|
'GIVN' => $name_fact->getAttribute('GIVN'), |
2831
|
|
|
'NICK' => $name_fact->getAttribute('NICK'), |
2832
|
|
|
'SPFX' => $name_fact->getAttribute('SPFX'), |
2833
|
|
|
'SURN' => $name_fact->getAttribute('SURN'), |
2834
|
|
|
'NSFX' => $name_fact->getAttribute('NSFX'), |
2835
|
|
|
]; |
2836
|
|
|
|
2837
|
|
|
// Populate any missing subfields from the NAME field |
2838
|
|
|
$npfx_accept = implode('|', Config::namePrefixes()); |
2839
|
|
|
if (preg_match('/(((' . $npfx_accept . ')\.? +)*)([^\n\/"]*)("(.*)")? *\/(([a-z]{2,3} +)*)(.*)\/ *(.*)/i', $name_fields['NAME'], $name_bits)) { |
2840
|
|
|
$name_fields['NPFX'] = $name_fields['NPFX'] ?: $name_bits[1]; |
2841
|
|
|
$name_fields['GIVN'] = $name_fields['GIVN'] ?: $name_bits[4]; |
2842
|
|
|
$name_fields['NICK'] = $name_fields['NICK'] ?: $name_bits[6]; |
2843
|
|
|
$name_fields['SPFX'] = $name_fields['SPFX'] ?: trim($name_bits[7]); |
2844
|
|
|
$name_fields['SURN'] = $name_fields['SURN'] ?: preg_replace('~/[^/]*/~', ',', $name_bits[9]); |
2845
|
|
|
$name_fields['NSFX'] = $name_fields['NSFX'] ?: $name_bits[10]; |
2846
|
|
|
} |
2847
|
|
|
} else { |
2848
|
|
|
// Creating a new name |
2849
|
|
|
$name_fact_id = null; |
2850
|
|
|
$namerec = null; |
2851
|
|
|
$name_fields = [ |
2852
|
|
|
'NAME' => '', |
2853
|
|
|
'TYPE' => '', |
2854
|
|
|
'NPFX' => '', |
2855
|
|
|
'GIVN' => '', |
2856
|
|
|
'NICK' => '', |
2857
|
|
|
'SPFX' => '', |
2858
|
|
|
'SURN' => '', |
2859
|
|
|
'NSFX' => '', |
2860
|
|
|
]; |
2861
|
|
|
|
2862
|
|
|
// Inherit surname from parents, spouse or child |
2863
|
|
|
if ($family) { |
2864
|
|
|
$father = $family->getHusband(); |
2865
|
|
|
if ($father && $father->getFirstFact('NAME')) { |
2866
|
|
|
$father_name = $father->getFirstFact('NAME')->getValue(); |
2867
|
|
|
} else { |
2868
|
|
|
$father_name = ''; |
2869
|
|
|
} |
2870
|
|
|
$mother = $family->getWife(); |
2871
|
|
|
if ($mother && $mother->getFirstFact('NAME')) { |
2872
|
|
|
$mother_name = $mother->getFirstFact('NAME')->getValue(); |
2873
|
|
|
} else { |
2874
|
|
|
$mother_name = ''; |
2875
|
|
|
} |
2876
|
|
|
} else { |
2877
|
|
|
$father = null; |
2878
|
|
|
$mother = null; |
|
|
|
|
2879
|
|
|
$father_name = ''; |
2880
|
|
|
$mother_name = ''; |
2881
|
|
|
} |
2882
|
|
|
if ($person && $person->getFirstFact('NAME')) { |
2883
|
|
|
$indi_name = $person->getFirstFact('NAME')->getValue(); |
2884
|
|
|
} else { |
2885
|
|
|
$indi_name = ''; |
2886
|
|
|
} |
2887
|
|
|
|
2888
|
|
|
switch ($nextaction) { |
2889
|
|
|
case 'add_child_to_family_action': |
2890
|
|
|
$name_fields = array_merge($name_fields, $surname_tradition->newChildNames($father_name, $mother_name, $gender)); |
2891
|
|
|
break; |
2892
|
|
|
case 'add_child_to_individual_action': |
2893
|
|
|
if ($person->getSex() === 'F') { |
|
|
|
|
2894
|
|
|
$name_fields = array_merge($name_fields, $surname_tradition->newChildNames('', $indi_name, $gender)); |
2895
|
|
|
} else { |
2896
|
|
|
$name_fields = array_merge($name_fields, $surname_tradition->newChildNames($indi_name, '', $gender)); |
2897
|
|
|
} |
2898
|
|
|
break; |
2899
|
|
|
case 'add_parent_to_individual_action': |
2900
|
|
|
$name_fields = array_merge($name_fields, $surname_tradition->newParentNames($indi_name, $gender)); |
2901
|
|
|
break; |
2902
|
|
|
case 'add_spouse_to_family_action': |
2903
|
|
|
if ($father) { |
2904
|
|
|
$name_fields = array_merge($name_fields, $surname_tradition->newSpouseNames($father_name, $gender)); |
2905
|
|
|
} else { |
2906
|
|
|
$name_fields = array_merge($name_fields, $surname_tradition->newSpouseNames($mother_name, $gender)); |
2907
|
|
|
} |
2908
|
|
|
break; |
2909
|
|
|
case 'add_spouse_to_individual_action': |
2910
|
|
|
$name_fields = array_merge($name_fields, $surname_tradition->newSpouseNames($indi_name, $gender)); |
2911
|
|
|
break; |
2912
|
|
|
case 'add_unlinked_indi_action': |
2913
|
|
|
case 'update': |
2914
|
|
|
if ($surname_tradition->hasSurnames()) { |
2915
|
|
|
$name_fields['NAME'] = '//'; |
2916
|
|
|
} |
2917
|
|
|
break; |
2918
|
|
|
} |
2919
|
|
|
} |
2920
|
|
|
|
2921
|
|
|
$bdm = ''; // used to copy '1 SOUR' to '2 SOUR' for BIRT DEAT MARR |
2922
|
|
|
|
2923
|
|
|
echo '<h2>', $controller->getPageTitle(), '</h2>'; |
2924
|
|
|
|
2925
|
|
|
FunctionsPrint::initializeCalendarPopup(); |
2926
|
|
|
echo '<form method="post" name="addchildform" onsubmit="return checkform();">'; |
2927
|
|
|
echo '<input type="hidden" name="ged" value="', $controller->tree()->getNameHtml(), '">'; |
2928
|
|
|
echo '<input type="hidden" name="action" value="', $nextaction, '">'; |
2929
|
|
|
echo '<input type="hidden" name="fact_id" value="', $name_fact_id, '">'; |
2930
|
|
|
echo '<input type="hidden" name="xref" value="', $xref, '">'; |
|
|
|
|
2931
|
|
|
echo '<input type="hidden" name="famtag" value="', $famtag, '">'; |
2932
|
|
|
echo '<input type="hidden" name="gender" value="', $gender, '">'; |
2933
|
|
|
echo Filter::getCsrf(); |
2934
|
|
|
echo '<table class="table wt-facts-table">'; |
2935
|
|
|
|
2936
|
|
|
switch ($nextaction) { |
2937
|
|
|
case 'add_child_to_family_action': |
2938
|
|
|
case 'add_child_to_individual_action': |
2939
|
|
|
// When adding a new child, specify the pedigree |
2940
|
|
|
echo FunctionsEdit::addSimpleTag('0 PEDI'); |
2941
|
|
|
break; |
2942
|
|
|
} |
2943
|
|
|
// First - standard name fields |
2944
|
|
|
foreach ($name_fields as $tag => $value) { |
2945
|
|
|
if (substr_compare($tag, '_', 0, 1) !== 0) { |
2946
|
|
|
echo FunctionsEdit::addSimpleTag('0 ' . $tag . ' ' . $value, '', '', null, $person); |
2947
|
|
|
} |
2948
|
|
|
} |
2949
|
|
|
|
2950
|
|
|
// Second - advanced name fields |
2951
|
|
|
if ($surname_tradition->hasMarriedNames() || preg_match('/\n2 _MARNM /', $namerec)) { |
2952
|
|
|
$adv_name_fields = ['_MARNM' => '']; |
2953
|
|
|
} else { |
2954
|
|
|
$adv_name_fields = []; |
2955
|
|
|
} |
2956
|
|
|
if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $controller->tree()->getPreference('ADVANCED_NAME_FACTS'), $match)) { |
2957
|
|
|
foreach ($match[1] as $tag) { |
2958
|
|
|
// Ignore advanced facts that duplicate standard facts |
2959
|
|
|
if (!in_array($tag, ['TYPE', 'NPFX', 'GIVN', 'NICK', 'SPFX', 'SURN', 'NSFX'])) { |
2960
|
|
|
$adv_name_fields[$tag] = ''; |
2961
|
|
|
} |
2962
|
|
|
} |
2963
|
|
|
} |
2964
|
|
|
|
2965
|
|
|
foreach (array_keys($adv_name_fields) as $tag) { |
2966
|
|
|
// Edit existing tags, grouped together |
2967
|
|
|
if (preg_match_all('/2 ' . $tag . ' (.+)/', $namerec, $match)) { |
2968
|
|
View Code Duplication |
foreach ($match[1] as $value) { |
2969
|
|
|
echo FunctionsEdit::addSimpleTag('2 ' . $tag . ' ' . $value, '', GedcomTag::getLabel('NAME:' . $tag, $person)); |
2970
|
|
|
if ($tag === '_MARNM') { |
2971
|
|
|
preg_match_all('/\/([^\/]*)\//', $value, $matches); |
2972
|
|
|
echo FunctionsEdit::addSimpleTag('2 _MARNM_SURN ' . implode(',', $matches[1])); |
2973
|
|
|
} |
2974
|
|
|
} |
2975
|
|
|
} |
2976
|
|
|
// Allow a new tag to be entered |
2977
|
|
|
if (!array_key_exists($tag, $name_fields)) { |
2978
|
|
|
echo FunctionsEdit::addSimpleTag('0 ' . $tag, '', GedcomTag::getLabel('NAME:' . $tag, $person)); |
2979
|
|
|
if ($tag === '_MARNM') { |
2980
|
|
|
echo FunctionsEdit::addSimpleTag('0 _MARNM_SURN'); |
2981
|
|
|
} |
2982
|
|
|
} |
2983
|
|
|
} |
2984
|
|
|
|
2985
|
|
|
// Third - new/existing custom name fields |
2986
|
|
View Code Duplication |
foreach ($name_fields as $tag => $value) { |
2987
|
|
|
if (substr_compare($tag, '_', 0, 1) === 0) { |
2988
|
|
|
echo FunctionsEdit::addSimpleTag('0 ' . $tag . ' ' . $value); |
2989
|
|
|
if ($tag === '_MARNM') { |
2990
|
|
|
preg_match_all('/\/([^\/]*)\//', $value, $matches); |
2991
|
|
|
echo FunctionsEdit::addSimpleTag('2 _MARNM_SURN ' . implode(',', $matches[1])); |
2992
|
|
|
} |
2993
|
|
|
} |
2994
|
|
|
} |
2995
|
|
|
|
2996
|
|
|
// Fourth - SOUR, NOTE, _CUSTOM, etc. |
2997
|
|
|
if ($namerec) { |
|
|
|
|
2998
|
|
|
$gedlines = explode("\n", $namerec); // -- find the number of lines in the record |
2999
|
|
|
$fields = explode(' ', $gedlines[0]); |
3000
|
|
|
$glevel = $fields[0]; |
3001
|
|
|
$level = $glevel; |
3002
|
|
|
$type = $fields[1]; |
3003
|
|
|
$tags = []; |
3004
|
|
|
$i = 0; |
3005
|
|
|
do { |
3006
|
|
|
if ($type !== 'TYPE' && !array_key_exists($type, $name_fields) && !array_key_exists($type, $adv_name_fields)) { |
3007
|
|
|
$text = ''; |
3008
|
|
View Code Duplication |
for ($j = 2; $j < count($fields); $j++) { |
|
|
|
|
3009
|
|
|
if ($j > 2) { |
3010
|
|
|
$text .= ' '; |
3011
|
|
|
} |
3012
|
|
|
$text .= $fields[$j]; |
3013
|
|
|
} |
3014
|
|
View Code Duplication |
while (($i + 1 < count($gedlines)) && (preg_match('/' . ($level + 1) . ' CONT ?(.*)/', $gedlines[$i + 1], $cmatch) > 0)) { |
3015
|
|
|
$text .= "\n" . $cmatch[1]; |
3016
|
|
|
$i++; |
3017
|
|
|
} |
3018
|
|
|
echo FunctionsEdit::addSimpleTag($level . ' ' . $type . ' ' . $text); |
|
|
|
|
3019
|
|
|
} |
3020
|
|
|
$tags[] = $type; |
3021
|
|
|
$i++; |
3022
|
|
|
if (isset($gedlines[$i])) { |
3023
|
|
|
$fields = explode(' ', $gedlines[$i]); |
3024
|
|
|
$level = $fields[0]; |
3025
|
|
|
if (isset($fields[1])) { |
3026
|
|
|
$type = $fields[1]; |
3027
|
|
|
} |
3028
|
|
|
} |
3029
|
|
|
} while (($level > $glevel) && ($i < count($gedlines))); |
3030
|
|
|
} |
3031
|
|
|
|
3032
|
|
|
// If we are adding a new individual, add the basic details |
3033
|
|
|
if ($nextaction !== 'update') { |
3034
|
|
|
echo '</table><br><table class="table wt-facts-table">'; |
3035
|
|
|
// 1 SEX |
3036
|
|
|
if ($famtag === 'HUSB' || $gender === 'M') { |
3037
|
|
|
echo FunctionsEdit::addSimpleTag('0 SEX M'); |
3038
|
|
|
} elseif ($famtag === 'WIFE' || $gender === 'F') { |
3039
|
|
|
echo FunctionsEdit::addSimpleTag('0 SEX F'); |
3040
|
|
|
} else { |
3041
|
|
|
echo FunctionsEdit::addSimpleTag('0 SEX U'); |
3042
|
|
|
} |
3043
|
|
|
$bdm = 'BD'; |
3044
|
|
View Code Duplication |
if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $controller->tree()->getPreference('QUICK_REQUIRED_FACTS'), $matches)) { |
3045
|
|
|
foreach ($matches[1] as $match) { |
3046
|
|
|
if (!in_array($match, explode('|', WT_EVENTS_DEAT))) { |
3047
|
|
|
echo FunctionsEdit::addSimpleTags($match); |
3048
|
|
|
} |
3049
|
|
|
} |
3050
|
|
|
} |
3051
|
|
|
//-- if adding a spouse add the option to add a marriage fact to the new family |
3052
|
|
|
if ($nextaction === 'add_spouse_to_individual_action' || $nextaction === 'add_spouse_to_family_action') { |
3053
|
|
|
$bdm .= 'M'; |
3054
|
|
View Code Duplication |
if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $controller->tree()->getPreference('QUICK_REQUIRED_FAMFACTS'), $matches)) { |
3055
|
|
|
foreach ($matches[1] as $match) { |
3056
|
|
|
echo FunctionsEdit::addSimpleTags($match); |
3057
|
|
|
} |
3058
|
|
|
} |
3059
|
|
|
} |
3060
|
|
View Code Duplication |
if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $controller->tree()->getPreference('QUICK_REQUIRED_FACTS'), $matches)) { |
3061
|
|
|
foreach ($matches[1] as $match) { |
3062
|
|
|
if (in_array($match, explode('|', WT_EVENTS_DEAT))) { |
3063
|
|
|
echo FunctionsEdit::addSimpleTags($match); |
3064
|
|
|
} |
3065
|
|
|
} |
3066
|
|
|
} |
3067
|
|
|
} |
3068
|
|
|
|
3069
|
|
|
echo keep_chan($person); |
3070
|
|
|
echo '</table>'; |
3071
|
|
|
if ($nextaction === 'update') { |
3072
|
|
|
// GEDCOM 5.5.1 spec says NAME doesn’t get a OBJE |
3073
|
|
|
FunctionsEdit::printAddLayer('SOUR'); |
3074
|
|
|
FunctionsEdit::printAddLayer('NOTE'); |
3075
|
|
|
FunctionsEdit::printAddLayer('SHARED_NOTE'); |
3076
|
|
|
FunctionsEdit::printAddLayer('RESN'); |
3077
|
|
|
} else { |
3078
|
|
|
FunctionsEdit::printAddLayer('SOUR', 1); |
3079
|
|
|
FunctionsEdit::printAddLayer('NOTE', 1); |
3080
|
|
|
FunctionsEdit::printAddLayer('SHARED_NOTE', 1); |
3081
|
|
|
FunctionsEdit::printAddLayer('RESN', 1); |
3082
|
|
|
} |
3083
|
|
|
|
3084
|
|
|
?> |
3085
|
|
|
<div class="row form-group"> |
3086
|
|
|
<div class="col-sm-9 offset-sm-3"> |
3087
|
|
|
<button class="btn btn-primary" type="submit"> |
3088
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
3089
|
|
|
<?= /* I18N: A button label. */ I18N::translate('save') ?> |
3090
|
|
|
</button> |
3091
|
|
|
<?php if (preg_match('/^add_(child|spouse|parent|unlinked_indi)/', $nextaction)): ?> |
3092
|
|
|
|
3093
|
|
|
<button class="btn btn-primary" type="submit" name="goto" value="<?= $xref ?>"> |
|
|
|
|
3094
|
|
|
<?= FontAwesome::decorativeIcon('save') ?> |
3095
|
|
|
<?= /* I18N: A button label. */ I18N::translate('go to new individual') ?> |
3096
|
|
|
</button> |
3097
|
|
|
<?php endif ?> |
3098
|
|
|
<a class="btn btn-secondary" href="<?= Html::escape($person ? $person->getRawUrl() : $family->getRawUrl()) ?>"> |
|
|
|
|
3099
|
|
|
<?= FontAwesome::decorativeIcon('cancel') ?> |
3100
|
|
|
<?= /* I18N: A button label. */ I18N::translate('cancel') ?> |
3101
|
|
|
</a> |
3102
|
|
View Code Duplication |
<?php if ($name_fact !== null && (Auth::isAdmin() || $controller->tree()->getPreference('SHOW_GEDCOM_RECORD'))): ?> |
3103
|
|
|
<a class="btn btn-link" |
3104
|
|
|
href="edit_interface.php?action=editrawfact&xref=<?= $xref ?>&fact_id=<?= $name_fact->getFactId() ?>&ged=<?= $controller->tree()->getNameUrl() ?>"> |
|
|
|
|
3105
|
|
|
<?= I18N::translate('Edit the raw GEDCOM') ?> |
3106
|
|
|
</a> |
3107
|
|
|
<?php endif ?> |
3108
|
|
|
</div> |
3109
|
|
|
</div> |
3110
|
|
|
</form> |
3111
|
|
|
|
3112
|
|
|
<?php |
3113
|
|
|
$controller->addInlineJavascript(' |
3114
|
|
|
SURNAME_TRADITION="' . $controller->tree()->getPreference('SURNAME_TRADITION') . '"; |
3115
|
|
|
gender="' . $gender . '"; |
3116
|
|
|
famtag="' . $famtag . '"; |
3117
|
|
|
function trim(str) { |
3118
|
|
|
str=str.replace(/\s\s+/g, " "); |
3119
|
|
|
return str.replace(/(^\s+)|(\s+$)/g, ""); |
3120
|
|
|
} |
3121
|
|
|
|
3122
|
|
|
function lang_class(str) { |
3123
|
|
|
if (str.match(/[\u0370-\u03FF]/)) return "greek"; |
3124
|
|
|
if (str.match(/[\u0400-\u04FF]/)) return "cyrillic"; |
3125
|
|
|
if (str.match(/[\u0590-\u05FF]/)) return "hebrew"; |
3126
|
|
|
if (str.match(/[\u0600-\u06FF]/)) return "arabic"; |
3127
|
|
|
return "latin"; // No matched text implies latin :-) |
3128
|
|
|
} |
3129
|
|
|
|
3130
|
|
|
// Generate a full name from the name components |
3131
|
|
|
function generate_name() { |
3132
|
|
|
var npfx = $("#NPFX").val(); |
3133
|
|
|
var givn = $("#GIVN").val(); |
3134
|
|
|
var spfx = $("#SPFX").val(); |
3135
|
|
|
var surn = $("#SURN").val(); |
3136
|
|
|
var nsfx = $("#NSFX").val(); |
3137
|
|
|
if (SURNAME_TRADITION === "polish" && (gender === "F" || famtag === "WIFE")) { |
3138
|
|
|
surn = surn.replace(/ski$/, "ska"); |
3139
|
|
|
surn = surn.replace(/cki$/, "cka"); |
3140
|
|
|
surn = surn.replace(/dzki$/, "dzka"); |
3141
|
|
|
surn = surn.replace(/żki$/, "żka"); |
3142
|
|
|
} |
3143
|
|
|
// Commas are used in the GIVN and SURN field to separate lists of surnames. |
3144
|
|
|
// For example, to differentiate the two Spanish surnames from an English |
3145
|
|
|
// double-barred name. |
3146
|
|
|
// Commas *may* be used in other fields, and will form part of the NAME. |
3147
|
|
|
if (WT_LOCALE === "vi" || WT_LOCALE === "hu") { |
3148
|
|
|
// Default format: /SURN/ GIVN |
3149
|
|
|
return trim(npfx+" /"+trim(spfx+" "+surn).replace(/ *, */g, " ")+"/ "+givn.replace(/ *, */g, " ")+" "+nsfx); |
3150
|
|
|
} else if (WT_LOCALE === "zh-Hans" || WT_LOCALE === "zh-Hant") { |
3151
|
|
|
// Default format: /SURN/GIVN |
3152
|
|
|
return npfx+"/"+spfx+surn+"/"+givn+nsfx; |
3153
|
|
|
} else { |
3154
|
|
|
// Default format: GIVN /SURN/ |
3155
|
|
|
return trim(npfx+" "+givn.replace(/ *, */g, " ")+" /"+trim(spfx+" "+surn).replace(/ *, */g, " ")+"/ "+nsfx); |
3156
|
|
|
} |
3157
|
|
|
} |
3158
|
|
|
|
3159
|
|
|
// Update the NAME and _MARNM fields from the name components |
3160
|
|
|
// and also display the value in read-only "gedcom" format. |
3161
|
|
|
function updatewholename() { |
3162
|
|
|
// Don’t update the name if the user manually changed it |
3163
|
|
|
if (manualChange) { |
3164
|
|
|
return; |
3165
|
|
|
} |
3166
|
|
|
var npfx = $("#NPFX").val(); |
3167
|
|
|
var givn = $("#GIVN").val(); |
3168
|
|
|
var spfx = $("#SPFX").val(); |
3169
|
|
|
var surn = $("#SURN").val(); |
3170
|
|
|
var nsfx = $("#NSFX").val(); |
3171
|
|
|
var name = generate_name(); |
3172
|
|
|
$("#NAME").val(name); |
3173
|
|
|
$("#NAME_display").text(name); |
3174
|
|
|
// Married names inherit some NSFX values, but not these |
3175
|
|
|
nsfx = nsfx.replace(/^(I|II|III|IV|V|VI|Junior|Jr\.?|Senior|Sr\.?)$/i, ""); |
3176
|
|
|
// Update _MARNM field from _MARNM_SURN field and display it |
3177
|
|
|
// Be careful of mixing latin/hebrew/etc. character sets. |
3178
|
|
|
var ip = document.getElementsByTagName("input"); |
3179
|
|
|
var marnm_id = ""; |
3180
|
|
|
var romn = ""; |
3181
|
|
|
var heb = ""; |
3182
|
|
|
for (var i = 0; i < ip.length; i++) { |
3183
|
|
|
var val = trim(ip[i].value); |
3184
|
|
|
if (ip[i].id.indexOf("_HEB") === 0) |
3185
|
|
|
heb = val; |
3186
|
|
|
if (ip[i].id.indexOf("ROMN") === 0) |
3187
|
|
|
romn = val; |
3188
|
|
|
if (ip[i].id.indexOf("_MARNM") === 0) { |
3189
|
|
|
if (ip[i].id.indexOf("_MARNM_SURN") === 0) { |
3190
|
|
|
var msurn = ""; |
3191
|
|
|
if (val !== "") { |
3192
|
|
|
var lc = lang_class(document.getElementById(ip[i].id).value); |
3193
|
|
|
if (lang_class(name) === lc) |
3194
|
|
|
msurn = trim(npfx + " " + givn + " /" + val + "/ " + nsfx); |
3195
|
|
|
else if (lc === "hebrew") |
3196
|
|
|
msurn = heb.replace(/\/.*\//, "/" + val + "/"); |
3197
|
|
|
else if (lang_class(romn) === lc) |
3198
|
|
|
msurn = romn.replace(/\/.*\//, "/" + val + "/"); |
3199
|
|
|
} |
3200
|
|
|
document.getElementById(marnm_id).value = msurn; |
3201
|
|
|
document.getElementById(marnm_id+"_display").innerHTML = msurn; |
3202
|
|
|
} else { |
3203
|
|
|
marnm_id = ip[i].id; |
3204
|
|
|
} |
3205
|
|
|
} |
3206
|
|
|
} |
3207
|
|
|
} |
3208
|
|
|
|
3209
|
|
|
// Toggle the name editor fields between |
3210
|
|
|
// <input type="hidden"> <span style="display:inline"> |
3211
|
|
|
// <input type="text"> <span style="display:none"> |
3212
|
|
|
var oldName = ""; |
3213
|
|
|
|
3214
|
|
|
// Calls to generate_name() trigger an update - hence need to |
3215
|
|
|
// set the manual change to true first. We are probably |
3216
|
|
|
// listening to the wrong events on the input fields... |
3217
|
|
|
var manualChange = true; |
3218
|
|
|
manualChange = generate_name() !== $("#NAME").val(); |
3219
|
|
|
|
3220
|
|
|
function convertHidden(eid) { |
3221
|
|
|
var input1 = $("#" + eid); |
3222
|
|
|
var input2 = $("#" + eid + "_display"); |
3223
|
|
|
// Note that IE does not allow us to change the type of an input, so we must create a new one. |
3224
|
|
|
if (input1.attr("type")=="hidden") { |
3225
|
|
|
input1.replaceWith(input1.clone().attr("type", "text")); |
3226
|
|
|
input2.hide(); |
3227
|
|
|
} else { |
3228
|
|
|
input1.replaceWith(input1.clone().attr("type", "hidden")); |
3229
|
|
|
input2.show(); |
3230
|
|
|
} |
3231
|
|
|
} |
3232
|
|
|
|
3233
|
|
|
/** |
3234
|
|
|
* if the user manually changed the NAME field, then update the textual |
3235
|
|
|
* HTML representation of it |
3236
|
|
|
* If the value changed set manualChange to true so that changing |
3237
|
|
|
* the other fields doesn’t change the NAME line |
3238
|
|
|
*/ |
3239
|
|
|
function updateTextName(eid) { |
3240
|
|
|
var element = document.getElementById(eid); |
3241
|
|
|
if (element) { |
3242
|
|
|
if (element.value!=oldName) manualChange = true; |
3243
|
|
|
var delement = document.getElementById(eid+"_display"); |
3244
|
|
|
if (delement) { |
3245
|
|
|
delement.innerHTML = element.value; |
3246
|
|
|
} |
3247
|
|
|
} |
3248
|
|
|
} |
3249
|
|
|
|
3250
|
|
|
function checkform() { |
3251
|
|
|
var ip=document.getElementsByTagName("input"); |
3252
|
|
|
for (var i=0; i<ip.length; i++) { |
3253
|
|
|
// ADD slashes to _HEB and _AKA names |
3254
|
|
|
if (ip[i].id.indexOf("_AKA")==0 || ip[i].id.indexOf("_HEB")==0 || ip[i].id.indexOf("ROMN")==0) |
3255
|
|
|
if (ip[i].value.indexOf("/")<0 && ip[i].value!="") |
3256
|
|
|
ip[i].value=ip[i].value.replace(/([^\s]+)\s*$/, "/$1/"); |
3257
|
|
|
// Blank out temporary _MARNM_SURN |
3258
|
|
|
if (ip[i].id.indexOf("_MARNM_SURN")==0) |
3259
|
|
|
ip[i].value=""; |
3260
|
|
|
// Convert "xxx yyy" and "xxx y yyy" surnames to "xxx,yyy" |
3261
|
|
|
if ((SURNAME_TRADITION=="spanish" || "SURNAME_TRADITION"=="portuguese") && ip[i].id.indexOf("SURN")==0) { |
3262
|
|
|
ip[i].value=document.forms[0].SURN.value.replace(/^\s*([^\s,]{2,})\s+([iIyY] +)?([^\s,]{2,})\s*$/, "$1,$3"); |
3263
|
|
|
} |
3264
|
|
|
} |
3265
|
|
|
return true; |
3266
|
|
|
} |
3267
|
|
|
|
3268
|
|
|
// If the name isn’t initially formed from the components in a standard way, |
3269
|
|
|
// then don’t automatically update it. |
3270
|
|
|
if (document.getElementById("NAME").value!=generate_name() && document.getElementById("NAME").value!="//") { |
3271
|
|
|
convertHidden("NAME"); |
3272
|
|
|
} |
3273
|
|
|
'); |
3274
|
|
|
} |
3275
|
|
|
|
3276
|
|
|
/** |
3277
|
|
|
* Can we edit a GedcomRecord object |
3278
|
|
|
* |
3279
|
|
|
* @param GedcomRecord $record |
3280
|
|
|
*/ |
3281
|
|
|
function check_record_access(GedcomRecord $record = null) { |
3282
|
|
|
if (!$record || !$record->canShow() || !$record->canEdit()) { |
3283
|
|
|
header('Location: ' . $record->getRawUrl()); |
|
|
|
|
3284
|
|
|
|
3285
|
|
|
exit; |
|
|
|
|
3286
|
|
|
} |
3287
|
|
|
} |
3288
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.