Completed
Push — develop ( 152113...fddfbb )
by Greg
12:05
created

statisticsplot.php ➔ format_range_of_numbers()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 1
eloc 5
c 1
b 1
f 0
nc 1
nop 2
dl 0
loc 7
rs 9.4285
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 27 and the first side effect is on line 23.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
24
25
use Fisharebest\Webtrees\Date\GregorianDate;
26
27
define('WT_SCRIPT_NAME', 'statisticsplot.php');
28
require './includes/session.php';
29
30
/**
31
 * Month of birth
32
 *
33
 * @param int   $z_axis
34
 * @param int[] $z_boundaries
35
 * @param Stats $stats
36
 *
37
 * @return int
38
 */
39 View Code Duplication
function month_of_birth($z_axis, array $z_boundaries, Stats $stats) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
40
	$total = 0;
41
42
	if ($z_axis === 300) {
43
		$num = $stats->statsBirthQuery(false);
44
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
45
			foreach (array('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC') as $key => $month) {
46
				if ($month === $values['d_month']) {
47
					fill_y_data(0, $key, $values['total']);
48
					$total += $values['total'];
49
				}
50
			}
51
		}
52
	} elseif ($z_axis === 301) {
53
		$num = $stats->statsBirthQuery(false, true);
54
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
55
			foreach (array('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC') as $key => $month) {
56
				if ($month === $values['d_month']) {
57
					if ($values['i_sex'] === 'M') {
58
						fill_y_data(0, $key, $values['total']);
59
						$total += $values['total'];
60
					} elseif ($values['i_sex'] === 'F') {
61
						fill_y_data(1, $key, $values['total']);
62
						$total += $values['total'];
63
					}
64
				}
65
			}
66
		}
67
	} else {
68
		$zstart = 0;
69
		foreach ($z_boundaries as $boundary) {
70
			$num = $stats->statsBirthQuery(false, false, $zstart, $boundary);
71
			foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
72
				foreach (array('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC') as $key => $month) {
73
					if ($month === $values['d_month']) {
74
						fill_y_data($boundary, $key, $values['total']);
75
						$total += $values['total'];
76
					}
77
				}
78
			}
79
			$zstart = $boundary + 1;
80
		}
81
	}
82
83
	return $total;
84
}
85
86
/**
87
 * Month of birth of first child in a relation
88
 *
89
 * @param int   $z_axis
90
 * @param int[] $z_boundaries
91
 * @param Stats $stats
92
 *
93
 * @return int
94
 */
95 View Code Duplication
function month_of_birth_of_first_child($z_axis, array $z_boundaries, Stats $stats) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
96
	$total = 0;
97
98
	if ($z_axis === 300) {
99
		$num = $stats->monthFirstChildQuery(false);
100
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
101
			foreach (array('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC') as $key => $month) {
102
				if ($month === $values['d_month']) {
103
					fill_y_data(0, $key, $values['total']);
104
					$total += $values['total'];
105
				}
106
			}
107
		}
108
	} elseif ($z_axis === 301) {
109
		$num = $stats->monthFirstChildQuery(false, true);
110
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
111
			foreach (array('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC') as $key => $month) {
112
				if ($month === $values['d_month']) {
113
					if ($values['i_sex'] === 'M') {
114
						fill_y_data(0, $key, $values['total']);
115
						$total += $values['total'];
116
					} elseif ($values['i_sex'] === 'F') {
117
						fill_y_data(1, $key, $values['total']);
118
						$total += $values['total'];
119
					}
120
				}
121
			}
122
		}
123
	} else {
124
		$zstart = 0;
125
		foreach ($z_boundaries as $boundary) {
126
			$num = $stats->monthFirstChildQuery(false, false, $zstart, $boundary);
127
			foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
128
				foreach (array('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC') as $key => $month) {
129
					if ($month === $values['d_month']) {
130
						fill_y_data($boundary, $key, $values['total']);
131
						$total += $values['total'];
132
					}
133
				}
134
			}
135
			$zstart = $boundary + 1;
136
		}
137
	}
138
139
	return $total;
140
}
141
142
/**
143
 * Month of death
144
 *
145
 * @param int   $z_axis
146
 * @param int[] $z_boundaries
147
 * @param Stats $stats
148
 *
149
 * @return int
150
 */
151 View Code Duplication
function month_of_death($z_axis, array $z_boundaries, Stats $stats) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
152
	$total = 0;
153
154
	if ($z_axis === 300) {
155
		$num = $stats->statsDeathQuery(false);
156
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
157
			foreach (array('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC') as $key => $month) {
158
				if ($month === $values['d_month']) {
159
					fill_y_data(0, $key, $values['total']);
160
					$total += $values['total'];
161
				}
162
			}
163
		}
164
	} elseif ($z_axis === 301) {
165
		$num = $stats->statsDeathQuery(false, true);
166
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
167
			foreach (array('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC') as $key => $month) {
168
				if ($month === $values['d_month']) {
169
					if ($values['i_sex'] === 'M') {
170
						fill_y_data(0, $key, $values['total']);
171
						$total += $values['total'];
172
					} elseif ($values['i_sex'] === 'F') {
173
						fill_y_data(1, $key, $values['total']);
174
						$total += $values['total'];
175
					}
176
				}
177
			}
178
		}
179
	} else {
180
		$zstart = 0;
181
		foreach ($z_boundaries as $boundary) {
182
			$num = $stats->statsDeathQuery(false, false, $zstart, $boundary);
183
			foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
184
				foreach (array('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC') as $key => $month) {
185
					if ($month === $values['d_month']) {
186
						fill_y_data($boundary, $key, $values['total']);
187
						$total += $values['total'];
188
					}
189
				}
190
			}
191
			$zstart = $boundary + 1;
192
		}
193
	}
194
195
	return $total;
196
}
197
198
/**
199
 * Month of marriage
200
 *
201
 * @param int   $z_axis
202
 * @param int[] $z_boundaries
203
 * @param Stats $stats
204
 *
205
 * @return int
206
 */
207
function month_of_marriage($z_axis, array $z_boundaries, Stats $stats) {
208
	$total = 0;
209
210
	if ($z_axis === 300) {
211
		$num = $stats->statsMarrQuery(false, false);
212
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
213
			foreach (array('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC') as $key => $month) {
214
				if ($month === $values['d_month']) {
215
					fill_y_data(0, $key, $values['total']);
216
					$total += $values['total'];
217
				}
218
			}
219
		}
220
	} else {
221
		$zstart = 0;
222
		foreach ($z_boundaries as $boundary) {
223
			$num = $stats->statsMarrQuery(false, false, $zstart, $boundary);
224
			foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
225
				foreach (array('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC') as $key => $month) {
226
					if ($month === $values['d_month']) {
227
						fill_y_data($boundary, $key, $values['total']);
228
						$total += $values['total'];
229
					}
230
				}
231
			}
232
			$zstart = $boundary + 1;
233
		}
