Completed
Push — master ( 94717f...b0ff97 )
by Jonathan
06:05
created
src/Webtrees/Functions/FunctionsPrint.php 2 patches
Spacing   +42 added lines, -42 removed lines patch added patch discarded remove patch
@@ -32,7 +32,7 @@  discard block
 block discarded – undo
32 32
 	 * @return string List of elements
33 33
 	 */
34 34
 	public static function getListFromArray(array $array) {
35
-		$n=count($array);
35
+		$n = count($array);
36 36
 		switch ($n) {
37 37
 			case 0:
38 38
 				return '';
@@ -41,10 +41,10 @@  discard block
 block discarded – undo
41 41
 			default:
42 42
 				return implode(
43 43
 						/* I18N: list separator */ I18N::translate(', '), 
44
-						array_slice($array, 0, $n-1)
45
-					) .
46
-					/* I18N: last list separator, " and " in English, " et " in French  */ I18N::translate(' and ') . 
47
-					$array[$n-1];
44
+						array_slice($array, 0, $n - 1)
45
+					).
46
+					/* I18N: last list separator, " and " in English, " et " in French  */ I18N::translate(' and '). 
47
+					$array[$n - 1];
48 48
 		}
49 49
 	}
50 50
 
@@ -60,10 +60,10 @@  discard block
 block discarded – undo
60 60
 			\MyArtJaub\Webtrees\Map\MapProviderInterface $mapProvider
