Completed
Push — master ( bdc52b...f93e28 )
by Jonathan
36:53
created
src/Webtrees/Module/Sosa/Views/SosaStatsView.php 1 patch
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -30,11 +30,11 @@  discard block
 block discarded – undo
30 30
 			<?php 
31 31
 			/** @var \Fisharebest\Webtrees\Individual $root_indi */
32 32
 			$root_indi = $this->data->get('root_indi');
33
-			if($root_indi !== null && $root_indi->canShowName()) { ?>
33
+			if ($root_indi !== null && $root_indi->canShowName()) { ?>
34 34
 			<h4 class="center"><?= I18N::translate('%s: %s', I18N::translate('Root individual'), $root_indi->getFullName()); ?><h4>
35 35
 			<?php } ?>
36 36
 			
37
-			<?php  if($this->data->get('is_setup')) {  
37
+			<?php  if ($this->data->get('is_setup')) {  
38 38
 			    $general_stats = $this->data->get('general_stats'); ?>
39 39
 			<h3><?php echo I18N::translate('General statistics'); ?></h3>
40 40
 			<div class="maj-table">
@@ -56,7 +56,7 @@  discard block
 block discarded – undo
56 56
 				</div>
57 57
 				<div class="maj-row">
58 58
 					<div class="label"><?php echo I18N::translate('Mean generation time'); ?></div>
59
-					<div class="value"><?php echo I18N::plural('%s year', '%s years', $general_stats['mean_gen_time'],  I18N::number($general_stats['mean_gen_time'], 1)); ?></div>
59
+					<div class="value"><?php echo I18N::plural('%s year', '%s years', $general_stats['mean_gen_time'], I18N::number($general_stats['mean_gen_time'], 1)); ?></div>
60 60
 				</div>
61 61
 			</div>
62 62
 			
@@ -96,7 +96,7 @@  discard block
 block discarded – undo
96 96
 					</tr>
97 97
 				</thead>
98 98
 				<tbody>
99
-					<?php foreach($this->data->get('generation_stats') as $gen => $row) { ?>
99
+					<?php foreach ($this->data->get('generation_stats') as $gen => $row) { ?>
100 100
 					<tr class="maj-row">
101 101
 						<td class="label"><?php echo I18N::translate('<strong>G%d</strong>', $gen); ?></td>
102 102
 						<td class="label"><?php echo I18N::translate('%1$s <> %2$s', $row['gen_min_birth'], $row['gen_max_birth']); ?></td>
@@ -110,7 +110,7 @@  discard block
 block discarded – undo
110 110
 						<td class="value"><?php echo I18N::number($row['different']); ?></td>
111 111
 						<td class="value left percent_container">
112 112
 							<div class="percent_frame">
113
-								<div class="percent_cell" style="width:<?php echo 100*$row['perc_different'] ?>%;">
113
+								<div class="percent_cell" style="width:<?php echo 100 * $row['perc_different'] ?>%;">
114 114
 									&nbsp;<?php echo I18N::percentage($row['perc_different']); ?>&nbsp;
115 115
 								</div>
116 116
 							</div>
@@ -123,7 +123,7 @@  discard block
 block discarded – undo
123 123
 				<tfoot>
124 124
 					<tr class="maj-row">
125 125
 						<td class="label" colspan="13">
126
-							<?php echo I18N::translate('Generation-equivalent: %s generations', I18N::number($this->data->get('equivalent_gen'),2)); ?>
126
+							<?php echo I18N::translate('Generation-equivalent: %s generations', I18N::number($this->data->get('equivalent_gen'), 2)); ?>
127 127
 						</td>
128 128
 					</tr>
129 129
 				</tfoot>
@@ -132,8 +132,8 @@  discard block
 block discarded – undo
132 132
 			
133 133
 			<h3><?php echo I18N::translate('Known Sosa ancestors\' family dispersion'); ?></h3>
134 134
 			<div class="center">
135
-				<?php echo $this->data->get('chart_img_g2') ?: '' ; ?>
136
-				<?php echo $this->data->get('chart_img_g3') ?: '' ; ?>				
135
+				<?php echo $this->data->get('chart_img_g2') ?: ''; ?>
136
+				<?php echo $this->data->get('chart_img_g3') ?: ''; ?>				
137 137
 				<!--  <canvas id="chart_ancestors_g2" width="300" height="300"></canvas>  -->
138 138
 			</div>
139 139
 			
Please login to merge, or discard this patch.
src/Webtrees/Module/Sosa/SosaStatsController.php 1 patch
Indentation   +180 added lines, -180 removed lines patch added patch discarded remove patch
@@ -25,218 +25,218 @@
 block discarded – undo
25 25
  */
26 26
 class SosaStatsController extends MvcController
27 27
 {
28
-    /**
29
-     * Sosa Provider for the controller
30
-     * @var SosaProvider $sosa_provider
31
-     */
32
-    protected $sosa_provider;
28
+	/**
29
+	 * Sosa Provider for the controller
30
+	 * @var SosaProvider $sosa_provider
31
+	 */
32
+	protected $sosa_provider;
33 33
     
34
-    /**
35
-     * Constructor for SosaStatsController
36
-     * @param AbstractModule $module
37
-     */
38
-    public function __construct(AbstractModule $module) {
39
-        global $WT_TREE;
34
+	/**
35
+	 * Constructor for SosaStatsController
36
+	 * @param AbstractModule $module
37
+	 */
38
+	public function __construct(AbstractModule $module) {
39
+		global $WT_TREE;
40 40
         
41
-        parent::__construct($module);
41
+		parent::__construct($module);
42 42
         
43
-        $this->sosa_provider = new SosaProvider($WT_TREE, Auth::user());
44
-    }
43
+		$this->sosa_provider = new SosaProvider($WT_TREE, Auth::user());
44
+	}
45 45
     
46
-    /**
47
-     * Pages
48
-     */
46
+	/**
47
+	 * Pages
48
+	 */
49 49
     
50
-    /**
51
-     * SosaStats@index
52
-     */
53
-    public function index() {
54
-        global $WT_TREE;
50
+	/**
51
+	 * SosaStats@index
52
+	 */
53
+	public function index() {
54
+		global $WT_TREE;
55 55
         
56
-        $controller = new PageController();
57
-        $controller
58
-            ->setPageTitle(I18N::translate('Sosa Statistics'))
59
-            ->addInlineJavascript('$(".help_tooltip").tooltip();')
60
-        ;
56
+		$controller = new PageController();
57
+		$controller
58
+			->setPageTitle(I18N::translate('Sosa Statistics'))
59
+			->addInlineJavascript('$(".help_tooltip").tooltip();')
60
+		;
61 61
 
62
-        $view_bag = new ViewBag();
63
-        $view_bag->set('title', $controller->getPageTitle());
64
-        $view_bag->set('is_setup', false);
62
+		$view_bag = new ViewBag();
63
+		$view_bag->set('title', $controller->getPageTitle());
64
+		$view_bag->set('is_setup', false);
65 65
         
66
-        if($this->sosa_provider->isSetup()) {
67
-            $view_bag->set('is_setup', true);
66
+		if($this->sosa_provider->isSetup()) {
67
+			$view_bag->set('is_setup', true);
68 68
             
69
-            $view_bag->set('root_indi', $this->sosa_provider->getRootIndi());
69
+			$view_bag->set('root_indi', $this->sosa_provider->getRootIndi());
70 70
             
71
-            $sosaCount = $this->sosa_provider->getSosaCount();
72
-            $diffSosaCount = $this->sosa_provider->getDifferentSosaCount();
71
+			$sosaCount = $this->sosa_provider->getSosaCount();
72
+			$diffSosaCount = $this->sosa_provider->getDifferentSosaCount();
73 73
             
74
-            $general_stats = array(
75
-                'sosa_count' => $sosaCount,
76
-                'distinct_count' => $diffSosaCount,
77
-                'sosa_rate' => Functions::safeDivision($diffSosaCount, $this->sosa_provider->getTotalIndividuals()),
78
-                'pedi_collapse' => 1 - Functions::safeDivision($diffSosaCount, $sosaCount),
79
-                'mean_gen_time' => $this->sosa_provider->getMeanGenerationTime()
80
-            );
81
-            $view_bag->set('general_stats', $general_stats);
74
+			$general_stats = array(
75
+				'sosa_count' => $sosaCount,
76
+				'distinct_count' => $diffSosaCount,
77
+				'sosa_rate' => Functions::safeDivision($diffSosaCount, $this->sosa_provider->getTotalIndividuals()),
78
+				'pedi_collapse' => 1 - Functions::safeDivision($diffSosaCount, $sosaCount),
79
+				'mean_gen_time' => $this->sosa_provider->getMeanGenerationTime()
80
+			);
81
+			$view_bag->set('general_stats', $general_stats);
82 82
             
83
-            $stats_gen = $this->sosa_provider->getStatisticsByGeneration();
84
-            $view_bag->set('missinganc_url', 'module.php?mod='.$this->module->getName().'&mod_action=SosaList@missing&ged='.$WT_TREE->getNameUrl().'&gen=');
85
-            $view_bag->set('sosaanc_url', 'module.php?mod='.$this->module->getName().'&mod_action=SosaList&ged='.$WT_TREE->getNameUrl().'&gen=');
83
+			$stats_gen = $this->sosa_provider->getStatisticsByGeneration();
84
+			$view_bag->set('missinganc_url', 'module.php?mod='.$this->module->getName().'&mod_action=SosaList@missing&ged='.$WT_TREE->getNameUrl().'&gen=');
85
+			$view_bag->set('sosaanc_url', 'module.php?mod='.$this->module->getName().'&mod_action=SosaList&ged='.$WT_TREE->getNameUrl().'&gen=');
86 86
             
87
-            $gen_theoretical=1;
88
-            $total_theoretical=0;
89
-            $prev_diff=0;
90
-            $prev_known=0.5;
91
-            $gen_equiv=0;            
92
-            $generation_stats = array();
87
+			$gen_theoretical=1;
88
+			$total_theoretical=0;
89
+			$prev_diff=0;
90
+			$prev_known=0.5;
91
+			$gen_equiv=0;            
92
+			$generation_stats = array();
93 93
             
94
-            foreach($stats_gen as $gen => $tab){
95
-                $genY1= I18N::translate('-');
96
-                $genY2= I18N::translate('-');
97
-                if($tab['firstBirth']>0) $genY1=$tab['firstBirth'];
98
-                if($tab['lastBirth']>0) $genY2=$tab['lastBirth'];
99
-                $total_theoretical += $gen_theoretical;
100
-                $perc_sosa_count_theor = Functions::safeDivision($tab['sosaCount'], $gen_theoretical);
101
-                $gen_equiv += $perc_sosa_count_theor;
102
-                $missing=2*$prev_known - $tab['sosaCount'];
103
-                $gen_diff=$tab['diffSosaTotalCount']-$prev_diff;
94
+			foreach($stats_gen as $gen => $tab){
95
+				$genY1= I18N::translate('-');
96
+				$genY2= I18N::translate('-');
97
+				if($tab['firstBirth']>0) $genY1=$tab['firstBirth'];
98
+				if($tab['lastBirth']>0) $genY2=$tab['lastBirth'];
99
+				$total_theoretical += $gen_theoretical;
100
+				$perc_sosa_count_theor = Functions::safeDivision($tab['sosaCount'], $gen_theoretical);
101
+				$gen_equiv += $perc_sosa_count_theor;
102
+				$missing=2*$prev_known - $tab['sosaCount'];
103
+				$gen_diff=$tab['diffSosaTotalCount']-$prev_diff;
104 104
                 
105
-                $generation_stats[$gen] = array(
106
-                    'gen_min_birth' => $genY1,
107
-                    'gen_max_birth' => $genY2,
108
-                    'theoretical' => $gen_theoretical,
109
-                    'known' => $tab['sosaCount'],
110
-                    'perc_known' => $perc_sosa_count_theor,
111
-                    'missing' => $missing,
112
-                    'perc_missing' => 1-Functions::safeDivision($tab['sosaCount'], 2*$prev_known),
113
-                    'total_known' => $tab['sosaTotalCount'],
114
-                    'perc_total_known' => Functions::safeDivision($tab['sosaTotalCount'], $total_theoretical),
115
-                    'different' => $gen_diff,
116
-                    'perc_different' => Functions::safeDivision($gen_diff, $tab['sosaCount']),
117
-                    'total_different' => $tab['diffSosaTotalCount'],
118
-                    'pedi_collapse' => 1 - Functions::safeDivision($tab['diffSosaTotalCount'], $tab['sosaTotalCount'])
119
-                );
105
+				$generation_stats[$gen] = array(
106
+					'gen_min_birth' => $genY1,
107
+					'gen_max_birth' => $genY2,
108
+					'theoretical' => $gen_theoretical,
109
+					'known' => $tab['sosaCount'],
110
+					'perc_known' => $perc_sosa_count_theor,
111
+					'missing' => $missing,
112
+					'perc_missing' => 1-Functions::safeDivision($tab['sosaCount'], 2*$prev_known),
113
+					'total_known' => $tab['sosaTotalCount'],
114
+					'perc_total_known' => Functions::safeDivision($tab['sosaTotalCount'], $total_theoretical),
115
+					'different' => $gen_diff,
116
+					'perc_different' => Functions::safeDivision($gen_diff, $tab['sosaCount']),
117
+					'total_different' => $tab['diffSosaTotalCount'],
118
+					'pedi_collapse' => 1 - Functions::safeDivision($tab['diffSosaTotalCount'], $tab['sosaTotalCount'])
119
+				);
120 120
                 
121
-                $gen_theoretical = $gen_theoretical * 2;
122
-                $prev_known=$tab['sosaCount'];
123
-                $prev_diff=$tab['diffSosaTotalCount'];
124
-            }
121
+				$gen_theoretical = $gen_theoretical * 2;
122
+				$prev_known=$tab['sosaCount'];
123
+				$prev_diff=$tab['diffSosaTotalCount'];
124
+			}
125 125
             
126
-            $view_bag->set('generation_stats', $generation_stats);
127
-            $view_bag->set('equivalent_gen', $gen_equiv);
126
+			$view_bag->set('generation_stats', $generation_stats);
127
+			$view_bag->set('equivalent_gen', $gen_equiv);
128 128
                         
129
-            $view_bag->set('chart_img_g2', $this->htmlAncestorDispersionG2());
130
-            $view_bag->set('chart_img_g3', $this->htmlAncestorDispersionG3());
129
+			$view_bag->set('chart_img_g2', $this->htmlAncestorDispersionG2());
130
+			$view_bag->set('chart_img_g3', $this->htmlAncestorDispersionG3());
131 131
             
132
-        }
132
+		}
133 133
         
134
-        ViewFactory::make('SosaStats', $this, $controller, $view_bag)->render();   
135
-    }
134
+		ViewFactory::make('SosaStats', $this, $controller, $view_bag)->render();   
135
+	}
136 136
     
137
-    /**
138
-     * Returns HTML code for a graph showing the dispersion of ancestors across father & mother
139
-     * @return string HTML code
140
-     */
141
-     private function htmlAncestorDispersionG2()
142
-    {
143
-        $ancestorsDispGen2 = $this->sosa_provider->getAncestorDispersionForGen(2);
144
-        if(count($ancestorsDispGen2) == 0) return;
137
+	/**
138
+	 * Returns HTML code for a graph showing the dispersion of ancestors across father & mother
139
+	 * @return string HTML code
140
+	 */
141
+	 private function htmlAncestorDispersionG2()
142
+	{
143
+		$ancestorsDispGen2 = $this->sosa_provider->getAncestorDispersionForGen(2);
144
+		if(count($ancestorsDispGen2) == 0) return;
145 145
         
146
-        $size = '600x300';
146
+		$size = '600x300';
147 147
         
148
-        $total = array_sum($ancestorsDispGen2);
149
-        $father_count = array_key_exists(1, $ancestorsDispGen2) ? $ancestorsDispGen2[1] : 0;
150
-        $father = array (
151
-            'color' => '84beff', 
152
-            'count' => $father_count, 
153
-            'perc' => Functions::safeDivision($father_count, $total), 
154
-            'name' => \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fat')            
155
-        );
156
-        $mother_count = array_key_exists(2, $ancestorsDispGen2) ? $ancestorsDispGen2[2] : 0;
157
-        $mother = array (
158
-            'color' => 'ffd1dc', 
159
-            'count' => $mother_count, 
160
-            'perc' => Functions::safeDivision($mother_count, $total),
161
-            'name' => \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('mot')
162
-        );
163
-        $shared_count = array_key_exists(-1, $ancestorsDispGen2) ? $ancestorsDispGen2[-1] : 0;
164
-        $shared = array (
165
-            'color' => '777777', 
166
-            'count' => $shared_count, 
167
-            'perc' => Functions::safeDivision($shared_count, $total),
168
-            'name' => I18N::translate('Shared')
169
-        );
148
+		$total = array_sum($ancestorsDispGen2);
149
+		$father_count = array_key_exists(1, $ancestorsDispGen2) ? $ancestorsDispGen2[1] : 0;
150
+		$father = array (
151
+			'color' => '84beff', 
152
+			'count' => $father_count, 
153
+			'perc' => Functions::safeDivision($father_count, $total), 
154
+			'name' => \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fat')            
155
+		);
156
+		$mother_count = array_key_exists(2, $ancestorsDispGen2) ? $ancestorsDispGen2[2] : 0;
157
+		$mother = array (
158
+			'color' => 'ffd1dc', 
159
+			'count' => $mother_count, 
160
+			'perc' => Functions::safeDivision($mother_count, $total),
161
+			'name' => \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('mot')
162
+		);
163
+		$shared_count = array_key_exists(-1, $ancestorsDispGen2) ? $ancestorsDispGen2[-1] : 0;
164
+		$shared = array (
165
+			'color' => '777777', 
166
+			'count' => $shared_count, 
167
+			'perc' => Functions::safeDivision($shared_count, $total),
168
+			'name' => I18N::translate('Shared')
169
+		);
170 170
         
171
-        $chd = $this->arrayToExtendedEncoding(array(4095 * $father['perc'], 4095 * $shared['perc'], 4095 * $mother['perc']));
172
-        $chart_title = I18N::translate('Known Sosa ancestors\' dispersion');
173
-        $chl = 
174
-             $father['name'] . ' - ' . I18N::percentage($father['perc'], 1) . '|' .
175
-             $shared['name'] . ' - ' . I18N::percentage($shared['perc'], 1) . '|' .
176
-             $mother['name'] . ' - ' . I18N::percentage($mother['perc'], 1);
177
-        return "<img src=\"https://chart.googleapis.com/chart?cht=p&chp=1.5708&amp;chd=e:{$chd}&amp;chs={$size}&amp;chco={$father['color']},{$shared['color']},{$mother['color']}&amp;chf=bg,s,ffffff00&amp;chl={$chl}\" alt=\"" . $chart_title . "\" title=\"" . $chart_title . "\" />";
178
-    }
171
+		$chd = $this->arrayToExtendedEncoding(array(4095 * $father['perc'], 4095 * $shared['perc'], 4095 * $mother['perc']));
172
+		$chart_title = I18N::translate('Known Sosa ancestors\' dispersion');
173
+		$chl = 
174
+			 $father['name'] . ' - ' . I18N::percentage($father['perc'], 1) . '|' .
175
+			 $shared['name'] . ' - ' . I18N::percentage($shared['perc'], 1) . '|' .
176
+			 $mother['name'] . ' - ' . I18N::percentage($mother['perc'], 1);
177
+		return "<img src=\"https://chart.googleapis.com/chart?cht=p&chp=1.5708&amp;chd=e:{$chd}&amp;chs={$size}&amp;chco={$father['color']},{$shared['color']},{$mother['color']}&amp;chf=bg,s,ffffff00&amp;chl={$chl}\" alt=\"" . $chart_title . "\" title=\"" . $chart_title . "\" />";
178
+	}
179 179
     
180
-    /**
181
-     * Returns HTML code for a graph showing the dispersion of ancestors across grand-parents
182
-     * @return string HTML code
183
-     */
184
-    private function htmlAncestorDispersionG3()
185
-    {
186
-        $ancestorsDispGen2 = $this->sosa_provider->getAncestorDispersionForGen(3);
180
+	/**
181
+	 * Returns HTML code for a graph showing the dispersion of ancestors across grand-parents
182
+	 * @return string HTML code
183
+	 */
184
+	private function htmlAncestorDispersionG3()
185
+	{
186
+		$ancestorsDispGen2 = $this->sosa_provider->getAncestorDispersionForGen(3);
187 187
         
188
-        $size = '700x300';
188
+		$size = '700x300';
189 189
         
190
-        $color_motmot = 'ffd1dc';
191
-        $color_motfat = 'b998a0';
192
-        $color_fatfat = '577292';
193
-        $color_fatmot = '84beff';
194
-        $color_shared = '777777';
190
+		$color_motmot = 'ffd1dc';
191
+		$color_motfat = 'b998a0';
192
+		$color_fatfat = '577292';
193
+		$color_fatmot = '84beff';
194
+		$color_shared = '777777';
195 195
     
196
-        $total_fatfat = array_key_exists(1, $ancestorsDispGen2) ? $ancestorsDispGen2[1] : 0;
197
-        $total_fatmot = array_key_exists(2, $ancestorsDispGen2) ? $ancestorsDispGen2[2] : 0;
198
-        $total_motfat = array_key_exists(4, $ancestorsDispGen2) ? $ancestorsDispGen2[4] : 0;
199
-        $total_motmot = array_key_exists(8, $ancestorsDispGen2) ? $ancestorsDispGen2[8] : 0;
200
-        $total_sha = array_key_exists(-1, $ancestorsDispGen2) ? $ancestorsDispGen2[-1] : 0;
201
-        $total = $total_fatfat + $total_fatmot + $total_motfat+ $total_motmot + $total_sha;
196
+		$total_fatfat = array_key_exists(1, $ancestorsDispGen2) ? $ancestorsDispGen2[1] : 0;
197
+		$total_fatmot = array_key_exists(2, $ancestorsDispGen2) ? $ancestorsDispGen2[2] : 0;
198
+		$total_motfat = array_key_exists(4, $ancestorsDispGen2) ? $ancestorsDispGen2[4] : 0;
199
+		$total_motmot = array_key_exists(8, $ancestorsDispGen2) ? $ancestorsDispGen2[8] : 0;
200
+		$total_sha = array_key_exists(-1, $ancestorsDispGen2) ? $ancestorsDispGen2[-1] : 0;
201
+		$total = $total_fatfat + $total_fatmot + $total_motfat+ $total_motmot + $total_sha;
202 202
     
203
-        $chd = $this->arrayToExtendedEncoding(array(
204
-            4095 * $total_fatfat / $total, 
205
-            4095 * $total_fatmot / $total,
206
-            4095 * $total_sha / $total, 
207
-            4095 * $total_motfat / $total,
208
-            4095 * $total_motmot / $total            
209
-        ));
210
-        $chart_title = I18N::translate('Known Sosa ancestors\' dispersion - G3');
211
-        $chl =
212
-            \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fatfat') . ' - ' . I18N::percentage(Functions::safeDivision($total_fatfat, $total), 1) . '|' .
213
-            \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fatmot') . ' - ' . I18N::percentage(Functions::safeDivision($total_fatmot, $total), 1) . '|' .
214
-            I18N::translate('Shared') . ' - ' . I18N::percentage(Functions::safeDivision($total_sha, $total), 1) . '|' .
215
-            \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('motfat') . ' - ' . I18N::percentage(Functions::safeDivision($total_motfat, $total), 1) . '|' .
216
-            \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('motmot') . ' - ' . I18N::percentage(Functions::safeDivision($total_motmot, $total), 1);
217
-         return "<img src=\"https://chart.googleapis.com/chart?cht=p&chp=1.5708&amp;chd=e:{$chd}&amp;chs={$size}&amp;chco={$color_fatfat},{$color_fatmot},{$color_shared},{$color_motfat},{$color_motmot}&amp;chf=bg,s,ffffff00&amp;chl={$chl}\" alt=\"" . $chart_title . "\" title=\"" . $chart_title . "\" />";
218
-    }
203
+		$chd = $this->arrayToExtendedEncoding(array(
204
+			4095 * $total_fatfat / $total, 
205
+			4095 * $total_fatmot / $total,
206
+			4095 * $total_sha / $total, 
207
+			4095 * $total_motfat / $total,
208
+			4095 * $total_motmot / $total            
209
+		));
210
+		$chart_title = I18N::translate('Known Sosa ancestors\' dispersion - G3');
211
+		$chl =
212
+			\Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fatfat') . ' - ' . I18N::percentage(Functions::safeDivision($total_fatfat, $total), 1) . '|' .
213
+			\Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fatmot') . ' - ' . I18N::percentage(Functions::safeDivision($total_fatmot, $total), 1) . '|' .
214
+			I18N::translate('Shared') . ' - ' . I18N::percentage(Functions::safeDivision($total_sha, $total), 1) . '|' .
215
+			\Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('motfat') . ' - ' . I18N::percentage(Functions::safeDivision($total_motfat, $total), 1) . '|' .
216
+			\Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('motmot') . ' - ' . I18N::percentage(Functions::safeDivision($total_motmot, $total), 1);
217
+		 return "<img src=\"https://chart.googleapis.com/chart?cht=p&chp=1.5708&amp;chd=e:{$chd}&amp;chs={$size}&amp;chco={$color_fatfat},{$color_fatmot},{$color_shared},{$color_motfat},{$color_motmot}&amp;chf=bg,s,ffffff00&amp;chl={$chl}\" alt=\"" . $chart_title . "\" title=\"" . $chart_title . "\" />";
218
+	}
219 219
 
220
-    /**
221
-     * Convert an array to Google Chart encoding
222
-     * @param arrat $a Array to encode
223
-     * @return string
224
-     */
225
-    private function arrayToExtendedEncoding($a) {
226
-        $xencoding = WT_GOOGLE_CHART_ENCODING;
220
+	/**
221
+	 * Convert an array to Google Chart encoding
222
+	 * @param arrat $a Array to encode
223
+	 * @return string
224
+	 */
225
+	private function arrayToExtendedEncoding($a) {
226
+		$xencoding = WT_GOOGLE_CHART_ENCODING;
227 227
     
228
-        $encoding = '';
229
-        foreach ($a as $value) {
230
-            if ($value < 0) {
231
-                $value = 0;
232
-            }
233
-            $first  = (int) ($value / 64);
234
-            $second = $value % 64;
235
-            $encoding .= $xencoding[(int) $first] . $xencoding[(int) $second];
236
-        }
228
+		$encoding = '';
229
+		foreach ($a as $value) {
230
+			if ($value < 0) {
231
+				$value = 0;
232
+			}
233
+			$first  = (int) ($value / 64);
234
+			$second = $value % 64;
235
+			$encoding .= $xencoding[(int) $first] . $xencoding[(int) $second];
236
+		}
237 237
     
238
-        return $encoding;
239
-    }
238
+		return $encoding;
239
+	}
240 240
     
241 241
     
242 242
 }
243 243
\ No newline at end of file
Please login to merge, or discard this patch.
src/Webtrees/Module/Sosa/Model/SosaProvider.php 2 patches
Indentation   +561 added lines, -561 removed lines patch added patch discarded remove patch
@@ -22,390 +22,390 @@  discard block
 block discarded – undo
22 22
  */
23 23
 class SosaProvider {
24 24
     
25
-    /**
26
-     * Maximum number of generation the database is able to hold.
27
-     * @var int MAX_DB_GENERATIONS
28
-     */
29
-    const MAX_DB_GENERATIONS = 64;
30
-    
31
-    /**
32
-     * System's default user (ID -1 in the database
33
-     * @var User $default_user
34
-     */
35
-    protected static $default_user;
36
-    
37
-    /**
38
-     * Reference user
39
-     * @var User $user
40
-     */
41
-    protected $user;
42
-    
43
-    /**
44
-     * Reference tree
45
-     * @var Tree $tree
46
-     */
47
-    protected $tree;
48
-    
49
-    /**
50
-     * Cached list of Sosa Individuals by generation
51
-     * Format: key = generation, value = array ( sosa => Individual ID)
52
-     * @var array $sosa_list_by_gen
53
-     */
54
-    protected $sosa_list_by_gen;
55
-    
56
-    /**
57
-     * Cached list of Sosa Families by generation
58
-     * Format: key = generation, value = array ( sosa => Family ID)
59
-     * @var unknown $sosa_fam_list_by_gen
60
-     */
61
-    protected $sosa_fam_list_by_gen;
62
-    
63
-    /**
64
-     * Cached array of statistics by generation
65
-     * Format:  key = generation, 
66
-     *          value = array(
67
-     *              sosaCount, sosaTotalCount, diffSosaTotalCount, firstBirth, lastBirth, avgBirth
68
-     *           )
69
-     * @var array $statistics_tab
70
-     */
71
-    protected $statistics_tab;
72
-    
73
-    /**
74
-     * Has the provider's initialisation completed
75
-     * @var bool $is_setup
76
-     */
77
-    protected $is_setup;
78
-    
79
-    /**
80
-     * Constructor for Sosa Provider.
81
-     * A provider is defined in relation to a specific tree and reference user.
82
-     * 
83
-     * @param Tree $tree
84
-     * @param User $user
85
-     */
86
-    public function __construct(Tree $tree, User $user = null) {
87
-        if(self::$default_user === null) 
88
-            self::$default_user = User::find(-1);
25
+	/**
26
+	 * Maximum number of generation the database is able to hold.
27
+	 * @var int MAX_DB_GENERATIONS
28
+	 */
29
+	const MAX_DB_GENERATIONS = 64;
30
+    
31
+	/**
32
+	 * System's default user (ID -1 in the database
33
+	 * @var User $default_user
34
+	 */
35
+	protected static $default_user;
36
+    
37
+	/**
38
+	 * Reference user
39
+	 * @var User $user
40
+	 */
41
+	protected $user;
42
+    
43
+	/**
44
+	 * Reference tree
45
+	 * @var Tree $tree
46
+	 */
47
+	protected $tree;
48
+    
49
+	/**
50
+	 * Cached list of Sosa Individuals by generation
51
+	 * Format: key = generation, value = array ( sosa => Individual ID)
52
+	 * @var array $sosa_list_by_gen
53
+	 */
54
+	protected $sosa_list_by_gen;
55
+    
56
+	/**
57
+	 * Cached list of Sosa Families by generation
58
+	 * Format: key = generation, value = array ( sosa => Family ID)
59
+	 * @var unknown $sosa_fam_list_by_gen
60
+	 */
61
+	protected $sosa_fam_list_by_gen;
62
+    
63
+	/**
64
+	 * Cached array of statistics by generation
65
+	 * Format:  key = generation, 
66
+	 *          value = array(
67
+	 *              sosaCount, sosaTotalCount, diffSosaTotalCount, firstBirth, lastBirth, avgBirth
68
+	 *           )
69
+	 * @var array $statistics_tab
70
+	 */
71
+	protected $statistics_tab;
72
+    
73
+	/**
74
+	 * Has the provider's initialisation completed
75
+	 * @var bool $is_setup
76
+	 */
77
+	protected $is_setup;
78
+    
79
+	/**
80
+	 * Constructor for Sosa Provider.
81
+	 * A provider is defined in relation to a specific tree and reference user.
82
+	 * 
83
+	 * @param Tree $tree
84
+	 * @param User $user
85
+	 */
86
+	public function __construct(Tree $tree, User $user = null) {
87
+		if(self::$default_user === null) 
88
+			self::$default_user = User::find(-1);
89 89
         
90
-        $this->tree = $tree;
91
-        $this->user = $user;
92
-        $this->is_setup = true;
93
-        if($this->user === null) $this->user = Auth::user();
94
-        if(strlen($this->user->getUserId()) == 0) $this->user = self::$default_user;
90
+		$this->tree = $tree;
91
+		$this->user = $user;
92
+		$this->is_setup = true;
93
+		if($this->user === null) $this->user = Auth::user();
94
+		if(strlen($this->user->getUserId()) == 0) $this->user = self::$default_user;
95 95
         
96
-        // Check if the user, or the default user, has a root already setup;
97
-        if(empty($this->getRootIndiId())) {
98
-            if($this->user == self::$default_user) {  // If the default user is not setup
99
-                $this->is_setup = false;
100
-            }
101
-            else {
102
-                $this->user = self::$default_user;
103
-                $this->is_setup = $this->getRootIndiId() === null;
104
-            }            
105
-        }
106
-    }
107
-    
108
-    /**
109
-     * Returns is the Provider has been successfully set up
110
-     * @return bool
111
-     */
112
-    public function isSetup() {
113
-        return $this->is_setup;
114
-    }
115
-    
116
-    /**
117
-     * Return the root individual ID for the reference tree and user.
118
-     * @return string Individual ID
119
-     */
120
-    public function getRootIndiId() {
121
-        return $this->tree->getUserPreference($this->user, 'MAJ_SOSA_ROOT_ID');
122
-    }
123
-    
124
-    /**
125
-     * Return the root individual for the reference tree and user.
126
-     * @return Individual Individual
127
-     */
128
-    public function getRootIndi() {
129
-        $root_indi_id = $this->getRootIndiId();
130
-        if(!empty($root_indi_id)) {
131
-            return Individual::getInstance($root_indi_id, $this->tree);
132
-        }
133
-        return null;
134
-    }
96
+		// Check if the user, or the default user, has a root already setup;
97
+		if(empty($this->getRootIndiId())) {
98
+			if($this->user == self::$default_user) {  // If the default user is not setup
99
+				$this->is_setup = false;
100
+			}
101
+			else {
102
+				$this->user = self::$default_user;
103
+				$this->is_setup = $this->getRootIndiId() === null;
104
+			}            
105
+		}
106
+	}
107
+    
108
+	/**
109
+	 * Returns is the Provider has been successfully set up
110
+	 * @return bool
111
+	 */
112
+	public function isSetup() {
113
+		return $this->is_setup;
114
+	}
115
+    
116
+	/**
117
+	 * Return the root individual ID for the reference tree and user.
118
+	 * @return string Individual ID
119
+	 */
120
+	public function getRootIndiId() {
121
+		return $this->tree->getUserPreference($this->user, 'MAJ_SOSA_ROOT_ID');
122
+	}
123
+    
124
+	/**
125
+	 * Return the root individual for the reference tree and user.
126
+	 * @return Individual Individual
127
+	 */
128
+	public function getRootIndi() {
129
+		$root_indi_id = $this->getRootIndiId();
130
+		if(!empty($root_indi_id)) {
131
+			return Individual::getInstance($root_indi_id, $this->tree);
132
+		}
133
+		return null;
134
+	}
135 135
        
136
-    /*****************
136
+	/*****************
137 137
      * DATA CRUD LAYER
138 138
      *****************/
139 139
     
140
-    /**
141
-     * Remove all Sosa entries related to the gedcom file and user
142
-     */
143
-    public function deleteAll() {
144
-        if(!$this->is_setup) return;
145
-        Database::prepare(
146
-            'DELETE FROM `##maj_sosa`'.
147
-            ' WHERE majs_gedcom_id= :tree_id and majs_user_id = :user_id ')
148
-            ->execute(array(
149
-                'tree_id' => $this->tree->getTreeId(), 
150
-                'user_id' => $this->user->getUserId()                
151
-            ));
152
-    }
153
-    
154
-    /**
155
-     * Remove all ancestors of a sosa number
156
-     * 
157
-     * @param int $sosa
158
-     */
159
-    public function deleteAncestors($sosa) {
160
-        if(!$this->is_setup) return;
161
-        $gen = Functions::getGeneration($sosa);
162
-        Database::prepare(
163
-            'DELETE FROM `##maj_sosa`'.
164
-            ' WHERE majs_gedcom_id=:tree_id and majs_user_id = :user_id' .
165
-            ' AND majs_gen >= :gen' .
166
-            ' AND FLOOR(majs_sosa / (POW(2, (majs_gen - :gen)))) = :sosa'
167
-        )->execute(array(
168
-            'tree_id' => $this->tree->getTreeId(), 
169
-            'user_id' => $this->user->getUserId(),
170
-            'gen' => $gen,
171
-            'sosa' => $sosa
172
-        ));
173
-    }    
174
-    
175
-    /**
176
-     * Insert (or update if already existing) a list of Sosa individuals
177
-     * @param array $sosa_records
178
-     */
179
-    public function insertOrUpdate($sosa_records) {
180
-        if(!$this->is_setup) return;
140
+	/**
141
+	 * Remove all Sosa entries related to the gedcom file and user
142
+	 */
143
+	public function deleteAll() {
144
+		if(!$this->is_setup) return;
145
+		Database::prepare(
146
+			'DELETE FROM `##maj_sosa`'.
147
+			' WHERE majs_gedcom_id= :tree_id and majs_user_id = :user_id ')
148
+			->execute(array(
149
+				'tree_id' => $this->tree->getTreeId(), 
150
+				'user_id' => $this->user->getUserId()                
151
+			));
152
+	}
153
+    
154
+	/**
155
+	 * Remove all ancestors of a sosa number
156
+	 * 
157
+	 * @param int $sosa
158
+	 */
159
+	public function deleteAncestors($sosa) {
160
+		if(!$this->is_setup) return;
161
+		$gen = Functions::getGeneration($sosa);
162
+		Database::prepare(
163
+			'DELETE FROM `##maj_sosa`'.
164
+			' WHERE majs_gedcom_id=:tree_id and majs_user_id = :user_id' .
165
+			' AND majs_gen >= :gen' .
166
+			' AND FLOOR(majs_sosa / (POW(2, (majs_gen - :gen)))) = :sosa'
167
+		)->execute(array(
168
+			'tree_id' => $this->tree->getTreeId(), 
169
+			'user_id' => $this->user->getUserId(),
170
+			'gen' => $gen,
171
+			'sosa' => $sosa
172
+		));
173
+	}    
174
+    
175
+	/**
176
+	 * Insert (or update if already existing) a list of Sosa individuals
177
+	 * @param array $sosa_records
178
+	 */
179
+	public function insertOrUpdate($sosa_records) {
180
+		if(!$this->is_setup) return;
181 181
         
182
-        $treeid = $this->tree->getTreeId();
183
-        $userid = $this->user->getUserId();
184
-        $questionmarks_table = array();
185
-        $values_table = array();
182
+		$treeid = $this->tree->getTreeId();
183
+		$userid = $this->user->getUserId();
184
+		$questionmarks_table = array();
185
+		$values_table = array();
186 186
         
187
-        $i = 0;
188
-        foreach  ($sosa_records as $row) {
189
-            $gen = Functions::getGeneration($row['sosa']);
190
-            if($gen <= self::MAX_DB_GENERATIONS) {
191
-                $questionmarks_table[] = 
192
-                    '(:tree_id'.$i.', :user_id'.$i.', :sosa'.$i.', :indi_id'.$i.', :gen'.$i.', :byear'.$i.', :dyear'.$i.')';
193
-                $values_table = array_merge(
194
-                    $values_table, 
195
-                    array(
196
-                        'tree_id'.$i => $treeid, 
197
-                        'user_id'.$i => $userid, 
198
-                        'sosa'.$i => $row['sosa'], 
199
-                        'indi_id'.$i => $row['indi'], 
200
-                        'gen'.$i => Functions::getGeneration($row['sosa']),
201
-                        'byear'.$i => $row['birth_year'],
202
-                        'dyear'.$i => $row['death_year']
203
-                    )
204
-                );
205
-            }
206
-            $i++;
207
-        }
187
+		$i = 0;
188
+		foreach  ($sosa_records as $row) {
189
+			$gen = Functions::getGeneration($row['sosa']);
190
+			if($gen <= self::MAX_DB_GENERATIONS) {
191
+				$questionmarks_table[] = 
192
+					'(:tree_id'.$i.', :user_id'.$i.', :sosa'.$i.', :indi_id'.$i.', :gen'.$i.', :byear'.$i.', :dyear'.$i.')';
193
+				$values_table = array_merge(
194
+					$values_table, 
195
+					array(
196
+						'tree_id'.$i => $treeid, 
197
+						'user_id'.$i => $userid, 
198
+						'sosa'.$i => $row['sosa'], 
199
+						'indi_id'.$i => $row['indi'], 
200
+						'gen'.$i => Functions::getGeneration($row['sosa']),
201
+						'byear'.$i => $row['birth_year'],
202
+						'dyear'.$i => $row['death_year']
203
+					)
204
+				);
205
+			}
206
+			$i++;
207
+		}
208 208
         
209
-        $sql = 'REPLACE INTO `##maj_sosa`' .
210
-            ' (majs_gedcom_id, majs_user_id, majs_sosa, majs_i_id, majs_gen, majs_birth_year, majs_death_year)' .
211
-            ' VALUES '. implode(',', $questionmarks_table);
212
-        Database::prepare($sql)->execute($values_table);
213
-    }
209
+		$sql = 'REPLACE INTO `##maj_sosa`' .
210
+			' (majs_gedcom_id, majs_user_id, majs_sosa, majs_i_id, majs_gen, majs_birth_year, majs_death_year)' .
211
+			' VALUES '. implode(',', $questionmarks_table);
212
+		Database::prepare($sql)->execute($values_table);
213
+	}
214 214
     
215
-    /****************
215
+	/****************
216 216
      * SIMPLE QUERIES
217 217
      ****************/
218 218
     
219
-    /**
220
-     * Returns the list of Sosa numbers to which an individual is related.
221
-     * Format: key = sosa number, value = generation for the Sosa number
222
-     * 
223
-     * @param Individual $indi
224
-     * @return array Array of sosa numbers
225
-     */
226
-    public function getSosaNumbers(Individual $indi) {
227
-        if(!$this->is_setup) return array();
228
-        return Database::prepare(
229
-                'SELECT majs_sosa, majs_gen FROM `##maj_sosa`'.
230
-                ' WHERE majs_i_id=:indi_id AND majs_gedcom_id=:tree_id AND majs_user_id=:user_id'
231
-            )->execute(array(
232
-                'indi_id' => $indi->getXref(), 
233
-                'tree_id' => $this->tree->getTreeId(), 
234
-                'user_id' => $this->user->getUserId()
235
-            ))->fetchAssoc();
236
-    }
237
-    
238
-    /**
239
-     * Get the last generation of Sosa ancestors
240
-     *
241
-     * @return number Last generation if found, 1 otherwise
242
-     */
243
-    public function getLastGeneration() {
244
-        if(!$this->is_setup) return;
245
-        return Database::prepare(
246
-                'SELECT MAX(majs_gen) FROM `##maj_sosa`'.
247
-                ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'
248
-            )->execute(array(
249
-                'tree_id' => $this->tree->getTreeId(), 
250
-                'user_id' => $this->user->getUserId()                
251
-            ))->fetchOne() ?: 1;
252
-    }
253
-    
254
-    /*************
219
+	/**
220
+	 * Returns the list of Sosa numbers to which an individual is related.
221
+	 * Format: key = sosa number, value = generation for the Sosa number
222
+	 * 
223
+	 * @param Individual $indi
224
+	 * @return array Array of sosa numbers
225
+	 */
226
+	public function getSosaNumbers(Individual $indi) {
227
+		if(!$this->is_setup) return array();
228
+		return Database::prepare(
229
+				'SELECT majs_sosa, majs_gen FROM `##maj_sosa`'.
230
+				' WHERE majs_i_id=:indi_id AND majs_gedcom_id=:tree_id AND majs_user_id=:user_id'
231
+			)->execute(array(
232
+				'indi_id' => $indi->getXref(), 
233
+				'tree_id' => $this->tree->getTreeId(), 
234
+				'user_id' => $this->user->getUserId()
235
+			))->fetchAssoc();
236
+	}
237
+    
238
+	/**
239
+	 * Get the last generation of Sosa ancestors
240
+	 *
241
+	 * @return number Last generation if found, 1 otherwise
242
+	 */
243
+	public function getLastGeneration() {
244
+		if(!$this->is_setup) return;
245
+		return Database::prepare(
246
+				'SELECT MAX(majs_gen) FROM `##maj_sosa`'.
247
+				' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'
248
+			)->execute(array(
249
+				'tree_id' => $this->tree->getTreeId(), 
250
+				'user_id' => $this->user->getUserId()                
251
+			))->fetchOne() ?: 1;
252
+	}
253
+    
254
+	/*************
255 255
      * SOSA LISTS
256 256
      *************/
257 257
     
258
-    /**
259
-     * Return the list of all sosas, with the generations it belongs to
260
-     *
261
-     * @param int $ged_id ID of the gedcom file
262
-     * @return array Associative array of Sosa ancestors, with their generation, comma separated
263
-     */
264
-    public function getAllSosaWithGenerations(){
265
-        if(!$this->is_setup) return array();
266
-        return Database::prepare(
267
-            'SELECT majs_i_id AS indi,' .
268
-            ' GROUP_CONCAT(DISTINCT majs_gen ORDER BY majs_gen ASC SEPARATOR ",") AS generations' .
269
-            ' FROM `##maj_sosa`' .
270
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id' .
271
-            ' GROUP BY majs_i_id'
272
-        )->execute(array(
273
-            'tree_id' => $this->tree->getTreeId(),
274
-            'user_id' => $this->user->getUserId()
275
-        ))->fetchAssoc();
276
-    }
277
-    
278
-    /**
279
-     * Get an associative array of Sosa individuals in generation G. Keys are Sosa numbers, values individuals.
280
-     *
281
-     * @param number $gen Generation
282
-     * @return array Array of Sosa individuals
283
-     */
284
-    public function getSosaListAtGeneration($gen){
285
-        if(!$this->is_setup) return array();
286
-        if(!$this->sosa_list_by_gen)
287
-            $this->sosa_list_by_gen = array();
258
+	/**
259
+	 * Return the list of all sosas, with the generations it belongs to
260
+	 *
261
+	 * @param int $ged_id ID of the gedcom file
262
+	 * @return array Associative array of Sosa ancestors, with their generation, comma separated
263
+	 */
264
+	public function getAllSosaWithGenerations(){
265
+		if(!$this->is_setup) return array();
266
+		return Database::prepare(
267
+			'SELECT majs_i_id AS indi,' .
268
+			' GROUP_CONCAT(DISTINCT majs_gen ORDER BY majs_gen ASC SEPARATOR ",") AS generations' .
269
+			' FROM `##maj_sosa`' .
270
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id' .
271
+			' GROUP BY majs_i_id'
272
+		)->execute(array(
273
+			'tree_id' => $this->tree->getTreeId(),
274
+			'user_id' => $this->user->getUserId()
275
+		))->fetchAssoc();
276
+	}
277
+    
278
+	/**
279
+	 * Get an associative array of Sosa individuals in generation G. Keys are Sosa numbers, values individuals.
280
+	 *
281
+	 * @param number $gen Generation
282
+	 * @return array Array of Sosa individuals
283
+	 */
284
+	public function getSosaListAtGeneration($gen){
285
+		if(!$this->is_setup) return array();
286
+		if(!$this->sosa_list_by_gen)
287
+			$this->sosa_list_by_gen = array();
288 288
         
289
-        if($gen){
290
-            if(!isset($this->sosa_list_by_gen[$gen])){
291
-                $this->sosa_list_by_gen[$gen] = Database::prepare(
292
-                    'SELECT majs_sosa AS sosa, majs_i_id AS indi'.
293
-                    ' FROM `##maj_sosa`'.
294
-                    ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
295
-                    ' AND majs_gen = :gen'.
296
-                    ' ORDER BY majs_sosa ASC')
297
-                ->execute(array(
298
-                    'tree_id' => $this->tree->getTreeId(),
299
-                    'user_id' => $this->user->getUserId(),
300
-                    'gen' => $gen
301
-                ))
302
-                ->fetchAssoc();
303
-            }
304
-            return $this->sosa_list_by_gen[$gen];
305
-        }
306
-        return array();
307
-    }
308
-    
309
-    /**
310
-     * Get an associative array of Sosa families in generation G. Keys are Sosa numbers for the husband, values families.
311
-     *
312
-     * @param number $gen Generation
313
-     * @return array Array of Sosa families
314
-     */
315
-    public function getFamilySosaListAtGeneration($gen){
316
-        if(!$this->is_setup) return array();
317
-        if(!$this->sosa_fam_list_by_gen)
318
-            $this->sosa_fam_list_by_gen = array();
289
+		if($gen){
290
+			if(!isset($this->sosa_list_by_gen[$gen])){
291
+				$this->sosa_list_by_gen[$gen] = Database::prepare(
292
+					'SELECT majs_sosa AS sosa, majs_i_id AS indi'.
293
+					' FROM `##maj_sosa`'.
294
+					' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
295
+					' AND majs_gen = :gen'.
296
+					' ORDER BY majs_sosa ASC')
297
+				->execute(array(
298
+					'tree_id' => $this->tree->getTreeId(),
299
+					'user_id' => $this->user->getUserId(),
300
+					'gen' => $gen
301
+				))
302
+				->fetchAssoc();
303
+			}
304
+			return $this->sosa_list_by_gen[$gen];
305
+		}
306
+		return array();
307
+	}
308
+    
309
+	/**
310
+	 * Get an associative array of Sosa families in generation G. Keys are Sosa numbers for the husband, values families.
311
+	 *
312
+	 * @param number $gen Generation
313
+	 * @return array Array of Sosa families
314
+	 */
315
+	public function getFamilySosaListAtGeneration($gen){
316
+		if(!$this->is_setup) return array();
317
+		if(!$this->sosa_fam_list_by_gen)
318
+			$this->sosa_fam_list_by_gen = array();
319 319
         
320
-        if($gen){
321
-            if(!isset($this->sosa_fam_list_by_gen[$gen])){
322
-                $this->sosa_fam_list_by_gen[$gen] = Database::prepare(
323
-                    'SELECT s1.majs_sosa AS sosa, f_id AS fam'.
324
-                    ' FROM `##families`'.
325
-                    ' INNER JOIN `##maj_sosa` AS s1 ON (`##families`.f_husb = s1.majs_i_id AND `##families`.f_file = s1.majs_gedcom_id)'.
326
-                    ' INNER JOIN `##maj_sosa` AS s2 ON (`##families`.f_wife = s2.majs_i_id AND `##families`.f_file = s2.majs_gedcom_id)'.
327
-                    ' WHERE s1.majs_sosa + 1 = s2.majs_sosa'.
328
-                    ' AND s1.majs_gedcom_id= :tree_id AND s1.majs_user_id=:user_id'.
329
-                    ' AND s2.majs_gedcom_id= :tree_id AND s2.majs_user_id=:user_id'.
330
-                    ' AND s1.majs_gen = :gen'.
331
-                    ' ORDER BY s1.majs_sosa ASC'
332
-                    )
333
-                    ->execute(array(
334
-                        'tree_id' => $this->tree->getTreeId(),
335
-                        'user_id' => $this->user->getUserId(),
336
-                        'gen' => $gen
337
-                    ))
338
-                    ->fetchAssoc();
339
-            }
340
-            return $this->sosa_fam_list_by_gen[$gen];
341
-        }
342
-        return array();
343
-    }
344
-    
345
-    /**
346
-     * Get an associative array of Sosa individuals in generation G who are missing parents. Keys are Sosa numbers, values individuals.
347
-     *
348
-     * @param number $gen Generation
349
-     * @return array Array of Sosa individuals
350
-     */
351
-    public function getMissingSosaListAtGeneration($gen){
352
-        if(!$this->is_setup) return array();    
353
-        if($gen){
354
-            return $this->sosa_list_by_gen[$gen] = Database::prepare(
355
-                'SELECT schild.majs_sosa sosa, schild.majs_i_id indi, sfat.majs_sosa IS NOT NULL has_father, smot.majs_sosa IS NOT NULL has_mother'.
356
-                ' FROM `##maj_sosa` schild'.
357
-                ' LEFT JOIN `##maj_sosa` sfat ON ((schild.majs_sosa * 2) = sfat.majs_sosa AND schild.majs_gedcom_id = sfat.majs_gedcom_id AND schild.majs_user_id = sfat.majs_user_id)'.
358
-                ' LEFT JOIN `##maj_sosa` smot ON ((schild.majs_sosa * 2 + 1) = smot.majs_sosa AND schild.majs_gedcom_id = smot.majs_gedcom_id AND schild.majs_user_id = smot.majs_user_id)'.
359
-                ' WHERE schild.majs_gedcom_id = :tree_id AND schild.majs_user_id = :user_id'.
360
-                ' AND schild.majs_gen = :gen'.
361
-                ' AND (sfat.majs_sosa IS NULL OR smot.majs_sosa IS NULL)'.
362
-                ' ORDER BY schild.majs_sosa ASC')
363
-                ->execute(array(
364
-                    'tree_id' => $this->tree->getTreeId(),
365
-                    'user_id' => $this->user->getUserId(),
366
-                    'gen' => $gen - 1
367
-                ))->fetchAll(\PDO::FETCH_ASSOC);
368
-        }
369
-        return array();
370
-    }
371
-    
372
-    
373
-    
374
-    /*************
320
+		if($gen){
321
+			if(!isset($this->sosa_fam_list_by_gen[$gen])){
322
+				$this->sosa_fam_list_by_gen[$gen] = Database::prepare(
323
+					'SELECT s1.majs_sosa AS sosa, f_id AS fam'.
324
+					' FROM `##families`'.
325
+					' INNER JOIN `##maj_sosa` AS s1 ON (`##families`.f_husb = s1.majs_i_id AND `##families`.f_file = s1.majs_gedcom_id)'.
326
+					' INNER JOIN `##maj_sosa` AS s2 ON (`##families`.f_wife = s2.majs_i_id AND `##families`.f_file = s2.majs_gedcom_id)'.
327
+					' WHERE s1.majs_sosa + 1 = s2.majs_sosa'.
328
+					' AND s1.majs_gedcom_id= :tree_id AND s1.majs_user_id=:user_id'.
329
+					' AND s2.majs_gedcom_id= :tree_id AND s2.majs_user_id=:user_id'.
330
+					' AND s1.majs_gen = :gen'.
331
+					' ORDER BY s1.majs_sosa ASC'
332
+					)
333
+					->execute(array(
334
+						'tree_id' => $this->tree->getTreeId(),
335
+						'user_id' => $this->user->getUserId(),
336
+						'gen' => $gen
337
+					))
338
+					->fetchAssoc();
339
+			}
340
+			return $this->sosa_fam_list_by_gen[$gen];
341
+		}
342
+		return array();
343
+	}
344
+    
345
+	/**
346
+	 * Get an associative array of Sosa individuals in generation G who are missing parents. Keys are Sosa numbers, values individuals.
347
+	 *
348
+	 * @param number $gen Generation
349
+	 * @return array Array of Sosa individuals
350
+	 */
351
+	public function getMissingSosaListAtGeneration($gen){
352
+		if(!$this->is_setup) return array();    
353
+		if($gen){
354
+			return $this->sosa_list_by_gen[$gen] = Database::prepare(
355
+				'SELECT schild.majs_sosa sosa, schild.majs_i_id indi, sfat.majs_sosa IS NOT NULL has_father, smot.majs_sosa IS NOT NULL has_mother'.
356
+				' FROM `##maj_sosa` schild'.
357
+				' LEFT JOIN `##maj_sosa` sfat ON ((schild.majs_sosa * 2) = sfat.majs_sosa AND schild.majs_gedcom_id = sfat.majs_gedcom_id AND schild.majs_user_id = sfat.majs_user_id)'.
358
+				' LEFT JOIN `##maj_sosa` smot ON ((schild.majs_sosa * 2 + 1) = smot.majs_sosa AND schild.majs_gedcom_id = smot.majs_gedcom_id AND schild.majs_user_id = smot.majs_user_id)'.
359
+				' WHERE schild.majs_gedcom_id = :tree_id AND schild.majs_user_id = :user_id'.
360
+				' AND schild.majs_gen = :gen'.
361
+				' AND (sfat.majs_sosa IS NULL OR smot.majs_sosa IS NULL)'.
362
+				' ORDER BY schild.majs_sosa ASC')
363
+				->execute(array(
364
+					'tree_id' => $this->tree->getTreeId(),
365
+					'user_id' => $this->user->getUserId(),
366
+					'gen' => $gen - 1
367
+				))->fetchAll(\PDO::FETCH_ASSOC);
368
+		}
369
+		return array();
370
+	}
371
+    
372
+    
373
+    
374
+	/*************
375 375
      * STATISTICS
376 376
      *************/
377
-    /**
378
-     * Get the statistic array detailed by generation.
379
-     * Statistics for each generation are:
380
-     * 	- The number of Sosa in generation
381
-     * 	- The number of Sosa up to generation
382
-     *  - The number of distinct Sosa up to generation
383
-     *  - The year of the first birth in generation
384
-     *  - The year of the last birth in generation
385
-     *  - The average year of birth in generation
386
-     *
387
-     * @return array Statistics array
388
-     */
389
-    public function getStatisticsByGeneration() {
390
-        if(!$this->is_setup) return array();
391
-        if(!$this->statistics_tab) {
392
-            $this->statistics_tab = array();
393
-            if($maxGeneration = $this->getLastGeneration()) {
394
-                for ($gen = 1; $gen <= $maxGeneration; $gen++) {
395
-                    $birthStats = $this->getStatsBirthYearInGeneration($gen);
396
-                    $this->statistics_tab[$gen] = array(
397
-                        'sosaCount'				=>	$this->getSosaCountAtGeneration($gen),
398
-                        'sosaTotalCount'		=>	$this->getSosaCountUpToGeneration($gen),
399
-                        'diffSosaTotalCount'	=>	$this->getDifferentSosaCountUpToGeneration($gen),
400
-                        'firstBirth'			=>	$birthStats['first'],
401
-                        'lastBirth'				=>	$birthStats['last'],
402
-                        'avgBirth'				=>	$birthStats['avg']
403
-                    );
404
-                }
405
-            }
406
-        }
407
-        return $this->statistics_tab;        
408
-    }
377
+	/**
378
+	 * Get the statistic array detailed by generation.
379
+	 * Statistics for each generation are:
380
+	 * 	- The number of Sosa in generation
381
+	 * 	- The number of Sosa up to generation
382
+	 *  - The number of distinct Sosa up to generation
383
+	 *  - The year of the first birth in generation
384
+	 *  - The year of the last birth in generation
385
+	 *  - The average year of birth in generation
386
+	 *
387
+	 * @return array Statistics array
388
+	 */
389
+	public function getStatisticsByGeneration() {
390
+		if(!$this->is_setup) return array();
391
+		if(!$this->statistics_tab) {
392
+			$this->statistics_tab = array();
393
+			if($maxGeneration = $this->getLastGeneration()) {
394
+				for ($gen = 1; $gen <= $maxGeneration; $gen++) {
395
+					$birthStats = $this->getStatsBirthYearInGeneration($gen);
396
+					$this->statistics_tab[$gen] = array(
397
+						'sosaCount'				=>	$this->getSosaCountAtGeneration($gen),
398
+						'sosaTotalCount'		=>	$this->getSosaCountUpToGeneration($gen),
399
+						'diffSosaTotalCount'	=>	$this->getDifferentSosaCountUpToGeneration($gen),
400
+						'firstBirth'			=>	$birthStats['first'],
401
+						'lastBirth'				=>	$birthStats['last'],
402
+						'avgBirth'				=>	$birthStats['avg']
403
+					);
404
+				}
405
+			}
406
+		}
407
+		return $this->statistics_tab;        
408
+	}
409 409
     
410 410
 	/**
411 411
 	 * How many individuals exist in the tree.
@@ -413,205 +413,205 @@  discard block
 block discarded – undo
413 413
 	 * @return int
414 414
 	 */
415 415
 	public function getTotalIndividuals() {
416
-	    if(!$this->is_setup) return 0;
417
-	    return Database::prepare(
418
-	        'SELECT SQL_CACHE COUNT(*) FROM `##individuals`' .
419
-	        ' WHERE i_file = :tree_id')
420
-	        ->execute(array('tree_id' => $this->tree->getTreeId()))
421
-	        ->fetchOne() ?: 0;
416
+		if(!$this->is_setup) return 0;
417
+		return Database::prepare(
418
+			'SELECT SQL_CACHE COUNT(*) FROM `##individuals`' .
419
+			' WHERE i_file = :tree_id')
420
+			->execute(array('tree_id' => $this->tree->getTreeId()))
421
+			->fetchOne() ?: 0;
422 422
 	}
423 423
     
424
-    /**
425
-     * Get the total Sosa count for all generations
426
-     *
427
-     * @return number Number of Sosas
428
-     */
429
-    public function getSosaCount(){
430
-        if(!$this->is_setup) return 0;
431
-        return Database::prepare(
432
-            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
433
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
434
-            ->execute(array(
435
-                'tree_id' => $this->tree->getTreeId(), 
436
-                'user_id' => $this->user->getUserId() 
437
-            ))->fetchOne() ?: 0;
438
-    }
439
-    
440
-    /**
441
-     * Get the number of Sosa in a specific generation.
442
-     *
443
-     * @param number $gen Generation
444
-     * @return number Number of Sosas in generation
445
-     */
446
-    public function getSosaCountAtGeneration($gen){
447
-        if(!$this->is_setup) return 0;
448
-        return Database::prepare(
449
-            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
450
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
451
-            ' AND majs_gen= :gen')
452
-        ->execute(array(
453
-                'tree_id' => $this->tree->getTreeId(), 
454
-                'user_id' => $this->user->getUserId(),
455
-                'gen' => $gen            
456
-        ))->fetchOne() ?: 0;
457
-    }
458
-    
459
-    /**
460
-     * Get the total number of Sosa up to a specific generation.
461
-     *
462
-     * @param number $gen Generation
463
-     * @return number Total number of Sosas up to generation
464
-     */
465
-    public function getSosaCountUpToGeneration($gen){
466
-        if(!$this->is_setup) return 0;
467
-        return Database::prepare(
468
-            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
469
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
470
-            ' AND majs_gen <= :gen')
471
-        ->execute(array(
472
-                'tree_id' => $this->tree->getTreeId(), 
473
-                'user_id' => $this->user->getUserId(),
474
-                'gen' => $gen 
475
-        ))->fetchOne() ?: 0;
476
-    }
477
-    
478
-    /**
479
-     * Get the total number of distinct Sosa individual for all generations.
480
-     *
481
-     * @return number Total number of distinct individual
482
-     */
483
-    public function getDifferentSosaCount(){
484
-        if(!$this->is_setup) return 0;
485
-        return Database::prepare(
486
-            'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
487
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
488
-        ->execute(array(
489
-                'tree_id' => $this->tree->getTreeId(), 
490
-                'user_id' => $this->user->getUserId()
491
-        ))->fetchOne() ?: 0;
492
-    }
493
-    
494
-    /**
495
-     * Get the number of distinct Sosa individual up to a specific generation.
496
-     *
497
-     * @param number $gen Generation
498
-     * @return number Number of distinct Sosa individuals up to generation
499
-     */
500
-    public function getDifferentSosaCountUpToGeneration($gen){
501
-        if(!$this->is_setup) return 0;
502
-        return Database::prepare(
503
-            'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
504
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
505
-            ' AND majs_gen <= :gen')
506
-        ->execute(array(
507
-                'tree_id' => $this->tree->getTreeId(), 
508
-                'user_id' => $this->user->getUserId(),
509
-                'gen' => $gen 
510
-        ))->fetchOne() ?: 0;
511
-    }
512
-    
513
-    /**
514
-     * Get an array of birth statistics for a specific generation
515
-     * Statistics are :
516
-     * 	- first : First birth year in generation
517
-     *  - last : Last birth year in generation
518
-     *  - avg : Average birth year
519
-     *
520
-     * @param number $gen Generation
521
-     * @return array Birth statistics array
522
-     */
523
-    public function getStatsBirthYearInGeneration($gen){
524
-        if(!$this->is_setup) return array('first' => 0, 'avg' => 0, 'last' => 0);
525
-        return Database::prepare(
526
-            'SELECT MIN(majs_birth_year) AS first, AVG(majs_birth_year) AS avg, MAX(majs_birth_year) AS last'.
527
-            ' FROM `##maj_sosa`' .
528
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
529
-            ' AND majs_gen=:gen AND NOT majs_birth_year = :birth_year')
530
-            ->execute(array(
531
-                'tree_id' => $this->tree->getTreeId(), 
532
-                'user_id' => $this->user->getUserId(),
533
-                'gen' => $gen,
534
-                'birth_year' => 0))
535
-            ->fetchOneRow(\PDO::FETCH_ASSOC) ?: array('first' => 0, 'avg' => 0, 'last' => 0);
536
-    }
537
-    
538
-    /**
539
-     * Get the mean generation time, based on a linear regression of birth years and generations
540
-     *
541
-     * @return number|NULL Mean generation time
542
-     */
543
-    public function getMeanGenerationTime(){
544
-        if(!$this->is_setup) return;
545
-        if(!$this->statistics_tab){
546
-            $this->getStatisticsByGeneration();
547
-        }
548
-        //Linear regression on x=generation and y=birthdate
549
-        $sum_xy = 0;
550
-        $sum_x=0;
551
-        $sum_y=0;
552
-        $sum_x2=0;
553
-        $n=count($this->statistics_tab);
554
-        foreach($this->statistics_tab as $gen=>$stats){
555
-            $sum_xy+=$gen*$stats['avgBirth'];
556
-            $sum_x+=$gen;
557
-            $sum_y+=$stats['avgBirth'];
558
-            $sum_x2+=$gen*$gen;
559
-        }
560
-        $denom=($n*$sum_x2)-($sum_x*$sum_x);
561
-        if($denom!=0){
562
-            return -(($n*$sum_xy)-($sum_x*$sum_y))/($denom);
563
-        }
564
-        return null;
565
-    }
566
-    
567
-    /**
568
-     * Return a computed array of statistics about the dispersion of ancestors across the ancestors
569
-     * at a specified generation.
570
-     * This statistics cannot be used for generations above 11, as it would cause a out of range in MySQL
571
-     * 
572
-     * Format: 
573
-     *  - key : a base-2 representation of the ancestor at generation G for which exclusive ancestors have been found,
574
-     *          -1 is used for shared ancestors
575
-     *          For instance base2(0100) = base10(4) represent the maternal grand father
576
-     *  - values: number of ancestors exclusively in the ancestors of the ancestor in key
577
-     *  
578
-     *  For instance a result at generation 3 could be :
579
-     *      array (   -1        =>  12      -> 12 ancestors are shared by the grand-parents
580
-     *                base10(1) =>  32      -> 32 ancestors are exclusive to the paternal grand-father
581
-     *                base10(2) =>  25      -> 25 ancestors are exclusive to the paternal grand-mother
582
-     *                base10(4) =>  12      -> 12 ancestors are exclusive to the maternal grand-father
583
-     *                base10(8) =>  30      -> 30 ancestors are exclusive to the maternal grand-mother
584
-     *            )
585
-     *  
586
-     * @param int $gen Reference generation
587
-     * @return array
588
-     */
589
-    public function getAncestorDispersionForGen($gen) {
590
-        if(!$this->is_setup || $gen > 11) return array();  // Going further than 11 gen will be out of range in the query
591
-        return Database::prepare(
592
-            'SELECT branches, count(i_id)'.
593
-            ' FROM ('.
594
-            '   SELECT i_id,'.
595
-            '       CASE'.
596
-            '           WHEN CEIL(LOG2(SUM(branch))) = LOG2(SUM(branch)) THEN SUM(branch)'.
597
-            '           ELSE -1'.   // We put all ancestors shared between some branches in the same bucket
598
-            '       END branches'.
599
-            '   FROM ('.
600
-            '       SELECT DISTINCT majs_i_id i_id,'.
601
-            '           POW(2, FLOOR(majs_sosa / POW(2, (majs_gen - :gen))) - POW(2, :gen -1)) branch'.
602
-            '       FROM `##maj_sosa`'.
603
-            '       WHERE majs_gedcom_id = :tree_id AND majs_user_id = :user_id'.
604
-            '           AND majs_gen >= :gen'.
605
-            '   ) indistat'.
606
-            '   GROUP BY i_id'.
607
-            ') grouped'.
608
-            ' GROUP BY branches')
609
-            ->execute(array(
610
-                'tree_id' => $this->tree->getTreeId(), 
611
-                'user_id' => $this->user->getUserId(),
612
-                'gen' => $gen
613
-            ))->fetchAssoc() ?: array();
614
-    }
424
+	/**
425
+	 * Get the total Sosa count for all generations
426
+	 *
427
+	 * @return number Number of Sosas
428
+	 */
429
+	public function getSosaCount(){
430
+		if(!$this->is_setup) return 0;
431
+		return Database::prepare(
432
+			'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
433
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
434
+			->execute(array(
435
+				'tree_id' => $this->tree->getTreeId(), 
436
+				'user_id' => $this->user->getUserId() 
437
+			))->fetchOne() ?: 0;
438
+	}
439
+    
440
+	/**
441
+	 * Get the number of Sosa in a specific generation.
442
+	 *
443
+	 * @param number $gen Generation
444
+	 * @return number Number of Sosas in generation
445
+	 */
446
+	public function getSosaCountAtGeneration($gen){
447
+		if(!$this->is_setup) return 0;
448
+		return Database::prepare(
449
+			'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
450
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
451
+			' AND majs_gen= :gen')
452
+		->execute(array(
453
+				'tree_id' => $this->tree->getTreeId(), 
454
+				'user_id' => $this->user->getUserId(),
455
+				'gen' => $gen            
456
+		))->fetchOne() ?: 0;
457
+	}
458
+    
459
+	/**
460
+	 * Get the total number of Sosa up to a specific generation.
461
+	 *
462
+	 * @param number $gen Generation
463
+	 * @return number Total number of Sosas up to generation
464
+	 */
465
+	public function getSosaCountUpToGeneration($gen){
466
+		if(!$this->is_setup) return 0;
467
+		return Database::prepare(
468
+			'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
469
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
470
+			' AND majs_gen <= :gen')
471
+		->execute(array(
472
+				'tree_id' => $this->tree->getTreeId(), 
473
+				'user_id' => $this->user->getUserId(),
474
+				'gen' => $gen 
475
+		))->fetchOne() ?: 0;
476
+	}
477
+    
478
+	/**
479
+	 * Get the total number of distinct Sosa individual for all generations.
480
+	 *
481
+	 * @return number Total number of distinct individual
482
+	 */
483
+	public function getDifferentSosaCount(){
484
+		if(!$this->is_setup) return 0;
485
+		return Database::prepare(
486
+			'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
487
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
488
+		->execute(array(
489
+				'tree_id' => $this->tree->getTreeId(), 
490
+				'user_id' => $this->user->getUserId()
491
+		))->fetchOne() ?: 0;
492
+	}
493
+    
494
+	/**
495
+	 * Get the number of distinct Sosa individual up to a specific generation.
496
+	 *
497
+	 * @param number $gen Generation
498
+	 * @return number Number of distinct Sosa individuals up to generation
499
+	 */
500
+	public function getDifferentSosaCountUpToGeneration($gen){
501
+		if(!$this->is_setup) return 0;
502
+		return Database::prepare(
503
+			'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
504
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
505
+			' AND majs_gen <= :gen')
506
+		->execute(array(
507
+				'tree_id' => $this->tree->getTreeId(), 
508
+				'user_id' => $this->user->getUserId(),
509
+				'gen' => $gen 
510
+		))->fetchOne() ?: 0;
511
+	}
512
+    
513
+	/**
514
+	 * Get an array of birth statistics for a specific generation
515
+	 * Statistics are :
516
+	 * 	- first : First birth year in generation
517
+	 *  - last : Last birth year in generation
518
+	 *  - avg : Average birth year
519
+	 *
520
+	 * @param number $gen Generation
521
+	 * @return array Birth statistics array
522
+	 */
523
+	public function getStatsBirthYearInGeneration($gen){
524
+		if(!$this->is_setup) return array('first' => 0, 'avg' => 0, 'last' => 0);
525
+		return Database::prepare(
526
+			'SELECT MIN(majs_birth_year) AS first, AVG(majs_birth_year) AS avg, MAX(majs_birth_year) AS last'.
527
+			' FROM `##maj_sosa`' .
528
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
529
+			' AND majs_gen=:gen AND NOT majs_birth_year = :birth_year')
530
+			->execute(array(
531
+				'tree_id' => $this->tree->getTreeId(), 
532
+				'user_id' => $this->user->getUserId(),
533
+				'gen' => $gen,
534
+				'birth_year' => 0))
535
+			->fetchOneRow(\PDO::FETCH_ASSOC) ?: array('first' => 0, 'avg' => 0, 'last' => 0);
536
+	}
537
+    
538
+	/**
539
+	 * Get the mean generation time, based on a linear regression of birth years and generations
540
+	 *
541
+	 * @return number|NULL Mean generation time
542
+	 */
543
+	public function getMeanGenerationTime(){
544
+		if(!$this->is_setup) return;
545
+		if(!$this->statistics_tab){
546
+			$this->getStatisticsByGeneration();
547
+		}
548
+		//Linear regression on x=generation and y=birthdate
549
+		$sum_xy = 0;
550
+		$sum_x=0;
551
+		$sum_y=0;
552
+		$sum_x2=0;
553
+		$n=count($this->statistics_tab);
554
+		foreach($this->statistics_tab as $gen=>$stats){
555
+			$sum_xy+=$gen*$stats['avgBirth'];
556
+			$sum_x+=$gen;
557
+			$sum_y+=$stats['avgBirth'];
558
+			$sum_x2+=$gen*$gen;
559
+		}
560
+		$denom=($n*$sum_x2)-($sum_x*$sum_x);
561
+		if($denom!=0){
562
+			return -(($n*$sum_xy)-($sum_x*$sum_y))/($denom);
563
+		}
564
+		return null;
565
+	}
566
+    
567
+	/**
568
+	 * Return a computed array of statistics about the dispersion of ancestors across the ancestors
569
+	 * at a specified generation.
570
+	 * This statistics cannot be used for generations above 11, as it would cause a out of range in MySQL
571
+	 * 
572
+	 * Format: 
573
+	 *  - key : a base-2 representation of the ancestor at generation G for which exclusive ancestors have been found,
574
+	 *          -1 is used for shared ancestors
575
+	 *          For instance base2(0100) = base10(4) represent the maternal grand father
576
+	 *  - values: number of ancestors exclusively in the ancestors of the ancestor in key
577
+	 *  
578
+	 *  For instance a result at generation 3 could be :
579
+	 *      array (   -1        =>  12      -> 12 ancestors are shared by the grand-parents
580
+	 *                base10(1) =>  32      -> 32 ancestors are exclusive to the paternal grand-father
581
+	 *                base10(2) =>  25      -> 25 ancestors are exclusive to the paternal grand-mother
582
+	 *                base10(4) =>  12      -> 12 ancestors are exclusive to the maternal grand-father
583
+	 *                base10(8) =>  30      -> 30 ancestors are exclusive to the maternal grand-mother
584
+	 *            )
585
+	 *  
586
+	 * @param int $gen Reference generation
587
+	 * @return array
588
+	 */
589
+	public function getAncestorDispersionForGen($gen) {
590
+		if(!$this->is_setup || $gen > 11) return array();  // Going further than 11 gen will be out of range in the query
591
+		return Database::prepare(
592
+			'SELECT branches, count(i_id)'.
593
+			' FROM ('.
594
+			'   SELECT i_id,'.
595
+			'       CASE'.
596
+			'           WHEN CEIL(LOG2(SUM(branch))) = LOG2(SUM(branch)) THEN SUM(branch)'.
597
+			'           ELSE -1'.   // We put all ancestors shared between some branches in the same bucket
598
+			'       END branches'.
599
+			'   FROM ('.
600
+			'       SELECT DISTINCT majs_i_id i_id,'.
601
+			'           POW(2, FLOOR(majs_sosa / POW(2, (majs_gen - :gen))) - POW(2, :gen -1)) branch'.
602
+			'       FROM `##maj_sosa`'.
603
+			'       WHERE majs_gedcom_id = :tree_id AND majs_user_id = :user_id'.
604
+			'           AND majs_gen >= :gen'.
605
+			'   ) indistat'.
606
+			'   GROUP BY i_id'.
607
+			') grouped'.
608
+			' GROUP BY branches')
609
+			->execute(array(
610
+				'tree_id' => $this->tree->getTreeId(), 
611
+				'user_id' => $this->user->getUserId(),
612
+				'gen' => $gen
613
+			))->fetchAssoc() ?: array();
614
+	}
615 615
     
616 616
                
617 617
 }
Please login to merge, or discard this patch.
Spacing   +77 added lines, -77 removed lines patch added patch discarded remove patch
@@ -84,18 +84,18 @@  discard block
 block discarded – undo
84 84
      * @param User $user
85 85
      */
86 86
     public function __construct(Tree $tree, User $user = null) {
87
-        if(self::$default_user === null) 
87
+        if (self::$default_user === null) 
88 88
             self::$default_user = User::find(-1);
89 89
         
90 90
         $this->tree = $tree;
91 91
         $this->user = $user;
92 92
         $this->is_setup = true;
93
-        if($this->user === null) $this->user = Auth::user();
94
-        if(strlen($this->user->getUserId()) == 0) $this->user = self::$default_user;
93
+        if ($this->user === null) $this->user = Auth::user();
94
+        if (strlen($this->user->getUserId()) == 0) $this->user = self::$default_user;
95 95
         
96 96
         // Check if the user, or the default user, has a root already setup;
97
-        if(empty($this->getRootIndiId())) {
98
-            if($this->user == self::$default_user) {  // If the default user is not setup
97
+        if (empty($this->getRootIndiId())) {
98
+            if ($this->user == self::$default_user) {  // If the default user is not setup
99 99
                 $this->is_setup = false;
100 100
             }
101 101
             else {
@@ -127,7 +127,7 @@  discard block
 block discarded – undo
127 127
      */
128 128
     public function getRootIndi() {
129 129
         $root_indi_id = $this->getRootIndiId();
130
-        if(!empty($root_indi_id)) {
130
+        if (!empty($root_indi_id)) {
131 131
             return Individual::getInstance($root_indi_id, $this->tree);
132 132
         }
133 133
         return null;
@@ -141,7 +141,7 @@  discard block
 block discarded – undo
141 141
      * Remove all Sosa entries related to the gedcom file and user
142 142
      */
143 143
     public function deleteAll() {
144
-        if(!$this->is_setup) return;
144
+        if (!$this->is_setup) return;
145 145
         Database::prepare(
146 146
             'DELETE FROM `##maj_sosa`'.
147 147
             ' WHERE majs_gedcom_id= :tree_id and majs_user_id = :user_id ')
@@ -157,12 +157,12 @@  discard block
 block discarded – undo
157 157
      * @param int $sosa
158 158
      */
159 159
     public function deleteAncestors($sosa) {
160
-        if(!$this->is_setup) return;
160
+        if (!$this->is_setup) return;
161 161
         $gen = Functions::getGeneration($sosa);
162 162
         Database::prepare(
163 163
             'DELETE FROM `##maj_sosa`'.
164
-            ' WHERE majs_gedcom_id=:tree_id and majs_user_id = :user_id' .
165
-            ' AND majs_gen >= :gen' .
164
+            ' WHERE majs_gedcom_id=:tree_id and majs_user_id = :user_id'.
165
+            ' AND majs_gen >= :gen'.
166 166
             ' AND FLOOR(majs_sosa / (POW(2, (majs_gen - :gen)))) = :sosa'
167 167
         )->execute(array(
168 168
             'tree_id' => $this->tree->getTreeId(), 
@@ -177,7 +177,7 @@  discard block
 block discarded – undo
177 177
      * @param array $sosa_records
178 178
      */
179 179
     public function insertOrUpdate($sosa_records) {
180
-        if(!$this->is_setup) return;
180
+        if (!$this->is_setup) return;
181 181
         
182 182
         $treeid = $this->tree->getTreeId();
183 183
         $userid = $this->user->getUserId();
@@ -185,9 +185,9 @@  discard block
 block discarded – undo
185 185
         $values_table = array();
186 186
         
187 187
         $i = 0;
188
-        foreach  ($sosa_records as $row) {
188
+        foreach ($sosa_records as $row) {
189 189
             $gen = Functions::getGeneration($row['sosa']);
190
-            if($gen <= self::MAX_DB_GENERATIONS) {
190
+            if ($gen <= self::MAX_DB_GENERATIONS) {
191 191
                 $questionmarks_table[] = 
192 192
                     '(:tree_id'.$i.', :user_id'.$i.', :sosa'.$i.', :indi_id'.$i.', :gen'.$i.', :byear'.$i.', :dyear'.$i.')';
193 193
                 $values_table = array_merge(
@@ -206,9 +206,9 @@  discard block
 block discarded – undo
206 206
             $i++;
207 207
         }
208 208
         
209
-        $sql = 'REPLACE INTO `##maj_sosa`' .
210
-            ' (majs_gedcom_id, majs_user_id, majs_sosa, majs_i_id, majs_gen, majs_birth_year, majs_death_year)' .
211
-            ' VALUES '. implode(',', $questionmarks_table);
209
+        $sql = 'REPLACE INTO `##maj_sosa`'.
210
+            ' (majs_gedcom_id, majs_user_id, majs_sosa, majs_i_id, majs_gen, majs_birth_year, majs_death_year)'.
211
+            ' VALUES '.implode(',', $questionmarks_table);
212 212
         Database::prepare($sql)->execute($values_table);
213 213
     }
214 214
     
@@ -224,7 +224,7 @@  discard block
 block discarded – undo
224 224
      * @return array Array of sosa numbers
225 225
      */
226 226
     public function getSosaNumbers(Individual $indi) {
227
-        if(!$this->is_setup) return array();
227
+        if (!$this->is_setup) return array();
228 228
         return Database::prepare(
229 229
                 'SELECT majs_sosa, majs_gen FROM `##maj_sosa`'.
230 230
                 ' WHERE majs_i_id=:indi_id AND majs_gedcom_id=:tree_id AND majs_user_id=:user_id'
@@ -241,7 +241,7 @@  discard block
 block discarded – undo
241 241
      * @return number Last generation if found, 1 otherwise
242 242
      */
243 243
     public function getLastGeneration() {
244
-        if(!$this->is_setup) return;
244
+        if (!$this->is_setup) return;
245 245
         return Database::prepare(
246 246
                 'SELECT MAX(majs_gen) FROM `##maj_sosa`'.
247 247
                 ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'
@@ -261,13 +261,13 @@  discard block
 block discarded – undo
261 261
      * @param int $ged_id ID of the gedcom file
262 262
      * @return array Associative array of Sosa ancestors, with their generation, comma separated
263 263
      */
264
-    public function getAllSosaWithGenerations(){
265
-        if(!$this->is_setup) return array();
264
+    public function getAllSosaWithGenerations() {
265
+        if (!$this->is_setup) return array();
266 266
         return Database::prepare(
267
-            'SELECT majs_i_id AS indi,' .
268
-            ' GROUP_CONCAT(DISTINCT majs_gen ORDER BY majs_gen ASC SEPARATOR ",") AS generations' .
269
-            ' FROM `##maj_sosa`' .
270
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id' .
267
+            'SELECT majs_i_id AS indi,'.
268
+            ' GROUP_CONCAT(DISTINCT majs_gen ORDER BY majs_gen ASC SEPARATOR ",") AS generations'.
269
+            ' FROM `##maj_sosa`'.
270
+            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
271 271
             ' GROUP BY majs_i_id'
272 272
         )->execute(array(
273 273
             'tree_id' => $this->tree->getTreeId(),
@@ -281,13 +281,13 @@  discard block
 block discarded – undo
281 281
      * @param number $gen Generation
282 282
      * @return array Array of Sosa individuals
283 283
      */
284
-    public function getSosaListAtGeneration($gen){
285
-        if(!$this->is_setup) return array();
286
-        if(!$this->sosa_list_by_gen)
284
+    public function getSosaListAtGeneration($gen) {
285
+        if (!$this->is_setup) return array();
286
+        if (!$this->sosa_list_by_gen)
287 287
             $this->sosa_list_by_gen = array();
288 288
         
289
-        if($gen){
290
-            if(!isset($this->sosa_list_by_gen[$gen])){
289
+        if ($gen) {
290
+            if (!isset($this->sosa_list_by_gen[$gen])) {
291 291
                 $this->sosa_list_by_gen[$gen] = Database::prepare(
292 292
                     'SELECT majs_sosa AS sosa, majs_i_id AS indi'.
293 293
                     ' FROM `##maj_sosa`'.
@@ -312,13 +312,13 @@  discard block
 block discarded – undo
312 312
      * @param number $gen Generation
313 313
      * @return array Array of Sosa families
314 314
      */
315
-    public function getFamilySosaListAtGeneration($gen){
316
-        if(!$this->is_setup) return array();
317
-        if(!$this->sosa_fam_list_by_gen)
315
+    public function getFamilySosaListAtGeneration($gen) {
316
+        if (!$this->is_setup) return array();
317
+        if (!$this->sosa_fam_list_by_gen)
318 318
             $this->sosa_fam_list_by_gen = array();
319 319
         
320
-        if($gen){
321
-            if(!isset($this->sosa_fam_list_by_gen[$gen])){
320
+        if ($gen) {
321
+            if (!isset($this->sosa_fam_list_by_gen[$gen])) {
322 322
                 $this->sosa_fam_list_by_gen[$gen] = Database::prepare(
323 323
                     'SELECT s1.majs_sosa AS sosa, f_id AS fam'.
324 324
                     ' FROM `##families`'.
@@ -348,9 +348,9 @@  discard block
 block discarded – undo
348 348
      * @param number $gen Generation
349 349
      * @return array Array of Sosa individuals
350 350
      */
351
-    public function getMissingSosaListAtGeneration($gen){
352
-        if(!$this->is_setup) return array();    
353
-        if($gen){
351
+    public function getMissingSosaListAtGeneration($gen) {
352
+        if (!$this->is_setup) return array();    
353
+        if ($gen) {
354 354
             return $this->sosa_list_by_gen[$gen] = Database::prepare(
355 355
                 'SELECT schild.majs_sosa sosa, schild.majs_i_id indi, sfat.majs_sosa IS NOT NULL has_father, smot.majs_sosa IS NOT NULL has_mother'.
356 356
                 ' FROM `##maj_sosa` schild'.
@@ -387,10 +387,10 @@  discard block
 block discarded – undo
387 387
      * @return array Statistics array
388 388
      */
389 389
     public function getStatisticsByGeneration() {
390
-        if(!$this->is_setup) return array();
391
-        if(!$this->statistics_tab) {
390
+        if (!$this->is_setup) return array();
391
+        if (!$this->statistics_tab) {
392 392
             $this->statistics_tab = array();
393
-            if($maxGeneration = $this->getLastGeneration()) {
393
+            if ($maxGeneration = $this->getLastGeneration()) {
394 394
                 for ($gen = 1; $gen <= $maxGeneration; $gen++) {
395 395
                     $birthStats = $this->getStatsBirthYearInGeneration($gen);
396 396
                     $this->statistics_tab[$gen] = array(
@@ -413,9 +413,9 @@  discard block
 block discarded – undo
413 413
 	 * @return int
414 414
 	 */
415 415
 	public function getTotalIndividuals() {
416
-	    if(!$this->is_setup) return 0;
416
+	    if (!$this->is_setup) return 0;
417 417
 	    return Database::prepare(
418
-	        'SELECT SQL_CACHE COUNT(*) FROM `##individuals`' .
418
+	        'SELECT SQL_CACHE COUNT(*) FROM `##individuals`'.
419 419
 	        ' WHERE i_file = :tree_id')
420 420
 	        ->execute(array('tree_id' => $this->tree->getTreeId()))
421 421
 	        ->fetchOne() ?: 0;
@@ -426,10 +426,10 @@  discard block
 block discarded – undo
426 426
      *
427 427
      * @return number Number of Sosas
428 428
      */
429
-    public function getSosaCount(){
430
-        if(!$this->is_setup) return 0;
429
+    public function getSosaCount() {
430
+        if (!$this->is_setup) return 0;
431 431
         return Database::prepare(
432
-            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
432
+            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`'.
433 433
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
434 434
             ->execute(array(
435 435
                 'tree_id' => $this->tree->getTreeId(), 
@@ -443,10 +443,10 @@  discard block
 block discarded – undo
443 443
      * @param number $gen Generation
444 444
      * @return number Number of Sosas in generation
445 445
      */
446
-    public function getSosaCountAtGeneration($gen){
447
-        if(!$this->is_setup) return 0;
446
+    public function getSosaCountAtGeneration($gen) {
447
+        if (!$this->is_setup) return 0;
448 448
         return Database::prepare(
449
-            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
449
+            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`'.
450 450
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
451 451
             ' AND majs_gen= :gen')
452 452
         ->execute(array(
@@ -462,10 +462,10 @@  discard block
 block discarded – undo
462 462
      * @param number $gen Generation
463 463
      * @return number Total number of Sosas up to generation
464 464
      */
465
-    public function getSosaCountUpToGeneration($gen){
466
-        if(!$this->is_setup) return 0;
465
+    public function getSosaCountUpToGeneration($gen) {
466
+        if (!$this->is_setup) return 0;
467 467
         return Database::prepare(
468
-            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
468
+            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`'.
469 469
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
470 470
             ' AND majs_gen <= :gen')
471 471
         ->execute(array(
@@ -480,10 +480,10 @@  discard block
 block discarded – undo
480 480
      *
481 481
      * @return number Total number of distinct individual
482 482
      */
483
-    public function getDifferentSosaCount(){
484
-        if(!$this->is_setup) return 0;
483
+    public function getDifferentSosaCount() {
484
+        if (!$this->is_setup) return 0;
485 485
         return Database::prepare(
486
-            'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
486
+            'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`'.
487 487
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
488 488
         ->execute(array(
489 489
                 'tree_id' => $this->tree->getTreeId(), 
@@ -497,10 +497,10 @@  discard block
 block discarded – undo
497 497
      * @param number $gen Generation
498 498
      * @return number Number of distinct Sosa individuals up to generation
499 499
      */
500
-    public function getDifferentSosaCountUpToGeneration($gen){
501
-        if(!$this->is_setup) return 0;
500
+    public function getDifferentSosaCountUpToGeneration($gen) {
501
+        if (!$this->is_setup) return 0;
502 502
         return Database::prepare(
503
-            'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
503
+            'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`'.
504 504
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
505 505
             ' AND majs_gen <= :gen')
506 506
         ->execute(array(
@@ -520,11 +520,11 @@  discard block
 block discarded – undo
520 520
      * @param number $gen Generation
521 521
      * @return array Birth statistics array
522 522
      */
523
-    public function getStatsBirthYearInGeneration($gen){
524
-        if(!$this->is_setup) return array('first' => 0, 'avg' => 0, 'last' => 0);
523
+    public function getStatsBirthYearInGeneration($gen) {
524
+        if (!$this->is_setup) return array('first' => 0, 'avg' => 0, 'last' => 0);
525 525
         return Database::prepare(
526 526
             'SELECT MIN(majs_birth_year) AS first, AVG(majs_birth_year) AS avg, MAX(majs_birth_year) AS last'.
527
-            ' FROM `##maj_sosa`' .
527
+            ' FROM `##maj_sosa`'.
528 528
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
529 529
             ' AND majs_gen=:gen AND NOT majs_birth_year = :birth_year')
530 530
             ->execute(array(
@@ -540,26 +540,26 @@  discard block
 block discarded – undo
540 540
      *
541 541
      * @return number|NULL Mean generation time
542 542
      */
543
-    public function getMeanGenerationTime(){
544
-        if(!$this->is_setup) return;
545
-        if(!$this->statistics_tab){
543
+    public function getMeanGenerationTime() {
544
+        if (!$this->is_setup) return;
545
+        if (!$this->statistics_tab) {
546 546
             $this->getStatisticsByGeneration();
547 547
         }
548 548
         //Linear regression on x=generation and y=birthdate
549 549
         $sum_xy = 0;
550
-        $sum_x=0;
551
-        $sum_y=0;
552
-        $sum_x2=0;
553
-        $n=count($this->statistics_tab);
554
-        foreach($this->statistics_tab as $gen=>$stats){
555
-            $sum_xy+=$gen*$stats['avgBirth'];
556
-            $sum_x+=$gen;
557
-            $sum_y+=$stats['avgBirth'];
558
-            $sum_x2+=$gen*$gen;
550
+        $sum_x = 0;
551
+        $sum_y = 0;
552
+        $sum_x2 = 0;
553
+        $n = count($this->statistics_tab);
554
+        foreach ($this->statistics_tab as $gen=>$stats) {
555
+            $sum_xy += $gen * $stats['avgBirth'];
556
+            $sum_x += $gen;
557
+            $sum_y += $stats['avgBirth'];
558
+            $sum_x2 += $gen * $gen;
559 559
         }
560
-        $denom=($n*$sum_x2)-($sum_x*$sum_x);
561
-        if($denom!=0){
562
-            return -(($n*$sum_xy)-($sum_x*$sum_y))/($denom);
560
+        $denom = ($n * $sum_x2) - ($sum_x * $sum_x);
561
+        if ($denom != 0) {
562
+            return -(($n * $sum_xy) - ($sum_x * $sum_y)) / ($denom);
563 563
         }
564 564
         return null;
565 565
     }
@@ -587,14 +587,14 @@  discard block
 block discarded – undo
587 587
      * @return array
588 588
      */
589 589
     public function getAncestorDispersionForGen($gen) {
590
-        if(!$this->is_setup || $gen > 11) return array();  // Going further than 11 gen will be out of range in the query
590
+        if (!$this->is_setup || $gen > 11) return array(); // Going further than 11 gen will be out of range in the query
591 591
         return Database::prepare(
592 592
             'SELECT branches, count(i_id)'.
593 593
             ' FROM ('.
594 594
             '   SELECT i_id,'.
595 595
             '       CASE'.
596 596
             '           WHEN CEIL(LOG2(SUM(branch))) = LOG2(SUM(branch)) THEN SUM(branch)'.
597
-            '           ELSE -1'.   // We put all ancestors shared between some branches in the same bucket
597
+            '           ELSE -1'.// We put all ancestors shared between some branches in the same bucket
598 598
             '       END branches'.
599 599
             '   FROM ('.
600 600
             '       SELECT DISTINCT majs_i_id i_id,'.
Please login to merge, or discard this patch.
src/Webtrees/Functions/Functions.php 2 patches
Spacing   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -38,9 +38,9 @@  discard block
 block discarded – undo
38 38
 	 *
39 39
 	 * @param string $text Text to display
40 40
 	 */
41
-	static public function promptAlert($text){
41
+	static public function promptAlert($text) {
42 42
 		echo '<script>';
43
-		echo 'alert("',fw\Filter::escapeHtml($text),'")';
43
+		echo 'alert("', fw\Filter::escapeHtml($text), '")';
44 44
 		echo '</script>';
45 45
 	}
46 46
 	
@@ -53,7 +53,7 @@  discard block
 block discarded – undo
53 53
 	 * @return float Result of the safe division
54 54
 	 */
55 55
 	public static function safeDivision($num, $denom, $default = 0) {
56
-		if($denom && $denom!=0){
56
+		if ($denom && $denom != 0) {
57 57
 			return $num / $denom;
58 58
 		}
59 59
 		return $default;
@@ -67,7 +67,7 @@  discard block
 block discarded – undo
67 67
 	 * @param float $default Default value if denominator null or 0
68 68
 	 * @return float Percentage
69 69
 	 */
70
-	public static function getPercentage($num, $denom, $default = 0){
70
+	public static function getPercentage($num, $denom, $default = 0) {
71 71
 		return 100 * self::safeDivision($num, $denom, $default);
72 72
 	}
73 73
 	
@@ -78,8 +78,8 @@  discard block
 block discarded – undo
78 78
 	 * @param int $target	The final max width/height
79 79
 	 * @return array array of ($width, $height). One of them must be $target
80 80
 	 */
81
-	static public function getResizedImageSize($file, $target=25){
82
-		list($width, $height, , ) = getimagesize($file);
81
+	static public function getResizedImageSize($file, $target = 25) {
82
+		list($width, $height,,) = getimagesize($file);
83 83
 		$max = max($width, $height);
84 84
 		$rapp = $target / $max;
85 85
 		$width = intval($rapp * $width);
@@ -109,21 +109,21 @@  discard block
 block discarded – undo
109 109
 	 * @param int $length Length of the token, default to 32
110 110
 	 * @return string Random token
111 111
 	 */
112
-	public static function generateRandomToken($length=32) {
112
+	public static function generateRandomToken($length = 32) {
113 113
 		$chars = str_split('abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
114 114
 		$len_chars = count($chars);
115 115
 		$token = '';
116 116
 		
117 117
 		for ($i = 0; $i < $length; $i++)
118
-			$token .= $chars[ mt_rand(0, $len_chars - 1) ];
118
+			$token .= $chars[mt_rand(0, $len_chars - 1)];
119 119
 		
120 120
 		# Number of 32 char chunks
121
-		$chunks = ceil( strlen($token) / 32 );
121
+		$chunks = ceil(strlen($token) / 32);
122 122
 		$md5token = '';
123 123
 		
124 124
 		# Run each chunk through md5
125
-		for ( $i=1; $i<=$chunks; $i++ )
126
-			$md5token .= md5( substr($token, $i * 32 - 32, 32) );
125
+		for ($i = 1; $i <= $chunks; $i++)
126
+			$md5token .= md5(substr($token, $i * 32 - 32, 32));
127 127
 		
128 128
 			# Trim the token
129 129
 		return substr($md5token, 0, $length);		
@@ -145,15 +145,15 @@  discard block
 block discarded – undo
145 145
 	 * @param string $data Text to encrypt
146 146
 	 * @return string Encrypted and encoded text
147 147
 	 */
148
-	public static function encryptToSafeBase64($data){
149
-	    if(!self::isEncryptionCompatible())
148
+	public static function encryptToSafeBase64($data) {
149
+	    if (!self::isEncryptionCompatible())
150 150
 	        throw new \Exception('MCrypt PHP extension is required to use encryption.');
151 151
 	    
152 152
 		$key = 'STANDARDKEYIFNOSERVER';
153
-		if(!empty(Filter::server('SERVER_NAME')) && !empty(Filter::server('SERVER_SOFTWARE')))
153
+		if (!empty(Filter::server('SERVER_NAME')) && !empty(Filter::server('SERVER_SOFTWARE')))
154 154
 			$key = md5(Filter::server('SERVER_NAME').Filter::server('SERVER_SOFTWARE'));
155 155
 		$iv = mcrypt_create_iv(self::ENCRYPTION_IV_SIZE, MCRYPT_RAND);
156
-		$id = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC,$iv);
156
+		$id = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv);
157 157
 		$encrypted = base64_encode($iv.$id);
158 158
 		// +, / and = are not URL-compatible
159 159
 		$encrypted = str_replace('+', '-', $encrypted);
@@ -168,25 +168,25 @@  discard block
 block discarded – undo
168 168
 	 * @param string $encrypted Text to decrypt
169 169
 	 * @return string Decrypted text
170 170
 	 */
171
-	public static function decryptFromSafeBase64($encrypted){
172
-	    if(!self::isEncryptionCompatible())
171
+	public static function decryptFromSafeBase64($encrypted) {
172
+	    if (!self::isEncryptionCompatible())
173 173
 	        throw new \Exception('MCrypt PHP extension is required to use encryption.');
174 174
 	    
175 175
 		$key = 'STANDARDKEYIFNOSERVER';
176
-		if(!empty(Filter::server('SERVER_NAME')) && !empty(Filter::server('SERVER_SOFTWARE')))
176
+		if (!empty(Filter::server('SERVER_NAME')) && !empty(Filter::server('SERVER_SOFTWARE')))
177 177
 			$key = md5(Filter::server('SERVER_NAME').Filter::server('SERVER_SOFTWARE'));
178 178
 		$encrypted = str_replace('-', '+', $encrypted);
179 179
 		$encrypted = str_replace('_', '/', $encrypted);
180 180
 		$encrypted = str_replace('*', '=', $encrypted);
181 181
 		$encrypted = base64_decode($encrypted);
182
-		if(!$encrypted)
182
+		if (!$encrypted)
183 183
 			throw new \InvalidArgumentException('The encrypted value is not in correct base64 format.');
184
-		if(strlen($encrypted) < self::ENCRYPTION_IV_SIZE) 
184
+		if (strlen($encrypted) < self::ENCRYPTION_IV_SIZE) 
185 185
 			throw new \InvalidArgumentException('The encrypted value does not contain enough characters for the key.');
186 186
 		$iv_dec = substr($encrypted, 0, self::ENCRYPTION_IV_SIZE);
187 187
 		$encrypted = substr($encrypted, self::ENCRYPTION_IV_SIZE);
188 188
 		$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $encrypted, MCRYPT_MODE_CBC, $iv_dec);
189
-		return  preg_replace('~(?:\\000+)$~','',$decrypted);
189
+		return  preg_replace('~(?:\\000+)$~', '', $decrypted);
190 190
 	}
191 191
 	
192 192
 	/**
@@ -195,9 +195,9 @@  discard block
 block discarded – undo
195 195
 	 * @param string $string Filesystem encoded string to encode
196 196
 	 * @return string UTF-8 encoded string
197 197
 	 */
198
-	public static function encodeFileSystemToUtf8($string){
198
+	public static function encodeFileSystemToUtf8($string) {
199 199
 		if (strtoupper(substr(php_uname('s'), 0, 7)) === 'WINDOWS') {
200
-		    return iconv('cp1252', 'utf-8//IGNORE',$string);
200
+		    return iconv('cp1252', 'utf-8//IGNORE', $string);
201 201
 		}
202 202
 		return $string;
203 203
 	}
@@ -208,9 +208,9 @@  discard block
 block discarded – undo
208 208
 	 * @param string $string UTF-8 encoded string to encode
209 209
 	 * @return string Filesystem encoded string
210 210
 	 */
211
-	public static function encodeUtf8ToFileSystem($string){
211
+	public static function encodeUtf8ToFileSystem($string) {
212 212
 		if (preg_match('//u', $string) && strtoupper(substr(php_uname('s'), 0, 7)) === 'WINDOWS') {
213
-			return iconv('utf-8', 'cp1252//IGNORE' ,  $string);
213
+			return iconv('utf-8', 'cp1252//IGNORE', $string);
214 214
 		}
215 215
 		return $string;
216 216
 	}
@@ -223,7 +223,7 @@  discard block
 block discarded – undo
223 223
 	 * @return boolean True if path valid
224 224
 	 */
225 225
 	public static function isValidPath($filename, $acceptfolder = FALSE) {		
226
-		if(strpbrk($filename, $acceptfolder ? '?%*:|"<>' : '\\/?%*:|"<>') === FALSE) return true;
226
+		if (strpbrk($filename, $acceptfolder ? '?%*:|"<>' : '\\/?%*:|"<>') === FALSE) return true;
227 227
 		return false;
228 228
 	}
229 229
 	
@@ -235,7 +235,7 @@  discard block
 block discarded – undo
235 235
 	 * @return array Array of month short names
236 236
 	 */
237 237
 	public static function getCalendarShortMonths($calendarId = 0) {
238
-		if(!isset(self::$calendarShortMonths[$calendarId])) {
238
+		if (!isset(self::$calendarShortMonths[$calendarId])) {
239 239
 			$calendar_info = cal_info($calendarId);
240 240
 			self::$calendarShortMonths[$calendarId] = $calendar_info['abbrevmonths'];
241 241
 		}		
@@ -248,8 +248,8 @@  discard block
 block discarded – undo
248 248
 	 * @param int $sosa Sosa number
249 249
 	 * @return number
250 250
 	 */
251
-	public static function getGeneration($sosa){
252
-		return(int)log($sosa, 2)+1;
251
+	public static function getGeneration($sosa) {
252
+		return(int)log($sosa, 2) + 1;
253 253
 	}
254 254
 	
255 255
 	
Please login to merge, or discard this patch.
Braces   +27 added lines, -17 removed lines patch added patch discarded remove patch
@@ -114,16 +114,18 @@  discard block
 block discarded – undo
114 114
 		$len_chars = count($chars);
115 115
 		$token = '';
116 116
 		
117
-		for ($i = 0; $i < $length; $i++)
118
-			$token .= $chars[ mt_rand(0, $len_chars - 1) ];
117
+		for ($i = 0; $i < $length; $i++) {
118
+					$token .= $chars[ mt_rand(0, $len_chars - 1) ];
119
+		}
119 120
 		
120 121
 		# Number of 32 char chunks
121 122
 		$chunks = ceil( strlen($token) / 32 );
122 123
 		$md5token = '';
123 124
 		
124 125
 		# Run each chunk through md5
125
-		for ( $i=1; $i<=$chunks; $i++ )
126
-			$md5token .= md5( substr($token, $i * 32 - 32, 32) );
126
+		for ( $i=1; $i<=$chunks; $i++ ) {
127
+					$md5token .= md5( substr($token, $i * 32 - 32, 32) );
128
+		}
127 129
 		
128 130
 			# Trim the token
129 131
 		return substr($md5token, 0, $length);		
@@ -146,12 +148,14 @@  discard block
 block discarded – undo
146 148
 	 * @return string Encrypted and encoded text
147 149
 	 */
148 150
 	public static function encryptToSafeBase64($data){
149
-	    if(!self::isEncryptionCompatible())
150
-	        throw new \Exception('MCrypt PHP extension is required to use encryption.');
151
+	    if(!self::isEncryptionCompatible()) {
152
+	    	        throw new \Exception('MCrypt PHP extension is required to use encryption.');
153
+	    }
151 154
 	    
152 155
 		$key = 'STANDARDKEYIFNOSERVER';
153
-		if(!empty(Filter::server('SERVER_NAME')) && !empty(Filter::server('SERVER_SOFTWARE')))
154
-			$key = md5(Filter::server('SERVER_NAME').Filter::server('SERVER_SOFTWARE'));
156
+		if(!empty(Filter::server('SERVER_NAME')) && !empty(Filter::server('SERVER_SOFTWARE'))) {
157
+					$key = md5(Filter::server('SERVER_NAME').Filter::server('SERVER_SOFTWARE'));
158
+		}
155 159
 		$iv = mcrypt_create_iv(self::ENCRYPTION_IV_SIZE, MCRYPT_RAND);
156 160
 		$id = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC,$iv);
157 161
 		$encrypted = base64_encode($iv.$id);
@@ -169,20 +173,24 @@  discard block
 block discarded – undo
169 173
 	 * @return string Decrypted text
170 174
 	 */
171 175
 	public static function decryptFromSafeBase64($encrypted){
172
-	    if(!self::isEncryptionCompatible())
173
-	        throw new \Exception('MCrypt PHP extension is required to use encryption.');
176
+	    if(!self::isEncryptionCompatible()) {
177
+	    	        throw new \Exception('MCrypt PHP extension is required to use encryption.');
178
+	    }
174 179
 	    
175 180
 		$key = 'STANDARDKEYIFNOSERVER';
176
-		if(!empty(Filter::server('SERVER_NAME')) && !empty(Filter::server('SERVER_SOFTWARE')))
177
-			$key = md5(Filter::server('SERVER_NAME').Filter::server('SERVER_SOFTWARE'));
181
+		if(!empty(Filter::server('SERVER_NAME')) && !empty(Filter::server('SERVER_SOFTWARE'))) {
182
+					$key = md5(Filter::server('SERVER_NAME').Filter::server('SERVER_SOFTWARE'));
183
+		}
178 184
 		$encrypted = str_replace('-', '+', $encrypted);
179 185
 		$encrypted = str_replace('_', '/', $encrypted);
180 186
 		$encrypted = str_replace('*', '=', $encrypted);
181 187
 		$encrypted = base64_decode($encrypted);
182
-		if(!$encrypted)
183
-			throw new \InvalidArgumentException('The encrypted value is not in correct base64 format.');
184
-		if(strlen($encrypted) < self::ENCRYPTION_IV_SIZE) 
185
-			throw new \InvalidArgumentException('The encrypted value does not contain enough characters for the key.');
188
+		if(!$encrypted) {
189
+					throw new \InvalidArgumentException('The encrypted value is not in correct base64 format.');
190
+		}
191
+		if(strlen($encrypted) < self::ENCRYPTION_IV_SIZE) {
192
+					throw new \InvalidArgumentException('The encrypted value does not contain enough characters for the key.');
193
+		}
186 194
 		$iv_dec = substr($encrypted, 0, self::ENCRYPTION_IV_SIZE);
187 195
 		$encrypted = substr($encrypted, self::ENCRYPTION_IV_SIZE);
188 196
 		$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $encrypted, MCRYPT_MODE_CBC, $iv_dec);
@@ -223,7 +231,9 @@  discard block
 block discarded – undo
223 231
 	 * @return boolean True if path valid
224 232
 	 */
225 233
 	public static function isValidPath($filename, $acceptfolder = FALSE) {		
226
-		if(strpbrk($filename, $acceptfolder ? '?%*:|"<>' : '\\/?%*:|"<>') === FALSE) return true;
234
+		if(strpbrk($filename, $acceptfolder ? '?%*:|"<>' : '\\/?%*:|"<>') === FALSE) {
235
+			return true;
236
+		}
227 237
 		return false;
228 238
 	}
229 239
 	
Please login to merge, or discard this patch.