print_indi_form()   F
last analyzed

Complexity

Conditions 82
Paths 0

Size

Total Lines 460
Code Lines 209

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 82
eloc 209
nc 0
nop 6
dl 0
loc 460
rs 3.3333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * webtrees: online genealogy
4
 * Copyright (C) 2019 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
namespace Fisharebest\Webtrees;
17
18
/**
19
 * Defined in session.php
20
 *
21
 * @global Tree $WT_TREE
22
 */
23
global $WT_TREE;
24
25
use Fisharebest\Webtrees\Controller\SimpleController;
26
use Fisharebest\Webtrees\Functions\FunctionsEdit;
27
use Fisharebest\Webtrees\Functions\FunctionsPrint;
28
use Fisharebest\Webtrees\GedcomCode\GedcomCodePedi;
29
30
define('WT_SCRIPT_NAME', 'edit_interface.php');
31
require './includes/session.php';
32
33
$action = Filter::post('action', null, Filter::get('action'));
34
35
$controller = new SimpleController;
36
$controller
37
    ->restrictAccess(Auth::isEditor($WT_TREE))
38
    ->addExternalJavascript(WT_AUTOCOMPLETE_JS_URL)
39
    ->addInlineJavascript('autocomplete();')
40
    ->addInlineJavascript('var locale_date_format="' . preg_replace('/[^DMY]/', '', str_replace(array('j', 'F'), array('D', 'M'), I18N::dateFormat())) . '";');