234
	}
235
236
	return $total;
237
}
238
239
/**
240
 * Month of first marriage
241
 *
242
 * @param int   $z_axis
243
 * @param int[] $z_boundaries
244
 * @param Stats $stats
245
 *
246
 * @return int
247
 */
248
function month_of_first_marriage($z_axis, array $z_boundaries, Stats $stats) {
249
	$total = 0;
250
251
	if ($z_axis === 300) {
252
		$num  = $stats->statsMarrQuery(false, true);
253
		$indi = array();
254
		$fam  = array();
255 View Code Duplication
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
256
			if (!in_array($values['indi'], $indi) && !in_array($values['fams'], $fam)) {
257
				foreach (array('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC') as $key => $month) {
258
					if ($month === $values['month']) {
259
						fill_y_data(0, $key, 1);
260
						$total++;
261
					}
262
				}
263
				$indi[] = $values['indi'];
264
				$fam[]  = $values['fams'];
265
			}
266
		}
267
	} else {
268
		$zstart = 0;
269
		$indi   = array();
270
		$fam    = array();
271
		foreach ($z_boundaries as $boundary) {
272
			$num = $stats->statsMarrQuery(false, true, $zstart, $boundary);
273 View Code Duplication
			foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
274
				if (!in_array($values['indi'], $indi) && !in_array($values['fams'], $fam)) {
275
					foreach (array('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC') as $key => $month) {
276
						if ($month === $values['month']) {
277
							fill_y_data($boundary, $key, 1);
278
							$total++;
279
						}
280
					}
281
					$indi[] = $values['indi'];
282
					$fam[]  = $values['fams'];
283
				}
284
			}
285
			$zstart = $boundary + 1;
286
		}
287
	}
288
289
	return $total;
290
}
291
292
/**
293
 * Age related to birth year
294
 *
295
 * @param int   $z_axis
296
 * @param int[] $z_boundaries
297
 * @param Stats $stats
298
 *
299
 * @return int
300
 */
301 View Code Duplication
function lifespan_by_birth_year($z_axis, array $z_boundaries, Stats $stats) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
302
	$total = 0;
303
304
	if ($z_axis === 300) {
305
		$num = $stats->statsAgeQuery(false, 'BIRT');
306
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
307
			foreach ($values as $age_value) {
308
				fill_y_data(0, (int) ($age_value / 365.25), 1);
309
				$total++;
310
			}
311
		}
312
	} elseif ($z_axis === 301) {
313
		$num = $stats->statsAgeQuery(false, 'BIRT', 'M');
314
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
315
			foreach ($values as $age_value) {
316
				fill_y_data(0, (int) ($age_value / 365.25), 1);
317
				$total++;
318
			}
319
		}
320
		$num = $stats->statsAgeQuery(false, 'BIRT', 'F');
321
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
322
			foreach ($values as $age_value) {
323
				fill_y_data(1, (int) ($age_value / 365.25), 1);
324
				$total++;
325
			}
326
		}
327
	} else {
328
		$zstart = 0;
329
		foreach ($z_boundaries as $boundary) {
330
			$num = $stats->statsAgeQuery(false, 'BIRT', 'BOTH', $zstart, $boundary);
331
			foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
332
				foreach ($values as $age_value) {
333
					fill_y_data($boundary, (int) ($age_value / 365.25), 1);
334
					$total++;
335
				}
336
			}
337
			$zstart = $boundary + 1;
338
		}
339
	}
340
341
	return $total;
342
}
343
344
/**
345
 * Age related to death year
346
 *
347
 * @param int   $z_axis
348
 * @param int[] $z_boundaries
349
 * @param Stats $stats
350
 *
351
 * @return int
352
 */
353 View Code Duplication
function lifespan_by_death_year($z_axis, array $z_boundaries, Stats $stats) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
354
	$total = 0;
355
356
	if ($z_axis === 300) {
357
		$num = $stats->statsAgeQuery(false, 'DEAT');
358
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
359
			foreach ($values as $age_value) {
360
				fill_y_data(0, (int) ($age_value / 365.25), 1);
361
				$total++;
362
			}
363
		}
364
	} elseif ($z_axis === 301) {
365
		$num = $stats->statsAgeQuery(false, 'DEAT', 'M');
366
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
367
			foreach ($values as $age_value) {
368
				fill_y_data(0, (int) ($age_value / 365.25), 1);
369
				$total++;
370
			}
371
		}
372
		$num = $stats->statsAgeQuery(false, 'DEAT', 'F');
373
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
374
			foreach ($values as $age_value) {
375
				fill_y_data(1, (int) ($age_value / 365.25), 1);
376
				$total++;
377
			}
378
		}
379
	} else {
380
		$zstart = 0;
381
		foreach ($z_boundaries as $boundary) {
382
			$num = $stats->statsAgeQuery(false, 'DEAT', 'BOTH', $zstart, $boundary);
383
			foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
384
				foreach ($values as $age_value) {
385
					fill_y_data($boundary, (int) ($age_value / 365.25), 1);
386
					$total++;
387
				}
388
			}
389
			$zstart = $boundary + 1;
390
		}
391
	}
392
393
	return $total;
394
}
395
396
/**
397
 * Age in year of marriage
398
 *
399
 * @param int   $z_axis
400
 * @param int[] $z_boundaries
401
 * @param Stats $stats
402
 *
403
 * @return int
404
 */
405
function age_at_marriage($z_axis, array $z_boundaries, Stats $stats) {
406
	$total = 0;
407
408
	if ($z_axis === 300) {
409
		$num = $stats->statsMarrAgeQuery(false, 'M');
410
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
411
			fill_y_data(0, (int) ($values['age'] / 365.25), 1);
412
			$total++;
413
		}
414
		$num = $stats->statsMarrAgeQuery(false, 'F');
415
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
416
			fill_y_data(0, (int) ($values['age'] / 365.25), 1);
417
			$total++;
418
		}
419
	} elseif ($z_axis === 301) {
420
		$num = $stats->statsMarrAgeQuery(false, 'M');
421
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
422
			fill_y_data(0, (int) ($values['age'] / 365.25), 1);
423
			$total++;
424
		}
425
		$num = $stats->statsMarrAgeQuery(false, 'F');
426
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
427
			fill_y_data(1, (int) ($values['age'] / 365.25), 1);
428
			$total++;
429
		}
430
	} else {
431
		$zstart = 0;
432
		foreach ($z_boundaries as $boundary) {
433
			$num = $stats->statsMarrAgeQuery(false, 'M', $zstart, $boundary);
434
			foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
435
				fill_y_data($boundary, (int) ($values['age'] / 365.25), 1);
436
				$total++;
437
			}
438
			$num = $stats->statsMarrAgeQuery(false, 'F', $zstart, $boundary);
439
			foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
440
				fill_y_data($boundary, (int) ($values['age'] / 365.25), 1);
441
				$total++;
442
			}
443
			$zstart = $boundary + 1;
