FunctionsCharts::printFamilyChildren()   F
last analyzed

Complexity

Conditions 27
Paths 128

Size

Total Lines 130
Code Lines 90

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 27
eloc 90
nc 128
nop 6
dl 0
loc 130
rs 3.9333
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\Functions;
17
18
use Fisharebest\Webtrees\Auth;
19
use Fisharebest\Webtrees\Family;
20
use Fisharebest\Webtrees\I18N;
21
use Fisharebest\Webtrees\Individual;
22
use Fisharebest\Webtrees\Theme;
23
24
/**
25
 * Class FunctionsCharts - common functions
26
 */
27
class FunctionsCharts
28
{
29
    /**
30
     * print a table cell with sosa number
31
     *
32
     * @param int $sosa
33
     * @param string $pid optional pid
34
     * @param string $arrowDirection direction of link arrow
35
     */
36
    public static function printSosaNumber($sosa, $pid = "", $arrowDirection = "up")
37
    {
38
        if (substr($sosa, -1, 1) == ".") {
39
            $personLabel = substr($sosa, 0, -1);
40
        } else {
41
            $personLabel = $sosa;
42
        }
43
        if ($arrowDirection == "blank") {
44
            $visibility = "hidden";
45
        } else {
46
            $visibility = "normal";
47
        }
48
        echo "<td class=\"subheaders center\" style=\"vertical-align: middle; text-indent: 0px; margin-top: 0px; white-space: nowrap; visibility: ", $visibility, ";\">";
49
        echo $personLabel;
50
        if ($sosa != "1" && $pid != "") {
51
            if ($arrowDirection == "left") {
52
                $dir = 0;
53
            } elseif ($arrowDirection == "right") {
54
                $dir = 1;
55
            } elseif ($arrowDirection == "down") {
56
                $dir = 3;
57
            } else {
58
                $dir = 2; // either 'blank' or 'up'
59
            }
60
            echo '<br>';
61
            self::printUrlArrow('#' . $pid, $pid, $dir);
62
        }
63
        echo '</td>';
64
    }
65
66
    /**
67
     * print the parents table for a family
68
     *
69
     * @param Family $family family gedcom ID
70
     * @param int $sosa child sosa number
71
     * @param string $label indi label (descendancy booklet)
72
     * @param string $parid parent ID (descendancy booklet)
73
     * @param string $gparid gd-parent ID (descendancy booklet)
74
     * @param int $show_full large or small box
75
     */
76
    public static function printFamilyParents(Family $family, $sosa = 0, $label = '', $parid = '', $gparid = '', $show_full = 1)
77
    {
78
        if ($show_full) {
79
            $pbheight = Theme::theme()->parameter('chart-box-y') + 14;
80
        } else {
81
            $pbheight = Theme::theme()->parameter('compact-chart-box-y') + 14;
82
        }
83
84
        $husb = $family->getHusband();
85
        if ($husb) {
86
            echo '<a name="', $husb->getXref(), '"></a>';
87
        } else {
88
            $husb = new Individual('M', "0 @M@ INDI\n1 SEX M", null, $family->getTree());
89
        }
90
        $wife = $family->getWife();
91
        if ($wife) {
92
            echo '<a name="', $wife->getXref(), '"></a>';
93
        } else {
94
            $wife = new Individual('F', "0 @F@ INDI\n1 SEX F", null, $family->getTree());
95
        }
96
97
        if ($sosa) {
98
            echo '<p class="name_head">', $family->getFullName(), '</p>';
99
        }
100
101
        /**
102
         * husband side
103
         */
104
        echo '<table cellspacing="0" cellpadding="0" border="0"><tr><td rowspan="2">';
105
        echo '<table border="0"><tr>';
106
107
        if ($parid) {
108
            if ($husb->getXref() == $parid) {
109
                self::printSosaNumber($label);
110
            } else {
111
                self::printSosaNumber($label, '', 'blank');
112
            }
113
        } elseif ($sosa) {
114
            self::printSosaNumber($sosa * 2);
115
        }
116
        if ($husb->isPendingAddtion()) {
117
            echo '<td class="facts_value new">';
118
        } elseif ($husb->isPendingDeletion()) {
119
            echo '<td class="facts_value old">';
120
        } else {
121
            echo '<td>';
122
        }
123
        FunctionsPrint::printPedigreePerson($husb, $show_full);
124
        echo '</td></tr></table>';
125
        echo '</td>';
126
        // husband’s parents
127
        $hfam = $husb->getPrimaryChildFamily();
128
        if ($hfam) {
129
            // remove the|| test for $sosa
130
            echo '<td rowspan="2"><img src="' . Theme::theme()->parameter('image-hline') . '"></td><td rowspan="2"><img src="' . Theme::theme()->parameter('image-vline') . '" width="3" height="' . ($pbheight + 9) . '"></td>';
131
            echo '<td><img class="line5" src="' . Theme::theme()->parameter('image-hline') . '"></td><td>';
132
            // husband’s father
133
            if ($hfam && $hfam->getHusband()) {
134
                echo '<table border="0"><tr>';
135
                if ($sosa > 0) {
136
                    self::printSosaNumber($sosa * 4, $hfam->getHusband()->getXref(), 'down');
137
                }
138
                if (!empty($gparid) && $hfam->getHusband()->getXref() == $gparid) {
139
                    self::printSosaNumber(trim(substr($label, 0, -3), '.') . '.');
140
                }
141
                echo '<td>';
142
                FunctionsPrint::printPedigreePerson($hfam->getHusband(), $show_full);
143
                echo '</td></tr></table>';
144
            } elseif ($hfam && !$hfam->getHusband()) {
145
                // Empty box for grandfather
146
                echo '<table border="0"><tr>';
147
                echo '<td>';
148
                FunctionsPrint::printPedigreePerson($hfam->getHusband(), $show_full);
149
                echo '</td></tr></table>';
150
            }
151
            echo '</td>';
152
        }
153
        if ($hfam && ($sosa != -1)) {
154
            echo '<td rowspan="2">';
155
            self::printUrlArrow(($sosa == 0 ? '?famid=' . $hfam->getXref() . '&amp;ged=' . $hfam->getTree()->getNameUrl() : '#' . $hfam->getXref()), $hfam->getXref(), 1);
156
            echo '</td>';
157
        }
158
        if ($hfam) {
159
            // husband’s mother
160
            echo '</tr><tr><td><img src="' . Theme::theme()->parameter('image-hline') . '"></td><td>';
161
            if ($hfam && $hfam->getWife()) {
162
                echo '<table border=\'0\'><tr>';
163
                if ($sosa > 0) {
164
                    self::printSosaNumber($sosa * 4 + 1, $hfam->getWife()->getXref(), 'down');
165
                }
166
                if (!empty($gparid) && $hfam->getWife()->getXref() == $gparid) {
167
                    self::printSosaNumber(trim(substr($label, 0, -3), '.') . '.');
168
                }
169
                echo '<td>';
170
                FunctionsPrint::printPedigreePerson($hfam->getWife(), $show_full);
171
                echo '</td></tr></table>';
172
            } elseif ($hfam && !$hfam->getWife()) {
173
                // Empty box for grandmother
174
                echo '<table border="0"><tr>';
175
                echo '<td>';
176
                FunctionsPrint::printPedigreePerson($hfam->getWife(), $show_full);
177
                echo '</td></tr></table>';
178
            }
179
            echo '</td>';
180
        }
181
        echo '</tr></table>';
182
        if ($sosa && $family->canShow()) {
183
            foreach ($family->getFacts(WT_EVENTS_MARR) as $fact) {
184
                echo '<a href="', $family->getHtmlUrl(), '" class="details1">';
185
                echo str_repeat('&nbsp;', 10);
186
                echo $fact->summary();
187
                echo '</a>';
188
            }
189
        } else {
190
            echo '<br>';
191
        }
192
193
        /**
194
         * wife side
195
         */
196
        echo '<table cellspacing="0" cellpadding="0" border="0"><tr><td rowspan="2">';
197
        echo '<table><tr>';
198
        if ($parid) {
199
            if ($wife->getXref() == $parid) {
200
                self::printSosaNumber($label);
201
            } else {
202
                self::printSosaNumber($label, '', 'blank');
203
            }
204
        } elseif ($sosa) {
205
            self::printSosaNumber($sosa * 2 + 1);
206
        }
207
        if ($wife->isPendingAddtion()) {
208
            echo '<td class="facts_value new">';
209
        } elseif ($wife->isPendingDeletion()) {
210
            echo '<td class="facts_value old">';
211
        } else {
212
            echo '<td>';
213
        }
214
        FunctionsPrint::printPedigreePerson($wife, $show_full);
215
        echo '</td></tr></table>';
216
        echo '</td>';
217
        // wife’s parents
218
        $hfam = $wife->getPrimaryChildFamily();
219
220
        if ($hfam) {
221
            echo '<td rowspan="2"><img src="' . Theme::theme()->parameter('image-hline') . '"></td><td rowspan="2"><img src="' . Theme::theme()->parameter('image-vline') . '" width="3" height="' . ($pbheight + 9) . '"></td>';
222
            echo '<td><img class="line5" src="' . Theme::theme()->parameter('image-hline') . '"></td><td>';
223
            // wife’s father
224
            if ($hfam && $hfam->getHusband()) {
225
                echo '<table><tr>';
226
                if ($sosa > 0) {
227
                    self::printSosaNumber($sosa * 4 + 2, $hfam->getHusband()->getXref(), 'down');
228
                }
229
                if (!empty($gparid) && $hfam->getHusband()->getXref() == $gparid) {
230
                    self::printSosaNumber(trim(substr($label, 0, -3), '.') . '.');
231
                }
232
                echo '<td>';
233
                FunctionsPrint::printPedigreePerson($hfam->getHusband(), $show_full);
234
                echo '</td></tr></table>';
235
            } elseif ($hfam && !$hfam->getHusband()) {
236
                // Empty box for grandfather
237
                echo '<table border="0"><tr>';
238
                echo '<td>';
239
                FunctionsPrint::printPedigreePerson($hfam->getHusband(), $show_full);
240
                echo '</td></tr></table>';
241
            }
242
            echo '</td>';
243
        }
244
        if ($hfam && ($sosa != -1)) {
245
            echo '<td rowspan="2">';
246
            self::printUrlArrow(($sosa == 0 ? '?famid=' . $hfam->getXref() . '&amp;ged=' . $hfam->getTree()->getNameUrl() : '#' . $hfam->getXref()), $hfam->getXref(), 1);
247
            echo '</td>';
248
        }
249
        if ($hfam) {
250
            // wife’s mother
251
            echo '</tr><tr><td><img src="' . Theme::theme()->parameter('image-hline') . '"></td><td>';
252
            if ($hfam && $hfam->getWife()) {
253
                echo '<table><tr>';
254
                if ($sosa > 0) {
255
                    self::printSosaNumber($sosa * 4 + 3, $hfam->getWife()->getXref(), 'down');
256
                }
257
                if (!empty($gparid) && $hfam->getWife()->getXref() == $gparid) {
258
                    self::printSosaNumber(trim(substr($label, 0, -3), '.') . '.');
259
                }
260
                echo '<td>';
261
                FunctionsPrint::printPedigreePerson($hfam->getWife(), $show_full);
262
                echo '</td></tr></table>';
263
            } elseif ($hfam && !$hfam->getWife()) {
264
                // Empty box for grandmother
265
                echo '<table border="0"><tr>';
266
                echo '<td>';
267
                FunctionsPrint::printPedigreePerson($hfam->getWife(), $show_full);
268
                echo '</td></tr></table>';
269
            }
270
            echo '</td>';
271
        }
272
        echo '</tr></table>';
273
    }
274
275
    /**
276
     * print the children table for a family
277
     *
278
     * @param Family $family family
279
     * @param string $childid child ID
280
     * @param int $sosa child sosa number
281
     * @param string $label indi label (descendancy booklet)
282
     * @param int $show_cousins display cousins on chart
283
     * @param int $show_full large or small box
284
     */
285
    public static function printFamilyChildren(Family $family, $childid = '', $sosa = 0, $label = '', $show_cousins = 0, $show_full = 1)
286
    {
287
        if ($show_full) {
288
            $bheight = Theme::theme()->parameter('chart-box-y');
289
        } else {
290
            $bheight = Theme::theme()->parameter('compact-chart-box-y');
291
        }
292
293
        $pbheight = $bheight + 14;
294
295
        $children = $family->getChildren();
296
        $numchil  = count($children);
297
298
        echo '<table border="0" cellpadding="0" cellspacing="2"><tr>';
299
        if ($sosa > 0) {
300
            echo '<td></td>';
301
        }
302
        echo '<td><span class="subheaders">';
303
        if ($numchil == 0) {
304
            echo I18N::translate('No children');
305
        } else {
306
            echo I18N::plural('%s child', '%s children', $numchil, $numchil);
307
        }
308
        echo '</span>';
309
310
        if ($sosa == 0 && Auth::isEditor($family->getTree())) {
311
            echo '<br>';
312
            echo "<a href=\"#\" onclick=\"return add_child_to_family('", $family->getXref(), "', 'U');\">" . I18N::translate('Add a child to this family') . "</a>";
313
            echo ' <a class="icon-sex_m_15x15" href="#" onclick="return add_child_to_family(\'', $family->getXref(), '\', \'M\');" title="', I18N::translate('son'), '"></a>';
314
            echo ' <a class="icon-sex_f_15x15" href="#" onclick="return add_child_to_family(\'', $family->getXref(), '\', \'F\');" title="', I18N::translate('daughter'), '"></a>';
315
            echo '<br><br>';
316
        }
317
        echo '</td>';
318
        if ($sosa > 0) {
319
            echo '<td></td><td></td>';
320
        }
321
        echo '</tr>';
322
323
        $nchi = 1;
324
        if ($children) {
325
            foreach ($children as $child) {
326
                echo '<tr>';
327
                if ($sosa != 0) {
328
                    if ($child->getXref() == $childid) {
329
                        self::printSosaNumber($sosa, $childid);
330
                    } elseif (empty($label)) {
331
                        self::printSosaNumber("");
332
                    } else {
333
                        self::printSosaNumber($label . ($nchi++) . ".");
334
                    }
335
                }
336
                if ($child->isPendingAddtion()) {
337
                    echo '<td class="new">';
338
                } elseif ($child->isPendingDeletion()) {
339
                    echo '<td class="old">';
340
                } else {
341
                    echo '<td>';
342
                }
343
                FunctionsPrint::printPedigreePerson($child, $show_full);
344
                echo '</td>';
345
                if ($sosa != 0) {
346
                    // loop for all families where current child is a spouse
347
                    $famids = $child->getSpouseFamilies();
348
349
                    $maxfam = count($famids) - 1;
350
                    for ($f = 0; $f <= $maxfam; $f++) {
351
                        $famid_child = $famids[$f]->getXref();
352
                        // multiple marriages
353
                        if ($f > 0) {
354
                            echo '</tr><tr><td></td>';
355
                            echo '<td style="text-align:end; vertical-align: top;">';
356
357
                            //find out how many cousins there are to establish vertical line on second families
358
                            $fchildren = $famids[$f]->getChildren();
359
                            $kids      = count($fchildren);
360
                            $Pheader   = ($bheight - 1) * $kids;
361
                            $PBadj     = 6; // default
362
                            if ($show_cousins > 0) {
363
                                if ($kids) {
364
                                    $PBadj = max(0, $Pheader / 2 + $kids * 4.5);
365
                                }
366
                            }
367
368
                            if ($f == $maxfam) {
369
                                echo '<img height="' . ((($bheight / 2)) + $PBadj) . 'px"';
370
                            } else {
371
                                echo '<img height="' . $pbheight . 'px"';
372
                            }
373
                            echo ' width="3" src="' . Theme::theme()->parameter('image-vline') . '">';
374
                            echo '</td>';
375
                        }
376
                        echo '<td class="details1" style="text-align:center;">';
377
                        $spouse = $famids[$f]->getSpouse($child);
378
379
                        $marr = $famids[$f]->getFirstFact('MARR');
380
                        $div  = $famids[$f]->getFirstFact('DIV');
381
                        if ($marr) {
382
                            // marriage date
383
                            echo $marr->getDate()->minimumDate()->format('%Y');
384
                            // divorce date
385
                            if ($div) {
386
                                echo '–', $div->getDate()->minimumDate()->format('%Y');
387
                            }
388
                        }
389
                        echo "<br><img width=\"100%\" class=\"line5\" height=\"3\" src=\"" . Theme::theme()->parameter('image-hline') . "\" alt=\"\">";
390
                        echo "</td>";
391
                        // spouse information
392
                        echo "<td style=\"vertical-align: center;";
393
                        if (!empty($divrec)) {
394
                            echo " filter:alpha(opacity=40);opacity:0.4;\">";
395
                        } else {
396
                            echo "\">";
397
                        }
398
                        FunctionsPrint::printPedigreePerson($spouse, $show_full);
399
                        echo "</td>";
400
                        // cousins
401
                        if ($show_cousins) {
402
                            self::printCousins($famid_child, $show_full);
403
                        }
404
                    }
405
                }
406
                echo "</tr>";
407
            }
408
        } elseif ($sosa < 1) {
409
            // message 'no children' except for sosa
410
            if (preg_match('/\n1 NCHI (\d+)/', $family->getGedcom(), $match) && $match[1] == 0) {
411
                echo '<tr><td><i class="icon-childless"></i> ' . I18N::translate('This family remained childless') . '</td></tr>';
412
            }
413
        }
414
        echo "</table><br>";
415
    }
416
417
    /**
418
     * print a family with Sosa-Stradonitz numbering system
419
     * ($rootid=1, father=2, mother=3 ...)
420
     *
421
     * @param string $famid family gedcom ID
422
     * @param string $childid tree root ID
423
     * @param int $sosa starting sosa number
424
     * @param string $label indi label (descendancy booklet)
425
     * @param string $parid parent ID (descendancy booklet)
426
     * @param string $gparid gd-parent ID (descendancy booklet)
427
     * @param int $show_cousins display cousins on chart
428
     * @param int $show_full large or small box
429
     */
430
    public static function printSosaFamily($famid, $childid, $sosa, $label = '', $parid = '', $gparid = '', $show_cousins = 0, $show_full = 1)
431
    {
432
        global $WT_TREE;
433
434
        echo '<hr>';
435
        echo '<p style="page-break-before: always;">';
436
        if (!empty($famid)) {
437
            echo '<a name="', $famid, '"></a>';
438
        }
439
        self::printFamilyParents(Family::getInstance($famid, $WT_TREE), $sosa, $label, $parid, $gparid, $show_full);
440
        echo '<br>';
441
        echo '<table><tr><td>';
442
        self::printFamilyChildren(Family::getInstance($famid, $WT_TREE), $childid, $sosa, $label, $show_cousins, $show_full);
443
        echo '</td></tr></table>';
444
        echo '<br>';
445
    }
446
447
    /**
448
     * print an arrow to a new url
449
     *
450
     * @param string $url target url
451
     * @param string $label arrow label
452
     * @param int $dir arrow direction 0=left 1=right 2=up 3=down (default=2)
453
     */
454
    public static function printUrlArrow($url, $label, $dir = 2)
455
    {
456
        if ($url === '') {
457
            return;
458
        }
459
460
        // arrow direction
461
        $adir = $dir;
462
        if (I18N::direction() === 'rtl' && $dir === 0) {
463
            $adir = 1;
464
        }
465
        if (I18N::direction() === 'rtl' && $dir === 1) {
466
            $adir = 0;
467
        }
468
469
        // arrow style     0         1         2         3
470
        $array_style = array('icon-larrow', 'icon-rarrow', 'icon-uarrow', 'icon-darrow');
471
        $astyle      = $array_style[$adir];
472
473
        // Labels include people’s names, which may contain markup
474
        echo '<a href="' . $url . '" title="' . strip_tags($label) . '" class="' . $astyle . '"></a>';
475
    }
476
477
    /**
478
     * builds and returns sosa relationship name in the active language
479
     *
480
     * @param string $sosa sosa number
481
     *
482
     * @return string
483
     */
484
    public static function getSosaName($sosa)
485
    {
486
        $path = '';
487
        while ($sosa > 1) {
488
            if ($sosa % 2 == 1) {
489
                $sosa -= 1;
490
                $path = 'mot' . $path;
491
            } else {
492
                $path = 'fat' . $path;
493
            }
494
            $sosa /= 2;
495
        }
496
497
        return Functions::getRelationshipNameFromPath($path, null, null);
498
    }
499
500
    /**
501
     * print cousins list
502
     *
503
     * @param string $famid family ID
504
     * @param int $show_full large or small box
505
     */
506
    public static function printCousins($famid, $show_full = 1)
507
    {
508
        global $WT_TREE;
509
510
        if ($show_full) {
511
            $bheight = Theme::theme()->parameter('chart-box-y');
512
        } else {
513
            $bheight = Theme::theme()->parameter('compact-chart-box-y');
514
        }
515
516
        $family    = Family::getInstance($famid, $WT_TREE);
517
        $fchildren = $family->getChildren();
518
519
        $kids = count($fchildren);
520
521
        echo '<td>';
522
        if ($kids) {
523
            echo '<table cellspacing="0" cellpadding="0" border="0" ><tr>';
524
            if ($kids > 1) {
525
                echo '<td rowspan="', $kids, '"><img width="3px" height="', (($bheight + 9) * ($kids - 1)), 'px" src="', Theme::theme()->parameter('image-vline'), '"></td>';
526
            }
527
            $ctkids = count($fchildren);
528
            $i      = 1;
529
            foreach ($fchildren as $fchil) {
530
                if ($i == 1) {
531
                    echo '<td><img width="10px" height="3px" style="vertical-align:top"';
532
                } else {
533
                    echo '<td><img width="10px" height="3px"';
534
                }
535
                if (I18N::direction() === 'ltr') {
536
                    echo ' style="padding-right: 2px;"';
537
                } else {
538
                    echo ' style="padding-left: 2px;"';
539
                }
540
                echo ' src="', Theme::theme()->parameter('image-hline'), '"></td><td>';
541
                FunctionsPrint::printPedigreePerson($fchil, $show_full);
542
                echo '</td></tr>';
543
                if ($i < $ctkids) {
544
                    echo '<tr>';
545
                    $i++;
546
                }
547
            }
548
            echo '</table>';
549
        } else {
550
            // If there is known that there are no children (as opposed to no known children)
551
            if (preg_match('/\n1 NCHI (\d+)/', $family->getGedcom(), $match) && $match[1] == 0) {
552
                echo ' <i class="icon-childless" title="', I18N::translate('This family remained childless'), '"></i>';
553
            }
554
        }
555
        echo '</td>';
556
    }
557
}
558