41
42
switch ($action) {
43
////////////////////////////////////////////////////////////////////////////////
44
    case 'editraw':
45
        $xref = Filter::get('xref', WT_REGEX_XREF);
46
47
        $record = GedcomRecord::getInstance($xref, $WT_TREE);
48
        check_record_access($record);
49
50
        $controller
51
        ->setPageTitle($record->getFullName() . ' - ' . I18N::translate('Edit the raw GEDCOM'))
52
        ->pageHeader()
53
        ->addInlineJavascript('jQuery("#raw-gedcom-list").sortable({opacity: 0.7, cursor: "move", axis: "y"});');
54
55
        ?>
56
    <div id="edit_interface-page">
57
        <h2>
58
            <?php echo $controller->getPageTitle(); ?>
59
            <?php echo FunctionsPrint::helpLink('edit_edit_raw'); ?>
60
        </h2>
61
        <pre>     <?php echo '0 @' . $record->getXref() . '@ ' . $record::RECORD_TYPE; ?></pre>
62
        <form method="post" action="edit_interface.php">
63
            <input type="hidden" name="ged" value="<?php echo $WT_TREE->getNameHtml(); ?>">
64
            <input type="hidden" name="action" value="updateraw">
65
            <input type="hidden" name="xref" value="<?php echo $xref; ?>">
66
            <?php echo Filter::getCsrf(); ?>
67
            <ul id="raw-gedcom-list">
68
                <?php foreach ($record->getFacts() as $fact) { ?>
69
                    <?php if (!$fact->isPendingDeletion()) { ?>
70
                    <li>
71
                        <div style="cursor:move;">
72
                            <?php echo $fact->summary(); ?>
73
                        </div>
74
                        <input type="hidden" name="fact_id[]" value="<?php echo $fact->getFactId(); ?>">
75
                        <textarea name="fact[]" dir="ltr" rows="<?php echo preg_match_all('/\n/', $fact->getGedcom(), $dummy_parameter_for_php53); ?>" style="width:100%;"><?php echo Filter::escapeHtml($fact->getGedcom()); ?></textarea>
76
                    </li>
77
                    <?php } ?>
78
                <?php } ?>
79
                <li>
80
                    <div style="cursor:move;">
81
                        <b><i><?php echo I18N::translate('Add a fact'); ?><i></b>
82
                    </div>
83
                    <input type="hidden" name="fact_id[]" value="">
84
                    <textarea name="fact[]" dir="ltr" rows="2" style="width:100%;"></textarea>
85
                </li>
86
            </ul>
87
            <p id="save-cancel">
88
                <input type="submit" class="save" value="<?php echo I18N::translate('save'); ?>">
89
                <input type="button" class="cancel" value="<?php echo I18N::translate('close'); ?>" onclick="window.close();">
90
            </p>
91
        </form>
92
    </div>
93
        <?php
94
        break;
95
96
////////////////////////////////////////////////////////////////////////////////
97
    case 'updateraw':
98
        $xref      = Filter::post('xref', WT_REGEX_XREF);
99
        $facts     = Filter::postArray('fact');
100
        $fact_ids  = Filter::postArray('fact_id');
101
102
        if (!Filter::checkCsrf()) {
103
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=editraw&xref=' . $xref);
104
105
            return;
106
        }
107
108
        $record = GedcomRecord::getInstance($xref, $WT_TREE);
109
        check_record_access($record);
110
111
        $controller
112
        ->setPageTitle($record->getFullName() . ' - ' . I18N::translate('Edit the raw GEDCOM'))
113
        ->pageHeader();
114
115
        $gedcom = '0 @' . $record->getXref() . '@ ' . $record::RECORD_TYPE;
116
117
        // Retain any private facts
118
        foreach ($record->getFacts(null, false, Auth::PRIV_HIDE) as $fact) {
119
            if (!in_array($fact->getFactId(), $fact_ids) && !$fact->isPendingDeletion()) {
120
                $gedcom .= "\n" . $fact->getGedcom();
121
            }
122
        }
123
        // Append the new facts
124
        foreach ($facts as $fact) {
125
            $gedcom .= "\n" . $fact;
126
        }
127
128
        // Cleanup the client’s bad editing?
129
        $gedcom = preg_replace('/[\r\n]+/', "\n", $gedcom); // Empty lines
130
        $gedcom = trim($gedcom); // Leading/trailing spaces
131
132
        $record->updateRecord($gedcom, false);
133
134
        $controller->addInlineJavascript('closePopupAndReloadParent();');
135
        break;
136
137
////////////////////////////////////////////////////////////////////////////////
138
    case 'editrawfact':
139
        $xref    = Filter::get('xref', WT_REGEX_XREF);
140
        $fact_id = Filter::get('fact_id');
141
142
        $record = GedcomRecord::getInstance($xref, $WT_TREE);
143
        check_record_access($record);
144
145
        // Find the fact to edit
146
        $edit_fact = null;
147
        foreach ($record->getFacts() as $fact) {
148
            if ($fact->getFactId() === $fact_id && $fact->canEdit()) {
149
                $edit_fact = $fact;
150
                break;
151
            }
152
        }
153
        if (!$edit_fact) {
154
            $controller
155
            ->pageHeader()
156
            ->addInlineJavascript('closePopupAndReloadParent();');
157
158
            return;
159
        }
160
161
        $controller
162
        ->setPageTitle($record->getFullName() . ' - ' . I18N::translate('Edit the raw GEDCOM'))
163
        ->pageHeader();
164
165
        ?>
166
    <div id="edit_interface-page">
167
        <h2>
168
            <?php echo $controller->getPageTitle(); ?>
169
            <?php echo FunctionsPrint::helpLink('edit_edit_raw'); ?>
170
            <?php FunctionsPrint::printSpecialCharacterLink('gedcom'); ?>
171
        </h2>
172
        <form method="post" action="edit_interface.php">
173
            <input type="hidden" name="ged" value="<?php echo $WT_TREE->getNameHtml(); ?>">
174
            <input type="hidden" name="action" value="updaterawfact">
175
            <input type="hidden" name="xref" value="<?php echo $xref; ?>">
176
            <input type="hidden" name="fact_id" value="<?php echo $fact_id; ?>">
177
            <?php echo Filter::getCsrf(); ?>
178
            <textarea name="gedcom" id="gedcom" dir="ltr"><?php echo Filter::escapeHtml($edit_fact->getGedcom()); ?></textarea>
179
            <table class="facts_table">
180
                <?php echo keep_chan($record); ?>
181
            </table>
182
            <p id="save-cancel">
183
                <input type="submit" class="save" value="<?php echo I18N::translate('save'); ?>">
184
                <input type="button" class="cancel" value="<?php echo I18N::translate('close'); ?>" onclick="window.close();">
185
            </p>
186
        </form>
187
    </div>
188
        <?php
189
        break;
190
191
////////////////////////////////////////////////////////////////////////////////
192
    case 'updaterawfact':
193
        $xref      = Filter::post('xref', WT_REGEX_XREF);
194
        $fact_id   = Filter::post('fact_id');
195
        $gedcom    = Filter::post('gedcom');
196
        $keep_chan = Filter::postBool('keep_chan');
197
198
        if (!Filter::checkCsrf()) {
199
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=editrawfact&xref=' . $xref . '&fact_id=' . $fact_id);
200
201
            return;
202
        }
203
204
        $record = GedcomRecord::getInstance($xref, $WT_TREE);
205
        check_record_access($record);
206
207
        // Find the fact to edit
208
        $edit_fact = null;
209
        foreach ($record->getFacts() as $fact) {
210
            if ($fact->getFactId() === $fact_id && $fact->canEdit()) {
211
                $edit_fact = $fact;
212
                break;
213
            }
214
        }
215
        if (!$edit_fact) {
216
            $controller
217
            ->pageHeader()
218
            ->addInlineJavascript('closePopupAndReloadParent();');
219
220
            return;
221
        }
222
223
        $controller
224
        ->setPageTitle($record->getFullName() . ' - ' . I18N::translate('Edit the raw GEDCOM'))
225
        ->pageHeader();
226
227
        // Cleanup the client’s bad editing?
228
        $gedcom = preg_replace('/[\r\n]+/', "\n", $gedcom); // Empty lines
229
        $gedcom = trim($gedcom); // Leading/trailing spaces
230
231
        $record->updateFact($fact_id, $gedcom, !$keep_chan);
232
233
        $controller->addInlineJavascript('closePopupAndReloadParent();');
234
        break;
235
236
////////////////////////////////////////////////////////////////////////////////
237
    case 'edit':
238
        $xref    = Filter::get('xref', WT_REGEX_XREF);
239
        $fact_id = Filter::get('fact_id');
240
241
        $record = GedcomRecord::getInstance($xref, $WT_TREE);
242
        check_record_access($record);
243
244
        // Find the fact to edit
245
        $edit_fact = null;
246
        foreach ($record->getFacts() as $fact) {
247
            if ($fact->getFactId() === $fact_id && $fact->canEdit()) {
248
                $edit_fact = $fact;
249
                break;
250
            }
251
        }
252
        if (!$edit_fact) {
253
            $controller
254
            ->pageHeader()
255
            ->addInlineJavascript('closePopupAndReloadParent();');
256
257
            return;
258
        }
259
260
        $controller
261
        ->setPageTitle($record->getFullName() . ' - ' . I18N::translate('Edit'))
262
        ->pageHeader();
263
264
        echo '<div id="edit_interface-page">';
265
        echo '<h2>', $controller->getPageTitle(), '</h2>';
266
        FunctionsPrint::initializeCalendarPopup();
267
        echo '<form name="editform" method="post" action="edit_interface.php" enctype="multipart/form-data">';
268
        echo '<input type="hidden" name="ged" value="', $WT_TREE->getNameHtml(), '">';
269
        echo '<input type="hidden" name="action" value="update">';
270
        echo '<input type="hidden" name="fact_id" value="', $fact_id, '">';
271
        echo '<input type="hidden" name="xref" value="', $xref, '">';
272
        echo '<input type="hidden" name="prev_action" value="edit">';
273
        echo Filter::getCsrf();
274
        echo '<table class="facts_table">';
275
        FunctionsEdit::createEditForm($edit_fact);
276
        echo keep_chan($record);
277
        echo '</table>';
278
279
        $level1type = $edit_fact->getTag();
280
        switch ($record::RECORD_TYPE) {
281
            case 'REPO':
282
                // REPO:NAME facts may take a NOTE (but the REPO record may not).
283
                if ($level1type === 'NAME') {
284
                    FunctionsEdit::printAddLayer('NOTE');
285
                    FunctionsEdit::printAddLayer('SHARED_NOTE');
286
                }
287
            break;
288
            case 'FAM':
289
            case 'INDI':
290
                // FAM and INDI records have real facts. They can take NOTE/SOUR/OBJE/etc.
291
                if ($level1type !== 'SEX' && $level1type !== 'NOTE' && $level1type !== 'ALIA') {
292
                    if ($level1type !== 'SOUR') {
293
                        FunctionsEdit::printAddLayer('SOUR');
294
                    }
295
                    if ($level1type !== 'OBJE') {
296
                        FunctionsEdit::printAddLayer('OBJE');
297
                    }
298
                    FunctionsEdit::printAddLayer('NOTE');
299
                    FunctionsEdit::printAddLayer('SHARED_NOTE', 2, $level1type);
300
                    if ($level1type !== 'ASSO' && $level1type !== 'NOTE' && $level1type !== 'SOUR') {
301
                        FunctionsEdit::printAddLayer('ASSO');
302
                    }
303
                    // allow to add godfather and godmother for CHR fact or best man and bridesmaid  for MARR fact in one window
304
                    if (in_array($level1type, Config::twoAssociates())) {
305
                        FunctionsEdit::printAddLayer('ASSO2');
306
                    }
307
                    if ($level1type !== 'SOUR') {
308
                        FunctionsEdit::printAddLayer('RESN');
309
                    }
310
                }
311
            break;
312
            default:
313
                // Other types of record do not have these lower-level records
314
            break;
315
        }
316
        if (Auth::isAdmin() || $WT_TREE->getPreference('SHOW_GEDCOM_RECORD')) {
317
            echo
318
            '<br><br><a href="edit_interface.php?action=editrawfact&amp;xref=', $xref, '&amp;fact_id=', $fact_id, '&amp;ged=', $WT_TREE->getNameUrl(), '">',
319
            I18N::translate('Edit the raw GEDCOM'),
320
            '</a>';
321
        }
322
        ?>
323
        <p id="save-cancel">
324
            <input type="submit" class="save" value="<?php echo I18N::translate('save'); ?>">
325
            <input type="button" class="cancel" value="<?php echo I18N::translate('close'); ?>" onclick="window.close();">
326
        </p>
327
    </form>
328
    </div>
329
        <?php
330
        break;
331
332
////////////////////////////////////////////////////////////////////////////////
333
    case 'add':
334
        $xref = Filter::get('xref', WT_REGEX_XREF);
335
        $fact = Filter::get('fact', WT_REGEX_TAG);
336
337
        $record = GedcomRecord::getInstance($xref, $WT_TREE);
338
        check_record_access($record);
339
340
        $controller
341
        ->setPageTitle($record->getFullName() . ' - ' . GedcomTag::getLabel($fact, $record))
342
        ->pageHeader();
343
344
        $level0type = $record::RECORD_TYPE;
345
346
        echo '<div id="edit_interface-page">';
347
        echo '<h2>', $controller->getPageTitle(), '</h2>';
348
349
        FunctionsPrint::initializeCalendarPopup();
350
        echo '<form name="addform" method="post" action="edit_interface.php" enctype="multipart/form-data">';
351
        echo '<input type="hidden" name="ged" value="', $WT_TREE->getNameHtml(), '">';
352
        echo '<input type="hidden" name="action" value="update">';
353
        echo '<input type="hidden" name="xref" value="', $xref, '">';
354
        echo '<input type="hidden" name="prev_action" value="add">';
355
        echo '<input type="hidden" name="fact_type" value="' . $fact . '">';
356
        echo Filter::getCsrf();
357
        echo '<table class="facts_table">';
358
359
        FunctionsEdit::createAddForm($fact);
360
361
        echo keep_chan($record);
362
        echo '</table>';
363
364
        // Genealogical facts (e.g. for INDI and FAM records) can have 2 SOUR/NOTE/OBJE/ASSO/RESN ...
365
        if ($level0type === 'INDI' || $level0type === 'FAM') {
366
            // ... but not facts which are simply links to other records
367
            if ($fact !== 'OBJE' && $fact !== 'NOTE' && $fact !== 'SHARED_NOTE' && $fact !== 'REPO' && $fact !== 'SOUR' && $fact !== 'ASSO' && $fact !== 'ALIA') {
368
                FunctionsEdit::printAddLayer('SOUR');
369
                FunctionsEdit::printAddLayer('OBJE');
370
                // Don’t add notes to notes!
371
                if ($fact !== 'NOTE') {
372
                    FunctionsEdit::printAddLayer('NOTE');
373
                    FunctionsEdit::printAddLayer('SHARED_NOTE', 2, $fact);
374
                }
375
                FunctionsEdit::printAddLayer('ASSO');
376
                // allow to add godfather and godmother for CHR fact or best man and bridesmaid  for MARR fact in one window
377
                if (in_array($fact, Config::twoAssociates())) {
378
                    FunctionsEdit::printAddLayer('ASSO2');
379
                }
380
                FunctionsEdit::printAddLayer('RESN');
381
            }
382
        }
383
        ?>
384
        <p id="save-cancel">
385
            <input type="submit" class="save" value="<?php echo I18N::translate('save'); ?>">
386
            <input type="button" class="cancel" value="<?php echo I18N::translate('close'); ?>" onclick="window.close();">
387
        </p>
388
    </form>
389
    </div>
390
        <?php
391
        break;
392
393
////////////////////////////////////////////////////////////////////////////////
394
    case 'update':
395
        // Update a fact
396
        $xref      = Filter::post('xref', WT_REGEX_XREF);
397
        $fact_id   = Filter::post('fact_id');
398
        $keep_chan = Filter::postBool('keep_chan');
399
400
        if (!Filter::checkCsrf()) {
401
            $prev_action = Filter::post('prev_action', 'add|edit|addname|editname');
402
            $fact_type   = Filter::post('fact_type', WT_REGEX_TAG);
403
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=' . $prev_action . '&xref=' . $xref . '&fact_id=' . $fact_id . '&fact=' . $fact_type);
404
405
            return;
406
        }
407
408
        $record = GedcomRecord::getInstance($xref, $WT_TREE);
409
        check_record_access($record);
410
411
        // Arrays for each GEDCOM line
412
        $glevels = Filter::postArray('glevels', '[0-9]');
413
        $tag     = Filter::postArray('tag', WT_REGEX_TAG);
414
        $text    = Filter::postArray('text');
415
        $islink  = Filter::postArray('islink', '[01]');
416
417
        $controller
418
        ->setPageTitle(I18N::translate('Edit'))
419
        ->pageHeader();
420
421
        // If the fact has a DATE or PLAC, then delete any value of Y
422
        if ($text[0] === 'Y') {
423
            for ($n = 1; $n < count($tag); ++$n) {
424
                if ($glevels[$n] == 2 && ($tag[$n] === 'DATE' || $tag[$n] === 'PLAC') && $text[$n]) {
425
                    $text[0] = '';
426
                    break;
427
                }
428
            }
429
        }
430
431
        $newged = '';
432
        if (!empty($_POST['NAME'])) {
433
            $newged .= "\n1 NAME " . $_POST['NAME'];
434
            $name_facts = array('TYPE', 'NPFX', 'GIVN', 'SPFX', 'SURN', 'NSFX');
435
            foreach ($name_facts as $name_fact) {
436
                if (!empty($_POST[$name_fact])) {
437
                    $newged .= "\n2 " . $name_fact . ' ' . $_POST[$name_fact];
438
                }
439
            }
440
        }
441
442
        if (isset($_POST['NOTE'])) {
443
            $NOTE = $_POST['NOTE'];
444
        }
445
        if (!empty($NOTE)) {
446
            $tempnote = preg_split('/\r?\n/', trim($NOTE) . "\n"); // make sure only one line ending on the end
447
            $title[]  = '0 @' . $xref . '@ NOTE ' . array_shift($tempnote);
448
            foreach ($tempnote as &$line) {
449
                $line = trim('1 CONT ' . $line, ' ');
450
            }
451
        }
452
453
        $newged = FunctionsEdit::handleUpdates($newged);
454
455
        // Add new names after existing names
456
        if (!empty($_POST['NAME'])) {
457
            preg_match_all('/[_0-9A-Z]+/', $WT_TREE->getPreference('ADVANCED_NAME_FACTS'), $match);
458
            $name_facts = array_unique(array_merge(array('_MARNM'), $match[0]));
459
            foreach ($name_facts as $name_fact) {
460
                if (!empty($_POST[$name_fact])) {
461
                    $newged .= "\n2 " . $name_fact . ' ' . $_POST[$name_fact];
462
                }
463
            }
464
        }
465
466
        $newged = substr($newged, 1); // Remove leading newline
467
        $record->updateFact($fact_id, $newged, !$keep_chan);
468
469
        // For the GEDFact_assistant module
470
        $pid_array = Filter::post('pid_array');
471
        if ($pid_array) {
472
            foreach (explode(',', $pid_array) as $pid) {
473
                if ($pid !== $xref) {
474
                    $indi = Individual::getInstance($pid, $WT_TREE);
475
                    if ($indi && $indi->canEdit()) {
476
                        $indi->updateFact($fact_id, $newged, !$keep_chan);
477
                    }
478
                }
479
            }
480
        }
481
482
        $controller->addInlineJavascript('closePopupAndReloadParent();');
483
        break;
484
485
////////////////////////////////////////////////////////////////////////////////
486
// Add a child to an existing family
487
////////////////////////////////////////////////////////////////////////////////
488
    case 'add_child_to_family':
489
        $xref   = Filter::get('xref', WT_REGEX_XREF);
490
        $gender = Filter::get('gender', '[MFU]', 'U');
491
492
        $family = Family::getInstance($xref, $WT_TREE);
493
        check_record_access($family);
494
495
        $controller
496
        ->setPageTitle($family->getFullName() . ' - ' . I18N::translate('Add a child'))
497
        ->pageHeader();
498
499
        print_indi_form('add_child_to_family_action', null, $family, null, 'CHIL', $gender);
500
        break;
501
502
    case 'add_child_to_family_action':
503
        $xref      = Filter::post('xref', WT_REGEX_XREF);
504
        $PEDI      = Filter::post('PEDI');
505
        $keep_chan = Filter::postBool('keep_chan');
506
        $glevels   = Filter::postArray('glevels', '[0-9]');
507
        $tag       = Filter::postArray('tag', WT_REGEX_TAG);
508
        $text      = Filter::postArray('text');
509
        $islink    = Filter::postArray('islink', '[01]');
510
511
        if (!Filter::checkCsrf()) {
512
            $gender = Filter::get('gender', '[MFU]', 'U');
513
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=add_child_to_family&xref=' . $xref . '&gender=' . $gender);
514
515
            return;
516
        }
517
518
        $family = Family::getInstance($xref, $WT_TREE);
519
        check_record_access($family);
520
521
        $controller->pageHeader();
522
523
        FunctionsEdit::splitSource();
524
        $gedrec = '0 @REF@ INDI';
525
        $gedrec .= FunctionsEdit::addNewName();
526
        $gedrec .= FunctionsEdit::addNewSex();
527
        if (preg_match_all('/([A-Z0-9_]+)/', $WT_TREE->getPreference('QUICK_REQUIRED_FACTS'), $matches)) {
528
            foreach ($matches[1] as $match) {
529
                $gedrec .= FunctionsEdit::addNewFact($match);
530
            }
531
        }
532
        $gedrec .= "\n" . GedcomCodePedi::createNewFamcPedi($PEDI, $xref);
533
        if (Filter::postBool('SOUR_INDI')) {
534
            $gedrec = FunctionsEdit::handleUpdates($gedrec);
535
        } else {
536
            $gedrec = FunctionsEdit::updateRest($gedrec);
537
        }
538
539
        // Create the new child
540
        $new_child = $family->getTree()->createRecord($gedrec);
541
542
        // Insert new child at the right place
543
        $done = false;
544
        foreach ($family->getFacts('CHIL') as $fact) {
545
            $old_child = $fact->getTarget();
546
            if ($old_child && Date::compare($new_child->getEstimatedBirthDate(), $old_child->getEstimatedBirthDate()) < 0) {
547
                // Insert before this child
548
                $family->updateFact($fact->getFactId(), '1 CHIL @' . $new_child->getXref() . "@\n" . $fact->getGedcom(), !$keep_chan);
549
                $done = true;
550
                break;
551
            }
552
        }
553
        if (!$done) {
554
            // Append child at end
555
            $family->createFact('1 CHIL @' . $new_child->getXref() . '@', !$keep_chan);
556
        }
557
558
        if (Filter::post('goto') === 'new') {
559
            $controller->addInlineJavascript('closePopupAndReloadParent("' . $new_child->getRawUrl() . '");');
560
        } else {
561
            $controller->addInlineJavascript('closePopupAndReloadParent();');
562
        }
563
        break;
564
565
////////////////////////////////////////////////////////////////////////////////
566
// Add a child to an existing individual (creating a one-parent family)
567
////////////////////////////////////////////////////////////////////////////////
568
    case 'add_child_to_individual':
569
        $xref = Filter::get('xref', WT_REGEX_XREF);
570
571
        $person = Individual::getInstance($xref, $WT_TREE);
572
        check_record_access($person);
573
574
        $controller
575
        ->setPageTitle($person->getFullName() . ' - ' . I18N::translate('Add a child to create a one-parent family'))
576
        ->pageHeader();
577
578
        print_indi_form('add_child_to_individual_action', $person, null, null, 'CHIL', $person->getSex());
579
        break;
580
581
    case 'add_child_to_individual_action':
582
        $xref    = Filter::post('xref', WT_REGEX_XREF);
583
        $PEDI    = Filter::post('PEDI');
584
        $glevels = Filter::postArray('glevels', '[0-9]');
585
        $tag     = Filter::postArray('tag', WT_REGEX_TAG);
586
        $text    = Filter::postArray('text');
587
        $islink  = Filter::postArray('islink', '[01]');
588
589
        if (!Filter::checkCsrf()) {
590
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=add_child_to_individual&xref=' . $xref);
591
592
            return;
593
        }
594
595
        $person = Individual::getInstance($xref, $WT_TREE);
596
        check_record_access($person);
597
598
        $controller->pageHeader();
599
600
        // Create a family
601
        if ($person->getSex() === 'F') {
602
            $gedcom = "0 @NEW@ FAM\n1 WIFE @" . $person->getXref() . '@';
603
        } else {
604
            $gedcom = "0 @NEW@ FAM\n1 HUSB @" . $person->getXref() . '@';
605
        }
606
        $family = $person->getTree()->createRecord($gedcom);
607
608
        // Link the parent to the family
609
        $person->createFact('1 FAMS @' . $family->getXref() . '@', true);
610
611
        // Create a child
612
        FunctionsEdit::splitSource(); // separate SOUR record from the rest
613
614
        $gedcom = '0 @NEW@ INDI';
615
        $gedcom .= FunctionsEdit::addNewName();
616
        $gedcom .= FunctionsEdit::addNewSex();
617
        $gedcom .= "\n" . GedcomCodePedi::createNewFamcPedi($PEDI, $family->getXref());
618
        if (preg_match_all('/([A-Z0-9_]+)/', $WT_TREE->getPreference('QUICK_REQUIRED_FACTS'), $matches)) {
619
            foreach ($matches[1] as $match) {
620
                $gedcom .= FunctionsEdit::addNewFact($match);
621
            }
622
        }
623
        if (Filter::postBool('SOUR_INDI')) {
624
            $gedcom = FunctionsEdit::handleUpdates($gedcom);
625
        } else {
626
            $gedcom = FunctionsEdit::updateRest($gedcom);
627
        }
628
629
        $child = $person->getTree()->createRecord($gedcom);
630
631
        // Link the family to the child
632
        $family->createFact('1 CHIL @' . $child->getXref() . '@', true);
633
634
        if (Filter::post('goto') === 'new') {
635
            $controller->addInlineJavascript('closePopupAndReloadParent("' . $child->getRawUrl() . '");');
636
        } else {
637
            $controller->addInlineJavascript('closePopupAndReloadParent();');
638
        }
639
        break;
640
641
////////////////////////////////////////////////////////////////////////////////
642
// Add a new parent to an existing individual (creating a one-parent family)
643
////////////////////////////////////////////////////////////////////////////////
644
    case 'add_parent_to_individual':
645
        $xref   = Filter::get('xref', WT_REGEX_XREF);
646
        $gender = Filter::get('gender', '[MF]', 'U');
647
648
        $individual = Individual::getInstance($xref, $WT_TREE);
649
        check_record_access($individual);
650
651
        if ($gender === 'F') {
652
            $controller->setPageTitle(I18N::translate('Add a mother'));
653
            $famtag = 'WIFE';
654
        } else {
655
            $controller->setPageTitle(I18N::translate('Add a father'));
656
            $famtag = 'HUSB';
657
        }
658
        $controller->pageHeader();
659
660
        print_indi_form('add_parent_to_individual_action', $individual, null, null, $famtag, $gender);
661
        break;
662
663
    case 'add_parent_to_individual_action':
664
        $xref    = Filter::post('xref', WT_REGEX_XREF);
665
        $PEDI    = Filter::post('PEDI');
666
        $glevels = Filter::postArray('glevels', '[0-9]');
667
        $tag     = Filter::postArray('tag', WT_REGEX_TAG);
668
        $text    = Filter::postArray('text');
669
        $islink  = Filter::postArray('islink', '[01]');
670
671
        if (!Filter::checkCsrf()) {
672
            $gender = Filter::get('gender', '[MFU]', 'U');
673
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=add_parent_to_individual&xref=' . $xref . '&gender=' . $gender);
674
675
            return;
676
        }
677
678
        $person = Individual::getInstance($xref, $WT_TREE);
679
        check_record_access($person);
680
681
        $controller->pageHeader();
682
683
        // Create a new family
684
        $gedcom = "0 @NEW@ FAM\n1 CHIL @" . $person->getXref() . '@';
685
        $family = $person->getTree()->createRecord($gedcom);
686
687
        // Link the child to the family
688
        $person->createFact('1 FAMC @' . $family->getXref() . '@', true);
689
690
        // Create a child
691
        FunctionsEdit::splitSource(); // separate SOUR record from the rest
692
693
        $gedcom = '0 @NEW@ INDI';
694
        $gedcom .= FunctionsEdit::addNewName();
695
        $gedcom .= FunctionsEdit::addNewSex();
696
        if (preg_match_all('/([A-Z0-9_]+)/', $WT_TREE->getPreference('QUICK_REQUIRED_FACTS'), $matches)) {
697
            foreach ($matches[1] as $match) {
698
                $gedcom .= FunctionsEdit::addNewFact($match);
699
            }
700
        }
701
        if (Filter::postBool('SOUR_INDI')) {
702
            $gedcom = FunctionsEdit::handleUpdates($gedcom);
703
        } else {
704
            $gedcom = FunctionsEdit::updateRest($gedcom);
705
        }
706
        $gedcom .= "\n1 FAMS @" . $family->getXref() . '@';
707
708
        $parent = $person->getTree()->createRecord($gedcom);
709
710
        // Link the family to the child
711
        if ($parent->getSex() === 'F') {
712
            $family->createFact('1 WIFE @' . $parent->getXref() . '@', true);
713
        } else {
714
            $family->createFact('1 HUSB @' . $parent->getXref() . '@', true);
715
        }
716
717
        if (Filter::post('goto') === 'new') {
718
            $controller->addInlineJavascript('closePopupAndReloadParent("' . $parent->getRawUrl() . '");');
719
        } else {
720
            $controller->addInlineJavascript('closePopupAndReloadParent();');
721
        }
722
        break;
723
724
////////////////////////////////////////////////////////////////////////////////
725
// Add a new, unlinked individual
726
////////////////////////////////////////////////////////////////////////////////
727
    case 'add_unlinked_indi':
728
        $controller
729
        ->restrictAccess(Auth::isManager($WT_TREE))
730
        ->setPageTitle(I18N::translate('Create an individual'))
731
        ->pageHeader();
732
733
        print_indi_form('add_unlinked_indi_action', null, null, null, null, null);
734
        break;
735
736
    case 'add_unlinked_indi_action':
737
        $glevels = Filter::postArray('glevels', '[0-9]');
738
        $tag     = Filter::postArray('tag', WT_REGEX_TAG);
739
        $text    = Filter::postArray('text');
740
        $islink  = Filter::postArray('islink', '[01]');
741
742
        if (!Filter::checkCsrf()) {
743
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=add_unlinked_indi');
744
745
            return;
746
        }
747
748
        $controller
749
        ->restrictAccess(Auth::isManager($WT_TREE))
750
        ->pageHeader();
751
752
        FunctionsEdit::splitSource();
753
        $gedrec = '0 @REF@ INDI';
754
        $gedrec .= FunctionsEdit::addNewName();
755
        $gedrec .= FunctionsEdit::addNewSex();
756
        if (preg_match_all('/([A-Z0-9_]+)/', $WT_TREE->getPreference('QUICK_REQUIRED_FACTS'), $matches)) {
757
            foreach ($matches[1] as $match) {
758
                $gedrec .= FunctionsEdit::addNewFact($match);
759
            }
760
        }
761
        if (Filter::postBool('SOUR_INDI')) {
762
            $gedrec = FunctionsEdit::handleUpdates($gedrec);
763
        } else {
764
            $gedrec = FunctionsEdit::updateRest($gedrec);
765
        }
766
767
        $new_indi = $WT_TREE->createRecord($gedrec);
768
769
        if (Filter::post('goto') === 'new') {
770
            $controller->addInlineJavascript('closePopupAndReloadParent("' . $new_indi->getRawUrl() . '");');
771
        } else {
772
            $controller->addInlineJavascript('closePopupAndReloadParent();');
773
        }
774
        break;
775
776
////////////////////////////////////////////////////////////////////////////////
777
// Add a spouse to an existing individual (creating a new family)
778
////////////////////////////////////////////////////////////////////////////////
779
    case 'add_spouse_to_individual':
780
        $famtag = Filter::get('famtag', 'HUSB|WIFE');
781
        $xref   = Filter::get('xref', WT_REGEX_XREF);
782
783
        $individual = Individual::getInstance($xref, $WT_TREE);
784
        check_record_access($individual);
785
786
        if ($famtag === 'WIFE') {
787
            $controller->setPageTitle(I18N::translate('Add a wife'));
788
            $sex = 'F';
789
        } else {
790
            $controller->setPageTitle(I18N::translate('Add a husband'));
791
            $sex = 'M';
792
        }
793
        $controller->pageHeader();
794
795
        print_indi_form('add_spouse_to_individual_action', $individual, null, null, $famtag, $sex);
796
        break;
797
798
    case 'add_spouse_to_individual_action':
799
        $xref    = Filter::post('xref'); // Add a spouse to this individual
800
        $sex     = Filter::post('SEX', '[MFU]', 'U');
801
        $glevels = Filter::postArray('glevels', '[0-9]');
802
        $tag     = Filter::postArray('tag', WT_REGEX_TAG);
803
        $text    = Filter::postArray('text');
804
        $islink  = Filter::postArray('islink', '[01]');
805
806
        if (!Filter::checkCsrf()) {
807
            $famtag = Filter::get('famtag', 'HUSB|WIFE');
808
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=add_spouse_to_individual&xref=' . $xref . '&famtag=' . $famtag);
809
810
            return;
811
        }
812
813
        $person = Individual::getInstance($xref, $WT_TREE);
814
        check_record_access($person);
815
816
        $controller
817
        ->setPageTitle(I18N::translate('Add a spouse'))
818
        ->pageHeader();
819
820
        FunctionsEdit::splitSource();
821
        $indi_gedcom = '0 @REF@ INDI';
822
        $indi_gedcom .= FunctionsEdit::addNewName();
823
        $indi_gedcom .= FunctionsEdit::addNewSex();
824
        if (preg_match_all('/([A-Z0-9_]+)/', $WT_TREE->getPreference('QUICK_REQUIRED_FACTS'), $matches)) {
825
            foreach ($matches[1] as $match) {
826
                $indi_gedcom .= FunctionsEdit::addNewFact($match);
827
            }
828
        }
829
        if (Filter::postBool('SOUR_INDI')) {
830
            $indi_gedcom = FunctionsEdit::handleUpdates($indi_gedcom);
831
        } else {
832
            $indi_gedcom = FunctionsEdit::updateRest($indi_gedcom);
833
        }
834
835
        $fam_gedcom = '';
836
        if (preg_match_all('/([A-Z0-9_]+)/', $WT_TREE->getPreference('QUICK_REQUIRED_FAMFACTS'), $matches)) {
837
            foreach ($matches[1] as $match) {
838
                $fam_gedcom .= FunctionsEdit::addNewFact($match);
839
            }
840
        }
841
        if (Filter::postBool('SOUR_FAM')) {
842
            $fam_gedcom = FunctionsEdit::handleUpdates($fam_gedcom);
843
        } else {
844
            $fam_gedcom = FunctionsEdit::updateRest($fam_gedcom);
845
        }
846
847
        // Create the new spouse
848
        $spouse = $person->getTree()->createRecord($indi_gedcom);
849
        // Create a new family
850
        if ($sex === 'F') {
851
            $family = $spouse->getTree()->createRecord("0 @NEW@ FAM\n1 WIFE @" . $spouse->getXref() . "@\n1 HUSB @" . $person->getXref() . '@' . $fam_gedcom);
852
        } else {
853
            $family = $spouse->getTree()->createRecord("0 @NEW@ FAM\n1 HUSB @" . $spouse->getXref() . "@\n1 WIFE @" . $person->getXref() . '@' . $fam_gedcom);
854
        }
855
        // Link the spouses to the family
856
        $spouse->createFact('1 FAMS @' . $family->getXref() . '@', true);
857
        $person->createFact('1 FAMS @' . $family->getXref() . '@', true);
858
859
        if (Filter::post('goto') === 'new') {
860
            $controller->addInlineJavascript('closePopupAndReloadParent("' . $spouse->getRawUrl() . '");');
861
        } else {
862
            $controller->addInlineJavascript('closePopupAndReloadParent();');
863
        }
864
        break;
865
866
////////////////////////////////////////////////////////////////////////////////
867
// Add a spouse to an existing family
868
////////////////////////////////////////////////////////////////////////////////
869
    case 'add_spouse_to_family':
870
        $xref   = Filter::get('xref', WT_REGEX_XREF);
871
        $famtag = Filter::get('famtag', 'HUSB|WIFE');
872
873
        $family = Family::getInstance($xref, $WT_TREE);
874
        check_record_access($family);
875
876
        if ($famtag === 'WIFE') {
877
            $controller->setPageTitle(I18N::translate('Add a wife'));
878
            $sex = 'F';
879
        } else {
880
            $controller->setPageTitle(I18N::translate('Add a husband'));
881
            $sex = 'M';
882
        }
883
        $controller->pageHeader();
884
885
        print_indi_form('add_spouse_to_family_action', null, $family, null, $famtag, $sex);
886
        break;
887
888
    case 'add_spouse_to_family_action':
889
        $xref    = Filter::post('xref', WT_REGEX_XREF);
890
        $glevels = Filter::postArray('glevels', '[0-9]');
891
        $tag     = Filter::postArray('tag', WT_REGEX_TAG);
892
        $text    = Filter::postArray('text');
893
        $islink  = Filter::postArray('islink', '[01]');
894
895
        $family  = Family::getInstance($xref, $WT_TREE);
896
        check_record_access($family);
897
898
        if (!Filter::checkCsrf()) {
899
            $famtag = Filter::get('famtag', 'HUSB|WIFE');
900
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=add_spouse_to_family&xref=' . $xref . '&famtag=' . $famtag);
901
902
            return;
903
        }
904
905
        $controller->pageHeader();
906
907
        // Create the new spouse
908
        FunctionsEdit::splitSource(); // separate SOUR record from the rest
909
910
        $gedrec = '0 @REF@ INDI';
911
        $gedrec .= FunctionsEdit::addNewName();
912
        $gedrec .= FunctionsEdit::addNewSex();
913
        if (preg_match_all('/([A-Z0-9_]+)/', $WT_TREE->getPreference('QUICK_REQUIRED_FACTS'), $matches)) {
914
            foreach ($matches[1] as $match) {
915
                $gedrec .= FunctionsEdit::addNewFact($match);
916
            }
917
        }
918
919
        if (Filter::postBool('SOUR_INDI')) {
920
            $gedrec = FunctionsEdit::handleUpdates($gedrec);
921
        } else {
922
            $gedrec = FunctionsEdit::updateRest($gedrec);
923
        }
924
        $gedrec .= "\n1 FAMS @" . $family->getXref() . '@';
925
        $spouse = $family->getTree()->createRecord($gedrec);
926
927
        // Update the existing family - add marriage, etc
928
        if ($family->getFirstFact('HUSB')) {
929
            $family->createFact('1 WIFE @' . $spouse->getXref() . '@', true);
930
        } else {
931
            $family->createFact('1 HUSB @' . $spouse->getXref() . '@', true);
932
        }
933
        $famrec = '';
934
        if (preg_match_all('/([A-Z0-9_]+)/', $WT_TREE->getPreference('QUICK_REQUIRED_FAMFACTS'), $matches)) {
935
            foreach ($matches[1] as $match) {
936
                $famrec .= FunctionsEdit::addNewFact($match);
937
            }
938
        }
939
        if (Filter::postBool('SOUR_FAM')) {
940
            $famrec = FunctionsEdit::handleUpdates($famrec);
941
        } else {
942
            $famrec = FunctionsEdit::updateRest($famrec);
943
        }
944
        $family->createFact(trim($famrec), true); // trim leading \n
945
946
        if (Filter::post('goto') === 'new') {
947
            $controller->addInlineJavascript('closePopupAndReloadParent("' . $spouse->getRawUrl() . '");');
948
        } else {
949
            $controller->addInlineJavascript('closePopupAndReloadParent();');
950
        }
951
        break;
952
953
////////////////////////////////////////////////////////////////////////////////
954
// Link an individual to an existing family, as a child
955
////////////////////////////////////////////////////////////////////////////////
956
    case 'addfamlink':
957
        $xref = Filter::get('xref', WT_REGEX_XREF);
958
959
        $person = Individual::getInstance($xref, $WT_TREE);
960
        check_record_access($person);
961
962
        $controller
963
        ->setPageTitle($person->getFullName() . ' - ' . I18N::translate('Link this individual to an existing family as a child'))
964
        ->pageHeader();
965
966
        ?>
967
    <div id="edit_interface-page">
968
        <h2><?php echo $controller->getPageTitle(); ?></h2>
969
        <form method="post" name="addchildform" action="edit_interface.php">
970
            <input type="hidden" name="ged" value="<?php echo $WT_TREE->getNameHtml(); ?>">
971
            <input type="hidden" name="action" value="linkfamaction">
972
            <input type="hidden" name="xref" value="<?php echo $person->getXref(); ?>">
973
            <?php echo Filter::getCsrf(); ?>
974
            <table class="facts_table">
975
                <tr>
976
                    <td class="facts_label">
977
                        <?php echo I18N::translate('Family'); ?>
978
                    </td>
979
                    <td class="facts_value">
980
                        <input data-autocomplete-type="FAM" type="text" id="famid" name="famid" size="8">
981
                        <?php echo FunctionsPrint::printFindFamilyLink('famid'); ?>
982
                    </td>
983
                </tr>
984
                <tr>
985
                    <td class="facts_label">
986
                        <?php echo GedcomTag::getLabel('PEDI'); ?>
987
                    </td>
988
                    <td class="facts_value">
989
                        <?php echo FunctionsEdit::editFieldPedigree('PEDI', '', '', $person); ?>
990
                        <p class="small text-muted">
991
                            <?php echo 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.'); ?>
992
                        </p>
993
                    </td>
994
                </tr>
995
                <?php echo keep_chan($person); ?>
996
            </table>
997
            <p id="save-cancel">
998
                <input type="submit" class="save" value="<?php echo I18N::translate('save'); ?>">
999
                <input type="button" class="cancel" value="<?php echo I18N::translate('close'); ?>" onclick="window.close();">
1000
            </p>
1001
        </form>
1002
    </div>
1003
        <?php
1004
        break;
1005
1006
    case 'linkfamaction':
1007
        $xref   = Filter::post('xref', WT_REGEX_XREF);
1008
        $famid  = Filter::post('famid', WT_REGEX_XREF);
1009
        $PEDI   = Filter::post('PEDI');
1010
1011
        if (!Filter::checkCsrf()) {
1012
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=addfamlink&xref=' . $xref);
1013
1014
            return;
1015
        }
1016
1017
        $person = Individual::getInstance($xref, $WT_TREE);
1018
        $family = Family::getInstance($famid, $WT_TREE);
1019
        check_record_access($person);
1020
        check_record_access($family);
1021
1022
        $controller
1023
        ->setPageTitle($person->getFullName() . ' - ' . I18N::translate('Link this individual to an existing family as a child'))
1024
        ->pageHeader();
1025
1026
        // Replace any existing child->family link (we may be changing the PEDI);
1027
        $fact_id = null;
1028
        foreach ($person->getFacts('FAMC') as $fact) {
1029
            if ($family === $fact->getTarget()) {
1030
                $fact_id = $fact->getFactId();
1031
                break;
1032
            }
1033
        }
1034
1035
        $gedcom = GedcomCodePedi::createNewFamcPedi($PEDI, $famid);
1036
        $person->updateFact($fact_id, $gedcom, true);
1037
1038
        // Only set the family->child link if it does not already exist
1039
        $edit_fact = null;
1040
        foreach ($family->getFacts('CHIL') as $fact) {
1041
            if ($person === $fact->getTarget()) {
1042
                $edit_fact = $fact;
1043
                break;
1044
            }
1045
        }
1046
        if (!$edit_fact) {
1047
            $family->createFact('1 CHIL @' . $person->getXref() . '@', true);
1048
        }
1049
1050
        $controller->addInlineJavascript('closePopupAndReloadParent();');
1051
        break;
1052
1053
////////////////////////////////////////////////////////////////////////////////
1054
// Link and individual to an existing individual as a spouse
1055
////////////////////////////////////////////////////////////////////////////////
1056
    case 'linkspouse':
1057
        $famtag = Filter::get('famtag', 'HUSB|WIFE');
1058
        $xref   = Filter::get('xref', WT_REGEX_XREF);
1059
1060
        $person = Individual::getInstance($xref, $WT_TREE);
1061
        check_record_access($person);
1062
1063
        if ($person->getSex() === 'F') {
1064
            $controller->setPageTitle($person->getFullName() . ' - ' . I18N::translate('Add a husband using an existing individual'));
1065
            $label = I18N::translate('Husband');
1066
        } else {
1067
            $controller->setPageTitle($person->getFullName() . ' - ' . I18N::translate('Add a wife using an existing individual'));
1068
            $label = I18N::translate('Wife');
1069
        }
1070
1071
        $controller->pageHeader();
1072
        FunctionsPrint::initializeCalendarPopup();
1073
1074
        ?>
1075
    <div id="edit_interface-page">
1076
        <h2><?php echo $controller->getPageTitle(); ?></h2>
1077
        <form method="post" name="addchildform" action="edit_interface.php">
1078
            <input type="hidden" name="ged" value="<?php echo $WT_TREE->getNameHtml(); ?>">
1079
            <input type="hidden" name="action" value="linkspouseaction">
1080
            <input type="hidden" name="xref" value="<?php echo $person->getXref(); ?>">
1081
            <input type="hidden" name="famtag" value="<?php echo $famtag; ?>">
1082
            <?php echo Filter::getCsrf(); ?>
1083
            <table class="facts_table">
1084
                <tr>
1085
                    <td class="facts_label">
1086
                        <?php echo $label; ?>
1087
                    </td>
1088
                    <td class="facts_value">
1089
                        <input data-autocomplete-type="INDI" id="spouseid" type="text" name="spid" size="8">
1090
                        <?php echo FunctionsPrint::printFindIndividualLink('spouseid'); ?>
1091
                    </td>
1092
                </tr>
1093
                <?php FunctionsEdit::addSimpleTag('0 MARR Y'); ?>
1094
                <?php FunctionsEdit::addSimpleTag('0 DATE', 'MARR'); ?>
1095
                <?php FunctionsEdit::addSimpleTag('0 PLAC', 'MARR'); ?>
1096
                <?php echo keep_chan($person); ?>
1097
            </table>
1098
            <?php FunctionsEdit::printAddLayer('SOUR'); ?>
1099
            <?php FunctionsEdit::printAddLayer('OBJE'); ?>
1100
            <?php FunctionsEdit::printAddLayer('NOTE'); ?>
1101
            <?php FunctionsEdit::printAddLayer('SHARED_NOTE'); ?>
1102
            <?php FunctionsEdit::printAddLayer('ASSO'); ?>
1103
            <?php FunctionsEdit::printAddLayer('ASSO2'); ?>
1104
            <?php FunctionsEdit::printAddLayer('RESN'); ?>
1105
            <p id="save-cancel">
1106
                <input type="submit" class="save" value="<?php echo I18N::translate('save'); ?>">
1107
                <input type="button" class="cancel" value="<?php echo I18N::translate('close'); ?>" onclick="window.close();">
1108
            </p>
1109
        </form>
1110
    </div>
1111
        <?php
1112
        break;
1113
1114
    case 'linkspouseaction':
1115
        $xref    = Filter::post('xref', WT_REGEX_XREF);
1116
        $spid    = Filter::post('spid', WT_REGEX_XREF);
1117
        $famtag  = Filter::post('famtag', 'HUSB|WIFE');
1118
        $glevels = Filter::postArray('glevels', '[0-9]');
1119
        $tag     = Filter::postArray('tag', WT_REGEX_TAG);
1120
        $text    = Filter::postArray('text');
1121
        $islink  = Filter::postArray('islink', '[01]');
1122
1123
        if (!Filter::checkCsrf()) {
1124
            $famtag = Filter::get('famtag', 'HUSB|WIFE');
1125
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=linkspouse&xref=' . $xref . '&famtag=' . $famtag);
1126
1127
            return;
1128
        }
1129
1130
        $person  = Individual::getInstance($xref, $WT_TREE);
1131
        $spouse  = Individual::getInstance($spid, $WT_TREE);
1132
        check_record_access($person);
1133
        check_record_access($spouse);
1134
1135
        if ($person->getSex() === 'F') {
1136
            $controller->setPageTitle($person->getFullName() . ' - ' . I18N::translate('Add a husband using an existing individual'));
1137
        } else {
1138
            $controller->setPageTitle($person->getFullName() . ' - ' . I18N::translate('Add a wife using an existing individual'));
1139
        }
1140
        $controller->pageHeader();
1141
1142
        if ($person->getSex() === 'M') {
1143
            $gedcom = "0 @new@ FAM\n1 HUSB @" . $person->getXref() . "@\n1 WIFE @" . $spouse->getXref() . '@';
1144
        } else {
1145
            $gedcom = "0 @new@ FAM\n1 HUSB @" . $spouse->getXref() . "@\n1 WIFE @" . $person->getXref() . '@';
1146
        }
1147
        FunctionsEdit::splitSource();
1148
        $gedcom .= FunctionsEdit::addNewFact('MARR');
1149
1150
        if (Filter::postBool('SOUR_FAM') || count($tagSOUR) > 0) {
1151
            // before adding 2 SOUR it needs to add 1 MARR Y first
1152
            if (FunctionsEdit::addNewFact('MARR') === '') {
1153
                $gedcom .= "\n1 MARR Y";
1154
            }
1155
            $gedcom = FunctionsEdit::handleUpdates($gedcom);
1156
        } else {
1157
            // before adding level 2 facts it needs to add 1 MARR Y first
1158
            if (FunctionsEdit::addNewFact('MARR') === '') {
1159
                $gedcom .= "\n1 MARR Y";
1160
            }
1161
            $gedcom = FunctionsEdit::updateRest($gedcom);
1162
        }
1163
1164
        $family = $person->getTree()->createRecord($gedcom);
1165
        $person->createFact('1 FAMS @' . $family->getXref() . '@', true);
1166
        $spouse->createFact('1 FAMS @' . $family->getXref() . '@', true);
1167
1168
        $controller->addInlineJavascript('closePopupAndReloadParent();');
1169
        break;
1170
1171
////////////////////////////////////////////////////////////////////////////////
1172
// Create a new source record
1173
////////////////////////////////////////////////////////////////////////////////
1174
    case 'addnewsource':
1175
        $controller
1176
        ->setPageTitle(I18N::translate('Create a source'))
1177
        ->pageHeader();
1178
1179
        ?>
1180
    <script>
1181
        function check_form(frm) {
1182
            if (frm.TITL.value=="") {
1183
                alert('<?php echo I18N::translate('You must provide a source title'); ?>');
1184
                frm.TITL.focus();
1185
                return false;
1186
            }
1187
            return true;
1188
        }
1189
    </script>
1190
    <div id="edit_interface-page">
1191
        <h2><?php echo $controller->getPageTitle(); ?></h2>
1192
        <form method="post" action="edit_interface.php" onsubmit="return check_form(this);">
1193
            <input type="hidden" name="ged" value="<?php echo $WT_TREE->getNameHtml(); ?>">
1194
            <input type="hidden" name="action" value="addsourceaction">
1195
            <input type="hidden" name="xref" value="newsour">
1196
            <?php echo Filter::getCsrf(); ?>
1197
            <table class="facts_table">
1198
                <tr><td class="descriptionbox wrap width25"><?php echo GedcomTag::getLabel('TITL'); ?></td>
1199
                <td class="optionbox wrap"><input type="text" data-autocomplete-type="SOUR_TITL" name="TITL" id="TITL" value="" size="60"> <?php echo FunctionsPrint::printSpecialCharacterLink('TITL'); ?></td></tr>
1200
                <tr><td class="descriptionbox wrap width25"><?php echo GedcomTag::getLabel('ABBR'); ?></td>
1201
                <td class="optionbox wrap"><input type="text" name="ABBR" id="ABBR" value="" size="40" maxlength="255"> <?php echo FunctionsPrint::printSpecialCharacterLink('ABBR'); ?></td></tr>
1202
                <?php if (strstr($WT_TREE->getPreference('ADVANCED_NAME_FACTS'), "_HEB") !== false) { ?>
1203
                <tr><td class="descriptionbox wrap width25"><?php echo GedcomTag::getLabel('_HEB'); ?></td>
1204
                <td class="optionbox wrap"><input type="text" name="_HEB" id="_HEB" value="" size="60"> <?php echo FunctionsPrint::printSpecialCharacterLink('_HEB'); ?></td></tr>
1205
                <?php } ?>
1206
                <?php if (strstr($WT_TREE->getPreference('ADVANCED_NAME_FACTS'), "ROMN") !== false) { ?>
1207
                <tr><td class="descriptionbox wrap width25"><?php echo GedcomTag::getLabel('ROMN'); ?></td>
1208
                <td class="optionbox wrap"><input  type="text" name="ROMN" id="ROMN" value="" size="60"> <?php echo FunctionsPrint::printSpecialCharacterLink('ROMN'); ?></td></tr>
1209
                <?php } ?>
1210
                <tr><td class="descriptionbox wrap width25"><?php echo GedcomTag::getLabel('AUTH'); ?></td>
1211
                <td class="optionbox wrap"><input type="text" name="AUTH" id="AUTH" value="" size="40" maxlength="255"> <?php echo FunctionsPrint::printSpecialCharacterLink('AUTH'); ?></td></tr>
1212
                <tr><td class="descriptionbox wrap width25"><?php echo GedcomTag::getLabel('PUBL'); ?></td>
1213
                <td class="optionbox wrap"><textarea name="PUBL" id="PUBL" rows="5" cols="60"></textarea><br><?php echo FunctionsPrint::printSpecialCharacterLink('PUBL'); ?></td></tr>
1214
                <tr><td class="descriptionbox wrap width25"><?php echo GedcomTag::getLabel('REPO'); ?></td>
1215
                <td class="optionbox wrap"><input type="text" data-autocomplete-type="REPO" name="REPO" id="REPO" value="" size="10"> <?php echo FunctionsPrint::printFindRepositoryLink('REPO'), ' ', FunctionsEdit::printAddNewRepositoryLink('REPO'); ?></td></tr>
1216
                <tr><td class="descriptionbox wrap width25"><?php echo GedcomTag::getLabel('CALN'); ?></td>
1217
                <td class="optionbox wrap"><input type="text" name="CALN" id="CALN" value=""></td></tr>
1218
                <?php echo keep_chan(); ?>
1219
            </table>
1220
                <a href="#"  onclick="return expand_layer('events');"><i id="events_img" class="icon-plus"></i>
1221
                <?php echo I18N::translate('Associate events with this source'); ?></a>
1222
                <div id="events" style="display: none;">
1223
                <table class="facts_table">
1224
                <tr>
1225
                    <td class="descriptionbox wrap width25"><?php echo I18N::translate('Select events'), FunctionsPrint::helpLink('edit_SOUR_EVEN'); ?></td>
1226
                    <td class="optionbox wrap"><select name="EVEN[]" multiple="multiple" size="5">
1227
                        <?php
1228
                        $parts = explode(',', $WT_TREE->getPreference('INDI_FACTS_ADD'));
1229
                        foreach ($parts as $key) {
1230
                            ?><option value="<?php echo $key; ?>"><?php echo GedcomTag::getLabel($key); ?></option>
1231
                            <?php
1232
                        }
1233
                        $parts = explode(',', $WT_TREE->getPreference('FAM_FACTS_ADD'));
1234
                        foreach ($parts as $key) {
1235
                            ?><option value="<?php echo $key; ?>"><?php echo GedcomTag::getLabel($key); ?></option>
1236
                            <?php
1237
                        }
1238
                        ?>
1239
                    </select></td>
1240
                </tr>
1241
                    <?php
1242
                    FunctionsEdit::addSimpleTag('0 DATE', 'EVEN');
1243
                    FunctionsEdit::addSimpleTag('0 PLAC', 'EVEN');
1244
                    FunctionsEdit::addSimpleTag('0 AGNC');
1245
                    ?>
1246
                </table>
1247
            </div>
1248
            <p id="save-cancel">
1249
                <input type="submit" class="save" value="<?php echo I18N::translate('save'); ?>">
1250
                <input type="button" class="cancel" value="<?php echo I18N::translate('close'); ?>" onclick="window.close();">
1251
            </p>
1252
        </form>
1253
    </div>
1254
        <?php
1255
        break;
1256
1257
    case 'addsourceaction':
1258
        $controller
1259
        ->setPageTitle(I18N::translate('Create a source'))
1260
        ->pageHeader();
1261
1262
        if (!Filter::checkCsrf()) {
1263
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=addnewsource');
1264
1265
            return;
1266
        }
1267
1268
        $newgedrec = '0 @XREF@ SOUR';
1269
        $ABBR      = Filter::post('ABBR');
1270
        if ($ABBR) {
1271
            $newgedrec .= "\n1 ABBR " . $ABBR;
1272
        }
1273
        $TITL = Filter::post('TITL');
1274
        if ($TITL) {
1275
            $newgedrec .= "\n1 TITL " . $TITL;
1276
            $_HEB = Filter::post('_HEB');
1277
            if ($_HEB) {
1278
                $newgedrec .= "\n2 _HEB " . $_HEB;
1279
            }
1280
            $ROMN = Filter::post('ROMN');
1281
            if ($ROMN) {
1282
                $newgedrec .= "\n2 ROMN " . $ROMN;
1283
            }
1284
        }
1285
        $AUTH = Filter::post('AUTH');
1286
        if ($AUTH) {
1287
            $newgedrec .= "\n1 AUTH " . $AUTH;
1288
        }
1289
        $PUBL = Filter::post('PUBL');
1290
        if ($PUBL) {
1291
            $newgedrec .= "\n1 PUBL " . preg_replace('/\r?\n/', "\n2 CONT ", $PUBL);
1292
        }
1293
        $REPO = Filter::post('REPO', WT_REGEX_XREF);
1294
        if ($REPO) {
1295
            $newgedrec .= "\n1 REPO @" . $REPO . '@';
1296
            $CALN = Filter::post('CALN');
1297
            if ($CALN) {
1298
                $newgedrec .= "\n2 CALN " . $CALN;
1299
            }
1300
        }
1301
        $EVEN = Filter::postArray('EVEN', WT_REGEX_TAG);
1302
        if ($EVEN) {
1303
            $newgedrec .= "\n1 DATA";
1304
            $newgedrec .= "\n2 EVEN " . implode(',', $EVEN);
1305
            $EVEN_DATE = Filter::post('EVEN_DATE');
1306
            if ($EVEN_DATE) {
1307
                $newgedrec .= "\n3 EVEN_DATE " . $EVEN_DATE;
1308
            }
1309
            $EVEN_PLAC = Filter::post('EVEN_PLAC');
1310
            if ($EVEN_PLAC) {
1311
                $newgedrec .= "\n3 EVEN_PLAC " . $EVEN_PLAC;
1312
            }
1313
            $AGNC = Filter::post('AGNC');
1314
            if ($AGNC) {
1315
                $newgedrec .= "\n2 AGNC " . $AGNC;
1316
            }
1317
        }
1318
1319
        $record = $WT_TREE->createRecord($newgedrec);
1320
        $controller->addInlineJavascript('openerpasteid("' . $record->getXref() . '");');
1321
        break;
1322
1323
////////////////////////////////////////////////////////////////////////////////
1324
// Create a new note record
1325
////////////////////////////////////////////////////////////////////////////////
1326
    case 'addnewnote':
1327
        $controller
1328
        ->setPageTitle(I18N::translate('Create a shared note'))
1329
        ->pageHeader();
1330
1331
        ?>
1332
    <div id="edit_interface-page">
1333
        <h2><?php echo $controller->getPageTitle(); ?></h2>
1334
1335
        <form method="post" action="edit_interface.php" onsubmit="return check_form(this);">
1336
            <input type="hidden" name="ged" value="<?php echo $WT_TREE->getNameHtml(); ?>">
1337
            <input type="hidden" name="action" value="addnoteaction">
1338
            <input type="hidden" name="noteid" value="newnote">
1339
            <?php echo Filter::getCsrf(); ?>
1340
            <?php
1341
            echo '<table class="facts_table">';
1342
            echo '<tr>';
1343
            echo '<td class="descriptionbox nowrap">';
1344
            echo I18N::translate('Shared note');
1345
            echo '</td>';
1346
            echo '<td class="optionbox wrap"><textarea name="NOTE" id="NOTE" rows="15" cols="87"></textarea>';
1347
            echo FunctionsPrint::printSpecialCharacterLink('NOTE');
1348
            echo '</td>';
1349
            echo '</tr>';
1350
            echo keep_chan();
1351
            echo '</table>';
1352
            ?>
1353
            <p id="save-cancel">
1354
                <input type="submit" class="save" value="<?php echo I18N::translate('save'); ?>">
1355
                <input type="button" class="cancel" value="<?php echo I18N::translate('close'); ?>" onclick="window.close();">
1356
            </p>
1357
        </form>
1358
    </div>
1359
        <?php
1360
        break;
1361
1362
    case 'addnoteaction':
1363
        $controller
1364
        ->setPageTitle(I18N::translate('Create a shared note'))
1365
        ->pageHeader();
1366
1367
        if (!Filter::checkCsrf()) {
1368
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=addnewnote');
1369
1370
            return;
1371
        }
1372
1373
        $gedrec = '0 @XREF@ NOTE ' . preg_replace("/\r?\n/", "\n1 CONT ", Filter::post('NOTE'));
1374
1375
        $record = $WT_TREE->createRecord($gedrec);
1376
        $controller->addInlineJavascript('openerpasteid("' . $record->getXref() . '");');
1377
        break;
1378
1379
////////////////////////////////////////////////////////////////////////////////
1380
    case 'addnewnote_assisted':
1381
        require WT_ROOT . WT_MODULES_DIR . 'GEDFact_assistant/census/census-edit.php';
1382
        break;
1383
1384
////////////////////////////////////////////////////////////////////////////////
1385
    case 'addnoteaction_assisted':
1386
        require WT_ROOT . WT_MODULES_DIR . 'GEDFact_assistant/census/census-save.php';
1387
        break;
1388
1389
////////////////////////////////////////////////////////////////////////////////
1390
    case 'addmedia_links':
1391
        $pid = Filter::get('pid', WT_REGEX_XREF);
1392
1393
        $person = Individual::getInstance($pid, $WT_TREE);
1394
        check_record_access($person);
1395
1396
        $controller
1397
        ->setPageTitle(I18N::translate('Family navigator') . ' — ' . $person->getFullName())
1398
        ->pageHeader();
1399
1400
        ?>
1401
    <div id="edit_interface-page">
1402
        <h2><?php echo $controller->getPageTitle(); ?></h2>
1403
        <form method="post" action="edit_interface.php?xref=<?php echo $person->getXref(); ?>" onsubmit="findindi()">
1404
            <input type="hidden" name="ged" value="<?php echo $WT_TREE->getNameHtml(); ?>">
1405
            <input type="hidden" name="action" value="addmedia_links">
1406
            <input type="hidden" name="noteid" value="newnote">
1407
            <?php echo Filter::getCsrf(); ?>
1408
            <?php require WT_ROOT . WT_MODULES_DIR . 'GEDFact_assistant/MEDIA_ctrl.php'; ?>
1409
        </form>
1410
    </div>
1411
        <?php
1412
        break;
1413
1414
////////////////////////////////////////////////////////////////////////////////
1415
// Edit a note record
1416
////////////////////////////////////////////////////////////////////////////////
1417
    case 'editnote':
1418
        $xref = Filter::get('xref', WT_REGEX_XREF);
1419
1420
        $note = Note::getInstance($xref, $WT_TREE);
1421
        check_record_access($note);
1422
1423
        $controller
1424
        ->setPageTitle(I18N::translate('Edit the shared note'))
1425
        ->pageHeader();
1426
1427
        ?>
1428
    <div id="edit_interface-page">
1429
        <h2><?php echo $controller->getPageTitle(); ?></h2>
1430
        <form method="post" action="edit_interface.php">
1431
            <input type="hidden" name="ged" value="<?php echo $WT_TREE->getNameHtml(); ?>">
1432
            <input type="hidden" name="action" value="editnoteaction">
1433
            <input type="hidden" name="xref" value="<?php echo $xref; ?>">
1434
            <?php echo Filter::getCsrf(); ?>
1435
            <table class="facts_table">
1436
                <tr>
1437
                    <td class="descriptionbox wrap width25"><?php echo I18N::translate('Shared note'); ?></td>
1438
                    <td class="optionbox wrap">
1439
                        <textarea name="NOTE" id="NOTE" rows="15" cols="90"><?php echo Filter::escapeHtml($note->getNote()); ?></textarea>
1440
                        <br>
1441
                        <?php echo FunctionsPrint::printSpecialCharacterLink('NOTE'); ?>
1442
                    </td>
1443
                </tr>
1444
                <?php echo keep_chan($note); ?>
1445
            </table>
1446
            <p id="save-cancel">
1447
                <input type="submit" class="save" value="<?php echo I18N::translate('save'); ?>">
1448
                <input type="button" class="cancel" value="<?php echo I18N::translate('close'); ?>" onclick="window.close();">
1449
            </p>
1450
        </form>
1451
    </div>
1452
        <?php
1453
        break;
1454
1455
    case 'editnoteaction':
1456
        $xref      = Filter::post('xref', WT_REGEX_XREF);
1457
        $keep_chan = Filter::postBool('keep_chan');
1458
        $note      = Filter::post('NOTE');
1459
1460
        if (!Filter::checkCsrf()) {
1461
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=editnote&xref=' . $xref);
1462
1463
            return;
1464
        }
1465
1466
        $record = Note::getInstance($xref, $WT_TREE);
1467
        check_record_access($record);
1468
1469
        $controller
1470
        ->setPageTitle(I18N::translate('Edit the shared note'))
1471
        ->pageHeader();
1472
1473
        // We have user-supplied data in a replacement string - escape it against backreferences
1474
        $note = str_replace(array('\\', '$'), array('\\\\', '\\$'), $note);
1475
1476
        $gedrec = preg_replace(
1477
        '/^0 @' . $record->getXref() . '@ NOTE.*(\n1 CONT.*)*/',
1478
        '0 @' . $record->getXref() . '@ NOTE ' . preg_replace("/\r?\n/", "\n1 CONT ", $note),
1479
        $record->getGedcom()
1480
        );
1481
1482
        $record->updateRecord($gedrec, !$keep_chan);
1483
1484
        $controller->addInlineJavascript('closePopupAndReloadParent();');
1485
        break;
1486
1487
////////////////////////////////////////////////////////////////////////////////
1488
// Create a new repository
1489
////////////////////////////////////////////////////////////////////////////////
1490
    case 'addnewrepository':
1491
        $controller
1492
        ->setPageTitle(I18N::translate('Create a repository'))
1493
        ->pageHeader();
1494
1495
        echo '<div id="edit_interface-page">';
1496
        echo '<h2>', $controller->getPageTitle(), '</h2>';
1497
1498
        echo '<script>';
1499
        ?>
1500
        function check_form(frm) {
1501
            if (frm.NAME.value=="") {
1502
                alert('<?php echo I18N::translate('You must provide a repository name.'); ?>');
1503
                frm.NAME.focus();
1504
                return false;
1505
            }
1506
            return true;
1507
        }
1508
        <?php
1509
        echo '</script>';
1510
        ?>
1511
    <form method="post" action="edit_interface.php" onsubmit="return check_form(this);">
1512
        <input type="hidden" name="ged" value="<?php echo $WT_TREE->getNameHtml(); ?>">
1513
        <input type="hidden" name="action" value="addrepoaction">
1514
        <input type="hidden" name="xref" value="newrepo">
1515
        <?php echo Filter::getCsrf(); ?>
1516
        <table class="facts_table">
1517
            <tr><td class="descriptionbox wrap width25"><?php echo I18N::translate('Repository name'); ?></td>
1518
            <td class="optionbox wrap"><input type="text" name="REPO_NAME" id="REPO_NAME" value="" size="40" maxlength="255"> <?php echo FunctionsPrint::printSpecialCharacterLink('REPO_NAME'); ?></td></tr>
1519
            <?php if (strstr($WT_TREE->getPreference('ADVANCED_NAME_FACTS'), "_HEB") !== false) { ?>
1520
            <tr><td class="descriptionbox wrap width25"><?php echo GedcomTag::getLabel('_HEB'); ?></td>
1521
            <td class="optionbox wrap"><input type="text" name="_HEB" id="_HEB" value="" size="40" maxlength="255"> <?php echo FunctionsPrint::printSpecialCharacterLink('_HEB'); ?></td></tr>
1522
            <?php } ?>
1523
            <?php if (strstr($WT_TREE->getPreference('ADVANCED_NAME_FACTS'), "ROMN") !== false) { ?>
1524
            <tr><td class="descriptionbox wrap width25"><?php echo GedcomTag::getLabel('ROMN'); ?></td>
1525
            <td class="optionbox wrap"><input type="text" name="ROMN" id="ROMN" value="" size="40" maxlength="255"> <?php echo FunctionsPrint::printSpecialCharacterLink('ROMN'); ?></td></tr>
1526
            <?php } ?>
1527
            <tr><td class="descriptionbox wrap width25"><?php echo GedcomTag::getLabel('ADDR'); ?></td>
1528
            <td class="optionbox wrap"><textarea name="ADDR" id="ADDR" rows="5" cols="60"></textarea><?php echo FunctionsPrint::printSpecialCharacterLink('ADDR'); ?> </td></tr>
1529
            <tr><td class="descriptionbox wrap width25"><?php echo GedcomTag::getLabel('PHON'); ?></td>
1530
            <td class="optionbox wrap"><input type="text" name="PHON" id="PHON" value="" size="40" maxlength="255"> </td></tr>
1531
            <tr><td class="descriptionbox wrap width25"><?php echo GedcomTag::getLabel('EMAIL'); ?></td>
1532
            <td class="optionbox wrap"><input type="text" name="EMAIL" id="EMAIL" value="" size="40" maxlength="255"></td></tr>
1533
            <tr><td class="descriptionbox wrap width25"><?php echo GedcomTag::getLabel('WWW'); ?></td>
1534
            <td class="optionbox wrap"><input type="text" name="WWW" id="WWW" value="" size="40" maxlength="255"> </td></tr>
1535
            <?php echo keep_chan(); ?>
1536
        </table>
1537
        <p id="save-cancel">
1538
            <input type="submit" class="save" value="<?php echo I18N::translate('save'); ?>">
1539
            <input type="button" class="cancel" value="<?php echo I18N::translate('close'); ?>" onclick="window.close();">
1540
        </p>
1541
    </form>
1542
    </div>
1543
        <?php
1544
        break;
1545
1546
    case 'addrepoaction':
1547
        if (!Filter::checkCsrf()) {
1548
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=addnewrepository');
1549
1550
            return;
1551
        }
1552
1553
        $controller
1554
        ->setPageTitle(I18N::translate('Create a repository'))
1555
        ->pageHeader();
1556
1557
        $gedrec    = '0 @XREF@ REPO';
1558
        $REPO_NAME = Filter::post('REPO_NAME');
1559
        if ($REPO_NAME) {
1560
            $gedrec .= "\n1 NAME " . $REPO_NAME;
1561
            $_HEB = Filter::post('_HEB');
1562
            if ($_HEB) {
1563
                $gedrec .= "\n2 _HEB " . $_HEB;
1564
            }
1565
            $ROMN = Filter::post('ROMN');
1566
            if ($ROMN) {
1567
                $gedrec .= "\n2 ROMN " . $ROMN;
1568
            }
1569
        }
1570
        $ADDR = Filter::post('ADDR');
1571
        if ($ADDR) {
1572
            $gedrec .= "\n1 ADDR " . preg_replace('/\r?\n/', "\n2 CONT ", $ADDR);
1573
        }
1574
        $PHON = Filter::post('PHON');
1575
        if ($PHON) {
1576
            $gedrec .= "\n1 PHON " . $PHON;
1577
        }
1578
        $FAX = Filter::post('FAX');
1579
        if ($FAX) {
1580
            $gedrec .= "\n1 FAX " . $FAX;
1581
        }
1582
        $EMAIL = Filter::post('EMAIL');
1583
        if ($EMAIL) {
1584
            $gedrec .= "\n1 EMAIL " . $EMAIL;
1585
        }
1586
        $WWW = Filter::post('WWW');
1587
        if ($WWW) {
1588
            $gedrec .= "\n1 WWW " . $WWW;
1589
        }
1590
1591
        $record = $WT_TREE->createRecord($gedrec);
1592
        $controller->addInlineJavascript('openerpasteid("' . $record->getXref() . '");');
1593
        break;
1594
1595
////////////////////////////////////////////////////////////////////////////////
1596
    case 'editname':
1597
        $xref    = Filter::get('xref', WT_REGEX_XREF);
1598
        $fact_id = Filter::get('fact_id');
1599
1600
        $person = Individual::getInstance($xref, $WT_TREE);
1601
        check_record_access($person);
1602
1603
        // Find the fact to edit
1604
        $name_fact = null;
1605
        foreach ($person->getFacts() as $fact) {
1606
            if ($fact->getFactId() === $fact_id && $fact->canEdit()) {
1607
                $name_fact = $fact;
1608
            }
1609
        }
1610
        if (!$name_fact) {
1611
            $controller
1612
            ->pageHeader()
1613
            ->addInlineJavascript('closePopupAndReloadParent();');
1614
1615
            return;
1616
        }
1617
1618
        $controller
1619
        ->setPageTitle(I18N::translate('Edit the name'))
1620
        ->pageHeader();
1621
1622
        print_indi_form('update', $person, null, $name_fact, '', $person->getSex());
1623
1624
        break;
1625
1626
////////////////////////////////////////////////////////////////////////////////
1627
    case 'addname':
1628
        $xref = Filter::get('xref', WT_REGEX_XREF);
1629
1630
        $person = Individual::getInstance($xref, $WT_TREE);
1631
        check_record_access($person);
1632
1633
        $controller
1634
        ->setPageTitle(I18N::translate('Add a name'))
1635
        ->pageHeader();
1636
1637
        print_indi_form('update', $person, null, null, '', $person->getSex());
1638
        break;
1639
1640
////////////////////////////////////////////////////////////////////////////////
1641
// Change the order of media objects
1642
////////////////////////////////////////////////////////////////////////////////
1643
    case 'reorder_media':
1644
        $xref = Filter::get('xref', WT_REGEX_XREF);
1645
1646
        $person = Individual::getInstance($xref, $WT_TREE);
1647
        check_record_access($person);
1648
1649
        $controller
1650
        ->setPageTitle(I18N::translate('Re-order media'))
1651
        ->pageHeader()
1652
        ->addInlineJavascript('
1653
			jQuery("#reorder_media_list").sortable({forceHelperSize: true, forcePlaceholderSize: true, opacity: 0.7, cursor: "move", axis: "y"});
1654
1655
			//-- update the order numbers after drag-n-drop sorting is complete
1656
			jQuery("#reorder_media_list").bind("sortupdate", function(event, ui) {
1657
					jQuery("#"+jQuery(this).attr("id")+" input").each(
1658
						function (index, value) {
1659
							value.value = index+1;
1660
						}
1661
					);
1662
				});
1663
		');
1664
1665
        // Get the current sort order
1666
        $sort_obje = array();
1667
        foreach ($person->getFacts('_WT_OBJE_SORT') as $fact) {
1668
            $media = $fact->getTarget();
1669
            if ($media && $media->canShow()) {
1670
                $sort_obje[] = $media;
1671
            }
1672
        }
1673
1674
        // Add other media objects from the individual and any spouse-families
1675
        $record_list = array($person);
1676
        foreach ($person->getSpouseFamilies() as $family) {
1677
            $record_list[] = $family;
1678
        }
1679
        foreach ($record_list as $record) {
1680
            if ($record->canShow()) {
1681
                foreach ($record->getFacts() as $fact) {
1682
                    if (!$fact->isPendingDeletion()) {
1683
                        preg_match_all('/(?:^1|\n\d) OBJE @(' . WT_REGEX_XREF . ')@/', $fact->getGedcom(), $matches);
1684
                        foreach ($matches[1] as $match) {
1685
                            $media = Media::getInstance($match, $WT_TREE);
1686
                            if (!in_array($media, $sort_obje)) {
1687
                                $sort_obje[] = $media;
1688
                            }
1689
                        }
1690
                    }
1691
                }
1692
            }
1693
        }
1694
1695
        ?>
1696
    <div id="edit_interface-page">
1697
        <h2><?php echo I18N::translate('Re-order media'); ?></h2>
1698
        <form name="reorder_form" method="post" action="edit_interface.php">
1699
            <input type="hidden" name="ged" value="<?php echo $WT_TREE->getNameHtml(); ?>">
1700
            <input type="hidden" name="action" value="reorder_media_update">
1701
            <input type="hidden" name="xref" value="<?php echo $xref; ?>">
1702
            <?php echo Filter::getCsrf(); ?>
1703
            <ul id="reorder_media_list">
1704
            <?php foreach ($sort_obje as $n => $obje) { ?>
1705
                <li class="facts_value" style="list-style:none;cursor:move;margin-bottom:2px;" id="li_<?php echo $obje->getXref(); ?>">
1706
                    <table class="pic">
1707
                        <tr>
1708
                            <td>
1709
                                <?php echo $obje->displayImage(); ?>
1710
                            </td>
1711
                            <td>
1712
                                <?php echo $obje->getFullName(); ?>
1713
                            </td>
1714
                        </tr>
1715
                    </table>
1716
                    <input type="hidden" name="order1[<?php echo $obje->getXref(); ?>]" value="<?php echo $n; ?>">
1717
                </li>
1718
            <?php } ?>
1719
            </ul>
1720
            <p id="save-cancel">
1721
                <input type="submit" class="save" value="<?php echo I18N::translate('save'); ?>">
1722
                <input type="button" class="cancel" value="<?php echo I18N::translate('close'); ?>" onclick="window.close();">
1723
            </p>
1724
        </form>
1725
    </div>
1726
        <?php
1727
        break;
1728
1729
    case 'reorder_media_update':
1730
        $xref   = Filter::post('xref', WT_REGEX_XREF);
1731
        $order1 = Filter::post('order1');
1732
1733
        if (!Filter::checkCsrf()) {
1734
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=reorder_media_&xref=' . $xref);
1735
1736
            return;
1737
        }
1738
1739
        $person = Individual::getInstance($xref, $WT_TREE);
1740
        check_record_access($person);
1741
1742
        $controller
1743
        ->setPageTitle(I18N::translate('Re-order media'))
1744
        ->pageHeader();
1745
1746
        // Delete any existing _WT_OBJE_SORT records
1747
        $facts = array('0 @' . $person->getXref() . '@ INDI');
1748
        foreach ($person->getFacts() as $fact) {
1749
            if ($fact->getTag() !== '_WT_OBJE_SORT') {
1750
                $facts[] = $fact->getGedcom();
1751
            }
1752
        }
1753
        if (is_array($order1)) {
1754
            // Add new _WT_OBJE_SORT records
1755
            foreach ($order1 as $xref => $n) {
1756
                $facts[] = '1 _WT_OBJE_SORT @' . $xref . '@';
1757
            }
1758
        }
1759
1760
        $person->updateRecord(implode("\n", $facts), false);
1761
1762
        $controller->addInlineJavascript('closePopupAndReloadParent();');
1763
        break;
1764
1765
////////////////////////////////////////////////////////////////////////////////
1766
// Change the order of children within a family record
1767
////////////////////////////////////////////////////////////////////////////////
1768
    case 'reorder_children':
1769
        $xref   = Filter::post('xref', WT_REGEX_XREF, Filter::get('xref', WT_REGEX_XREF));
1770
        $option = Filter::post('option');
1771
1772
        $family = Family::getInstance($xref, $WT_TREE);
1773
        check_record_access($family);
1774
1775
        $controller
1776
        ->addInlineJavascript('jQuery("#reorder_list").sortable({forceHelperSize: true, forcePlaceholderSize: true, opacity: 0.7, cursor: "move", axis: "y"});')
1777
        ->addInlineJavascript('jQuery("#reorder_list").bind("sortupdate", function(event, ui) { jQuery("#"+jQuery(this).attr("id")+" input").each( function (index, value) { value.value = index+1; }); });')
1778
        ->setPageTitle(I18N::translate('Re-order children'))
1779
        ->pageHeader();
1780
1781
        ?>
1782
    <div id="edit_interface-page">
1783
        <h2><?php echo $controller->getPageTitle(); ?></h2>
1784
        <form name="reorder_form" method="post" action="edit_interface.php">
1785
            <input type="hidden" name="ged" value="<?php echo $WT_TREE->getNameHtml(); ?>">
1786
            <input type="hidden" name="action" value="reorder_update">
1787
            <input type="hidden" name="xref" value="<?php echo $xref; ?>">
1788
            <input type="hidden" name="option" value="bybirth">
1789
            <?php echo Filter::getCsrf(); ?>
1790
            <ul id="reorder_list">
1791
                <?php
1792
                // reorder children in modified families
1793
                $ids = array();
1794
                foreach ($family->getChildren() as $child) {
1795
                    $ids[] = $child->getXref();
1796
                }
1797
                $children = array();
1798
                foreach ($family->getChildren() as $k => $child) {
1799
                    $bdate = $child->getEstimatedBirthDate();
1800
                    if ($bdate->isOK()) {
1801
                        $sortkey = $bdate->julianDay();
1802
                    } else {
1803
                        $sortkey = 1e8; // birth date missing => sort last
1804
                    }
1805
                    $children[$child->getXref()] = $sortkey;
1806
                }
1807
                if ($option === 'bybirth') {
1808
                    asort($children);
1809
                }
1810
                $i = 0;
1811
                foreach ($children as $id => $child) {
1812
                    echo '<li style="cursor:move; margin-bottom:2px; position:relative;"';
1813
                    if (!in_array($id, $ids)) {
1814
                        echo ' class="facts_value new"';
1815
                    }
1816
                    echo ' id="li_', $id, '">';
1817
                    echo Theme::theme()->individualBoxLarge(Individual::getInstance($id, $WT_TREE));
1818
                    echo '<input type="hidden" name="order[', $id, ']" value="', $i, '">';
1819
                    echo '</li>';
1820
                    $i++;
1821
                }
1822
                ?>
1823
            </ul>
1824
            <p id="save-cancel">
1825
                <input type="submit" class="save" value="<?php echo I18N::translate('save'); ?>">
1826
                <input type="submit" class="save" onclick="document.reorder_form.action.value='reorder_children'; document.reorder_form.submit();" value="<?php echo I18N::translate('sort by date of birth'); ?>">
1827
                <input type="button" class="cancel" value="<?php echo I18N::translate('close'); ?>" onclick="window.close();">
1828
            </p>
1829
        </form>
1830
    </div>
1831
        <?php
1832
        break;
1833
1834
    case 'reorder_update':
1835
        $xref  = Filter::post('xref', WT_REGEX_XREF);
1836
        $order = Filter::post('order');
1837
1838
        if (!Filter::checkCsrf()) {
1839
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=reorder_children&xref=' . $xref);
1840
1841
            return;
1842
        }
1843
1844
        $family = Family::getInstance($xref, $WT_TREE);
1845
        check_record_access($family);
1846
1847
        $controller
1848
        ->setPageTitle(I18N::translate('Re-order children'))
1849
        ->pageHeader();
1850
1851
        if (is_array($order)) {
1852
            $gedcom = array('0 @' . $family->getXref() . '@ FAM');
1853
            $facts  = $family->getFacts();
1854
1855
            // Move children to the end of the record
1856
            foreach ($order as $child => $num) {
1857
                foreach ($facts as $n => $fact) {
1858
                    if ($fact->getValue() === '@' . $child . '@') {
1859
                        $facts[] = $fact;
1860
                        unset($facts[$n]);
1861
                        break;
1862
                    }
1863
                }
1864
            }
1865
            foreach ($facts as $fact) {
1866
                $gedcom[] = $fact->getGedcom();
1867
            }
1868
1869
            $family->updateRecord(implode("\n", $gedcom), false);
1870
        }
1871
1872
        $controller->addInlineJavascript('closePopupAndReloadParent();');
1873
        break;
1874
1875
////////////////////////////////////////////////////////////////////////////////
1876
// Change the members of a family record
1877
////////////////////////////////////////////////////////////////////////////////
1878
    case 'changefamily':
1879
        $xref = Filter::get('xref', WT_REGEX_XREF);
1880
1881
        $family = Family::getInstance($xref, $WT_TREE);
1882
        check_record_access($family);
1883
1884
        $controller
1885
        ->setPageTitle(I18N::translate('Change family members') . ' – ' . $family->getFullName())
1886
        ->pageHeader();
1887
1888
        $father   = $family->getHusband();
1889
        $mother   = $family->getWife();
1890
        $children = $family->getChildren();
1891
        ?>
1892
    <div id="edit_interface-page">
1893
        <h2><?php echo $controller->getPageTitle(); ?></h2>
1894
        <div id="changefam">
1895
            <form name="changefamform" method="post" action="edit_interface.php">
1896
                <input type="hidden" name="ged" value="<?php echo $WT_TREE->getNameHtml(); ?>">
1897
                <input type="hidden" name="action" value="changefamily_update">
1898
                <input type="hidden" name="xref" value="<?php echo $xref; ?>">
1899
                <?php echo Filter::getCsrf(); ?>
1900
                <table>
1901
                    <tr>
1902
                    <?php if ($father) { ?>
1903
                        <td class="descriptionbox">
1904
                            <b>
1905
                                <?php
1906
                                switch ($father->getSex()) {
1907
                                    case 'M':
1908
                                        echo I18N::translate('husband');
1909
                                        break;
1910
                                    case 'F':
1911
                                        echo I18N::translate('wife');
1912
                                        break;
1913
                                    default:
1914
                                        echo I18N::translate('spouse');
1915
                                        break;
1916
                                }
1917
                                ?>
1918
                            </b>
1919
                            <input type="hidden" name="HUSB" value="<?php echo $father->getXref(); ?>">
1920
                        </td>
1921
                        <td id="HUSBName" class="optionbox"><?php echo $father->getFullName(); ?>
1922
                        </td>
1923
                    <?php } else { ?>
1924
                        <td class="descriptionbox">
1925
                            <b><?php echo I18N::translate('spouse'); ?></b>
1926
                            <input type="hidden" name="HUSB" value="">
1927
                        </td>
1928
                        <td id="HUSBName" class="optionbox">
1929
                        </td>
1930
                    <?php } ?>
1931
                        <td class="optionbox">
1932
                            <a href="#" id="husbrem" style="display: <?php echo $father === null ? 'none' : 'block'; ?>;" onclick="document.changefamform.HUSB.value=''; document.getElementById('HUSBName').innerHTML=''; this.style.display='none'; return false;">
1933
                                <?php echo I18N::translate('Remove'); ?>
1934
                            </a>
1935
                        </td>
1936
                        <td class="optionbox">
1937
                            <a href="#" onclick="return findIndi(document.changefamform.HUSB, document.getElementById('HUSBName'));">
1938
                                <?php echo I18N::translate('Change'); ?>
1939
                            </a>
1940
                        </td>
1941
                    </tr>
1942
                    <tr>
1943
                        <?php if ($mother) { ?>
1944
                        <td class="descriptionbox">
1945
                            <b>
1946
                                <?php
1947
                                switch ($mother->getSex()) {
1948
                                    case 'M':
1949
                                        echo I18N::translate('husband');
1950
                                        break;
1951
                                    case 'F':
1952
                                        echo I18N::translate('wife');
1953
                                        break;
1954
                                    default:
1955
                                        echo I18N::translate('spouse');
1956
                                        break;
1957
                                }
1958
                                ?>
1959
                            </b>
1960
                            <input type="hidden" name="WIFE" value="<?php echo $mother->getXref(); ?>">
1961
                        </td>
1962
                        <td id="WIFEName" class="optionbox">
1963
                            <?php echo $mother->getFullName(); ?>
1964
                        </td>
1965
                    <?php } else { ?>
1966
                        <td class="descriptionbox">
1967
                            <b><?php echo I18N::translate('spouse'); ?></b>
1968
                            <input type="hidden" name="WIFE" value="">
1969
                        </td>
1970
                        <td id="WIFEName" class="optionbox">
1971
                        </td>
1972
                    <?php } ?>
1973
                        <td class="optionbox">
1974
                            <a href="#" id="wiferem" style="display: <?php echo $mother === null ? 'none' : 'block'; ?>;" onclick="document.changefamform.WIFE.value=''; document.getElementById('WIFEName').innerHTML=''; this.style.display='none'; return false;">
1975
                                <?php echo I18N::translate('Remove'); ?>
1976
                            </a>
1977
                        </td>
1978
                        <td class="optionbox">
1979
                            <a href="#" onclick="return findIndi(document.changefamform.WIFE, document.getElementById('WIFEName'));">
1980
                                <?php echo I18N::translate('Change'); ?>
1981
                            </a>
1982
                        </td>
1983
                    </tr>
1984
                        <?php $i = 0; foreach ($children as $child) { ?>
1985
                    <tr>
1986
                        <td class="descriptionbox">
1987
                            <b>
1988
                                <?php
1989
                                switch ($child->getSex()) {
1990
                                    case 'M':
1991
                                        echo I18N::translate('son');
1992
                                        break;
1993
                                    case 'F':
1994
                                        echo I18N::translate('daughter');
1995
                                        break;
1996
                                    default:
1997
                                        echo I18N::translate('child');
1998
                                        break;
1999
                                }
2000
                                ?>
2001
                            </b>
2002
                            <input type="hidden" name="CHIL<?php echo $i; ?>" value="<?php echo $child->getXref(); ?>">
2003
                        </td>
2004
                        <td id="CHILName<?php echo $i; ?>" class="optionbox"><?php echo $child->getFullName(); ?>
2005
                        </td>
2006
                        <td class="optionbox">
2007
                            <a href="#" id="childrem<?php echo $i; ?>" style="display: block;" onclick="document.changefamform.CHIL<?php echo $i; ?>.value=''; document.getElementById('CHILName<?php echo $i; ?>').innerHTML=''; this.style.display='none'; return false;">
2008
                                <?php echo I18N::translate('Remove'); ?>
2009
                            </a>
2010
                        </td>
2011
                        <td class="optionbox">
2012
                            <a href="#" onclick="return findIndi(document.changefamform.CHIL<?php echo $i; ?>, document.getElementById('CHILName<?php echo $i; ?>'));">
2013
                                <?php echo I18N::translate('Change'); ?>
2014
                            </a>
2015
                        </td>
2016
                    </tr>
2017
                    <?php $i++; } ?>
2018
                    <tr>
2019
                        <td class="descriptionbox">
2020
                            <b><?php echo I18N::translate('child'); ?></b>
2021
                            <input type="hidden" name="CHIL<?php echo $i; ?>" value="">
2022
                        </td>
2023
                        <td id="CHILName<?php echo $i; ?>" class="optionbox">
2024
                        </td>
2025
                        <td colspan="2" class="optionbox child">
2026
                            <a href="#" id="childrem<?php echo $i; ?>" style="display: none;" onclick="document.changefamform.CHIL<?php echo $i; ?>.value=''; document.getElementById('CHILName<?php echo $i; ?>').innerHTML=''; this.style.display='none'; return false;">
2027
                                <?php echo I18N::translate('Remove'); ?>
2028
                            </a>
2029
                            <a href="#" onclick="remElement = document.getElementById('childrem<?php echo $i; ?>'); return findIndi(document.changefamform.CHIL<?php echo $i; ?>, document.getElementById('CHILName<?php echo $i; ?>'));">
2030
                                <?php echo I18N::translate('Add'); ?>
2031
                            </a>
2032
                        </td>
2033
                    </tr>
2034
                </table>
2035
                <p id="save-cancel">
2036
                    <input type="submit" class="save" value="<?php echo I18N::translate('save'); ?>">
2037
                    <input type="button" class="cancel" value="<?php echo I18N::translate('close'); ?>" onclick="window.close();">
2038
                </p>
2039
            </form>
2040
        </div>
2041
    </div>
2042
        <?php
2043
        break;
2044
2045
    case 'changefamily_update':
2046
        $xref      = Filter::post('xref', WT_REGEX_XREF);
2047
        $HUSB      = Filter::post('HUSB', WT_REGEX_XREF);
2048
        $WIFE      = Filter::post('WIFE', WT_REGEX_XREF);
2049
        $keep_chan = Filter::postBool('keep_chan');
2050
2051
        if (!Filter::checkCsrf()) {
2052
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=changefamily&xref=' . $xref);
2053
2054
            return;
2055
        }
2056
2057
        $CHIL = array();
2058
        for ($i = 0; isset($_POST['CHIL' . $i]); ++$i) {
2059
            $CHIL[] = Filter::post('CHIL' . $i, WT_REGEX_XREF);
2060
        }
2061
2062
        $family = Family::getInstance($xref, $WT_TREE);
2063
        check_record_access($family);
2064
2065
        $controller
2066
        ->setPageTitle(I18N::translate('Change family members') . ' – ' . $family->getFullName())
2067
        ->pageHeader();
2068
2069
        // Current family members
2070
        $old_father   = $family->getHusband();
2071
        $old_mother   = $family->getWife();
2072
        $old_children = $family->getChildren();
2073
2074
        // New family members
2075
        $new_father   = Individual::getInstance($HUSB, $WT_TREE);
2076
        $new_mother   = Individual::getInstance($WIFE, $WT_TREE);
2077
        $new_children = array();
2078
        foreach ($CHIL as $child) {
2079
            $new_children[] = Individual::getInstance($child, $WT_TREE);
2080
        }
2081
2082
        if ($old_father !== $new_father) {
2083
            if ($old_father) {
2084
                // Remove old FAMS link
2085
                foreach ($old_father->getFacts('FAMS') as $fact) {
2086
                    if ($fact->getTarget() === $family) {
2087
                        $old_father->deleteFact($fact->getFactId(), !$keep_chan);
2088
                    }
2089
                }
2090
                // Remove old HUSB link
2091
                foreach ($family->getFacts('HUSB|WIFE') as $fact) {
2092
                    if ($fact->getTarget() === $old_father) {
2093
                        $family->deleteFact($fact->getFactId(), !$keep_chan);
2094
                    }
2095
                }
2096
            }
2097
            if ($new_father) {
2098
                // Add new FAMS link
2099
                $new_father->createFact('1 FAMS @' . $family->getXref() . '@', !$keep_chan);
2100
                // Add new HUSB link
2101
                $family->createFact('1 HUSB @' . $new_father->getXref() . '@', !$keep_chan);
2102
            }
2103
        }
2104
2105
        if ($old_mother !== $new_mother) {
2106
            if ($old_mother) {
2107
                // Remove old FAMS link
2108
                foreach ($old_mother->getFacts('FAMS') as $fact) {
2109
                    if ($fact->getTarget() === $family) {
2110
                        $old_mother->deleteFact($fact->getFactId(), !$keep_chan);
2111
                    }
2112
                }
2113
                // Remove old WIFE link
2114
                foreach ($family->getFacts('HUSB|WIFE') as $fact) {
2115
                    if ($fact->getTarget() === $old_mother) {
2116
                        $family->deleteFact($fact->getFactId(), !$keep_chan);
2117
                    }
2118
                }
2119
            }
2120
            if ($new_mother) {
2121
                // Add new FAMS link
2122
                $new_mother->createFact('1 FAMS @' . $family->getXref() . '@', !$keep_chan);
2123
                // Add new WIFE link
2124
                $family->createFact('1 WIFE @' . $new_mother->getXref() . '@', !$keep_chan);
2125
            }
2126
        }
2127
2128
        foreach ($old_children as $old_child) {
2129
            if ($old_child && !in_array($old_child, $new_children)) {
2130
                // Remove old FAMC link
2131
                foreach ($old_child->getFacts('FAMC') as $fact) {
2132
                    if ($fact->getTarget() === $family) {
2133
                        $old_child->deleteFact($fact->getFactId(), !$keep_chan);
2134
                    }
2135
                }
2136
                // Remove old CHIL link
2137
                foreach ($family->getFacts('CHIL') as $fact) {
2138
                    if ($fact->getTarget() === $old_child) {
2139
                        $family->deleteFact($fact->getFactId(), !$keep_chan);
2140
                    }
2141
                }
2142
            }
2143
        }
2144
2145
        foreach ($new_children as $new_child) {
2146
            if ($new_child && !in_array($new_child, $old_children)) {
2147
                // Add new FAMC link
2148
                $new_child->createFact('1 FAMC @' . $family->getXref() . '@', !$keep_chan);
2149
                // Add new CHIL link
2150
                $family->createFact('1 CHIL @' . $new_child->getXref() . '@', !$keep_chan);
2151
            }
2152
        }
2153
2154
        $controller->addInlineJavascript('closePopupAndReloadParent();');
2155
        break;
2156
2157
////////////////////////////////////////////////////////////////////////////////
2158
// Change the order of FAMS records within an INDI record
2159
////////////////////////////////////////////////////////////////////////////////
2160
    case 'reorder_fams':
2161
        $xref   = Filter::post('xref', WT_REGEX_XREF, Filter::get('xref', WT_REGEX_XREF));
2162
        $option = Filter::post('option');
2163
2164
        $person = Individual::getInstance($xref, $WT_TREE);
2165
        check_record_access($person);
2166
2167
        $controller
2168
        ->addInlineJavascript('jQuery("#reorder_list").sortable({forceHelperSize: true, forcePlaceholderSize: true, opacity: 0.7, cursor: "move", axis: "y"});')
2169
        //-- update the order numbers after drag-n-drop sorting is complete
2170
        ->addInlineJavascript('jQuery("#reorder_list").bind("sortupdate", function(event, ui) { jQuery("#"+jQuery(this).attr("id")+" input").each( function (index, value) { value.value = index+1; }); });')
2171
        ->setPageTitle(I18N::translate('Re-order families'))
2172
        ->pageHeader();
2173
2174
        $fams = $person->getSpouseFamilies();
2175
        if ($option === 'bymarriage') {
2176
            usort($fams, '\Fisharebest\Webtrees\Family::compareMarrDate');
2177
        }
2178
2179
        ?>
2180
    <div id="edit_interface-page">
2181
    <h2><?php echo $controller->getPageTitle(); ?></h2>
2182
    <form name="reorder_form" method="post" action="edit_interface.php">
2183
        <input type="hidden" name="ged" value="<?php echo $WT_TREE->getNameHtml(); ?>">
2184
        <input type="hidden" name="action" value="reorder_fams_update">
2185
        <input type="hidden" name="xref" value="<?php echo $xref; ?>">
2186
        <input type="hidden" name="option" value="bymarriage">
2187
        <?php echo Filter::getCsrf(); ?>
2188
        <ul id="reorder_list">
2189
        <?php foreach ($fams as $n => $family) { ?>
2190
            <li class="facts_value" style="cursor:move;margin-bottom:2px;" id="li_<?php echo $family->getXref(); ?>">
2191
                <div class="name2"><?php echo $family->getFullName(); ?></div>
2192
                <?php echo $family->formatFirstMajorFact(WT_EVENTS_MARR, 2); ?>
2193
                <input type="hidden" name="order[<?php echo $family->getXref(); ?>]" value="<?php echo $n; ?>">
2194
            </li>
2195
        <?php } ?>
2196
        </ul>
2197
        <p id="save-cancel">
2198
            <input type="submit" class="save" value="<?php echo I18N::translate('save'); ?>">
2199
            <input type="submit" class="save" onclick="document.reorder_form.action.value='reorder_fams'; document.reorder_form.submit();" value="<?php echo I18N::translate('sort by date of marriage'); ?>">
2200
            <input type="button" class="cancel" value="<?php echo I18N::translate('close'); ?>" onclick="window.close();">
2201
        </p>
2202
    </form>
2203
    </div>
2204
        <?php
2205
        break;
2206
2207
    case 'reorder_fams_update':
2208
        $xref  = Filter::post('xref', WT_REGEX_XREF);
2209
        $order = Filter::post('order');
2210
2211
        if (!Filter::checkCsrf()) {
2212
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=reorder_fams&xref=' . $xref);
2213
2214
            return;
2215
        }
2216
2217
        $person = Individual::getInstance($xref, $WT_TREE);
2218
        check_record_access($person);
2219
2220
        $controller
2221
        ->setPageTitle(I18N::translate('Re-order families'))
2222
        ->pageHeader();
2223
2224
        if (is_array($order)) {
2225
            $gedcom = array('0 @' . $person->getXref() . '@ INDI');
2226
            $facts  = $person->getFacts();
2227
2228
            // Move families to the end of the record
2229
            foreach ($order as $family => $num) {
2230
                foreach ($facts as $n => $fact) {
2231
                    if ($fact->getValue() === '@' . $family . '@') {
2232
                        $facts[] = $fact;
2233
                        unset($facts[$n]);
2234
                        break;
2235
                    }
2236
                }
2237
            }
2238
            foreach ($facts as $fact) {
2239
                $gedcom[] = $fact->getGedcom();
2240
            }
2241
2242
            $person->updateRecord(implode("\n", $gedcom), false);
2243
        }
2244
2245
        $controller->addInlineJavascript('closePopupAndReloadParent();');
2246
        break;
2247
}
2248
2249
/**
2250
 * Show an option to preserve the existing CHAN record when editing.
2251
 *
2252
 * @param GedcomRecord $record
2253
 *
2254
 * @return string
2255
 */
2256
function keep_chan(GedcomRecord $record = null)
2257
{
2258
    global $WT_TREE;
2259
2260
    if (Auth::isAdmin()) {
2261
        if ($record) {
2262
            $details =
2263
                GedcomTag::getLabelValue('DATE', $record->lastChangeTimestamp()) .
2264
                GedcomTag::getLabelValue('_WT_USER', Filter::escapeHtml($record->lastChangeUser()));
2265
        } else {
2266
            $details = '';
2267
        }
2268
2269
        return
2270
            '<tr><td class="descriptionbox wrap width25">' .
2271
            GedcomTag::getLabel('CHAN') .
2272
            '</td><td class="optionbox wrap">' .
2273
            '<input type="checkbox" name="keep_chan" value="1" ' . ($WT_TREE->getPreference('NO_UPDATE_CHAN') ? 'checked' : '') . '>' .
2274
            I18N::translate('Keep the existing “last change” information') .
2275
            $details .
2276
            '</td></tr>';
2277
    } else {
2278
        return '';
2279
    }
2280
}
2281
2282
/**
2283
 * Print a form to add an individual or edit an individual’s name
2284
 *
2285
 * @param string     $nextaction
2286
 * @param Individual $person
2287
 * @param Family     $family
2288
 * @param Fact       $name_fact
2289
 * @param string     $famtag
2290
 * @param string     $gender
2291
 */
2292
function print_indi_form($nextaction, Individual $person = null, Family $family = null, Fact $name_fact = null, $famtag = 'CHIL', $gender = 'U')
2293
{
2294
    global $WT_TREE, $bdm, $controller;
2295
2296
    if ($person) {
2297
        $xref = $person->getXref();
2298
    } elseif ($family) {
2299
        $xref = $family->getXref();
2300
    } else {
2301
        $xref = 'new';
2302
    }
2303
2304
    // Different cultures do surnames differently
2305
    $surname_tradition = SurnameTradition::create($WT_TREE->getPreference('SURNAME_TRADITION'));
2306
2307
    $name_fields = array();
2308
    if ($name_fact) {
2309
        // Editing an existing name
2310
        $name_fact_id = $name_fact->getFactId();
2311
        $name_type    = $name_fact->getAttribute('TYPE');
2312
        $namerec      = $name_fact->getGedcom();
2313
        foreach (Config::standardNameFacts() as $tag) {
2314
            if ($tag === 'NAME') {
2315
                $name_fields[$tag] = $name_fact->getValue();
2316
            } else {
2317
                $name_fields[$tag] = $name_fact->getAttribute($tag);
2318
            }
2319
        }
2320
        // Populate any missing 2 XXXX fields from the 1 NAME field
2321
        $npfx_accept = implode('|', Config::namePrefixes());
2322
        if (preg_match('/(((' . $npfx_accept . ')\.? +)*)([^\n\/"]*)("(.*)")? *\/(([a-z]{2,3} +)*)(.*)\/ *(.*)/i', $name_fields['NAME'], $name_bits)) {
2323
            if (empty($name_fields['NPFX'])) {
2324
                $name_fields['NPFX'] = $name_bits[1];
2325
            }
2326
            if (empty($name_fields['SPFX']) && empty($name_fields['SURN'])) {
2327
                $name_fields['SPFX'] = trim($name_bits[7]);
2328
                // For names with two surnames, there will be four slashes.
2329
                // Turn them into a list
2330
                $name_fields['SURN'] = preg_replace('~/[^/]*/~', ',', $name_bits[9]);
2331
            }
2332
            if (empty($name_fields['GIVN'])) {
2333
                $name_fields['GIVN'] = $name_bits[4];
2334
            }
2335
            if (empty($name_fields['NICK']) && !empty($name_bits[6]) && !preg_match('/^2 NICK/m', $namerec)) {
2336
                $name_fields['NICK'] = $name_bits[6];
2337
            }
2338
        }
2339
2340
    } else {
2341
        // Creating a new name
2342
        $name_fact_id = null;
2343
        $name_type    = null;
2344
        $namerec      = null;
2345
        // Populate the standard NAME field and subfields
2346
        foreach (Config::standardNameFacts() as $tag) {
2347
            $name_fields[$tag] = '';
2348
        }
2349
        // Inherit surname from parents, spouse or child
2350
        if ($family) {
2351
            $father = $family->getHusband();
2352
            if ($father && $father->getFirstFact('NAME')) {
2353
                $father_name = $father->getFirstFact('NAME')->getValue();
2354
            } else {
2355
                $father_name = '';
2356
            }
2357
            $mother = $family->getWife();
2358
            if ($mother && $mother->getFirstFact('NAME')) {
2359
                $mother_name = $mother->getFirstFact('NAME')->getValue();
2360
            } else {
2361
                $mother_name = '';
2362
            }
2363
        } else {
2364
            $father      = null;
2365
            $mother      = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $mother is dead and can be removed.
Loading history...
2366
            $father_name = '';
2367
            $mother_name = '';
2368
        }
2369
        if ($person && $person->getFirstFact('NAME')) {
2370
            $indi_name = $person->getFirstFact('NAME')->getValue();
2371
        } else {
2372
            $indi_name = '';
2373
        }
2374
2375
        switch ($nextaction) {
2376
            case 'add_child_to_family_action':
2377
                $name_fields = array_merge($name_fields, $surname_tradition->newChildNames($father_name, $mother_name, $gender));
2378
                break;
2379
            case 'add_child_to_individual_action':
2380
                if ($person->getSex() === 'F') {
0 ignored issues
show
Bug introduced by
The method getSex() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

2380
                if ($person->/** @scrutinizer ignore-call */ getSex() === 'F') {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
2381
                    $name_fields = array_merge($name_fields, $surname_tradition->newChildNames('', $indi_name, $gender));
2382
                } else {
2383
                    $name_fields = array_merge($name_fields, $surname_tradition->newChildNames($indi_name, '', $gender));
2384
                }
2385
                break;
2386
            case 'add_parent_to_individual_action':
2387
                $name_fields = array_merge($name_fields, $surname_tradition->newParentNames($indi_name, $gender));
2388
                break;
2389
            case 'add_spouse_to_family_action':
2390
                if ($father) {
2391
                    $name_fields = array_merge($name_fields, $surname_tradition->newSpouseNames($father_name, $gender));
2392
                } else {
2393
                    $name_fields = array_merge($name_fields, $surname_tradition->newSpouseNames($mother_name, $gender));
2394
                }
2395
                break;
2396
            case 'add_spouse_to_individual_action':
2397
                $name_fields = array_merge($name_fields, $surname_tradition->newSpouseNames($indi_name, $gender));
2398
                break;
2399
            case 'add_unlinked_indi_action':
2400
            case 'update':
2401
                if ($surname_tradition->hasSurnames()) {
2402
                    $name_fields['NAME'] = '//';
2403
                }
2404
                break;
2405
        }
2406
    }
2407
2408
    $bdm = ''; // used to copy '1 SOUR' to '2 SOUR' for BIRT DEAT MARR
2409
2410
    echo '<div id="edit_interface-page">';
2411
    echo '<h2>', $controller->getPageTitle(), '</h2>';
2412
    FunctionsPrint::initializeCalendarPopup();
2413
    echo '<form method="post" name="addchildform" onsubmit="return checkform();">';
2414
    echo '<input type="hidden" name="ged" value="', $WT_TREE->getNameHtml(), '">';
2415
    echo '<input type="hidden" name="action" value="', $nextaction, '">';
2416
    echo '<input type="hidden" name="fact_id" value="', $name_fact_id, '">';
2417
    echo '<input type="hidden" name="xref" value="', $xref, '">';
2418
    echo '<input type="hidden" name="famtag" value="', $famtag, '">';
2419
    echo '<input type="hidden" name="gender" value="', $gender, '">';
2420
    echo '<input type="hidden" name="goto" value="">'; // set by javascript
2421
    echo Filter::getCsrf();
2422
    echo '<table class="facts_table">';
2423
2424
    switch ($nextaction) {
2425
        case 'add_child_to_family_action':
2426
        case 'add_child_to_individual_action':
2427
            // When adding a new child, specify the pedigree
2428
            FunctionsEdit::addSimpleTag('0 PEDI');
2429
            break;
2430
        case 'update':
2431
            // When adding/editing a name, specify the type
2432
            FunctionsEdit::addSimpleTag('0 TYPE ' . $name_type, '', '', null, $person);
2433
            break;
2434
    }
2435
2436
    // First - new/existing standard name fields
2437
    foreach ($name_fields as $tag => $value) {
2438
        if (substr_compare($tag, '_', 0, 1) !== 0) {
2439
            FunctionsEdit::addSimpleTag('0 ' . $tag . ' ' . $value);
2440
        }
2441
    }
2442
2443
    // Second - new/existing advanced name fields
2444
    if ($surname_tradition->hasMarriedNames() || preg_match('/\n2 _MARNM /', $namerec)) {
0 ignored issues
show
Bug introduced by
It seems like $namerec can also be of type null; however, parameter $subject of preg_match() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

2444
    if ($surname_tradition->hasMarriedNames() || preg_match('/\n2 _MARNM /', /** @scrutinizer ignore-type */ $namerec)) {
Loading history...
2445
        $adv_name_fields = array('_MARNM' => '');
2446
    } else {
2447
        $adv_name_fields = array();
2448
    }
2449
    if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('ADVANCED_NAME_FACTS'), $match)) {
2450
        foreach ($match[1] as $tag) {
2451
            $adv_name_fields[$tag] = '';
2452
        }
2453
    }
2454
2455
    foreach (array_keys($adv_name_fields) as $tag) {
2456
        // Edit existing tags, grouped together
2457
        if (preg_match_all('/2 ' . $tag . ' (.+)/', $namerec, $match)) {
2458
            foreach ($match[1] as $value) {
2459
                FunctionsEdit::addSimpleTag('2 ' . $tag . ' ' . $value, '', GedcomTag::getLabel('NAME:' . $tag, $person));
2460
                if ($tag === '_MARNM') {
2461
                    preg_match_all('/\/([^\/]*)\//', $value, $matches);
2462
                    FunctionsEdit::addSimpleTag('2 _MARNM_SURN ' . implode(',', $matches[1]));
2463
                }
2464
            }
2465
        }
2466
        // Allow a new tag to be entered
2467
        if (!array_key_exists($tag, $name_fields)) {
2468
            FunctionsEdit::addSimpleTag('0 ' . $tag, '', GedcomTag::getLabel('NAME:' . $tag, $person));
2469
            if ($tag === '_MARNM') {
2470
                FunctionsEdit::addSimpleTag('0 _MARNM_SURN');
2471
            }
2472
        }
2473
    }
2474
2475
    // Third - new/existing custom name fields
2476
    foreach ($name_fields as $tag => $value) {
2477
        if (substr_compare($tag, '_', 0, 1) === 0) {
2478
            FunctionsEdit::addSimpleTag('0 ' . $tag . ' ' . $value);
2479
            if ($tag === '_MARNM') {
2480
                preg_match_all('/\/([^\/]*)\//', $value, $matches);
2481
                FunctionsEdit::addSimpleTag('2 _MARNM_SURN ' . implode(',', $matches[1]));
2482
            }
2483
        }
2484
    }
2485
2486
    // Fourth - SOUR, NOTE, _CUSTOM, etc.
2487
    if ($namerec) {
2488
        $gedlines = explode("\n", $namerec); // -- find the number of lines in the record
2489
        $fields   = explode(' ', $gedlines[0]);
2490
        $glevel   = $fields[0];
2491
        $level    = $glevel;
2492
        $type     = $fields[1];
2493
        $tags     = array();
2494
        $i        = 0;
2495
        do {
2496
            if ($type !== 'TYPE' && !array_key_exists($type, $name_fields) && !array_key_exists($type, $adv_name_fields)) {
2497
                $text = '';
2498
                for ($j = 2; $j < count($fields); $j++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
2499
                    if ($j > 2) {
2500
                        $text .= ' ';
2501
                    }
2502
                    $text .= $fields[$j];
2503
                }
2504
                while (($i + 1 < count($gedlines)) && (preg_match('/' . ($level + 1) . ' CONT ?(.*)/', $gedlines[$i + 1], $cmatch) > 0)) {
2505
                    $text .= "\n" . $cmatch[1];
2506
                    $i++;
2507
                }
2508
                FunctionsEdit::addSimpleTag($level . ' ' . $type . ' ' . $text);
2509
            }
2510
            $tags[] = $type;
2511
            $i++;
2512
            if (isset($gedlines[$i])) {
2513
                $fields = explode(' ', $gedlines[$i]);
2514
                $level  = $fields[0];
2515
                if (isset($fields[1])) {
2516
                    $type = $fields[1];
2517
                }
2518
            }
2519
        } while (($level > $glevel) && ($i < count($gedlines)));
2520
    }
2521
2522
    // If we are adding a new individual, add the basic details
2523
    if ($nextaction !== 'update') {
2524
        echo '</table><br><table class="facts_table">';
2525
        // 1 SEX
2526
        if ($famtag === 'HUSB' || $gender === 'M') {
2527
            FunctionsEdit::addSimpleTag("0 SEX M");
2528
        } elseif ($famtag === 'WIFE' || $gender === 'F') {
2529
            FunctionsEdit::addSimpleTag('0 SEX F');
2530
        } else {
2531
            FunctionsEdit::addSimpleTag('0 SEX');
2532
        }
2533
        $bdm = 'BD';
2534
        if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('QUICK_REQUIRED_FACTS'), $matches)) {
2535
            foreach ($matches[1] as $match) {
2536
                if (!in_array($match, explode('|', WT_EVENTS_DEAT))) {
2537
                    FunctionsEdit::addSimpleTags($match);
2538
                }
2539
            }
2540
        }
2541
        //-- if adding a spouse add the option to add a marriage fact to the new family
2542
        if ($nextaction === 'add_spouse_to_individual_action' || $nextaction === 'add_spouse_to_family_action') {
2543
            $bdm .= 'M';
2544
            if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('QUICK_REQUIRED_FAMFACTS'), $matches)) {
2545
                foreach ($matches[1] as $match) {
2546
                    FunctionsEdit::addSimpleTags($match);
2547
                }
2548
            }