444
		}
445
	}
446
447
	return $total;
448
}
449
450
/**
451
 * Age in year of first marriage
452
 *
453
 * @param int   $z_axis
454
 * @param int[] $z_boundaries
455
 * @param Stats $stats
456
 *
457
 * @return int
458
 */
459
function age_at_first_marriage($z_axis, array $z_boundaries, Stats $stats) {
460
	$total = 0;
461
462
	if ($z_axis === 300) {
463
		$num  = $stats->statsMarrAgeQuery(false, 'M');
464
		$indi = array();
465 View Code Duplication
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
466
			if (!in_array($values['d_gid'], $indi)) {
467
				fill_y_data(0, (int) ($values['age'] / 365.25), 1);
468
				$total++;
469
				$indi[] = $values['d_gid'];
470
			}
471
		}
472
		$num  = $stats->statsMarrAgeQuery(false, 'F');
473
		$indi = array();
474 View Code Duplication
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
475
			if (!in_array($values['d_gid'], $indi)) {
476
				fill_y_data(0, (int) ($values['age'] / 365.25), 1);
477
				$total++;
478
				$indi[] = $values['d_gid'];
479
			}
480
		}
481
	} elseif ($z_axis === 301) {
482
		$num  = $stats->statsMarrAgeQuery(false, 'M');
483
		$indi = array();
484 View Code Duplication
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
485
			if (!in_array($values['d_gid'], $indi)) {
486
				fill_y_data(0, (int) ($values['age'] / 365.25), 1);
487
				$total++;
488
				$indi[] = $values['d_gid'];
489
			}
490
		}
491
		$num  = $stats->statsMarrAgeQuery(false, 'F');
492
		$indi = array();
493 View Code Duplication
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
494
			if (!in_array($values['d_gid'], $indi)) {
495
				fill_y_data(1, (int) ($values['age'] / 365.25), 1);
496
				$total++;
497
				$indi[] = $values['d_gid'];
498
			}
499
		}
500
	} else {
501
		$zstart = 0;
502
		$indi   = array();
503
		foreach ($z_boundaries as $boundary) {
504
			$num = $stats->statsMarrAgeQuery(false, 'M', $zstart, $boundary);
505 View Code Duplication
			foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
506
				if (!in_array($values['d_gid'], $indi)) {
507
					fill_y_data($boundary, (int) ($values['age'] / 365.25), 1);
508
					$total++;
509
					$indi[] = $values['d_gid'];
510
				}
511
			}
512
			$num = $stats->statsMarrAgeQuery(false, 'F', $zstart, $boundary);
513 View Code Duplication
			foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
514
				if (!in_array($values['d_gid'], $indi)) {
515
					fill_y_data($boundary, (int) ($values['age'] / 365.25), 1);
516
					$total++;
517
					$indi[] = $values['d_gid'];
518
				}
519
			}
520
			$zstart = $boundary + 1;
521
		}
522
	}
523
524
	return $total;
525
}
526
527
/**
528
 * Number of children
529
 *
530
 * @param int   $z_axis
531
 * @param int[] $z_boundaries
532
 * @param Stats $stats
533
 *
534
 * @return int
535
 */
536
function number_of_children($z_axis, array $z_boundaries, Stats $stats) {
537
	$total = 0;
538
539
	if ($z_axis === 300) {
540
		$num = $stats->statsChildrenQuery(false);
541 View Code Duplication
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
542
			fill_y_data(0, $values['f_numchil'], $values['total']);
543
			$total += $values['f_numchil'] * $values['total'];
544
		}
545
	} elseif ($z_axis === 301) {
546
		$num = $stats->statsChildrenQuery(false, 'M');
547 View Code Duplication
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
548
			fill_y_data(0, $values['num'], $values['total']);
549
			$total += $values['num'] * $values['total'];
550
		}
551
		$num = $stats->statsChildrenQuery(false, 'F');
552 View Code Duplication
		foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
553
			fill_y_data(1, $values['num'], $values['total']);
554
			$total += $values['num'] * $values['total'];
555
		}
556
	} else {
557
		$zstart = 0;
558
		foreach ($z_boundaries as $boundary) {
559
			$num = $stats->statsChildrenQuery(false, 'BOTH', $zstart, $boundary);
560 View Code Duplication
			foreach ($num as $values) {
0 ignored issues
show
Bug introduced by
The expression $num of type string|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
561
				fill_y_data($boundary, $values['f_numchil'], $values['total']);
562
				$total += $values['f_numchil'] * $values['total'];
563
			}
564
			$zstart = $boundary + 1;
565
		}
566
	}
567
568
	return $total;
569
}
570
571
/**
572
 * Calculate the Y axis.
573
 *
574
 * @param int $z
575
 * @param int $x
576
 * @param int $val
577
 */
578
function fill_y_data($z, $x, $val) {
579
	global $ydata, $xmax, $x_boundaries, $zmax, $z_boundaries, $xgiven, $zgiven;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
580
	//-- calculate index $i out of given z value
581
	//-- calculate index $j out of given x value
582
	if ($xgiven) {
583
		$j = $x;
584
	} else {
585
		$j = 0;
586
		while (($x > $x_boundaries[$j]) && ($j < $xmax)) {
587
			$j++;
588
		}
589
	}
590
	if ($zgiven) {
591
		$i = $z;
592
	} else {
593
		$i = 0;
594
		while (($z > $z_boundaries[$i]) && ($i < $zmax)) {
595
			$i++;
596
		}
597
	}
598
	if (isset($ydata[$i][$j])) {
599
		$ydata[$i][$j] += $val;
600
	} else {
601
		$ydata[$i][$j] = $val;
602
	}
603
}
604
605
/**
606
 * Plot the data.
607
 *
608
 * @param string      $mytitle
609
 * @param integer[][] $xdata
610
 * @param string      $xtitle
611
 * @param integer[][] $ydata
612
 * @param string      $ytitle
613
 * @param string[]    $legend
614
 */
