These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * webtrees: online genealogy |
||
4 | * Copyright (C) 2016 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\RelationshipController; |
||
26 | use Fisharebest\Webtrees\Functions\Functions; |
||
27 | use Fisharebest\Webtrees\Functions\FunctionsEdit; |
||
28 | use Fisharebest\Webtrees\Functions\FunctionsPrint; |
||
29 | use Fisharebest\Webtrees\Module\RelationshipsChartModule; |
||
30 | |||
31 | define('WT_SCRIPT_NAME', 'relationship.php'); |
||
32 | require './includes/session.php'; |
||
33 | |||
34 | $max_recursion = $WT_TREE->getPreference('RELATIONSHIP_RECURSION', RelationshipsChartModule::DEFAULT_RECURSION); |
||
35 | $ancestors_only = $WT_TREE->getPreference('RELATIONSHIP_ANCESTORS', RelationshipsChartModule::DEFAULT_ANCESTORS); |
||
36 | |||
37 | $controller = new RelationshipController; |
||
38 | $pid1 = Filter::get('pid1', WT_REGEX_XREF); |
||
39 | $pid2 = Filter::get('pid2', WT_REGEX_XREF); |
||
40 | $show_full = Filter::getInteger('show_full', 0, 1, $WT_TREE->getPreference('PEDIGREE_FULL_DETAILS')); |
||
41 | $recursion = Filter::getInteger('recursion', 0, $max_recursion, 0); |
||
42 | $ancestors = Filter::getInteger('ancestors', 0, 1, 0); |
||
43 | |||
44 | $person1 = Individual::getInstance($pid1, $WT_TREE); |
||
45 | $person2 = Individual::getInstance($pid2, $WT_TREE); |
||
46 | |||
47 | $controller |
||
48 | ->restrictAccess(Module::isActiveChart($WT_TREE, 'relationships_chart')) |
||
49 | ->addExternalJavascript(WT_AUTOCOMPLETE_JS_URL) |
||
50 | ->addInlineJavascript('autocomplete();'); |
||
51 | |||
52 | if ($person1 && $person2) { |
||
53 | $controller |
||
54 | ->setPageTitle(I18N::translate(/* I18N: %s are individual’s names */ 'Relationships between %1$s and %2$s', $person1->getFullName(), $person2->getFullName())) |
||
55 | ->pageHeader(); |
||
56 | $paths = $controller->calculateRelationships($person1, $person2, $recursion, (bool) $ancestors); |
||
0 ignored issues
–
show
$person2 of type object<Fisharebest\Webtrees\GedcomRecord> is not a sub-type of object<Fisharebest\Webtrees\Individual> . It seems like you assume a child class of the class Fisharebest\Webtrees\GedcomRecord to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type. ![]() |
|||
57 | } else { |
||
58 | $controller |
||
59 | ->setPageTitle(I18N::translate('Relationships')) |
||
60 | ->pageHeader(); |
||
61 | $paths = array(); |
||
62 | } |
||
63 | |||
64 | ?> |
||
65 | <h2><?php echo $controller->getPageTitle() ?></h2> |
||
66 | <form name="people" method="get" action="?"> |
||
67 | <input type="hidden" name="ged" value="<?php echo $WT_TREE->getNameHtml() ?>"> |
||
68 | <table class="list_table"> |
||
69 | <tbody> |
||
70 | <tr> |
||
71 | <td class="descriptionbox"> |
||
72 | <label for="pid1"> |
||
73 | <?php echo I18N::translate('Individual 1') ?> |
||
74 | </label> |
||
75 | </td> |
||
76 | <td class="optionbox"> |
||
77 | <input class="pedigree_form" data-autocomplete-type="INDI" type="text" name="pid1" id="pid1" size="3" value="<?php echo $pid1 ?>"> |
||
78 | <?php echo FunctionsPrint::printFindIndividualLink('pid1') ?> |
||
79 | </td> |
||
80 | <td class="optionbox"> |
||
81 | <label> |
||
82 | <?php echo FunctionsEdit::twoStateCheckbox('show_full', $show_full) ?> |
||
83 | <?php echo I18N::translate('Show details') ?> |
||
84 | </label> |
||
85 | </td> |
||
86 | <td class="optionbox vmiddle" rowspan="2"> |
||
87 | <input type="submit" value="<?php echo /* I18N: A button label. */ I18N::translate('view') ?>"> |
||
88 | </td> |
||
89 | </tr> |
||
90 | <tr> |
||
91 | <td class="descriptionbox"> |
||
92 | <label for="pid2"> |
||
93 | <?php echo I18N::translate('Individual 2') ?> |
||
94 | </label> |
||
95 | </td> |
||
96 | <td class="optionbox"> |
||
97 | <input class="pedigree_form" data-autocomplete-type="INDI" type="text" name="pid2" id="pid2" size="3" value="<?php echo $pid2 ?>"> |
||
98 | <?php echo FunctionsPrint::printFindIndividualLink('pid2') ?> |
||
99 | <br> |
||
100 | <a href="#" onclick="var x = jQuery('#pid1').val(); jQuery('#pid1').val(jQuery('#pid2').val()); jQuery('#pid2').val(x); return false;"><?php echo /* I18N: Reverse the order of two individuals */ I18N::translate('Swap individuals') ?></a> |
||
101 | </td> |
||
102 | <td class="optionbox"> |
||
103 | <?php if ($ancestors_only === '1'): ?> |
||
104 | <input type="hidden" name="ancestors" value="1"> |
||
105 | <?php echo I18N::translate('Find relationships via ancestors') ?> |
||
106 | <?php else: ?> |
||
107 | <label> |
||
108 | <input type="radio" name="ancestors" value="0" <?php echo $ancestors == 0 ? 'checked' : '' ?>> |
||
109 | <?php echo I18N::translate('Find any relationship') ?> |
||
110 | </label> |
||
111 | <br> |
||
112 | <label> |
||
113 | <input type="radio" name="ancestors" value="1" <?php echo $ancestors == 1 ? 'checked' : '' ?>> |
||
114 | <?php echo I18N::translate('Find relationships via ancestors') ?> |
||
115 | </label> |
||
116 | <?php endif; ?> |
||
117 | |||
118 | <hr> |
||
119 | |||
120 | <?php if ($max_recursion == 0): ?> |
||
121 | <?php echo I18N::translate('Find the closest relationships') ?> |
||
122 | <input type="hidden" name="recursion" value="0"> |
||
123 | <?php else: ?> |
||
124 | <label> |
||
125 | <input type="radio" name="recursion" value="0" <?php echo $recursion == 0 ? 'checked' : '' ?>> |
||
126 | <?php echo I18N::translate('Find the closest relationships') ?> |
||
127 | </label> |
||
128 | <br> |
||
129 | <label> |
||
130 | <input type="radio" name="recursion" value="<?php echo $max_recursion ?>" <?php echo $recursion > 0 ? 'checked' : '' ?>> |
||
131 | <?php if ($max_recursion == RelationshipsChartModule::UNLIMITED_RECURSION): ?> |
||
132 | <?php echo I18N::translate('Find all possible relationships') ?> |
||
133 | <?php else: ?> |
||
134 | <?php echo I18N::translate('Find other relationships') ?> |
||
135 | <?php endif; ?> |
||
136 | </label> |
||
137 | <?php endif; ?> |
||
138 | </td> |
||
139 | </tr> |
||
140 | </tbody> |
||
141 | </table> |
||
142 | </form> |
||
143 | <?php |
||
144 | |||
145 | if ($person1 && $person2) { |
||
146 | if (I18N::direction() === 'ltr') { |
||
147 | $horizontal_arrow = '<br><i class="icon-rarrow"></i>'; |
||
148 | $diagonal1 = Theme::theme()->parameter('image-dline'); |
||
149 | $diagonal2 = Theme::theme()->parameter('image-dline2'); |
||
150 | } else { |
||
151 | $horizontal_arrow = '<br><i class="icon-larrow"></i>'; |
||
152 | $diagonal1 = Theme::theme()->parameter('image-dline2'); |
||
153 | $diagonal2 = Theme::theme()->parameter('image-dline'); |
||
154 | } |
||
155 | $up_arrow = ' <i class="icon-uarrow"></i>'; |
||
156 | $down_arrow = ' <i class="icon-darrow"></i>'; |
||
157 | |||
158 | $num_paths = 0; |
||
159 | foreach ($paths as $path) { |
||
160 | // Extract the relationship names between pairs of individuals |
||
161 | $relationships = $controller->oldStyleRelationshipPath($path); |
||
162 | if (empty($relationships)) { |
||
163 | // Cannot see one of the families/individuals, due to privacy; |
||
164 | continue; |
||
165 | } |
||
166 | echo '<h3>', I18N::translate('Relationship: %s', Functions::getRelationshipNameFromPath(implode('', $relationships), $person1, $person2)), '</h3>'; |
||
167 | $num_paths++; |
||
168 | |||
169 | // Use a table/grid for layout. |
||
170 | $table = array(); |
||
171 | // Current position in the grid. |
||
172 | $x = 0; |
||
173 | $y = 0; |
||
174 | // Extent of the grid. |
||
175 | $min_y = 0; |
||
176 | $max_y = 0; |
||
177 | $max_x = 0; |
||
178 | // For each node in the path. |
||
179 | foreach ($path as $n => $xref) { |
||
180 | if ($n % 2 === 1) { |
||
181 | switch ($relationships[$n]) { |
||
182 | case 'hus': |
||
183 | case 'wif': |
||
184 | case 'spo': |
||
185 | case 'bro': |
||
186 | case 'sis': |
||
187 | case 'sib': |
||
188 | $table[$x + 1][$y] = '<div style="background:url(' . Theme::theme()->parameter('image-hline') . ') repeat-x center; width: 94px; text-align: center"><div class="hline-text" style="height: 32px;">' . Functions::getRelationshipNameFromPath($relationships[$n], Individual::getInstance($path[$n - 1], $WT_TREE), Individual::getInstance($path[$n + 1], $WT_TREE)) . '</div><div style="height: 32px;">' . $horizontal_arrow . '</div></div>'; |
||
189 | $x += 2; |
||
190 | break; |
||
191 | case 'son': |
||
192 | case 'dau': |
||
193 | case 'chi': |
||
194 | View Code Duplication | if ($n > 2 && preg_match('/fat|mot|par/', $relationships[$n - 2])) { |
|
195 | $table[$x + 1][$y - 1] = '<div style="background:url(' . $diagonal2 . '); width: 64px; height: 64px; text-align: center;"><div style="height: 32px; text-align: end;">' . Functions::getRelationshipNameFromPath($relationships[$n], Individual::getInstance($path[$n - 1], $WT_TREE), Individual::getInstance($path[$n + 1], $WT_TREE)) . '</div><div style="height: 32px; text-align: start;">' . $down_arrow . '</div></div>'; |
||
196 | $x += 2; |
||
197 | } else { |
||
198 | $table[$x][$y - 1] = '<div style="background:url(' . Theme::theme() |
||
199 | ->parameter('image-vline') . ') repeat-y center; height: 64px; text-align: center;"><div class="vline-text" style="display: inline-block; width:50%; line-height: 64px;">' . Functions::getRelationshipNameFromPath($relationships[$n], Individual::getInstance($path[$n - 1], $WT_TREE), Individual::getInstance($path[$n + 1], $WT_TREE)) . '</div><div style="display: inline-block; width:50%; line-height: 64px;">' . $down_arrow . '</div></div>'; |
||
200 | } |
||
201 | $y -= 2; |
||
202 | break; |
||
203 | case 'fat': |
||
204 | case 'mot': |
||
205 | case 'par': |
||
206 | View Code Duplication | if ($n > 2 && preg_match('/son|dau|chi/', $relationships[$n - 2])) { |
|
207 | $table[$x + 1][$y + 1] = '<div style="background:url(' . $diagonal1 . '); background-position: top right; width: 64px; height: 64px; text-align: center;"><div style="height: 32px; text-align: start;">' . Functions::getRelationshipNameFromPath($relationships[$n], Individual::getInstance($path[$n - 1], $WT_TREE), Individual::getInstance($path[$n + 1], $WT_TREE)) . '</div><div style="height: 32px; text-align: end;">' . $up_arrow . '</div></div>'; |
||
208 | $x += 2; |
||
209 | } else { |
||
210 | $table[$x][$y + 1] = '<div style="background:url(' . Theme::theme() |
||
211 | ->parameter('image-vline') . ') repeat-y center; height: 64px; text-align:center; "><div class="vline-text" style="display: inline-block; width: 50%; line-height: 32px;">' . Functions::getRelationshipNameFromPath($relationships[$n], Individual::getInstance($path[$n - 1], $WT_TREE), Individual::getInstance($path[$n + 1], $WT_TREE)) . '</div><div style="display: inline-block; width: 50%; line-height: 32px">' . $up_arrow . '</div></div>'; |
||
212 | } |
||
213 | $y += 2; |
||
214 | break; |
||
215 | } |
||
216 | $max_x = max($max_x, $x); |
||
217 | $min_y = min($min_y, $y); |
||
218 | $max_y = max($max_y, $y); |
||
219 | } else { |
||
220 | $individual = Individual::getInstance($xref, $WT_TREE); |
||
221 | ob_start(); |
||
222 | FunctionsPrint::printPedigreePerson($individual, $show_full); |
||
223 | $table[$x][$y] = ob_get_clean(); |
||
224 | } |
||
225 | } |
||
226 | echo '<table id="relationship-page" style="border-collapse: collapse; margin: 20px 50px;">'; |
||
227 | for ($y = $max_y; $y >= $min_y; --$y) { |
||
228 | echo '<tr>'; |
||
229 | for ($x = 0; $x <= $max_x; ++$x) { |
||
230 | echo '<td style="padding: 0;">'; |
||
231 | if (isset($table[$x][$y])) { |
||
232 | echo $table[$x][$y]; |
||
233 | } |
||
234 | echo '</td>'; |
||
235 | } |
||
236 | echo '</tr>'; |
||
237 | } |
||
238 | echo '</table>'; |
||
239 | } |
||
240 | |||
241 | if (!$num_paths) { |
||
242 | echo '<p>', I18N::translate('No link between the two individuals could be found.'), '</p>'; |
||
243 | } |
||
244 | } |
||
245 |
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.
Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.