61 61
 	) {
62 62
 		$place = $fact->getPlace();
63
-		if(!$place->isEmpty()) {
64
-			$iconPlace= $mapProvider->getPlaceIcon($place);	
65
-			if($iconPlace && strlen($iconPlace) > 0){
66
-				return	'<div class="fact_flag">'. self::htmlPlaceIcon($place, $iconPlace, 50). '</div>';
63
+		if (!$place->isEmpty()) {
64
+			$iconPlace = $mapProvider->getPlaceIcon($place);	
65
+			if ($iconPlace && strlen($iconPlace) > 0) {
66
+				return	'<div class="fact_flag">'.self::htmlPlaceIcon($place, $iconPlace, 50).'</div>';
67 67
 			}
68 68
 		}
69 69
 		return '';
@@ -77,8 +77,8 @@  discard block
 block discarded – undo
77 77
 	 * @param number $size
78 78
 	 * @return string HTML code of the inserted flag
79 79
 	 */
80
-	public static function htmlPlaceIcon(\Fisharebest\Webtrees\Place $place, $icon_path , $size = 50) {
81
-	    return '<img class="flag_gm_h'. $size . '" src="' . $icon_path . '" title="' . $place->getGedcomName() . '" alt="' . $place->getGedcomName() . '" />';
80
+	public static function htmlPlaceIcon(\Fisharebest\Webtrees\Place $place, $icon_path, $size = 50) {
81
+	    return '<img class="flag_gm_h'.$size.'" src="'.$icon_path.'" title="'.$place->getGedcomName().'" alt="'.$place->getGedcomName().'" />';
82 82
 	}
83 83
 	
84 84
 	/**
@@ -96,7 +96,7 @@  discard block
 block discarded – undo
96 96
 		$minimum = PHP_INT_MAX;
97 97
 		$maximum = 1;
98 98
 		foreach ($list as $params) {
99
-			if(array_key_exists('count', $params)) {
99
+			if (array_key_exists('count', $params)) {
100 100
 				$maximum = max($maximum, $params['count']);
101 101
 				$minimum = min($minimum, $params['count']);
102 102
 			}
@@ -114,15 +114,15 @@  discard block
 block discarded – undo
114 114
 				$size = 75.0 + 125.0 * ($count - $minimum) / ($maximum - $minimum);
115 115
 			}
116 116
 			
117
-			$html .= '<a style="font-size:' . $size . '%" href="' . $url . '">';
117
+			$html .= '<a style="font-size:'.$size.'%" href="'.$url.'">';
118 118
 			if ($totals) {
119
-				$html .= I18N::translate('%1$s (%2$s)', '<span dir="auto">' . $text . '</span>', I18N::number($count));
119
+				$html .= I18N::translate('%1$s (%2$s)', '<span dir="auto">'.$text.'</span>', I18N::number($count));
120 120
 			} else {
121 121
 				$html .= $text;
122 122
 			}
123 123
 			$html .= '</a>';
124 124
 		}
125
-		return '<div class="tag_cloud">' . $html . '</div>';
125
+		return '<div class="tag_cloud">'.$html.'</div>';
126 126
 	}
127 127
 	
128 128
 
@@ -157,11 +157,11 @@  discard block
 block discarded – undo
157 157
 	 * @param bool $isStrong Bolden the name ?
158 158
 	 * @return string HTML Code for individual item
159 159
 	 */
160
-	public static function htmlIndividualForList(\Fisharebest\Webtrees\Individual $individual, $isStrong = true){
160
+	public static function htmlIndividualForList(\Fisharebest\Webtrees\Individual $individual, $isStrong = true) {
161 161
 		$html = '';
162 162
 		$tag = 'em';
163
-		if($isStrong) $tag = 'strong';
164
-		if($individual && $individual->canShow()){
163
+		if ($isStrong) $tag = 'strong';
164
+		if ($individual && $individual->canShow()) {
165 165
 			$dindi = new Individual($individual);
166 166
 			$html = $individual->getSexImage();
167 167
 			$html .= '<a class="list_item" href="'.
@@ -176,7 +176,7 @@  discard block
 block discarded – undo
176 176
 			$html .= '</a>';
177 177
 		}
178 178
 		else {
179
-			$html .= '<span class=\"list_item\"><'.$tag.'>' . I18N::translate('Private') . '</'.$tag.'></span>';
179
+			$html .= '<span class=\"list_item\"><'.$tag.'>'.I18N::translate('Private').'</'.$tag.'></span>';
180 180
 		}
181 181
 		return $html;
182 182
 	}
@@ -188,20 +188,20 @@  discard block
 block discarded – undo
188 188
 	 * @param boolean $anchor option to print a link to calendar
189 189
 	 * @return string HTML code for short date
190 190
 	 */
191
-	public static function formatFactDateShort(\Fisharebest\Webtrees\Fact $fact, $anchor=false) {
192
-		$html='';
191
+	public static function formatFactDateShort(\Fisharebest\Webtrees\Fact $fact, $anchor = false) {
192
+		$html = '';
193 193
 		$date = $fact->getDate();
194
-		if($date->isOK()){
195
-			$html.=' '.$date->Display($anchor && !Globals::isSearchSpider(), '%Y');
194
+		if ($date->isOK()) {
195
+			$html .= ' '.$date->Display($anchor && !Globals::isSearchSpider(), '%Y');
196 196
 		}
197
-		else{
197
+		else {
198 198
 			// 1 DEAT Y with no DATE => print YES
199 199
 			// 1 BIRT 2 SOUR @S1@ => print YES
200 200
 			// 1 DEAT N is not allowed
201 201
 			// It is not proper GEDCOM form to use a N(o) value with an event tag to infer that it did not happen.
202 202
 			$factdetail = explode(' ', trim($fact->getGedcom()));
203 203
 			if (isset($factdetail) && (count($factdetail) == 3 && strtoupper($factdetail[2]) == 'Y') || (count($factdetail) == 4 && $factdetail[2] == 'SOUR')) {
204
-				$html.=I18N::translate('yes');
204
+				$html .= I18N::translate('yes');
205 205
 			}
206 206
 		}
207 207
 		return $html;
@@ -215,12 +215,12 @@  discard block
 block discarded – undo
215 215
 	 * @param boolean $anchor option to print a link to placelist
216 216
 	 * @return string HTML code for short place
217 217
 	 */
218
-	public static function formatFactPlaceShort(\Fisharebest\Webtrees\Fact $fact, $format, $anchor=false){
219
-		$html='';
218
+	public static function formatFactPlaceShort(\Fisharebest\Webtrees\Fact $fact, $format, $anchor = false) {
219
+		$html = '';
220 220
 		
221 221
 		if ($fact === null) return $html;
222 222
 		$place = $fact->getPlace();
223
-		if($place){
223
+		if ($place) {
224 224
 			$dplace = new Place($place);
225 225
 			$html .= $dplace->htmlFormattedName($format, $anchor);
226 226
 		}
@@ -238,21 +238,21 @@  discard block
 block discarded – undo
238 238
 	 * @param string $size CSS size for the icon. A CSS style css_$size is required
239 239
 	 * @return string HTML code for the formatted Sosa numbers
240 240
 	 */
241
-	public static function formatSosaNumbers(array $sosatab, $format = 1, $size = 'small'){
241
+	public static function formatSosaNumbers(array $sosatab, $format = 1, $size = 'small') {
242 242
 		$html = '';
243
-		switch($format){
243
+		switch ($format) {
244 244
 			case 1:
245
-				if(count($sosatab)>0){
245
+				if (count($sosatab) > 0) {
246 246
 					$html = '<i class="icon-maj-sosa_'.$size.'" title="'.I18N::translate('Sosa').'"></i>';
247 247
 				}
248 248
 				break;
249 249
 			case 2:
250
-				if(count($sosatab)>0){
250
+				if (count($sosatab) > 0) {
251 251
 					ksort($sosatab);
252 252
 					$tmp_html = array();
253 253
 					foreach ($sosatab as $sosa => $gen) {
254 254
 						$tmp_html[] = sprintf(
255
-								'<i class="icon-maj-sosa_%1$s" title="'.I18N::translate('Sosa').'"></i>&nbsp;<strong>%2$d&nbsp;'.I18N::translate('(G%s)', $gen) .'</strong>',
255
+								'<i class="icon-maj-sosa_%1$s" title="'.I18N::translate('Sosa').'"></i>&nbsp;<strong>%2$d&nbsp;'.I18N::translate('(G%s)', $gen).'</strong>',
256 256
 								$size,
257 257
 								$sosa
258 258
 							);
@@ -278,15 +278,15 @@  discard block
 block discarded – undo
278 278
 	 * @param string $size CSS size for the icon. A CSS style css_$size is required
279 279
 	 * @return string HTML code for IsSourced icon
280 280
 	 */
281
-	public static function formatIsSourcedIcon($sourceType, $isSourced, $tag='EVEN', $format = 1, $size='normal'){
282
-		$html='';
283
-		$image=null;
284
-		$title=null;
285
-		switch($format){
281
+	public static function formatIsSourcedIcon($sourceType, $isSourced, $tag = 'EVEN', $format = 1, $size = 'normal') {
282
+		$html = '';
283
+		$image = null;
284
+		$title = null;
285
+		switch ($format) {
286 286
 			case 1:
287
-				switch($sourceType){
287
+				switch ($sourceType) {
288 288
 					case 'E':
289
-						switch($isSourced){
289
+						switch ($isSourced) {
290 290
 							case 0:
291 291
 								$image = 'event_unknown';
292 292
 								$title = I18N::translate('%s not found', GedcomTag::getLabel($tag));
@@ -316,7 +316,7 @@  discard block
 block discarded – undo
316 316
 						}
317 317
 						break;
318 318
 					case 'R':
319
-						switch($isSourced){
319
+						switch ($isSourced) {
320 320
 							case -1:
321 321
 								$image = 'record_notsourced';
322 322
 								$title = I18N::translate('%s not sourced', GedcomTag::getLabel($tag));
@@ -336,7 +336,7 @@  discard block
 block discarded – undo
336 336
 					default:
337 337
 						break;
338 338
 				}
339
-				if($image && $title) $html = '<i class="icon-maj-sourced-'.$size.'_'.$image.'" title="'.$title.'"></i>';
339
+				if ($image && $title) $html = '<i class="icon-maj-sourced-'.$size.'_'.$image.'" title="'.$title.'"></i>';
340 340
 				break;
341 341
 			default:
342 342
 				break;
Please login to merge, or discard this patch.
Braces   +11 added lines, -7 removed lines patch added patch discarded remove patch
@@ -160,7 +160,9 @@  discard block
 block discarded – undo
160 160
 	public static function htmlIndividualForList(\Fisharebest\Webtrees\Individual $individual, $isStrong = true){
161 161
 		$html = '';
162 162
 		$tag = 'em';
163
-		if($isStrong) $tag = 'strong';
163
+		if($isStrong) {
164
+			$tag = 'strong';
165
+		}
164 166
 		if($individual && $individual->canShow()){
165 167
 			$dindi = new Individual($individual);
166 168
 			$html = $individual->getSexImage();
@@ -174,8 +176,7 @@  discard block
 block discarded – undo
174 176
 			$html .= '&nbsp;<span><small><em>'.$dindi->formatFirstMajorFact(WT_EVENTS_BIRT, 10).'</em></small></span>';
175 177
 			$html .= '&nbsp;<span><small><em>'.$dindi->formatFirstMajorFact(WT_EVENTS_DEAT, 10).'</em></small></span>';
176 178
 			$html .= '</a>';
177
-		}
178
-		else {
179
+		} else {
179 180
 			$html .= '<span class=\"list_item\"><'.$tag.'>' . I18N::translate('Private') . '</'.$tag.'></span>';
180 181
 		}
181 182
 		return $html;
@@ -193,8 +194,7 @@  discard block
 block discarded – undo
193 194
 		$date = $fact->getDate();
194 195
 		if($date->isOK()){
195 196
 			$html.=' '.$date->Display($anchor && !Globals::isSearchSpider(), '%Y');
196
-		}
197
-		else{
197
+		} else{
198 198
 			// 1 DEAT Y with no DATE => print YES
199 199
 			// 1 BIRT 2 SOUR @S1@ => print YES
200 200
 			// 1 DEAT N is not allowed
@@ -218,7 +218,9 @@  discard block
 block discarded – undo
218 218
 	public static function formatFactPlaceShort(\Fisharebest\Webtrees\Fact $fact, $format, $anchor=false){
219 219
 		$html='';
220 220
 		
221
-		if ($fact === null) return $html;
221
+		if ($fact === null) {
222
+			return $html;
223
+		}
222 224
 		$place = $fact->getPlace();
223 225
 		if($place){
224 226
 			$dplace = new Place($place);
@@ -336,7 +338,9 @@  discard block
 block discarded – undo
336 338
 					default:
337 339
 						break;
338 340
 				}
339
-				if($image && $title) $html = '<i class="icon-maj-sourced-'.$size.'_'.$image.'" title="'.$title.'"></i>';
341
+				if($image && $title) {
342
+					$html = '<i class="icon-maj-sourced-'.$size.'_'.$image.'" title="'.$title.'"></i>';
343
+				}
340 344
 				break;
341 345
 			default:
342 346
 				break;
Please login to merge, or discard this patch.
src/Webtrees/Module/Sosa/SosaListController.php 2 patches
Indentation   +270 added lines, -270 removed lines patch added patch discarded remove patch
@@ -37,67 +37,67 @@  discard block
 block discarded – undo
37 37
  */
38 38
 class SosaListController extends MvcController
39 39
 {
40
-    /**
41
-     * Sosa Provider for the controller
42
-     * @var SosaProvider $sosa_provider
43
-     */
44
-    protected $sosa_provider;
40
+	/**
41
+	 * Sosa Provider for the controller
42
+	 * @var SosaProvider $sosa_provider
43
+	 */
44
+	protected $sosa_provider;
45 45
     
46
-    /**
47
-     * Generation used for the controller
48
-     * @var int $generation
49
-     */
50
-    protected $generation;
46
+	/**
47
+	 * Generation used for the controller
48
+	 * @var int $generation
49
+	 */
50
+	protected $generation;
51 51
     
52
-    /**
53
-     * ViewBag to hold data for the controller
54
-     * @var ViewBag $view_bag
55
-     */
56
-    protected $view_bag;
52
+	/**
53
+	 * ViewBag to hold data for the controller
54
+	 * @var ViewBag $view_bag
55
+	 */
56
+	protected $view_bag;
57 57
     
58
-    /**
59
-     * {@inheritDoc}
60
-     * @see \MyArtJaub\Webtrees\Mvc\Controller\MvcController::__construct(AbstractModule $module)
61
-     */
62
-    public function __construct(AbstractModule $module) {
63
-        parent::__construct($module);
58
+	/**
59
+	 * {@inheritDoc}
60
+	 * @see \MyArtJaub\Webtrees\Mvc\Controller\MvcController::__construct(AbstractModule $module)
61
+	 */
62
+	public function __construct(AbstractModule $module) {
63
+		parent::__construct($module);
64 64
 
65
-        $this->sosa_provider = new SosaProvider(Globals::getTree(), Auth::user());
65
+		$this->sosa_provider = new SosaProvider(Globals::getTree(), Auth::user());
66 66
 
67
-        $this->generation = Filter::getInteger('gen');
67
+		$this->generation = Filter::getInteger('gen');
68 68
         
69
-        $this->view_bag = new ViewBag();
70
-        $this->view_bag->set('generation', $this->generation);
71
-        $this->view_bag->set('max_gen', $this->sosa_provider->getLastGeneration());
72
-        $this->view_bag->set('is_setup', $this->sosa_provider->isSetup() && $this->view_bag->get('max_gen', 0)> 0);
69
+		$this->view_bag = new ViewBag();
70
+		$this->view_bag->set('generation', $this->generation);
71
+		$this->view_bag->set('max_gen', $this->sosa_provider->getLastGeneration());
72
+		$this->view_bag->set('is_setup', $this->sosa_provider->isSetup() && $this->view_bag->get('max_gen', 0)> 0);
73 73
         
74
-    }
74
+	}
75 75
     
76 76
     
77
-    /**
78
-     * Pages
79
-     */
77
+	/**
78
+	 * Pages
79
+	 */
80 80
     
81
-    /**
82
-     * SosaList@index
83
-     */
84
-    public function index() {
85
-        $wt_tree = Globals::getTree();
86
-        $controller = new PageController();
87
-        $controller
88
-            ->setPageTitle(I18N::translate('Sosa Ancestors'));            
81
+	/**
82
+	 * SosaList@index
83
+	 */
84
+	public function index() {
85
+		$wt_tree = Globals::getTree();
86
+		$controller = new PageController();
87
+		$controller
88
+			->setPageTitle(I18N::translate('Sosa Ancestors'));            
89 89
 
90
-        $this->view_bag->set('title', $controller->getPageTitle());
90
+		$this->view_bag->set('title', $controller->getPageTitle());
91 91
         
92
-        if($this->view_bag->get('is_setup', false)) {
93
-            $this->view_bag->set('has_sosa', $this->generation > 0 && $this->sosa_provider->getSosaCountAtGeneration($this->generation) > 0);
94
-            $this->view_bag->set('url_module', $this->module->getName());
95
-            $this->view_bag->set('url_action', 'SosaList');
96
-            $this->view_bag->set('url_ged', $wt_tree->getNameUrl()); 
97
-            $this->view_bag->set('min_gen', 1);
92
+		if($this->view_bag->get('is_setup', false)) {
93
+			$this->view_bag->set('has_sosa', $this->generation > 0 && $this->sosa_provider->getSosaCountAtGeneration($this->generation) > 0);
94
+			$this->view_bag->set('url_module', $this->module->getName());
95
+			$this->view_bag->set('url_action', 'SosaList');
96
+			$this->view_bag->set('url_ged', $wt_tree->getNameUrl()); 
97
+			$this->view_bag->set('min_gen', 1);
98 98
             
99
-            if($this->view_bag->get('has_sosa', false)) {            
100
-                $controller->addInlineJavascript('
99
+			if($this->view_bag->get('has_sosa', false)) {            
100
+				$controller->addInlineJavascript('
101 101
             		jQuery("#sosalist-tabs").tabs();
102 102
             		jQuery("#sosalist-tabs").css("visibility", "visible");
103 103
                 
@@ -151,43 +151,43 @@  discard block
 block discarded – undo
151 151
             		);
152 152
                 
153 153
             	');            
154
-            }
155
-        }
154
+			}
155
+		}
156 156
                 
157
-        ViewFactory::make('SosaList', $this, $controller, $this->view_bag)->render();   
158
-    }    
157
+		ViewFactory::make('SosaList', $this, $controller, $this->view_bag)->render();   
158
+	}    
159 159
     
160 160
 
161
-    /**
162
-     * SosaList@missing
163
-     */
164
-    public function missing() {
165
-        $wt_tree = Globals::getTree();
166
-        $controller = new PageController();
167
-        $controller
168
-        ->setPageTitle(I18N::translate('Missing Ancestors'));
161
+	/**
162
+	 * SosaList@missing
163
+	 */
164
+	public function missing() {
165
+		$wt_tree = Globals::getTree();
166
+		$controller = new PageController();
167
+		$controller
168
+		->setPageTitle(I18N::translate('Missing Ancestors'));
169 169
         
170
-        $this->view_bag->set('title', $controller->getPageTitle());
170
+		$this->view_bag->set('title', $controller->getPageTitle());
171 171
         
172
-        if($this->view_bag->get('is_setup', false)) {
173
-            $this->view_bag->set('url_module', $this->module->getName());
174
-            $this->view_bag->set('url_action', 'SosaList@missing');
175
-            $this->view_bag->set('url_ged', $wt_tree->getNameUrl());
176
-            $this->view_bag->set('min_gen', 2);
172
+		if($this->view_bag->get('is_setup', false)) {
173
+			$this->view_bag->set('url_module', $this->module->getName());
174
+			$this->view_bag->set('url_action', 'SosaList@missing');
175
+			$this->view_bag->set('url_ged', $wt_tree->getNameUrl());
176
+			$this->view_bag->set('min_gen', 2);
177 177
             
178
-            $missing_list = $this->sosa_provider->getMissingSosaListAtGeneration($this->generation);
179
-            $this->view_bag->set('has_missing', $this->generation > 0 && count($missing_list) > 0);
178
+			$missing_list = $this->sosa_provider->getMissingSosaListAtGeneration($this->generation);
179
+			$this->view_bag->set('has_missing', $this->generation > 0 && count($missing_list) > 0);
180 180
             
181
-            $perc_sosa = Functions::safeDivision($this->sosa_provider->getSosaCountAtGeneration($this->generation), pow(2, $this->generation -1));
182
-            $this->view_bag->set('perc_sosa', $perc_sosa);
181
+			$perc_sosa = Functions::safeDivision($this->sosa_provider->getSosaCountAtGeneration($this->generation), pow(2, $this->generation -1));
182
+			$this->view_bag->set('perc_sosa', $perc_sosa);
183 183
             
184
-            if($this->view_bag->get('has_missing', false)) {
185
-                $table_id = 'table-sosa-missing-' . Uuid::uuid4();
186
-                $this->view_bag->set('table_id', $table_id);
184
+			if($this->view_bag->get('has_missing', false)) {
185
+				$table_id = 'table-sosa-missing-' . Uuid::uuid4();
186
+				$this->view_bag->set('table_id', $table_id);
187 187
                 
188
-                $controller
189
-                ->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)
190
-                ->addInlineJavascript('
188
+				$controller
189
+				->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)
190
+				->addInlineJavascript('
191 191
 				    jQuery.fn.dataTableExt.oSort["text-asc"] = textCompareAsc;
192 192
 				    jQuery.fn.dataTableExt.oSort["text-desc"] = textCompareDesc;
193 193
                     
@@ -239,76 +239,76 @@  discard block
 block discarded – undo
239 239
     				jQuery(".loading-image").css("display", "none");
240 240
     			');
241 241
                         
242
-                $unique_indis = array();
243
-                $sum_missing_different = 0;
244
-                $sum_missing_different_without_hidden = 0;
245
-                foreach($missing_list as $num => $missing_tab) {
246
-                    if(isset($unique_indis[$missing_tab['indi']])) {
247
-                        unset($missing_list[$num]);
248
-                        continue;
249
-                    }
250
-                    $sum_missing_different += !$missing_tab['has_father'] + !$missing_tab['has_mother'];
251
-                    $person = Individual::getInstance($missing_tab['indi'], $wt_tree);
252
-                    if (!$person || !$person->canShowName()) {
253
-                        unset($missing_list[$num]);
254
-                        continue;
255
-                    }  
256
-                    $sum_missing_different_without_hidden += !$missing_tab['has_father'] + !$missing_tab['has_mother'];
257
-                    $unique_indis[$person->getXref()] = true;
258
-                    $missing_tab['indi'] = $person;
259
-                    $missing_list[$num] = $missing_tab;
260
-                }
261
-                $this->view_bag->set('missing_list', $missing_list);
262
-                $this->view_bag->set('missing_diff_count', $sum_missing_different);
263
-                $this->view_bag->set('missing_hidden', $sum_missing_different - $sum_missing_different_without_hidden);
264
-                $perc_sosa_potential = Functions::safeDivision($this->sosa_provider->getSosaCountAtGeneration($this->generation - 1), pow(2, $this->generation-2));
265
-                $this->view_bag->set('perc_sosa_potential', $perc_sosa_potential);
266
-            }            
267
-        }
242
+				$unique_indis = array();
243
+				$sum_missing_different = 0;
244
+				$sum_missing_different_without_hidden = 0;
245
+				foreach($missing_list as $num => $missing_tab) {
246
+					if(isset($unique_indis[$missing_tab['indi']])) {
247
+						unset($missing_list[$num]);
248
+						continue;
249
+					}
250
+					$sum_missing_different += !$missing_tab['has_father'] + !$missing_tab['has_mother'];
251
+					$person = Individual::getInstance($missing_tab['indi'], $wt_tree);
252
+					if (!$person || !$person->canShowName()) {
253
+						unset($missing_list[$num]);
254
+						continue;
255
+					}  
256
+					$sum_missing_different_without_hidden += !$missing_tab['has_father'] + !$missing_tab['has_mother'];
257
+					$unique_indis[$person->getXref()] = true;
258
+					$missing_tab['indi'] = $person;
259
+					$missing_list[$num] = $missing_tab;
260
+				}
261
+				$this->view_bag->set('missing_list', $missing_list);
262
+				$this->view_bag->set('missing_diff_count', $sum_missing_different);
263
+				$this->view_bag->set('missing_hidden', $sum_missing_different - $sum_missing_different_without_hidden);
264
+				$perc_sosa_potential = Functions::safeDivision($this->sosa_provider->getSosaCountAtGeneration($this->generation - 1), pow(2, $this->generation-2));
265
+				$this->view_bag->set('perc_sosa_potential', $perc_sosa_potential);
266
+			}            
267
+		}
268 268
         
269
-        ViewFactory::make('SosaListMissing', $this, $controller, $this->view_bag)->render();
270
-    }
269
+		ViewFactory::make('SosaListMissing', $this, $controller, $this->view_bag)->render();
270
+	}
271 271
     
272
-    /**
273
-     * SosaList@sosalist
274
-     */
275
-    public function sosalist() {
272
+	/**
273
+	 * SosaList@sosalist
274
+	 */
275
+	public function sosalist() {
276 276
                 
277
-        $type = Filter::get('type', 'indi|fam', null);
277
+		$type = Filter::get('type', 'indi|fam', null);
278 278
         
279
-        $controller = new AjaxController();
280
-        $controller->restrictAccess($this->generation > 0 || !is_null($type));
279
+		$controller = new AjaxController();
280
+		$controller->restrictAccess($this->generation > 0 || !is_null($type));
281 281
         
282
-        switch ($type){
283
-            case 'indi':
284
-                $this->renderSosaListIndi($controller);
285
-                break;
286
-            case 'fam':
287
-                $this->renderFamSosaListIndi($controller);
288
-                break;
289
-            default:
290
-                break;
291
-        }
282
+		switch ($type){
283
+			case 'indi':
284
+				$this->renderSosaListIndi($controller);
285
+				break;
286
+			case 'fam':
287
+				$this->renderFamSosaListIndi($controller);
288
+				break;
289
+			default:
290
+				break;
291
+		}
292 292
 
293
-    }
293
+	}
294 294
     
295
-    /**
296
-     * Render the Ajax response for the sortable table of Sosa individuals
297
-     * @param AjaxController $controller
298
-     */
299
-    protected function renderSosaListIndi(AjaxController $controller) {
300
-        $wt_tree = Globals::getTree();
301
-        $listSosa = $this->sosa_provider->getSosaListAtGeneration($this->generation); 
302
-        $this->view_bag->set('has_sosa', false);
295
+	/**
296
+	 * Render the Ajax response for the sortable table of Sosa individuals
297
+	 * @param AjaxController $controller
298
+	 */
299
+	protected function renderSosaListIndi(AjaxController $controller) {
300
+		$wt_tree = Globals::getTree();
301
+		$listSosa = $this->sosa_provider->getSosaListAtGeneration($this->generation); 
302
+		$this->view_bag->set('has_sosa', false);
303 303
         
304
-        if(count($listSosa) > 0) {
305
-            $this->view_bag->set('has_sosa', true);
306
-            $table_id = 'table-sosa-indi-' . Uuid::uuid4();
307
-            $this->view_bag->set('table_id', $table_id);
304
+		if(count($listSosa) > 0) {
305
+			$this->view_bag->set('has_sosa', true);
306
+			$table_id = 'table-sosa-indi-' . Uuid::uuid4();
307
+			$this->view_bag->set('table_id', $table_id);
308 308
                      
309
-            $controller
310
-            ->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)
311
-            ->addInlineJavascript('
309
+			$controller
310
+			->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)
311
+			->addInlineJavascript('
312 312
                 jQuery.fn.dataTableExt.oSort["text-asc"] = textCompareAsc;
313 313
                 jQuery.fn.dataTableExt.oSort["text-desc"] = textCompareDesc;
314 314
                 
@@ -375,95 +375,95 @@  discard block
 block discarded – undo
375 375
 				jQuery("#btn-toggle-statistics-'.$table_id.'").click();
376 376
            ');
377 377
             
378
-            $stats = new Stats($wt_tree);         
378
+			$stats = new Stats($wt_tree);         
379 379
             
380
-            // Bad data can cause "longest life" to be huge, blowing memory limits
381
-            $max_age = min($wt_tree->getPreference('MAX_ALIVE_AGE'), $stats->LongestLifeAge()) + 1;
382
-            // Inititialise chart data
383
-            $deat_by_age = array();
384
-            for ($age = 0; $age <= $max_age; $age++) {
385
-                $deat_by_age[$age] = '';
386
-            }
387
-            $birt_by_decade = array();
388
-            $deat_by_decade = array();
389
-            for ($year = 1550; $year < 2030; $year += 10) {
390
-                $birt_by_decade[$year] = '';
391
-                $deat_by_decade[$year] = '';
392
-            }
380
+			// Bad data can cause "longest life" to be huge, blowing memory limits
381
+			$max_age = min($wt_tree->getPreference('MAX_ALIVE_AGE'), $stats->LongestLifeAge()) + 1;
382
+			// Inititialise chart data
383
+			$deat_by_age = array();
384
+			for ($age = 0; $age <= $max_age; $age++) {
385
+				$deat_by_age[$age] = '';
386
+			}
387
+			$birt_by_decade = array();
388
+			$deat_by_decade = array();
389
+			for ($year = 1550; $year < 2030; $year += 10) {
390
+				$birt_by_decade[$year] = '';
391
+				$deat_by_decade[$year] = '';
392
+			}
393 393
             
394
-            $unique_indis = array(); // Don't double-count indis with multiple names.
395
-            $nb_displayed = 0;
394
+			$unique_indis = array(); // Don't double-count indis with multiple names.
395
+			$nb_displayed = 0;
396 396
             
397
-            Individual::load($wt_tree, $listSosa);
398
-            foreach($listSosa as $sosa => $pid) {
399
-                $person = Individual::getInstance($pid, $wt_tree);
400
-                if (!$person || !$person->canShowName()) {
401
-                    unset($listSosa[$sosa]);
402
-                    continue;
403
-                }
404
-                $nb_displayed++;
405
-                if ($birth_dates=$person->getAllBirthDates()) {
406
-                    if (
407
-                        FunctionsPrint::isDateWithinChartsRange($birth_dates[0]) &&
408
-                        !isset($unique_indis[$person->getXref()])
409
-                        ) {
410
-                        $birt_by_decade[(int)($birth_dates[0]->gregorianYear()/10)*10] .= $person->getSex();
411
-                    }
412
-                }
413
-                else {
414
-                    $birth_dates[0]=new Date('');
415
-                }
416
-                if ($death_dates = $person->getAllDeathDates()) {
417
-                    if (
418
-                        FunctionsPrint::isDateWithinChartsRange($death_dates[0]) &&
419
-                        !isset($unique_indis[$person->getXref()])
420
-                        ) {
421
-                        $deat_by_decade[(int) ($death_dates[0]->gregorianYear() / 10) * 10] .= $person->getSex();
422
-                    }
423
-                }
424
-                else {
425
-                    $death_dates[0] = new Date('');
426
-                }
427
-                $age = Date::getAge($birth_dates[0], $death_dates[0], 0);
428
-                if (!isset($unique_indis[$person->getXref()]) && $age >= 0 && $age <= $max_age) {
429
-                    $deat_by_age[$age] .= $person->getSex();
430
-                }
431
-                $listSosa[$sosa] = $person;
432
-                $unique_indis[$person->getXref()] = true;
433
-            }
434
-            $this->view_bag->set('sosa_list', $listSosa);   
397
+			Individual::load($wt_tree, $listSosa);
398
+			foreach($listSosa as $sosa => $pid) {
399
+				$person = Individual::getInstance($pid, $wt_tree);
400
+				if (!$person || !$person->canShowName()) {
401
+					unset($listSosa[$sosa]);
402
+					continue;
403
+				}
404
+				$nb_displayed++;
405
+				if ($birth_dates=$person->getAllBirthDates()) {
406
+					if (
407
+						FunctionsPrint::isDateWithinChartsRange($birth_dates[0]) &&
408
+						!isset($unique_indis[$person->getXref()])
409
+						) {
410
+						$birt_by_decade[(int)($birth_dates[0]->gregorianYear()/10)*10] .= $person->getSex();
411
+					}
412
+				}
413
+				else {
414
+					$birth_dates[0]=new Date('');
415
+				}
416
+				if ($death_dates = $person->getAllDeathDates()) {
417
+					if (
418
+						FunctionsPrint::isDateWithinChartsRange($death_dates[0]) &&
419
+						!isset($unique_indis[$person->getXref()])
420
+						) {
421
+						$deat_by_decade[(int) ($death_dates[0]->gregorianYear() / 10) * 10] .= $person->getSex();
422
+					}
423
+				}
424
+				else {
425
+					$death_dates[0] = new Date('');
426
+				}
427
+				$age = Date::getAge($birth_dates[0], $death_dates[0], 0);
428
+				if (!isset($unique_indis[$person->getXref()]) && $age >= 0 && $age <= $max_age) {
429
+					$deat_by_age[$age] .= $person->getSex();
430
+				}
431
+				$listSosa[$sosa] = $person;
432
+				$unique_indis[$person->getXref()] = true;
433
+			}
434
+			$this->view_bag->set('sosa_list', $listSosa);   
435 435
             
436
-            $this->view_bag->set('sosa_count', count($listSosa));
437
-            $this->view_bag->set('sosa_theo', pow(2, $this->generation-1));
438
-            $this->view_bag->set('sosa_ratio', Functions::safeDivision($this->view_bag->get('sosa_count'), $this->view_bag->get('sosa_theo')));
436
+			$this->view_bag->set('sosa_count', count($listSosa));
437
+			$this->view_bag->set('sosa_theo', pow(2, $this->generation-1));
438
+			$this->view_bag->set('sosa_ratio', Functions::safeDivision($this->view_bag->get('sosa_count'), $this->view_bag->get('sosa_theo')));
439 439
             
440
-            $this->view_bag->set('sosa_hidden', $this->view_bag->get('sosa_count') - $nb_displayed);
440
+			$this->view_bag->set('sosa_hidden', $this->view_bag->get('sosa_count') - $nb_displayed);
441 441
             
442
-            $this->view_bag->set('chart_births', FunctionsPrintLists::chartByDecade($birt_by_decade, I18N::translate('Decade of birth')));
443
-            $this->view_bag->set('chart_deaths', FunctionsPrintLists::chartByDecade($deat_by_decade, I18N::translate('Decade of death')));
444
-            $this->view_bag->set('chart_ages', FunctionsPrintLists::chartByAge($deat_by_age, I18N::translate('Age related to death year')));
445
-        }
442
+			$this->view_bag->set('chart_births', FunctionsPrintLists::chartByDecade($birt_by_decade, I18N::translate('Decade of birth')));
443
+			$this->view_bag->set('chart_deaths', FunctionsPrintLists::chartByDecade($deat_by_decade, I18N::translate('Decade of death')));
444
+			$this->view_bag->set('chart_ages', FunctionsPrintLists::chartByAge($deat_by_age, I18N::translate('Age related to death year')));
445
+		}
446 446
         
447
-        ViewFactory::make('SosaListIndi', $this, $controller, $this->view_bag)->render();        
448
-    }
447
+		ViewFactory::make('SosaListIndi', $this, $controller, $this->view_bag)->render();        
448
+	}
449 449
     
450
-    /**
451
-     * Render the Ajax response for the sortable table of Sosa family
452
-     * @param AjaxController $controller
453
-     */
454
-    protected function renderFamSosaListIndi(AjaxController $controller) {
455
-        $wt_tree = Globals::getTree();
456
-        $listFamSosa = $this->sosa_provider->getFamilySosaListAtGeneration($this->generation);;
457
-        $this->view_bag->set('has_sosa', false);
450
+	/**
451
+	 * Render the Ajax response for the sortable table of Sosa family
452
+	 * @param AjaxController $controller
453
+	 */
454
+	protected function renderFamSosaListIndi(AjaxController $controller) {
455
+		$wt_tree = Globals::getTree();
456
+		$listFamSosa = $this->sosa_provider->getFamilySosaListAtGeneration($this->generation);;
457
+		$this->view_bag->set('has_sosa', false);
458 458
         
459
-        if(count($listFamSosa) > 0) {
460
-            $this->view_bag->set('has_sosa', true);
461
-            $table_id = 'table-sosa-fam-' . Uuid::uuid4();
462
-            $this->view_bag->set('table_id', $table_id);
459
+		if(count($listFamSosa) > 0) {
460
+			$this->view_bag->set('has_sosa', true);
461
+			$table_id = 'table-sosa-fam-' . Uuid::uuid4();
462
+			$this->view_bag->set('table_id', $table_id);
463 463
              
464
-            $controller
465
-            ->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)
466
-            ->addInlineJavascript('
464
+			$controller
465
+			->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)
466
+			->addInlineJavascript('
467 467
 				jQuery.fn.dataTableExt.oSort["text-asc"] = textCompareAsc;
468 468
 				jQuery.fn.dataTableExt.oSort["text-desc"] = textCompareDesc;
469 469
                 
@@ -527,67 +527,67 @@  discard block
 block discarded – undo
527 527
 				jQuery("#btn-toggle-statistics-'.$table_id.'").click();
528 528
            ');
529 529
         
530
-            $stats = new Stats($wt_tree);        
531
-            $max_age = max($stats->oldestMarriageMaleAge(), $stats->oldestMarriageFemaleAge()) + 1;
530
+			$stats = new Stats($wt_tree);        
531
+			$max_age = max($stats->oldestMarriageMaleAge(), $stats->oldestMarriageFemaleAge()) + 1;
532 532
             
533
-            //-- init chart data
534
-    		$marr_by_age = array();
535
-    		for ($age=0; $age<=$max_age; $age++) {
536
-    			$marr_by_age[$age] = '';
537
-    		}
538
-    		$birt_by_decade = array();
539
-    		$marr_by_decade = array();
540
-    		for ($year=1550; $year<2030; $year+=10) {
541
-    			$birt_by_decade[$year] = '';
542
-    			$marr_by_decade[$year] = '';
543
-    		}
533
+			//-- init chart data
534
+			$marr_by_age = array();
535
+			for ($age=0; $age<=$max_age; $age++) {
536
+				$marr_by_age[$age] = '';
537
+			}
538
+			$birt_by_decade = array();
539
+			$marr_by_decade = array();
540
+			for ($year=1550; $year<2030; $year+=10) {
541
+				$birt_by_decade[$year] = '';
542
+				$marr_by_decade[$year] = '';
543
+			}
544 544
     		
545
-            foreach($listFamSosa as $sosa => $fid) {
546
-                $sfamily = Family::getInstance($fid, $wt_tree);
547
-                if(!$sfamily || !$sfamily->canShow()) {
548
-                    unset($listFamSosa[$sosa]);
549
-                    continue;
550
-                }
551
-                $mdate=$sfamily->getMarriageDate();
545
+			foreach($listFamSosa as $sosa => $fid) {
546
+				$sfamily = Family::getInstance($fid, $wt_tree);
547
+				if(!$sfamily || !$sfamily->canShow()) {
548
+					unset($listFamSosa[$sosa]);
549
+					continue;
550
+				}
551
+				$mdate=$sfamily->getMarriageDate();
552 552
                 
553
-                if( ($husb = $sfamily->getHusband()) && 
554
-                    ($hdate = $husb->getBirthDate()) && 
555
-                    $hdate->isOK() && $mdate->isOK()) {
556
-                    if (FunctionsPrint::isDateWithinChartsRange($hdate)) {
557
-                        $birt_by_decade[(int) ($hdate->gregorianYear() / 10) * 10] .= $husb->getSex();
558
-                    }
559
-                    $hage = Date::getAge($hdate, $mdate, 0);
560
-                    if ($hage >= 0 && $hage <= $max_age) {
561
-                        $marr_by_age[$hage] .= $husb->getSex();
562
-                    }
563
-                }
553
+				if( ($husb = $sfamily->getHusband()) && 
554
+					($hdate = $husb->getBirthDate()) && 
555
+					$hdate->isOK() && $mdate->isOK()) {
556
+					if (FunctionsPrint::isDateWithinChartsRange($hdate)) {
557
+						$birt_by_decade[(int) ($hdate->gregorianYear() / 10) * 10] .= $husb->getSex();
558
+					}
559
+					$hage = Date::getAge($hdate, $mdate, 0);
560
+					if ($hage >= 0 && $hage <= $max_age) {
561
+						$marr_by_age[$hage] .= $husb->getSex();
562
+					}
563
+				}
564 564
                 
565
-                if(($wife = $sfamily->getWife()) &&
566
-                    ($wdate=$wife->getBirthDate()) &&
567
-                    $wdate->isOK() && $mdate->isOK()) {
568
-                    if (FunctionsPrint::isDateWithinChartsRange($wdate)) {
569
-                        $birt_by_decade[(int) ($wdate->gregorianYear() / 10) * 10] .= $wife->getSex();
570
-                    }
571
-                    $wage = Date::getAge($wdate, $mdate, 0);
572
-                    if ($wage >= 0 && $wage <= $max_age) {
573
-                        $marr_by_age[$wage] .= $wife->getSex();
574
-                    }
575
-                }                
565
+				if(($wife = $sfamily->getWife()) &&
566
+					($wdate=$wife->getBirthDate()) &&
567
+					$wdate->isOK() && $mdate->isOK()) {
568
+					if (FunctionsPrint::isDateWithinChartsRange($wdate)) {
569
+						$birt_by_decade[(int) ($wdate->gregorianYear() / 10) * 10] .= $wife->getSex();
570
+					}
571
+					$wage = Date::getAge($wdate, $mdate, 0);
572
+					if ($wage >= 0 && $wage <= $max_age) {
573
+						$marr_by_age[$wage] .= $wife->getSex();
574
+					}
575
+				}                
576 576
 
577
-                if ($mdate->isOK() && FunctionsPrint::isDateWithinChartsRange($mdate) && $husb && $wife) {
578
-                    $marr_by_decade[(int) ($mdate->gregorianYear() / 10) * 10] .= $husb->getSex() . $wife->getSex();
579
-                }
577
+				if ($mdate->isOK() && FunctionsPrint::isDateWithinChartsRange($mdate) && $husb && $wife) {
578
+					$marr_by_decade[(int) ($mdate->gregorianYear() / 10) * 10] .= $husb->getSex() . $wife->getSex();
579
+				}
580 580
                 
581
-                $listFamSosa[$sosa] = $sfamily;
582
-            }
583
-            $this->view_bag->set('sosa_list', $listFamSosa);
581
+				$listFamSosa[$sosa] = $sfamily;
582
+			}
583
+			$this->view_bag->set('sosa_list', $listFamSosa);
584 584
         
585
-            $this->view_bag->set('chart_births', FunctionsPrintLists::chartByDecade($birt_by_decade, I18N::translate('Decade of birth')));
586
-            $this->view_bag->set('chart_marriages', FunctionsPrintLists::chartByDecade($marr_by_decade, I18N::translate('Decade of marriage')));
587
-            $this->view_bag->set('chart_ages', FunctionsPrintLists::chartByAge($marr_by_age, I18N::translate('Age in year of marriage')));
588
-        }
585
+			$this->view_bag->set('chart_births', FunctionsPrintLists::chartByDecade($birt_by_decade, I18N::translate('Decade of birth')));
586
+			$this->view_bag->set('chart_marriages', FunctionsPrintLists::chartByDecade($marr_by_decade, I18N::translate('Decade of marriage')));
587
+			$this->view_bag->set('chart_ages', FunctionsPrintLists::chartByAge($marr_by_age, I18N::translate('Age in year of marriage')));
588
+		}
589 589
         
590
-        ViewFactory::make('SosaListFam', $this, $controller, $this->view_bag)->render();
591
-    }
590
+		ViewFactory::make('SosaListFam', $this, $controller, $this->view_bag)->render();
591
+	}
592 592
     
593 593
 }
594 594
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +47 added lines, -47 removed lines patch added patch discarded remove patch
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
         $this->view_bag = new ViewBag();
70 70
         $this->view_bag->set('generation', $this->generation);
71 71
         $this->view_bag->set('max_gen', $this->sosa_provider->getLastGeneration());
72
-        $this->view_bag->set('is_setup', $this->sosa_provider->isSetup() && $this->view_bag->get('max_gen', 0)> 0);
72
+        $this->view_bag->set('is_setup', $this->sosa_provider->isSetup() && $this->view_bag->get('max_gen', 0) > 0);
73 73
         
74 74
     }
75 75
     
@@ -89,14 +89,14 @@  discard block
 block discarded – undo
89 89
 
90 90
         $this->view_bag->set('title', $controller->getPageTitle());
91 91
         
92
-        if($this->view_bag->get('is_setup', false)) {
92
+        if ($this->view_bag->get('is_setup', false)) {
93 93
             $this->view_bag->set('has_sosa', $this->generation > 0 && $this->sosa_provider->getSosaCountAtGeneration($this->generation) > 0);
94 94
             $this->view_bag->set('url_module', $this->module->getName());
95 95
             $this->view_bag->set('url_action', 'SosaList');
96 96
             $this->view_bag->set('url_ged', $wt_tree->getNameUrl()); 
97 97
             $this->view_bag->set('min_gen', 1);
98 98
             
99
-            if($this->view_bag->get('has_sosa', false)) {            
99
+            if ($this->view_bag->get('has_sosa', false)) {            
100 100
                 $controller->addInlineJavascript('
101 101
             		jQuery("#sosalist-tabs").tabs();
102 102
             		jQuery("#sosalist-tabs").css("visibility", "visible");
@@ -106,7 +106,7 @@  discard block
 block discarded – undo
106 106
             			{
107 107
                             "mod" : "'.$this->module->getName().'",
108 108
                             "mod_action": "SosaList@sosalist",
109
-                            "ged" : "' . $wt_tree->getNameUrl(). '",
109
+                            "ged" : "' . $wt_tree->getNameUrl().'",
110 110
                             "type" : "indi",
111 111
                             "gen" : "'.$this->generation.'"
112 112
                         },
@@ -131,7 +131,7 @@  discard block
 block discarded – undo
131 131
                         {
132 132
                             "mod" : "'.$this->module->getName().'",
133 133
                             "mod_action": "SosaList@sosalist",
134
-                            "ged" : "' . $wt_tree->getNameUrl(). '",
134
+                            "ged" : "' . $wt_tree->getNameUrl().'",
135 135
                             "type" : "fam",
136 136
                             "gen" : "'.$this->generation.'"
137 137
                         },
@@ -169,7 +169,7 @@  discard block
 block discarded – undo
169 169
         
170 170
         $this->view_bag->set('title', $controller->getPageTitle());
171 171
         
172
-        if($this->view_bag->get('is_setup', false)) {
172
+        if ($this->view_bag->get('is_setup', false)) {
173 173
             $this->view_bag->set('url_module', $this->module->getName());
174 174
             $this->view_bag->set('url_action', 'SosaList@missing');
175 175
             $this->view_bag->set('url_ged', $wt_tree->getNameUrl());
@@ -178,11 +178,11 @@  discard block
 block discarded – undo
178 178
             $missing_list = $this->sosa_provider->getMissingSosaListAtGeneration($this->generation);
179 179
             $this->view_bag->set('has_missing', $this->generation > 0 && count($missing_list) > 0);
180 180
             
181
-            $perc_sosa = Functions::safeDivision($this->sosa_provider->getSosaCountAtGeneration($this->generation), pow(2, $this->generation -1));
181
+            $perc_sosa = Functions::safeDivision($this->sosa_provider->getSosaCountAtGeneration($this->generation), pow(2, $this->generation - 1));
182 182
             $this->view_bag->set('perc_sosa', $perc_sosa);
183 183
             
184
-            if($this->view_bag->get('has_missing', false)) {
185
-                $table_id = 'table-sosa-missing-' . Uuid::uuid4();
184
+            if ($this->view_bag->get('has_missing', false)) {
185
+                $table_id = 'table-sosa-missing-'.Uuid::uuid4();
186 186
                 $this->view_bag->set('table_id', $table_id);
187 187
                 
188 188
                 $controller
@@ -192,7 +192,7 @@  discard block
 block discarded – undo
192 192
 				    jQuery.fn.dataTableExt.oSort["text-desc"] = textCompareDesc;
193 193
                     
194 194
     				jQuery("#'.$table_id.'").dataTable( {
195
-                        dom: \'<"H"<"filtersH_' . $table_id . '">T<"dt-clear">pf<"dt-clear">irl>t<"F"pl<"dt-clear"><"filtersF_' . $table_id . '">>\',
195
+                        dom: \'<"H"<"filtersH_' . $table_id.'">T<"dt-clear">pf<"dt-clear">irl>t<"F"pl<"dt-clear"><"filtersF_'.$table_id.'">>\',
196 196
     					'.I18N::datatablesI18N().',
197 197
     					jQueryUI: true,
198 198
     					autoWidth:false,
@@ -218,14 +218,14 @@  discard block
 block discarded – undo
218 218
     					pagingType: "full_numbers"
219 219
     			   });
220 220
     			
221
-    				jQuery("#' . $table_id . '")
221
+    				jQuery("#' . $table_id.'")
222 222
     				/* Filter buttons in table header */
223 223
     				.on("click", "button[data-filter-column]", function() {
224 224
     					var btn = jQuery(this);
225 225
     					// De-activate the other buttons in this button group
226 226
     					btn.siblings().removeClass("ui-state-active");
227 227
     					// Apply (or clear) this filter
228
-    					var col = jQuery("#' . $table_id . '").DataTable().column(btn.data("filter-column"));
228
+    					var col = jQuery("#' . $table_id.'").DataTable().column(btn.data("filter-column"));
229 229
     					if (btn.hasClass("ui-state-active")) {
230 230
     						btn.removeClass("ui-state-active");
231 231
     						col.search("").draw();
@@ -242,8 +242,8 @@  discard block
 block discarded – undo
242 242
                 $unique_indis = array();
243 243
                 $sum_missing_different = 0;
244 244
                 $sum_missing_different_without_hidden = 0;
245
-                foreach($missing_list as $num => $missing_tab) {
246
-                    if(isset($unique_indis[$missing_tab['indi']])) {
245
+                foreach ($missing_list as $num => $missing_tab) {
246
+                    if (isset($unique_indis[$missing_tab['indi']])) {
247 247
                         unset($missing_list[$num]);
248 248
                         continue;
249 249
                     }
@@ -261,7 +261,7 @@  discard block
 block discarded – undo
261 261
                 $this->view_bag->set('missing_list', $missing_list);
262 262
                 $this->view_bag->set('missing_diff_count', $sum_missing_different);
263 263
                 $this->view_bag->set('missing_hidden', $sum_missing_different - $sum_missing_different_without_hidden);
264
-                $perc_sosa_potential = Functions::safeDivision($this->sosa_provider->getSosaCountAtGeneration($this->generation - 1), pow(2, $this->generation-2));
264
+                $perc_sosa_potential = Functions::safeDivision($this->sosa_provider->getSosaCountAtGeneration($this->generation - 1), pow(2, $this->generation - 2));
265 265
                 $this->view_bag->set('perc_sosa_potential', $perc_sosa_potential);
266 266
             }            
267 267
         }
@@ -279,7 +279,7 @@  discard block
 block discarded – undo
279 279
         $controller = new AjaxController();
280 280
         $controller->restrictAccess($this->generation > 0 || !is_null($type));
281 281
         
282
-        switch ($type){
282
+        switch ($type) {
283 283
             case 'indi':
284 284
                 $this->renderSosaListIndi($controller);
285 285
                 break;
@@ -301,9 +301,9 @@  discard block
 block discarded – undo
301 301
         $listSosa = $this->sosa_provider->getSosaListAtGeneration($this->generation); 
302 302
         $this->view_bag->set('has_sosa', false);
303 303
         
304
-        if(count($listSosa) > 0) {
304
+        if (count($listSosa) > 0) {
305 305
             $this->view_bag->set('has_sosa', true);
306
-            $table_id = 'table-sosa-indi-' . Uuid::uuid4();
306
+            $table_id = 'table-sosa-indi-'.Uuid::uuid4();
307 307
             $this->view_bag->set('table_id', $table_id);
308 308
                      
309 309
             $controller
@@ -313,8 +313,8 @@  discard block
 block discarded – undo
313 313
                 jQuery.fn.dataTableExt.oSort["text-desc"] = textCompareDesc;
314 314
                 
315 315
                 jQuery("#'.$table_id.'").dataTable( {
316
-					dom: \'<"H"<"filtersH_' . $table_id . '">T<"dt-clear">pf<"dt-clear">irl>t<"F"pl<"dt-clear"><"filtersF_' . $table_id . '">>\',
317
-					' . I18N::datatablesI18N() . ',
316
+					dom: \'<"H"<"filtersH_' . $table_id.'">T<"dt-clear">pf<"dt-clear">irl>t<"F"pl<"dt-clear"><"filtersF_'.$table_id.'">>\',
317
+					' . I18N::datatablesI18N().',
318 318
 					jQueryUI: true,
319 319
 					autoWidth: false,
320 320
 					processing: true,
@@ -343,7 +343,7 @@  discard block
 block discarded – undo
343 343
 					pagingType: "full_numbers"
344 344
 			   });
345 345
             
346
-				jQuery("#' . $table_id . '")
346
+				jQuery("#' . $table_id.'")
347 347
 				/* Hide/show parents */
348 348
 				.on("click", ".btn-toggle-parents", function() {
349 349
 					jQuery(this).toggleClass("ui-state-active");
@@ -352,7 +352,7 @@  discard block
 block discarded – undo
352 352
 				/* Hide/show statistics */
353 353
 				.on("click", ".btn-toggle-statistics", function() {
354 354
 					jQuery(this).toggleClass("ui-state-active");
355
-					jQuery("#indi_list_table-charts_' . $table_id . '").slideToggle();
355
+					jQuery("#indi_list_table-charts_' . $table_id.'").slideToggle();
356 356
 				})
357 357
 				/* Filter buttons in table header */
358 358
 				.on("click", "button[data-filter-column]", function() {
@@ -360,7 +360,7 @@  discard block
 block discarded – undo
360 360
 					// De-activate the other buttons in this button group
361 361
 					btn.siblings().removeClass("ui-state-active");
362 362
 					// Apply (or clear) this filter
363
-					var col = jQuery("#' . $table_id . '").DataTable().column(btn.data("filter-column"));
363
+					var col = jQuery("#' . $table_id.'").DataTable().column(btn.data("filter-column"));
364 364
 					if (btn.hasClass("ui-state-active")) {
365 365
 						btn.removeClass("ui-state-active");
366 366
 						col.search("").draw();
@@ -395,30 +395,30 @@  discard block
 block discarded – undo
395 395
             $nb_displayed = 0;
396 396
             
397 397
             Individual::load($wt_tree, $listSosa);
398
-            foreach($listSosa as $sosa => $pid) {
398
+            foreach ($listSosa as $sosa => $pid) {
399 399
                 $person = Individual::getInstance($pid, $wt_tree);
400 400
                 if (!$person || !$person->canShowName()) {
401 401
                     unset($listSosa[$sosa]);
402 402
                     continue;
403 403
                 }
404 404
                 $nb_displayed++;
405
-                if ($birth_dates=$person->getAllBirthDates()) {
405
+                if ($birth_dates = $person->getAllBirthDates()) {
406 406
                     if (
407 407
                         FunctionsPrint::isDateWithinChartsRange($birth_dates[0]) &&
408 408
                         !isset($unique_indis[$person->getXref()])
409 409
                         ) {
410
-                        $birt_by_decade[(int)($birth_dates[0]->gregorianYear()/10)*10] .= $person->getSex();
410
+                        $birt_by_decade[(int)($birth_dates[0]->gregorianYear() / 10) * 10] .= $person->getSex();
411 411
                     }
412 412
                 }
413 413
                 else {
414
-                    $birth_dates[0]=new Date('');
414
+                    $birth_dates[0] = new Date('');
415 415
                 }
416 416
                 if ($death_dates = $person->getAllDeathDates()) {
417 417
                     if (
418 418
                         FunctionsPrint::isDateWithinChartsRange($death_dates[0]) &&
419 419
                         !isset($unique_indis[$person->getXref()])
420 420
                         ) {
421
-                        $deat_by_decade[(int) ($death_dates[0]->gregorianYear() / 10) * 10] .= $person->getSex();
421
+                        $deat_by_decade[(int)($death_dates[0]->gregorianYear() / 10) * 10] .= $person->getSex();
422 422
                     }
423 423
                 }
424 424
                 else {
@@ -434,7 +434,7 @@  discard block
 block discarded – undo
434 434
             $this->view_bag->set('sosa_list', $listSosa);   
435 435
             
436 436
             $this->view_bag->set('sosa_count', count($listSosa));
437
-            $this->view_bag->set('sosa_theo', pow(2, $this->generation-1));
437
+            $this->view_bag->set('sosa_theo', pow(2, $this->generation - 1));
438 438
             $this->view_bag->set('sosa_ratio', Functions::safeDivision($this->view_bag->get('sosa_count'), $this->view_bag->get('sosa_theo')));
439 439
             
440 440
             $this->view_bag->set('sosa_hidden', $this->view_bag->get('sosa_count') - $nb_displayed);
@@ -453,12 +453,12 @@  discard block
 block discarded – undo
453 453
      */
454 454
     protected function renderFamSosaListIndi(AjaxController $controller) {
455 455
         $wt_tree = Globals::getTree();
456
-        $listFamSosa = $this->sosa_provider->getFamilySosaListAtGeneration($this->generation);;
456
+        $listFamSosa = $this->sosa_provider->getFamilySosaListAtGeneration($this->generation); ;
457 457
         $this->view_bag->set('has_sosa', false);
458 458
         
459
-        if(count($listFamSosa) > 0) {
459
+        if (count($listFamSosa) > 0) {
460 460
             $this->view_bag->set('has_sosa', true);
461
-            $table_id = 'table-sosa-fam-' . Uuid::uuid4();
461
+            $table_id = 'table-sosa-fam-'.Uuid::uuid4();
462 462
             $this->view_bag->set('table_id', $table_id);
463 463
              
464 464
             $controller
@@ -468,7 +468,7 @@  discard block
 block discarded – undo
468 468
 				jQuery.fn.dataTableExt.oSort["text-desc"] = textCompareDesc;
469 469
                 
470 470
                 jQuery("#'.$table_id.'").dataTable( {
471
-					dom: \'<"H"<"filtersH_' . $table_id . '"><"dt-clear">pf<"dt-clear">irl>t<"F"pl<"dt-clear"><"filtersF_' . $table_id . '">>\',
471
+					dom: \'<"H"<"filtersH_' . $table_id.'"><"dt-clear">pf<"dt-clear">irl>t<"F"pl<"dt-clear"><"filtersF_'.$table_id.'">>\',
472 472
                     '.I18N::datatablesI18N(array(16, 32, 64, 128, -1)).',
473 473
 					jQueryUI: true,
474 474
 					autoWidth: false,
@@ -495,7 +495,7 @@  discard block
 block discarded – undo
495 495
 					pagingType: "full_numbers"
496 496
 			   });
497 497
 					
498
-				jQuery("#' . $table_id . '")
498
+				jQuery("#' . $table_id.'")
499 499
 				/* Hide/show parents */
500 500
 				.on("click", ".btn-toggle-parents", function() {
501 501
 					jQuery(this).toggleClass("ui-state-active");
@@ -504,7 +504,7 @@  discard block
 block discarded – undo
504 504
 				/* Hide/show statistics */
505 505
 				.on("click",  ".btn-toggle-statistics", function() {
506 506
 					jQuery(this).toggleClass("ui-state-active");
507
-					jQuery("#fam_list_table-charts_' . $table_id . '").slideToggle();
507
+					jQuery("#fam_list_table-charts_' . $table_id.'").slideToggle();
508 508
 				})
509 509
 				/* Filter buttons in table header */
510 510
 				.on("click", "button[data-filter-column]", function() {
@@ -512,7 +512,7 @@  discard block
 block discarded – undo
512 512
 					// De-activate the other buttons in this button group
513 513
 					btn.siblings().removeClass("ui-state-active");
514 514
 					// Apply (or clear) this filter
515
-					var col = jQuery("#' . $table_id . '").DataTable().column(btn.data("filter-column"));
515
+					var col = jQuery("#' . $table_id.'").DataTable().column(btn.data("filter-column"));
516 516
 					if (btn.hasClass("ui-state-active")) {
517 517
 						btn.removeClass("ui-state-active");
518 518
 						col.search("").draw();
@@ -532,29 +532,29 @@  discard block
 block discarded – undo
532 532
             
533 533
             //-- init chart data
534 534
     		$marr_by_age = array();
535
-    		for ($age=0; $age<=$max_age; $age++) {
535
+    		for ($age = 0; $age <= $max_age; $age++) {
536 536
     			$marr_by_age[$age] = '';
537 537
     		}
538 538
     		$birt_by_decade = array();
539 539
     		$marr_by_decade = array();
540
-    		for ($year=1550; $year<2030; $year+=10) {
540
+    		for ($year = 1550; $year < 2030; $year += 10) {
541 541
     			$birt_by_decade[$year] = '';
542 542
     			$marr_by_decade[$year] = '';
543 543
     		}
544 544
     		
545
-            foreach($listFamSosa as $sosa => $fid) {
545
+            foreach ($listFamSosa as $sosa => $fid) {
546 546
                 $sfamily = Family::getInstance($fid, $wt_tree);
547
-                if(!$sfamily || !$sfamily->canShow()) {
547
+                if (!$sfamily || !$sfamily->canShow()) {
548 548
                     unset($listFamSosa[$sosa]);
549 549
                     continue;
550 550
                 }
551
-                $mdate=$sfamily->getMarriageDate();
551
+                $mdate = $sfamily->getMarriageDate();
552 552
                 
553
-                if( ($husb = $sfamily->getHusband()) && 
553
+                if (($husb = $sfamily->getHusband()) && 
554 554
                     ($hdate = $husb->getBirthDate()) && 
555 555
                     $hdate->isOK() && $mdate->isOK()) {
556 556
                     if (FunctionsPrint::isDateWithinChartsRange($hdate)) {
557
-                        $birt_by_decade[(int) ($hdate->gregorianYear() / 10) * 10] .= $husb->getSex();
557
+                        $birt_by_decade[(int)($hdate->gregorianYear() / 10) * 10] .= $husb->getSex();
558 558
                     }
559 559
                     $hage = Date::getAge($hdate, $mdate, 0);
560 560
                     if ($hage >= 0 && $hage <= $max_age) {
@@ -562,11 +562,11 @@  discard block
 block discarded – undo
562 562
                     }
563 563
                 }
564 564
                 
565
-                if(($wife = $sfamily->getWife()) &&
566
-                    ($wdate=$wife->getBirthDate()) &&
565
+                if (($wife = $sfamily->getWife()) &&
566
+                    ($wdate = $wife->getBirthDate()) &&
567 567
                     $wdate->isOK() && $mdate->isOK()) {
568 568
                     if (FunctionsPrint::isDateWithinChartsRange($wdate)) {
569
-                        $birt_by_decade[(int) ($wdate->gregorianYear() / 10) * 10] .= $wife->getSex();
569
+                        $birt_by_decade[(int)($wdate->gregorianYear() / 10) * 10] .= $wife->getSex();
570 570
                     }
571 571
                     $wage = Date::getAge($wdate, $mdate, 0);
572 572
                     if ($wage >= 0 && $wage <= $max_age) {
@@ -575,7 +575,7 @@  discard block
 block discarded – undo
575 575
                 }                
576 576
 
577 577
                 if ($mdate->isOK() && FunctionsPrint::isDateWithinChartsRange($mdate) && $husb && $wife) {
578
-                    $marr_by_decade[(int) ($mdate->gregorianYear() / 10) * 10] .= $husb->getSex() . $wife->getSex();
578
+                    $marr_by_decade[(int)($mdate->gregorianYear() / 10) * 10] .= $husb->getSex().$wife->getSex();
579 579
                 }
580 580
                 
581 581
                 $listFamSosa[$sosa] = $sfamily;
Please login to merge, or discard this patch.
src/Webtrees/Globals.php 1 patch
Indentation   +36 added lines, -36 removed lines patch added patch discarded remove patch
@@ -16,48 +16,48 @@
 block discarded – undo
16 16
  */
17 17
 class Globals {
18 18
     
19
-    /**
20
-     * Get global $WT_TREE variable.
21
-     * 
22
-     * @return \Fisharebest\Webtrees\Tree
23
-     */
24
-    public static function getTree() {
25
-        global $WT_TREE;
19
+	/**
20
+	 * Get global $WT_TREE variable.
21
+	 * 
22
+	 * @return \Fisharebest\Webtrees\Tree
23
+	 */
24
+	public static function getTree() {
25
+		global $WT_TREE;
26 26
         
27
-        return $WT_TREE;
28
-    }
27
+		return $WT_TREE;
28
+	}
29 29
     
30
-    /**
31
-     * Check whether the visitor is a bot.
32
-     * 
33
-     * @return boolean
34
-     */
35
-    public static function isSearchSpider() {
36
-        global $SEARCH_SPIDER;
30
+	/**
31
+	 * Check whether the visitor is a bot.
32
+	 * 
33
+	 * @return boolean
34
+	 */
35
+	public static function isSearchSpider() {
36
+		global $SEARCH_SPIDER;
37 37
         
38
-        return $SEARCH_SPIDER;
39
-    }
38
+		return $SEARCH_SPIDER;
39
+	}
40 40
     
41
-    /**
42
-     * Get the current controller.
43
-     * 
44
-     * @return \Fisharebest\Webtrees\BaseController
45
-     */
46
-    public static function getController() {
47
-        global $controller;
41
+	/**
42
+	 * Get the current controller.
43
+	 * 
44
+	 * @return \Fisharebest\Webtrees\BaseController
45
+	 */
46
+	public static function getController() {
47
+		global $controller;
48 48
         
49
-        return $controller;
50
-    }
49
+		return $controller;
50
+	}
51 51
     
52
-    /**
53
-     * Get the global facts
54
-     * 
55
-     * @return array
56
-     */
57
-    public static function getGlobalFacts() {
58
-        global $global_facts;
52
+	/**
53
+	 * Get the global facts
54
+	 * 
55
+	 * @return array
56
+	 */
57
+	public static function getGlobalFacts() {
58
+		global $global_facts;
59 59
         
60
-        return $global_facts;
61
-    }
60
+		return $global_facts;
61
+	}
62 62
     
63 63
 }
Please login to merge, or discard this patch.
src/Webtrees/Module/Sosa/Model/SosaProvider.php 4 patches
Doc Comments   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -277,7 +277,7 @@  discard block
 block discarded – undo
277 277
     /**
278 278
      * Get an associative array of Sosa individuals in generation G. Keys are Sosa numbers, values individuals.
279 279
      *
280
-     * @param number $gen Generation
280
+     * @param integer $gen Generation
281 281
      * @return array Array of Sosa individuals
282 282
      */
283 283
     public function getSosaListAtGeneration($gen){
@@ -308,7 +308,7 @@  discard block
 block discarded – undo
308 308
     /**
309 309
      * Get an associative array of Sosa families in generation G. Keys are Sosa numbers for the husband, values families.
310 310
      *
311
-     * @param number $gen Generation
311
+     * @param integer $gen Generation
312 312
      * @return array Array of Sosa families
313 313
      */
314 314
     public function getFamilySosaListAtGeneration($gen){
@@ -344,7 +344,7 @@  discard block
 block discarded – undo
344 344
     /**
345 345
      * Get an associative array of Sosa individuals in generation G who are missing parents. Keys are Sosa numbers, values individuals.
346 346
      *
347
-     * @param number $gen Generation
347
+     * @param integer $gen Generation
348 348
      * @return array Array of Sosa individuals
349 349
      */
350 350
     public function getMissingSosaListAtGeneration($gen){
@@ -439,8 +439,8 @@  discard block
 block discarded – undo
439 439
     /**
440 440
      * Get the number of Sosa in a specific generation.
441 441
      *
442
-     * @param number $gen Generation
443
-     * @return number Number of Sosas in generation
442
+     * @param integer $gen Generation
443
+     * @return integer Number of Sosas in generation
444 444
      */
445 445
     public function getSosaCountAtGeneration($gen){
446 446
         if(!$this->is_setup) return 0;
@@ -458,7 +458,7 @@  discard block
 block discarded – undo
458 458
     /**
459 459
      * Get the total number of Sosa up to a specific generation.
460 460
      *
461
-     * @param number $gen Generation
461
+     * @param integer $gen Generation
462 462
      * @return number Total number of Sosas up to generation
463 463
      */
464 464
     public function getSosaCountUpToGeneration($gen){
@@ -493,7 +493,7 @@  discard block
 block discarded – undo
493 493
     /**
494 494
      * Get the number of distinct Sosa individual up to a specific generation.
495 495
      *
496
-     * @param number $gen Generation
496
+     * @param integer $gen Generation
497 497
      * @return number Number of distinct Sosa individuals up to generation
498 498
      */
499 499
     public function getDifferentSosaCountUpToGeneration($gen){
@@ -516,7 +516,7 @@  discard block
 block discarded – undo
516 516
      *  - last : Last birth year in generation
517 517
      *  - avg : Average birth year
518 518
      *
519
-     * @param number $gen Generation
519
+     * @param integer $gen Generation
520 520
      * @return array Birth statistics array
521 521
      */
522 522
     public function getStatsBirthYearInGeneration($gen){
@@ -622,7 +622,7 @@  discard block
 block discarded – undo
622 622
      *  - key : root Sosa individual
623 623
      *  - value: number of duplications of the ancestor (e.g. 3 if it appears 3 times)
624 624
      * 
625
-     * @param number $limit Maximum number of individuals to return
625
+     * @param integer $limit Maximum number of individuals to return
626 626
      * @return array 
627 627
      */
628 628
     public function getTopMultiSosaAncestorsNoTies($limit) {
Please login to merge, or discard this patch.
Indentation   +613 added lines, -613 removed lines patch added patch discarded remove patch
@@ -22,389 +22,389 @@  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
-     * @return array Associative array of Sosa ancestors, with their generation, comma separated
262
-     */
263
-    public function getAllSosaWithGenerations(){
264
-        if(!$this->is_setup) return array();
265
-        return Database::prepare(
266
-            'SELECT majs_i_id AS indi,' .
267
-            ' GROUP_CONCAT(DISTINCT majs_gen ORDER BY majs_gen ASC SEPARATOR ",") AS generations' .
268
-            ' FROM `##maj_sosa`' .
269
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id' .
270
-            ' GROUP BY majs_i_id'
271
-        )->execute(array(
272
-            'tree_id' => $this->tree->getTreeId(),
273
-            'user_id' => $this->user->getUserId()
274
-        ))->fetchAssoc();
275
-    }
276
-    
277
-    /**
278
-     * Get an associative array of Sosa individuals in generation G. Keys are Sosa numbers, values individuals.
279
-     *
280
-     * @param number $gen Generation
281
-     * @return array Array of Sosa individuals
282
-     */
283
-    public function getSosaListAtGeneration($gen){
284
-        if(!$this->is_setup) return array();
285
-        if(!$this->sosa_list_by_gen)
286
-            $this->sosa_list_by_gen = array();
258
+	/**
259
+	 * Return the list of all sosas, with the generations it belongs to
260
+	 *
261
+	 * @return array Associative array of Sosa ancestors, with their generation, comma separated
262
+	 */
263
+	public function getAllSosaWithGenerations(){
264
+		if(!$this->is_setup) return array();
265
+		return Database::prepare(
266
+			'SELECT majs_i_id AS indi,' .
267
+			' GROUP_CONCAT(DISTINCT majs_gen ORDER BY majs_gen ASC SEPARATOR ",") AS generations' .
268
+			' FROM `##maj_sosa`' .
269
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id' .
270
+			' GROUP BY majs_i_id'
271
+		)->execute(array(
272
+			'tree_id' => $this->tree->getTreeId(),
273
+			'user_id' => $this->user->getUserId()
274
+		))->fetchAssoc();
275
+	}
276
+    
277
+	/**
278
+	 * Get an associative array of Sosa individuals in generation G. Keys are Sosa numbers, values individuals.
279
+	 *
280
+	 * @param number $gen Generation
281
+	 * @return array Array of Sosa individuals
282
+	 */
283
+	public function getSosaListAtGeneration($gen){
284
+		if(!$this->is_setup) return array();
285
+		if(!$this->sosa_list_by_gen)
286
+			$this->sosa_list_by_gen = array();
287 287
         
288
-        if($gen){
289
-            if(!isset($this->sosa_list_by_gen[$gen])){
290
-                $this->sosa_list_by_gen[$gen] = Database::prepare(
291
-                    'SELECT majs_sosa AS sosa, majs_i_id AS indi'.
292
-                    ' FROM `##maj_sosa`'.
293
-                    ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
294
-                    ' AND majs_gen = :gen'.
295
-                    ' ORDER BY majs_sosa ASC')
296
-                ->execute(array(
297
-                    'tree_id' => $this->tree->getTreeId(),
298
-                    'user_id' => $this->user->getUserId(),
299
-                    'gen' => $gen
300
-                ))
301
-                ->fetchAssoc();
302
-            }
303
-            return $this->sosa_list_by_gen[$gen];
304
-        }
305
-        return array();
306
-    }
307
-    
308
-    /**
309
-     * Get an associative array of Sosa families in generation G. Keys are Sosa numbers for the husband, values families.
310
-     *
311
-     * @param number $gen Generation
312
-     * @return array Array of Sosa families
313
-     */
314
-    public function getFamilySosaListAtGeneration($gen){
315
-        if(!$this->is_setup) return array();
316
-        if(!$this->sosa_fam_list_by_gen)
317
-            $this->sosa_fam_list_by_gen = array();
288
+		if($gen){
289
+			if(!isset($this->sosa_list_by_gen[$gen])){
290
+				$this->sosa_list_by_gen[$gen] = Database::prepare(
291
+					'SELECT majs_sosa AS sosa, majs_i_id AS indi'.
292
+					' FROM `##maj_sosa`'.
293
+					' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
294
+					' AND majs_gen = :gen'.
295
+					' ORDER BY majs_sosa ASC')
296
+				->execute(array(
297
+					'tree_id' => $this->tree->getTreeId(),
298
+					'user_id' => $this->user->getUserId(),
299
+					'gen' => $gen
300
+				))
301
+				->fetchAssoc();
302
+			}
303
+			return $this->sosa_list_by_gen[$gen];
304
+		}
305
+		return array();
306
+	}
307
+    
308
+	/**
309
+	 * Get an associative array of Sosa families in generation G. Keys are Sosa numbers for the husband, values families.
310
+	 *
311
+	 * @param number $gen Generation
312
+	 * @return array Array of Sosa families
313
+	 */
314
+	public function getFamilySosaListAtGeneration($gen){
315
+		if(!$this->is_setup) return array();
316
+		if(!$this->sosa_fam_list_by_gen)
317
+			$this->sosa_fam_list_by_gen = array();
318 318
         
319
-        if($gen){
320
-            if(!isset($this->sosa_fam_list_by_gen[$gen])){
321
-                $this->sosa_fam_list_by_gen[$gen] = Database::prepare(
322
-                    'SELECT s1.majs_sosa AS sosa, f_id AS fam'.
323
-                    ' FROM `##families`'.
324
-                    ' INNER JOIN `##maj_sosa` AS s1 ON (`##families`.f_husb = s1.majs_i_id AND `##families`.f_file = s1.majs_gedcom_id)'.
325
-                    ' INNER JOIN `##maj_sosa` AS s2 ON (`##families`.f_wife = s2.majs_i_id AND `##families`.f_file = s2.majs_gedcom_id)'.
326
-                    ' WHERE s1.majs_sosa + 1 = s2.majs_sosa'.
327
-                    ' AND s1.majs_gedcom_id= :tree_id AND s1.majs_user_id=:user_id'.
328
-                    ' AND s2.majs_gedcom_id= :tree_id AND s2.majs_user_id=:user_id'.
329
-                    ' AND s1.majs_gen = :gen'.
330
-                    ' ORDER BY s1.majs_sosa ASC'
331
-                    )
332
-                    ->execute(array(
333
-                        'tree_id' => $this->tree->getTreeId(),
334
-                        'user_id' => $this->user->getUserId(),
335
-                        'gen' => $gen
336
-                    ))
337
-                    ->fetchAssoc();
338
-            }
339
-            return $this->sosa_fam_list_by_gen[$gen];
340
-        }
341
-        return array();
342
-    }
343
-    
344
-    /**
345
-     * Get an associative array of Sosa individuals in generation G who are missing parents. Keys are Sosa numbers, values individuals.
346
-     *
347
-     * @param number $gen Generation
348
-     * @return array Array of Sosa individuals
349
-     */
350
-    public function getMissingSosaListAtGeneration($gen){
351
-        if(!$this->is_setup) return array();    
352
-        if($gen){
353
-            return $this->sosa_list_by_gen[$gen] = Database::prepare(
354
-                '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'.
355
-                ' FROM `##maj_sosa` schild'.
356
-                ' 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)'.
357
-                ' 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)'.
358
-                ' WHERE schild.majs_gedcom_id = :tree_id AND schild.majs_user_id = :user_id'.
359
-                ' AND schild.majs_gen = :gen'.
360
-                ' AND (sfat.majs_sosa IS NULL OR smot.majs_sosa IS NULL)'.
361
-                ' ORDER BY schild.majs_sosa ASC')
362
-                ->execute(array(
363
-                    'tree_id' => $this->tree->getTreeId(),
364
-                    'user_id' => $this->user->getUserId(),
365
-                    'gen' => $gen - 1
366
-                ))->fetchAll(\PDO::FETCH_ASSOC);
367
-        }
368
-        return array();
369
-    }
370
-    
371
-    
372
-    
373
-    /*************
319
+		if($gen){
320
+			if(!isset($this->sosa_fam_list_by_gen[$gen])){
321
+				$this->sosa_fam_list_by_gen[$gen] = Database::prepare(
322
+					'SELECT s1.majs_sosa AS sosa, f_id AS fam'.
323
+					' FROM `##families`'.
324
+					' INNER JOIN `##maj_sosa` AS s1 ON (`##families`.f_husb = s1.majs_i_id AND `##families`.f_file = s1.majs_gedcom_id)'.
325
+					' INNER JOIN `##maj_sosa` AS s2 ON (`##families`.f_wife = s2.majs_i_id AND `##families`.f_file = s2.majs_gedcom_id)'.
326
+					' WHERE s1.majs_sosa + 1 = s2.majs_sosa'.
327
+					' AND s1.majs_gedcom_id= :tree_id AND s1.majs_user_id=:user_id'.
328
+					' AND s2.majs_gedcom_id= :tree_id AND s2.majs_user_id=:user_id'.
329
+					' AND s1.majs_gen = :gen'.
330
+					' ORDER BY s1.majs_sosa ASC'
331
+					)
332
+					->execute(array(
333
+						'tree_id' => $this->tree->getTreeId(),
334
+						'user_id' => $this->user->getUserId(),
335
+						'gen' => $gen
336
+					))
337
+					->fetchAssoc();
338
+			}
339
+			return $this->sosa_fam_list_by_gen[$gen];
340
+		}
341
+		return array();
342
+	}
343
+    
344
+	/**
345
+	 * Get an associative array of Sosa individuals in generation G who are missing parents. Keys are Sosa numbers, values individuals.
346
+	 *
347
+	 * @param number $gen Generation
348
+	 * @return array Array of Sosa individuals
349
+	 */
350
+	public function getMissingSosaListAtGeneration($gen){
351
+		if(!$this->is_setup) return array();    
352
+		if($gen){
353
+			return $this->sosa_list_by_gen[$gen] = Database::prepare(
354
+				'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'.
355
+				' FROM `##maj_sosa` schild'.
356
+				' 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)'.
357
+				' 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)'.
358
+				' WHERE schild.majs_gedcom_id = :tree_id AND schild.majs_user_id = :user_id'.
359
+				' AND schild.majs_gen = :gen'.
360
+				' AND (sfat.majs_sosa IS NULL OR smot.majs_sosa IS NULL)'.
361
+				' ORDER BY schild.majs_sosa ASC')
362
+				->execute(array(
363
+					'tree_id' => $this->tree->getTreeId(),
364
+					'user_id' => $this->user->getUserId(),
365
+					'gen' => $gen - 1
366
+				))->fetchAll(\PDO::FETCH_ASSOC);
367
+		}
368
+		return array();
369
+	}
370
+    
371
+    
372
+    
373
+	/*************
374 374
      * STATISTICS
375 375
      *************/
376
-    /**
377
-     * Get the statistic array detailed by generation.
378
-     * Statistics for each generation are:
379
-     * 	- The number of Sosa in generation
380
-     * 	- The number of Sosa up to generation
381
-     *  - The number of distinct Sosa up to generation
382
-     *  - The year of the first birth in generation
383
-     *  - The year of the last birth in generation
384
-     *  - The average year of birth in generation
385
-     *
386
-     * @return array Statistics array
387
-     */
388
-    public function getStatisticsByGeneration() {
389
-        if(!$this->is_setup) return array();
390
-        if(!$this->statistics_tab) {
391
-            $this->statistics_tab = array();
392
-            if($maxGeneration = $this->getLastGeneration()) {
393
-                for ($gen = 1; $gen <= $maxGeneration; $gen++) {
394
-                    $birthStats = $this->getStatsBirthYearInGeneration($gen);
395
-                    $this->statistics_tab[$gen] = array(
396
-                        'sosaCount'				=>	$this->getSosaCountAtGeneration($gen),
397
-                        'sosaTotalCount'		=>	$this->getSosaCountUpToGeneration($gen),
398
-                        'diffSosaTotalCount'	=>	$this->getDifferentSosaCountUpToGeneration($gen),
399
-                        'firstBirth'			=>	$birthStats['first'],
400
-                        'lastBirth'				=>	$birthStats['last'],
401
-                        'avgBirth'				=>	$birthStats['avg']
402
-                    );
403
-                }
404
-            }
405
-        }
406
-        return $this->statistics_tab;        
407
-    }
376
+	/**
377
+	 * Get the statistic array detailed by generation.
378
+	 * Statistics for each generation are:
379
+	 * 	- The number of Sosa in generation
380
+	 * 	- The number of Sosa up to generation
381
+	 *  - The number of distinct Sosa up to generation
382
+	 *  - The year of the first birth in generation
383
+	 *  - The year of the last birth in generation
384
+	 *  - The average year of birth in generation
385
+	 *
386
+	 * @return array Statistics array
387
+	 */
388
+	public function getStatisticsByGeneration() {
389
+		if(!$this->is_setup) return array();
390
+		if(!$this->statistics_tab) {
391
+			$this->statistics_tab = array();
392
+			if($maxGeneration = $this->getLastGeneration()) {
393
+				for ($gen = 1; $gen <= $maxGeneration; $gen++) {
394
+					$birthStats = $this->getStatsBirthYearInGeneration($gen);
395
+					$this->statistics_tab[$gen] = array(
396
+						'sosaCount'				=>	$this->getSosaCountAtGeneration($gen),
397
+						'sosaTotalCount'		=>	$this->getSosaCountUpToGeneration($gen),
398
+						'diffSosaTotalCount'	=>	$this->getDifferentSosaCountUpToGeneration($gen),
399
+						'firstBirth'			=>	$birthStats['first'],
400
+						'lastBirth'				=>	$birthStats['last'],
401
+						'avgBirth'				=>	$birthStats['avg']
402
+					);
403
+				}
404
+			}
405
+		}
406
+		return $this->statistics_tab;        
407
+	}
408 408
     
409 409
 	/**
410 410
 	 * How many individuals exist in the tree.
@@ -412,258 +412,258 @@  discard block
 block discarded – undo
412 412
 	 * @return int
413 413
 	 */
414 414
 	public function getTotalIndividuals() {
415
-	    if(!$this->is_setup) return 0;
416
-	    return Database::prepare(
417
-	        'SELECT SQL_CACHE COUNT(*) FROM `##individuals`' .
418
-	        ' WHERE i_file = :tree_id')
419
-	        ->execute(array('tree_id' => $this->tree->getTreeId()))
420
-	        ->fetchOne() ?: 0;
415
+		if(!$this->is_setup) return 0;
416
+		return Database::prepare(
417
+			'SELECT SQL_CACHE COUNT(*) FROM `##individuals`' .
418
+			' WHERE i_file = :tree_id')
419
+			->execute(array('tree_id' => $this->tree->getTreeId()))
420
+			->fetchOne() ?: 0;
421
+	}
422
+    
423
+	/**
424
+	 * Get the total Sosa count for all generations
425
+	 *
426
+	 * @return number Number of Sosas
427
+	 */
428
+	public function getSosaCount(){
429
+		if(!$this->is_setup) return 0;
430
+		return Database::prepare(
431
+			'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
432
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
433
+			->execute(array(
434
+				'tree_id' => $this->tree->getTreeId(), 
435
+				'user_id' => $this->user->getUserId() 
436
+			))->fetchOne() ?: 0;
437
+	}
438
+    
439
+	/**
440
+	 * Get the number of Sosa in a specific generation.
441
+	 *
442
+	 * @param number $gen Generation
443
+	 * @return number Number of Sosas in generation
444
+	 */
445
+	public function getSosaCountAtGeneration($gen){
446
+		if(!$this->is_setup) return 0;
447
+		return Database::prepare(
448
+			'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
449
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
450
+			' AND majs_gen= :gen')
451
+		->execute(array(
452
+				'tree_id' => $this->tree->getTreeId(), 
453
+				'user_id' => $this->user->getUserId(),
454
+				'gen' => $gen            
455
+		))->fetchOne() ?: 0;
421 456
 	}
422 457
     
423
-    /**
424
-     * Get the total Sosa count for all generations
425
-     *
426
-     * @return number Number of Sosas
427
-     */
428
-    public function getSosaCount(){
429
-        if(!$this->is_setup) return 0;
430
-        return Database::prepare(
431
-            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
432
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
433
-            ->execute(array(
434
-                'tree_id' => $this->tree->getTreeId(), 
435
-                'user_id' => $this->user->getUserId() 
436
-            ))->fetchOne() ?: 0;
437
-    }
438
-    
439
-    /**
440
-     * Get the number of Sosa in a specific generation.
441
-     *
442
-     * @param number $gen Generation
443
-     * @return number Number of Sosas in generation
444
-     */
445
-    public function getSosaCountAtGeneration($gen){
446
-        if(!$this->is_setup) return 0;
447
-        return Database::prepare(
448
-            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
449
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
450
-            ' AND majs_gen= :gen')
451
-        ->execute(array(
452
-                'tree_id' => $this->tree->getTreeId(), 
453
-                'user_id' => $this->user->getUserId(),
454
-                'gen' => $gen            
455
-        ))->fetchOne() ?: 0;
456
-    }
457
-    
458
-    /**
459
-     * Get the total number of Sosa up to a specific generation.
460
-     *
461
-     * @param number $gen Generation
462
-     * @return number Total number of Sosas up to generation
463
-     */
464
-    public function getSosaCountUpToGeneration($gen){
465
-        if(!$this->is_setup) return 0;
466
-        return Database::prepare(
467
-            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
468
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
469
-            ' AND majs_gen <= :gen')
470
-        ->execute(array(
471
-                'tree_id' => $this->tree->getTreeId(), 
472
-                'user_id' => $this->user->getUserId(),
473
-                'gen' => $gen 
474
-        ))->fetchOne() ?: 0;
475
-    }
476
-    
477
-    /**
478
-     * Get the total number of distinct Sosa individual for all generations.
479
-     *
480
-     * @return number Total number of distinct individual
481
-     */
482
-    public function getDifferentSosaCount(){
483
-        if(!$this->is_setup) return 0;
484
-        return Database::prepare(
485
-            'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
486
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
487
-        ->execute(array(
488
-                'tree_id' => $this->tree->getTreeId(), 
489
-                'user_id' => $this->user->getUserId()
490
-        ))->fetchOne() ?: 0;
491
-    }
492
-    
493
-    /**
494
-     * Get the number of distinct Sosa individual up to a specific generation.
495
-     *
496
-     * @param number $gen Generation
497
-     * @return number Number of distinct Sosa individuals up to generation
498
-     */
499
-    public function getDifferentSosaCountUpToGeneration($gen){
500
-        if(!$this->is_setup) return 0;
501
-        return Database::prepare(
502
-            'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
503
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
504
-            ' AND majs_gen <= :gen')
505
-        ->execute(array(
506
-                'tree_id' => $this->tree->getTreeId(), 
507
-                'user_id' => $this->user->getUserId(),
508
-                'gen' => $gen 
509
-        ))->fetchOne() ?: 0;
510
-    }
511
-    
512
-    /**
513
-     * Get an array of birth statistics for a specific generation
514
-     * Statistics are :
515
-     * 	- first : First birth year in generation
516
-     *  - last : Last birth year in generation
517
-     *  - avg : Average birth year
518
-     *
519
-     * @param number $gen Generation
520
-     * @return array Birth statistics array
521
-     */
522
-    public function getStatsBirthYearInGeneration($gen){
523
-        if(!$this->is_setup) return array('first' => 0, 'avg' => 0, 'last' => 0);
524
-        return Database::prepare(
525
-            'SELECT MIN(majs_birth_year) AS first, AVG(majs_birth_year) AS avg, MAX(majs_birth_year) AS last'.
526
-            ' FROM `##maj_sosa`' .
527
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
528
-            ' AND majs_gen=:gen AND NOT majs_birth_year = :birth_year')
529
-            ->execute(array(
530
-                'tree_id' => $this->tree->getTreeId(), 
531
-                'user_id' => $this->user->getUserId(),
532
-                'gen' => $gen,
533
-                'birth_year' => 0))
534
-            ->fetchOneRow(\PDO::FETCH_ASSOC) ?: array('first' => 0, 'avg' => 0, 'last' => 0);
535
-    }
536
-    
537
-    /**
538
-     * Get the mean generation time, based on a linear regression of birth years and generations
539
-     *
540
-     * @return number|NULL Mean generation time
541
-     */
542
-    public function getMeanGenerationTime(){
543
-        if(!$this->is_setup) return;
544
-        if(!$this->statistics_tab){
545
-            $this->getStatisticsByGeneration();
546
-        }
547
-        //Linear regression on x=generation and y=birthdate
548
-        $sum_xy = 0;
549
-        $sum_x=0;
550
-        $sum_y=0;
551
-        $sum_x2=0;
552
-        $n=count($this->statistics_tab);
553
-        foreach($this->statistics_tab as $gen=>$stats){
554
-            $sum_xy+=$gen*$stats['avgBirth'];
555
-            $sum_x+=$gen;
556
-            $sum_y+=$stats['avgBirth'];
557
-            $sum_x2+=$gen*$gen;
558
-        }
559
-        $denom=($n*$sum_x2)-($sum_x*$sum_x);
560
-        if($denom!=0){
561
-            return -(($n*$sum_xy)-($sum_x*$sum_y))/($denom);
562
-        }
563
-        return null;
564
-    }
565
-    
566
-    /**
567
-     * Return a computed array of statistics about the dispersion of ancestors across the ancestors
568
-     * at a specified generation.
569
-     * This statistics cannot be used for generations above 11, as it would cause a out of range in MySQL
570
-     * 
571
-     * Format: 
572
-     *  - key : a base-2 representation of the ancestor at generation G for which exclusive ancestors have been found,
573
-     *          -1 is used for shared ancestors
574
-     *          For instance base2(0100) = base10(4) represent the maternal grand father
575
-     *  - values: number of ancestors exclusively in the ancestors of the ancestor in key
576
-     *  
577
-     *  For instance a result at generation 3 could be :
578
-     *      array (   -1        =>  12      -> 12 ancestors are shared by the grand-parents
579
-     *                base10(1) =>  32      -> 32 ancestors are exclusive to the paternal grand-father
580
-     *                base10(2) =>  25      -> 25 ancestors are exclusive to the paternal grand-mother
581
-     *                base10(4) =>  12      -> 12 ancestors are exclusive to the maternal grand-father
582
-     *                base10(8) =>  30      -> 30 ancestors are exclusive to the maternal grand-mother
583
-     *            )
584
-     *  
585
-     * @param int $gen Reference generation
586
-     * @return array
587
-     */
588
-    public function getAncestorDispersionForGen($gen) {
589
-        if(!$this->is_setup || $gen > 11) return array();  // Going further than 11 gen will be out of range in the query
590
-        return Database::prepare(
591
-            'SELECT branches, count(i_id)'.
592
-            ' FROM ('.
593
-            '   SELECT i_id,'.
594
-            '       CASE'.
595
-            '           WHEN CEIL(LOG2(SUM(branch))) = LOG2(SUM(branch)) THEN SUM(branch)'.
596
-            '           ELSE -1'.   // We put all ancestors shared between some branches in the same bucket
597
-            '       END branches'.
598
-            '   FROM ('.
599
-            '       SELECT DISTINCT majs_i_id i_id,'.
600
-            '           POW(2, FLOOR(majs_sosa / POW(2, (majs_gen - :gen))) - POW(2, :gen -1)) branch'.
601
-            '       FROM `##maj_sosa`'.
602
-            '       WHERE majs_gedcom_id = :tree_id AND majs_user_id = :user_id'.
603
-            '           AND majs_gen >= :gen'.
604
-            '   ) indistat'.
605
-            '   GROUP BY i_id'.
606
-            ') grouped'.
607
-            ' GROUP BY branches')
608
-            ->execute(array(
609
-                'tree_id' => $this->tree->getTreeId(), 
610
-                'user_id' => $this->user->getUserId(),
611
-                'gen' => $gen
612
-            ))->fetchAssoc() ?: array();
613
-    }
614
-    
615
-    /**
616
-     * Return an array of the most duplicated root Sosa ancestors.
617
-     * The number of ancestors to return is limited by the parameter $limit.
618
-     * If several individuals are tied when reaching the limit, none of them are returned,
619
-     * which means that there can be less individuals returned than requested.
620
-     * 
621
-     * Format: 
622
-     *  - key : root Sosa individual
623
-     *  - value: number of duplications of the ancestor (e.g. 3 if it appears 3 times)
624
-     * 
625
-     * @param number $limit Maximum number of individuals to return
626
-     * @return array 
627
-     */
628
-    public function getTopMultiSosaAncestorsNoTies($limit) {
629
-        if(!$this->is_setup) return array();
630
-        return Database::prepare(
631
-            'SELECT sosa_i_id, sosa_count FROM ('.
632
-            '   SELECT'.
633
-            '       top_sosa.sosa_i_id, top_sosa.sosa_count, top_sosa.sosa_min,'.
634
-            '       @keep := IF(@prev_count = 0 OR sosa_count = @prev_count, @keep, 1) AS keep,'.
635
-            '       @prev_count := top_sosa.sosa_count AS prev_count'.
636
-            '   FROM ('.
637
-            '       SELECT'.
638
-            '           sosa.majs_i_id sosa_i_id,'.
639
-            '           COUNT(sosa.majs_sosa) sosa_count,'.
640
-            '           MIN(sosa.majs_sosa) sosa_min'.
641
-            '       FROM ##maj_sosa AS sosa'.
642
-            '       LEFT JOIN ##maj_sosa AS sosa_fat ON sosa_fat.majs_sosa = 2 * sosa.majs_sosa'.   // Link to sosa's father
643
-            '           AND sosa.majs_gedcom_id = sosa_fat.majs_gedcom_id'.
644
-            '           AND sosa.majs_user_id = sosa_fat.majs_user_id'.
645
-            '       LEFT JOIN ##maj_sosa AS sosa_mot on sosa_mot.majs_sosa = (2 * sosa.majs_sosa + 1)'.  // Link to sosa's mother
646
-            '           AND sosa.majs_gedcom_id = sosa_fat.majs_gedcom_id'.
647
-            '           AND sosa.majs_user_id = sosa_fat.majs_user_id'.
648
-            '       WHERE sosa.majs_gedcom_id = :tree_id'.
649
-            '       AND sosa.majs_user_id = :user_id'.
650
-            '       AND sosa_fat.majs_sosa IS NULL'.    // We keep only root individuals, i.e. those with no father or mother
651
-            '       AND sosa_mot.majs_sosa IS NULL'. 
652
-            '       GROUP BY sosa.majs_i_id'.
653
-            '       HAVING COUNT(sosa.majs_sosa) > 1'.   // Limit to the duplicate sosas.
654
-            '       ORDER BY COUNT(sosa.majs_sosa) DESC'.
655
-            '       LIMIT ' . ($limit + 1) . // We want to select one more than required
656
-            '   ) AS top_sosa,'.
657
-            '   (SELECT @prev_count := 0, @keep := 0) x'.
658
-            '   ORDER BY top_sosa.sosa_count ASC'.
659
-            ' ) top_sosa_list'.
660
-            ' WHERE keep = 1'.
661
-            ' ORDER BY sosa_count DESC, sosa_min ASC'
662
-            )->execute(array(
663
-                'tree_id' => $this->tree->getTreeId(),
664
-                'user_id' => $this->user->getUserId()
665
-            ))->fetchAssoc() ?: array();
666
-    }
458
+	/**
459
+	 * Get the total number of Sosa up to a specific generation.
460
+	 *
461
+	 * @param number $gen Generation
462
+	 * @return number Total number of Sosas up to generation
463
+	 */
464
+	public function getSosaCountUpToGeneration($gen){
465
+		if(!$this->is_setup) return 0;
466
+		return Database::prepare(
467
+			'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
468
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
469
+			' AND majs_gen <= :gen')
470
+		->execute(array(
471
+				'tree_id' => $this->tree->getTreeId(), 
472
+				'user_id' => $this->user->getUserId(),
473
+				'gen' => $gen 
474
+		))->fetchOne() ?: 0;
475
+	}
476
+    
477
+	/**
478
+	 * Get the total number of distinct Sosa individual for all generations.
479
+	 *
480
+	 * @return number Total number of distinct individual
481
+	 */
482
+	public function getDifferentSosaCount(){
483
+		if(!$this->is_setup) return 0;
484
+		return Database::prepare(
485
+			'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
486
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
487
+		->execute(array(
488
+				'tree_id' => $this->tree->getTreeId(), 
489
+				'user_id' => $this->user->getUserId()
490
+		))->fetchOne() ?: 0;
491
+	}
492
+    
493
+	/**
494
+	 * Get the number of distinct Sosa individual up to a specific generation.
495
+	 *
496
+	 * @param number $gen Generation
497
+	 * @return number Number of distinct Sosa individuals up to generation
498
+	 */
499
+	public function getDifferentSosaCountUpToGeneration($gen){
500
+		if(!$this->is_setup) return 0;
501
+		return Database::prepare(
502
+			'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
503
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
504
+			' AND majs_gen <= :gen')
505
+		->execute(array(
506
+				'tree_id' => $this->tree->getTreeId(), 
507
+				'user_id' => $this->user->getUserId(),
508
+				'gen' => $gen 
509
+		))->fetchOne() ?: 0;
510
+	}
511
+    
512
+	/**
513
+	 * Get an array of birth statistics for a specific generation
514
+	 * Statistics are :
515
+	 * 	- first : First birth year in generation
516
+	 *  - last : Last birth year in generation
517
+	 *  - avg : Average birth year
518
+	 *
519
+	 * @param number $gen Generation
520
+	 * @return array Birth statistics array
521
+	 */
522
+	public function getStatsBirthYearInGeneration($gen){
523
+		if(!$this->is_setup) return array('first' => 0, 'avg' => 0, 'last' => 0);
524
+		return Database::prepare(
525
+			'SELECT MIN(majs_birth_year) AS first, AVG(majs_birth_year) AS avg, MAX(majs_birth_year) AS last'.
526
+			' FROM `##maj_sosa`' .
527
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
528
+			' AND majs_gen=:gen AND NOT majs_birth_year = :birth_year')
529
+			->execute(array(
530
+				'tree_id' => $this->tree->getTreeId(), 
531
+				'user_id' => $this->user->getUserId(),
532
+				'gen' => $gen,
533
+				'birth_year' => 0))
534
+			->fetchOneRow(\PDO::FETCH_ASSOC) ?: array('first' => 0, 'avg' => 0, 'last' => 0);
535
+	}
536
+    
537
+	/**
538
+	 * Get the mean generation time, based on a linear regression of birth years and generations
539
+	 *
540
+	 * @return number|NULL Mean generation time
541
+	 */
542
+	public function getMeanGenerationTime(){
543
+		if(!$this->is_setup) return;
544
+		if(!$this->statistics_tab){
545
+			$this->getStatisticsByGeneration();
546
+		}
547
+		//Linear regression on x=generation and y=birthdate
548
+		$sum_xy = 0;
549
+		$sum_x=0;
550
+		$sum_y=0;
551
+		$sum_x2=0;
552
+		$n=count($this->statistics_tab);
553
+		foreach($this->statistics_tab as $gen=>$stats){
554
+			$sum_xy+=$gen*$stats['avgBirth'];
555
+			$sum_x+=$gen;
556
+			$sum_y+=$stats['avgBirth'];
557
+			$sum_x2+=$gen*$gen;
558
+		}
559
+		$denom=($n*$sum_x2)-($sum_x*$sum_x);
560
+		if($denom!=0){
561
+			return -(($n*$sum_xy)-($sum_x*$sum_y))/($denom);
562
+		}
563
+		return null;
564
+	}
565
+    
566
+	/**
567
+	 * Return a computed array of statistics about the dispersion of ancestors across the ancestors
568
+	 * at a specified generation.
569
+	 * This statistics cannot be used for generations above 11, as it would cause a out of range in MySQL
570
+	 * 
571
+	 * Format: 
572
+	 *  - key : a base-2 representation of the ancestor at generation G for which exclusive ancestors have been found,
573
+	 *          -1 is used for shared ancestors
574
+	 *          For instance base2(0100) = base10(4) represent the maternal grand father
575
+	 *  - values: number of ancestors exclusively in the ancestors of the ancestor in key
576
+	 *  
577
+	 *  For instance a result at generation 3 could be :
578
+	 *      array (   -1        =>  12      -> 12 ancestors are shared by the grand-parents
579
+	 *                base10(1) =>  32      -> 32 ancestors are exclusive to the paternal grand-father
580
+	 *                base10(2) =>  25      -> 25 ancestors are exclusive to the paternal grand-mother
581
+	 *                base10(4) =>  12      -> 12 ancestors are exclusive to the maternal grand-father
582
+	 *                base10(8) =>  30      -> 30 ancestors are exclusive to the maternal grand-mother
583
+	 *            )
584
+	 *  
585
+	 * @param int $gen Reference generation
586
+	 * @return array
587
+	 */
588
+	public function getAncestorDispersionForGen($gen) {
589
+		if(!$this->is_setup || $gen > 11) return array();  // Going further than 11 gen will be out of range in the query
590
+		return Database::prepare(
591
+			'SELECT branches, count(i_id)'.
592
+			' FROM ('.
593
+			'   SELECT i_id,'.
594
+			'       CASE'.
595
+			'           WHEN CEIL(LOG2(SUM(branch))) = LOG2(SUM(branch)) THEN SUM(branch)'.
596
+			'           ELSE -1'.   // We put all ancestors shared between some branches in the same bucket
597
+			'       END branches'.
598
+			'   FROM ('.
599
+			'       SELECT DISTINCT majs_i_id i_id,'.
600
+			'           POW(2, FLOOR(majs_sosa / POW(2, (majs_gen - :gen))) - POW(2, :gen -1)) branch'.
601
+			'       FROM `##maj_sosa`'.
602
+			'       WHERE majs_gedcom_id = :tree_id AND majs_user_id = :user_id'.
603
+			'           AND majs_gen >= :gen'.
604
+			'   ) indistat'.
605
+			'   GROUP BY i_id'.
606
+			') grouped'.
607
+			' GROUP BY branches')
608
+			->execute(array(
609
+				'tree_id' => $this->tree->getTreeId(), 
610
+				'user_id' => $this->user->getUserId(),
611
+				'gen' => $gen
612
+			))->fetchAssoc() ?: array();
613
+	}
614
+    
615
+	/**
616
+	 * Return an array of the most duplicated root Sosa ancestors.
617
+	 * The number of ancestors to return is limited by the parameter $limit.
618
+	 * If several individuals are tied when reaching the limit, none of them are returned,
619
+	 * which means that there can be less individuals returned than requested.
620
+	 * 
621
+	 * Format: 
622
+	 *  - key : root Sosa individual
623
+	 *  - value: number of duplications of the ancestor (e.g. 3 if it appears 3 times)
624
+	 * 
625
+	 * @param number $limit Maximum number of individuals to return
626
+	 * @return array 
627
+	 */
628
+	public function getTopMultiSosaAncestorsNoTies($limit) {
629
+		if(!$this->is_setup) return array();
630
+		return Database::prepare(
631
+			'SELECT sosa_i_id, sosa_count FROM ('.
632
+			'   SELECT'.
633
+			'       top_sosa.sosa_i_id, top_sosa.sosa_count, top_sosa.sosa_min,'.
634
+			'       @keep := IF(@prev_count = 0 OR sosa_count = @prev_count, @keep, 1) AS keep,'.
635
+			'       @prev_count := top_sosa.sosa_count AS prev_count'.
636
+			'   FROM ('.
637
+			'       SELECT'.
638
+			'           sosa.majs_i_id sosa_i_id,'.
639
+			'           COUNT(sosa.majs_sosa) sosa_count,'.
640
+			'           MIN(sosa.majs_sosa) sosa_min'.
641
+			'       FROM ##maj_sosa AS sosa'.
642
+			'       LEFT JOIN ##maj_sosa AS sosa_fat ON sosa_fat.majs_sosa = 2 * sosa.majs_sosa'.   // Link to sosa's father
643
+			'           AND sosa.majs_gedcom_id = sosa_fat.majs_gedcom_id'.
644
+			'           AND sosa.majs_user_id = sosa_fat.majs_user_id'.
645
+			'       LEFT JOIN ##maj_sosa AS sosa_mot on sosa_mot.majs_sosa = (2 * sosa.majs_sosa + 1)'.  // Link to sosa's mother
646
+			'           AND sosa.majs_gedcom_id = sosa_fat.majs_gedcom_id'.
647
+			'           AND sosa.majs_user_id = sosa_fat.majs_user_id'.
648
+			'       WHERE sosa.majs_gedcom_id = :tree_id'.
649
+			'       AND sosa.majs_user_id = :user_id'.
650
+			'       AND sosa_fat.majs_sosa IS NULL'.    // We keep only root individuals, i.e. those with no father or mother
651
+			'       AND sosa_mot.majs_sosa IS NULL'. 
652
+			'       GROUP BY sosa.majs_i_id'.
653
+			'       HAVING COUNT(sosa.majs_sosa) > 1'.   // Limit to the duplicate sosas.
654
+			'       ORDER BY COUNT(sosa.majs_sosa) DESC'.
655
+			'       LIMIT ' . ($limit + 1) . // We want to select one more than required
656
+			'   ) AS top_sosa,'.
657
+			'   (SELECT @prev_count := 0, @keep := 0) x'.
658
+			'   ORDER BY top_sosa.sosa_count ASC'.
659
+			' ) top_sosa_list'.
660
+			' WHERE keep = 1'.
661
+			' ORDER BY sosa_count DESC, sosa_min ASC'
662
+			)->execute(array(
663
+				'tree_id' => $this->tree->getTreeId(),
664
+				'user_id' => $this->user->getUserId()
665
+			))->fetchAssoc() ?: array();
666
+	}
667 667
     
668 668
                
669 669
 }
Please login to merge, or discard this patch.
Spacing   +83 added lines, -83 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'
@@ -260,13 +260,13 @@  discard block
 block discarded – undo
260 260
      *
261 261
      * @return array Associative array of Sosa ancestors, with their generation, comma separated
262 262
      */
263
-    public function getAllSosaWithGenerations(){
264
-        if(!$this->is_setup) return array();
263
+    public function getAllSosaWithGenerations() {
264
+        if (!$this->is_setup) return array();
265 265
         return Database::prepare(
266
-            'SELECT majs_i_id AS indi,' .
267
-            ' GROUP_CONCAT(DISTINCT majs_gen ORDER BY majs_gen ASC SEPARATOR ",") AS generations' .
268
-            ' FROM `##maj_sosa`' .
269
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id' .
266
+            'SELECT majs_i_id AS indi,'.
267
+            ' GROUP_CONCAT(DISTINCT majs_gen ORDER BY majs_gen ASC SEPARATOR ",") AS generations'.
268
+            ' FROM `##maj_sosa`'.
269
+            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
270 270
             ' GROUP BY majs_i_id'
271 271
         )->execute(array(
272 272
             'tree_id' => $this->tree->getTreeId(),
@@ -280,13 +280,13 @@  discard block
 block discarded – undo
280 280
      * @param number $gen Generation
281 281
      * @return array Array of Sosa individuals
282 282
      */
283
-    public function getSosaListAtGeneration($gen){
284
-        if(!$this->is_setup) return array();
285
-        if(!$this->sosa_list_by_gen)
283
+    public function getSosaListAtGeneration($gen) {
284
+        if (!$this->is_setup) return array();
285
+        if (!$this->sosa_list_by_gen)
286 286
             $this->sosa_list_by_gen = array();
287 287
         
288
-        if($gen){
289
-            if(!isset($this->sosa_list_by_gen[$gen])){
288
+        if ($gen) {
289
+            if (!isset($this->sosa_list_by_gen[$gen])) {
290 290
                 $this->sosa_list_by_gen[$gen] = Database::prepare(
291 291
                     'SELECT majs_sosa AS sosa, majs_i_id AS indi'.
292 292
                     ' FROM `##maj_sosa`'.
@@ -311,13 +311,13 @@  discard block
 block discarded – undo
311 311
      * @param number $gen Generation
312 312
      * @return array Array of Sosa families
313 313
      */
314
-    public function getFamilySosaListAtGeneration($gen){
315
-        if(!$this->is_setup) return array();
316
-        if(!$this->sosa_fam_list_by_gen)
314
+    public function getFamilySosaListAtGeneration($gen) {
315
+        if (!$this->is_setup) return array();
316
+        if (!$this->sosa_fam_list_by_gen)
317 317
             $this->sosa_fam_list_by_gen = array();
318 318
         
319
-        if($gen){
320
-            if(!isset($this->sosa_fam_list_by_gen[$gen])){
319
+        if ($gen) {
320
+            if (!isset($this->sosa_fam_list_by_gen[$gen])) {
321 321
                 $this->sosa_fam_list_by_gen[$gen] = Database::prepare(
322 322
                     'SELECT s1.majs_sosa AS sosa, f_id AS fam'.
323 323
                     ' FROM `##families`'.
@@ -347,9 +347,9 @@  discard block
 block discarded – undo
347 347
      * @param number $gen Generation
348 348
      * @return array Array of Sosa individuals
349 349
      */
350
-    public function getMissingSosaListAtGeneration($gen){
351
-        if(!$this->is_setup) return array();    
352
-        if($gen){
350
+    public function getMissingSosaListAtGeneration($gen) {
351
+        if (!$this->is_setup) return array();    
352
+        if ($gen) {
353 353
             return $this->sosa_list_by_gen[$gen] = Database::prepare(
354 354
                 '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'.
355 355
                 ' FROM `##maj_sosa` schild'.
@@ -386,10 +386,10 @@  discard block
 block discarded – undo
386 386
      * @return array Statistics array
387 387
      */
388 388
     public function getStatisticsByGeneration() {
389
-        if(!$this->is_setup) return array();
390
-        if(!$this->statistics_tab) {
389
+        if (!$this->is_setup) return array();
390
+        if (!$this->statistics_tab) {
391 391
             $this->statistics_tab = array();
392
-            if($maxGeneration = $this->getLastGeneration()) {
392
+            if ($maxGeneration = $this->getLastGeneration()) {
393 393
                 for ($gen = 1; $gen <= $maxGeneration; $gen++) {
394 394
                     $birthStats = $this->getStatsBirthYearInGeneration($gen);
395 395
                     $this->statistics_tab[$gen] = array(
@@ -412,9 +412,9 @@  discard block
 block discarded – undo
412 412
 	 * @return int
413 413
 	 */
414 414
 	public function getTotalIndividuals() {
415
-	    if(!$this->is_setup) return 0;
415
+	    if (!$this->is_setup) return 0;
416 416
 	    return Database::prepare(
417
-	        'SELECT SQL_CACHE COUNT(*) FROM `##individuals`' .
417
+	        'SELECT SQL_CACHE COUNT(*) FROM `##individuals`'.
418 418
 	        ' WHERE i_file = :tree_id')
419 419
 	        ->execute(array('tree_id' => $this->tree->getTreeId()))
420 420
 	        ->fetchOne() ?: 0;
@@ -425,10 +425,10 @@  discard block
 block discarded – undo
425 425
      *
426 426
      * @return number Number of Sosas
427 427
      */
428
-    public function getSosaCount(){
429
-        if(!$this->is_setup) return 0;
428
+    public function getSosaCount() {
429
+        if (!$this->is_setup) return 0;
430 430
         return Database::prepare(
431
-            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
431
+            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`'.
432 432
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
433 433
             ->execute(array(
434 434
                 'tree_id' => $this->tree->getTreeId(), 
@@ -442,10 +442,10 @@  discard block
 block discarded – undo
442 442
      * @param number $gen Generation
443 443
      * @return number Number of Sosas in generation
444 444
      */
445
-    public function getSosaCountAtGeneration($gen){
446
-        if(!$this->is_setup) return 0;
445
+    public function getSosaCountAtGeneration($gen) {
446
+        if (!$this->is_setup) return 0;
447 447
         return Database::prepare(
448
-            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
448
+            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`'.
449 449
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
450 450
             ' AND majs_gen= :gen')
451 451
         ->execute(array(
@@ -461,10 +461,10 @@  discard block
 block discarded – undo
461 461
      * @param number $gen Generation
462 462
      * @return number Total number of Sosas up to generation
463 463
      */
464
-    public function getSosaCountUpToGeneration($gen){
465
-        if(!$this->is_setup) return 0;
464
+    public function getSosaCountUpToGeneration($gen) {
465
+        if (!$this->is_setup) return 0;
466 466
         return Database::prepare(
467
-            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
467
+            'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`'.
468 468
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
469 469
             ' AND majs_gen <= :gen')
470 470
         ->execute(array(
@@ -479,10 +479,10 @@  discard block
 block discarded – undo
479 479
      *
480 480
      * @return number Total number of distinct individual
481 481
      */
482
-    public function getDifferentSosaCount(){
483
-        if(!$this->is_setup) return 0;
482
+    public function getDifferentSosaCount() {
483
+        if (!$this->is_setup) return 0;
484 484
         return Database::prepare(
485
-            'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
485
+            'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`'.
486 486
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
487 487
         ->execute(array(
488 488
                 'tree_id' => $this->tree->getTreeId(), 
@@ -496,10 +496,10 @@  discard block
 block discarded – undo
496 496
      * @param number $gen Generation
497 497
      * @return number Number of distinct Sosa individuals up to generation
498 498
      */
499
-    public function getDifferentSosaCountUpToGeneration($gen){
500
-        if(!$this->is_setup) return 0;
499
+    public function getDifferentSosaCountUpToGeneration($gen) {
500
+        if (!$this->is_setup) return 0;
501 501
         return Database::prepare(
502
-            'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
502
+            'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`'.
503 503
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
504 504
             ' AND majs_gen <= :gen')
505 505
         ->execute(array(
@@ -519,11 +519,11 @@  discard block
 block discarded – undo
519 519
      * @param number $gen Generation
520 520
      * @return array Birth statistics array
521 521
      */
522
-    public function getStatsBirthYearInGeneration($gen){
523
-        if(!$this->is_setup) return array('first' => 0, 'avg' => 0, 'last' => 0);
522
+    public function getStatsBirthYearInGeneration($gen) {
523
+        if (!$this->is_setup) return array('first' => 0, 'avg' => 0, 'last' => 0);
524 524
         return Database::prepare(
525 525
             'SELECT MIN(majs_birth_year) AS first, AVG(majs_birth_year) AS avg, MAX(majs_birth_year) AS last'.
526
-            ' FROM `##maj_sosa`' .
526
+            ' FROM `##maj_sosa`'.
527 527
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
528 528
             ' AND majs_gen=:gen AND NOT majs_birth_year = :birth_year')
529 529
             ->execute(array(
@@ -539,26 +539,26 @@  discard block
 block discarded – undo
539 539
      *
540 540
      * @return number|NULL Mean generation time
541 541
      */
542
-    public function getMeanGenerationTime(){
543
-        if(!$this->is_setup) return;
544
-        if(!$this->statistics_tab){
542
+    public function getMeanGenerationTime() {
543
+        if (!$this->is_setup) return;
544
+        if (!$this->statistics_tab) {
545 545
             $this->getStatisticsByGeneration();
546 546
         }
547 547
         //Linear regression on x=generation and y=birthdate
548 548
         $sum_xy = 0;
549
-        $sum_x=0;
550
-        $sum_y=0;
551
-        $sum_x2=0;
552
-        $n=count($this->statistics_tab);
553
-        foreach($this->statistics_tab as $gen=>$stats){
554
-            $sum_xy+=$gen*$stats['avgBirth'];
555
-            $sum_x+=$gen;
556
-            $sum_y+=$stats['avgBirth'];
557
-            $sum_x2+=$gen*$gen;
549
+        $sum_x = 0;
550
+        $sum_y = 0;
551
+        $sum_x2 = 0;
552
+        $n = count($this->statistics_tab);
553
+        foreach ($this->statistics_tab as $gen=>$stats) {
554
+            $sum_xy += $gen * $stats['avgBirth'];
555
+            $sum_x += $gen;
556
+            $sum_y += $stats['avgBirth'];
557
+            $sum_x2 += $gen * $gen;
558 558
         }
559
-        $denom=($n*$sum_x2)-($sum_x*$sum_x);
560
-        if($denom!=0){
561
-            return -(($n*$sum_xy)-($sum_x*$sum_y))/($denom);
559
+        $denom = ($n * $sum_x2) - ($sum_x * $sum_x);
560
+        if ($denom != 0) {
561
+            return -(($n * $sum_xy) - ($sum_x * $sum_y)) / ($denom);
562 562
         }
563 563
         return null;
564 564
     }
@@ -586,14 +586,14 @@  discard block
 block discarded – undo
586 586
      * @return array
587 587
      */
588 588
     public function getAncestorDispersionForGen($gen) {
589
-        if(!$this->is_setup || $gen > 11) return array();  // Going further than 11 gen will be out of range in the query
589
+        if (!$this->is_setup || $gen > 11) return array(); // Going further than 11 gen will be out of range in the query
590 590
         return Database::prepare(
591 591
             'SELECT branches, count(i_id)'.
592 592
             ' FROM ('.
593 593
             '   SELECT i_id,'.
594 594
             '       CASE'.
595 595
             '           WHEN CEIL(LOG2(SUM(branch))) = LOG2(SUM(branch)) THEN SUM(branch)'.
596
-            '           ELSE -1'.   // We put all ancestors shared between some branches in the same bucket
596
+            '           ELSE -1'.// We put all ancestors shared between some branches in the same bucket
597 597
             '       END branches'.
598 598
             '   FROM ('.
599 599
             '       SELECT DISTINCT majs_i_id i_id,'.
@@ -626,7 +626,7 @@  discard block
 block discarded – undo
626 626
      * @return array 
627 627
      */
628 628
     public function getTopMultiSosaAncestorsNoTies($limit) {
629
-        if(!$this->is_setup) return array();
629
+        if (!$this->is_setup) return array();
630 630
         return Database::prepare(
631 631
             'SELECT sosa_i_id, sosa_count FROM ('.
632 632
             '   SELECT'.
@@ -639,20 +639,20 @@  discard block
 block discarded – undo
639 639
             '           COUNT(sosa.majs_sosa) sosa_count,'.
640 640
             '           MIN(sosa.majs_sosa) sosa_min'.
641 641
             '       FROM ##maj_sosa AS sosa'.
642
-            '       LEFT JOIN ##maj_sosa AS sosa_fat ON sosa_fat.majs_sosa = 2 * sosa.majs_sosa'.   // Link to sosa's father
642
+            '       LEFT JOIN ##maj_sosa AS sosa_fat ON sosa_fat.majs_sosa = 2 * sosa.majs_sosa'.// Link to sosa's father
643 643
             '           AND sosa.majs_gedcom_id = sosa_fat.majs_gedcom_id'.
644 644
             '           AND sosa.majs_user_id = sosa_fat.majs_user_id'.
645
-            '       LEFT JOIN ##maj_sosa AS sosa_mot on sosa_mot.majs_sosa = (2 * sosa.majs_sosa + 1)'.  // Link to sosa's mother
645
+            '       LEFT JOIN ##maj_sosa AS sosa_mot on sosa_mot.majs_sosa = (2 * sosa.majs_sosa + 1)'.// Link to sosa's mother
646 646
             '           AND sosa.majs_gedcom_id = sosa_fat.majs_gedcom_id'.
647 647
             '           AND sosa.majs_user_id = sosa_fat.majs_user_id'.
648 648
             '       WHERE sosa.majs_gedcom_id = :tree_id'.
649 649
             '       AND sosa.majs_user_id = :user_id'.
650
-            '       AND sosa_fat.majs_sosa IS NULL'.    // We keep only root individuals, i.e. those with no father or mother
650
+            '       AND sosa_fat.majs_sosa IS NULL'.// We keep only root individuals, i.e. those with no father or mother
651 651
             '       AND sosa_mot.majs_sosa IS NULL'. 
652 652
             '       GROUP BY sosa.majs_i_id'.
653
-            '       HAVING COUNT(sosa.majs_sosa) > 1'.   // Limit to the duplicate sosas.
653
+            '       HAVING COUNT(sosa.majs_sosa) > 1'.// Limit to the duplicate sosas.
654 654
             '       ORDER BY COUNT(sosa.majs_sosa) DESC'.
655
-            '       LIMIT ' . ($limit + 1) . // We want to select one more than required
655
+            '       LIMIT '.($limit + 1).// We want to select one more than required
656 656
             '   ) AS top_sosa,'.
657 657
             '   (SELECT @prev_count := 0, @keep := 0) x'.
658 658
             '   ORDER BY top_sosa.sosa_count ASC'.
Please login to merge, or discard this patch.
Braces   +77 added lines, -30 removed lines patch added patch discarded remove patch
@@ -84,21 +84,25 @@  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) 
88
-            self::$default_user = User::find(-1);
87
+        if(self::$default_user === null) {
88
+                    self::$default_user = User::find(-1);
89
+        }
89 90
         
90 91
         $this->tree = $tree;
91 92
         $this->user = $user;
92 93
         $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;
94
+        if($this->user === null) {
95
+        	$this->user = Auth::user();
96
+        }
97
+        if(strlen($this->user->getUserId()) == 0) {
98
+        	$this->user = self::$default_user;
99
+        }
95 100
         
96 101
         // Check if the user, or the default user, has a root already setup;
97 102
         if(empty($this->getRootIndiId())) {
98 103
             if($this->user == self::$default_user) {  // If the default user is not setup
99 104
                 $this->is_setup = false;
100
-            }
101
-            else {
105
+            } else {
102 106
                 $this->user = self::$default_user;
103 107
                 $this->is_setup = $this->getRootIndiId() === null;
104 108
             }            
@@ -141,7 +145,9 @@  discard block
 block discarded – undo
141 145
      * Remove all Sosa entries related to the gedcom file and user
142 146
      */
143 147
     public function deleteAll() {
144
-        if(!$this->is_setup) return;
148
+        if(!$this->is_setup) {
149
+        	return;
150
+        }
145 151
         Database::prepare(
146 152
             'DELETE FROM `##maj_sosa`'.
147 153
             ' WHERE majs_gedcom_id= :tree_id and majs_user_id = :user_id ')
@@ -157,7 +163,9 @@  discard block
 block discarded – undo
157 163
      * @param int $sosa
158 164
      */
159 165
     public function deleteAncestors($sosa) {
160
-        if(!$this->is_setup) return;
166
+        if(!$this->is_setup) {
167
+        	return;
168
+        }
161 169
         $gen = Functions::getGeneration($sosa);
162 170
         Database::prepare(
163 171
             'DELETE FROM `##maj_sosa`'.
@@ -177,7 +185,9 @@  discard block
 block discarded – undo
177 185
      * @param array $sosa_records
178 186
      */
179 187
     public function insertOrUpdate($sosa_records) {
180
-        if(!$this->is_setup) return;
188
+        if(!$this->is_setup) {
189
+        	return;
190
+        }
181 191
         
182 192
         $treeid = $this->tree->getTreeId();
183 193
         $userid = $this->user->getUserId();
@@ -224,7 +234,9 @@  discard block
 block discarded – undo
224 234
      * @return array Array of sosa numbers
225 235
      */
226 236
     public function getSosaNumbers(Individual $indi) {
227
-        if(!$this->is_setup) return array();
237
+        if(!$this->is_setup) {
238
+        	return array();
239
+        }
228 240
         return Database::prepare(
229 241
                 'SELECT majs_sosa, majs_gen FROM `##maj_sosa`'.
230 242
                 ' WHERE majs_i_id=:indi_id AND majs_gedcom_id=:tree_id AND majs_user_id=:user_id'
@@ -241,7 +253,9 @@  discard block
 block discarded – undo
241 253
      * @return number Last generation if found, 1 otherwise
242 254
      */
243 255
     public function getLastGeneration() {
244
-        if(!$this->is_setup) return;
256
+        if(!$this->is_setup) {
257
+        	return;
258
+        }
245 259
         return Database::prepare(
246 260
                 'SELECT MAX(majs_gen) FROM `##maj_sosa`'.
247 261
                 ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'
@@ -261,7 +275,9 @@  discard block
 block discarded – undo
261 275
      * @return array Associative array of Sosa ancestors, with their generation, comma separated
262 276
      */
263 277
     public function getAllSosaWithGenerations(){
264
-        if(!$this->is_setup) return array();
278
+        if(!$this->is_setup) {
279
+        	return array();
280
+        }
265 281
         return Database::prepare(
266 282
             'SELECT majs_i_id AS indi,' .
267 283
             ' GROUP_CONCAT(DISTINCT majs_gen ORDER BY majs_gen ASC SEPARATOR ",") AS generations' .
@@ -281,9 +297,12 @@  discard block
 block discarded – undo
281 297
      * @return array Array of Sosa individuals
282 298
      */
283 299
     public function getSosaListAtGeneration($gen){
284
-        if(!$this->is_setup) return array();
285
-        if(!$this->sosa_list_by_gen)
286
-            $this->sosa_list_by_gen = array();
300
+        if(!$this->is_setup) {
301
+        	return array();
302
+        }
303
+        if(!$this->sosa_list_by_gen) {
304
+                    $this->sosa_list_by_gen = array();
305
+        }
287 306
         
288 307
         if($gen){
289 308
             if(!isset($this->sosa_list_by_gen[$gen])){
@@ -312,9 +331,12 @@  discard block
 block discarded – undo
312 331
      * @return array Array of Sosa families
313 332
      */
314 333
     public function getFamilySosaListAtGeneration($gen){
315
-        if(!$this->is_setup) return array();
316
-        if(!$this->sosa_fam_list_by_gen)
317
-            $this->sosa_fam_list_by_gen = array();
334
+        if(!$this->is_setup) {
335
+        	return array();
336
+        }
337
+        if(!$this->sosa_fam_list_by_gen) {
338
+                    $this->sosa_fam_list_by_gen = array();
339
+        }
318 340
         
319 341
         if($gen){
320 342
             if(!isset($this->sosa_fam_list_by_gen[$gen])){
@@ -348,7 +370,9 @@  discard block
 block discarded – undo
348 370
      * @return array Array of Sosa individuals
349 371
      */
350 372
     public function getMissingSosaListAtGeneration($gen){
351
-        if(!$this->is_setup) return array();    
373
+        if(!$this->is_setup) {
374
+        	return array();
375
+        }
352 376
         if($gen){
353 377
             return $this->sosa_list_by_gen[$gen] = Database::prepare(
354 378
                 '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'.
@@ -386,7 +410,9 @@  discard block
 block discarded – undo
386 410
      * @return array Statistics array
387 411
      */
388 412
     public function getStatisticsByGeneration() {
389
-        if(!$this->is_setup) return array();
413
+        if(!$this->is_setup) {
414
+        	return array();
415
+        }
390 416
         if(!$this->statistics_tab) {
391 417
             $this->statistics_tab = array();
392 418
             if($maxGeneration = $this->getLastGeneration()) {
@@ -412,7 +438,9 @@  discard block
 block discarded – undo
412 438
 	 * @return int
413 439
 	 */
414 440
 	public function getTotalIndividuals() {
415
-	    if(!$this->is_setup) return 0;
441
+	    if(!$this->is_setup) {
442
+	    	return 0;
443
+	    }
416 444
 	    return Database::prepare(
417 445
 	        'SELECT SQL_CACHE COUNT(*) FROM `##individuals`' .
418 446
 	        ' WHERE i_file = :tree_id')
@@ -426,7 +454,9 @@  discard block
 block discarded – undo
426 454
      * @return number Number of Sosas
427 455
      */
428 456
     public function getSosaCount(){
429
-        if(!$this->is_setup) return 0;
457
+        if(!$this->is_setup) {
458
+        	return 0;
459
+        }
430 460
         return Database::prepare(
431 461
             'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
432 462
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
@@ -443,7 +473,9 @@  discard block
 block discarded – undo
443 473
      * @return number Number of Sosas in generation
444 474
      */
445 475
     public function getSosaCountAtGeneration($gen){
446
-        if(!$this->is_setup) return 0;
476
+        if(!$this->is_setup) {
477
+        	return 0;
478
+        }
447 479
         return Database::prepare(
448 480
             'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
449 481
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
@@ -462,7 +494,9 @@  discard block
 block discarded – undo
462 494
      * @return number Total number of Sosas up to generation
463 495
      */
464 496
     public function getSosaCountUpToGeneration($gen){
465
-        if(!$this->is_setup) return 0;
497
+        if(!$this->is_setup) {
498
+        	return 0;
499
+        }
466 500
         return Database::prepare(
467 501
             'SELECT SQL_CACHE COUNT(majs_sosa) FROM `##maj_sosa`' .
468 502
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
@@ -480,7 +514,9 @@  discard block
 block discarded – undo
480 514
      * @return number Total number of distinct individual
481 515
      */
482 516
     public function getDifferentSosaCount(){
483
-        if(!$this->is_setup) return 0;
517
+        if(!$this->is_setup) {
518
+        	return 0;
519
+        }
484 520
         return Database::prepare(
485 521
             'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
486 522
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
@@ -497,7 +533,9 @@  discard block
 block discarded – undo
497 533
      * @return number Number of distinct Sosa individuals up to generation
498 534
      */
499 535
     public function getDifferentSosaCountUpToGeneration($gen){
500
-        if(!$this->is_setup) return 0;
536
+        if(!$this->is_setup) {
537
+        	return 0;
538
+        }
501 539
         return Database::prepare(
502 540
             'SELECT SQL_CACHE COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
503 541
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
@@ -520,7 +558,9 @@  discard block
 block discarded – undo
520 558
      * @return array Birth statistics array
521 559
      */
522 560
     public function getStatsBirthYearInGeneration($gen){
523
-        if(!$this->is_setup) return array('first' => 0, 'avg' => 0, 'last' => 0);
561
+        if(!$this->is_setup) {
562
+        	return array('first' => 0, 'avg' => 0, 'last' => 0);
563
+        }
524 564
         return Database::prepare(
525 565
             'SELECT MIN(majs_birth_year) AS first, AVG(majs_birth_year) AS avg, MAX(majs_birth_year) AS last'.
526 566
             ' FROM `##maj_sosa`' .
@@ -540,7 +580,9 @@  discard block
 block discarded – undo
540 580
      * @return number|NULL Mean generation time
541 581
      */
542 582
     public function getMeanGenerationTime(){
543
-        if(!$this->is_setup) return;
583
+        if(!$this->is_setup) {
584
+        	return;
585
+        }
544 586
         if(!$this->statistics_tab){
545 587
             $this->getStatisticsByGeneration();
546 588
         }
@@ -586,7 +628,10 @@  discard block
 block discarded – undo
586 628
      * @return array
587 629
      */
588 630
     public function getAncestorDispersionForGen($gen) {
589
-        if(!$this->is_setup || $gen > 11) return array();  // Going further than 11 gen will be out of range in the query
631
+        if(!$this->is_setup || $gen > 11) {
632
+        	return array();
633
+        }
634
+        // Going further than 11 gen will be out of range in the query
590 635
         return Database::prepare(
591 636
             'SELECT branches, count(i_id)'.
592 637
             ' FROM ('.
@@ -626,7 +671,9 @@  discard block
 block discarded – undo
626 671
      * @return array 
627 672
      */
628 673
     public function getTopMultiSosaAncestorsNoTies($limit) {
629
-        if(!$this->is_setup) return array();
674
+        if(!$this->is_setup) {
675
+        	return array();
676
+        }
630 677
         return Database::prepare(
631 678
             'SELECT sosa_i_id, sosa_count FROM ('.
632 679
             '   SELECT'.
Please login to merge, or discard this patch.
src/Webtrees/Module/Sosa/Views/SosaStatsView.php 2 patches
Indentation   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -23,8 +23,8 @@  discard block
 block discarded – undo
23 23
 	 * {@inhericDoc}
24 24
 	 * @see \MyArtJaub\Webtrees\Mvc\View\AbstractView::renderContent()
25 25
 	 */
26
-    protected function renderContent() {      
27
-        ?>                
26
+	protected function renderContent() {      
27
+		?>                
28 28
         <div id="maj-sosa-stats-page">
29 29
 			<h2><?php echo $this->data->get('title'); ?></h2>
30 30
 			
@@ -36,7 +36,7 @@  discard block
 block discarded – undo
36 36
 			<?php } ?>
37 37
 			
38 38
 			<?php  if($this->data->get('is_setup')) {  
39
-			    $general_stats = $this->data->get('general_stats'); ?>
39
+				$general_stats = $this->data->get('general_stats'); ?>
40 40
 			<h3><?php echo I18N::translate('General statistics'); ?></h3>
41 41
 			<div class="maj-table">
42 42
 				<div class="maj-row">
@@ -140,13 +140,13 @@  discard block
 block discarded – undo
140 140
 			    <div class="maj-row">
141 141
 			    	<div class="label"><?= I18N::translate('%s times', I18N::number($count)); ?></div>
142 142
 			    	<div class="value"><?php 
143
-			    	echo implode(
144
-			    	    I18N::$list_separator, 
145
-			    	    array_map(function(Individual $indi) {
146
-			    	        return '<a href="'. $indi->getHtmlUrl(). '">'. $indi->getFullName() . '&nbsp;' . $indi->getSexImage() . '</a>';
147
-			    	    }, $indis)
148
-			    	);
149
-			    	?></div>
143
+					echo implode(
144
+						I18N::$list_separator, 
145
+						array_map(function(Individual $indi) {
146
+							return '<a href="'. $indi->getHtmlUrl(). '">'. $indi->getFullName() . '&nbsp;' . $indi->getSexImage() . '</a>';
147
+						}, $indis)
148
+					);
149
+					?></div>
150 150
 				</div>
151 151
 			<?php } ?>
152 152
 			</div>
@@ -162,6 +162,6 @@  discard block
 block discarded – undo
162 162
 			<?php   } else { ?>
163 163
 			<div class="center warning"><?php echo I18N::translate('No Sosa root individual has been defined.'); ?></div>
164 164
 			<?php }     
165
-    }
165
+	}
166 166
     
167 167
 }
168 168
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -31,11 +31,11 @@  discard block
 block discarded – undo
31 31
 			<?php 
32 32
 			/** @var \Fisharebest\Webtrees\Individual $root_indi */
33 33
 			$root_indi = $this->data->get('root_indi');
34
-			if($root_indi !== null && $root_indi->canShowName()) { ?>
34
+			if ($root_indi !== null && $root_indi->canShowName()) { ?>
35 35
 			<h4 class="center"><?= I18N::translate('%s: %s', I18N::translate('Root individual'), $root_indi->getFullName()); ?><h4>
36 36
 			<?php } ?>
37 37
 			
38
-			<?php  if($this->data->get('is_setup')) {  
38
+			<?php  if ($this->data->get('is_setup')) {  
39 39
 			    $general_stats = $this->data->get('general_stats'); ?>
40 40
 			<h3><?php echo I18N::translate('General statistics'); ?></h3>
41 41
 			<div class="maj-table">
@@ -57,7 +57,7 @@  discard block
 block discarded – undo
57 57
 				</div>
58 58
 				<div class="maj-row">
59 59
 					<div class="label"><?php echo I18N::translate('Mean generation time'); ?></div>
60
-					<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
+					<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>
61 61
 				</div>
62 62
 			</div>
63 63
 			
@@ -97,7 +97,7 @@  discard block
 block discarded – undo
97 97
 					</tr>
98 98
 				</thead>
99 99
 				<tbody>
100
-					<?php foreach($this->data->get('generation_stats') as $gen => $row) { ?>
100
+					<?php foreach ($this->data->get('generation_stats') as $gen => $row) { ?>
101 101
 					<tr class="maj-row">
102 102
 						<td class="label"><?php echo I18N::translate('<strong>G%d</strong>', $gen); ?></td>
103 103
 						<td class="label"><?php echo I18N::translate('%1$s <> %2$s', $row['gen_min_birth'], $row['gen_max_birth']); ?></td>
@@ -111,7 +111,7 @@  discard block
 block discarded – undo
111 111
 						<td class="value"><?php echo I18N::number($row['different']); ?></td>
112 112
 						<td class="value left percent_container">
113 113
 							<div class="percent_frame">
114
-								<div class="percent_cell" style="width:<?php echo 100*$row['perc_different'] ?>%;">
114
+								<div class="percent_cell" style="width:<?php echo 100 * $row['perc_different'] ?>%;">
115 115
 									&nbsp;<?php echo I18N::percentage($row['perc_different']); ?>&nbsp;
116 116
 								</div>
117 117
 							</div>
@@ -124,7 +124,7 @@  discard block
 block discarded – undo
124 124
 				<tfoot>
125 125
 					<tr class="maj-row">
126 126
 						<td class="label" colspan="13">
127
-							<?php echo I18N::translate('Generation-equivalent: %s generations', I18N::number($this->data->get('equivalent_gen'),2)); ?>
127
+							<?php echo I18N::translate('Generation-equivalent: %s generations', I18N::number($this->data->get('equivalent_gen'), 2)); ?>
128 128
 						</td>
129 129
 					</tr>
130 130
 				</tfoot>
@@ -133,17 +133,17 @@  discard block
 block discarded – undo
133 133
 			
134 134
 			<?php  
135 135
 			$top10_multi_ancestors = $this->data->get('top10multiancestors');
136
-			if(count($top10_multi_ancestors) > 0) { ?>
136
+			if (count($top10_multi_ancestors) > 0) { ?>
137 137
 			<h3><?= I18N::translate('Most duplicated root Sosa ancestors'); ?></h3>
138 138
 			<div class="maj-table">
139
-			<?php foreach($top10_multi_ancestors as $count => $indis) { ?>
139
+			<?php foreach ($top10_multi_ancestors as $count => $indis) { ?>
140 140
 			    <div class="maj-row">
141 141
 			    	<div class="label"><?= I18N::translate('%s times', I18N::number($count)); ?></div>
142 142
 			    	<div class="value"><?php 
143 143
 			    	echo implode(
144 144
 			    	    I18N::$list_separator, 
145 145
 			    	    array_map(function(Individual $indi) {
146
-			    	        return '<a href="'. $indi->getHtmlUrl(). '">'. $indi->getFullName() . '&nbsp;' . $indi->getSexImage() . '</a>';
146
+			    	        return '<a href="'.$indi->getHtmlUrl().'">'.$indi->getFullName().'&nbsp;'.$indi->getSexImage().'</a>';
147 147
 			    	    }, $indis)
148 148
 			    	);
149 149
 			    	?></div>
@@ -154,8 +154,8 @@  discard block
 block discarded – undo
154 154
 			
155 155
 			<h3><?php echo I18N::translate('Known Sosa ancestors\' family dispersion'); ?></h3>
156 156
 			<div class="center">
157
-				<?php echo $this->data->get('chart_img_g2') ?: '' ; ?>
158
-				<?php echo $this->data->get('chart_img_g3') ?: '' ; ?>				
157
+				<?php echo $this->data->get('chart_img_g2') ?: ''; ?>
158
+				<?php echo $this->data->get('chart_img_g3') ?: ''; ?>				
159 159
 				<!--  <canvas id="chart_ancestors_g2" width="300" height="300"></canvas>  -->
160 160
 			</div>
161 161
 			
Please login to merge, or discard this patch.
src/Webtrees/Module/Sosa/SosaStatsController.php 2 patches
Indentation   +192 added lines, -192 removed lines patch added patch discarded remove patch
@@ -27,229 +27,229 @@
 block discarded – undo
27 27
  */
28 28
 class SosaStatsController extends MvcController
29 29
 {
30
-    /**
31
-     * Sosa Provider for the controller
32
-     * @var SosaProvider $sosa_provider
33
-     */
34
-    protected $sosa_provider;
30
+	/**
31
+	 * Sosa Provider for the controller
32
+	 * @var SosaProvider $sosa_provider
33
+	 */
34
+	protected $sosa_provider;
35 35
     
36
-    /**
37
-     * Constructor for SosaStatsController
38
-     * @param AbstractModule $module
39
-     */
40
-    public function __construct(AbstractModule $module) {
41
-        parent::__construct($module);
36
+	/**
37
+	 * Constructor for SosaStatsController
38
+	 * @param AbstractModule $module
39
+	 */
40
+	public function __construct(AbstractModule $module) {
41
+		parent::__construct($module);
42 42
         
43
-        $this->sosa_provider = new SosaProvider(Globals::getTree(), Auth::user());
44
-    }
43
+		$this->sosa_provider = new SosaProvider(Globals::getTree(), 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
-        $wt_tree = Globals::getTree();
55
-        $controller = new PageController();
56
-        $controller
57
-            ->setPageTitle(I18N::translate('Sosa Statistics'))
58
-            ->addInlineJavascript('$(".help_tooltip").tooltip();')
59
-        ;
50
+	/**
51
+	 * SosaStats@index
52
+	 */
53
+	public function index() {
54
+		$wt_tree = Globals::getTree();
55
+		$controller = new PageController();
56
+		$controller
57
+			->setPageTitle(I18N::translate('Sosa Statistics'))
58
+			->addInlineJavascript('$(".help_tooltip").tooltip();')
59
+		;
60 60
 
61
-        $view_bag = new ViewBag();
62
-        $view_bag->set('title', $controller->getPageTitle());
63
-        $view_bag->set('is_setup', false);
61
+		$view_bag = new ViewBag();
62
+		$view_bag->set('title', $controller->getPageTitle());
63
+		$view_bag->set('is_setup', false);
64 64
         
65
-        if($this->sosa_provider->isSetup()) {
66
-            $view_bag->set('is_setup', true);
65
+		if($this->sosa_provider->isSetup()) {
66
+			$view_bag->set('is_setup', true);
67 67
             
68
-            $view_bag->set('root_indi', $this->sosa_provider->getRootIndi());
68
+			$view_bag->set('root_indi', $this->sosa_provider->getRootIndi());
69 69
             
70
-            $sosaCount = $this->sosa_provider->getSosaCount();
71
-            $diffSosaCount = $this->sosa_provider->getDifferentSosaCount();
70
+			$sosaCount = $this->sosa_provider->getSosaCount();
71
+			$diffSosaCount = $this->sosa_provider->getDifferentSosaCount();
72 72
             
73
-            $general_stats = array(
74
-                'sosa_count' => $sosaCount,
75
-                'distinct_count' => $diffSosaCount,
76
-                'sosa_rate' => Functions::safeDivision($diffSosaCount, $this->sosa_provider->getTotalIndividuals()),
77
-                'pedi_collapse' => 1 - Functions::safeDivision($diffSosaCount, $sosaCount),
78
-                'mean_gen_time' => $this->sosa_provider->getMeanGenerationTime()
79
-            );
80
-            $view_bag->set('general_stats', $general_stats);
73
+			$general_stats = array(
74
+				'sosa_count' => $sosaCount,
75
+				'distinct_count' => $diffSosaCount,
76
+				'sosa_rate' => Functions::safeDivision($diffSosaCount, $this->sosa_provider->getTotalIndividuals()),
77
+				'pedi_collapse' => 1 - Functions::safeDivision($diffSosaCount, $sosaCount),
78
+				'mean_gen_time' => $this->sosa_provider->getMeanGenerationTime()
79
+			);
80
+			$view_bag->set('general_stats', $general_stats);
81 81
             
82
-            $stats_gen = $this->sosa_provider->getStatisticsByGeneration();
83
-            $view_bag->set('missinganc_url', 'module.php?mod='.$this->module->getName().'&mod_action=SosaList@missing&ged='.$wt_tree->getNameUrl().'&gen=');
84
-            $view_bag->set('sosaanc_url', 'module.php?mod='.$this->module->getName().'&mod_action=SosaList&ged='.$wt_tree->getNameUrl().'&gen=');
82
+			$stats_gen = $this->sosa_provider->getStatisticsByGeneration();
83
+			$view_bag->set('missinganc_url', 'module.php?mod='.$this->module->getName().'&mod_action=SosaList@missing&ged='.$wt_tree->getNameUrl().'&gen=');
84
+			$view_bag->set('sosaanc_url', 'module.php?mod='.$this->module->getName().'&mod_action=SosaList&ged='.$wt_tree->getNameUrl().'&gen=');
85 85
             
86
-            $gen_theoretical=1;
87
-            $total_theoretical=0;
88
-            $prev_diff=0;
89
-            $prev_known=0.5;
90
-            $gen_equiv=0;            
91
-            $generation_stats = array();
86
+			$gen_theoretical=1;
87
+			$total_theoretical=0;
88
+			$prev_diff=0;
89
+			$prev_known=0.5;
90
+			$gen_equiv=0;            
91
+			$generation_stats = array();
92 92
             
93
-            foreach($stats_gen as $gen => $tab){
94
-                $genY1= I18N::translate('-');
95
-                $genY2= I18N::translate('-');
96
-                if($tab['firstBirth']>0) $genY1=$tab['firstBirth'];
97
-                if($tab['lastBirth']>0) $genY2=$tab['lastBirth'];
98
-                $total_theoretical += $gen_theoretical;
99
-                $perc_sosa_count_theor = Functions::safeDivision($tab['sosaCount'], $gen_theoretical);
100
-                $gen_equiv += $perc_sosa_count_theor;
101
-                $missing=2*$prev_known - $tab['sosaCount'];
102
-                $gen_diff=$tab['diffSosaTotalCount']-$prev_diff;
93
+			foreach($stats_gen as $gen => $tab){
94
+				$genY1= I18N::translate('-');
95
+				$genY2= I18N::translate('-');
96
+				if($tab['firstBirth']>0) $genY1=$tab['firstBirth'];
97
+				if($tab['lastBirth']>0) $genY2=$tab['lastBirth'];
98
+				$total_theoretical += $gen_theoretical;
99
+				$perc_sosa_count_theor = Functions::safeDivision($tab['sosaCount'], $gen_theoretical);
100
+				$gen_equiv += $perc_sosa_count_theor;
101
+				$missing=2*$prev_known - $tab['sosaCount'];
102
+				$gen_diff=$tab['diffSosaTotalCount']-$prev_diff;
103 103
                 
104
-                $generation_stats[$gen] = array(
105
-                    'gen_min_birth' => $genY1,
106
-                    'gen_max_birth' => $genY2,
107
-                    'theoretical' => $gen_theoretical,
108
-                    'known' => $tab['sosaCount'],
109
-                    'perc_known' => $perc_sosa_count_theor,
110
-                    'missing' => $missing,
111
-                    'perc_missing' => 1-Functions::safeDivision($tab['sosaCount'], 2*$prev_known),
112
-                    'total_known' => $tab['sosaTotalCount'],
113
-                    'perc_total_known' => Functions::safeDivision($tab['sosaTotalCount'], $total_theoretical),
114
-                    'different' => $gen_diff,
115
-                    'perc_different' => Functions::safeDivision($gen_diff, $tab['sosaCount']),
116
-                    'total_different' => $tab['diffSosaTotalCount'],
117
-                    'pedi_collapse' => 1 - Functions::safeDivision($tab['diffSosaTotalCount'], $tab['sosaTotalCount'])
118
-                );
104
+				$generation_stats[$gen] = array(
105
+					'gen_min_birth' => $genY1,
106
+					'gen_max_birth' => $genY2,
107
+					'theoretical' => $gen_theoretical,
108
+					'known' => $tab['sosaCount'],
109
+					'perc_known' => $perc_sosa_count_theor,
110
+					'missing' => $missing,
111
+					'perc_missing' => 1-Functions::safeDivision($tab['sosaCount'], 2*$prev_known),
112
+					'total_known' => $tab['sosaTotalCount'],
113
+					'perc_total_known' => Functions::safeDivision($tab['sosaTotalCount'], $total_theoretical),
114
+					'different' => $gen_diff,
115
+					'perc_different' => Functions::safeDivision($gen_diff, $tab['sosaCount']),
116
+					'total_different' => $tab['diffSosaTotalCount'],
117
+					'pedi_collapse' => 1 - Functions::safeDivision($tab['diffSosaTotalCount'], $tab['sosaTotalCount'])
118
+				);
119 119
                 
120
-                $gen_theoretical = $gen_theoretical * 2;
121
-                $prev_known=$tab['sosaCount'];
122
-                $prev_diff=$tab['diffSosaTotalCount'];
123
-            }
120
+				$gen_theoretical = $gen_theoretical * 2;
121
+				$prev_known=$tab['sosaCount'];
122
+				$prev_diff=$tab['diffSosaTotalCount'];
123
+			}
124 124
             
125
-            $view_bag->set('generation_stats', $generation_stats);
126
-            $view_bag->set('equivalent_gen', $gen_equiv);
125
+			$view_bag->set('generation_stats', $generation_stats);
126
+			$view_bag->set('equivalent_gen', $gen_equiv);
127 127
             
128
-            $top10multiancestors = $this->sosa_provider->getTopMultiSosaAncestorsNoTies(10);
129
-            $top10ancestors = array();
130
-            if($top10multiancestors !== null && count($top10multiancestors)) {
131
-                foreach($top10multiancestors as $pid => $count) {
132
-                    $indi = Individual::getInstance($pid, $wt_tree);
133
-                    if($indi !== null && $indi->canShowName()) {
134
-                        array_key_exists($count, $top10ancestors) ?
135
-                            $top10ancestors[$count][] = $indi:
136
-                            $top10ancestors[$count] = array($count => $indi);
137
-                    }
138
-                }
139
-            }
140
-            $view_bag->set('top10multiancestors', $top10ancestors);
128
+			$top10multiancestors = $this->sosa_provider->getTopMultiSosaAncestorsNoTies(10);
129
+			$top10ancestors = array();
130
+			if($top10multiancestors !== null && count($top10multiancestors)) {
131
+				foreach($top10multiancestors as $pid => $count) {
132
+					$indi = Individual::getInstance($pid, $wt_tree);
133
+					if($indi !== null && $indi->canShowName()) {
134
+						array_key_exists($count, $top10ancestors) ?
135
+							$top10ancestors[$count][] = $indi:
136
+							$top10ancestors[$count] = array($count => $indi);
137
+					}
138
+				}
139
+			}
140
+			$view_bag->set('top10multiancestors', $top10ancestors);
141 141
             
142
-            $view_bag->set('chart_img_g2', $this->htmlAncestorDispersionG2());
143
-            $view_bag->set('chart_img_g3', $this->htmlAncestorDispersionG3());
142
+			$view_bag->set('chart_img_g2', $this->htmlAncestorDispersionG2());
143
+			$view_bag->set('chart_img_g3', $this->htmlAncestorDispersionG3());
144 144
             
145
-        }
145
+		}
146 146
         
147
-        ViewFactory::make('SosaStats', $this, $controller, $view_bag)->render();   
148
-    }
147
+		ViewFactory::make('SosaStats', $this, $controller, $view_bag)->render();   
148
+	}
149 149
     
150
-    /**
151
-     * Returns HTML code for a graph showing the dispersion of ancestors across father & mother
152
-     * @return string HTML code
153
-     */
154
-     private function htmlAncestorDispersionG2()
155
-    {
156
-        $ancestorsDispGen2 = $this->sosa_provider->getAncestorDispersionForGen(2);
157
-        if(count($ancestorsDispGen2) == 0) return;
150
+	/**
151
+	 * Returns HTML code for a graph showing the dispersion of ancestors across father & mother
152
+	 * @return string HTML code
153
+	 */
154
+	 private function htmlAncestorDispersionG2()
155
+	{
156
+		$ancestorsDispGen2 = $this->sosa_provider->getAncestorDispersionForGen(2);
157
+		if(count($ancestorsDispGen2) == 0) return;
158 158
         
159
-        $size = '600x300';
159
+		$size = '600x300';
160 160
         
161
-        $total = array_sum($ancestorsDispGen2);
162
-        $father_count = array_key_exists(1, $ancestorsDispGen2) ? $ancestorsDispGen2[1] : 0;
163
-        $father = array (
164
-            'color' => '84beff', 
165
-            'count' => $father_count, 
166
-            'perc' => Functions::safeDivision($father_count, $total), 
167
-            'name' => \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fat')            
168
-        );
169
-        $mother_count = array_key_exists(2, $ancestorsDispGen2) ? $ancestorsDispGen2[2] : 0;
170
-        $mother = array (
171
-            'color' => 'ffd1dc', 
172
-            'count' => $mother_count, 
173
-            'perc' => Functions::safeDivision($mother_count, $total),
174
-            'name' => \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('mot')
175
-        );
176
-        $shared_count = array_key_exists(-1, $ancestorsDispGen2) ? $ancestorsDispGen2[-1] : 0;
177
-        $shared = array (
178
-            'color' => '777777', 
179
-            'count' => $shared_count, 
180
-            'perc' => Functions::safeDivision($shared_count, $total),
181
-            'name' => I18N::translate('Shared')
182
-        );
161
+		$total = array_sum($ancestorsDispGen2);
162
+		$father_count = array_key_exists(1, $ancestorsDispGen2) ? $ancestorsDispGen2[1] : 0;
163
+		$father = array (
164
+			'color' => '84beff', 
165
+			'count' => $father_count, 
166
+			'perc' => Functions::safeDivision($father_count, $total), 
167
+			'name' => \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fat')            
168
+		);
169
+		$mother_count = array_key_exists(2, $ancestorsDispGen2) ? $ancestorsDispGen2[2] : 0;
170
+		$mother = array (
171
+			'color' => 'ffd1dc', 
172
+			'count' => $mother_count, 
173
+			'perc' => Functions::safeDivision($mother_count, $total),
174
+			'name' => \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('mot')
175
+		);
176
+		$shared_count = array_key_exists(-1, $ancestorsDispGen2) ? $ancestorsDispGen2[-1] : 0;
177
+		$shared = array (
178
+			'color' => '777777', 
179
+			'count' => $shared_count, 
180
+			'perc' => Functions::safeDivision($shared_count, $total),
181
+			'name' => I18N::translate('Shared')
182
+		);
183 183
         
184
-        $chd = $this->arrayToExtendedEncoding(array(4095 * $father['perc'], 4095 * $shared['perc'], 4095 * $mother['perc']));
185
-        $chart_title = I18N::translate('Known Sosa ancestors\' dispersion');
186
-        $chl = 
187
-             $father['name'] . ' - ' . I18N::percentage($father['perc'], 1) . '|' .
188
-             $shared['name'] . ' - ' . I18N::percentage($shared['perc'], 1) . '|' .
189
-             $mother['name'] . ' - ' . I18N::percentage($mother['perc'], 1);
190
-        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 . "\" />";
191
-    }
184
+		$chd = $this->arrayToExtendedEncoding(array(4095 * $father['perc'], 4095 * $shared['perc'], 4095 * $mother['perc']));
185
+		$chart_title = I18N::translate('Known Sosa ancestors\' dispersion');
186
+		$chl = 
187
+			 $father['name'] . ' - ' . I18N::percentage($father['perc'], 1) . '|' .
188
+			 $shared['name'] . ' - ' . I18N::percentage($shared['perc'], 1) . '|' .
189
+			 $mother['name'] . ' - ' . I18N::percentage($mother['perc'], 1);
190
+		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 . "\" />";
191
+	}
192 192
     
193
-    /**
194
-     * Returns HTML code for a graph showing the dispersion of ancestors across grand-parents
195
-     * @return string HTML code
196
-     */
197
-    private function htmlAncestorDispersionG3()
198
-    {
199
-        $ancestorsDispGen2 = $this->sosa_provider->getAncestorDispersionForGen(3);
193
+	/**
194
+	 * Returns HTML code for a graph showing the dispersion of ancestors across grand-parents
195
+	 * @return string HTML code
196
+	 */
197
+	private function htmlAncestorDispersionG3()
198
+	{
199
+		$ancestorsDispGen2 = $this->sosa_provider->getAncestorDispersionForGen(3);
200 200
         
201
-        $size = '700x300';
201
+		$size = '700x300';
202 202
         
203
-        $color_motmot = 'ffd1dc';
204
-        $color_motfat = 'b998a0';
205
-        $color_fatfat = '577292';
206
-        $color_fatmot = '84beff';
207
-        $color_shared = '777777';
203
+		$color_motmot = 'ffd1dc';
204
+		$color_motfat = 'b998a0';
205
+		$color_fatfat = '577292';
206
+		$color_fatmot = '84beff';
207
+		$color_shared = '777777';
208 208
     
209
-        $total_fatfat = array_key_exists(1, $ancestorsDispGen2) ? $ancestorsDispGen2[1] : 0;
210
-        $total_fatmot = array_key_exists(2, $ancestorsDispGen2) ? $ancestorsDispGen2[2] : 0;
211
-        $total_motfat = array_key_exists(4, $ancestorsDispGen2) ? $ancestorsDispGen2[4] : 0;
212
-        $total_motmot = array_key_exists(8, $ancestorsDispGen2) ? $ancestorsDispGen2[8] : 0;
213
-        $total_sha = array_key_exists(-1, $ancestorsDispGen2) ? $ancestorsDispGen2[-1] : 0;
214
-        $total = $total_fatfat + $total_fatmot + $total_motfat+ $total_motmot + $total_sha;
209
+		$total_fatfat = array_key_exists(1, $ancestorsDispGen2) ? $ancestorsDispGen2[1] : 0;
210
+		$total_fatmot = array_key_exists(2, $ancestorsDispGen2) ? $ancestorsDispGen2[2] : 0;
211
+		$total_motfat = array_key_exists(4, $ancestorsDispGen2) ? $ancestorsDispGen2[4] : 0;
212
+		$total_motmot = array_key_exists(8, $ancestorsDispGen2) ? $ancestorsDispGen2[8] : 0;
213
+		$total_sha = array_key_exists(-1, $ancestorsDispGen2) ? $ancestorsDispGen2[-1] : 0;
214
+		$total = $total_fatfat + $total_fatmot + $total_motfat+ $total_motmot + $total_sha;
215 215
     
216
-        $chd = $this->arrayToExtendedEncoding(array(
217
-	    4095 * Functions::safeDivision($total_fatfat, $total), 
218
-            4095 * Functions::safeDivision($total_fatmot, $total),
219
-            4095 * Functions::safeDivision($total_sha, $total), 
220
-            4095 * Functions::safeDivision($total_motfat, $total),
221
-            4095 * Functions::safeDivision($total_motmot, $total)          
222
-        ));
223
-        $chart_title = I18N::translate('Known Sosa ancestors\' dispersion - G3');
224
-        $chl =
225
-            \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fatfat') . ' - ' . I18N::percentage(Functions::safeDivision($total_fatfat, $total), 1) . '|' .
226
-            \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fatmot') . ' - ' . I18N::percentage(Functions::safeDivision($total_fatmot, $total), 1) . '|' .
227
-            I18N::translate('Shared') . ' - ' . I18N::percentage(Functions::safeDivision($total_sha, $total), 1) . '|' .
228
-            \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('motfat') . ' - ' . I18N::percentage(Functions::safeDivision($total_motfat, $total), 1) . '|' .
229
-            \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('motmot') . ' - ' . I18N::percentage(Functions::safeDivision($total_motmot, $total), 1);
230
-         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 . "\" />";
231
-    }
216
+		$chd = $this->arrayToExtendedEncoding(array(
217
+		4095 * Functions::safeDivision($total_fatfat, $total), 
218
+			4095 * Functions::safeDivision($total_fatmot, $total),
219
+			4095 * Functions::safeDivision($total_sha, $total), 
220
+			4095 * Functions::safeDivision($total_motfat, $total),
221
+			4095 * Functions::safeDivision($total_motmot, $total)          
222
+		));
223
+		$chart_title = I18N::translate('Known Sosa ancestors\' dispersion - G3');
224
+		$chl =
225
+			\Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fatfat') . ' - ' . I18N::percentage(Functions::safeDivision($total_fatfat, $total), 1) . '|' .
226
+			\Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fatmot') . ' - ' . I18N::percentage(Functions::safeDivision($total_fatmot, $total), 1) . '|' .
227
+			I18N::translate('Shared') . ' - ' . I18N::percentage(Functions::safeDivision($total_sha, $total), 1) . '|' .
228
+			\Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('motfat') . ' - ' . I18N::percentage(Functions::safeDivision($total_motfat, $total), 1) . '|' .
229
+			\Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('motmot') . ' - ' . I18N::percentage(Functions::safeDivision($total_motmot, $total), 1);
230
+		 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 . "\" />";
231
+	}
232 232
 
233
-    /**
234
-     * Convert an array to Google Chart encoding
235
-     * @param arrat $a Array to encode
236
-     * @return string
237
-     */
238
-    private function arrayToExtendedEncoding($a) {
239
-        $xencoding = WT_GOOGLE_CHART_ENCODING;
233
+	/**
234
+	 * Convert an array to Google Chart encoding
235
+	 * @param arrat $a Array to encode
236
+	 * @return string
237
+	 */
238
+	private function arrayToExtendedEncoding($a) {
239
+		$xencoding = WT_GOOGLE_CHART_ENCODING;
240 240
     
241
-        $encoding = '';
242
-        foreach ($a as $value) {
243
-            if ($value < 0) {
244
-                $value = 0;
245
-            }
246
-            $first  = (int) ($value / 64);
247
-            $second = $value % 64;
248
-            $encoding .= $xencoding[(int) $first] . $xencoding[(int) $second];
249
-        }
241
+		$encoding = '';
242
+		foreach ($a as $value) {
243
+			if ($value < 0) {
244
+				$value = 0;
245
+			}
246
+			$first  = (int) ($value / 64);
247
+			$second = $value % 64;
248
+			$encoding .= $xencoding[(int) $first] . $xencoding[(int) $second];
249
+		}
250 250
     
251
-        return $encoding;
252
-    }
251
+		return $encoding;
252
+	}
253 253
     
254 254
     
255 255
 }
256 256
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +37 added lines, -38 removed lines patch added patch discarded remove patch
@@ -62,7 +62,7 @@  discard block
 block discarded – undo
62 62
         $view_bag->set('title', $controller->getPageTitle());
63 63
         $view_bag->set('is_setup', false);
64 64
         
65
-        if($this->sosa_provider->isSetup()) {
65
+        if ($this->sosa_provider->isSetup()) {
66 66
             $view_bag->set('is_setup', true);
67 67
             
68 68
             $view_bag->set('root_indi', $this->sosa_provider->getRootIndi());
@@ -83,23 +83,23 @@  discard block
 block discarded – undo
83 83
             $view_bag->set('missinganc_url', 'module.php?mod='.$this->module->getName().'&mod_action=SosaList@missing&ged='.$wt_tree->getNameUrl().'&gen=');
84 84
             $view_bag->set('sosaanc_url', 'module.php?mod='.$this->module->getName().'&mod_action=SosaList&ged='.$wt_tree->getNameUrl().'&gen=');
85 85
             
86
-            $gen_theoretical=1;
87
-            $total_theoretical=0;
88
-            $prev_diff=0;
89
-            $prev_known=0.5;
90
-            $gen_equiv=0;            
86
+            $gen_theoretical = 1;
87
+            $total_theoretical = 0;
88
+            $prev_diff = 0;
89
+            $prev_known = 0.5;
90
+            $gen_equiv = 0;            
91 91
             $generation_stats = array();
92 92
             
93
-            foreach($stats_gen as $gen => $tab){
94
-                $genY1= I18N::translate('-');
95
-                $genY2= I18N::translate('-');
96
-                if($tab['firstBirth']>0) $genY1=$tab['firstBirth'];
97
-                if($tab['lastBirth']>0) $genY2=$tab['lastBirth'];
93
+            foreach ($stats_gen as $gen => $tab) {
94
+                $genY1 = I18N::translate('-');
95
+                $genY2 = I18N::translate('-');
96
+                if ($tab['firstBirth'] > 0) $genY1 = $tab['firstBirth'];
97
+                if ($tab['lastBirth'] > 0) $genY2 = $tab['lastBirth'];
98 98
                 $total_theoretical += $gen_theoretical;
99 99
                 $perc_sosa_count_theor = Functions::safeDivision($tab['sosaCount'], $gen_theoretical);
100 100
                 $gen_equiv += $perc_sosa_count_theor;
101
-                $missing=2*$prev_known - $tab['sosaCount'];
102
-                $gen_diff=$tab['diffSosaTotalCount']-$prev_diff;
101
+                $missing = 2 * $prev_known - $tab['sosaCount'];
102
+                $gen_diff = $tab['diffSosaTotalCount'] - $prev_diff;
103 103
                 
104 104
                 $generation_stats[$gen] = array(
105 105
                     'gen_min_birth' => $genY1,
@@ -108,7 +108,7 @@  discard block
 block discarded – undo
108 108
                     'known' => $tab['sosaCount'],
109 109
                     'perc_known' => $perc_sosa_count_theor,
110 110
                     'missing' => $missing,
111
-                    'perc_missing' => 1-Functions::safeDivision($tab['sosaCount'], 2*$prev_known),
111
+                    'perc_missing' => 1 - Functions::safeDivision($tab['sosaCount'], 2 * $prev_known),
112 112
                     'total_known' => $tab['sosaTotalCount'],
113 113
                     'perc_total_known' => Functions::safeDivision($tab['sosaTotalCount'], $total_theoretical),
114 114
                     'different' => $gen_diff,
@@ -118,8 +118,8 @@  discard block
 block discarded – undo
118 118
                 );
119 119
                 
120 120
                 $gen_theoretical = $gen_theoretical * 2;
121
-                $prev_known=$tab['sosaCount'];
122
-                $prev_diff=$tab['diffSosaTotalCount'];
121
+                $prev_known = $tab['sosaCount'];
122
+                $prev_diff = $tab['diffSosaTotalCount'];
123 123
             }
124 124
             
125 125
             $view_bag->set('generation_stats', $generation_stats);
@@ -127,13 +127,12 @@  discard block
 block discarded – undo
127 127
             
128 128
             $top10multiancestors = $this->sosa_provider->getTopMultiSosaAncestorsNoTies(10);
129 129
             $top10ancestors = array();
130
-            if($top10multiancestors !== null && count($top10multiancestors)) {
131
-                foreach($top10multiancestors as $pid => $count) {
130
+            if ($top10multiancestors !== null && count($top10multiancestors)) {
131
+                foreach ($top10multiancestors as $pid => $count) {
132 132
                     $indi = Individual::getInstance($pid, $wt_tree);
133
-                    if($indi !== null && $indi->canShowName()) {
133
+                    if ($indi !== null && $indi->canShowName()) {
134 134
                         array_key_exists($count, $top10ancestors) ?
135
-                            $top10ancestors[$count][] = $indi:
136
-                            $top10ancestors[$count] = array($count => $indi);
135
+                            $top10ancestors[$count][] = $indi : $top10ancestors[$count] = array($count => $indi);
137 136
                     }
138 137
                 }
139 138
             }
@@ -154,27 +153,27 @@  discard block
 block discarded – undo
154 153
      private function htmlAncestorDispersionG2()
155 154
     {
156 155
         $ancestorsDispGen2 = $this->sosa_provider->getAncestorDispersionForGen(2);
157
-        if(count($ancestorsDispGen2) == 0) return;
156
+        if (count($ancestorsDispGen2) == 0) return;
158 157
         
159 158
         $size = '600x300';
160 159
         
161 160
         $total = array_sum($ancestorsDispGen2);
162 161
         $father_count = array_key_exists(1, $ancestorsDispGen2) ? $ancestorsDispGen2[1] : 0;
163
-        $father = array (
162
+        $father = array(
164 163
             'color' => '84beff', 
165 164
             'count' => $father_count, 
166 165
             'perc' => Functions::safeDivision($father_count, $total), 
167 166
             'name' => \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fat')            
168 167
         );
169 168
         $mother_count = array_key_exists(2, $ancestorsDispGen2) ? $ancestorsDispGen2[2] : 0;
170
-        $mother = array (
169
+        $mother = array(
171 170
             'color' => 'ffd1dc', 
172 171
             'count' => $mother_count, 
173 172
             'perc' => Functions::safeDivision($mother_count, $total),
174 173
             'name' => \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('mot')
175 174
         );
176 175
         $shared_count = array_key_exists(-1, $ancestorsDispGen2) ? $ancestorsDispGen2[-1] : 0;
177
-        $shared = array (
176
+        $shared = array(
178 177
             'color' => '777777', 
179 178
             'count' => $shared_count, 
180 179
             'perc' => Functions::safeDivision($shared_count, $total),
@@ -184,10 +183,10 @@  discard block
 block discarded – undo
184 183
         $chd = $this->arrayToExtendedEncoding(array(4095 * $father['perc'], 4095 * $shared['perc'], 4095 * $mother['perc']));
185 184
         $chart_title = I18N::translate('Known Sosa ancestors\' dispersion');
186 185
         $chl = 
187
-             $father['name'] . ' - ' . I18N::percentage($father['perc'], 1) . '|' .
188
-             $shared['name'] . ' - ' . I18N::percentage($shared['perc'], 1) . '|' .
189
-             $mother['name'] . ' - ' . I18N::percentage($mother['perc'], 1);
190
-        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 . "\" />";
186
+             $father['name'].' - '.I18N::percentage($father['perc'], 1).'|'.
187
+             $shared['name'].' - '.I18N::percentage($shared['perc'], 1).'|'.
188
+             $mother['name'].' - '.I18N::percentage($mother['perc'], 1);
189
+        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."\" />";
191 190
     }
192 191
     
193 192
     /**
@@ -211,7 +210,7 @@  discard block
 block discarded – undo
211 210
         $total_motfat = array_key_exists(4, $ancestorsDispGen2) ? $ancestorsDispGen2[4] : 0;
212 211
         $total_motmot = array_key_exists(8, $ancestorsDispGen2) ? $ancestorsDispGen2[8] : 0;
213 212
         $total_sha = array_key_exists(-1, $ancestorsDispGen2) ? $ancestorsDispGen2[-1] : 0;
214
-        $total = $total_fatfat + $total_fatmot + $total_motfat+ $total_motmot + $total_sha;
213
+        $total = $total_fatfat + $total_fatmot + $total_motfat + $total_motmot + $total_sha;
215 214
     
216 215
         $chd = $this->arrayToExtendedEncoding(array(
217 216
 	    4095 * Functions::safeDivision($total_fatfat, $total), 
@@ -222,12 +221,12 @@  discard block
 block discarded – undo
222 221
         ));
223 222
         $chart_title = I18N::translate('Known Sosa ancestors\' dispersion - G3');
224 223
         $chl =
225
-            \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fatfat') . ' - ' . I18N::percentage(Functions::safeDivision($total_fatfat, $total), 1) . '|' .
226
-            \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fatmot') . ' - ' . I18N::percentage(Functions::safeDivision($total_fatmot, $total), 1) . '|' .
227
-            I18N::translate('Shared') . ' - ' . I18N::percentage(Functions::safeDivision($total_sha, $total), 1) . '|' .
228
-            \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('motfat') . ' - ' . I18N::percentage(Functions::safeDivision($total_motfat, $total), 1) . '|' .
229
-            \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('motmot') . ' - ' . I18N::percentage(Functions::safeDivision($total_motmot, $total), 1);
230
-         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 . "\" />";
224
+            \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fatfat').' - '.I18N::percentage(Functions::safeDivision($total_fatfat, $total), 1).'|'.
225
+            \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fatmot').' - '.I18N::percentage(Functions::safeDivision($total_fatmot, $total), 1).'|'.
226
+            I18N::translate('Shared').' - '.I18N::percentage(Functions::safeDivision($total_sha, $total), 1).'|'.
227
+            \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('motfat').' - '.I18N::percentage(Functions::safeDivision($total_motfat, $total), 1).'|'.
228
+            \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('motmot').' - '.I18N::percentage(Functions::safeDivision($total_motmot, $total), 1);
229
+         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."\" />";
231 230
     }
232 231
 
233 232
     /**
@@ -243,9 +242,9 @@  discard block
 block discarded – undo
243 242
             if ($value < 0) {
244 243
                 $value = 0;
245 244
             }
246
-            $first  = (int) ($value / 64);
245
+            $first  = (int)($value / 64);
247 246
             $second = $value % 64;
248
-            $encoding .= $xencoding[(int) $first] . $xencoding[(int) $second];
247
+            $encoding .= $xencoding[(int)$first].$xencoding[(int)$second];
249 248
         }
250 249
     
251 250
         return $encoding;
Please login to merge, or discard this patch.