2549
        }
2550
        if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('QUICK_REQUIRED_FACTS'), $matches)) {
2551
            foreach ($matches[1] as $match) {
2552
                if (in_array($match, explode('|', WT_EVENTS_DEAT))) {
2553
                    FunctionsEdit::addSimpleTags($match);
2554
                }
2555
            }
2556
        }
2557
    }
2558
2559
    echo keep_chan($person);
2560
    echo '</table>';
2561
    if ($nextaction === 'update') {
2562
        // GEDCOM 5.5.1 spec says NAME doesn’t get a OBJE
2563
        FunctionsEdit::printAddLayer('SOUR');
2564
        FunctionsEdit::printAddLayer('NOTE');
2565
        FunctionsEdit::printAddLayer('SHARED_NOTE');
2566
        FunctionsEdit::printAddLayer('RESN');
2567
    } else {
2568
        FunctionsEdit::printAddLayer('SOUR', 1);
2569
        FunctionsEdit::printAddLayer('NOTE', 1);
2570
        FunctionsEdit::printAddLayer('SHARED_NOTE', 1);
2571
        FunctionsEdit::printAddLayer('RESN', 1);
2572
    }
2573
2574
    // If we are editing an existing name, allow raw GEDCOM editing
2575
    if ($name_fact && (Auth::isAdmin() || $WT_TREE->getPreference('SHOW_GEDCOM_RECORD'))) {
2576
        echo
2577
            '<br><br><a href="edit_interface.php?action=editrawfact&amp;xref=', $xref, '&amp;fact_id=', $name_fact->getFactId(), '&amp;ged=', $WT_TREE->getNameUrl(), '">',
2578
            I18N::translate('Edit the raw GEDCOM'),
2579
            '</a>';
2580
    }
