Completed
Push — 1.7 ( fa0ef8...580c36 )
by Greg
08:51
created

relationship.php (2 issues)

Severity

Upgrade to new PHP Analysis Engine

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
$person1 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.

Loading history...
$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.

Loading history...
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