615
function my_plot($mytitle, $xdata, $xtitle, $ydata, $ytitle, $legend) {
616
	global $percentage, $male_female, $ymax, $scalefactor, $datastring, $imgurl;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
617
618
	// Google Chart API only allows text encoding for numbers less than 100
619
	// and it does not allow adjusting the y-axis range, so we must find the maximum y-value
620
	// in order to adjust beforehand by changing the numbers
621
622
	if ($male_female) {
623
		$stop = 2;
624
	} else {
625
		$stop = count($ydata);
626
	}
627
	if ($percentage) {
628
		$ypercentmax = 0;
629
		$yt          = array();
630
		for ($i = 0; $i < $stop; $i++) {
631
			if (isset($ydata[$i])) {
632
				$ymax   = max($ydata[$i]);
633
				$yt[$i] = array_sum($ydata[$i]);
634
				if ($yt[$i] > 0) {
635
					$ypercent    = round($ymax / $yt[$i] * 100, 1);
636
					$ypercentmax = max($ypercentmax, $ypercent);
637
				}
638
			}
639
		}
640
		$ymax = $ypercentmax;
641
		if ($ymax > 0) {
642
			$scalefactor = 100.0 / $ymax;
643
		} else {
644
			$scalefactor = 0;
645
		}
646
		$datastring = 'chd=t:';
647
		for ($i = 0; $i < $stop; $i++) {
648
			if (isset($ydata[$i])) {
649
				foreach ($ydata[$i] as $j => $data) {
650
					if ($j > 0) {
651
						$datastring .= ',';
652
					}
653
					if ($yt[$i] > 0) {
654
						$datastring .= round($data / $yt[$i] * 100 * $scalefactor, 1);
655
					} else {
656
						$datastring .= '0';
657
					}
658
				}
659
				if ($i !== $stop - 1) {
660
					$datastring .= '|';
661
				}
662
			}
663
		}
664
	} else {
665
		for ($i = 0; $i < $stop; $i++) {
666
			$ymax = max($ymax, max($ydata[$i]));
667
		}
668
		if ($ymax > 0) {
669
			$scalefactor = 100.0 / $ymax;
670
		} else {
671
			$scalefactor = 0;
672
		}
673
		$datastring = 'chd=t:';
674
		for ($i = 0; $i < $stop; $i++) {
675
			foreach ($ydata[$i] as $j => $data) {
676
				if ($j > 0) {
677
					$datastring .= ',';
678
				}
679
				$datastring .= round($data * $scalefactor, 1);
680
			}
681
			if ($i !== $stop - 1) {
682
				$datastring .= '|';
683
			}
684
		}
685
	}
686
	$colors      = array('0000FF', 'FFA0CB', '9F00FF', 'FF7000', '905030', 'FF0000', '00FF00', 'F0F000');
687
	$colorstring = 'chco=';
688
	for ($i = 0; $i < $stop; $i++) {
689
		if (isset($colors[$i])) {
690
			$colorstring .= $colors[$i];
691
			if ($i !== ($stop - 1)) {
692
				$colorstring .= ',';
693
			}
694
		}
695
	}
696
697
	$titleLength = strpos($mytitle . "\n", "\n");
698
	$title       = substr($mytitle, 0, $titleLength);
699
700
	$imgurl = 'https://chart.googleapis.com/chart?cht=bvg&amp;chs=950x300&amp;chf=bg,s,ffffff00|c,s,ffffff00&amp;chtt=' . rawurlencode($title) . '&amp;' . $datastring . '&amp;' . $colorstring . '&amp;chbh=';
701
	if (count($ydata) > 3) {
702
		$imgurl .= '5,1';
703
	} elseif (count($ydata) < 2) {
704
		$imgurl .= '45,1';
705
	} else {
706
		$imgurl .= '20,3';
707
	}
708
	$imgurl .= '&amp;chxt=x,x,y,y&amp;chxl=0:|';
709
	foreach ($xdata as $data) {
710
		$imgurl .= rawurlencode($data) . '|';
711
	}
712
713
	$imgurl .= '1:||||' . rawurlencode($xtitle) . '|2:|';
714
	$imgurl .= '0|';
715
	if ($percentage) {
716
		for ($i = 1; $i < 11; $i++) {
717
			if ($ymax < 11) {
718
				$imgurl .= round($ymax * $i / 10, 1) . '|';
719
			} else {
720
				$imgurl .= round($ymax * $i / 10, 0) . '|';
721
			}
722
		}
723
		$imgurl .= '3:||%|';
724
	} else {
725
		if ($ymax < 11) {
726 View Code Duplication
			for ($i = 1; $i < $ymax + 1; $i++) {
727
				$imgurl .= round($ymax * $i / ($ymax), 0) . '|';
728
			}
729
		} else {
730 View Code Duplication
			for ($i = 1; $i < 11; $i++) {
731
				$imgurl .= round($ymax * $i / 10, 0) . '|';
732
			}
733
		}
734
		$imgurl .= '3:||' . rawurlencode($ytitle) . '|';
735
	}
736
	// Only show legend if y-data is non-2-dimensional
737
	if (count($ydata) > 1) {
738
		$imgurl .= '&amp;chdl=';
739
		foreach ($legend as $i => $data) {
740
			if ($i > 0) {
741
				$imgurl .= '|';
742
			}
743
			$imgurl .= rawurlencode($data);
744
		}
745
	}
746
	$title = strstr($mytitle, '|', true);
747
	echo '<img src="', $imgurl, '" width="950" height="300" alt="', Filter::escapeHtml($title), '" title="', Filter::escapeHtml($title), '">';
748
}
749
750
/**
751
 * Create the X azxs.
752
 *
753
 * @param string $x_axis_boundaries
754
 */
755
function calculate_axis($x_axis_boundaries) {
756
	global $x_axis, $xdata, $xmax, $x_boundaries;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
757
758
	// Calculate xdata and zdata elements out of chart values
759
	$hulpar = explode(',', $x_axis_boundaries);
760
	$i      = 1;
761
	if ($x_axis === 21 && $hulpar[0] == 1) {
762
		$xdata[0] = 0;
763
	} else {
764
		$xdata[0] = format_range_of_numbers(0, $hulpar[0]);
765
	}
766
	$x_boundaries[0] = $hulpar[0] - 1;
767
	while (isset($hulpar[$i])) {
768
		$i1 = $i - 1;
769
		if (($hulpar[$i] - $hulpar[$i1]) === 1) {
770
			$xdata[$i]        = $hulpar[$i1];
771
			$x_boundaries[$i] = $hulpar[$i1];
772
		} elseif ($hulpar[$i1] === $hulpar[0]) {
773
			$xdata[$i]        = format_range_of_numbers($hulpar[$i1], $hulpar[$i]);
774
			$x_boundaries[$i] = $hulpar[$i];
775
		} else {
776
			$xdata[$i]        = format_range_of_numbers($hulpar[$i1] + 1, $hulpar[$i]);
777
			$x_boundaries[$i] = $hulpar[$i];
778
		}
779
		$i++;
780
	}
781
	$xdata[$i]        = $hulpar[$i - 1];
782
	$x_boundaries[$i] = $hulpar[$i - 1];
783
	if ($hulpar[$i - 1] === $i) {
784
		$xmax = $i + 1;
785
	} else {
786
		$xmax = $i;
787
	}
788
	$xdata[$xmax]        = /* I18N: Label on a graph; 40+ means 40 or more */ I18N::translate('%s+',I18N::number($hulpar[$i - 1]));
789
	$x_boundaries[$xmax] = 10000;
790
	$xmax                = $xmax + 1;
791
	if ($xmax > 20) {
792
		$xmax = 20;
793
	}
794
}
795
796
/**
797
 * A range of integers.
798
 *
799
 * @param int $x
800
 * @param int $y
801
 *
802
 * @return string
803
 */