2581
2582
    echo '<p id="save-cancel">';
2583
    echo '<input type="submit" class="save" value="', /* I18N: A button label. */ I18N::translate('save'), '">';
2584
    if (preg_match('/^add_(child|spouse|parent|unlinked_indi)/', $nextaction)) {
2585
        echo '<input type="submit" class="save" value="', /* I18N: A button label. */ I18N::translate('go to new individual'), '" onclick="document.addchildform.goto.value=\'new\';">';
2586
    }
2587
    echo '<input type="button" class="cancel" value="', /* I18N: A button label. */ I18N::translate('close'), '" onclick="window.close();">';
2588
    echo '</p>';
2589
    echo '</form>';
2590
    $controller->addInlineJavascript('
2591
	SURNAME_TRADITION="' . $WT_TREE->getPreference('SURNAME_TRADITION') . '";
2592
	gender="' . $gender . '";
2593
	famtag="' . $famtag . '";
2594
	function trim(str) {
2595
		str=str.replace(/\s\s+/g, " ");
2596
		return str.replace(/(^\s+)|(\s+$)/g, "");
2597
	}
2598
2599
	function lang_class(str) {
2600
		if (str.match(/[\u0370-\u03FF]/)) return "greek";
2601
		if (str.match(/[\u0400-\u04FF]/)) return "cyrillic";
2602
		if (str.match(/[\u0590-\u05FF]/)) return "hebrew";
2603
		if (str.match(/[\u0600-\u06FF]/)) return "arabic";
2604
		return "latin"; // No matched text implies latin :-)
2605
	}
2606
2607
	// Generate a full name from the name components
2608
	function generate_name() {
2609
		var npfx = jQuery("#NPFX").val();
2610
		var givn = jQuery("#GIVN").val();
2611
		var spfx = jQuery("#SPFX").val();
2612
		var surn = jQuery("#SURN").val();
2613
		var nsfx = jQuery("#NSFX").val();
2614
		if (SURNAME_TRADITION === "polish" && (gender === "F" || famtag === "WIFE")) {
2615
			surn = surn.replace(/ski$/, "ska");
2616
			surn = surn.replace(/cki$/, "cka");
2617
			surn = surn.replace(/dzki$/, "dzka");
2618
			surn = surn.replace(/żki$/, "żka");
2619
		}
2620
		// Commas are used in the GIVN and SURN field to separate lists of surnames.
2621
		// For example, to differentiate the two Spanish surnames from an English
2622
		// double-barred name.
2623
		// Commas *may* be used in other fields, and will form part of the NAME.
2624
		if (WT_LOCALE === "vi" || WT_LOCALE === "hu") {
2625
			// Default format: /SURN/ GIVN
2626
			return trim(npfx+" /"+trim(spfx+" "+surn).replace(/ *, */g, " ")+"/ "+givn.replace(/ *, */g, " ")+" "+nsfx);
2627
		} else if (WT_LOCALE === "zh-Hans" || WT_LOCALE === "zh-Hant") {
2628
			// Default format: /SURN/GIVN
2629
			return npfx+"/"+spfx+surn+"/"+givn+nsfx;
2630
		} else {
2631
			// Default format: GIVN /SURN/
2632
			return trim(npfx+" "+givn.replace(/ *, */g, " ")+" /"+trim(spfx+" "+surn).replace(/ *, */g, " ")+"/ "+nsfx);
2633
		}
2634
	}
2635
2636
	// Update the NAME and _MARNM fields from the name components
2637
	// and also display the value in read-only "gedcom" format.
2638
	function updatewholename() {
2639
		// Don’t update the name if the user manually changed it
2640
		if (manualChange) {
2641
			return;
2642
		}
2643
		var npfx = jQuery("#NPFX").val();
2644
		var givn = jQuery("#GIVN").val();
2645
		var spfx = jQuery("#SPFX").val();
2646
		var surn = jQuery("#SURN").val();
2647
		var nsfx = jQuery("#NSFX").val();
2648
		var name = generate_name();
2649
		jQuery("#NAME").val(name);
2650
		jQuery("#NAME_display").text(name);
2651
		// Married names inherit some NSFX values, but not these
2652
		nsfx = nsfx.replace(/^(I|II|III|IV|V|VI|Junior|Jr\.?|Senior|Sr\.?)$/i, "");
2653
		// Update _MARNM field from _MARNM_SURN field and display it
2654
		// Be careful of mixing latin/hebrew/etc. character sets.
2655
		var ip = document.getElementsByTagName("input");
2656
		var marnm_id = "";
2657
		var romn = "";
2658
		var heb = "";
2659
		for (var i = 0; i < ip.length; i++) {
2660
			var val = trim(ip[i].value);
2661
			if (ip[i].id.indexOf("_HEB") === 0)
2662
				heb = val;
2663
			if (ip[i].id.indexOf("ROMN") === 0)
2664
				romn = val;
2665
			if (ip[i].id.indexOf("_MARNM") === 0) {
2666
				if (ip[i].id.indexOf("_MARNM_SURN") === 0) {
2667
					var msurn = "";
2668
					if (val !== "") {
2669
						var lc = lang_class(document.getElementById(ip[i].id).value);
2670
						if (lang_class(name) === lc)
2671
							msurn = trim(npfx + " " + givn + " /" + val + "/ " + nsfx);
2672
						else if (lc === "hebrew")
2673
							msurn = heb.replace(/\/.*\//, "/" + val + "/");
2674
						else if (lang_class(romn) === lc)
2675
							msurn = romn.replace(/\/.*\//, "/" + val + "/");
2676
					}
2677
					document.getElementById(marnm_id).value = msurn;
2678
					document.getElementById(marnm_id+"_display").innerHTML = msurn;
2679
				} else {
2680
					marnm_id = ip[i].id;
2681
				}
2682
			}
2683
		}
2684
	}
2685
2686
	// Toggle the name editor fields between
2687
	// <input type="hidden"> <span style="display:inline">
2688
	// <input type="text">   <span style="display:hidden">
2689
	var oldName = "";
2690
2691
	// Calls to generate_name() trigger an update - hence need to
2692
	// set the manual change to true first. We are probably
2693
	// listening to the wrong events on the input fields...
2694
	var manualChange = true;
2695
	manualChange = generate_name() !== jQuery("#NAME").val();
2696
2697
	function convertHidden(eid) {
2698
		var input1 = jQuery("#" + eid);
2699
		var input2 = jQuery("#" + eid + "_display");
2700
		// Note that IE does not allow us to change the type of an input, so we must create a new one.
2701
		if (input1.attr("type")=="hidden") {
2702
			input1.replaceWith(input1.clone().attr("type", "text"));
2703
			input2.hide();
2704
		} else {
2705
			input1.replaceWith(input1.clone().attr("type", "hidden"));
2706
			input2.show();
2707
		}
2708
	}
2709
2710
	/**
2711
	 * if the user manually changed the NAME field, then update the textual
2712
	 * HTML representation of it
2713
	 * If the value changed set manualChange to true so that changing
2714
	 * the other fields doesn’t change the NAME line
2715
	 */
2716
	function updateTextName(eid) {
2717
		var element = document.getElementById(eid);
2718
		if (element) {
2719
			if (element.value!=oldName) manualChange = true;
2720
			var delement = document.getElementById(eid+"_display");
2721
			if (delement) {
2722
				delement.innerHTML = element.value;
2723
			}
2724
		}
2725
	}
2726
2727
	function checkform() {
2728
		var ip=document.getElementsByTagName("input");
2729
		for (var i=0; i<ip.length; i++) {
2730
			// ADD slashes to _HEB and _AKA names
2731
			if (ip[i].id.indexOf("_AKA")==0 || ip[i].id.indexOf("_HEB")==0 || ip[i].id.indexOf("ROMN")==0)
2732
				if (ip[i].value.indexOf("/")<0 && ip[i].value!="")
2733
					ip[i].value=ip[i].value.replace(/([^\s]+)\s*$/, "/$1/");
2734
			// Blank out temporary _MARNM_SURN
2735
			if (ip[i].id.indexOf("_MARNM_SURN")==0)
2736
					ip[i].value="";
2737
			// Convert "xxx yyy" and "xxx y yyy" surnames to "xxx,yyy"
2738
			if ((SURNAME_TRADITION=="spanish" || "SURNAME_TRADITION"=="portuguese") && ip[i].id.indexOf("SURN")==0) {
2739
				ip[i].value=document.forms[0].SURN.value.replace(/^\s*([^\s,]{2,})\s+([iIyY] +)?([^\s,]{2,})\s*$/, "$1,$3");
2740
			}
2741
		}
2742
		return true;
2743
	}
2744
2745
	// If the name isn’t initially formed from the components in a standard way,
2746
	// then don’t automatically update it.
2747
	if (document.getElementById("NAME").value!=generate_name() && document.getElementById("NAME").value!="//") {
2748
		convertHidden("NAME");
2749
	}
2750
	');
2751
    echo '</div>';
2752
}
2753
2754
/**
2755
 * Can we edit a GedcomRecord object
2756
 *
2757
 * @param GedcomRecord $object
2758
 */
2759
function check_record_access(GedcomRecord $object = null)
2760
{
2761
    global $controller;
2762
2763
    if (!$object || !$object->canShow() || !$object->canEdit()) {
2764
        $controller
2765
            ->pageHeader()
2766
            ->addInlineJavascript('closePopupAndReloadParent();');
2767
        exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
2768
    }
2769
}
2770