804
function format_range_of_numbers($x, $y) {
805
	return /* I18N: A range of numbers */ I18N::translate(
806
		'%1$s–%2$s',
807
		I18N::number($x),
808
		I18N::number($y)
809
	);
810
}
811
812
/**
813
 * Calculate the Z axis.
814
 *
815
 * @param string $boundaries_z_axis
816
 */
817
function calculate_legend($boundaries_z_axis) {
818
	global $legend, $zmax, $z_boundaries;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
819
820
	// calculate the legend values
821
	$hulpar          = explode(',', $boundaries_z_axis);
822
	$i               = 1;
823
	$date            = new Date('BEF ' . $hulpar[0]);
824
	$legend[0]       = strip_tags($date->display());
825
	$z_boundaries[0] = $hulpar[0] - 1;
826
	while (isset($hulpar[$i])) {
827
		$i1               = $i - 1;
828
		$date             = new Date('BET ' . $hulpar[$i1] . ' AND ' . ($hulpar[$i] - 1));
829
		$legend[$i]       = strip_tags($date->display());
830
		$z_boundaries[$i] = $hulpar[$i] - 1;
831
		$i++;
832
	}
833
	$zmax                = $i;
834
	$zmax1               = $zmax - 1;
835
	$date                = new Date('AFT ' . $hulpar[$zmax1]);
836
	$legend[$zmax]       = strip_tags($date->display());
837
	$z_boundaries[$zmax] = 10000;
838
	$zmax                = $zmax + 1;
839
	if ($zmax > 8) {
840
		$zmax = 8;
841
	}
842
}
843
844
global $legend, $xdata, $ydata, $xmax, $zmax, $z_boundaries, $xgiven, $zgiven, $percentage, $male_female;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
845
846
$x_axis       = Filter::getInteger('x-as', 1, 21, 11);
847
$y_axis       = Filter::getInteger('y-as', 201, 202, 201);
848
$z_axis       = Filter::getInteger('z-as', 300, 302, 302);
849
$stats        = new Stats($WT_TREE);
850
$z_boundaries = array();
851
852
echo '<div class="statistics_chart" title="', I18N::translate('Statistics chart'), '">';
853
854
switch ($x_axis) {
855
case '1':
856
	echo $stats->chartDistribution(array(Filter::get('chart_shows'), Filter::get('chart_type'), Filter::get('SURN')));
857
	break;
858
case '2':
859
	echo $stats->chartDistribution(array(Filter::get('chart_shows'), 'birth_distribution_chart'));
860
	break;
861
case '3':
862
	echo $stats->chartDistribution(array(Filter::get('chart_shows'), 'death_distribution_chart'));
863
	break;
864
case '4':
865
	echo $stats->chartDistribution(array(Filter::get('chart_shows'), 'marriage_distribution_chart'));
866
	break;
867 View Code Duplication
case '11':
868
	$monthdata = array();
869
	for ($i = 0; $i < 12; ++$i) {
870
		$monthdata[$i] = GregorianDate::monthNameNominativeCase($i + 1, false);
871
	}
872
	$xgiven            = true;
873
	$zgiven            = false;
874
	$title             = I18N::translate('Month of birth');
875
	$xtitle            = I18N::translate('month');
876
	$ytitle            = I18N::translate('numbers');
877
	$boundaries_z_axis = Filter::get('z-axis-boundaries-periods', null, '0');
878
	$xdata             = $monthdata;
879
	$xmax              = 12;
880
	if ($z_axis !== 300 && $z_axis !== 301) {
881
		calculate_legend($boundaries_z_axis);
882
	}
883
	$percentage = false;
884
	if ($y_axis === 201) {
885
		$percentage = false;
886
		$ytitle     = I18N::translate('Individuals');
887
	} elseif ($y_axis === 202) {
888
		$percentage = true;
889
		$ytitle     = I18N::translate('percentage');
890
	}
891
	$male_female = false;
892
	if ($z_axis === 300) {
893
		$zgiven          = false;
894
		$legend[0]       = 'all';
895
		$zmax            = 1;
896
		$z_boundaries[0] = 100000;
897
	} elseif ($z_axis === 301) {
898
		$male_female = true;
899
		$zgiven      = true;
900
		$legend[0]   = I18N::translate('Male');
901
		$legend[1]   = I18N::translate('Female');
902
		$zmax        = 2;
903
		$xtitle      = $xtitle . I18N::translate(' per gender');
904
	} elseif ($z_axis === 302) {
905
		$xtitle = $xtitle . I18N::translate(' per time period');
906
	}
907
	//-- reset the data array
908
	for ($i = 0; $i < $zmax; $i++) {
909
		for ($j = 0; $j < $xmax; $j++) {
910
			$ydata[$i][$j] = 0;
911
		}
912
	}
913
	$total = month_of_birth($z_axis, $z_boundaries, $stats);
914
	$hstr  = $title . '|' . I18N::translate('Counts ') . ' ' . I18N::number($total) . ' ' . I18N::translate('of') . ' ' . $stats->totalIndividuals();
915
	my_plot($hstr, $xdata, $xtitle, $ydata, $ytitle, $legend);
916
	break;
917 View Code Duplication
case '12':
918
	$monthdata = array();
919
	for ($i = 0; $i < 12; ++$i) {
920
		$monthdata[$i] = GregorianDate::monthNameNominativeCase($i + 1, false);
921
	}
922
	$xgiven            = true;
923
	$zgiven            = false;
924
	$title             = I18N::translate('Month of death');
925
	$xtitle            = I18N::translate('month');
926
	$ytitle            = I18N::translate('numbers');
927
	$boundaries_z_axis = Filter::get('z-axis-boundaries-periods', null, '0');
928
	$xdata             = $monthdata;
929
	$xmax              = 12;
930
	if ($z_axis !== 300 && $z_axis !== 301) {
931
		calculate_legend($boundaries_z_axis);
932
	}
933
	$percentage = false;
934
	if ($y_axis === 201) {
935
		$percentage = false;
936
		$ytitle     = I18N::translate('Individuals');
937
	} elseif ($y_axis === 202) {
938
		$percentage = true;
939
		$ytitle     = I18N::translate('percentage');
940
	}
941
	$male_female = false;
942
	if ($z_axis === 300) {
943
		$zgiven          = false;
944
		$legend[0]       = 'all';
945
		$zmax            = 1;
946
		$z_boundaries[0] = 100000;
947
	} elseif ($z_axis === 301) {
948
		$male_female = true;
949
		$zgiven      = true;
950
		$legend[0]   = I18N::translate('Male');
951
		$legend[1]   = I18N::translate('Female');
952
		$zmax        = 2;
953
		$xtitle      = $xtitle . I18N::translate(' per gender');
954
	} elseif ($z_axis === 302) {
955
		$xtitle = $xtitle . I18N::translate(' per time period');
956
	}
957
	//-- reset the data array
958
	for ($i = 0; $i < $zmax; $i++) {
959
		for ($j = 0; $j < $xmax; $j++) {
960
			$ydata[$i][$j] = 0;
961
		}
962
	}
963
	$total = month_of_death($z_axis, $z_boundaries, $stats);
964
	$hstr  = $title . '|' . I18N::translate('Counts ') . ' ' . I18N::number($total) . ' ' . I18N::translate('of') . ' ' . $stats->totalIndividuals();
965
	my_plot($hstr, $xdata, $xtitle, $ydata, $ytitle, $legend);
966
	break;
967 View Code Duplication
case '13':
968
	$monthdata = array();
969
	for ($i = 0; $i < 12; ++$i) {
970
		$monthdata[$i] = GregorianDate::monthNameNominativeCase($i + 1, false);
971
	}
972
973
	if ($z_axis === 301) {
974
		$z_axis = 300;
975
	}
976
	$xgiven            = true;
977
	$zgiven            = false;
978
	$title             = I18N::translate('Month of marriage');
979
	$xtitle            = I18N::translate('month');
980
	$ytitle            = I18N::translate('numbers');
981
	$boundaries_z_axis = Filter::get('z-axis-boundaries-periods', null, '0');
982
	$xdata             = $monthdata;
983
	$xmax              = 12;
984
	if ($z_axis !== 300 && $z_axis !== 301) {
985
		calculate_legend($boundaries_z_axis);
986
	}
987
	$percentage = false;
988
	if ($y_axis === 201) {
989
		$percentage = false;
990
		$ytitle     = I18N::translate('Families');
991
	} elseif ($y_axis === 202) {
992
		$percentage = true;
993
		$ytitle     = I18N::translate('percentage');
994
	}
995
	$male_female = false;
996
	if ($z_axis === 300) {
997
		$zgiven          = false;
998
		$legend[0]       = 'all';
999
		$zmax            = 1;
1000
		$z_boundaries[0] = 100000;
1001
	} elseif ($z_axis === 301) {
1002
		$male_female = true;
1003
		$zgiven      = true;
1004
		$legend[0]   = I18N::translate('Male');
1005
		$legend[1]   = I18N::translate('Female');
1006
		$zmax        = 2;
1007
		$xtitle      = $xtitle . I18N::translate(' per gender');
1008
	} elseif ($z_axis === 302) {
1009
		$xtitle = $xtitle . I18N::translate(' per time period');
1010
	}
1011
	//-- reset the data array
1012
	for ($i = 0; $i < $zmax; $i++) {
1013
		for ($j = 0; $j < $xmax; $j++) {
1014
			$ydata[$i][$j] = 0;
1015
		}
1016
	}
1017
	$total = month_of_marriage($z_axis, $z_boundaries, $stats);
1018
	$hstr  = $title . '|' . I18N::translate('Counts ') . ' ' . I18N::number($total) . ' ' . I18N::translate('of') . ' ' . $stats->totalFamilies();
1019
	my_plot($hstr, $xdata, $xtitle, $ydata, $ytitle, $legend);
1020
	break;
1021 View Code Duplication
case '14':
1022
	$monthdata = array();
1023
	for ($i = 0; $i < 12; ++$i) {
1024
		$monthdata[$i] = GregorianDate::monthNameNominativeCase($i + 1, false);
1025
	}
1026
	$xgiven            = true;
1027
	$zgiven            = false;
1028
	$title             = I18N::translate('Month of birth of first child in a relation');
1029
	$xtitle            = I18N::translate('month');
1030
	$ytitle            = I18N::translate('numbers');
1031
	$boundaries_z_axis = Filter::get('z-axis-boundaries-periods', null, '0');
1032
	$xdata             = $monthdata;
1033
	$xmax              = 12;
1034
	if ($z_axis !== 300 && $z_axis !== 301) {
1035
		calculate_legend($boundaries_z_axis);
1036
	}
1037
	$percentage = false;
1038
	if ($y_axis === 201) {
1039
		$percentage = false;
1040
		$ytitle     = I18N::translate('Children');
1041
	} elseif ($y_axis === 202) {
1042
		$percentage = true;
1043
		$ytitle     = I18N::translate('percentage');
1044
	}
1045
	$male_female = false;
1046
	if ($z_axis === 300) {
1047
		$zgiven          = false;
1048
		$legend[0]       = 'all';
1049
		$zmax            = 1;
1050
		$z_boundaries[0] = 100000;
1051
	} elseif ($z_axis === 301) {
1052
		$male_female = true;
1053
		$zgiven      = true;
1054
		$legend[0]   = I18N::translate('Male');
1055
		$legend[1]   = I18N::translate('Female');
1056
		$zmax        = 2;
1057
		$xtitle      = $xtitle . I18N::translate(' per gender');
1058
	} elseif ($z_axis === 302) {
1059
		$xtitle = $xtitle . I18N::translate(' per time period');
1060
	}
1061
	//-- reset the data array
1062
	for ($i = 0; $i < $zmax; $i++) {
1063
		for ($j = 0; $j < $xmax; $j++) {
1064
			$ydata[$i][$j] = 0;
1065
		}
1066
	}
1067
	$total = month_of_birth_of_first_child($z_axis, $z_boundaries, $stats);
1068
	$hstr  = $title . '|' . I18N::translate('Counts ') . ' ' . I18N::number($total) . ' ' . I18N::translate('of') . ' ' . $stats->totalFamilies();
1069
	my_plot($hstr, $xdata, $xtitle, $ydata, $ytitle, $legend);
1070
	break;
1071 View Code Duplication
case '15':
1072
	$monthdata = array();
1073
	for ($i = 0; $i < 12; ++$i) {
1074
		$monthdata[$i] = GregorianDate::monthNameNominativeCase($i + 1, false);
1075
	}
1076
1077
	if ($z_axis === 301) {
1078
		$z_axis = 300;
1079
	}
1080
	$xgiven            = true;
1081
	$zgiven            = false;
1082
	$title             = I18N::translate('Month of first marriage');
1083
	$xtitle            = I18N::translate('month');
1084
	$ytitle            = I18N::translate('numbers');
1085
	$boundaries_z_axis = Filter::get('z-axis-boundaries-periods', null, '0');
1086
	$xdata             = $monthdata;
1087
	$xmax              = 12;
1088
	if ($z_axis !== 300 && $z_axis !== 301) {
1089
		calculate_legend($boundaries_z_axis);
1090
	}
1091
	$percentage = false;
1092
	if ($y_axis === 201) {
1093
		$percentage = false;
1094
		$ytitle     = I18N::translate('Families');
1095
	} elseif ($y_axis === 202) {
1096
		$percentage = true;
1097
		$ytitle     = I18N::translate('percentage');
1098
	}
1099
	$male_female = false;
1100
	if ($z_axis === 300) {
1101
		$zgiven          = false;
1102
		$legend[0]       = 'all';
1103
		$zmax            = 1;
1104
		$z_boundaries[0] = 100000;
1105
	} elseif ($z_axis === 301) {
1106
		$male_female = true;
1107
		$zgiven      = true;
1108
		$legend[0]   = I18N::translate('Male');
1109
		$legend[1]   = I18N::translate('Female');
1110
		$zmax        = 2;
1111
		$xtitle      = $xtitle . I18N::translate(' per gender');
1112
	} elseif ($z_axis === 302) {
1113
		$xtitle = $xtitle . I18N::translate(' per time period');
1114
	}
1115
	//-- reset the data array
1116
	for ($i = 0; $i < $zmax; $i++) {
1117
		for ($j = 0; $j < $xmax; $j++) {
1118
			$ydata[$i][$j] = 0;
1119
		}
1120
	}
1121
	$total = month_of_first_marriage($z_axis, $z_boundaries, $stats);
1122
	$hstr  = $title . '|' . I18N::translate('Counts ') . ' ' . I18N::number($total) . ' ' . I18N::translate('of') . ' ' . $stats->totalFamilies();
1123
	my_plot($hstr, $xdata, $xtitle, $ydata, $ytitle, $legend);
1124
	break;
1125 View Code Duplication
case '17':
1126
	$monthdata = array();
1127
	for ($i = 0; $i < 12; ++$i) {
1128
		$monthdata[$i] = GregorianDate::monthNameNominativeCase($i + 1, false);
1129
	}
1130
	$xgiven            = false;
1131
	$zgiven            = false;
1132
	$title             = I18N::translate('Age related to birth year');
1133
	$xtitle            = I18N::translate('age');
1134
	$ytitle            = I18N::translate('numbers');
1135
	$boundaries_x_axis = Filter::get('x-axis-boundaries-ages');
1136
	$boundaries_z_axis = Filter::get('z-axis-boundaries-periods', null, '0');
1137
	calculate_axis($boundaries_x_axis);
1138
	if ($z_axis !== 300 && $z_axis !== 301) {
1139
		calculate_legend($boundaries_z_axis);
1140
	}
1141
	$percentage = false;
1142
	if ($y_axis === 201) {
1143
		$percentage = false;
1144
		$ytitle     = I18N::translate('Individuals');
1145
	} elseif ($y_axis === 202) {
1146
		$percentage = true;
1147
		$ytitle     = I18N::translate('percentage');
1148
	}
1149
	$male_female = false;
1150
	if ($z_axis === 300) {
1151
		$zgiven          = false;
1152
		$legend[0]       = 'all';
1153
		$zmax            = 1;
1154
		$z_boundaries[0] = 100000;
1155
	} elseif ($z_axis === 301) {
1156
		$male_female = true;
1157
		$zgiven      = true;
1158
		$legend[0]   = I18N::translate('Male');
1159
		$legend[1]   = I18N::translate('Female');
1160
		$zmax        = 2;
1161
		$xtitle      = $xtitle . I18N::translate(' per gender');
1162
	} elseif ($z_axis === 302) {
1163
		$xtitle = $xtitle . I18N::translate(' per time period');
1164
	}
1165
	//-- reset the data array
1166
	for ($i = 0; $i < $zmax; $i++) {
1167
		for ($j = 0; $j < $xmax; $j++) {
1168
			$ydata[$i][$j] = 0;
1169
		}
1170
	}
1171
	$total = lifespan_by_birth_year($z_axis, $z_boundaries, $stats);
1172
	$hstr  = $title . '|' . I18N::translate('Counts ') . ' ' . I18N::number($total) . ' ' . I18N::translate('of') . ' ' . $stats->totalIndividuals();
1173
	my_plot($hstr, $xdata, $xtitle, $ydata, $ytitle, $legend);
1174
	break;
1175 View Code Duplication
case '18':
1176
	$monthdata = array();
1177
	for ($i = 0; $i < 12; ++$i) {
1178
		$monthdata[$i] = GregorianDate::monthNameNominativeCase($i + 1, false);
1179
	}
1180
	$xgiven            = false;
1181
	$zgiven            = false;
1182
	$title             = I18N::translate('Age related to death year');
1183
	$xtitle            = I18N::translate('age');
1184
	$ytitle            = I18N::translate('numbers');
1185
	$boundaries_x_axis = Filter::get('x-axis-boundaries-ages');
1186
	$boundaries_z_axis = Filter::get('z-axis-boundaries-periods', null, '0');
1187
	calculate_axis($boundaries_x_axis);
1188
	if ($z_axis !== 300 && $z_axis !== 301) {
1189
		calculate_legend($boundaries_z_axis);
1190
	}
1191
	$percentage = false;
1192
	if ($y_axis === 201) {
1193
		$percentage = false;
1194
		$ytitle     = I18N::translate('Individuals');
1195
	} elseif ($y_axis === 202) {
1196
		$percentage = true;
1197
		$ytitle     = I18N::translate('percentage');
1198
	}
1199
	$male_female = false;
1200
	if ($z_axis === 300) {
1201
		$zgiven          = false;
1202
		$legend[0]       = 'all';
1203
		$zmax            = 1;
1204
		$z_boundaries[0] = 100000;
1205
	} elseif ($z_axis === 301) {
1206
		$male_female = true;
1207
		$zgiven      = true;
1208
		$legend[0]   = I18N::translate('Male');
1209
		$legend[1]   = I18N::translate('Female');
1210
		$zmax        = 2;
1211
		$xtitle      = $xtitle . I18N::translate(' per gender');
1212
	} elseif ($z_axis === 302) {
1213
		$xtitle = $xtitle . I18N::translate(' per time period');
1214
	}
1215
	//-- reset the data array
1216
	for ($i = 0; $i < $zmax; $i++) {
1217
		for ($j = 0; $j < $xmax; $j++) {
1218
			$ydata[$i][$j] = 0;
1219
		}
1220
	}
1221
	$total = lifespan_by_death_year($z_axis, $z_boundaries, $stats);
1222
	$hstr  = $title . '|' . I18N::translate('Counts ') . ' ' . I18N::number($total) . ' ' . I18N::translate('of') . ' ' . $stats->totalIndividuals();
1223
	my_plot($hstr, $xdata, $xtitle, $ydata, $ytitle, $legend);
1224
	break;
1225 View Code Duplication
case '19':
1226
	$monthdata = array();
1227
	for ($i = 0; $i < 12; ++$i) {
1228
		$monthdata[$i] = GregorianDate::monthNameNominativeCase($i + 1, false);
1229
	}
1230
	$xgiven            = false;
1231
	$zgiven            = false;
1232
	$title             = I18N::translate('Age in year of marriage');
1233
	$xtitle            = I18N::translate('age');
1234
	$ytitle            = I18N::translate('numbers');
1235
	$boundaries_x_axis = Filter::get('x-axis-boundaries-ages_m');
1236
	$boundaries_z_axis = Filter::get('z-axis-boundaries-periods', null, '0');
1237
	calculate_axis($boundaries_x_axis);
1238
	if ($z_axis !== 300 && $z_axis !== 301) {
1239
		calculate_legend($boundaries_z_axis);
1240
	}
1241
	$percentage = false;
1242
	if ($y_axis === 201) {
1243
		$percentage = false;
1244
		$ytitle     = I18N::translate('Individuals');
1245
	} elseif ($y_axis === 202) {
1246
		$percentage = true;
1247
		$ytitle     = I18N::translate('percentage');
1248
	}
1249
	$male_female     = false;
1250
	$z_boundaries[0] = 100000;
1251
	if ($z_axis === 300) {
1252
		$zgiven          = false;
1253
		$legend[0]       = 'all';
1254
		$zmax            = 1;
1255
	} elseif ($z_axis === 301) {
1256
		$male_female = true;
1257
		$zgiven      = true;
1258
		$legend[0]   = I18N::translate('Male');
1259
		$legend[1]   = I18N::translate('Female');
1260
		$zmax        = 2;
1261
		$xtitle      = $xtitle . I18N::translate(' per gender');
1262
	} elseif ($z_axis === 302) {
1263
		$xtitle = $xtitle . I18N::translate(' per time period');
1264
	}
1265
	//-- reset the data array
1266
	for ($i = 0; $i < $zmax; $i++) {
1267
		for ($j = 0; $j < $xmax; $j++) {
1268
			$ydata[$i][$j] = 0;
1269
		}
1270
	}
1271
	$total = age_at_marriage($z_axis, $z_boundaries, $stats);
1272
	$hstr  = $title . '|' . I18N::translate('Counts ') . ' ' . I18N::number($total) . ' ' . I18N::translate('of') . ' ' . $stats->totalIndividuals();
1273
	my_plot($hstr, $xdata, $xtitle, $ydata, $ytitle, $legend);
1274
	break;
1275 View Code Duplication
case '20':
1276
	$monthdata = array();
1277
	for ($i = 0; $i < 12; ++$i) {
1278
		$monthdata[$i] = GregorianDate::monthNameNominativeCase($i + 1, false);
1279
	}
1280
	$xgiven            = false;
1281
	$zgiven            = false;
1282
	$title             = I18N::translate('Age in year of first marriage');
1283
	$xtitle            = I18N::translate('age');
1284
	$ytitle            = I18N::translate('numbers');
1285
	$boundaries_x_axis = Filter::get('x-axis-boundaries-ages_m');
1286
	$boundaries_z_axis = Filter::get('z-axis-boundaries-periods', null, '0');
1287
	calculate_axis($boundaries_x_axis);
1288
	if ($z_axis !== 300 && $z_axis !== 301) {
1289
		calculate_legend($boundaries_z_axis);
1290
	}
1291
	$percentage = false;
1292
	if ($y_axis === 201) {
1293
		$percentage = false;
1294
		$ytitle     = I18N::translate('Individuals');
1295
	} elseif ($y_axis === 202) {
1296
		$percentage = true;
1297
		$ytitle     = I18N::translate('percentage');
1298
	}
1299
	$male_female = false;
1300
	if ($z_axis === 300) {
1301
		$zgiven          = false;
1302
		$legend[0]       = 'all';
1303
		$zmax            = 1;
1304
		$z_boundaries[0] = 100000;
1305
	} elseif ($z_axis === 301) {
1306
		$male_female = true;
1307
		$zgiven      = true;
1308
		$legend[0]   = I18N::translate('Male');
1309
		$legend[1]   = I18N::translate('Female');
1310
		$zmax        = 2;
1311
		$xtitle      = $xtitle . I18N::translate(' per gender');
1312
	} elseif ($z_axis === 302) {
1313
		$xtitle = $xtitle . I18N::translate(' per time period');
1314
	}
1315
	//-- reset the data array
1316
	for ($i = 0; $i < $zmax; $i++) {
1317
		for ($j = 0; $j < $xmax; $j++) {
1318
			$ydata[$i][$j] = 0;
1319
		}
1320
	}
1321
	$total = age_at_first_marriage($z_axis, $z_boundaries, $stats);
1322
	$hstr  = $title . '|' . I18N::translate('Counts ') . ' ' . I18N::number($total) . ' ' . I18N::translate('of') . ' ' . $stats->totalIndividuals();
1323
	my_plot($hstr, $xdata, $xtitle, $ydata, $ytitle, $legend);
1324
	break;
1325 View Code Duplication
case '21':
1326
	$monthdata = array();
1327
	for ($i = 0; $i < 12; ++$i) {
1328
		$monthdata[$i] = GregorianDate::monthNameNominativeCase($i + 1, false);
1329
	}
1330
	$xgiven            = false;
1331
	$zgiven            = false;
1332
	$title             = I18N::translate('Number of children');
1333
	$xtitle            = I18N::translate('children');
1334
	$ytitle            = I18N::translate('numbers');
1335
	$boundaries_x_axis = Filter::get('x-axis-boundaries-numbers');
1336
	$boundaries_z_axis = Filter::get('z-axis-boundaries-periods', null, '0');
1337
	calculate_axis($boundaries_x_axis);
1338
	if ($z_axis !== 300 && $z_axis !== 301) {
1339
		calculate_legend($boundaries_z_axis);
1340
	}
1341
	$percentage = false;
1342
	if ($y_axis === 201) {
1343
		$percentage = false;
1344
		$ytitle     = I18N::translate('Families');
1345
	} elseif ($y_axis === 202) {
1346
		$percentage = true;
1347
		$ytitle     = I18N::translate('percentage');
1348
	}
1349
	$male_female = false;
1350
	if ($z_axis === 300) {
1351
		$zgiven          = false;
1352
		$legend[0]       = 'all';
1353
		$zmax            = 1;
1354
		$z_boundaries[0] = 100000;
1355
	} elseif ($z_axis === 301) {
1356
		$male_female = true;
1357
		$zgiven      = true;
1358
		$legend[0]   = I18N::translate('Male');
1359
		$legend[1]   = I18N::translate('Female');
1360
		$zmax        = 2;
1361
		$xtitle      = $xtitle . I18N::translate(' per gender');
1362
	} elseif ($z_axis === 302) {
1363
		$xtitle = $xtitle . I18N::translate(' per time period');
1364
	}
1365
	//-- reset the data array
1366
	for ($i = 0; $i < $zmax; $i++) {
1367
		for ($j = 0; $j < $xmax; $j++) {
1368
			$ydata[$i][$j] = 0;
1369
		}
1370
	}
1371
	$total = number_of_children($z_axis, $z_boundaries, $stats);
1372
	$hstr  = $title . '|' . I18N::translate('Counts ') . ' ' . I18N::number($total) . ' ' . I18N::translate('of') . ' ' . $stats->totalChildren();
1373
	my_plot($hstr, $xdata, $xtitle, $ydata, $ytitle, $legend);
1374
	break;
1375
default:
1376
	echo '<i class="icon-loading-large"></i>';
1377
	break;
1378
}
1379
echo '</div>';
1380