Passed
Branch feature/2.0 (d2af8f)
by Jonathan
13:07
created
src/Webtrees/ImageBuilder.php 3 patches
Indentation   +299 added lines, -299 removed lines patch added patch discarded remove patch
@@ -22,61 +22,61 @@  discard block
 block discarded – undo
22 22
  */
23 23
 class ImageBuilder {
24 24
     
25
-    /**
26
-     * Reference media
27
-     * @var Media $media
28
-     */
29
-    protected $media;
25
+	/**
26
+	 * Reference media
27
+	 * @var Media $media
28
+	 */
29
+	protected $media;
30 30
     
31
-    /**
32
-     * Use TTF font
33
-     * @var bool $use_ttf
34
-     */
35
-    protected $use_ttf;
31
+	/**
32
+	 * Use TTF font
33
+	 * @var bool $use_ttf
34
+	 */
35
+	protected $use_ttf;
36 36
     
37
-    /**
38
-     * Expiration offset. Default is one day.
39
-     * @var int $expire_offset
40
-     */
41
-    protected $expire_offset;
37
+	/**
38
+	 * Expiration offset. Default is one day.
39
+	 * @var int $expire_offset
40
+	 */
41
+	protected $expire_offset;
42 42
    
43
-    /**
44
-     * Should the certificate display a watermark
45
-     * @var bool $show_watermark
46
-     */
47
-    protected $show_watermark;
43
+	/**
44
+	 * Should the certificate display a watermark
45
+	 * @var bool $show_watermark
46
+	 */
47
+	protected $show_watermark;
48 48
         
49
-    /**
50
-     * Maximum watermark font size. Default is 18.
51
-     * @var int $font_max_size
52
-     */
53
-    protected $font_max_size;
49
+	/**
50
+	 * Maximum watermark font size. Default is 18.
51
+	 * @var int $font_max_size
52
+	 */
53
+	protected $font_max_size;
54 54
     
55
-    /**
56
-     * Watermark font color, in hexadecimal. Default is #4D6DF3.
57
-     * @var string $font_color
58
-     */
59
-    protected $font_color;
55
+	/**
56
+	 * Watermark font color, in hexadecimal. Default is #4D6DF3.
57
+	 * @var string $font_color
58
+	 */
59
+	protected $font_color;
60 60
     
61
-    /**
62
-     * Should the image be rendered as attachment (vs inline)     * 
63
-     * @var bool $as_attachment
64
-     */
65
-    protected $as_attachment;
61
+	/**
62
+	 * Should the image be rendered as attachment (vs inline)     * 
63
+	 * @var bool $as_attachment
64
+	 */
65
+	protected $as_attachment;
66 66
     
67 67
 	/**
68
-	* Contructor for ImageBuilder
69
-	*
70
-	* @param Media|null $media Reference media object
71
-	*/
68
+	 * Contructor for ImageBuilder
69
+	 *
70
+	 * @param Media|null $media Reference media object
71
+	 */
72 72
 	public function __construct(Media $media = null){
73
-	    $this->media = $media;
74
-	    $this->use_ttf = function_exists('imagettftext');
75
-	    $this->expire_offset = 3600 * 24;
76
-	    $this->show_watermark = true;
77
-	    $this->font_max_size = 18;
78
-	    $this->font_color = '#4D6DF3';
79
-	    $this->as_attachment = false;
73
+		$this->media = $media;
74
+		$this->use_ttf = function_exists('imagettftext');
75
+		$this->expire_offset = 3600 * 24;
76
+		$this->show_watermark = true;
77
+		$this->font_max_size = 18;
78
+		$this->font_color = '#4D6DF3';
79
+		$this->as_attachment = false;
80 80
 	}
81 81
 	
82 82
 	/**
@@ -85,7 +85,7 @@  discard block
 block discarded – undo
85 85
 	 * @return int
86 86
 	 */
87 87
 	public function getExpireOffset() {
88
-	    return $this->expire_offset;
88
+		return $this->expire_offset;
89 89
 	}
90 90
 	
91 91
 	/**
@@ -95,8 +95,8 @@  discard block
 block discarded – undo
95 95
 	 * @return ImageBuilder
96 96
 	 */
97 97
 	public function setExpireOffset($expireOffset) {
98
-	    if($expireOffset) $this->expire_offset = $expireOffset;
99
-	    return $this;
98
+		if($expireOffset) $this->expire_offset = $expireOffset;
99
+		return $this;
100 100
 	}
101 101
 	
102 102
 	/**
@@ -105,7 +105,7 @@  discard block
 block discarded – undo
105 105
 	 * @return bool
106 106
 	 */
107 107
 	public function isShowWatermark() {
108
-	    return $this->show_watermark;
108
+		return $this->show_watermark;
109 109
 	}
110 110
 	
111 111
 	/**
@@ -115,8 +115,8 @@  discard block
 block discarded – undo
115 115
 	 * @return ImageBuilder
116 116
 	 */
117 117
 	public function setShowWatermark($show_watermark) {
118
-	    if(!is_null($show_watermark)) $this->show_watermark = $show_watermark;
119
-	    return $this;
118
+		if(!is_null($show_watermark)) $this->show_watermark = $show_watermark;
119
+		return $this;
120 120
 	}
121 121
 	
122 122
 	/**
@@ -126,8 +126,8 @@  discard block
 block discarded – undo
126 126
 	 * @return ImageBuilder
127 127
 	 */
128 128
 	public function setFontMaxSize($font_max_size) {
129
-	    if($font_max_size) $this->font_max_size = $font_max_size;
130
-	    return $this;
129
+		if($font_max_size) $this->font_max_size = $font_max_size;
130
+		return $this;
131 131
 	}
132 132
 	
133 133
 	/**
@@ -137,8 +137,8 @@  discard block
 block discarded – undo
137 137
 	 * @return ImageBuilder
138 138
 	 */
139 139
 	public function setFontColor($font_color) {
140
-	    if($font_color) $this->font_color = $font_color;
141
-	    return $this;
140
+		if($font_color) $this->font_color = $font_color;
141
+		return $this;
142 142
 	}
143 143
 	
144 144
 	/**
@@ -148,8 +148,8 @@  discard block
 block discarded – undo
148 148
 	 * @return ImageBuilder
149 149
 	 */
150 150
 	public function setAsAttachment($is_attachement) {
151
-	    if(is_bool($is_attachement)) $this->as_attachment = $is_attachement;
152
-	    return $this;
151
+		if(is_bool($is_attachement)) $this->as_attachment = $is_attachement;
152
+		return $this;
153 153
 	}
154 154
 	
155 155
 	/**
@@ -157,135 +157,135 @@  discard block
 block discarded – undo
157 157
 	 */
158 158
 	public function render(){
159 159
 	    
160
-	    if (!$this->media || !$this->media->canShow()) {
161
-	        Log::addMediaLog('Image Builder error: >' . I18N::translate('Missing or private media object.'));
162
-	        $this->renderError();
163
-	    }
160
+		if (!$this->media || !$this->media->canShow()) {
161
+			Log::addMediaLog('Image Builder error: >' . I18N::translate('Missing or private media object.'));
162
+			$this->renderError();
163
+		}
164 164
 	    
165
-	    $serverFilename = $this->media->getServerFilename();
165
+		$serverFilename = $this->media->getServerFilename();
166 166
 	    
167
-	    if (!file_exists($serverFilename)) {
168
-	        Log::addMediaLog('Image Builder error: >'. I18N::translate('The media object does not exist.').'< for path >'.$serverFilename.'<');
169
-	        $this->renderError();
170
-	    }
167
+		if (!file_exists($serverFilename)) {
168
+			Log::addMediaLog('Image Builder error: >'. I18N::translate('The media object does not exist.').'< for path >'.$serverFilename.'<');
169
+			$this->renderError();
170
+		}
171 171
 	    
172
-	    $mimetype = $this->media->mimeType();
173
-	    $imgsize = $this->media->getImageAttributes();
174
-	    $filetime = $this->media->getFiletime();
175
-	    $filetimeHeader = gmdate('D, d M Y H:i:s', $filetime) . ' GMT';	    
176
-	    $expireHeader = gmdate('D, d M Y H:i:s', WT_TIMESTAMP + $this->getExpireOffset()) . ' GMT';
172
+		$mimetype = $this->media->mimeType();
173
+		$imgsize = $this->media->getImageAttributes();
174
+		$filetime = $this->media->getFiletime();
175
+		$filetimeHeader = gmdate('D, d M Y H:i:s', $filetime) . ' GMT';	    
176
+		$expireHeader = gmdate('D, d M Y H:i:s', WT_TIMESTAMP + $this->getExpireOffset()) . ' GMT';
177 177
 	    
178
-	    $type = Functions::isImageTypeSupported($imgsize['ext']);
179
-	    $usewatermark = false;
180
-	    // if this image supports watermarks and the watermark module is intalled...
181
-	    if ($type) {
182
-	        $usewatermark = $this->isShowWatermark();
183
-	    }
178
+		$type = Functions::isImageTypeSupported($imgsize['ext']);
179
+		$usewatermark = false;
180
+		// if this image supports watermarks and the watermark module is intalled...
181
+		if ($type) {
182
+			$usewatermark = $this->isShowWatermark();
183
+		}
184 184
 	    
185
-	    // determine whether we have enough memory to watermark this image
186
-	    if ($usewatermark) {
187
-	        if (!FunctionsMedia::hasMemoryForImage($serverFilename)) {
188
-	            // not enough memory to watermark this file
189
-	            $usewatermark = false;
190
-	        }
191
-	    }
185
+		// determine whether we have enough memory to watermark this image
186
+		if ($usewatermark) {
187
+			if (!FunctionsMedia::hasMemoryForImage($serverFilename)) {
188
+				// not enough memory to watermark this file
189
+				$usewatermark = false;
190
+			}
191
+		}
192 192
 	    
193
-	    $etag = $this->media->getEtag();
193
+		$etag = $this->media->getEtag();
194 194
 	    
195
-	    // parse IF_MODIFIED_SINCE header from client
196
-	    $if_modified_since = 'x';
197
-	    if (!empty(Filter::server('HTTP_IF_MODIFIED_SINCE'))) {
198
-	        $if_modified_since = preg_replace('/;.*$/', '', Filter::server('HTTP_IF_MODIFIED_SINCE'));
199
-	    }
195
+		// parse IF_MODIFIED_SINCE header from client
196
+		$if_modified_since = 'x';
197
+		if (!empty(Filter::server('HTTP_IF_MODIFIED_SINCE'))) {
198
+			$if_modified_since = preg_replace('/;.*$/', '', Filter::server('HTTP_IF_MODIFIED_SINCE'));
199
+		}
200 200
 	    
201
-	    // parse IF_NONE_MATCH header from client
202
-	    $if_none_match = 'x';
203
-	    if (!empty(Filter::server('HTTP_IF_NONE_MATCH'))) {
204
-	        $if_none_match = str_replace('"', '', Filter::server('HTTP_IF_NONE_MATCH'));
205
-	    }
201
+		// parse IF_NONE_MATCH header from client
202
+		$if_none_match = 'x';
203
+		if (!empty(Filter::server('HTTP_IF_NONE_MATCH'))) {
204
+			$if_none_match = str_replace('"', '', Filter::server('HTTP_IF_NONE_MATCH'));
205
+		}
206 206
 	    
207
-	    // add caching headers.  allow browser to cache file, but not proxy
208
-	    header('Last-Modified: ' . $filetimeHeader);
209
-	    header('ETag: "' . $etag . '"');
210
-	    header('Expires: ' . $expireHeader);
211
-	    header('Cache-Control: max-age=' . $this->getExpireOffset() . ', s-maxage=0, proxy-revalidate');
207
+		// add caching headers.  allow browser to cache file, but not proxy
208
+		header('Last-Modified: ' . $filetimeHeader);
209
+		header('ETag: "' . $etag . '"');
210
+		header('Expires: ' . $expireHeader);
211
+		header('Cache-Control: max-age=' . $this->getExpireOffset() . ', s-maxage=0, proxy-revalidate');
212 212
 	    
213
-	    // if this file is already in the user’s cache, don’t resend it
214
-	    // first check if the if_modified_since param matches
215
-	    if ($if_modified_since === $filetimeHeader) {
216
-	        // then check if the etag matches
217
-	        if ($if_none_match === $etag) {
218
-	            http_response_code(304);
213
+		// if this file is already in the user’s cache, don’t resend it
214
+		// first check if the if_modified_since param matches
215
+		if ($if_modified_since === $filetimeHeader) {
216
+			// then check if the etag matches
217
+			if ($if_none_match === $etag) {
218
+				http_response_code(304);
219 219
 	    
220
-	            return;
221
-	        }
222
-	    }	    
220
+				return;
221
+			}
222
+		}	    
223 223
 
224
-	    // send headers for the image
225
-	    $disposition = $this->as_attachment ? 'attachment' : 'inline';
226
-	    header('Content-Type: ' . $mimetype);
227
-	    header('Content-Disposition: ' . $disposition . '; filename="' . addslashes(basename($this->media->getFilename())) . '"');
224
+		// send headers for the image
225
+		$disposition = $this->as_attachment ? 'attachment' : 'inline';
226
+		header('Content-Type: ' . $mimetype);
227
+		header('Content-Disposition: ' . $disposition . '; filename="' . addslashes(basename($this->media->getFilename())) . '"');
228 228
 	     
229
-	    if ($usewatermark) {
230
-	        // generate the watermarked image
231
-	        $imCreateFunc = 'imagecreatefrom' . $type;
232
-	        $imSendFunc   = 'image' . $type;
229
+		if ($usewatermark) {
230
+			// generate the watermarked image
231
+			$imCreateFunc = 'imagecreatefrom' . $type;
232
+			$imSendFunc   = 'image' . $type;
233 233
 	    
234
-	        if (function_exists($imCreateFunc) && function_exists($imSendFunc)) {
235
-	            $im = $imCreateFunc($serverFilename);
236
-	            $im = $this->applyWatermark($im);
234
+			if (function_exists($imCreateFunc) && function_exists($imSendFunc)) {
235
+				$im = $imCreateFunc($serverFilename);
236
+				$im = $this->applyWatermark($im);
237 237
 	    	    
238
-	            // send the image
239
-	            $imSendFunc($im);
240
-	            imagedestroy($im);
238
+				// send the image
239
+				$imSendFunc($im);
240
+				imagedestroy($im);
241 241
 	    
242
-	            return;
243
-	        } else {
244
-	            // this image is defective.  log it
245
-	            Log::addMediaLog('Image Builder error: >' . I18N::translate('This media file is broken and cannot be watermarked.') . '< in file >' . $serverFilename . '< memory used: ' . memory_get_usage());
246
-	        }
247
-	    }
242
+				return;
243
+			} else {
244
+				// this image is defective.  log it
245
+				Log::addMediaLog('Image Builder error: >' . I18N::translate('This media file is broken and cannot be watermarked.') . '< in file >' . $serverFilename . '< memory used: ' . memory_get_usage());
246
+			}
247
+		}
248 248
 	    
249
-	    // determine filesize of image (could be original or watermarked version)
250
-	    $filesize = filesize($serverFilename);
249
+		// determine filesize of image (could be original or watermarked version)
250
+		$filesize = filesize($serverFilename);
251 251
 	    
252
-	    // set content-length header, send file
253
-	    header('Content-Length: ' . $filesize);
252
+		// set content-length header, send file
253
+		header('Content-Length: ' . $filesize);
254 254
 	    
255
-	    // Some servers disable fpassthru() and readfile()
256
-	    if (function_exists('readfile')) {
257
-	        readfile($serverFilename);
258
-	    } else {
259
-	        $fp = fopen($serverFilename, 'rb');
260
-	        if (function_exists('fpassthru')) {
261
-	            fpassthru($fp);
262
-	        } else {
263
-	            while (!feof($fp)) {
264
-	                echo fread($fp, 65536);
265
-	            }
266
-	        }
267
-	        fclose($fp);
268
-	    }	    
255
+		// Some servers disable fpassthru() and readfile()
256
+		if (function_exists('readfile')) {
257
+			readfile($serverFilename);
258
+		} else {
259
+			$fp = fopen($serverFilename, 'rb');
260
+			if (function_exists('fpassthru')) {
261
+				fpassthru($fp);
262
+			} else {
263
+				while (!feof($fp)) {
264
+					echo fread($fp, 65536);
265
+				}
266
+			}
267
+			fclose($fp);
268
+		}	    
269 269
 	}
270 270
 	
271 271
 	/**
272 272
 	 * Render an error as an image.
273 273
 	 */
274 274
 	protected function renderError() {	
275
-	    $error = I18N::translate('The media file was not found in this family tree.');
275
+		$error = I18N::translate('The media file was not found in this family tree.');
276 276
 
277
-    	$width  = (mb_strlen($error) * 6.5 + 50) * 1.15;
278
-    	$height = 60;
279
-    	$im     = imagecreatetruecolor($width, $height); /* Create a black image */
280
-    	$bgc    = imagecolorallocate($im, 255, 255, 255); /* set background color */
281
-    	imagefilledrectangle($im, 2, 2, $width - 4, $height - 4, $bgc); /* create a rectangle, leaving 2 px border */
277
+		$width  = (mb_strlen($error) * 6.5 + 50) * 1.15;
278
+		$height = 60;
279
+		$im     = imagecreatetruecolor($width, $height); /* Create a black image */
280
+		$bgc    = imagecolorallocate($im, 255, 255, 255); /* set background color */
281
+		imagefilledrectangle($im, 2, 2, $width - 4, $height - 4, $bgc); /* create a rectangle, leaving 2 px border */
282 282
     
283
-    	$this->embedText($im, $error, 100, '255, 0, 0', WT_ROOT . Config::FONT_DEJAVU_SANS_TTF, 'top', 'left');
283
+		$this->embedText($im, $error, 100, '255, 0, 0', WT_ROOT . Config::FONT_DEJAVU_SANS_TTF, 'top', 'left');
284 284
     
285
-    	http_response_code(404);
286
-    	header('Content-Type: image/png');
287
-    	imagepng($im);
288
-    	imagedestroy($im);
285
+		http_response_code(404);
286
+		header('Content-Type: image/png');
287
+		imagepng($im);
288
+		imagedestroy($im);
289 289
 	}
290 290
 	
291 291
 	/**
@@ -297,25 +297,25 @@  discard block
 block discarded – undo
297 297
 	 */
298 298
 	protected function applyWatermark($im) {
299 299
 	    
300
-	    // text to watermark with	    
301
-	    if(method_exists($this->media, 'getWatermarkText')) {
302
-	       $word1_text = $this->media->getWatermarkText();
303
-	    }
304
-	    else {
305
-	        $word1_text = $this->media->getTitle();
306
-	    }
300
+		// text to watermark with	    
301
+		if(method_exists($this->media, 'getWatermarkText')) {
302
+		   $word1_text = $this->media->getWatermarkText();
303
+		}
304
+		else {
305
+			$word1_text = $this->media->getTitle();
306
+		}
307 307
 	
308
-	    $this->embedText(
309
-	        $im, 
310
-	        $word1_text, 
311
-	        $this->font_max_size,
312
-	        $this->font_color,
313
-	        WT_ROOT . Config::FONT_DEJAVU_SANS_TTF,
314
-	        'top', 
315
-	        'left'
316
-	     );
308
+		$this->embedText(
309
+			$im, 
310
+			$word1_text, 
311
+			$this->font_max_size,
312
+			$this->font_color,
313
+			WT_ROOT . Config::FONT_DEJAVU_SANS_TTF,
314
+			'top', 
315
+			'left'
316
+		 );
317 317
 	
318
-	    return ($im);
318
+		return ($im);
319 319
 	}
320 320
 	
321 321
 	/**
@@ -332,94 +332,94 @@  discard block
 block discarded – undo
332 332
 	 */
333 333
 	protected function embedText($im, $text, $maxsize, $color, $font, $vpos, $hpos) {
334 334
 	    
335
-	    // there are two ways to embed text with PHP
336
-	    // (preferred) using GD and FreeType you can embed text using any True Type font
337
-	    // (fall back) if that is not available, you can insert basic monospaced text
335
+		// there are two ways to embed text with PHP
336
+		// (preferred) using GD and FreeType you can embed text using any True Type font
337
+		// (fall back) if that is not available, you can insert basic monospaced text
338 338
 	    
339
-	    $col = $this->hexrgb($color);
340
-	    $textcolor = imagecolorallocate($im, $col['red'], $col['green'], $col['blue']);
339
+		$col = $this->hexrgb($color);
340
+		$textcolor = imagecolorallocate($im, $col['red'], $col['green'], $col['blue']);
341 341
 	    
342
-	    // make adjustments to settings that imagestring and imagestringup can’t handle
343
-	    if (!$this->use_ttf) {
344
-	        // imagestringup only writes up, can’t use top2bottom
345
-	        if ($hpos === 'top2bottom') {
346
-	            $hpos = 'bottom2top';
347
-	        }
348
-	    }
342
+		// make adjustments to settings that imagestring and imagestringup can’t handle
343
+		if (!$this->use_ttf) {
344
+			// imagestringup only writes up, can’t use top2bottom
345
+			if ($hpos === 'top2bottom') {
346
+				$hpos = 'bottom2top';
347
+			}
348
+		}
349 349
 	    
350
-	    $text       = I18N::reverseText($text);
351
-	    $height     = imagesy($im);
352
-	    $width      = imagesx($im);
353
-	    $calc_angle = rad2deg(atan($height / $width));
354
-	    $hypoth     = $height / sin(deg2rad($calc_angle));
350
+		$text       = I18N::reverseText($text);
351
+		$height     = imagesy($im);
352
+		$width      = imagesx($im);
353
+		$calc_angle = rad2deg(atan($height / $width));
354
+		$hypoth     = $height / sin(deg2rad($calc_angle));
355 355
 	    
356
-	    // vertical and horizontal position of the text
357
-	    switch ($vpos) {
358
-	        default:
359
-	        case 'top':
360
-	            $taille   = $this->textLength($maxsize, $width, $text);
361
-	            $pos_y    = $height * 0.15 + $taille;
362
-	            $pos_x    = $width * 0.15;
363
-	            $rotation = 0;
364
-	            break;
365
-	        case 'middle':
366
-	            $taille   = $this->textLength($maxsize, $width, $text);
367
-	            $pos_y    = ($height + $taille) / 2;
368
-	            $pos_x    = $width * 0.15;
369
-	            $rotation = 0;
370
-	            break;
371
-	        case 'bottom':
372
-	            $taille   = $this->textLength($maxsize, $width, $text);
373
-	            $pos_y    = ($height * .85 - $taille);
374
-	            $pos_x    = $width * 0.15;
375
-	            $rotation = 0;
376
-	            break;
377
-	        case 'across':
378
-	            switch ($hpos) {
379
-	                default:
380
-	                case 'left':
381
-	                    $taille   = $this->textLength($maxsize, $hypoth, $text);
382
-	                    $pos_y    = ($height * .85 - $taille);
383
-	                    $pos_x    = $width * 0.15;
384
-	                    $rotation = $calc_angle;
385
-	                    break;
386
-	                case 'right':
387
-	                    $taille   = $this->textLength($maxsize, $hypoth, $text);
388
-	                    $pos_y    = ($height * .15 - $taille);
389
-	                    $pos_x    = $width * 0.85;
390
-	                    $rotation = $calc_angle + 180;
391
-	                    break;
392
-	                case 'top2bottom':
393
-	                    $taille   = $this->textLength($maxsize, $height, $text);
394
-	                    $pos_y    = ($height * .15 - $taille);
395
-	                    $pos_x    = ($width * .90 - $taille);
396
-	                    $rotation = -90;
397
-	                    break;
398
-	                case 'bottom2top':
399
-	                    $taille   = $this->textLength($maxsize, $height, $text);
400
-	                    $pos_y    = $height * 0.85;
401
-	                    $pos_x    = $width * 0.15;
402
-	                    $rotation = 90;
403
-	                    break;
404
-	            }
405
-	            break;
406
-	    }
356
+		// vertical and horizontal position of the text
357
+		switch ($vpos) {
358
+			default:
359
+			case 'top':
360
+				$taille   = $this->textLength($maxsize, $width, $text);
361
+				$pos_y    = $height * 0.15 + $taille;
362
+				$pos_x    = $width * 0.15;
363
+				$rotation = 0;
364
+				break;
365
+			case 'middle':
366
+				$taille   = $this->textLength($maxsize, $width, $text);
367
+				$pos_y    = ($height + $taille) / 2;
368
+				$pos_x    = $width * 0.15;
369
+				$rotation = 0;
370
+				break;
371
+			case 'bottom':
372
+				$taille   = $this->textLength($maxsize, $width, $text);
373
+				$pos_y    = ($height * .85 - $taille);
374
+				$pos_x    = $width * 0.15;
375
+				$rotation = 0;
376
+				break;
377
+			case 'across':
378
+				switch ($hpos) {
379
+					default:
380
+					case 'left':
381
+						$taille   = $this->textLength($maxsize, $hypoth, $text);
382
+						$pos_y    = ($height * .85 - $taille);
383
+						$pos_x    = $width * 0.15;
384
+						$rotation = $calc_angle;
385
+						break;
386
+					case 'right':
387
+						$taille   = $this->textLength($maxsize, $hypoth, $text);
388
+						$pos_y    = ($height * .15 - $taille);
389
+						$pos_x    = $width * 0.85;
390
+						$rotation = $calc_angle + 180;
391
+						break;
392
+					case 'top2bottom':
393
+						$taille   = $this->textLength($maxsize, $height, $text);
394
+						$pos_y    = ($height * .15 - $taille);
395
+						$pos_x    = ($width * .90 - $taille);
396
+						$rotation = -90;
397
+						break;
398
+					case 'bottom2top':
399
+						$taille   = $this->textLength($maxsize, $height, $text);
400
+						$pos_y    = $height * 0.85;
401
+						$pos_x    = $width * 0.15;
402
+						$rotation = 90;
403
+						break;
404
+				}
405
+				break;
406
+		}
407 407
 	    
408
-	    // apply the text
409
-	    if ($this->use_ttf) {
410
-	        // if imagettftext throws errors, catch them with a custom error handler
411
-	        set_error_handler(array($this, 'imageTtfTextErrorHandler'));
412
-	        imagettftext($im, $taille, $rotation, $pos_x, $pos_y, $textcolor, $font, $text);
413
-	        restore_error_handler();
414
-	    }
415
-	    // Don’t use an ‘else’ here since imagettftextErrorHandler may have changed the value of $useTTF from true to false
416
-	    if (!$this->use_ttf) {
417
-	        if ($rotation !== 90) {
418
-	            imagestring($im, 5, $pos_x, $pos_y, $text, $textcolor);
419
-	        } else {
420
-	            imagestringup($im, 5, $pos_x, $pos_y, $text, $textcolor);
421
-	        }
422
-	    }
408
+		// apply the text
409
+		if ($this->use_ttf) {
410
+			// if imagettftext throws errors, catch them with a custom error handler
411
+			set_error_handler(array($this, 'imageTtfTextErrorHandler'));
412
+			imagettftext($im, $taille, $rotation, $pos_x, $pos_y, $textcolor, $font, $text);
413
+			restore_error_handler();
414
+		}
415
+		// Don’t use an ‘else’ here since imagettftextErrorHandler may have changed the value of $useTTF from true to false
416
+		if (!$this->use_ttf) {
417
+			if ($rotation !== 90) {
418
+				imagestring($im, 5, $pos_x, $pos_y, $text, $textcolor);
419
+			} else {
420
+				imagestringup($im, 5, $pos_x, $pos_y, $text, $textcolor);
421
+			}
422
+		}
423 423
 	
424 424
 	}
425 425
 	
@@ -431,53 +431,53 @@  discard block
 block discarded – undo
431 431
 	 */
432 432
 	protected function hexrgb ($hexstr)
433 433
 	{
434
-	    $int = hexdec($hexstr);
434
+		$int = hexdec($hexstr);
435 435
 	
436
-	    return array('red' => 0xFF & ($int >> 0x10),
437
-	        'green' => 0xFF & ($int >> 0x8),
438
-	        'blue' => 0xFF & $int);
436
+		return array('red' => 0xFF & ($int >> 0x10),
437
+			'green' => 0xFF & ($int >> 0x8),
438
+			'blue' => 0xFF & $int);
439 439
 	}
440 440
 	
441
-    /**
442
-     * Generate an approximate length of text, in pixels.
443
-     *
444
-     * @param int    $t
445
-     * @param int    $mxl
446
-     * @param string $text
447
-     *
448
-     * @return int
449
-     */
450
-    function textLength($t, $mxl, $text) {
451
-    	$taille_c = $t;
452
-    	$len      = mb_strlen($text);
453
-    	while (($taille_c - 2) * $len > $mxl) {
454
-    		$taille_c--;
455
-    		if ($taille_c == 2) {
456
-    			break;
457
-    		}
458
-    	}
441
+	/**
442
+	 * Generate an approximate length of text, in pixels.
443
+	 *
444
+	 * @param int    $t
445
+	 * @param int    $mxl
446
+	 * @param string $text
447
+	 *
448
+	 * @return int
449
+	 */
450
+	function textLength($t, $mxl, $text) {
451
+		$taille_c = $t;
452
+		$len      = mb_strlen($text);
453
+		while (($taille_c - 2) * $len > $mxl) {
454
+			$taille_c--;
455
+			if ($taille_c == 2) {
456
+				break;
457
+			}
458
+		}
459 459
     
460
-    	return $taille_c;
461
-    }
460
+		return $taille_c;
461
+	}
462 462
     
463
-    /**
464
-     * imagettftext is the function that is most likely to throw an error
465
-     * use this custom error handler to catch and log it
466
-     *
467
-     * @param int    $errno
468
-     * @param string $errstr
469
-     *
470
-     * @return bool
471
-     */
472
-    function imageTtfTextErrorHandler($errno, $errstr) {
473
-        // log the error
474
-        Log::addErrorLog('Image Builder error: >' . $errno . '/' . $errstr . '< while processing file >' . $this->media->getServerFilename() . '<');
463
+	/**
464
+	 * imagettftext is the function that is most likely to throw an error
465
+	 * use this custom error handler to catch and log it
466
+	 *
467
+	 * @param int    $errno
468
+	 * @param string $errstr
469
+	 *
470
+	 * @return bool
471
+	 */
472
+	function imageTtfTextErrorHandler($errno, $errstr) {
473
+		// log the error
474
+		Log::addErrorLog('Image Builder error: >' . $errno . '/' . $errstr . '< while processing file >' . $this->media->getServerFilename() . '<');
475 475
     
476
-        // change value of useTTF to false so the fallback watermarking can be used.
477
-        $this->use_ttf = false;
476
+		// change value of useTTF to false so the fallback watermarking can be used.
477
+		$this->use_ttf = false;
478 478
     
479
-        return true;
480
-    }
479
+		return true;
480
+	}
481 481
 		
482 482
 }
483 483
 
Please login to merge, or discard this patch.
Spacing   +26 added lines, -26 removed lines patch added patch discarded remove patch
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
 	*
70 70
 	* @param Media|null $media Reference media object
71 71
 	*/
72
-	public function __construct(Media $media = null){
72
+	public function __construct(Media $media = null) {
73 73
 	    $this->media = $media;
74 74
 	    $this->use_ttf = function_exists('imagettftext');
75 75
 	    $this->expire_offset = 3600 * 24;
@@ -95,7 +95,7 @@  discard block
 block discarded – undo
95 95
 	 * @return ImageBuilder
96 96
 	 */
97 97
 	public function setExpireOffset($expireOffset) {
98
-	    if($expireOffset) $this->expire_offset = $expireOffset;
98
+	    if ($expireOffset) $this->expire_offset = $expireOffset;
99 99
 	    return $this;
100 100
 	}
101 101
 	
@@ -115,7 +115,7 @@  discard block
 block discarded – undo
115 115
 	 * @return ImageBuilder
116 116
 	 */
117 117
 	public function setShowWatermark($show_watermark) {
118
-	    if(!is_null($show_watermark)) $this->show_watermark = $show_watermark;
118
+	    if (!is_null($show_watermark)) $this->show_watermark = $show_watermark;
119 119
 	    return $this;
120 120
 	}
121 121
 	
@@ -126,7 +126,7 @@  discard block
 block discarded – undo
126 126
 	 * @return ImageBuilder
127 127
 	 */
128 128
 	public function setFontMaxSize($font_max_size) {
129
-	    if($font_max_size) $this->font_max_size = $font_max_size;
129
+	    if ($font_max_size) $this->font_max_size = $font_max_size;
130 130
 	    return $this;
131 131
 	}
132 132
 	
@@ -137,7 +137,7 @@  discard block
 block discarded – undo
137 137
 	 * @return ImageBuilder
138 138
 	 */
139 139
 	public function setFontColor($font_color) {
140
-	    if($font_color) $this->font_color = $font_color;
140
+	    if ($font_color) $this->font_color = $font_color;
141 141
 	    return $this;
142 142
 	}
143 143
 	
@@ -148,32 +148,32 @@  discard block
 block discarded – undo
148 148
 	 * @return ImageBuilder
149 149
 	 */
150 150
 	public function setAsAttachment($is_attachement) {
151
-	    if(is_bool($is_attachement)) $this->as_attachment = $is_attachement;
151
+	    if (is_bool($is_attachement)) $this->as_attachment = $is_attachement;
152 152
 	    return $this;
153 153
 	}
154 154
 	
155 155
 	/**
156 156
 	 * Render the image to the output.
157 157
 	 */
158
-	public function render(){
158
+	public function render() {
159 159
 	    
160 160
 	    if (!$this->media || !$this->media->canShow()) {
161
-	        Log::addMediaLog('Image Builder error: >' . I18N::translate('Missing or private media object.'));
161
+	        Log::addMediaLog('Image Builder error: >'.I18N::translate('Missing or private media object.'));
162 162
 	        $this->renderError();
163 163
 	    }
164 164
 	    
165 165
 	    $serverFilename = $this->media->getServerFilename();
166 166
 	    
167 167
 	    if (!file_exists($serverFilename)) {
168
-	        Log::addMediaLog('Image Builder error: >'. I18N::translate('The media object does not exist.').'< for path >'.$serverFilename.'<');
168
+	        Log::addMediaLog('Image Builder error: >'.I18N::translate('The media object does not exist.').'< for path >'.$serverFilename.'<');
169 169
 	        $this->renderError();
170 170
 	    }
171 171
 	    
172 172
 	    $mimetype = $this->media->mimeType();
173 173
 	    $imgsize = $this->media->getImageAttributes();
174 174
 	    $filetime = $this->media->getFiletime();
175
-	    $filetimeHeader = gmdate('D, d M Y H:i:s', $filetime) . ' GMT';	    
176
-	    $expireHeader = gmdate('D, d M Y H:i:s', WT_TIMESTAMP + $this->getExpireOffset()) . ' GMT';
175
+	    $filetimeHeader = gmdate('D, d M Y H:i:s', $filetime).' GMT';	    
176
+	    $expireHeader = gmdate('D, d M Y H:i:s', WT_TIMESTAMP + $this->getExpireOffset()).' GMT';
177 177
 	    
178 178
 	    $type = Functions::isImageTypeSupported($imgsize['ext']);
179 179
 	    $usewatermark = false;
@@ -205,10 +205,10 @@  discard block
 block discarded – undo
205 205
 	    }
206 206
 	    
207 207
 	    // add caching headers.  allow browser to cache file, but not proxy
208
-	    header('Last-Modified: ' . $filetimeHeader);
209
-	    header('ETag: "' . $etag . '"');
210
-	    header('Expires: ' . $expireHeader);
211
-	    header('Cache-Control: max-age=' . $this->getExpireOffset() . ', s-maxage=0, proxy-revalidate');
208
+	    header('Last-Modified: '.$filetimeHeader);
209
+	    header('ETag: "'.$etag.'"');
210
+	    header('Expires: '.$expireHeader);
211
+	    header('Cache-Control: max-age='.$this->getExpireOffset().', s-maxage=0, proxy-revalidate');
212 212
 	    
213 213
 	    // if this file is already in the user’s cache, don’t resend it
214 214
 	    // first check if the if_modified_since param matches
@@ -223,13 +223,13 @@  discard block
 block discarded – undo
223 223
 
224 224
 	    // send headers for the image
225 225
 	    $disposition = $this->as_attachment ? 'attachment' : 'inline';
226
-	    header('Content-Type: ' . $mimetype);
227
-	    header('Content-Disposition: ' . $disposition . '; filename="' . addslashes(basename($this->media->getFilename())) . '"');
226
+	    header('Content-Type: '.$mimetype);
227
+	    header('Content-Disposition: '.$disposition.'; filename="'.addslashes(basename($this->media->getFilename())).'"');
228 228
 	     
229 229
 	    if ($usewatermark) {
230 230
 	        // generate the watermarked image
231
-	        $imCreateFunc = 'imagecreatefrom' . $type;
232
-	        $imSendFunc   = 'image' . $type;
231
+	        $imCreateFunc = 'imagecreatefrom'.$type;
232
+	        $imSendFunc   = 'image'.$type;
233 233
 	    
234 234
 	        if (function_exists($imCreateFunc) && function_exists($imSendFunc)) {
235 235
 	            $im = $imCreateFunc($serverFilename);
@@ -242,7 +242,7 @@  discard block
 block discarded – undo
242 242
 	            return;
243 243
 	        } else {
244 244
 	            // this image is defective.  log it
245
-	            Log::addMediaLog('Image Builder error: >' . I18N::translate('This media file is broken and cannot be watermarked.') . '< in file >' . $serverFilename . '< memory used: ' . memory_get_usage());
245
+	            Log::addMediaLog('Image Builder error: >'.I18N::translate('This media file is broken and cannot be watermarked.').'< in file >'.$serverFilename.'< memory used: '.memory_get_usage());
246 246
 	        }
247 247
 	    }
248 248
 	    
@@ -250,7 +250,7 @@  discard block
 block discarded – undo
250 250
 	    $filesize = filesize($serverFilename);
251 251
 	    
252 252
 	    // set content-length header, send file
253
-	    header('Content-Length: ' . $filesize);
253
+	    header('Content-Length: '.$filesize);
254 254
 	    
255 255
 	    // Some servers disable fpassthru() and readfile()
256 256
 	    if (function_exists('readfile')) {
@@ -280,7 +280,7 @@  discard block
 block discarded – undo
280 280
     	$bgc    = imagecolorallocate($im, 255, 255, 255); /* set background color */
281 281
     	imagefilledrectangle($im, 2, 2, $width - 4, $height - 4, $bgc); /* create a rectangle, leaving 2 px border */
282 282
     
283
-    	$this->embedText($im, $error, 100, '255, 0, 0', WT_ROOT . Config::FONT_DEJAVU_SANS_TTF, 'top', 'left');
283
+    	$this->embedText($im, $error, 100, '255, 0, 0', WT_ROOT.Config::FONT_DEJAVU_SANS_TTF, 'top', 'left');
284 284
     
285 285
     	http_response_code(404);
286 286
     	header('Content-Type: image/png');
@@ -298,7 +298,7 @@  discard block
 block discarded – undo
298 298
 	protected function applyWatermark($im) {
299 299
 	    
300 300
 	    // text to watermark with	    
301
-	    if(method_exists($this->media, 'getWatermarkText')) {
301
+	    if (method_exists($this->media, 'getWatermarkText')) {
302 302
 	       $word1_text = $this->media->getWatermarkText();
303 303
 	    }
304 304
 	    else {
@@ -310,7 +310,7 @@  discard block
 block discarded – undo
310 310
 	        $word1_text, 
311 311
 	        $this->font_max_size,
312 312
 	        $this->font_color,
313
-	        WT_ROOT . Config::FONT_DEJAVU_SANS_TTF,
313
+	        WT_ROOT.Config::FONT_DEJAVU_SANS_TTF,
314 314
 	        'top', 
315 315
 	        'left'
316 316
 	     );
@@ -429,7 +429,7 @@  discard block
 block discarded – undo
429 429
 	 * @param string $hexstr
430 430
 	 * @return int[]
431 431
 	 */
432
-	protected function hexrgb ($hexstr)
432
+	protected function hexrgb($hexstr)
433 433
 	{
434 434
 	    $int = hexdec($hexstr);
435 435
 	
@@ -471,7 +471,7 @@  discard block
 block discarded – undo
471 471
      */
472 472
     function imageTtfTextErrorHandler($errno, $errstr) {
473 473
         // log the error
474
-        Log::addErrorLog('Image Builder error: >' . $errno . '/' . $errstr . '< while processing file >' . $this->media->getServerFilename() . '<');
474
+        Log::addErrorLog('Image Builder error: >'.$errno.'/'.$errstr.'< while processing file >'.$this->media->getServerFilename().'<');
475 475
     
476 476
         // change value of useTTF to false so the fallback watermarking can be used.
477 477
         $this->use_ttf = false;
Please login to merge, or discard this patch.
Braces   +16 added lines, -7 removed lines patch added patch discarded remove patch
@@ -95,7 +95,9 @@  discard block
 block discarded – undo
95 95
 	 * @return ImageBuilder
96 96
 	 */
97 97
 	public function setExpireOffset($expireOffset) {
98
-	    if($expireOffset) $this->expire_offset = $expireOffset;
98
+	    if($expireOffset) {
99
+	    	$this->expire_offset = $expireOffset;
100
+	    }
99 101
 	    return $this;
100 102
 	}
101 103
 	
@@ -115,7 +117,9 @@  discard block
 block discarded – undo
115 117
 	 * @return ImageBuilder
116 118
 	 */
117 119
 	public function setShowWatermark($show_watermark) {
118
-	    if(!is_null($show_watermark)) $this->show_watermark = $show_watermark;
120
+	    if(!is_null($show_watermark)) {
121
+	    	$this->show_watermark = $show_watermark;
122
+	    }
119 123
 	    return $this;
120 124
 	}
121 125
 	
@@ -126,7 +130,9 @@  discard block
 block discarded – undo
126 130
 	 * @return ImageBuilder
127 131
 	 */
128 132
 	public function setFontMaxSize($font_max_size) {
129
-	    if($font_max_size) $this->font_max_size = $font_max_size;
133
+	    if($font_max_size) {
134
+	    	$this->font_max_size = $font_max_size;
135
+	    }
130 136
 	    return $this;
131 137
 	}
132 138
 	
@@ -137,7 +143,9 @@  discard block
 block discarded – undo
137 143
 	 * @return ImageBuilder
138 144
 	 */
139 145
 	public function setFontColor($font_color) {
140
-	    if($font_color) $this->font_color = $font_color;
146
+	    if($font_color) {
147
+	    	$this->font_color = $font_color;
148
+	    }
141 149
 	    return $this;
142 150
 	}
143 151
 	
@@ -148,7 +156,9 @@  discard block
 block discarded – undo
148 156
 	 * @return ImageBuilder
149 157
 	 */
150 158
 	public function setAsAttachment($is_attachement) {
151
-	    if(is_bool($is_attachement)) $this->as_attachment = $is_attachement;
159
+	    if(is_bool($is_attachement)) {
160
+	    	$this->as_attachment = $is_attachement;
161
+	    }
152 162
 	    return $this;
153 163
 	}
154 164
 	
@@ -300,8 +310,7 @@  discard block
 block discarded – undo
300 310
 	    // text to watermark with	    
301 311
 	    if(method_exists($this->media, 'getWatermarkText')) {
302 312
 	       $word1_text = $this->media->getWatermarkText();
303
-	    }
304
-	    else {
313
+	    } else {
305 314
 	        $word1_text = $this->media->getTitle();
306 315
 	    }
307 316
 	
Please login to merge, or discard this patch.
src/Webtrees/Module/Sosa/Model/SosaProvider.php 3 patches
Braces   +80 added lines, -31 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
             }            
@@ -159,7 +163,9 @@  discard block
 block discarded – undo
159 163
      * Remove all Sosa entries related to the gedcom file and user
160 164
      */
161 165
     public function deleteAll() {
162
-        if(!$this->is_setup) return;
166
+        if(!$this->is_setup) {
167
+        	return;
168
+        }
163 169
         Database::prepare(
164 170
             'DELETE FROM `##maj_sosa`'.
165 171
             ' WHERE majs_gedcom_id= :tree_id and majs_user_id = :user_id ')
@@ -175,7 +181,9 @@  discard block
 block discarded – undo
175 181
      * @param int $sosa
176 182
      */
177 183
     public function deleteAncestors($sosa) {
178
-        if(!$this->is_setup) return;
184
+        if(!$this->is_setup) {
185
+        	return;
186
+        }
179 187
         $gen = Functions::getGeneration($sosa);
180 188
         Database::prepare(
181 189
             'DELETE FROM `##maj_sosa`'.
@@ -195,7 +203,9 @@  discard block
 block discarded – undo
195 203
      * @param array $sosa_records
196 204
      */
197 205
     public function insertOrUpdate($sosa_records) {
198
-        if(!$this->is_setup) return;
206
+        if(!$this->is_setup) {
207
+        	return;
208
+        }
199 209
         
200 210
         $treeid = $this->tree->getTreeId();
201 211
         $userid = $this->user->getUserId();
@@ -244,7 +254,9 @@  discard block
 block discarded – undo
244 254
      * @return array Array of sosa numbers
245 255
      */
246 256
     public function getSosaNumbers(Individual $indi) {
247
-        if(!$this->is_setup) return array();
257
+        if(!$this->is_setup) {
258
+        	return array();
259
+        }
248 260
         return Database::prepare(
249 261
                 'SELECT majs_sosa, majs_gen FROM `##maj_sosa`'.
250 262
                 ' WHERE majs_i_id=:indi_id AND majs_gedcom_id=:tree_id AND majs_user_id=:user_id'
@@ -261,7 +273,9 @@  discard block
 block discarded – undo
261 273
      * @return number Last generation if found, 1 otherwise
262 274
      */
263 275
     public function getLastGeneration() {
264
-        if(!$this->is_setup) return;
276
+        if(!$this->is_setup) {
277
+        	return;
278
+        }
265 279
         return Database::prepare(
266 280
                 'SELECT MAX(majs_gen) FROM `##maj_sosa`'.
267 281
                 ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'
@@ -281,7 +295,9 @@  discard block
 block discarded – undo
281 295
      * @return array Associative array of Sosa ancestors, with their generation, comma separated
282 296
      */
283 297
     public function getAllSosaWithGenerations(){
284
-        if(!$this->is_setup) return array();
298
+        if(!$this->is_setup) {
299
+        	return array();
300
+        }
285 301
         return Database::prepare(
286 302
             'SELECT majs_i_id AS indi,' .
287 303
             ' GROUP_CONCAT(DISTINCT majs_gen ORDER BY majs_gen ASC SEPARATOR ",") AS generations' .
@@ -301,9 +317,12 @@  discard block
 block discarded – undo
301 317
      * @return array Array of Sosa individuals
302 318
      */
303 319
     public function getSosaListAtGeneration($gen){
304
-        if(!$this->is_setup) return array();
305
-        if(!$this->sosa_list_by_gen)
306
-            $this->sosa_list_by_gen = array();
320
+        if(!$this->is_setup) {
321
+        	return array();
322
+        }
323
+        if(!$this->sosa_list_by_gen) {
324
+                    $this->sosa_list_by_gen = array();
325
+        }
307 326
         
308 327
         if($gen){
309 328
             if(!isset($this->sosa_list_by_gen[$gen])){
@@ -332,9 +351,12 @@  discard block
 block discarded – undo
332 351
      * @return array Array of Sosa families
333 352
      */
334 353
     public function getFamilySosaListAtGeneration($gen){
335
-        if(!$this->is_setup) return array();
336
-        if(!$this->sosa_fam_list_by_gen)
337
-            $this->sosa_fam_list_by_gen = array();
354
+        if(!$this->is_setup) {
355
+        	return array();
356
+        }
357
+        if(!$this->sosa_fam_list_by_gen) {
358
+                    $this->sosa_fam_list_by_gen = array();
359
+        }
338 360
         
339 361
         if($gen){
340 362
             if(!isset($this->sosa_fam_list_by_gen[$gen])){
@@ -368,7 +390,9 @@  discard block
 block discarded – undo
368 390
      * @return array Array of Sosa individuals
369 391
      */
370 392
     public function getMissingSosaListAtGeneration($gen){
371
-        if(!$this->is_setup) return array();    
393
+        if(!$this->is_setup) {
394
+        	return array();
395
+        }
372 396
         if($gen){
373 397
             return $this->sosa_list_by_gen[$gen] = Database::prepare(
374 398
                 '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'.
@@ -408,7 +432,9 @@  discard block
 block discarded – undo
408 432
      * @return array Statistics array
409 433
      */
410 434
     public function getStatisticsByGeneration() {
411
-        if(!$this->is_setup) return array();
435
+        if(!$this->is_setup) {
436
+        	return array();
437
+        }
412 438
         if(!$this->statistics_tab) {
413 439
             $this->statistics_tab = array();
414 440
             if($maxGeneration = $this->getLastGeneration()) {
@@ -436,7 +462,9 @@  discard block
 block discarded – undo
436 462
 	 * @return int
437 463
 	 */
438 464
 	public function getTotalIndividuals() {
439
-	    if(!$this->is_setup) return 0;
465
+	    if(!$this->is_setup) {
466
+	    	return 0;
467
+	    }
440 468
 	    return Database::prepare(
441 469
 	        'SELECT COUNT(*) FROM `##individuals`' .
442 470
 	        ' WHERE i_file = :tree_id')
@@ -450,7 +478,9 @@  discard block
 block discarded – undo
450 478
      * @return number Number of Sosas
451 479
      */
452 480
     public function getSosaCount(){
453
-        if(!$this->is_setup) return 0;
481
+        if(!$this->is_setup) {
482
+        	return 0;
483
+        }
454 484
         return Database::prepare(
455 485
             'SELECT COUNT(majs_sosa) FROM `##maj_sosa`' .
456 486
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
@@ -467,7 +497,9 @@  discard block
 block discarded – undo
467 497
      * @return number Number of Sosas in generation
468 498
      */
469 499
     public function getSosaCountAtGeneration($gen){
470
-        if(!$this->is_setup) return 0;
500
+        if(!$this->is_setup) {
501
+        	return 0;
502
+        }
471 503
         return Database::prepare(
472 504
             'SELECT COUNT(majs_sosa) FROM `##maj_sosa`' .
473 505
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
@@ -486,7 +518,9 @@  discard block
 block discarded – undo
486 518
      * @return number Total number of Sosas up to generation
487 519
      */
488 520
     public function getSosaCountUpToGeneration($gen){
489
-        if(!$this->is_setup) return 0;
521
+        if(!$this->is_setup) {
522
+        	return 0;
523
+        }
490 524
         return Database::prepare(
491 525
             'SELECT COUNT(majs_sosa) FROM `##maj_sosa`' .
492 526
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
@@ -504,7 +538,9 @@  discard block
 block discarded – undo
504 538
      * @return number Total number of distinct individual
505 539
      */
506 540
     public function getDifferentSosaCount(){
507
-        if(!$this->is_setup) return 0;
541
+        if(!$this->is_setup) {
542
+        	return 0;
543
+        }
508 544
         return Database::prepare(
509 545
             'SELECT COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
510 546
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
@@ -521,7 +557,9 @@  discard block
 block discarded – undo
521 557
      * @return number Number of distinct Sosa individuals up to generation
522 558
      */
523 559
     public function getDifferentSosaCountUpToGeneration($gen){
524
-        if(!$this->is_setup) return 0;
560
+        if(!$this->is_setup) {
561
+        	return 0;
562
+        }
525 563
         return Database::prepare(
526 564
             'SELECT COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
527 565
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
@@ -546,7 +584,9 @@  discard block
 block discarded – undo
546 584
      * @return array Birth statistics array
547 585
      */
548 586
     public function getStatsBirthYearInGeneration($gen){
549
-        if(!$this->is_setup) return array('first' => 0, 'first_est' => 0, 'avg' => 0, 'last' => 0, 'last_est' => 0);
587
+        if(!$this->is_setup) {
588
+        	return array('first' => 0, 'first_est' => 0, 'avg' => 0, 'last' => 0, 'last_est' => 0);
589
+        }
550 590
         return Database::prepare(
551 591
             'SELECT'.
552 592
             ' MIN(majs_birth_year) AS first, MIN(majs_birth_year_est) AS first_est,'.
@@ -568,7 +608,9 @@  discard block
 block discarded – undo
568 608
      * @return number|NULL Mean generation time
569 609
      */
570 610
     public function getMeanGenerationTime(){
571
-        if(!$this->is_setup) return;
611
+        if(!$this->is_setup) {
612
+        	return;
613
+        }
572 614
         if(!$this->statistics_tab){
573 615
             $this->getStatisticsByGeneration();
574 616
         }
@@ -610,7 +652,9 @@  discard block
 block discarded – undo
610 652
      * @return array
611 653
      */
612 654
     public function getGenerationDepthStatsAtGen($gen) {
613
-        if(!$this->is_setup) return array();
655
+        if(!$this->is_setup) {
656
+        	return array();
657
+        }
614 658
         $gen_depth_stats_raw = Database::prepare(
615 659
             'SELECT stats_by_gen.root_ancestor AS root_ancestor_sosa,'.
616 660
             '   sosa_list.majs_i_id as root_ancestor_id,'.
@@ -685,7 +729,10 @@  discard block
 block discarded – undo
685 729
      * @return array
686 730
      */
687 731
     public function getAncestorDispersionForGen($gen) {
688
-        if(!$this->is_setup || $gen > 11) return array();  // Going further than 11 gen will be out of range in the query
732
+        if(!$this->is_setup || $gen > 11) {
733
+        	return array();
734
+        }
735
+        // Going further than 11 gen will be out of range in the query
689 736
         return Database::prepare(
690 737
             'SELECT branches, count(i_id)'.
691 738
             ' FROM ('.
@@ -725,7 +772,9 @@  discard block
 block discarded – undo
725 772
      * @return array 
726 773
      */
727 774
     public function getTopMultiSosaAncestorsNoTies($limit) {
728
-        if(!$this->is_setup) return array();
775
+        if(!$this->is_setup) {
776
+        	return array();
777
+        }
729 778
         return Database::prepare(
730 779
             'SELECT sosa_i_id, sosa_count FROM ('.
731 780
             '   SELECT'.
Please login to merge, or discard this patch.
Indentation   +710 added lines, -710 removed lines patch added patch discarded remove patch
@@ -22,413 +22,413 @@  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 reference tree
118
-     * 
119
-     *  @return Tree Reference tree
120
-     */
121
-    public function getTree() {
122
-        return $this->tree;
123
-    }
124
-    
125
-    /**
126
-     * Return the reference user
127
-     * 
128
-     * @return User
129
-     */
130
-    public function getUser() {
131
-        return $this->user;
132
-    }
133
-    
134
-    /**
135
-     * Return the root individual ID for the reference tree and user.
136
-     * @return string Individual ID
137
-     */
138
-    public function getRootIndiId() {
139
-        return $this->tree->getUserPreference($this->user, 'MAJ_SOSA_ROOT_ID');
140
-    }
141
-    
142
-    /**
143
-     * Return the root individual for the reference tree and user.
144
-     * @return Individual Individual
145
-     */
146
-    public function getRootIndi() {
147
-        $root_indi_id = $this->getRootIndiId();
148
-        if(!empty($root_indi_id)) {
149
-            return Individual::getInstance($root_indi_id, $this->tree);
150
-        }
151
-        return null;
152
-    }
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 reference tree
118
+	 * 
119
+	 *  @return Tree Reference tree
120
+	 */
121
+	public function getTree() {
122
+		return $this->tree;
123
+	}
124
+    
125
+	/**
126
+	 * Return the reference user
127
+	 * 
128
+	 * @return User
129
+	 */
130
+	public function getUser() {
131
+		return $this->user;
132
+	}
133
+    
134
+	/**
135
+	 * Return the root individual ID for the reference tree and user.
136
+	 * @return string Individual ID
137
+	 */
138
+	public function getRootIndiId() {
139
+		return $this->tree->getUserPreference($this->user, 'MAJ_SOSA_ROOT_ID');
140
+	}
141
+    
142
+	/**
143
+	 * Return the root individual for the reference tree and user.
144
+	 * @return Individual Individual
145
+	 */
146
+	public function getRootIndi() {
147
+		$root_indi_id = $this->getRootIndiId();
148
+		if(!empty($root_indi_id)) {
149
+			return Individual::getInstance($root_indi_id, $this->tree);
150
+		}
151
+		return null;
152
+	}
153 153
        
154
-    /*****************
154
+	/*****************
155 155
      * DATA CRUD LAYER
156 156
      *****************/
157 157
     
158
-    /**
159
-     * Remove all Sosa entries related to the gedcom file and user
160
-     */
161
-    public function deleteAll() {
162
-        if(!$this->is_setup) return;
163
-        Database::prepare(
164
-            'DELETE FROM `##maj_sosa`'.
165
-            ' WHERE majs_gedcom_id= :tree_id and majs_user_id = :user_id ')
166
-            ->execute(array(
167
-                'tree_id' => $this->tree->getTreeId(), 
168
-                'user_id' => $this->user->getUserId()                
169
-            ));
170
-    }
171
-    
172
-    /**
173
-     * Remove all ancestors of a sosa number
174
-     * 
175
-     * @param int $sosa
176
-     */
177
-    public function deleteAncestors($sosa) {
178
-        if(!$this->is_setup) return;
179
-        $gen = Functions::getGeneration($sosa);
180
-        Database::prepare(
181
-            'DELETE FROM `##maj_sosa`'.
182
-            ' WHERE majs_gedcom_id=:tree_id and majs_user_id = :user_id' .
183
-            ' AND majs_gen >= :gen' .
184
-            ' AND FLOOR(majs_sosa / (POW(2, (majs_gen - :gen)))) = :sosa'
185
-        )->execute(array(
186
-            'tree_id' => $this->tree->getTreeId(), 
187
-            'user_id' => $this->user->getUserId(),
188
-            'gen' => $gen,
189
-            'sosa' => $sosa
190
-        ));
191
-    }    
192
-    
193
-    /**
194
-     * Insert (or update if already existing) a list of Sosa individuals
195
-     * @param array $sosa_records
196
-     */
197
-    public function insertOrUpdate($sosa_records) {
198
-        if(!$this->is_setup) return;
158
+	/**
159
+	 * Remove all Sosa entries related to the gedcom file and user
160
+	 */
161
+	public function deleteAll() {
162
+		if(!$this->is_setup) return;
163
+		Database::prepare(
164
+			'DELETE FROM `##maj_sosa`'.
165
+			' WHERE majs_gedcom_id= :tree_id and majs_user_id = :user_id ')
166
+			->execute(array(
167
+				'tree_id' => $this->tree->getTreeId(), 
168
+				'user_id' => $this->user->getUserId()                
169
+			));
170
+	}
171
+    
172
+	/**
173
+	 * Remove all ancestors of a sosa number
174
+	 * 
175
+	 * @param int $sosa
176
+	 */
177
+	public function deleteAncestors($sosa) {
178
+		if(!$this->is_setup) return;
179
+		$gen = Functions::getGeneration($sosa);
180
+		Database::prepare(
181
+			'DELETE FROM `##maj_sosa`'.
182
+			' WHERE majs_gedcom_id=:tree_id and majs_user_id = :user_id' .
183
+			' AND majs_gen >= :gen' .
184
+			' AND FLOOR(majs_sosa / (POW(2, (majs_gen - :gen)))) = :sosa'
185
+		)->execute(array(
186
+			'tree_id' => $this->tree->getTreeId(), 
187
+			'user_id' => $this->user->getUserId(),
188
+			'gen' => $gen,
189
+			'sosa' => $sosa
190
+		));
191
+	}    
192
+    
193
+	/**
194
+	 * Insert (or update if already existing) a list of Sosa individuals
195
+	 * @param array $sosa_records
196
+	 */
197
+	public function insertOrUpdate($sosa_records) {
198
+		if(!$this->is_setup) return;
199 199
         
200
-        $treeid = $this->tree->getTreeId();
201
-        $userid = $this->user->getUserId();
202
-        $questionmarks_table = array();
203
-        $values_table = array();
200
+		$treeid = $this->tree->getTreeId();
201
+		$userid = $this->user->getUserId();
202
+		$questionmarks_table = array();
203
+		$values_table = array();
204 204
         
205
-        $i = 0;
206
-        foreach  ($sosa_records as $row) {
207
-            $gen = Functions::getGeneration($row['sosa']);
208
-            if($gen <= self::MAX_DB_GENERATIONS) {
209
-                $questionmarks_table[] = 
210
-                    '(:tree_id'.$i.', :user_id'.$i.', :sosa'.$i.', :indi_id'.$i.', :gen'.$i.', :byear'.$i.', :byearest'.$i.', :dyear'.$i.', :dyearest'.$i.')';
211
-                $values_table = array_merge(
212
-                    $values_table, 
213
-                    array(
214
-                        'tree_id'.$i => $treeid, 
215
-                        'user_id'.$i => $userid, 
216
-                        'sosa'.$i => $row['sosa'], 
217
-                        'indi_id'.$i => $row['indi'], 
218
-                        'gen'.$i => Functions::getGeneration($row['sosa']),
219
-                        'byear'.$i => $row['birth_year'],
220
-                        'byearest'.$i => $row['birth_year_est'],
221
-                        'dyear'.$i => $row['death_year'],
222
-                        'dyearest'.$i => $row['death_year_est']
223
-                    )
224
-                );
225
-            }
226
-            $i++;
227
-        }
205
+		$i = 0;
206
+		foreach  ($sosa_records as $row) {
207
+			$gen = Functions::getGeneration($row['sosa']);
208
+			if($gen <= self::MAX_DB_GENERATIONS) {
209
+				$questionmarks_table[] = 
210
+					'(:tree_id'.$i.', :user_id'.$i.', :sosa'.$i.', :indi_id'.$i.', :gen'.$i.', :byear'.$i.', :byearest'.$i.', :dyear'.$i.', :dyearest'.$i.')';
211
+				$values_table = array_merge(
212
+					$values_table, 
213
+					array(
214
+						'tree_id'.$i => $treeid, 
215
+						'user_id'.$i => $userid, 
216
+						'sosa'.$i => $row['sosa'], 
217
+						'indi_id'.$i => $row['indi'], 
218
+						'gen'.$i => Functions::getGeneration($row['sosa']),
219
+						'byear'.$i => $row['birth_year'],
220
+						'byearest'.$i => $row['birth_year_est'],
221
+						'dyear'.$i => $row['death_year'],
222
+						'dyearest'.$i => $row['death_year_est']
223
+					)
224
+				);
225
+			}
226
+			$i++;
227
+		}
228 228
         
229
-        $sql = 'REPLACE INTO `##maj_sosa`' .
230
-            ' (majs_gedcom_id, majs_user_id, majs_sosa, majs_i_id, majs_gen, majs_birth_year, majs_birth_year_est, majs_death_year, majs_death_year_est)' .
231
-            ' VALUES '. implode(',', $questionmarks_table);
232
-        Database::prepare($sql)->execute($values_table);
233
-    }
229
+		$sql = 'REPLACE INTO `##maj_sosa`' .
230
+			' (majs_gedcom_id, majs_user_id, majs_sosa, majs_i_id, majs_gen, majs_birth_year, majs_birth_year_est, majs_death_year, majs_death_year_est)' .
231
+			' VALUES '. implode(',', $questionmarks_table);
232
+		Database::prepare($sql)->execute($values_table);
233
+	}
234 234
     
235
-    /****************
235
+	/****************
236 236
      * SIMPLE QUERIES
237 237
      ****************/
238 238
     
239
-    /**
240
-     * Returns the list of Sosa numbers to which an individual is related.
241
-     * Format: key = sosa number, value = generation for the Sosa number
242
-     * 
243
-     * @param Individual $indi
244
-     * @return array Array of sosa numbers
245
-     */
246
-    public function getSosaNumbers(Individual $indi) {
247
-        if(!$this->is_setup) return array();
248
-        return Database::prepare(
249
-                'SELECT majs_sosa, majs_gen FROM `##maj_sosa`'.
250
-                ' WHERE majs_i_id=:indi_id AND majs_gedcom_id=:tree_id AND majs_user_id=:user_id'
251
-            )->execute(array(
252
-                'indi_id' => $indi->getXref(), 
253
-                'tree_id' => $this->tree->getTreeId(), 
254
-                'user_id' => $this->user->getUserId()
255
-            ))->fetchAssoc();
256
-    }
257
-    
258
-    /**
259
-     * Get the last generation of Sosa ancestors
260
-     *
261
-     * @return number Last generation if found, 1 otherwise
262
-     */
263
-    public function getLastGeneration() {
264
-        if(!$this->is_setup) return;
265
-        return Database::prepare(
266
-                'SELECT MAX(majs_gen) FROM `##maj_sosa`'.
267
-                ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'
268
-            )->execute(array(
269
-                'tree_id' => $this->tree->getTreeId(), 
270
-                'user_id' => $this->user->getUserId()                
271
-            ))->fetchOne() ?: 1;
272
-    }
273
-    
274
-    /*************
239
+	/**
240
+	 * Returns the list of Sosa numbers to which an individual is related.
241
+	 * Format: key = sosa number, value = generation for the Sosa number
242
+	 * 
243
+	 * @param Individual $indi
244
+	 * @return array Array of sosa numbers
245
+	 */
246
+	public function getSosaNumbers(Individual $indi) {
247
+		if(!$this->is_setup) return array();
248
+		return Database::prepare(
249
+				'SELECT majs_sosa, majs_gen FROM `##maj_sosa`'.
250
+				' WHERE majs_i_id=:indi_id AND majs_gedcom_id=:tree_id AND majs_user_id=:user_id'
251
+			)->execute(array(
252
+				'indi_id' => $indi->getXref(), 
253
+				'tree_id' => $this->tree->getTreeId(), 
254
+				'user_id' => $this->user->getUserId()
255
+			))->fetchAssoc();
256
+	}
257
+    
258
+	/**
259
+	 * Get the last generation of Sosa ancestors
260
+	 *
261
+	 * @return number Last generation if found, 1 otherwise
262
+	 */
263
+	public function getLastGeneration() {
264
+		if(!$this->is_setup) return;
265
+		return Database::prepare(
266
+				'SELECT MAX(majs_gen) FROM `##maj_sosa`'.
267
+				' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'
268
+			)->execute(array(
269
+				'tree_id' => $this->tree->getTreeId(), 
270
+				'user_id' => $this->user->getUserId()                
271
+			))->fetchOne() ?: 1;
272
+	}
273
+    
274
+	/*************
275 275
      * SOSA LISTS
276 276
      *************/
277 277
     
278
-    /**
279
-     * Return the list of all sosas, with the generations it belongs to
280
-     *
281
-     * @return array Associative array of Sosa ancestors, with their generation, comma separated
282
-     */
283
-    public function getAllSosaWithGenerations(){
284
-        if(!$this->is_setup) return array();
285
-        return Database::prepare(
286
-            'SELECT majs_i_id AS indi,' .
287
-            ' GROUP_CONCAT(DISTINCT majs_gen ORDER BY majs_gen ASC SEPARATOR ",") AS generations' .
288
-            ' FROM `##maj_sosa`' .
289
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id' .
290
-            ' GROUP BY majs_i_id'
291
-        )->execute(array(
292
-            'tree_id' => $this->tree->getTreeId(),
293
-            'user_id' => $this->user->getUserId()
294
-        ))->fetchAssoc();
295
-    }
296
-    
297
-    /**
298
-     * Get an associative array of Sosa individuals in generation G. Keys are Sosa numbers, values individuals.
299
-     *
300
-     * @param number $gen Generation
301
-     * @return array Array of Sosa individuals
302
-     */
303
-    public function getSosaListAtGeneration($gen){
304
-        if(!$this->is_setup) return array();
305
-        if(!$this->sosa_list_by_gen)
306
-            $this->sosa_list_by_gen = array();
278
+	/**
279
+	 * Return the list of all sosas, with the generations it belongs to
280
+	 *
281
+	 * @return array Associative array of Sosa ancestors, with their generation, comma separated
282
+	 */
283
+	public function getAllSosaWithGenerations(){
284
+		if(!$this->is_setup) return array();
285
+		return Database::prepare(
286
+			'SELECT majs_i_id AS indi,' .
287
+			' GROUP_CONCAT(DISTINCT majs_gen ORDER BY majs_gen ASC SEPARATOR ",") AS generations' .
288
+			' FROM `##maj_sosa`' .
289
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id' .
290
+			' GROUP BY majs_i_id'
291
+		)->execute(array(
292
+			'tree_id' => $this->tree->getTreeId(),
293
+			'user_id' => $this->user->getUserId()
294
+		))->fetchAssoc();
295
+	}
296
+    
297
+	/**
298
+	 * Get an associative array of Sosa individuals in generation G. Keys are Sosa numbers, values individuals.
299
+	 *
300
+	 * @param number $gen Generation
301
+	 * @return array Array of Sosa individuals
302
+	 */
303
+	public function getSosaListAtGeneration($gen){
304
+		if(!$this->is_setup) return array();
305
+		if(!$this->sosa_list_by_gen)
306
+			$this->sosa_list_by_gen = array();
307 307
         
308
-        if($gen){
309
-            if(!isset($this->sosa_list_by_gen[$gen])){
310
-                $this->sosa_list_by_gen[$gen] = Database::prepare(
311
-                    'SELECT majs_sosa AS sosa, majs_i_id AS indi'.
312
-                    ' FROM `##maj_sosa`'.
313
-                    ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
314
-                    ' AND majs_gen = :gen'.
315
-                    ' ORDER BY majs_sosa ASC')
316
-                ->execute(array(
317
-                    'tree_id' => $this->tree->getTreeId(),
318
-                    'user_id' => $this->user->getUserId(),
319
-                    'gen' => $gen
320
-                ))
321
-                ->fetchAssoc();
322
-            }
323
-            return $this->sosa_list_by_gen[$gen];
324
-        }
325
-        return array();
326
-    }
327
-    
328
-    /**
329
-     * Get an associative array of Sosa families in generation G. Keys are Sosa numbers for the husband, values families.
330
-     *
331
-     * @param number $gen Generation
332
-     * @return array Array of Sosa families
333
-     */
334
-    public function getFamilySosaListAtGeneration($gen){
335
-        if(!$this->is_setup) return array();
336
-        if(!$this->sosa_fam_list_by_gen)
337
-            $this->sosa_fam_list_by_gen = array();
308
+		if($gen){
309
+			if(!isset($this->sosa_list_by_gen[$gen])){
310
+				$this->sosa_list_by_gen[$gen] = Database::prepare(
311
+					'SELECT majs_sosa AS sosa, majs_i_id AS indi'.
312
+					' FROM `##maj_sosa`'.
313
+					' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
314
+					' AND majs_gen = :gen'.
315
+					' ORDER BY majs_sosa ASC')
316
+				->execute(array(
317
+					'tree_id' => $this->tree->getTreeId(),
318
+					'user_id' => $this->user->getUserId(),
319
+					'gen' => $gen
320
+				))
321
+				->fetchAssoc();
322
+			}
323
+			return $this->sosa_list_by_gen[$gen];
324
+		}
325
+		return array();
326
+	}
327
+    
328
+	/**
329
+	 * Get an associative array of Sosa families in generation G. Keys are Sosa numbers for the husband, values families.
330
+	 *
331
+	 * @param number $gen Generation
332
+	 * @return array Array of Sosa families
333
+	 */
334
+	public function getFamilySosaListAtGeneration($gen){
335
+		if(!$this->is_setup) return array();
336
+		if(!$this->sosa_fam_list_by_gen)
337
+			$this->sosa_fam_list_by_gen = array();
338 338
         
339
-        if($gen){
340
-            if(!isset($this->sosa_fam_list_by_gen[$gen])){
341
-                $this->sosa_fam_list_by_gen[$gen] = Database::prepare(
342
-                    'SELECT s1.majs_sosa AS sosa, f_id AS fam'.
343
-                    ' FROM `##families`'.
344
-                    ' INNER JOIN `##maj_sosa` AS s1 ON (`##families`.f_husb = s1.majs_i_id AND `##families`.f_file = s1.majs_gedcom_id)'.
345
-                    ' INNER JOIN `##maj_sosa` AS s2 ON (`##families`.f_wife = s2.majs_i_id AND `##families`.f_file = s2.majs_gedcom_id)'.
346
-                    ' WHERE s1.majs_sosa + 1 = s2.majs_sosa'.
347
-                    ' AND s1.majs_gedcom_id= :tree_id AND s1.majs_user_id=:user_id'.
348
-                    ' AND s2.majs_gedcom_id= :tree_id AND s2.majs_user_id=:user_id'.
349
-                    ' AND s1.majs_gen = :gen'.
350
-                    ' ORDER BY s1.majs_sosa ASC'
351
-                    )
352
-                    ->execute(array(
353
-                        'tree_id' => $this->tree->getTreeId(),
354
-                        'user_id' => $this->user->getUserId(),
355
-                        'gen' => $gen
356
-                    ))
357
-                    ->fetchAssoc();
358
-            }
359
-            return $this->sosa_fam_list_by_gen[$gen];
360
-        }
361
-        return array();
362
-    }
363
-    
364
-    /**
365
-     * Get an associative array of Sosa individuals in generation G who are missing parents. Keys are Sosa numbers, values individuals.
366
-     *
367
-     * @param number $gen Generation
368
-     * @return array Array of Sosa individuals
369
-     */
370
-    public function getMissingSosaListAtGeneration($gen){
371
-        if(!$this->is_setup) return array();    
372
-        if($gen){
373
-            return $this->sosa_list_by_gen[$gen] = Database::prepare(
374
-                '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'.
375
-                ' FROM `##maj_sosa` schild'.
376
-                ' 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)'.
377
-                ' 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)'.
378
-                ' WHERE schild.majs_gedcom_id = :tree_id AND schild.majs_user_id = :user_id'.
379
-                ' AND schild.majs_gen = :gen'.
380
-                ' AND (sfat.majs_sosa IS NULL OR smot.majs_sosa IS NULL)'.
381
-                ' ORDER BY schild.majs_sosa ASC')
382
-                ->execute(array(
383
-                    'tree_id' => $this->tree->getTreeId(),
384
-                    'user_id' => $this->user->getUserId(),
385
-                    'gen' => $gen - 1
386
-                ))->fetchAll(\PDO::FETCH_ASSOC);
387
-        }
388
-        return array();
389
-    }
390
-    
391
-    
392
-    
393
-    /*************
339
+		if($gen){
340
+			if(!isset($this->sosa_fam_list_by_gen[$gen])){
341
+				$this->sosa_fam_list_by_gen[$gen] = Database::prepare(
342
+					'SELECT s1.majs_sosa AS sosa, f_id AS fam'.
343
+					' FROM `##families`'.
344
+					' INNER JOIN `##maj_sosa` AS s1 ON (`##families`.f_husb = s1.majs_i_id AND `##families`.f_file = s1.majs_gedcom_id)'.
345
+					' INNER JOIN `##maj_sosa` AS s2 ON (`##families`.f_wife = s2.majs_i_id AND `##families`.f_file = s2.majs_gedcom_id)'.
346
+					' WHERE s1.majs_sosa + 1 = s2.majs_sosa'.
347
+					' AND s1.majs_gedcom_id= :tree_id AND s1.majs_user_id=:user_id'.
348
+					' AND s2.majs_gedcom_id= :tree_id AND s2.majs_user_id=:user_id'.
349
+					' AND s1.majs_gen = :gen'.
350
+					' ORDER BY s1.majs_sosa ASC'
351
+					)
352
+					->execute(array(
353
+						'tree_id' => $this->tree->getTreeId(),
354
+						'user_id' => $this->user->getUserId(),
355
+						'gen' => $gen
356
+					))
357
+					->fetchAssoc();
358
+			}
359
+			return $this->sosa_fam_list_by_gen[$gen];
360
+		}
361
+		return array();
362
+	}
363
+    
364
+	/**
365
+	 * Get an associative array of Sosa individuals in generation G who are missing parents. Keys are Sosa numbers, values individuals.
366
+	 *
367
+	 * @param number $gen Generation
368
+	 * @return array Array of Sosa individuals
369
+	 */
370
+	public function getMissingSosaListAtGeneration($gen){
371
+		if(!$this->is_setup) return array();    
372
+		if($gen){
373
+			return $this->sosa_list_by_gen[$gen] = Database::prepare(
374
+				'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'.
375
+				' FROM `##maj_sosa` schild'.
376
+				' 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)'.
377
+				' 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)'.
378
+				' WHERE schild.majs_gedcom_id = :tree_id AND schild.majs_user_id = :user_id'.
379
+				' AND schild.majs_gen = :gen'.
380
+				' AND (sfat.majs_sosa IS NULL OR smot.majs_sosa IS NULL)'.
381
+				' ORDER BY schild.majs_sosa ASC')
382
+				->execute(array(
383
+					'tree_id' => $this->tree->getTreeId(),
384
+					'user_id' => $this->user->getUserId(),
385
+					'gen' => $gen - 1
386
+				))->fetchAll(\PDO::FETCH_ASSOC);
387
+		}
388
+		return array();
389
+	}
390
+    
391
+    
392
+    
393
+	/*************
394 394
      * STATISTICS
395 395
      *************/
396
-    /**
397
-     * Get the statistic array detailed by generation.
398
-     * Statistics for each generation are:
399
-     * 	- The number of Sosa in generation
400
-     * 	- The number of Sosa up to generation
401
-     *  - The number of distinct Sosa up to generation
402
-     *  - The year of the first birth in generation
403
-     *  - The year of the first estimated birth in generation
404
-     *  - The year of the last birth in generation
405
-     *  - The year of the last estimated birth in generation
406
-     *  - The average year of birth in generation
407
-     *
408
-     * @return array Statistics array
409
-     */
410
-    public function getStatisticsByGeneration() {
411
-        if(!$this->is_setup) return array();
412
-        if(!$this->statistics_tab) {
413
-            $this->statistics_tab = array();
414
-            if($maxGeneration = $this->getLastGeneration()) {
415
-                for ($gen = 1; $gen <= $maxGeneration; $gen++) {
416
-                    $birthStats = $this->getStatsBirthYearInGeneration($gen);
417
-                    $this->statistics_tab[$gen] = array(
418
-                        'sosaCount'				=>	$this->getSosaCountAtGeneration($gen),
419
-                        'sosaTotalCount'		=>	$this->getSosaCountUpToGeneration($gen),
420
-                        'diffSosaTotalCount'	=>	$this->getDifferentSosaCountUpToGeneration($gen),
421
-                        'firstBirth'			=>	$birthStats['first'],
422
-                        'firstEstimatedBirth'	=>	$birthStats['first_est'],
423
-                        'lastBirth'				=>	$birthStats['last'],
424
-                        'lastEstimatedBirth'	=>	$birthStats['last_est'],
425
-                        'avgBirth'				=>	$birthStats['avg']
426
-                    );
427
-                }
428
-            }
429
-        }
430
-        return $this->statistics_tab;        
431
-    }
396
+	/**
397
+	 * Get the statistic array detailed by generation.
398
+	 * Statistics for each generation are:
399
+	 * 	- The number of Sosa in generation
400
+	 * 	- The number of Sosa up to generation
401
+	 *  - The number of distinct Sosa up to generation
402
+	 *  - The year of the first birth in generation
403
+	 *  - The year of the first estimated birth in generation
404
+	 *  - The year of the last birth in generation
405
+	 *  - The year of the last estimated birth in generation
406
+	 *  - The average year of birth in generation
407
+	 *
408
+	 * @return array Statistics array
409
+	 */
410
+	public function getStatisticsByGeneration() {
411
+		if(!$this->is_setup) return array();
412
+		if(!$this->statistics_tab) {
413
+			$this->statistics_tab = array();
414
+			if($maxGeneration = $this->getLastGeneration()) {
415
+				for ($gen = 1; $gen <= $maxGeneration; $gen++) {
416
+					$birthStats = $this->getStatsBirthYearInGeneration($gen);
417
+					$this->statistics_tab[$gen] = array(
418
+						'sosaCount'				=>	$this->getSosaCountAtGeneration($gen),
419
+						'sosaTotalCount'		=>	$this->getSosaCountUpToGeneration($gen),
420
+						'diffSosaTotalCount'	=>	$this->getDifferentSosaCountUpToGeneration($gen),
421
+						'firstBirth'			=>	$birthStats['first'],
422
+						'firstEstimatedBirth'	=>	$birthStats['first_est'],
423
+						'lastBirth'				=>	$birthStats['last'],
424
+						'lastEstimatedBirth'	=>	$birthStats['last_est'],
425
+						'avgBirth'				=>	$birthStats['avg']
426
+					);
427
+				}
428
+			}
429
+		}
430
+		return $this->statistics_tab;        
431
+	}
432 432
     
433 433
 	/**
434 434
 	 * How many individuals exist in the tree.
@@ -436,332 +436,332 @@  discard block
 block discarded – undo
436 436
 	 * @return int
437 437
 	 */
438 438
 	public function getTotalIndividuals() {
439
-	    if(!$this->is_setup) return 0;
440
-	    return Database::prepare(
441
-	        'SELECT COUNT(*) FROM `##individuals`' .
442
-	        ' WHERE i_file = :tree_id')
443
-	        ->execute(array('tree_id' => $this->tree->getTreeId()))
444
-	        ->fetchOne() ?: 0;
439
+		if(!$this->is_setup) return 0;
440
+		return Database::prepare(
441
+			'SELECT COUNT(*) FROM `##individuals`' .
442
+			' WHERE i_file = :tree_id')
443
+			->execute(array('tree_id' => $this->tree->getTreeId()))
444
+			->fetchOne() ?: 0;
445 445
 	}
446 446
     
447
-    /**
448
-     * Get the total Sosa count for all generations
449
-     *
450
-     * @return number Number of Sosas
451
-     */
452
-    public function getSosaCount(){
453
-        if(!$this->is_setup) return 0;
454
-        return Database::prepare(
455
-            'SELECT COUNT(majs_sosa) FROM `##maj_sosa`' .
456
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
457
-            ->execute(array(
458
-                'tree_id' => $this->tree->getTreeId(), 
459
-                'user_id' => $this->user->getUserId() 
460
-            ))->fetchOne() ?: 0;
461
-    }
462
-    
463
-    /**
464
-     * Get the number of Sosa in a specific generation.
465
-     *
466
-     * @param number $gen Generation
467
-     * @return number Number of Sosas in generation
468
-     */
469
-    public function getSosaCountAtGeneration($gen){
470
-        if(!$this->is_setup) return 0;
471
-        return Database::prepare(
472
-            'SELECT COUNT(majs_sosa) FROM `##maj_sosa`' .
473
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
474
-            ' AND majs_gen= :gen')
475
-        ->execute(array(
476
-                'tree_id' => $this->tree->getTreeId(), 
477
-                'user_id' => $this->user->getUserId(),
478
-                'gen' => $gen            
479
-        ))->fetchOne() ?: 0;
480
-    }
481
-    
482
-    /**
483
-     * Get the total number of Sosa up to a specific generation.
484
-     *
485
-     * @param number $gen Generation
486
-     * @return number Total number of Sosas up to generation
487
-     */
488
-    public function getSosaCountUpToGeneration($gen){
489
-        if(!$this->is_setup) return 0;
490
-        return Database::prepare(
491
-            'SELECT COUNT(majs_sosa) FROM `##maj_sosa`' .
492
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
493
-            ' AND majs_gen <= :gen')
494
-        ->execute(array(
495
-                'tree_id' => $this->tree->getTreeId(), 
496
-                'user_id' => $this->user->getUserId(),
497
-                'gen' => $gen 
498
-        ))->fetchOne() ?: 0;
499
-    }
500
-    
501
-    /**
502
-     * Get the total number of distinct Sosa individual for all generations.
503
-     *
504
-     * @return number Total number of distinct individual
505
-     */
506
-    public function getDifferentSosaCount(){
507
-        if(!$this->is_setup) return 0;
508
-        return Database::prepare(
509
-            'SELECT COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
510
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
511
-        ->execute(array(
512
-                'tree_id' => $this->tree->getTreeId(), 
513
-                'user_id' => $this->user->getUserId()
514
-        ))->fetchOne() ?: 0;
515
-    }
516
-    
517
-    /**
518
-     * Get the number of distinct Sosa individual up to a specific generation.
519
-     *
520
-     * @param number $gen Generation
521
-     * @return number Number of distinct Sosa individuals up to generation
522
-     */
523
-    public function getDifferentSosaCountUpToGeneration($gen){
524
-        if(!$this->is_setup) return 0;
525
-        return Database::prepare(
526
-            'SELECT COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
527
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
528
-            ' AND majs_gen <= :gen')
529
-        ->execute(array(
530
-                'tree_id' => $this->tree->getTreeId(), 
531
-                'user_id' => $this->user->getUserId(),
532
-                'gen' => $gen 
533
-        ))->fetchOne() ?: 0;
534
-    }
535
-    
536
-    /**
537
-     * Get an array of birth statistics for a specific generation
538
-     * Statistics are :
539
-     * 	- first : First birth year in generation
540
-     *  - first_est: First estimated birth year in generation
541
-     *  - last : Last birth year in generation
542
-     *  - last_est : Last estimated birth year in generation
543
-     *  - avg : Average birth year (based on non-estimated birth date)
544
-     *
545
-     * @param number $gen Generation
546
-     * @return array Birth statistics array
547
-     */
548
-    public function getStatsBirthYearInGeneration($gen){
549
-        if(!$this->is_setup) return array('first' => 0, 'first_est' => 0, 'avg' => 0, 'last' => 0, 'last_est' => 0);
550
-        return Database::prepare(
551
-            'SELECT'.
552
-            ' MIN(majs_birth_year) AS first, MIN(majs_birth_year_est) AS first_est,'.
553
-            ' AVG(majs_birth_year) AS avg,'.
554
-            ' MAX(majs_birth_year) AS last, MAX(majs_birth_year_est) AS last_est'.
555
-            ' FROM `##maj_sosa`'.
556
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
557
-            ' AND majs_gen=:gen')
558
-            ->execute(array(
559
-                'tree_id' => $this->tree->getTreeId(), 
560
-                'user_id' => $this->user->getUserId(),
561
-                'gen' => $gen))
562
-            ->fetchOneRow(\PDO::FETCH_ASSOC) ?: array('first' => 0, 'first_est' => 0, 'avg' => 0, 'last' => 0, 'last_est' => 0);
563
-    }
564
-    
565
-    /**
566
-     * Get the mean generation time, based on a linear regression of birth years and generations
567
-     *
568
-     * @return number|NULL Mean generation time
569
-     */
570
-    public function getMeanGenerationTime(){
571
-        if(!$this->is_setup) return;
572
-        if(!$this->statistics_tab){
573
-            $this->getStatisticsByGeneration();
574
-        }
575
-        //Linear regression on x=generation and y=birthdate
576
-        $sum_xy = $sum_x = $sum_y= $sum_x2 = $n = 0;
577
-        foreach($this->statistics_tab as $gen=>$stats){
578
-            if(!is_null($stats['avgBirth'])) {
579
-                $n++;
580
-                $sum_xy+=$gen*$stats['avgBirth'];
581
-                $sum_x+=$gen;
582
-                $sum_y+=$stats['avgBirth'];
583
-                $sum_x2+=$gen*$gen;
584
-            }
585
-        }
586
-        $denom=($n*$sum_x2)-($sum_x*$sum_x);
587
-        if($denom!=0){
588
-            return -(($n*$sum_xy)-($sum_x*$sum_y))/($denom);
589
-        }
590
-        return null;
591
-    }
592
-    
593
-    /**
594
-     * Return an array of the mean generation depth and standard deviation for all Sosa ancestors at a given generation.
595
-     * Sosa 1 is of generation 1.
596
-     * 
597
-     * Mean generation depth and deviation are calculated based on the works of Marie-Héléne Cazes and Pierre Cazes,
598
-     * published in Population (French Edition), Vol. 51, No. 1 (Jan. - Feb., 1996), pp. 117-140
599
-     * http://kintip.net/index.php?option=com_jdownloads&task=download.send&id=9&catid=4&m=0
600
-     * 
601
-     * Format: 
602
-     *  - key : sosa number of the ancestor
603
-     *  - values: array
604
-     *      - root_ancestor_id : ID of the ancestor
605
-     *      - mean_gen_depth : Mean generation depth
606
-     *      - stddev_gen_depth : Standard deviation of generation depth
607
-     *  
608
-     * @param number $gen Sosa generation
609
-     * @return array
610
-     */
611
-    public function getGenerationDepthStatsAtGen($gen) {
612
-        if(!$this->is_setup) return array();
613
-        $gen_depth_stats_raw = Database::prepare(
614
-            'SELECT stats_by_gen.root_ancestor AS root_ancestor_sosa,'.
615
-            '   sosa_list.majs_i_id as root_ancestor_id,'.
616
-            '   1 + SUM( (majs_gen_norm) * ( 2 * full_root_count + semi_root_count) /  (2 * POWER(2, majs_gen_norm))) AS mean_gen_depth,'.
617
-            '   SQRT('. 
618
-            '       SUM(POWER(majs_gen_norm, 2) * ( 2 * full_root_count + semi_root_count) /  (2 * POWER(2, majs_gen_norm)))'.
619
-            '       - POWER( SUM( (majs_gen_norm) * ( 2 * full_root_count + semi_root_count) /  (2 * POWER(2, majs_gen_norm))), 2)'.
620
-            '   ) AS stddev_gen_depth'.
621
-            ' FROM('.
622
-            '   SELECT'.
623
-            '       sosa.majs_gedcom_id,'.
624
-            '       sosa.majs_user_id,'.
625
-            '       sosa.majs_gen - :gen AS majs_gen_norm,'.
626
-            '       FLOOR(((sosa.majs_sosa / POW(2, sosa.majs_gen -1 )) - 1) * POWER(2, :gen - 1)) + POWER(2, :gen - 1) AS root_ancestor,'.
627
-            '       SUM(case when sosa_fat.majs_i_id IS NULL AND sosa_mot.majs_i_id IS NULL THEN 1 ELSE 0 END) AS full_root_count,'.
628
-            '       SUM(case when sosa_fat.majs_i_id IS NULL AND sosa_mot.majs_i_id IS NULL THEN 0 ELSE 1 END) As semi_root_count'.
629
-            '   FROM `##maj_sosa` AS sosa'.
630
-            '   LEFT JOIN `##maj_sosa` AS sosa_fat ON sosa_fat.majs_sosa = 2 * sosa.majs_sosa'.
631
-            '       AND sosa_fat.majs_gedcom_id = sosa.majs_gedcom_id'.
632
-            '       AND sosa_fat.majs_user_id = sosa.majs_user_id'.
633
-            '   LEFT JOIN `##maj_sosa` AS sosa_mot ON sosa_mot.majs_sosa = 2 * sosa.majs_sosa + 1'.
634
-            '       AND sosa_mot.majs_gedcom_id = sosa.majs_gedcom_id'.
635
-            '       AND sosa_mot.majs_user_id = sosa.majs_user_id'.
636
-            '   WHERE sosa.majs_gedcom_id = :tree_id'.
637
-            '       AND sosa.majs_user_id = :user_id'.
638
-            '       AND sosa.majs_gen >=  :gen'.
639
-            '       AND (sosa_fat.majs_i_id IS NULL OR sosa_mot.majs_i_id IS NULL)'.
640
-            '   GROUP BY sosa.majs_gen, root_ancestor'.
641
-            ' ) AS stats_by_gen'.
642
-            ' INNER JOIN `##maj_sosa` sosa_list ON sosa_list.majs_gedcom_id = stats_by_gen.majs_gedcom_id'.
643
-            '   AND sosa_list.majs_user_id = stats_by_gen.majs_user_id'.
644
-            '   AND sosa_list.majs_sosa = stats_by_gen.root_ancestor'.
645
-            ' GROUP BY stats_by_gen.root_ancestor, sosa_list.majs_i_id'.
646
-            ' ORDER BY stats_by_gen.root_ancestor')
647
-        ->execute(array(
648
-            'tree_id' => $this->tree->getTreeId(),
649
-            'user_id' => $this->user->getUserId(),
650
-            'gen' => $gen
651
-        ))->fetchAll() ?: array();
447
+	/**
448
+	 * Get the total Sosa count for all generations
449
+	 *
450
+	 * @return number Number of Sosas
451
+	 */
452
+	public function getSosaCount(){
453
+		if(!$this->is_setup) return 0;
454
+		return Database::prepare(
455
+			'SELECT COUNT(majs_sosa) FROM `##maj_sosa`' .
456
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
457
+			->execute(array(
458
+				'tree_id' => $this->tree->getTreeId(), 
459
+				'user_id' => $this->user->getUserId() 
460
+			))->fetchOne() ?: 0;
461
+	}
462
+    
463
+	/**
464
+	 * Get the number of Sosa in a specific generation.
465
+	 *
466
+	 * @param number $gen Generation
467
+	 * @return number Number of Sosas in generation
468
+	 */
469
+	public function getSosaCountAtGeneration($gen){
470
+		if(!$this->is_setup) return 0;
471
+		return Database::prepare(
472
+			'SELECT COUNT(majs_sosa) FROM `##maj_sosa`' .
473
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
474
+			' AND majs_gen= :gen')
475
+		->execute(array(
476
+				'tree_id' => $this->tree->getTreeId(), 
477
+				'user_id' => $this->user->getUserId(),
478
+				'gen' => $gen            
479
+		))->fetchOne() ?: 0;
480
+	}
481
+    
482
+	/**
483
+	 * Get the total number of Sosa up to a specific generation.
484
+	 *
485
+	 * @param number $gen Generation
486
+	 * @return number Total number of Sosas up to generation
487
+	 */
488
+	public function getSosaCountUpToGeneration($gen){
489
+		if(!$this->is_setup) return 0;
490
+		return Database::prepare(
491
+			'SELECT COUNT(majs_sosa) FROM `##maj_sosa`' .
492
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
493
+			' AND majs_gen <= :gen')
494
+		->execute(array(
495
+				'tree_id' => $this->tree->getTreeId(), 
496
+				'user_id' => $this->user->getUserId(),
497
+				'gen' => $gen 
498
+		))->fetchOne() ?: 0;
499
+	}
500
+    
501
+	/**
502
+	 * Get the total number of distinct Sosa individual for all generations.
503
+	 *
504
+	 * @return number Total number of distinct individual
505
+	 */
506
+	public function getDifferentSosaCount(){
507
+		if(!$this->is_setup) return 0;
508
+		return Database::prepare(
509
+			'SELECT COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
510
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
511
+		->execute(array(
512
+				'tree_id' => $this->tree->getTreeId(), 
513
+				'user_id' => $this->user->getUserId()
514
+		))->fetchOne() ?: 0;
515
+	}
516
+    
517
+	/**
518
+	 * Get the number of distinct Sosa individual up to a specific generation.
519
+	 *
520
+	 * @param number $gen Generation
521
+	 * @return number Number of distinct Sosa individuals up to generation
522
+	 */
523
+	public function getDifferentSosaCountUpToGeneration($gen){
524
+		if(!$this->is_setup) return 0;
525
+		return Database::prepare(
526
+			'SELECT COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
527
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
528
+			' AND majs_gen <= :gen')
529
+		->execute(array(
530
+				'tree_id' => $this->tree->getTreeId(), 
531
+				'user_id' => $this->user->getUserId(),
532
+				'gen' => $gen 
533
+		))->fetchOne() ?: 0;
534
+	}
535
+    
536
+	/**
537
+	 * Get an array of birth statistics for a specific generation
538
+	 * Statistics are :
539
+	 * 	- first : First birth year in generation
540
+	 *  - first_est: First estimated birth year in generation
541
+	 *  - last : Last birth year in generation
542
+	 *  - last_est : Last estimated birth year in generation
543
+	 *  - avg : Average birth year (based on non-estimated birth date)
544
+	 *
545
+	 * @param number $gen Generation
546
+	 * @return array Birth statistics array
547
+	 */
548
+	public function getStatsBirthYearInGeneration($gen){
549
+		if(!$this->is_setup) return array('first' => 0, 'first_est' => 0, 'avg' => 0, 'last' => 0, 'last_est' => 0);
550
+		return Database::prepare(
551
+			'SELECT'.
552
+			' MIN(majs_birth_year) AS first, MIN(majs_birth_year_est) AS first_est,'.
553
+			' AVG(majs_birth_year) AS avg,'.
554
+			' MAX(majs_birth_year) AS last, MAX(majs_birth_year_est) AS last_est'.
555
+			' FROM `##maj_sosa`'.
556
+			' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
557
+			' AND majs_gen=:gen')
558
+			->execute(array(
559
+				'tree_id' => $this->tree->getTreeId(), 
560
+				'user_id' => $this->user->getUserId(),
561
+				'gen' => $gen))
562
+			->fetchOneRow(\PDO::FETCH_ASSOC) ?: array('first' => 0, 'first_est' => 0, 'avg' => 0, 'last' => 0, 'last_est' => 0);
563
+	}
564
+    
565
+	/**
566
+	 * Get the mean generation time, based on a linear regression of birth years and generations
567
+	 *
568
+	 * @return number|NULL Mean generation time
569
+	 */
570
+	public function getMeanGenerationTime(){
571
+		if(!$this->is_setup) return;
572
+		if(!$this->statistics_tab){
573
+			$this->getStatisticsByGeneration();
574
+		}
575
+		//Linear regression on x=generation and y=birthdate
576
+		$sum_xy = $sum_x = $sum_y= $sum_x2 = $n = 0;
577
+		foreach($this->statistics_tab as $gen=>$stats){
578
+			if(!is_null($stats['avgBirth'])) {
579
+				$n++;
580
+				$sum_xy+=$gen*$stats['avgBirth'];
581
+				$sum_x+=$gen;
582
+				$sum_y+=$stats['avgBirth'];
583
+				$sum_x2+=$gen*$gen;
584
+			}
585
+		}
586
+		$denom=($n*$sum_x2)-($sum_x*$sum_x);
587
+		if($denom!=0){
588
+			return -(($n*$sum_xy)-($sum_x*$sum_y))/($denom);
589
+		}
590
+		return null;
591
+	}
592
+    
593
+	/**
594
+	 * Return an array of the mean generation depth and standard deviation for all Sosa ancestors at a given generation.
595
+	 * Sosa 1 is of generation 1.
596
+	 * 
597
+	 * Mean generation depth and deviation are calculated based on the works of Marie-Héléne Cazes and Pierre Cazes,
598
+	 * published in Population (French Edition), Vol. 51, No. 1 (Jan. - Feb., 1996), pp. 117-140
599
+	 * http://kintip.net/index.php?option=com_jdownloads&task=download.send&id=9&catid=4&m=0
600
+	 * 
601
+	 * Format: 
602
+	 *  - key : sosa number of the ancestor
603
+	 *  - values: array
604
+	 *      - root_ancestor_id : ID of the ancestor
605
+	 *      - mean_gen_depth : Mean generation depth
606
+	 *      - stddev_gen_depth : Standard deviation of generation depth
607
+	 *  
608
+	 * @param number $gen Sosa generation
609
+	 * @return array
610
+	 */
611
+	public function getGenerationDepthStatsAtGen($gen) {
612
+		if(!$this->is_setup) return array();
613
+		$gen_depth_stats_raw = Database::prepare(
614
+			'SELECT stats_by_gen.root_ancestor AS root_ancestor_sosa,'.
615
+			'   sosa_list.majs_i_id as root_ancestor_id,'.
616
+			'   1 + SUM( (majs_gen_norm) * ( 2 * full_root_count + semi_root_count) /  (2 * POWER(2, majs_gen_norm))) AS mean_gen_depth,'.
617
+			'   SQRT('. 
618
+			'       SUM(POWER(majs_gen_norm, 2) * ( 2 * full_root_count + semi_root_count) /  (2 * POWER(2, majs_gen_norm)))'.
619
+			'       - POWER( SUM( (majs_gen_norm) * ( 2 * full_root_count + semi_root_count) /  (2 * POWER(2, majs_gen_norm))), 2)'.
620
+			'   ) AS stddev_gen_depth'.
621
+			' FROM('.
622
+			'   SELECT'.
623
+			'       sosa.majs_gedcom_id,'.
624
+			'       sosa.majs_user_id,'.
625
+			'       sosa.majs_gen - :gen AS majs_gen_norm,'.
626
+			'       FLOOR(((sosa.majs_sosa / POW(2, sosa.majs_gen -1 )) - 1) * POWER(2, :gen - 1)) + POWER(2, :gen - 1) AS root_ancestor,'.
627
+			'       SUM(case when sosa_fat.majs_i_id IS NULL AND sosa_mot.majs_i_id IS NULL THEN 1 ELSE 0 END) AS full_root_count,'.
628
+			'       SUM(case when sosa_fat.majs_i_id IS NULL AND sosa_mot.majs_i_id IS NULL THEN 0 ELSE 1 END) As semi_root_count'.
629
+			'   FROM `##maj_sosa` AS sosa'.
630
+			'   LEFT JOIN `##maj_sosa` AS sosa_fat ON sosa_fat.majs_sosa = 2 * sosa.majs_sosa'.
631
+			'       AND sosa_fat.majs_gedcom_id = sosa.majs_gedcom_id'.
632
+			'       AND sosa_fat.majs_user_id = sosa.majs_user_id'.
633
+			'   LEFT JOIN `##maj_sosa` AS sosa_mot ON sosa_mot.majs_sosa = 2 * sosa.majs_sosa + 1'.
634
+			'       AND sosa_mot.majs_gedcom_id = sosa.majs_gedcom_id'.
635
+			'       AND sosa_mot.majs_user_id = sosa.majs_user_id'.
636
+			'   WHERE sosa.majs_gedcom_id = :tree_id'.
637
+			'       AND sosa.majs_user_id = :user_id'.
638
+			'       AND sosa.majs_gen >=  :gen'.
639
+			'       AND (sosa_fat.majs_i_id IS NULL OR sosa_mot.majs_i_id IS NULL)'.
640
+			'   GROUP BY sosa.majs_gen, root_ancestor'.
641
+			' ) AS stats_by_gen'.
642
+			' INNER JOIN `##maj_sosa` sosa_list ON sosa_list.majs_gedcom_id = stats_by_gen.majs_gedcom_id'.
643
+			'   AND sosa_list.majs_user_id = stats_by_gen.majs_user_id'.
644
+			'   AND sosa_list.majs_sosa = stats_by_gen.root_ancestor'.
645
+			' GROUP BY stats_by_gen.root_ancestor, sosa_list.majs_i_id'.
646
+			' ORDER BY stats_by_gen.root_ancestor')
647
+		->execute(array(
648
+			'tree_id' => $this->tree->getTreeId(),
649
+			'user_id' => $this->user->getUserId(),
650
+			'gen' => $gen
651
+		))->fetchAll() ?: array();
652 652
         
653
-        $gen_depth_stats = array();
654
-        foreach ($gen_depth_stats_raw as $gen_depth_stat) {
655
-            $gen_depth_stats[$gen_depth_stat->root_ancestor_sosa] = array(
656
-                'root_ancestor_id' => $gen_depth_stat->root_ancestor_id,
657
-                'mean_gen_depth' => $gen_depth_stat->mean_gen_depth,
658
-                'stddev_gen_depth' => $gen_depth_stat->stddev_gen_depth
659
-            );
660
-        }
661
-        return $gen_depth_stats;
662
-    }
663
-    
664
-    /**
665
-     * Return a computed array of statistics about the dispersion of ancestors across the ancestors
666
-     * at a specified generation.
667
-     * This statistics cannot be used for generations above 11, as it would cause a out of range in MySQL
668
-     * 
669
-     * Format: 
670
-     *  - key : a base-2 representation of the ancestor at generation G for which exclusive ancestors have been found,
671
-     *          -1 is used for shared ancestors
672
-     *          For instance base2(0100) = base10(4) represent the maternal grand father
673
-     *  - values: number of ancestors exclusively in the ancestors of the ancestor in key
674
-     *  
675
-     *  For instance a result at generation 3 could be :
676
-     *      array (   -1        =>  12      -> 12 ancestors are shared by the grand-parents
677
-     *                base10(1) =>  32      -> 32 ancestors are exclusive to the paternal grand-father
678
-     *                base10(2) =>  25      -> 25 ancestors are exclusive to the paternal grand-mother
679
-     *                base10(4) =>  12      -> 12 ancestors are exclusive to the maternal grand-father
680
-     *                base10(8) =>  30      -> 30 ancestors are exclusive to the maternal grand-mother
681
-     *            )
682
-     *  
683
-     * @param int $gen Reference generation
684
-     * @return array
685
-     */
686
-    public function getAncestorDispersionForGen($gen) {
687
-        if(!$this->is_setup || $gen > 11) return array();  // Going further than 11 gen will be out of range in the query
688
-        return Database::prepare(
689
-            'SELECT branches, count(i_id)'.
690
-            ' FROM ('.
691
-            '   SELECT i_id,'.
692
-            '       CASE'.
693
-            '           WHEN CEIL(LOG2(SUM(branch))) = LOG2(SUM(branch)) THEN SUM(branch)'.
694
-            '           ELSE -1'.   // We put all ancestors shared between some branches in the same bucket
695
-            '       END branches'.
696
-            '   FROM ('.
697
-            '       SELECT DISTINCT majs_i_id i_id,'.
698
-            '           POW(2, FLOOR(majs_sosa / POW(2, (majs_gen - :gen))) - POW(2, :gen -1)) branch'.
699
-            '       FROM `##maj_sosa`'.
700
-            '       WHERE majs_gedcom_id = :tree_id AND majs_user_id = :user_id'.
701
-            '           AND majs_gen >= :gen'.
702
-            '   ) indistat'.
703
-            '   GROUP BY i_id'.
704
-            ') grouped'.
705
-            ' GROUP BY branches')
706
-            ->execute(array(
707
-                'tree_id' => $this->tree->getTreeId(), 
708
-                'user_id' => $this->user->getUserId(),
709
-                'gen' => $gen
710
-            ))->fetchAssoc() ?: array();
711
-    }
712
-    
713
-    /**
714
-     * Return an array of the most duplicated root Sosa ancestors.
715
-     * The number of ancestors to return is limited by the parameter $limit.
716
-     * If several individuals are tied when reaching the limit, none of them are returned,
717
-     * which means that there can be less individuals returned than requested.
718
-     * 
719
-     * Format: 
720
-     *  - key : root Sosa individual
721
-     *  - value: number of duplications of the ancestor (e.g. 3 if it appears 3 times)
722
-     * 
723
-     * @param number $limit Maximum number of individuals to return
724
-     * @return array 
725
-     */
726
-    public function getTopMultiSosaAncestorsNoTies($limit) {
727
-        if(!$this->is_setup) return array();
728
-        return Database::prepare(
729
-            'SELECT sosa_i_id, sosa_count FROM ('.
730
-            '   SELECT'.
731
-            '       top_sosa.sosa_i_id, top_sosa.sosa_count, top_sosa.sosa_min,'.
732
-            '       @keep := IF(@prev_count = 0 OR sosa_count = @prev_count, @keep, 1) AS keep,'.
733
-            '       @prev_count := top_sosa.sosa_count AS prev_count'.
734
-            '   FROM ('.
735
-            '       SELECT'.
736
-            '           sosa.majs_i_id sosa_i_id,'.
737
-            '           COUNT(sosa.majs_sosa) sosa_count,'.
738
-            '           MIN(sosa.majs_sosa) sosa_min'.
739
-            '       FROM ##maj_sosa AS sosa'.
740
-            '       LEFT JOIN ##maj_sosa AS sosa_fat ON sosa_fat.majs_sosa = 2 * sosa.majs_sosa'.   // Link to sosa's father
741
-            '           AND sosa.majs_gedcom_id = sosa_fat.majs_gedcom_id'.
742
-            '           AND sosa.majs_user_id = sosa_fat.majs_user_id'.
743
-            '       LEFT JOIN ##maj_sosa AS sosa_mot on sosa_mot.majs_sosa = (2 * sosa.majs_sosa + 1)'.  // Link to sosa's mother
744
-            '           AND sosa.majs_gedcom_id = sosa_fat.majs_gedcom_id'.
745
-            '           AND sosa.majs_user_id = sosa_fat.majs_user_id'.
746
-            '       WHERE sosa.majs_gedcom_id = :tree_id'.
747
-            '       AND sosa.majs_user_id = :user_id'.
748
-            '       AND sosa_fat.majs_sosa IS NULL'.    // We keep only root individuals, i.e. those with no father or mother
749
-            '       AND sosa_mot.majs_sosa IS NULL'. 
750
-            '       GROUP BY sosa.majs_i_id'.
751
-            '       HAVING COUNT(sosa.majs_sosa) > 1'.   // Limit to the duplicate sosas.
752
-            '       ORDER BY COUNT(sosa.majs_sosa) DESC'.
753
-            '       LIMIT ' . ($limit + 1) . // We want to select one more than required
754
-            '   ) AS top_sosa,'.
755
-            '   (SELECT @prev_count := 0, @keep := 0) x'.
756
-            '   ORDER BY top_sosa.sosa_count ASC'.
757
-            ' ) top_sosa_list'.
758
-            ' WHERE keep = 1'.
759
-            ' ORDER BY sosa_count DESC, sosa_min ASC'
760
-            )->execute(array(
761
-                'tree_id' => $this->tree->getTreeId(),
762
-                'user_id' => $this->user->getUserId()
763
-            ))->fetchAssoc() ?: array();
764
-    }
653
+		$gen_depth_stats = array();
654
+		foreach ($gen_depth_stats_raw as $gen_depth_stat) {
655
+			$gen_depth_stats[$gen_depth_stat->root_ancestor_sosa] = array(
656
+				'root_ancestor_id' => $gen_depth_stat->root_ancestor_id,
657
+				'mean_gen_depth' => $gen_depth_stat->mean_gen_depth,
658
+				'stddev_gen_depth' => $gen_depth_stat->stddev_gen_depth
659
+			);
660
+		}
661
+		return $gen_depth_stats;
662
+	}
663
+    
664
+	/**
665
+	 * Return a computed array of statistics about the dispersion of ancestors across the ancestors
666
+	 * at a specified generation.
667
+	 * This statistics cannot be used for generations above 11, as it would cause a out of range in MySQL
668
+	 * 
669
+	 * Format: 
670
+	 *  - key : a base-2 representation of the ancestor at generation G for which exclusive ancestors have been found,
671
+	 *          -1 is used for shared ancestors
672
+	 *          For instance base2(0100) = base10(4) represent the maternal grand father
673
+	 *  - values: number of ancestors exclusively in the ancestors of the ancestor in key
674
+	 *  
675
+	 *  For instance a result at generation 3 could be :
676
+	 *      array (   -1        =>  12      -> 12 ancestors are shared by the grand-parents
677
+	 *                base10(1) =>  32      -> 32 ancestors are exclusive to the paternal grand-father
678
+	 *                base10(2) =>  25      -> 25 ancestors are exclusive to the paternal grand-mother
679
+	 *                base10(4) =>  12      -> 12 ancestors are exclusive to the maternal grand-father
680
+	 *                base10(8) =>  30      -> 30 ancestors are exclusive to the maternal grand-mother
681
+	 *            )
682
+	 *  
683
+	 * @param int $gen Reference generation
684
+	 * @return array
685
+	 */
686
+	public function getAncestorDispersionForGen($gen) {
687
+		if(!$this->is_setup || $gen > 11) return array();  // Going further than 11 gen will be out of range in the query
688
+		return Database::prepare(
689
+			'SELECT branches, count(i_id)'.
690
+			' FROM ('.
691
+			'   SELECT i_id,'.
692
+			'       CASE'.
693
+			'           WHEN CEIL(LOG2(SUM(branch))) = LOG2(SUM(branch)) THEN SUM(branch)'.
694
+			'           ELSE -1'.   // We put all ancestors shared between some branches in the same bucket
695
+			'       END branches'.
696
+			'   FROM ('.
697
+			'       SELECT DISTINCT majs_i_id i_id,'.
698
+			'           POW(2, FLOOR(majs_sosa / POW(2, (majs_gen - :gen))) - POW(2, :gen -1)) branch'.
699
+			'       FROM `##maj_sosa`'.
700
+			'       WHERE majs_gedcom_id = :tree_id AND majs_user_id = :user_id'.
701
+			'           AND majs_gen >= :gen'.
702
+			'   ) indistat'.
703
+			'   GROUP BY i_id'.
704
+			') grouped'.
705
+			' GROUP BY branches')
706
+			->execute(array(
707
+				'tree_id' => $this->tree->getTreeId(), 
708
+				'user_id' => $this->user->getUserId(),
709
+				'gen' => $gen
710
+			))->fetchAssoc() ?: array();
711
+	}
712
+    
713
+	/**
714
+	 * Return an array of the most duplicated root Sosa ancestors.
715
+	 * The number of ancestors to return is limited by the parameter $limit.
716
+	 * If several individuals are tied when reaching the limit, none of them are returned,
717
+	 * which means that there can be less individuals returned than requested.
718
+	 * 
719
+	 * Format: 
720
+	 *  - key : root Sosa individual
721
+	 *  - value: number of duplications of the ancestor (e.g. 3 if it appears 3 times)
722
+	 * 
723
+	 * @param number $limit Maximum number of individuals to return
724
+	 * @return array 
725
+	 */
726
+	public function getTopMultiSosaAncestorsNoTies($limit) {
727
+		if(!$this->is_setup) return array();
728
+		return Database::prepare(
729
+			'SELECT sosa_i_id, sosa_count FROM ('.
730
+			'   SELECT'.
731
+			'       top_sosa.sosa_i_id, top_sosa.sosa_count, top_sosa.sosa_min,'.
732
+			'       @keep := IF(@prev_count = 0 OR sosa_count = @prev_count, @keep, 1) AS keep,'.
733
+			'       @prev_count := top_sosa.sosa_count AS prev_count'.
734
+			'   FROM ('.
735
+			'       SELECT'.
736
+			'           sosa.majs_i_id sosa_i_id,'.
737
+			'           COUNT(sosa.majs_sosa) sosa_count,'.
738
+			'           MIN(sosa.majs_sosa) sosa_min'.
739
+			'       FROM ##maj_sosa AS sosa'.
740
+			'       LEFT JOIN ##maj_sosa AS sosa_fat ON sosa_fat.majs_sosa = 2 * sosa.majs_sosa'.   // Link to sosa's father
741
+			'           AND sosa.majs_gedcom_id = sosa_fat.majs_gedcom_id'.
742
+			'           AND sosa.majs_user_id = sosa_fat.majs_user_id'.
743
+			'       LEFT JOIN ##maj_sosa AS sosa_mot on sosa_mot.majs_sosa = (2 * sosa.majs_sosa + 1)'.  // Link to sosa's mother
744
+			'           AND sosa.majs_gedcom_id = sosa_fat.majs_gedcom_id'.
745
+			'           AND sosa.majs_user_id = sosa_fat.majs_user_id'.
746
+			'       WHERE sosa.majs_gedcom_id = :tree_id'.
747
+			'       AND sosa.majs_user_id = :user_id'.
748
+			'       AND sosa_fat.majs_sosa IS NULL'.    // We keep only root individuals, i.e. those with no father or mother
749
+			'       AND sosa_mot.majs_sosa IS NULL'. 
750
+			'       GROUP BY sosa.majs_i_id'.
751
+			'       HAVING COUNT(sosa.majs_sosa) > 1'.   // Limit to the duplicate sosas.
752
+			'       ORDER BY COUNT(sosa.majs_sosa) DESC'.
753
+			'       LIMIT ' . ($limit + 1) . // We want to select one more than required
754
+			'   ) AS top_sosa,'.
755
+			'   (SELECT @prev_count := 0, @keep := 0) x'.
756
+			'   ORDER BY top_sosa.sosa_count ASC'.
757
+			' ) top_sosa_list'.
758
+			' WHERE keep = 1'.
759
+			' ORDER BY sosa_count DESC, sosa_min ASC'
760
+			)->execute(array(
761
+				'tree_id' => $this->tree->getTreeId(),
762
+				'user_id' => $this->user->getUserId()
763
+			))->fetchAssoc() ?: array();
764
+	}
765 765
     
766 766
                
767 767
 }
Please login to merge, or discard this patch.
Spacing   +81 added lines, -81 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 {
@@ -145,7 +145,7 @@  discard block
 block discarded – undo
145 145
      */
146 146
     public function getRootIndi() {
147 147
         $root_indi_id = $this->getRootIndiId();
148
-        if(!empty($root_indi_id)) {
148
+        if (!empty($root_indi_id)) {
149 149
             return Individual::getInstance($root_indi_id, $this->tree);
150 150
         }
151 151
         return null;
@@ -159,7 +159,7 @@  discard block
 block discarded – undo
159 159
      * Remove all Sosa entries related to the gedcom file and user
160 160
      */
161 161
     public function deleteAll() {
162
-        if(!$this->is_setup) return;
162
+        if (!$this->is_setup) return;
163 163
         Database::prepare(
164 164
             'DELETE FROM `##maj_sosa`'.
165 165
             ' WHERE majs_gedcom_id= :tree_id and majs_user_id = :user_id ')
@@ -175,12 +175,12 @@  discard block
 block discarded – undo
175 175
      * @param int $sosa
176 176
      */
177 177
     public function deleteAncestors($sosa) {
178
-        if(!$this->is_setup) return;
178
+        if (!$this->is_setup) return;
179 179
         $gen = Functions::getGeneration($sosa);
180 180
         Database::prepare(
181 181
             'DELETE FROM `##maj_sosa`'.
182
-            ' WHERE majs_gedcom_id=:tree_id and majs_user_id = :user_id' .
183
-            ' AND majs_gen >= :gen' .
182
+            ' WHERE majs_gedcom_id=:tree_id and majs_user_id = :user_id'.
183
+            ' AND majs_gen >= :gen'.
184 184
             ' AND FLOOR(majs_sosa / (POW(2, (majs_gen - :gen)))) = :sosa'
185 185
         )->execute(array(
186 186
             'tree_id' => $this->tree->getTreeId(), 
@@ -195,7 +195,7 @@  discard block
 block discarded – undo
195 195
      * @param array $sosa_records
196 196
      */
197 197
     public function insertOrUpdate($sosa_records) {
198
-        if(!$this->is_setup) return;
198
+        if (!$this->is_setup) return;
199 199
         
200 200
         $treeid = $this->tree->getTreeId();
201 201
         $userid = $this->user->getUserId();
@@ -203,9 +203,9 @@  discard block
 block discarded – undo
203 203
         $values_table = array();
204 204
         
205 205
         $i = 0;
206
-        foreach  ($sosa_records as $row) {
206
+        foreach ($sosa_records as $row) {
207 207
             $gen = Functions::getGeneration($row['sosa']);
208
-            if($gen <= self::MAX_DB_GENERATIONS) {
208
+            if ($gen <= self::MAX_DB_GENERATIONS) {
209 209
                 $questionmarks_table[] = 
210 210
                     '(:tree_id'.$i.', :user_id'.$i.', :sosa'.$i.', :indi_id'.$i.', :gen'.$i.', :byear'.$i.', :byearest'.$i.', :dyear'.$i.', :dyearest'.$i.')';
211 211
                 $values_table = array_merge(
@@ -226,9 +226,9 @@  discard block
 block discarded – undo
226 226
             $i++;
227 227
         }
228 228
         
229
-        $sql = 'REPLACE INTO `##maj_sosa`' .
230
-            ' (majs_gedcom_id, majs_user_id, majs_sosa, majs_i_id, majs_gen, majs_birth_year, majs_birth_year_est, majs_death_year, majs_death_year_est)' .
231
-            ' VALUES '. implode(',', $questionmarks_table);
229
+        $sql = 'REPLACE INTO `##maj_sosa`'.
230
+            ' (majs_gedcom_id, majs_user_id, majs_sosa, majs_i_id, majs_gen, majs_birth_year, majs_birth_year_est, majs_death_year, majs_death_year_est)'.
231
+            ' VALUES '.implode(',', $questionmarks_table);
232 232
         Database::prepare($sql)->execute($values_table);
233 233
     }
234 234
     
@@ -244,7 +244,7 @@  discard block
 block discarded – undo
244 244
      * @return array Array of sosa numbers
245 245
      */
246 246
     public function getSosaNumbers(Individual $indi) {
247
-        if(!$this->is_setup) return array();
247
+        if (!$this->is_setup) return array();
248 248
         return Database::prepare(
249 249
                 'SELECT majs_sosa, majs_gen FROM `##maj_sosa`'.
250 250
                 ' WHERE majs_i_id=:indi_id AND majs_gedcom_id=:tree_id AND majs_user_id=:user_id'
@@ -261,7 +261,7 @@  discard block
 block discarded – undo
261 261
      * @return number Last generation if found, 1 otherwise
262 262
      */
263 263
     public function getLastGeneration() {
264
-        if(!$this->is_setup) return;
264
+        if (!$this->is_setup) return;
265 265
         return Database::prepare(
266 266
                 'SELECT MAX(majs_gen) FROM `##maj_sosa`'.
267 267
                 ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'
@@ -280,13 +280,13 @@  discard block
 block discarded – undo
280 280
      *
281 281
      * @return array Associative array of Sosa ancestors, with their generation, comma separated
282 282
      */
283
-    public function getAllSosaWithGenerations(){
284
-        if(!$this->is_setup) return array();
283
+    public function getAllSosaWithGenerations() {
284
+        if (!$this->is_setup) return array();
285 285
         return Database::prepare(
286
-            'SELECT majs_i_id AS indi,' .
287
-            ' GROUP_CONCAT(DISTINCT majs_gen ORDER BY majs_gen ASC SEPARATOR ",") AS generations' .
288
-            ' FROM `##maj_sosa`' .
289
-            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id' .
286
+            'SELECT majs_i_id AS indi,'.
287
+            ' GROUP_CONCAT(DISTINCT majs_gen ORDER BY majs_gen ASC SEPARATOR ",") AS generations'.
288
+            ' FROM `##maj_sosa`'.
289
+            ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
290 290
             ' GROUP BY majs_i_id'
291 291
         )->execute(array(
292 292
             'tree_id' => $this->tree->getTreeId(),
@@ -300,13 +300,13 @@  discard block
 block discarded – undo
300 300
      * @param number $gen Generation
301 301
      * @return array Array of Sosa individuals
302 302
      */
303
-    public function getSosaListAtGeneration($gen){
304
-        if(!$this->is_setup) return array();
305
-        if(!$this->sosa_list_by_gen)
303
+    public function getSosaListAtGeneration($gen) {
304
+        if (!$this->is_setup) return array();
305
+        if (!$this->sosa_list_by_gen)
306 306
             $this->sosa_list_by_gen = array();
307 307
         
308
-        if($gen){
309
-            if(!isset($this->sosa_list_by_gen[$gen])){
308
+        if ($gen) {
309
+            if (!isset($this->sosa_list_by_gen[$gen])) {
310 310
                 $this->sosa_list_by_gen[$gen] = Database::prepare(
311 311
                     'SELECT majs_sosa AS sosa, majs_i_id AS indi'.
312 312
                     ' FROM `##maj_sosa`'.
@@ -331,13 +331,13 @@  discard block
 block discarded – undo
331 331
      * @param number $gen Generation
332 332
      * @return array Array of Sosa families
333 333
      */
334
-    public function getFamilySosaListAtGeneration($gen){
335
-        if(!$this->is_setup) return array();
336
-        if(!$this->sosa_fam_list_by_gen)
334
+    public function getFamilySosaListAtGeneration($gen) {
335
+        if (!$this->is_setup) return array();
336
+        if (!$this->sosa_fam_list_by_gen)
337 337
             $this->sosa_fam_list_by_gen = array();
338 338
         
339
-        if($gen){
340
-            if(!isset($this->sosa_fam_list_by_gen[$gen])){
339
+        if ($gen) {
340
+            if (!isset($this->sosa_fam_list_by_gen[$gen])) {
341 341
                 $this->sosa_fam_list_by_gen[$gen] = Database::prepare(
342 342
                     'SELECT s1.majs_sosa AS sosa, f_id AS fam'.
343 343
                     ' FROM `##families`'.
@@ -367,9 +367,9 @@  discard block
 block discarded – undo
367 367
      * @param number $gen Generation
368 368
      * @return array Array of Sosa individuals
369 369
      */
370
-    public function getMissingSosaListAtGeneration($gen){
371
-        if(!$this->is_setup) return array();    
372
-        if($gen){
370
+    public function getMissingSosaListAtGeneration($gen) {
371
+        if (!$this->is_setup) return array();    
372
+        if ($gen) {
373 373
             return $this->sosa_list_by_gen[$gen] = Database::prepare(
374 374
                 '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'.
375 375
                 ' FROM `##maj_sosa` schild'.
@@ -408,10 +408,10 @@  discard block
 block discarded – undo
408 408
      * @return array Statistics array
409 409
      */
410 410
     public function getStatisticsByGeneration() {
411
-        if(!$this->is_setup) return array();
412
-        if(!$this->statistics_tab) {
411
+        if (!$this->is_setup) return array();
412
+        if (!$this->statistics_tab) {
413 413
             $this->statistics_tab = array();
414
-            if($maxGeneration = $this->getLastGeneration()) {
414
+            if ($maxGeneration = $this->getLastGeneration()) {
415 415
                 for ($gen = 1; $gen <= $maxGeneration; $gen++) {
416 416
                     $birthStats = $this->getStatsBirthYearInGeneration($gen);
417 417
                     $this->statistics_tab[$gen] = array(
@@ -436,9 +436,9 @@  discard block
 block discarded – undo
436 436
 	 * @return int
437 437
 	 */
438 438
 	public function getTotalIndividuals() {
439
-	    if(!$this->is_setup) return 0;
439
+	    if (!$this->is_setup) return 0;
440 440
 	    return Database::prepare(
441
-	        'SELECT COUNT(*) FROM `##individuals`' .
441
+	        'SELECT COUNT(*) FROM `##individuals`'.
442 442
 	        ' WHERE i_file = :tree_id')
443 443
 	        ->execute(array('tree_id' => $this->tree->getTreeId()))
444 444
 	        ->fetchOne() ?: 0;
@@ -449,10 +449,10 @@  discard block
 block discarded – undo
449 449
      *
450 450
      * @return number Number of Sosas
451 451
      */
452
-    public function getSosaCount(){
453
-        if(!$this->is_setup) return 0;
452
+    public function getSosaCount() {
453
+        if (!$this->is_setup) return 0;
454 454
         return Database::prepare(
455
-            'SELECT COUNT(majs_sosa) FROM `##maj_sosa`' .
455
+            'SELECT COUNT(majs_sosa) FROM `##maj_sosa`'.
456 456
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
457 457
             ->execute(array(
458 458
                 'tree_id' => $this->tree->getTreeId(), 
@@ -466,10 +466,10 @@  discard block
 block discarded – undo
466 466
      * @param number $gen Generation
467 467
      * @return number Number of Sosas in generation
468 468
      */
469
-    public function getSosaCountAtGeneration($gen){
470
-        if(!$this->is_setup) return 0;
469
+    public function getSosaCountAtGeneration($gen) {
470
+        if (!$this->is_setup) return 0;
471 471
         return Database::prepare(
472
-            'SELECT COUNT(majs_sosa) FROM `##maj_sosa`' .
472
+            'SELECT COUNT(majs_sosa) FROM `##maj_sosa`'.
473 473
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
474 474
             ' AND majs_gen= :gen')
475 475
         ->execute(array(
@@ -485,10 +485,10 @@  discard block
 block discarded – undo
485 485
      * @param number $gen Generation
486 486
      * @return number Total number of Sosas up to generation
487 487
      */
488
-    public function getSosaCountUpToGeneration($gen){
489
-        if(!$this->is_setup) return 0;
488
+    public function getSosaCountUpToGeneration($gen) {
489
+        if (!$this->is_setup) return 0;
490 490
         return Database::prepare(
491
-            'SELECT COUNT(majs_sosa) FROM `##maj_sosa`' .
491
+            'SELECT COUNT(majs_sosa) FROM `##maj_sosa`'.
492 492
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
493 493
             ' AND majs_gen <= :gen')
494 494
         ->execute(array(
@@ -503,10 +503,10 @@  discard block
 block discarded – undo
503 503
      *
504 504
      * @return number Total number of distinct individual
505 505
      */
506
-    public function getDifferentSosaCount(){
507
-        if(!$this->is_setup) return 0;
506
+    public function getDifferentSosaCount() {
507
+        if (!$this->is_setup) return 0;
508 508
         return Database::prepare(
509
-            'SELECT COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
509
+            'SELECT COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`'.
510 510
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id')
511 511
         ->execute(array(
512 512
                 'tree_id' => $this->tree->getTreeId(), 
@@ -520,10 +520,10 @@  discard block
 block discarded – undo
520 520
      * @param number $gen Generation
521 521
      * @return number Number of distinct Sosa individuals up to generation
522 522
      */
523
-    public function getDifferentSosaCountUpToGeneration($gen){
524
-        if(!$this->is_setup) return 0;
523
+    public function getDifferentSosaCountUpToGeneration($gen) {
524
+        if (!$this->is_setup) return 0;
525 525
         return Database::prepare(
526
-            'SELECT COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`' .
526
+            'SELECT COUNT(DISTINCT majs_i_id) FROM `##maj_sosa`'.
527 527
             ' WHERE majs_gedcom_id=:tree_id AND majs_user_id=:user_id'.
528 528
             ' AND majs_gen <= :gen')
529 529
         ->execute(array(
@@ -545,8 +545,8 @@  discard block
 block discarded – undo
545 545
      * @param number $gen Generation
546 546
      * @return array Birth statistics array
547 547
      */
548
-    public function getStatsBirthYearInGeneration($gen){
549
-        if(!$this->is_setup) return array('first' => 0, 'first_est' => 0, 'avg' => 0, 'last' => 0, 'last_est' => 0);
548
+    public function getStatsBirthYearInGeneration($gen) {
549
+        if (!$this->is_setup) return array('first' => 0, 'first_est' => 0, 'avg' => 0, 'last' => 0, 'last_est' => 0);
550 550
         return Database::prepare(
551 551
             'SELECT'.
552 552
             ' MIN(majs_birth_year) AS first, MIN(majs_birth_year_est) AS first_est,'.
@@ -567,25 +567,25 @@  discard block
 block discarded – undo
567 567
      *
568 568
      * @return number|NULL Mean generation time
569 569
      */
570
-    public function getMeanGenerationTime(){
571
-        if(!$this->is_setup) return;
572
-        if(!$this->statistics_tab){
570
+    public function getMeanGenerationTime() {
571
+        if (!$this->is_setup) return;
572
+        if (!$this->statistics_tab) {
573 573
             $this->getStatisticsByGeneration();
574 574
         }
575 575
         //Linear regression on x=generation and y=birthdate
576
-        $sum_xy = $sum_x = $sum_y= $sum_x2 = $n = 0;
577
-        foreach($this->statistics_tab as $gen=>$stats){
578
-            if(!is_null($stats['avgBirth'])) {
576
+        $sum_xy = $sum_x = $sum_y = $sum_x2 = $n = 0;
577
+        foreach ($this->statistics_tab as $gen=>$stats) {
578
+            if (!is_null($stats['avgBirth'])) {
579 579
                 $n++;
580
-                $sum_xy+=$gen*$stats['avgBirth'];
581
-                $sum_x+=$gen;
582
-                $sum_y+=$stats['avgBirth'];
583
-                $sum_x2+=$gen*$gen;
580
+                $sum_xy += $gen * $stats['avgBirth'];
581
+                $sum_x += $gen;
582
+                $sum_y += $stats['avgBirth'];
583
+                $sum_x2 += $gen * $gen;
584 584
             }
585 585
         }
586
-        $denom=($n*$sum_x2)-($sum_x*$sum_x);
587
-        if($denom!=0){
588
-            return -(($n*$sum_xy)-($sum_x*$sum_y))/($denom);
586
+        $denom = ($n * $sum_x2) - ($sum_x * $sum_x);
587
+        if ($denom != 0) {
588
+            return -(($n * $sum_xy) - ($sum_x * $sum_y)) / ($denom);
589 589
         }
590 590
         return null;
591 591
     }
@@ -609,7 +609,7 @@  discard block
 block discarded – undo
609 609
      * @return array
610 610
      */
611 611
     public function getGenerationDepthStatsAtGen($gen) {
612
-        if(!$this->is_setup) return array();
612
+        if (!$this->is_setup) return array();
613 613
         $gen_depth_stats_raw = Database::prepare(
614 614
             'SELECT stats_by_gen.root_ancestor AS root_ancestor_sosa,'.
615 615
             '   sosa_list.majs_i_id as root_ancestor_id,'.
@@ -684,14 +684,14 @@  discard block
 block discarded – undo
684 684
      * @return array
685 685
      */
686 686
     public function getAncestorDispersionForGen($gen) {
687
-        if(!$this->is_setup || $gen > 11) return array();  // Going further than 11 gen will be out of range in the query
687
+        if (!$this->is_setup || $gen > 11) return array(); // Going further than 11 gen will be out of range in the query
688 688
         return Database::prepare(
689 689
             'SELECT branches, count(i_id)'.
690 690
             ' FROM ('.
691 691
             '   SELECT i_id,'.
692 692
             '       CASE'.
693 693
             '           WHEN CEIL(LOG2(SUM(branch))) = LOG2(SUM(branch)) THEN SUM(branch)'.
694
-            '           ELSE -1'.   // We put all ancestors shared between some branches in the same bucket
694
+            '           ELSE -1'.// We put all ancestors shared between some branches in the same bucket
695 695
             '       END branches'.
696 696
             '   FROM ('.
697 697
             '       SELECT DISTINCT majs_i_id i_id,'.
@@ -724,7 +724,7 @@  discard block
 block discarded – undo
724 724
      * @return array 
725 725
      */
726 726
     public function getTopMultiSosaAncestorsNoTies($limit) {
727
-        if(!$this->is_setup) return array();
727
+        if (!$this->is_setup) return array();
728 728
         return Database::prepare(
729 729
             'SELECT sosa_i_id, sosa_count FROM ('.
730 730
             '   SELECT'.
@@ -737,20 +737,20 @@  discard block
 block discarded – undo
737 737
             '           COUNT(sosa.majs_sosa) sosa_count,'.
738 738
             '           MIN(sosa.majs_sosa) sosa_min'.
739 739
             '       FROM ##maj_sosa AS sosa'.
740
-            '       LEFT JOIN ##maj_sosa AS sosa_fat ON sosa_fat.majs_sosa = 2 * sosa.majs_sosa'.   // Link to sosa's father
740
+            '       LEFT JOIN ##maj_sosa AS sosa_fat ON sosa_fat.majs_sosa = 2 * sosa.majs_sosa'.// Link to sosa's father
741 741
             '           AND sosa.majs_gedcom_id = sosa_fat.majs_gedcom_id'.
742 742
             '           AND sosa.majs_user_id = sosa_fat.majs_user_id'.
743
-            '       LEFT JOIN ##maj_sosa AS sosa_mot on sosa_mot.majs_sosa = (2 * sosa.majs_sosa + 1)'.  // Link to sosa's mother
743
+            '       LEFT JOIN ##maj_sosa AS sosa_mot on sosa_mot.majs_sosa = (2 * sosa.majs_sosa + 1)'.// Link to sosa's mother
744 744
             '           AND sosa.majs_gedcom_id = sosa_fat.majs_gedcom_id'.
745 745
             '           AND sosa.majs_user_id = sosa_fat.majs_user_id'.
746 746
             '       WHERE sosa.majs_gedcom_id = :tree_id'.
747 747
             '       AND sosa.majs_user_id = :user_id'.
748
-            '       AND sosa_fat.majs_sosa IS NULL'.    // We keep only root individuals, i.e. those with no father or mother
748
+            '       AND sosa_fat.majs_sosa IS NULL'.// We keep only root individuals, i.e. those with no father or mother
749 749
             '       AND sosa_mot.majs_sosa IS NULL'. 
750 750
             '       GROUP BY sosa.majs_i_id'.
751
-            '       HAVING COUNT(sosa.majs_sosa) > 1'.   // Limit to the duplicate sosas.
751
+            '       HAVING COUNT(sosa.majs_sosa) > 1'.// Limit to the duplicate sosas.
752 752
             '       ORDER BY COUNT(sosa.majs_sosa) DESC'.
753
-            '       LIMIT ' . ($limit + 1) . // We want to select one more than required
753
+            '       LIMIT '.($limit + 1).// We want to select one more than required
754 754
             '   ) AS top_sosa,'.
755 755
             '   (SELECT @prev_count := 0, @keep := 0) x'.
756 756
             '   ORDER BY top_sosa.sosa_count ASC'.
Please login to merge, or discard this patch.
src/Webtrees/Module/GeoDispersion/Model/GeoAnalysisProvider.php 3 patches
Indentation   +329 added lines, -329 removed lines patch added patch discarded remove patch
@@ -21,130 +21,130 @@  discard block
 block discarded – undo
21 21
  */
22 22
 class GeoAnalysisProvider {
23 23
     
24
-    /**
25
-     * Reference tree
26
-     * @var Tree $tree
27
-     */
28
-    protected $tree;
24
+	/**
25
+	 * Reference tree
26
+	 * @var Tree $tree
27
+	 */
28
+	protected $tree;
29 29
     
30
-    /**
31
-     * Cached hierarchy of places in the Gedcom file.
32
-     * 
33
-     * @var (array|null) $place_hierarchy
34
-     */
35
-    protected $place_hierarchy;
30
+	/**
31
+	 * Cached hierarchy of places in the Gedcom file.
32
+	 * 
33
+	 * @var (array|null) $place_hierarchy
34
+	 */
35
+	protected $place_hierarchy;
36 36
     
37
-    /**
38
-     * Constructor for GeoAnalysis Provider.
39
-     * A provider is defined in relation to a specific tree.
40
-     *
41
-     * @param Tree $tree
42
-     */
43
-    public function __construct(Tree $tree) {
44
-        $this->tree = $tree;
45
-        $this->place_hierarchy = null;
46
-    }
37
+	/**
38
+	 * Constructor for GeoAnalysis Provider.
39
+	 * A provider is defined in relation to a specific tree.
40
+	 *
41
+	 * @param Tree $tree
42
+	 */
43
+	public function __construct(Tree $tree) {
44
+		$this->tree = $tree;
45
+		$this->place_hierarchy = null;
46
+	}
47 47
     
48
-    /**
49
-     * Creates and returns a GeoAnalysis object from a data row.
50
-     * The row data is expected to be an array with the indexes:
51
-     *  - majgd_id: geodispersion analysis ID
52
-     *  - majgd_descr: geodispersion analysis description/title
53
-     *  - majgd_sublevel: Analysis level
54
-     *  - majgd_useflagsgen: Use flags in places display
55
-     *  - majgd_detailsgen: Number of top places
56
-     *  - majgd_map: file name of the map
57
-     *  - majgd_toplevel: parent level for the map
58
-     * 
59
-     * @param array $row
60
-     * @return GeoAnalysis
61
-     */
62
-    protected function loadGeoAnalysisFromRow($row) {
63
-        $options = new GeoDisplayOptions();
64
-        $options
65
-        ->setUsingFlags($row['majgd_useflagsgen'] == 'yes')
66
-        ->setMaxDetailsInGen($row['majgd_detailsgen']);
48
+	/**
49
+	 * Creates and returns a GeoAnalysis object from a data row.
50
+	 * The row data is expected to be an array with the indexes:
51
+	 *  - majgd_id: geodispersion analysis ID
52
+	 *  - majgd_descr: geodispersion analysis description/title
53
+	 *  - majgd_sublevel: Analysis level
54
+	 *  - majgd_useflagsgen: Use flags in places display
55
+	 *  - majgd_detailsgen: Number of top places
56
+	 *  - majgd_map: file name of the map
57
+	 *  - majgd_toplevel: parent level for the map
58
+	 * 
59
+	 * @param array $row
60
+	 * @return GeoAnalysis
61
+	 */
62
+	protected function loadGeoAnalysisFromRow($row) {
63
+		$options = new GeoDisplayOptions();
64
+		$options
65
+		->setUsingFlags($row['majgd_useflagsgen'] == 'yes')
66
+		->setMaxDetailsInGen($row['majgd_detailsgen']);
67 67
         
68
-        if($row['majgd_map']) {
69
-            $options
70
-            ->setMap(new OutlineMap($row['majgd_map']))
71
-            ->setMapLevel($row['majgd_toplevel']);
72
-        }
68
+		if($row['majgd_map']) {
69
+			$options
70
+			->setMap(new OutlineMap($row['majgd_map']))
71
+			->setMapLevel($row['majgd_toplevel']);
72
+		}
73 73
         
74
-        $enabled = true;
75
-        if(isset($row['majgd_status']) && $row['majgd_status'] == 'disabled') {
76
-            $enabled = false;
77
-        }
74
+		$enabled = true;
75
+		if(isset($row['majgd_status']) && $row['majgd_status'] == 'disabled') {
76
+			$enabled = false;
77
+		}
78 78
         
79
-        return new GeoAnalysis(
80
-            $this->tree,
81
-            $row['majgd_id'],
82
-            $row['majgd_descr'],
83
-            $row['majgd_sublevel'],
84
-            $options,
85
-            $enabled
86
-            );
87
-    }
79
+		return new GeoAnalysis(
80
+			$this->tree,
81
+			$row['majgd_id'],
82
+			$row['majgd_descr'],
83
+			$row['majgd_sublevel'],
84
+			$options,
85
+			$enabled
86
+			);
87
+	}
88 88
     
89
-    /**
90
-     * Returns the number of geographical analysis (active and inactive). 
91
-     * 
92
-     * @return int
93
-     */
94
-    public function getGeoAnalysisCount() {
95
-        return Database::prepare(
96
-            'SELECT COUNT(majgd_id)' .
97
-            ' FROM `##maj_geodispersion`' .
98
-            ' WHERE majgd_file = :gedcom_id'
99
-            )->execute(array(
100
-                'gedcom_id' => $this->tree->getTreeId()
101
-            ))->fetchOne();
102
-    }
89
+	/**
90
+	 * Returns the number of geographical analysis (active and inactive). 
91
+	 * 
92
+	 * @return int
93
+	 */
94
+	public function getGeoAnalysisCount() {
95
+		return Database::prepare(
96
+			'SELECT COUNT(majgd_id)' .
97
+			' FROM `##maj_geodispersion`' .
98
+			' WHERE majgd_file = :gedcom_id'
99
+			)->execute(array(
100
+				'gedcom_id' => $this->tree->getTreeId()
101
+			))->fetchOne();
102
+	}
103 103
     
104
-    /**
105
-     * Get a geographical analysis by its ID.
106
-     * The function can only search for only enabled analysis, or all.
107
-     * 
108
-     * @param int $id geodispersion analysis ID
109
-     * @param bool $only_enabled Search for only enabled geodispersion analysis
110
-     * @return \MyArtJaub\Webtrees\Module\GeoDispersion\Model\GeoAnalysis|NULL
111
-     */
112
-    public function getGeoAnalysis($id, $only_enabled = true) {
113
-        $args = array (
114
-            'gedcom_id' => $this->tree->getTreeId(),
115
-            'ga_id' => $id
116
-        );
104
+	/**
105
+	 * Get a geographical analysis by its ID.
106
+	 * The function can only search for only enabled analysis, or all.
107
+	 * 
108
+	 * @param int $id geodispersion analysis ID
109
+	 * @param bool $only_enabled Search for only enabled geodispersion analysis
110
+	 * @return \MyArtJaub\Webtrees\Module\GeoDispersion\Model\GeoAnalysis|NULL
111
+	 */
112
+	public function getGeoAnalysis($id, $only_enabled = true) {
113
+		$args = array (
114
+			'gedcom_id' => $this->tree->getTreeId(),
115
+			'ga_id' => $id
116
+		);
117 117
         
118
-        $sql = 'SELECT majgd_id, majgd_descr, majgd_sublevel, majgd_map, majgd_toplevel, majgd_useflagsgen, majgd_detailsgen, majgd_status' .
119
-            ' FROM `##maj_geodispersion`' .
120
-            ' WHERE majgd_file = :gedcom_id AND majgd_id=:ga_id';
121
-        if($only_enabled) {
122
-            $sql .= ' AND majgd_status = :status';
123
-            $args['status'] = 'enabled';
124
-        }
125
-        $sql .= ' ORDER BY majgd_descr';
118
+		$sql = 'SELECT majgd_id, majgd_descr, majgd_sublevel, majgd_map, majgd_toplevel, majgd_useflagsgen, majgd_detailsgen, majgd_status' .
119
+			' FROM `##maj_geodispersion`' .
120
+			' WHERE majgd_file = :gedcom_id AND majgd_id=:ga_id';
121
+		if($only_enabled) {
122
+			$sql .= ' AND majgd_status = :status';
123
+			$args['status'] = 'enabled';
124
+		}
125
+		$sql .= ' ORDER BY majgd_descr';
126 126
         
127
-        $ga_array = Database::prepare($sql)->execute($args)->fetchOneRow(\PDO::FETCH_ASSOC);
127
+		$ga_array = Database::prepare($sql)->execute($args)->fetchOneRow(\PDO::FETCH_ASSOC);
128 128
         
129
-        if($ga_array) {
130
-            return $this->loadGeoAnalysisFromRow($ga_array);
131
-        }
129
+		if($ga_array) {
130
+			return $this->loadGeoAnalysisFromRow($ga_array);
131
+		}
132 132
         
133
-        return null;            
134
-    }
133
+		return null;            
134
+	}
135 135
     
136
-    /**
137
-     * Add a new geodispersion analysis in the database, in a transactional manner.
138
-     * When successful, eturns the newly created GeoAnalysis object.
139
-     * 
140
-     * @param string $description geodispersion analysis title
141
-     * @param int $analysis_level Analysis level
142
-     * @param string $map_file Filename of the map
143
-     * @param int $map_top_level Parent level of the map
144
-     * @param bool $use_flags Use flag in the place display
145
-     * @param int $gen_details Number of top places to display
146
-     * @return GeoAnalysis
147
-     */
136
+	/**
137
+	 * Add a new geodispersion analysis in the database, in a transactional manner.
138
+	 * When successful, eturns the newly created GeoAnalysis object.
139
+	 * 
140
+	 * @param string $description geodispersion analysis title
141
+	 * @param int $analysis_level Analysis level
142
+	 * @param string $map_file Filename of the map
143
+	 * @param int $map_top_level Parent level of the map
144
+	 * @param bool $use_flags Use flag in the place display
145
+	 * @param int $gen_details Number of top places to display
146
+	 * @return GeoAnalysis
147
+	 */
148 148
 	public function createGeoAnalysis($description, $analysis_level, $map_file, $map_top_level, $use_flags, $gen_details) {
149 149
 		try{
150 150
 			Database::beginTransaction();
@@ -174,17 +174,17 @@  discard block
 block discarded – undo
174 174
 			Log::addErrorLog('A new Geo Analysis failed to be created. Transaction rollbacked. Parameters ['.$description.', '.$analysis_level.','.$map_file.','.$map_top_level.','.$use_flags.', '.$gen_details.']. Exception: '.$ex->getMessage());
175 175
 		}
176 176
 		return $ga;
177
-    }
177
+	}
178 178
 	
179
-    /**
180
-     * Update a geodispersion analysis in the database, in transactional manner.
181
-     * When successful, returns the updated GeoAnalysis object
182
-     *  
183
-     * @param GeoAnalysis $ga
184
-     * @return GeoAnalysis
185
-     */
186
-    public function updateGeoAnalysis(GeoAnalysis $ga) {
187
-        try {
179
+	/**
180
+	 * Update a geodispersion analysis in the database, in transactional manner.
181
+	 * When successful, returns the updated GeoAnalysis object
182
+	 *  
183
+	 * @param GeoAnalysis $ga
184
+	 * @return GeoAnalysis
185
+	 */
186
+	public function updateGeoAnalysis(GeoAnalysis $ga) {
187
+		try {
188 188
 			Database::beginTransaction();
189 189
 		
190 190
 			Database::prepare(
@@ -217,239 +217,239 @@  discard block
 block discarded – undo
217 217
 			$ga = null;
218 218
 		}
219 219
 		return $ga;
220
-    }
220
+	}
221 221
     
222
-    /**
223
-     * Set the status of a specific analysis.
224
-     * The status can be enabled (true), or disabled (false).
225
-     * 
226
-     * @param GeoAnalysis $ga
227
-     * @param bool $status
228
-     */
229
-    public function setGeoAnalysisStatus(GeoAnalysis $ga, $status) {
230
-        Database::prepare(
231
-            'UPDATE `##maj_geodispersion`'.
232
-            ' SET majgd_status = :status'.
233
-            ' WHERE majgd_file = :gedcom_id AND majgd_id=:ga_id'
234
-        )->execute(array(
235
-                'gedcom_id' => $this->tree->getTreeId(),
236
-                'status' => $status ? 'enabled' : 'disabled',
237
-                'ga_id' => $ga->getId()
238
-        ));
239
-    }
222
+	/**
223
+	 * Set the status of a specific analysis.
224
+	 * The status can be enabled (true), or disabled (false).
225
+	 * 
226
+	 * @param GeoAnalysis $ga
227
+	 * @param bool $status
228
+	 */
229
+	public function setGeoAnalysisStatus(GeoAnalysis $ga, $status) {
230
+		Database::prepare(
231
+			'UPDATE `##maj_geodispersion`'.
232
+			' SET majgd_status = :status'.
233
+			' WHERE majgd_file = :gedcom_id AND majgd_id=:ga_id'
234
+		)->execute(array(
235
+				'gedcom_id' => $this->tree->getTreeId(),
236
+				'status' => $status ? 'enabled' : 'disabled',
237
+				'ga_id' => $ga->getId()
238
+		));
239
+	}
240 240
     
241
-    /**
242
-     * Delete a geodispersion analysis from the database.
243
-     * 
244
-     * @param GeoAnalysis $ga
245
-     */
246
-    public function deleteGeoAnalysis(GeoAnalysis $ga) {
247
-        Database::prepare(
248
-            'DELETE FROM `##maj_geodispersion`'.
249
-            ' WHERE majgd_file = :gedcom_id AND majgd_id=:ga_id'
250
-            )->execute(array(
251
-                'gedcom_id' => $this->tree->getTreeId(),
252
-                'ga_id' => $ga->getId()
253
-            ));
254
-    }
241
+	/**
242
+	 * Delete a geodispersion analysis from the database.
243
+	 * 
244
+	 * @param GeoAnalysis $ga
245
+	 */
246
+	public function deleteGeoAnalysis(GeoAnalysis $ga) {
247
+		Database::prepare(
248
+			'DELETE FROM `##maj_geodispersion`'.
249
+			' WHERE majgd_file = :gedcom_id AND majgd_id=:ga_id'
250
+			)->execute(array(
251
+				'gedcom_id' => $this->tree->getTreeId(),
252
+				'ga_id' => $ga->getId()
253
+			));
254
+	}
255 255
         
256
-    /**
257
-     * Return the list of geodispersion analysis recorded and enabled for a specific GEDCOM
258
-     *
259
-     * @return array List of enabled maps
260
-     */
261
-    public function getGeoAnalysisList(){
262
-        $res = array();
256
+	/**
257
+	 * Return the list of geodispersion analysis recorded and enabled for a specific GEDCOM
258
+	 *
259
+	 * @return array List of enabled maps
260
+	 */
261
+	public function getGeoAnalysisList(){
262
+		$res = array();
263 263
         
264
-        $list = Database::prepare(
265
-            'SELECT majgd_id, majgd_descr, majgd_sublevel, majgd_map, majgd_toplevel, majgd_useflagsgen, majgd_detailsgen' .
266
-            ' FROM `##maj_geodispersion`' .
267
-            ' WHERE majgd_file = :gedcom_id AND majgd_status = :status'.
268
-            ' ORDER BY majgd_descr'
269
-        )->execute(array(
270
-            'gedcom_id' => $this->tree->getTreeId(),
271
-            'status' => 'enabled'
272
-        ))->fetchAll(\PDO::FETCH_ASSOC);
264
+		$list = Database::prepare(
265
+			'SELECT majgd_id, majgd_descr, majgd_sublevel, majgd_map, majgd_toplevel, majgd_useflagsgen, majgd_detailsgen' .
266
+			' FROM `##maj_geodispersion`' .
267
+			' WHERE majgd_file = :gedcom_id AND majgd_status = :status'.
268
+			' ORDER BY majgd_descr'
269
+		)->execute(array(
270
+			'gedcom_id' => $this->tree->getTreeId(),
271
+			'status' => 'enabled'
272
+		))->fetchAll(\PDO::FETCH_ASSOC);
273 273
         
274
-        foreach($list as $ga) {
275
-           $res[] = $this->loadGeoAnalysisFromRow($ga);
276
-        }
274
+		foreach($list as $ga) {
275
+		   $res[] = $this->loadGeoAnalysisFromRow($ga);
276
+		}
277 277
         
278
-        return $res;
279
-    }
278
+		return $res;
279
+	}
280 280
     
281
-    /**
282
-     * Return the list of geodispersion analysis matching specified criterias.
283
-     * 
284
-     * @param string $search Search criteria in analysis description
285
-     * @param array $order_by Columns to order by
286
-     * @param int $start Offset to start with (for pagination)
287
-     * @param int|null $limit Max number of items to return (for pagination)
288
-     * @return \MyArtJaub\Webtrees\Module\GeoDispersion\Model\GeoAnalysis[]
289
-     */
290
-    public function getFilteredGeoAnalysisList($search = null, $order_by = null, $start = 0, $limit = null){
291
-        $res = array();
281
+	/**
282
+	 * Return the list of geodispersion analysis matching specified criterias.
283
+	 * 
284
+	 * @param string $search Search criteria in analysis description
285
+	 * @param array $order_by Columns to order by
286
+	 * @param int $start Offset to start with (for pagination)
287
+	 * @param int|null $limit Max number of items to return (for pagination)
288
+	 * @return \MyArtJaub\Webtrees\Module\GeoDispersion\Model\GeoAnalysis[]
289
+	 */
290
+	public function getFilteredGeoAnalysisList($search = null, $order_by = null, $start = 0, $limit = null){
291
+		$res = array();
292 292
             
293
-        $sql = 
294
-            'SELECT majgd_id, majgd_descr, majgd_sublevel, majgd_map, majgd_toplevel, majgd_useflagsgen, majgd_detailsgen, majgd_status' .
295
-            ' FROM `##maj_geodispersion`' .
296
-            ' WHERE majgd_file = :gedcom_id';
293
+		$sql = 
294
+			'SELECT majgd_id, majgd_descr, majgd_sublevel, majgd_map, majgd_toplevel, majgd_useflagsgen, majgd_detailsgen, majgd_status' .
295
+			' FROM `##maj_geodispersion`' .
296
+			' WHERE majgd_file = :gedcom_id';
297 297
         
298
-        $args = array('gedcom_id'=> $this->tree->getTreeId());
298
+		$args = array('gedcom_id'=> $this->tree->getTreeId());
299 299
         
300
-        if($search) {
301
-            $sql .= ' AND majgd_descr LIKE CONCAT(\'%\', :search, \'%\')';
302
-            $args['search'] = $search;
303
-        }
300
+		if($search) {
301
+			$sql .= ' AND majgd_descr LIKE CONCAT(\'%\', :search, \'%\')';
302
+			$args['search'] = $search;
303
+		}
304 304
         
305
-        if ($order_by) {
306
-            $sql .= ' ORDER BY ';
307
-            foreach ($order_by as $key => $value) {
308
-                if ($key > 0) {
309
-                    $sql .= ',';
310
-                }
305
+		if ($order_by) {
306
+			$sql .= ' ORDER BY ';
307
+			foreach ($order_by as $key => $value) {
308
+				if ($key > 0) {
309
+					$sql .= ',';
310
+				}
311 311
                 
312
-                switch ($value['dir']) {
313
-                    case 'asc':
314
-                        $sql .= $value['column'] . ' ASC ';
315
-                        break;
316
-                    case 'desc':
317
-                        $sql .= $value['column'] . ' DESC ';
318
-                        break;
319
-                }
320
-            }
321
-        } else {
322
-            $sql .= ' ORDER BY majgd_descr ASC';
323
-        }
312
+				switch ($value['dir']) {
313
+					case 'asc':
314
+						$sql .= $value['column'] . ' ASC ';
315
+						break;
316
+					case 'desc':
317
+						$sql .= $value['column'] . ' DESC ';
318
+						break;
319
+				}
320
+			}
321
+		} else {
322
+			$sql .= ' ORDER BY majgd_descr ASC';
323
+		}
324 324
         
325
-        if ($limit) {
326
-            $sql .= " LIMIT :limit OFFSET :offset";
327
-            $args['limit']  = $limit;
328
-            $args['offset'] = $start;
329
-        }
325
+		if ($limit) {
326
+			$sql .= " LIMIT :limit OFFSET :offset";
327
+			$args['limit']  = $limit;
328
+			$args['offset'] = $start;
329
+		}
330 330
             
331
-        $data = Database::prepare($sql)->execute($args)->fetchAll(\PDO::FETCH_ASSOC);
331
+		$data = Database::prepare($sql)->execute($args)->fetchAll(\PDO::FETCH_ASSOC);
332 332
 
333
-        foreach($data as $ga) {
334
-            $res[] = $this->loadGeoAnalysisFromRow($ga);
335
-        }
333
+		foreach($data as $ga) {
334
+			$res[] = $this->loadGeoAnalysisFromRow($ga);
335
+		}
336 336
         
337
-        return $res;
338
-    }
337
+		return $res;
338
+	}
339 339
             
340
-    /**
341
-     * Returns the infered place hierarchy, determined from the Gedcom data.
342
-     * Depending on the data, it can be based on the Gedcom Header description, or from a place example.
343
-     * This is returned as an associative array:
344
-     *      - type:    describe the source of the data (<em>header<em> / <em>data</em> / <em>none</em>)
345
-     *      - hierarchy: an array of the place hierarchy (in reverse order of the gedcom)
346
-     *      
347
-     * @return array
348
-     */
349
-    public function getPlacesHierarchy() {
350
-        if(!$this->place_hierarchy) {
351
-            if($place_structure = $this->getPlacesHierarchyFromHeader()) {
352
-                $this->place_hierarchy = array('type' => 'header', 'hierarchy' => $place_structure);
353
-            }
354
-            elseif ($place_structure = $this->getPlacesHierarchyFromData()){
355
-                $this->place_hierarchy = array('type' => 'data', 'hierarchy' => $place_structure);
356
-            }
357
-            else {
358
-                $this->place_hierarchy = array('type' => 'none', 'hierarchy' => null);
359
-            }
360
-        }
361
-        return $this->place_hierarchy;        
362
-    }
340
+	/**
341
+	 * Returns the infered place hierarchy, determined from the Gedcom data.
342
+	 * Depending on the data, it can be based on the Gedcom Header description, or from a place example.
343
+	 * This is returned as an associative array:
344
+	 *      - type:    describe the source of the data (<em>header<em> / <em>data</em> / <em>none</em>)
345
+	 *      - hierarchy: an array of the place hierarchy (in reverse order of the gedcom)
346
+	 *      
347
+	 * @return array
348
+	 */
349
+	public function getPlacesHierarchy() {
350
+		if(!$this->place_hierarchy) {
351
+			if($place_structure = $this->getPlacesHierarchyFromHeader()) {
352
+				$this->place_hierarchy = array('type' => 'header', 'hierarchy' => $place_structure);
353
+			}
354
+			elseif ($place_structure = $this->getPlacesHierarchyFromData()){
355
+				$this->place_hierarchy = array('type' => 'data', 'hierarchy' => $place_structure);
356
+			}
357
+			else {
358
+				$this->place_hierarchy = array('type' => 'none', 'hierarchy' => null);
359
+			}
360
+		}
361
+		return $this->place_hierarchy;        
362
+	}
363 363
     
364
-    /**
365
-     * Returns an array of the place hierarchy, as defined in the GEDCOM header.
366
-     * The places are reversed compared to normal GEDCOM structure.
367
-     * 
368
-     * @return array|null
369
-     */
370
-    protected function getPlacesHierarchyFromHeader() {
371
-        $head = GedcomRecord::getInstance('HEAD', $this->tree);
372
-        $head_place = $head->getFirstFact('PLAC');
373
-        if($head_place && $head_place_value = $head_place->getAttribute('FORM')){
374
-            return array_reverse(array_map('trim',explode(',', $head_place_value)));
375
-        }
376
-        return null;
377
-    }
364
+	/**
365
+	 * Returns an array of the place hierarchy, as defined in the GEDCOM header.
366
+	 * The places are reversed compared to normal GEDCOM structure.
367
+	 * 
368
+	 * @return array|null
369
+	 */
370
+	protected function getPlacesHierarchyFromHeader() {
371
+		$head = GedcomRecord::getInstance('HEAD', $this->tree);
372
+		$head_place = $head->getFirstFact('PLAC');
373
+		if($head_place && $head_place_value = $head_place->getAttribute('FORM')){
374
+			return array_reverse(array_map('trim',explode(',', $head_place_value)));
375
+		}
376
+		return null;
377
+	}
378 378
     
379
-    /**
380
-     * Returns an array of the place hierarchy, based on a random example of place within the GEDCOM.
381
-     * It will look for the longest hierarchy in the tree.
382
-     * The places are reversed compared to normal GEDCOM structure.
383
-     * 
384
-     * @return array
385
-     */
386
-    protected function getPlacesHierarchyFromData() {
387
-        $nb_levels = 0;
379
+	/**
380
+	 * Returns an array of the place hierarchy, based on a random example of place within the GEDCOM.
381
+	 * It will look for the longest hierarchy in the tree.
382
+	 * The places are reversed compared to normal GEDCOM structure.
383
+	 * 
384
+	 * @return array
385
+	 */
386
+	protected function getPlacesHierarchyFromData() {
387
+		$nb_levels = 0;
388 388
         
389
-        //Select all '2 PLAC ' tags in the file and create array
390
-        $places_list=array();
391
-        $ged_data = Database::prepare(
392
-            'SELECT i_gedcom AS gedcom'.
393
-            ' FROM `##individuals`'.
394
-            ' WHERE i_gedcom LIKE :gedcom AND i_file = :gedcom_id'.
395
-            ' UNION ALL'.
396
-            ' SELECT f_gedcom AS gedcom'.
397
-            ' FROM `##families`'.
398
-            ' WHERE f_gedcom LIKE :gedcom AND f_file = :gedcom_id'
399
-        )->execute(array(
400
-            'gedcom' => '%2 PLAC %',
401
-            'gedcom_id' => $this->tree->getTreeId()
402
-        ))->fetchOneColumn();
403
-        foreach ($ged_data as $ged_datum) {
404
-            $matches = null;
405
-            preg_match_all('/\n2 PLAC (.+)/', $ged_datum, $matches);
406
-            foreach ($matches[1] as $match) {
407
-                $places_list[$match]=true;
408
-            }
409
-        }
389
+		//Select all '2 PLAC ' tags in the file and create array
390
+		$places_list=array();
391
+		$ged_data = Database::prepare(
392
+			'SELECT i_gedcom AS gedcom'.
393
+			' FROM `##individuals`'.
394
+			' WHERE i_gedcom LIKE :gedcom AND i_file = :gedcom_id'.
395
+			' UNION ALL'.
396
+			' SELECT f_gedcom AS gedcom'.
397
+			' FROM `##families`'.
398
+			' WHERE f_gedcom LIKE :gedcom AND f_file = :gedcom_id'
399
+		)->execute(array(
400
+			'gedcom' => '%2 PLAC %',
401
+			'gedcom_id' => $this->tree->getTreeId()
402
+		))->fetchOneColumn();
403
+		foreach ($ged_data as $ged_datum) {
404
+			$matches = null;
405
+			preg_match_all('/\n2 PLAC (.+)/', $ged_datum, $matches);
406
+			foreach ($matches[1] as $match) {
407
+				$places_list[$match]=true;
408
+			}
409
+		}
410 410
         
411
-        // Get the places with higest numbers of levels
412
-        $places_with_high_level = array();
413
-        $max_level = 0;
411
+		// Get the places with higest numbers of levels
412
+		$places_with_high_level = array();
413
+		$max_level = 0;
414 414
         
415
-        foreach ($places_list as $place => $value) {
416
-            $levels = array_filter(array_map('trim', explode(",", $place)));
417
-            $parts = count($levels);
418
-            if($parts > $max_level) {
419
-                $max_level = $parts;
420
-                $places_with_high_level = array($place);
421
-            }
422
-            else if ($parts == $max_level) {
423
-                $places_with_high_level[] = $place;
424
-            }
425
-        }
415
+		foreach ($places_list as $place => $value) {
416
+			$levels = array_filter(array_map('trim', explode(",", $place)));
417
+			$parts = count($levels);
418
+			if($parts > $max_level) {
419
+				$max_level = $parts;
420
+				$places_with_high_level = array($place);
421
+			}
422
+			else if ($parts == $max_level) {
423
+				$places_with_high_level[] = $place;
424
+			}
425
+		}
426 426
         
427
-        // If empty array, then return null
428
-        if($max_level == 0) return null;
427
+		// If empty array, then return null
428
+		if($max_level == 0) return null;
429 429
                 
430
-        // Else, return the first alphabetical element -- cannot return random to ensure always the same example if used
431
-        usort($places_with_high_level, array('Fisharebest\\Webtrees\\I18N', 'strcasecmp'));        
432
-        return array_reverse(array_map('trim',explode(',', $places_with_high_level[0])));
430
+		// Else, return the first alphabetical element -- cannot return random to ensure always the same example if used
431
+		usort($places_with_high_level, array('Fisharebest\\Webtrees\\I18N', 'strcasecmp'));        
432
+		return array_reverse(array_map('trim',explode(',', $places_with_high_level[0])));
433 433
         
434
-    }
434
+	}
435 435
     
436
-    /**
437
-     * Returns the list of geodispersion maps available within the maps folder.
438
-     * 
439
-     * @return \MyArtJaub\Webtrees\Module\GeoDispersion\Model\OutlineMap[]
440
-     */
441
-    public function getOutlineMapsList() {
442
-        $res = array();
443
-        $root_path = WT_ROOT.WT_MODULES_DIR.Constants::MODULE_MAJ_GEODISP_NAME.'/maps/';
444
-        if(is_dir($root_path)){
445
-            $dir = opendir($root_path);
446
-            while (($file=readdir($dir))!== false) {
447
-                if (preg_match('/^[a-zA-Z0-9_]+.xml$/', $file)) {
448
-                    $res[base64_encode($file)] = new OutlineMap($file, true);
449
-                }
450
-            }
451
-        }
452
-        return $res;
453
-    }
436
+	/**
437
+	 * Returns the list of geodispersion maps available within the maps folder.
438
+	 * 
439
+	 * @return \MyArtJaub\Webtrees\Module\GeoDispersion\Model\OutlineMap[]
440
+	 */
441
+	public function getOutlineMapsList() {
442
+		$res = array();
443
+		$root_path = WT_ROOT.WT_MODULES_DIR.Constants::MODULE_MAJ_GEODISP_NAME.'/maps/';
444
+		if(is_dir($root_path)){
445
+			$dir = opendir($root_path);
446
+			while (($file=readdir($dir))!== false) {
447
+				if (preg_match('/^[a-zA-Z0-9_]+.xml$/', $file)) {
448
+					$res[base64_encode($file)] = new OutlineMap($file, true);
449
+				}
450
+			}
451
+		}
452
+		return $res;
453
+	}
454 454
 }
455 455
  
456 456
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +36 added lines, -36 removed lines patch added patch discarded remove patch
@@ -65,14 +65,14 @@  discard block
 block discarded – undo
65 65
         ->setUsingFlags($row['majgd_useflagsgen'] == 'yes')
66 66
         ->setMaxDetailsInGen($row['majgd_detailsgen']);
67 67
         
68
-        if($row['majgd_map']) {
68
+        if ($row['majgd_map']) {
69 69
             $options
70 70
             ->setMap(new OutlineMap($row['majgd_map']))
71 71
             ->setMapLevel($row['majgd_toplevel']);
72 72
         }
73 73
         
74 74
         $enabled = true;
75
-        if(isset($row['majgd_status']) && $row['majgd_status'] == 'disabled') {
75
+        if (isset($row['majgd_status']) && $row['majgd_status'] == 'disabled') {
76 76
             $enabled = false;
77 77
         }
78 78
         
@@ -93,8 +93,8 @@  discard block
 block discarded – undo
93 93
      */
94 94
     public function getGeoAnalysisCount() {
95 95
         return Database::prepare(
96
-            'SELECT COUNT(majgd_id)' .
97
-            ' FROM `##maj_geodispersion`' .
96
+            'SELECT COUNT(majgd_id)'.
97
+            ' FROM `##maj_geodispersion`'.
98 98
             ' WHERE majgd_file = :gedcom_id'
99 99
             )->execute(array(
100 100
                 'gedcom_id' => $this->tree->getTreeId()
@@ -110,15 +110,15 @@  discard block
 block discarded – undo
110 110
      * @return \MyArtJaub\Webtrees\Module\GeoDispersion\Model\GeoAnalysis|NULL
111 111
      */
112 112
     public function getGeoAnalysis($id, $only_enabled = true) {
113
-        $args = array (
113
+        $args = array(
114 114
             'gedcom_id' => $this->tree->getTreeId(),
115 115
             'ga_id' => $id
116 116
         );
117 117
         
118
-        $sql = 'SELECT majgd_id, majgd_descr, majgd_sublevel, majgd_map, majgd_toplevel, majgd_useflagsgen, majgd_detailsgen, majgd_status' .
119
-            ' FROM `##maj_geodispersion`' .
118
+        $sql = 'SELECT majgd_id, majgd_descr, majgd_sublevel, majgd_map, majgd_toplevel, majgd_useflagsgen, majgd_detailsgen, majgd_status'.
119
+            ' FROM `##maj_geodispersion`'.
120 120
             ' WHERE majgd_file = :gedcom_id AND majgd_id=:ga_id';
121
-        if($only_enabled) {
121
+        if ($only_enabled) {
122 122
             $sql .= ' AND majgd_status = :status';
123 123
             $args['status'] = 'enabled';
124 124
         }
@@ -126,7 +126,7 @@  discard block
 block discarded – undo
126 126
         
127 127
         $ga_array = Database::prepare($sql)->execute($args)->fetchOneRow(\PDO::FETCH_ASSOC);
128 128
         
129
-        if($ga_array) {
129
+        if ($ga_array) {
130 130
             return $this->loadGeoAnalysisFromRow($ga_array);
131 131
         }
132 132
         
@@ -146,7 +146,7 @@  discard block
 block discarded – undo
146 146
      * @return GeoAnalysis
147 147
      */
148 148
 	public function createGeoAnalysis($description, $analysis_level, $map_file, $map_top_level, $use_flags, $gen_details) {
149
-		try{
149
+		try {
150 150
 			Database::beginTransaction();
151 151
 		
152 152
 			Database::prepare(
@@ -168,7 +168,7 @@  discard block
 block discarded – undo
168 168
 			
169 169
 			Database::commit();
170 170
 		}
171
-		catch(\Exception $ex) {
171
+		catch (\Exception $ex) {
172 172
 			Database::rollback();
173 173
 			$ga = null;
174 174
 			Log::addErrorLog('A new Geo Analysis failed to be created. Transaction rollbacked. Parameters ['.$description.', '.$analysis_level.','.$map_file.','.$map_top_level.','.$use_flags.', '.$gen_details.']. Exception: '.$ex->getMessage());
@@ -211,9 +211,9 @@  discard block
 block discarded – undo
211 211
 			
212 212
 			 Database::commit();
213 213
 		}
214
-		catch(\Exception $ex) {		    
214
+		catch (\Exception $ex) {		    
215 215
 			Database::rollback();
216
-			Log::addErrorLog('The Geo Analysis ID “' . $ga->getId() . '” failed to be updated. Transaction rollbacked. Exception: '.$ex->getMessage());
216
+			Log::addErrorLog('The Geo Analysis ID “'.$ga->getId().'” failed to be updated. Transaction rollbacked. Exception: '.$ex->getMessage());
217 217
 			$ga = null;
218 218
 		}
219 219
 		return $ga;
@@ -258,12 +258,12 @@  discard block
 block discarded – undo
258 258
      *
259 259
      * @return array List of enabled maps
260 260
      */
261
-    public function getGeoAnalysisList(){
261
+    public function getGeoAnalysisList() {
262 262
         $res = array();
263 263
         
264 264
         $list = Database::prepare(
265
-            'SELECT majgd_id, majgd_descr, majgd_sublevel, majgd_map, majgd_toplevel, majgd_useflagsgen, majgd_detailsgen' .
266
-            ' FROM `##maj_geodispersion`' .
265
+            'SELECT majgd_id, majgd_descr, majgd_sublevel, majgd_map, majgd_toplevel, majgd_useflagsgen, majgd_detailsgen'.
266
+            ' FROM `##maj_geodispersion`'.
267 267
             ' WHERE majgd_file = :gedcom_id AND majgd_status = :status'.
268 268
             ' ORDER BY majgd_descr'
269 269
         )->execute(array(
@@ -271,7 +271,7 @@  discard block
 block discarded – undo
271 271
             'status' => 'enabled'
272 272
         ))->fetchAll(\PDO::FETCH_ASSOC);
273 273
         
274
-        foreach($list as $ga) {
274
+        foreach ($list as $ga) {
275 275
            $res[] = $this->loadGeoAnalysisFromRow($ga);
276 276
         }
277 277
         
@@ -287,17 +287,17 @@  discard block
 block discarded – undo
287 287
      * @param int|null $limit Max number of items to return (for pagination)
288 288
      * @return \MyArtJaub\Webtrees\Module\GeoDispersion\Model\GeoAnalysis[]
289 289
      */
290
-    public function getFilteredGeoAnalysisList($search = null, $order_by = null, $start = 0, $limit = null){
290
+    public function getFilteredGeoAnalysisList($search = null, $order_by = null, $start = 0, $limit = null) {
291 291
         $res = array();
292 292
             
293 293
         $sql = 
294
-            'SELECT majgd_id, majgd_descr, majgd_sublevel, majgd_map, majgd_toplevel, majgd_useflagsgen, majgd_detailsgen, majgd_status' .
295
-            ' FROM `##maj_geodispersion`' .
294
+            'SELECT majgd_id, majgd_descr, majgd_sublevel, majgd_map, majgd_toplevel, majgd_useflagsgen, majgd_detailsgen, majgd_status'.
295
+            ' FROM `##maj_geodispersion`'.
296 296
             ' WHERE majgd_file = :gedcom_id';
297 297
         
298 298
         $args = array('gedcom_id'=> $this->tree->getTreeId());
299 299
         
300
-        if($search) {
300
+        if ($search) {
301 301
             $sql .= ' AND majgd_descr LIKE CONCAT(\'%\', :search, \'%\')';
302 302
             $args['search'] = $search;
303 303
         }
@@ -311,10 +311,10 @@  discard block
 block discarded – undo
311 311
                 
312 312
                 switch ($value['dir']) {
313 313
                     case 'asc':
314
-                        $sql .= $value['column'] . ' ASC ';
314
+                        $sql .= $value['column'].' ASC ';
315 315
                         break;
316 316
                     case 'desc':
317
-                        $sql .= $value['column'] . ' DESC ';
317
+                        $sql .= $value['column'].' DESC ';
318 318
                         break;
319 319
                 }
320 320
             }
@@ -330,7 +330,7 @@  discard block
 block discarded – undo
330 330
             
331 331
         $data = Database::prepare($sql)->execute($args)->fetchAll(\PDO::FETCH_ASSOC);
332 332
 
333
-        foreach($data as $ga) {
333
+        foreach ($data as $ga) {
334 334
             $res[] = $this->loadGeoAnalysisFromRow($ga);
335 335
         }
336 336
         
@@ -347,11 +347,11 @@  discard block
 block discarded – undo
347 347
      * @return array
348 348
      */
349 349
     public function getPlacesHierarchy() {
350
-        if(!$this->place_hierarchy) {
351
-            if($place_structure = $this->getPlacesHierarchyFromHeader()) {
350
+        if (!$this->place_hierarchy) {
351
+            if ($place_structure = $this->getPlacesHierarchyFromHeader()) {
352 352
                 $this->place_hierarchy = array('type' => 'header', 'hierarchy' => $place_structure);
353 353
             }
354
-            elseif ($place_structure = $this->getPlacesHierarchyFromData()){
354
+            elseif ($place_structure = $this->getPlacesHierarchyFromData()) {
355 355
                 $this->place_hierarchy = array('type' => 'data', 'hierarchy' => $place_structure);
356 356
             }
357 357
             else {
@@ -370,8 +370,8 @@  discard block
 block discarded – undo
370 370
     protected function getPlacesHierarchyFromHeader() {
371 371
         $head = GedcomRecord::getInstance('HEAD', $this->tree);
372 372
         $head_place = $head->getFirstFact('PLAC');
373
-        if($head_place && $head_place_value = $head_place->getAttribute('FORM')){
374
-            return array_reverse(array_map('trim',explode(',', $head_place_value)));
373
+        if ($head_place && $head_place_value = $head_place->getAttribute('FORM')) {
374
+            return array_reverse(array_map('trim', explode(',', $head_place_value)));
375 375
         }
376 376
         return null;
377 377
     }
@@ -387,7 +387,7 @@  discard block
 block discarded – undo
387 387
         $nb_levels = 0;
388 388
         
389 389
         //Select all '2 PLAC ' tags in the file and create array
390
-        $places_list=array();
390
+        $places_list = array();
391 391
         $ged_data = Database::prepare(
392 392
             'SELECT i_gedcom AS gedcom'.
393 393
             ' FROM `##individuals`'.
@@ -404,7 +404,7 @@  discard block
 block discarded – undo
404 404
             $matches = null;
405 405
             preg_match_all('/\n2 PLAC (.+)/', $ged_datum, $matches);
406 406
             foreach ($matches[1] as $match) {
407
-                $places_list[$match]=true;
407
+                $places_list[$match] = true;
408 408
             }
409 409
         }
410 410
         
@@ -415,7 +415,7 @@  discard block
 block discarded – undo
415 415
         foreach ($places_list as $place => $value) {
416 416
             $levels = array_filter(array_map('trim', explode(",", $place)));
417 417
             $parts = count($levels);
418
-            if($parts > $max_level) {
418
+            if ($parts > $max_level) {
419 419
                 $max_level = $parts;
420 420
                 $places_with_high_level = array($place);
421 421
             }
@@ -425,11 +425,11 @@  discard block
 block discarded – undo
425 425
         }
426 426
         
427 427
         // If empty array, then return null
428
-        if($max_level == 0) return null;
428
+        if ($max_level == 0) return null;
429 429
                 
430 430
         // Else, return the first alphabetical element -- cannot return random to ensure always the same example if used
431 431
         usort($places_with_high_level, array('Fisharebest\\Webtrees\\I18N', 'strcasecmp'));        
432
-        return array_reverse(array_map('trim',explode(',', $places_with_high_level[0])));
432
+        return array_reverse(array_map('trim', explode(',', $places_with_high_level[0])));
433 433
         
434 434
     }
435 435
     
@@ -441,9 +441,9 @@  discard block
 block discarded – undo
441 441
     public function getOutlineMapsList() {
442 442
         $res = array();
443 443
         $root_path = WT_ROOT.WT_MODULES_DIR.Constants::MODULE_MAJ_GEODISP_NAME.'/maps/';
444
-        if(is_dir($root_path)){
444
+        if (is_dir($root_path)) {
445 445
             $dir = opendir($root_path);
446
-            while (($file=readdir($dir))!== false) {
446
+            while (($file = readdir($dir)) !== false) {
447 447
                 if (preg_match('/^[a-zA-Z0-9_]+.xml$/', $file)) {
448 448
                     $res[base64_encode($file)] = new OutlineMap($file, true);
449 449
                 }
Please login to merge, or discard this patch.
Braces   +8 added lines, -11 removed lines patch added patch discarded remove patch
@@ -167,8 +167,7 @@  discard block
 block discarded – undo
167 167
 			$ga = $this->getGeoAnalysis($id, false);
168 168
 			
169 169
 			Database::commit();
170
-		}
171
-		catch(\Exception $ex) {
170
+		} catch(\Exception $ex) {
172 171
 			Database::rollback();
173 172
 			$ga = null;
174 173
 			Log::addErrorLog('A new Geo Analysis failed to be created. Transaction rollbacked. Parameters ['.$description.', '.$analysis_level.','.$map_file.','.$map_top_level.','.$use_flags.', '.$gen_details.']. Exception: '.$ex->getMessage());
@@ -210,8 +209,7 @@  discard block
 block discarded – undo
210 209
 			$ga = $this->getGeoAnalysis($ga->getId(), false);
211 210
 			
212 211
 			 Database::commit();
213
-		}
214
-		catch(\Exception $ex) {		    
212
+		} catch(\Exception $ex) {		    
215 213
 			Database::rollback();
216 214
 			Log::addErrorLog('The Geo Analysis ID “' . $ga->getId() . '” failed to be updated. Transaction rollbacked. Exception: '.$ex->getMessage());
217 215
 			$ga = null;
@@ -350,11 +348,9 @@  discard block
 block discarded – undo
350 348
         if(!$this->place_hierarchy) {
351 349
             if($place_structure = $this->getPlacesHierarchyFromHeader()) {
352 350
                 $this->place_hierarchy = array('type' => 'header', 'hierarchy' => $place_structure);
353
-            }
354
-            elseif ($place_structure = $this->getPlacesHierarchyFromData()){
351
+            } elseif ($place_structure = $this->getPlacesHierarchyFromData()){
355 352
                 $this->place_hierarchy = array('type' => 'data', 'hierarchy' => $place_structure);
356
-            }
357
-            else {
353
+            } else {
358 354
                 $this->place_hierarchy = array('type' => 'none', 'hierarchy' => null);
359 355
             }
360 356
         }
@@ -418,14 +414,15 @@  discard block
 block discarded – undo
418 414
             if($parts > $max_level) {
419 415
                 $max_level = $parts;
420 416
                 $places_with_high_level = array($place);
421
-            }
422
-            else if ($parts == $max_level) {
417
+            } else if ($parts == $max_level) {
423 418
                 $places_with_high_level[] = $place;
424 419
             }
425 420
         }
426 421
         
427 422
         // If empty array, then return null
428
-        if($max_level == 0) return null;
423
+        if($max_level == 0) {
424
+        	return null;
425
+        }
429 426
                 
430 427
         // Else, return the first alphabetical element -- cannot return random to ensure always the same example if used
431 428
         usort($places_with_high_level, array('Fisharebest\\Webtrees\\I18N', 'strcasecmp'));        
Please login to merge, or discard this patch.
src/Webtrees/Module/GeoDispersion/Views/AdminConfigView.php 2 patches
Indentation   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -23,14 +23,14 @@  discard block
 block discarded – undo
23 23
 	 * {@inhericDoc}
24 24
 	 * @see \MyArtJaub\Webtrees\Mvc\View\AbstractView::renderContent()
25 25
 	 */
26
-    protected function renderContent() {
26
+	protected function renderContent() {
27 27
         
28
-        /** @var Tree $tree  */
29
-        $tree = $this->data->get('tree');
30
-        $root_url = $this->data->get('root_url');
31
-        $other_trees = $this->data->get('other_trees');
32
-        $table_id = $this->data->get('table_id');
33
-        ?>        
28
+		/** @var Tree $tree  */
29
+		$tree = $this->data->get('tree');
30
+		$root_url = $this->data->get('root_url');
31
+		$other_trees = $this->data->get('other_trees');
32
+		$table_id = $this->data->get('table_id');
33
+		?>        
34 34
         <ol class="breadcrumb small">
35 35
         	<li><a href="admin.php"><?php echo I18N::translate('Control panel'); ?></a></li>
36 36
 			<li><a href="admin_modules.php"><?php echo I18N::translate('Module administration'); ?></a></li>
@@ -63,23 +63,23 @@  discard block
 block discarded – undo
63 63
 		<p>
64 64
 		<?php $places_hierarchy = $this->data->get('places_hierarchy'); 
65 65
 		if($places_hierarchy && $places_hierarchy['type'] != 'none') {
66
-		    switch ($places_hierarchy['type']) {
67
-		        case 'header':
68
-		            echo I18N::translate('According to the GEDCOM header, the places within your file follows the structure: ');
69
-		            break;
70
-		        case 'data':
71
-		            echo I18N::translate('Your GEDCOM header does not contain any indication of place structure.').
72
-		            '<br/>'.
73
-		            I18N::translate('Here is an example of your place data: ');
74
-		            break;
75
-		        default:
76
-		            break;
77
-		    }
78
-		    $str_hierarchy = array();
79
-		    foreach($places_hierarchy['hierarchy'] as $key => $level) {
80
-		        $str_hierarchy[] = I18N::translate('(%d) %s', $key + 1, $level);
81
-		    }
82
-		    echo '<strong>' . implode(I18N::$list_separator, $str_hierarchy) . '</strong>';
66
+			switch ($places_hierarchy['type']) {
67
+				case 'header':
68
+					echo I18N::translate('According to the GEDCOM header, the places within your file follows the structure: ');
69
+					break;
70
+				case 'data':
71
+					echo I18N::translate('Your GEDCOM header does not contain any indication of place structure.').
72
+					'<br/>'.
73
+					I18N::translate('Here is an example of your place data: ');
74
+					break;
75
+				default:
76
+					break;
77
+			}
78
+			$str_hierarchy = array();
79
+			foreach($places_hierarchy['hierarchy'] as $key => $level) {
80
+				$str_hierarchy[] = I18N::translate('(%d) %s', $key + 1, $level);
81
+			}
82
+			echo '<strong>' . implode(I18N::$list_separator, $str_hierarchy) . '</strong>';
83 83
 		}
84 84
 		?>
85 85
 		</p>
@@ -109,7 +109,7 @@  discard block
 block discarded – undo
109 109
         </a>
110 110
 		
111 111
 		<?php        
112
-    }
112
+	}
113 113
     
114 114
 }
115 115
  
116 116
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -41,16 +41,16 @@  discard block
 block discarded – undo
41 41
 		
42 42
 		<h2>
43 43
 			<?php echo $tree->getTitleHtml(); ?>
44
-			<?php if(count($other_trees) > 0) {?>
44
+			<?php if (count($other_trees) > 0) {?>
45 45
 			<div class="btn-group">
46 46
 				<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
47 47
 					<?php echo I18N::translate('Change tree'); ?>
48 48
 					<span class="caret"></span>
49 49
 				</button>
50
-				<?php foreach($other_trees as $other_tree) { ?>
50
+				<?php foreach ($other_trees as $other_tree) { ?>
51 51
 				<ul class="dropdown-menu" role="menu">
52 52
 					<li>
53
-						<a href="<?php echo $root_url . '&ged=' . $other_tree->getNameUrl(); ?>">
53
+						<a href="<?php echo $root_url.'&ged='.$other_tree->getNameUrl(); ?>">
54 54
 							<i class="fa fa-fw fa-tree"></i>&nbsp;<?php echo $other_tree->getTitleHtml(); ?>
55 55
 						</a>
56 56
 					</li>
@@ -62,7 +62,7 @@  discard block
 block discarded – undo
62 62
 		
63 63
 		<p>
64 64
 		<?php $places_hierarchy = $this->data->get('places_hierarchy'); 
65
-		if($places_hierarchy && $places_hierarchy['type'] != 'none') {
65
+		if ($places_hierarchy && $places_hierarchy['type'] != 'none') {
66 66
 		    switch ($places_hierarchy['type']) {
67 67
 		        case 'header':
68 68
 		            echo I18N::translate('According to the GEDCOM header, the places within your file follows the structure: ');
@@ -76,10 +76,10 @@  discard block
 block discarded – undo
76 76
 		            break;
77 77
 		    }
78 78
 		    $str_hierarchy = array();
79
-		    foreach($places_hierarchy['hierarchy'] as $key => $level) {
79
+		    foreach ($places_hierarchy['hierarchy'] as $key => $level) {
80 80
 		        $str_hierarchy[] = I18N::translate('(%d) %s', $key + 1, $level);
81 81
 		    }
82
-		    echo '<strong>' . implode(I18N::$list_separator, $str_hierarchy) . '</strong>';
82
+		    echo '<strong>'.implode(I18N::$list_separator, $str_hierarchy).'</strong>';
83 83
 		}
84 84
 		?>
85 85
 		</p>
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
     		</tbody>
104 104
     	</table>
105 105
     	
106
-        <a type="button" class="btn btn-primary" href="<?php echo $root_url . '@add&ged=' . $tree->getNameUrl(); ?>" title="<?php echo I18N::translate('Add'); ?>">
106
+        <a type="button" class="btn btn-primary" href="<?php echo $root_url.'@add&ged='.$tree->getNameUrl(); ?>" title="<?php echo I18N::translate('Add'); ?>">
107 107
         	<i class="fa fa-plus"></i>
108 108
         	<?php echo I18N::translate('Add'); ?>
109 109
         </a>
Please login to merge, or discard this patch.
src/Webtrees/Module/GeoDispersion/AdminConfigController.php 3 patches
Indentation   +225 added lines, -225 removed lines patch added patch discarded remove patch
@@ -36,58 +36,58 @@  discard block
 block discarded – undo
36 36
  */
37 37
 class AdminConfigController extends MvcController
38 38
 {    
39
-    /**
40
-     * GeoAnalysis Provider
41
-     * @var GeoAnalysisProvider $provider
42
-     */
43
-    protected $provider;    
39
+	/**
40
+	 * GeoAnalysis Provider
41
+	 * @var GeoAnalysisProvider $provider
42
+	 */
43
+	protected $provider;    
44 44
     
45
-    /**
46
-     * Constructor for Admin Config controller
47
-     * @param AbstractModule $module
48
-     */
49
-    public function __construct(AbstractModule $module) {
50
-        parent::__construct($module);
45
+	/**
46
+	 * Constructor for Admin Config controller
47
+	 * @param AbstractModule $module
48
+	 */
49
+	public function __construct(AbstractModule $module) {
50
+		parent::__construct($module);
51 51
         
52
-        $this->provider = $this->module->getProvider();
53
-    }    
52
+		$this->provider = $this->module->getProvider();
53
+	}    
54 54
     
55
-    /**
56
-     * Pages
57
-     */
55
+	/**
56
+	 * Pages
57
+	 */
58 58
         
59
-    /**
60
-     * AdminConfig@index
61
-     */
62
-    public function index() {
63
-        $wt_tree = Globals::getTree();
64
-        Theme::theme(new AdministrationTheme)->init($wt_tree);
65
-        $controller = new PageController();
66
-        $controller
67
-            ->restrictAccess(Auth::isManager($wt_tree))
68
-            ->setPageTitle($this->module->getTitle());
59
+	/**
60
+	 * AdminConfig@index
61
+	 */
62
+	public function index() {
63
+		$wt_tree = Globals::getTree();
64
+		Theme::theme(new AdministrationTheme)->init($wt_tree);
65
+		$controller = new PageController();
66
+		$controller
67
+			->restrictAccess(Auth::isManager($wt_tree))
68
+			->setPageTitle($this->module->getTitle());
69 69
         
70
-        $data = new ViewBag();
71
-        $data->set('title', $controller->getPageTitle());
72
-        $data->set('tree', $wt_tree);
70
+		$data = new ViewBag();
71
+		$data->set('title', $controller->getPageTitle());
72
+		$data->set('tree', $wt_tree);
73 73
         
74
-        $data->set('root_url', 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig');
74
+		$data->set('root_url', 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig');
75 75
                 
76
-        $table_id = 'table-geoanalysis-' . Uuid::uuid4();
77
-        $data->set('table_id', $table_id);
76
+		$table_id = 'table-geoanalysis-' . Uuid::uuid4();
77
+		$data->set('table_id', $table_id);
78 78
         
79
-        $other_trees = array();
80
-        foreach (Tree::getAll() as $tree) {
81
-            if($tree->getTreeId() != $wt_tree->getTreeId()) $other_trees[] = $tree;
82
-        }      
83
-        $data->set('other_trees', $other_trees);
79
+		$other_trees = array();
80
+		foreach (Tree::getAll() as $tree) {
81
+			if($tree->getTreeId() != $wt_tree->getTreeId()) $other_trees[] = $tree;
82
+		}      
83
+		$data->set('other_trees', $other_trees);
84 84
         
85
-        $data->set('places_hierarchy', $this->provider->getPlacesHierarchy());
85
+		$data->set('places_hierarchy', $this->provider->getPlacesHierarchy());
86 86
         
87
-        $controller
88
-            ->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)
89
-            ->addExternalJavascript(WT_DATATABLES_BOOTSTRAP_JS_URL)
90
-            ->addInlineJavascript('
87
+		$controller
88
+			->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)
89
+			->addExternalJavascript(WT_DATATABLES_BOOTSTRAP_JS_URL)
90
+			->addInlineJavascript('
91 91
 				jQuery.fn.dataTableExt.oSort["text-asc"] = textCompareAsc;
92 92
 				jQuery.fn.dataTableExt.oSort["text-desc"] = textCompareDesc;
93 93
                 
@@ -119,7 +119,7 @@  discard block
 block discarded – undo
119 119
 				});
120 120
                 
121 121
                 ')
122
-                ->addInlineJavascript('				
122
+				->addInlineJavascript('				
123 123
                     function set_geoanalysis_status(ga_id, status, gedcom) {
124 124
                 		jQuery.ajax({
125 125
                             url: "module.php", 
@@ -163,54 +163,54 @@  discard block
 block discarded – undo
163 163
                 ');
164 164
         
165 165
         
166
-        ViewFactory::make('AdminConfig', $this, $controller, $data)->render();
167
-    }
166
+		ViewFactory::make('AdminConfig', $this, $controller, $data)->render();
167
+	}
168 168
 
169
-    /**
170
-     * AdminConfig@jsonGeoAnalysisList
171
-     */
172
-    public function jsonGeoAnalysisList() {
173
-        $wt_tree = Globals::getTree();
174
-        $controller = new JsonController();
175
-        $controller
176
-            ->restrictAccess(Auth::isManager($wt_tree));
169
+	/**
170
+	 * AdminConfig@jsonGeoAnalysisList
171
+	 */
172
+	public function jsonGeoAnalysisList() {
173
+		$wt_tree = Globals::getTree();
174
+		$controller = new JsonController();
175
+		$controller
176
+			->restrictAccess(Auth::isManager($wt_tree));
177 177
         
178
-        // Generate an AJAX/JSON response for datatables to load a block of rows
179
-        $search = Filter::postArray('search');
180
-        if($search) $search = $search['value'];
181
-        $start  = Filter::postInteger('start');
182
-        $length = Filter::postInteger('length');
183
-        $order  = Filter::postArray('order');
178
+		// Generate an AJAX/JSON response for datatables to load a block of rows
179
+		$search = Filter::postArray('search');
180
+		if($search) $search = $search['value'];
181
+		$start  = Filter::postInteger('start');
182
+		$length = Filter::postInteger('length');
183
+		$order  = Filter::postArray('order');
184 184
         
185
-        foreach($order as $key => &$value) {
186
-            switch($value['column']) {
187
-                case 3:
188
-                    $value['column'] = 'majgd_descr';
189
-                    break;
190
-                case 5;
191
-                    $value['column'] = 'majgd_sublevel';
192
-                    break;
193
-                default:
194
-                    unset($order[$key]);
195
-            }
196
-        }
185
+		foreach($order as $key => &$value) {
186
+			switch($value['column']) {
187
+				case 3:
188
+					$value['column'] = 'majgd_descr';
189
+					break;
190
+				case 5;
191
+					$value['column'] = 'majgd_sublevel';
192
+					break;
193
+				default:
194
+					unset($order[$key]);
195
+			}
196
+		}
197 197
         
198
-        /** @var GeoAnalysisProvider $provider */
199
-        $provider = $this->module->getProvider();
198
+		/** @var GeoAnalysisProvider $provider */
199
+		$provider = $this->module->getProvider();
200 200
         
201
-        $list = $provider->getFilteredGeoAnalysisList($search, $order, $start, $length);
202
-        $recordsFiltered = count($list);
203
-        $recordsTotal = $this->provider->getGeoAnalysisCount();
201
+		$list = $provider->getFilteredGeoAnalysisList($search, $order, $start, $length);
202
+		$recordsFiltered = count($list);
203
+		$recordsTotal = $this->provider->getGeoAnalysisCount();
204 204
         
205
-        $data = array();
206
-        $place_hierarchy = $this->provider->getPlacesHierarchy();
207
-        foreach($list as $ga) {
208
-            /** @var GeoAnalysis $ga */
205
+		$data = array();
206
+		$place_hierarchy = $this->provider->getPlacesHierarchy();
207
+		foreach($list as $ga) {
208
+			/** @var GeoAnalysis $ga */
209 209
             
210
-            $datum = array();
211
-            $options= $ga->getOptions();
210
+			$datum = array();
211
+			$options= $ga->getOptions();
212 212
             
213
-            $datum[0] = '
213
+			$datum[0] = '
214 214
                 <div class="btn-group">
215 215
                     <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
216 216
                         <i class="fa fa-pencil"></i><span class="caret"></span>
@@ -234,116 +234,116 @@  discard block
 block discarded – undo
234 234
                        </li>
235 235
                     </ul>
236 236
                 </div>';
237
-		    $datum[1] = $ga->getId();
238
-		    $datum[2] = $ga->isEnabled() ? 
237
+			$datum[1] = $ga->getId();
238
+			$datum[2] = $ga->isEnabled() ? 
239 239
 				'<i class="fa fa-check"></i><span class="sr-only">'.I18N::translate('Enabled').'</span>' : 
240 240
 				'<i class="fa fa-times"></i><span class="sr-only">'.I18N::translate('Disabled').'</span>';
241
-		    $datum[3] = $ga->getTitle();
242
-		    $analysis_level = $ga->getAnalysisLevel();
243
-		    if($place_hierarchy['type'] == 'header') {
244
-		        $datum[4] = $place_hierarchy['hierarchy'][$analysis_level - 1];
245
-		    } elseif ($place_hierarchy['type'] == 'data') {
246
-		        $datum[4] = $analysis_level . ' (' . $place_hierarchy['hierarchy'][$analysis_level - 1] . ')';
247
-		    } else {
248
-		        $datum[4] = $analysis_level;
249
-		    }
250
-		    $datum[5] = $ga->getAnalysisLevel();
251
-		    $datum[6] = '<i class="fa fa-times"></i><span class="sr-only">'.I18N::translate('None').'</span>';
252
-		    $datum[7] = '<i class="fa fa-times"></i><span class="sr-only">'.I18N::translate('None').'</span>';
253
-		    if($ga->hasMap()) {
254
-		        if($options->getMap()->isLoaded()) {
255
-    		        $datum[6] = $options->getMap()->getDescription();
256
-    		        $datum[7] = '<span data-toggle="tooltip" title="' . $options->getMap()->getTopLevelName() . '" />';
257
-    		        $top_level = $options->getMapLevel();
258
-    		        if($place_hierarchy['type'] == 'header') {
259
-    		            $datum[7] .= $place_hierarchy['hierarchy'][$top_level - 1];
260
-    		        } elseif ($place_hierarchy['type'] == 'data') {
261
-    		            $datum[7] .= $top_level . ' (' . $place_hierarchy['hierarchy'][$top_level - 1] . ')';
262
-    		        } else {
263
-    		            $datum[7] .= $top_level;
264
-    		        }
265
-    		        $datum[7] .= '</span>';
266
-		        }
267
-		        else {
268
-		            $datum[6] = I18N::translate('Error when loading map.');
269
-		        }
270
-		    }
271
-		    $datum[8] = $options->isUsingFlags() ? 
241
+			$datum[3] = $ga->getTitle();
242
+			$analysis_level = $ga->getAnalysisLevel();
243
+			if($place_hierarchy['type'] == 'header') {
244
+				$datum[4] = $place_hierarchy['hierarchy'][$analysis_level - 1];
245
+			} elseif ($place_hierarchy['type'] == 'data') {
246
+				$datum[4] = $analysis_level . ' (' . $place_hierarchy['hierarchy'][$analysis_level - 1] . ')';
247
+			} else {
248
+				$datum[4] = $analysis_level;
249
+			}
250
+			$datum[5] = $ga->getAnalysisLevel();
251
+			$datum[6] = '<i class="fa fa-times"></i><span class="sr-only">'.I18N::translate('None').'</span>';
252
+			$datum[7] = '<i class="fa fa-times"></i><span class="sr-only">'.I18N::translate('None').'</span>';
253
+			if($ga->hasMap()) {
254
+				if($options->getMap()->isLoaded()) {
255
+					$datum[6] = $options->getMap()->getDescription();
256
+					$datum[7] = '<span data-toggle="tooltip" title="' . $options->getMap()->getTopLevelName() . '" />';
257
+					$top_level = $options->getMapLevel();
258
+					if($place_hierarchy['type'] == 'header') {
259
+						$datum[7] .= $place_hierarchy['hierarchy'][$top_level - 1];
260
+					} elseif ($place_hierarchy['type'] == 'data') {
261
+						$datum[7] .= $top_level . ' (' . $place_hierarchy['hierarchy'][$top_level - 1] . ')';
262
+					} else {
263
+						$datum[7] .= $top_level;
264
+					}
265
+					$datum[7] .= '</span>';
266
+				}
267
+				else {
268
+					$datum[6] = I18N::translate('Error when loading map.');
269
+				}
270
+			}
271
+			$datum[8] = $options->isUsingFlags() ? 
272 272
 				'<i class="fa fa-check"></i><span class="sr-only">'.I18N::translate('Yes').'</span>' : 
273 273
 				'<i class="fa fa-times"></i><span class="sr-only">'.I18N::translate('No').'</span>';
274
-		    $datum[9] = $options->getMaxDetailsInGen() > 0 ? $options->getMaxDetailsInGen() : I18N::translate('All');
274
+			$datum[9] = $options->getMaxDetailsInGen() > 0 ? $options->getMaxDetailsInGen() : I18N::translate('All');
275 275
 		    
276
-		    $data[] = $datum;
277
-        }
276
+			$data[] = $datum;
277
+		}
278 278
         
279
-        $controller->pageHeader();
279
+		$controller->pageHeader();
280 280
         
281
-        $controller->encode(array(
282
-            'draw'            => Filter::getInteger('draw'),
283
-            'recordsTotal'    => $recordsTotal,
284
-            'recordsFiltered' => $recordsFiltered,
285
-            'data'            => $data
286
-        ));
281
+		$controller->encode(array(
282
+			'draw'            => Filter::getInteger('draw'),
283
+			'recordsTotal'    => $recordsTotal,
284
+			'recordsFiltered' => $recordsFiltered,
285
+			'data'            => $data
286
+		));
287 287
         
288
-    }
288
+	}
289 289
 
290
-    /**
291
-     * AdminConfig@edit
292
-     */
293
-    public function edit() {
294
-        $ga_id = Filter::getInteger('ga_id');
295
-        $ga = $this->provider->getGeoAnalysis($ga_id, false);
290
+	/**
291
+	 * AdminConfig@edit
292
+	 */
293
+	public function edit() {
294
+		$ga_id = Filter::getInteger('ga_id');
295
+		$ga = $this->provider->getGeoAnalysis($ga_id, false);
296 296
         
297
-        $this->renderEdit($ga);
298
-    }
297
+		$this->renderEdit($ga);
298
+	}
299 299
     
300
-    /**
301
-     * AdminConfig@add
302
-     */
303
-    public function add() {
304
-        $this->renderEdit(null);
305
-    }
300
+	/**
301
+	 * AdminConfig@add
302
+	 */
303
+	public function add() {
304
+		$this->renderEdit(null);
305
+	}
306 306
     
307
-    /**
308
-     * AdminConfig@save
309
-     */
310
-    public function save() {
311
-        $wt_tree = Globals::getTree();
312
-        $tmp_contrl = new PageController();
313
-        $tmp_contrl->restrictAccess(
314
-            Auth::isManager($wt_tree) 
315
-            && Filter::checkCsrf()
316
-         );
307
+	/**
308
+	 * AdminConfig@save
309
+	 */
310
+	public function save() {
311
+		$wt_tree = Globals::getTree();
312
+		$tmp_contrl = new PageController();
313
+		$tmp_contrl->restrictAccess(
314
+			Auth::isManager($wt_tree) 
315
+			&& Filter::checkCsrf()
316
+		 );
317 317
         
318
-        $ga_id          = Filter::postInteger('ga_id');
319
-        $description    = Filter::post('description');
320
-        $analysislevel  = Filter::postInteger('analysislevel');
321
-        $use_map        = Filter::postBool('use_map');
322
-        if($use_map) {
323
-            $map_file   = base64_decode(Filter::post('map_file'));
324
-            $map_top_level   = Filter::postInteger('map_top_level');
325
-        }
326
-        $use_flags      = Filter::postBool('use_flags');
327
-        $gen_details    = Filter::postInteger('gen_details');
318
+		$ga_id          = Filter::postInteger('ga_id');
319
+		$description    = Filter::post('description');
320
+		$analysislevel  = Filter::postInteger('analysislevel');
321
+		$use_map        = Filter::postBool('use_map');
322
+		if($use_map) {
323
+			$map_file   = base64_decode(Filter::post('map_file'));
324
+			$map_top_level   = Filter::postInteger('map_top_level');
325
+		}
326
+		$use_flags      = Filter::postBool('use_flags');
327
+		$gen_details    = Filter::postInteger('gen_details');
328 328
         
329
-        $success = false; 
330
-        if($ga_id) {
331
-            $ga = $this->provider->getGeoAnalysis($ga_id, false);
332
-            if($ga) {
333
-                $ga->setTitle($description);
334
-                $ga->setAnalysisLevel($analysislevel + 1);
335
-                $options = $ga->getOptions();
336
-                if($options) {
337
-                    $options->setUsingFlags($use_flags);
338
-                    $options->setMaxDetailsInGen($gen_details);
339
-                    if($use_map) {
340
-                        $options->setMap(new OutlineMap($map_file));
341
-                        $options->setMapLevel($map_top_level + 1);
342
-                    }
343
-                    else {
344
-                        $options->setMap(null);
345
-                    }
346
-                }
329
+		$success = false; 
330
+		if($ga_id) {
331
+			$ga = $this->provider->getGeoAnalysis($ga_id, false);
332
+			if($ga) {
333
+				$ga->setTitle($description);
334
+				$ga->setAnalysisLevel($analysislevel + 1);
335
+				$options = $ga->getOptions();
336
+				if($options) {
337
+					$options->setUsingFlags($use_flags);
338
+					$options->setMaxDetailsInGen($gen_details);
339
+					if($use_map) {
340
+						$options->setMap(new OutlineMap($map_file));
341
+						$options->setMapLevel($map_top_level + 1);
342
+					}
343
+					else {
344
+						$options->setMap(null);
345
+					}
346
+				}
347 347
 				
348 348
 				$res = $this->provider->updateGeoAnalysis($ga);
349 349
 				if($res) {
@@ -356,8 +356,8 @@  discard block
 block discarded – undo
356 356
 					FlashMessages::addMessage(I18N::translate('An error occured while updating the geographical dispersion analysis “%s”', $ga->getTitle()), 'danger');
357 357
 					Log::addConfigurationLog('Module '.$this->module->getName().' : Geo Analysis ID “'. $ga->getId() .'” could not be updated. See error log.');
358 358
 				}
359
-            }
360
-        } else {
359
+			}
360
+		} else {
361 361
 			$ga = $this->provider->createGeoAnalysis(
362 362
 				$description,
363 363
 				$analysislevel + 1,
@@ -375,33 +375,33 @@  discard block
 block discarded – undo
375 375
 				FlashMessages::addMessage(I18N::translate('An error occured while adding the geographical dispersion analysis “%s”', $description), 'danger');
376 376
 				Log::addConfigurationLog('Module '.$this->module->getName().' : Geo Analysis “'.$description.'” could not be added. See error log.');
377 377
 			}
378
-        }
378
+		}
379 379
         
380
-        $redirection_url = 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig&ged=' . $wt_tree->getNameUrl();
381
-        if(!$success) {			
382
-            if($ga) {
383
-                $redirection_url = 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig@edit&ga_id='. $ga->getId() .'&ged=' . $wt_tree->getNameUrl();
384
-            }
385
-            else {
386
-                $redirection_url = 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig@add&ged=' . $wt_tree->getNameUrl();
387
-            }
388
-        }        
389
-        header('Location: ' . WT_BASE_URL . $redirection_url);
380
+		$redirection_url = 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig&ged=' . $wt_tree->getNameUrl();
381
+		if(!$success) {			
382
+			if($ga) {
383
+				$redirection_url = 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig@edit&ga_id='. $ga->getId() .'&ged=' . $wt_tree->getNameUrl();
384
+			}
385
+			else {
386
+				$redirection_url = 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig@add&ged=' . $wt_tree->getNameUrl();
387
+			}
388
+		}        
389
+		header('Location: ' . WT_BASE_URL . $redirection_url);
390 390
         
391
-    }
391
+	}
392 392
      
393 393
 	/**
394 394
 	 * Renders the edit form, whether it is an edition of an existing GeoAnalysis, or the addition of a new one.
395 395
 	 * 
396 396
 	 * @param (GeoAnalysis!null) $ga GeoAnalysis to edit
397 397
 	 */
398
-    protected function renderEdit(GeoAnalysis $ga = null) {
399
-        $wt_tree = Globals::getTree();
400
-        Theme::theme(new AdministrationTheme)->init($wt_tree);
401
-        $controller = new PageController();        
402
-        $controller
403
-            ->restrictAccess(Auth::isManager($wt_tree))
404
-            ->addInlineJavascript('
398
+	protected function renderEdit(GeoAnalysis $ga = null) {
399
+		$wt_tree = Globals::getTree();
400
+		Theme::theme(new AdministrationTheme)->init($wt_tree);
401
+		$controller = new PageController();        
402
+		$controller
403
+			->restrictAccess(Auth::isManager($wt_tree))
404
+			->addInlineJavascript('
405 405
                 function toggleMapOptions() {
406 406
                     if($("input:radio[name=\'use_map\']:checked").val() == 1) {
407 407
                         $("#map_options").show();
@@ -415,34 +415,34 @@  discard block
 block discarded – undo
415 415
                 toggleMapOptions();
416 416
             ');
417 417
         
418
-        $data = new ViewBag();
419
-        if($ga) {
420
-            $controller->setPageTitle(I18N::translate('Edit the geographical dispersion analysis'));
421
-            $data->set('geo_analysis', $ga);
422
-        } else {
423
-            $controller->setPageTitle(I18N::translate('Add a geographical dispersion analysis'));
424
-        }
418
+		$data = new ViewBag();
419
+		if($ga) {
420
+			$controller->setPageTitle(I18N::translate('Edit the geographical dispersion analysis'));
421
+			$data->set('geo_analysis', $ga);
422
+		} else {
423
+			$controller->setPageTitle(I18N::translate('Add a geographical dispersion analysis'));
424
+		}
425 425
         
426
-        $data->set('title', $controller->getPageTitle());
427
-        $data->set('admin_config_url', 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig&ged=' . $wt_tree->getNameUrl());
428
-        $data->set('module_title', $this->module->getTitle());
429
-        $data->set('save_url', 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig@save&ged=' . $wt_tree->getNameUrl());
430
-        $data->set('places_hierarchy', $this->provider->getPlacesHierarchy());
426
+		$data->set('title', $controller->getPageTitle());
427
+		$data->set('admin_config_url', 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig&ged=' . $wt_tree->getNameUrl());
428
+		$data->set('module_title', $this->module->getTitle());
429
+		$data->set('save_url', 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig@save&ged=' . $wt_tree->getNameUrl());
430
+		$data->set('places_hierarchy', $this->provider->getPlacesHierarchy());
431 431
     
432
-        $map_list = array_map(
433
-            function(OutlineMap $map) {
434
-                return $map->getDescription();
435
-            },
436
-            $this->provider->getOutlineMapsList()
437
-            );
438
-        asort($map_list);
439
-        $data->set('map_list', $map_list);
432
+		$map_list = array_map(
433
+			function(OutlineMap $map) {
434
+				return $map->getDescription();
435
+			},
436
+			$this->provider->getOutlineMapsList()
437
+			);
438
+		asort($map_list);
439
+		$data->set('map_list', $map_list);
440 440
     
441
-        $gen_details = array(0 => I18N::translate('All'));
442
-        for($i = 1; $i <= 10 ; $i++) $gen_details[$i] = $i;
443
-        $data->set('generation_details', $gen_details);
441
+		$gen_details = array(0 => I18N::translate('All'));
442
+		for($i = 1; $i <= 10 ; $i++) $gen_details[$i] = $i;
443
+		$data->set('generation_details', $gen_details);
444 444
     
445
-        ViewFactory::make('GeoAnalysisEdit', $this, $controller, $data)->render();
446
-    }
445
+		ViewFactory::make('GeoAnalysisEdit', $this, $controller, $data)->render();
446
+	}
447 447
     
448 448
 }
449 449
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +44 added lines, -46 removed lines patch added patch discarded remove patch
@@ -71,14 +71,14 @@  discard block
 block discarded – undo
71 71
         $data->set('title', $controller->getPageTitle());
72 72
         $data->set('tree', $wt_tree);
73 73
         
74
-        $data->set('root_url', 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig');
74
+        $data->set('root_url', 'module.php?mod='.$this->module->getName().'&mod_action=AdminConfig');
75 75
                 
76
-        $table_id = 'table-geoanalysis-' . Uuid::uuid4();
76
+        $table_id = 'table-geoanalysis-'.Uuid::uuid4();
77 77
         $data->set('table_id', $table_id);
78 78
         
79 79
         $other_trees = array();
80 80
         foreach (Tree::getAll() as $tree) {
81
-            if($tree->getTreeId() != $wt_tree->getTreeId()) $other_trees[] = $tree;
81
+            if ($tree->getTreeId() != $wt_tree->getTreeId()) $other_trees[] = $tree;
82 82
         }      
83 83
         $data->set('other_trees', $other_trees);
84 84
         
@@ -101,7 +101,7 @@  discard block
 block discarded – undo
101 101
                     processing: true,
102 102
                     serverSide : true,
103 103
 					ajax : {
104
-						url : "module.php?mod='.$this->module->getName().'&mod_action=AdminConfig@jsonGeoAnalysisList&ged='. $wt_tree->getNameUrl().'",
104
+						url : "module.php?mod='.$this->module->getName().'&mod_action=AdminConfig@jsonGeoAnalysisList&ged='.$wt_tree->getNameUrl().'",
105 105
                         type : "POST"
106 106
 					},
107 107
                     columns: [
@@ -125,7 +125,7 @@  discard block
 block discarded – undo
125 125
                             url: "module.php", 
126 126
                             type: "GET",
127 127
                             data: {
128
-                			    mod: "' . $this->module->getName() .'",
128
+                			    mod: "' . $this->module->getName().'",
129 129
                                 mod_action:  "GeoAnalysis@setStatus",
130 130
                 			    ga_id: ga_id,
131 131
                 			    ged: typeof gedcom === "undefined" ? WT_GEDCOM : gedcom,
@@ -133,7 +133,7 @@  discard block
 block discarded – undo
133 133
                             },
134 134
                             error: function(result, stat, error) {
135 135
                                 var err = typeof result.responseJSON === "undefined" ? error : result.responseJSON.error;
136
-                                alert("' . I18N::translate('An error occured while editing this analysis:') . '" + err);
136
+                                alert("' . I18N::translate('An error occured while editing this analysis:').'" + err);
137 137
                             },
138 138
                             complete: function(result, stat) {
139 139
                                 geoAnalysisTable.ajax.reload(null, false);
@@ -146,14 +146,14 @@  discard block
 block discarded – undo
146 146
                             url: "module.php", 
147 147
                             type: "GET",
148 148
                             data: {
149
-                			    mod: "' . $this->module->getName() .'",
149
+                			    mod: "' . $this->module->getName().'",
150 150
                                 mod_action:  "GeoAnalysis@delete",
151 151
                 			    ga_id: ga_id,
152 152
                 			    ged: typeof gedcom === "undefined" ? WT_GEDCOM : gedcom
153 153
                             },
154 154
                             error: function(result, stat, error) {
155 155
                                 var err = typeof result.responseJSON === "undefined" ? error : result.responseJSON.error;
156
-                                alert("' . I18N::translate('An error occured while deleting this analysis:') . '" + err);
156
+                                alert("' . I18N::translate('An error occured while deleting this analysis:').'" + err);
157 157
                             },
158 158
                             complete: function(result, stat) {
159 159
                                 geoAnalysisTable.ajax.reload(null, false);
@@ -177,13 +177,13 @@  discard block
 block discarded – undo
177 177
         
178 178
         // Generate an AJAX/JSON response for datatables to load a block of rows
179 179
         $search = Filter::postArray('search');
180
-        if($search) $search = $search['value'];
180
+        if ($search) $search = $search['value'];
181 181
         $start  = Filter::postInteger('start');
182 182
         $length = Filter::postInteger('length');
183 183
         $order  = Filter::postArray('order');
184 184
         
185
-        foreach($order as $key => &$value) {
186
-            switch($value['column']) {
185
+        foreach ($order as $key => &$value) {
186
+            switch ($value['column']) {
187 187
                 case 3:
188 188
                     $value['column'] = 'majgd_descr';
189 189
                     break;
@@ -204,11 +204,11 @@  discard block
 block discarded – undo
204 204
         
205 205
         $data = array();
206 206
         $place_hierarchy = $this->provider->getPlacesHierarchy();
207
-        foreach($list as $ga) {
207
+        foreach ($list as $ga) {
208 208
             /** @var GeoAnalysis $ga */
209 209
             
210 210
             $datum = array();
211
-            $options= $ga->getOptions();
211
+            $options = $ga->getOptions();
212 212
             
213 213
             $datum[0] = '
214 214
                 <div class="btn-group">
@@ -218,47 +218,46 @@  discard block
 block discarded – undo
218 218
                     <ul class="dropdown-menu" role="menu">
219 219
                        <li>
220 220
                             <a href="#" onclick="return set_geoanalysis_status('. $ga->getId().', '.($ga->isEnabled() ? 'false' : 'true').', \''.Filter::escapeJs($wt_tree->getName()).'\');">
221
-                                <i class="fa fa-fw '.($ga->isEnabled() ? 'fa-times' : 'fa-check').'"></i> ' . ($ga->isEnabled() ? I18N::translate('Disable') : I18N::translate('Enable')) . '
221
+                                <i class="fa fa-fw '.($ga->isEnabled() ? 'fa-times' : 'fa-check').'"></i> '.($ga->isEnabled() ? I18N::translate('Disable') : I18N::translate('Enable')).'
222 222
                             </a>
223 223
                        </li>
224 224
                         <li>
225 225
                             <a href="module.php?mod='.$this->module->getName().'&mod_action=AdminConfig@edit&ga_id='.$ga->getId().'&ged='.$wt_tree->getName().'">
226
-                                <i class="fa fa-fw fa-pencil"></i> ' . I18N::translate('Edit') . '
226
+                                <i class="fa fa-fw fa-pencil"></i> ' . I18N::translate('Edit').'
227 227
                             </a>
228 228
                        </li>
229 229
                        <li class="divider" />
230 230
                        <li>
231 231
                             <a href="#" onclick="return delete_geoanalysis('. $ga->getId().', \''.Filter::escapeJs($wt_tree->getName()).'\');">
232
-                                <i class="fa fa-fw fa-trash-o"></i> ' . I18N::translate('Delete') . '
232
+                                <i class="fa fa-fw fa-trash-o"></i> ' . I18N::translate('Delete').'
233 233
                             </a>
234 234
                        </li>
235 235
                     </ul>
236 236
                 </div>';
237 237
 		    $datum[1] = $ga->getId();
238 238
 		    $datum[2] = $ga->isEnabled() ? 
239
-				'<i class="fa fa-check"></i><span class="sr-only">'.I18N::translate('Enabled').'</span>' : 
240
-				'<i class="fa fa-times"></i><span class="sr-only">'.I18N::translate('Disabled').'</span>';
239
+				'<i class="fa fa-check"></i><span class="sr-only">'.I18N::translate('Enabled').'</span>' : '<i class="fa fa-times"></i><span class="sr-only">'.I18N::translate('Disabled').'</span>';
241 240
 		    $datum[3] = $ga->getTitle();
242 241
 		    $analysis_level = $ga->getAnalysisLevel();
243
-		    if($place_hierarchy['type'] == 'header') {
242
+		    if ($place_hierarchy['type'] == 'header') {
244 243
 		        $datum[4] = $place_hierarchy['hierarchy'][$analysis_level - 1];
245 244
 		    } elseif ($place_hierarchy['type'] == 'data') {
246
-		        $datum[4] = $analysis_level . ' (' . $place_hierarchy['hierarchy'][$analysis_level - 1] . ')';
245
+		        $datum[4] = $analysis_level.' ('.$place_hierarchy['hierarchy'][$analysis_level - 1].')';
247 246
 		    } else {
248 247
 		        $datum[4] = $analysis_level;
249 248
 		    }
250 249
 		    $datum[5] = $ga->getAnalysisLevel();
251 250
 		    $datum[6] = '<i class="fa fa-times"></i><span class="sr-only">'.I18N::translate('None').'</span>';
252 251
 		    $datum[7] = '<i class="fa fa-times"></i><span class="sr-only">'.I18N::translate('None').'</span>';
253
-		    if($ga->hasMap()) {
254
-		        if($options->getMap()->isLoaded()) {
252
+		    if ($ga->hasMap()) {
253
+		        if ($options->getMap()->isLoaded()) {
255 254
     		        $datum[6] = $options->getMap()->getDescription();
256
-    		        $datum[7] = '<span data-toggle="tooltip" title="' . $options->getMap()->getTopLevelName() . '" />';
255
+    		        $datum[7] = '<span data-toggle="tooltip" title="'.$options->getMap()->getTopLevelName().'" />';
257 256
     		        $top_level = $options->getMapLevel();
258
-    		        if($place_hierarchy['type'] == 'header') {
257
+    		        if ($place_hierarchy['type'] == 'header') {
259 258
     		            $datum[7] .= $place_hierarchy['hierarchy'][$top_level - 1];
260 259
     		        } elseif ($place_hierarchy['type'] == 'data') {
261
-    		            $datum[7] .= $top_level . ' (' . $place_hierarchy['hierarchy'][$top_level - 1] . ')';
260
+    		            $datum[7] .= $top_level.' ('.$place_hierarchy['hierarchy'][$top_level - 1].')';
262 261
     		        } else {
263 262
     		            $datum[7] .= $top_level;
264 263
     		        }
@@ -269,8 +268,7 @@  discard block
 block discarded – undo
269 268
 		        }
270 269
 		    }
271 270
 		    $datum[8] = $options->isUsingFlags() ? 
272
-				'<i class="fa fa-check"></i><span class="sr-only">'.I18N::translate('Yes').'</span>' : 
273
-				'<i class="fa fa-times"></i><span class="sr-only">'.I18N::translate('No').'</span>';
271
+				'<i class="fa fa-check"></i><span class="sr-only">'.I18N::translate('Yes').'</span>' : '<i class="fa fa-times"></i><span class="sr-only">'.I18N::translate('No').'</span>';
274 272
 		    $datum[9] = $options->getMaxDetailsInGen() > 0 ? $options->getMaxDetailsInGen() : I18N::translate('All');
275 273
 		    
276 274
 		    $data[] = $datum;
@@ -319,24 +317,24 @@  discard block
 block discarded – undo
319 317
         $description    = Filter::post('description');
320 318
         $analysislevel  = Filter::postInteger('analysislevel');
321 319
         $use_map        = Filter::postBool('use_map');
322
-        if($use_map) {
320
+        if ($use_map) {
323 321
             $map_file   = base64_decode(Filter::post('map_file'));
324
-            $map_top_level   = Filter::postInteger('map_top_level');
322
+            $map_top_level = Filter::postInteger('map_top_level');
325 323
         }
326 324
         $use_flags      = Filter::postBool('use_flags');
327 325
         $gen_details    = Filter::postInteger('gen_details');
328 326
         
329 327
         $success = false; 
330
-        if($ga_id) {
328
+        if ($ga_id) {
331 329
             $ga = $this->provider->getGeoAnalysis($ga_id, false);
332
-            if($ga) {
330
+            if ($ga) {
333 331
                 $ga->setTitle($description);
334 332
                 $ga->setAnalysisLevel($analysislevel + 1);
335 333
                 $options = $ga->getOptions();
336
-                if($options) {
334
+                if ($options) {
337 335
                     $options->setUsingFlags($use_flags);
338 336
                     $options->setMaxDetailsInGen($gen_details);
339
-                    if($use_map) {
337
+                    if ($use_map) {
340 338
                         $options->setMap(new OutlineMap($map_file));
341 339
                         $options->setMapLevel($map_top_level + 1);
342 340
                     }
@@ -346,7 +344,7 @@  discard block
 block discarded – undo
346 344
                 }
347 345
 				
348 346
 				$res = $this->provider->updateGeoAnalysis($ga);
349
-				if($res) {
347
+				if ($res) {
350 348
 					FlashMessages::addMessage(I18N::translate('The geographical dispersion analysis “%s” has been successfully updated', $res->getTitle()), 'success');
351 349
 					Log::addConfigurationLog('Module '.$this->module->getName().' : Geo Analysis ID “'.$res->getId().'” has been updated.');
352 350
 					$ga = $res;
@@ -354,7 +352,7 @@  discard block
 block discarded – undo
354 352
 				}
355 353
 				else {
356 354
 					FlashMessages::addMessage(I18N::translate('An error occured while updating the geographical dispersion analysis “%s”', $ga->getTitle()), 'danger');
357
-					Log::addConfigurationLog('Module '.$this->module->getName().' : Geo Analysis ID “'. $ga->getId() .'” could not be updated. See error log.');
355
+					Log::addConfigurationLog('Module '.$this->module->getName().' : Geo Analysis ID “'.$ga->getId().'” could not be updated. See error log.');
358 356
 				}
359 357
             }
360 358
         } else {
@@ -366,7 +364,7 @@  discard block
 block discarded – undo
366 364
 				$use_flags,
367 365
 				$gen_details
368 366
 			);
369
-			if($ga) {
367
+			if ($ga) {
370 368
 				FlashMessages::addMessage(I18N::translate('The geographical dispersion analysis “%s” has been successfully added.', $ga->getTitle()), 'success');
371 369
 				Log::addConfigurationLog('Module '.$this->module->getName().' : Geo Analysis ID “'.$ga->getId().'” has been added.');
372 370
 				$success = true;
@@ -377,16 +375,16 @@  discard block
 block discarded – undo
377 375
 			}
378 376
         }
379 377
         
380
-        $redirection_url = 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig&ged=' . $wt_tree->getNameUrl();
381
-        if(!$success) {			
382
-            if($ga) {
383
-                $redirection_url = 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig@edit&ga_id='. $ga->getId() .'&ged=' . $wt_tree->getNameUrl();
378
+        $redirection_url = 'module.php?mod='.$this->module->getName().'&mod_action=AdminConfig&ged='.$wt_tree->getNameUrl();
379
+        if (!$success) {			
380
+            if ($ga) {
381
+                $redirection_url = 'module.php?mod='.$this->module->getName().'&mod_action=AdminConfig@edit&ga_id='.$ga->getId().'&ged='.$wt_tree->getNameUrl();
384 382
             }
385 383
             else {
386
-                $redirection_url = 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig@add&ged=' . $wt_tree->getNameUrl();
384
+                $redirection_url = 'module.php?mod='.$this->module->getName().'&mod_action=AdminConfig@add&ged='.$wt_tree->getNameUrl();
387 385
             }
388 386
         }        
389
-        header('Location: ' . WT_BASE_URL . $redirection_url);
387
+        header('Location: '.WT_BASE_URL.$redirection_url);
390 388
         
391 389
     }
392 390
      
@@ -416,7 +414,7 @@  discard block
 block discarded – undo
416 414
             ');
417 415
         
418 416
         $data = new ViewBag();
419
-        if($ga) {
417
+        if ($ga) {
420 418
             $controller->setPageTitle(I18N::translate('Edit the geographical dispersion analysis'));
421 419
             $data->set('geo_analysis', $ga);
422 420
         } else {
@@ -424,9 +422,9 @@  discard block
 block discarded – undo
424 422
         }
425 423
         
426 424
         $data->set('title', $controller->getPageTitle());
427
-        $data->set('admin_config_url', 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig&ged=' . $wt_tree->getNameUrl());
425
+        $data->set('admin_config_url', 'module.php?mod='.$this->module->getName().'&mod_action=AdminConfig&ged='.$wt_tree->getNameUrl());
428 426
         $data->set('module_title', $this->module->getTitle());
429
-        $data->set('save_url', 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig@save&ged=' . $wt_tree->getNameUrl());
427
+        $data->set('save_url', 'module.php?mod='.$this->module->getName().'&mod_action=AdminConfig@save&ged='.$wt_tree->getNameUrl());
430 428
         $data->set('places_hierarchy', $this->provider->getPlacesHierarchy());
431 429
     
432 430
         $map_list = array_map(
@@ -439,7 +437,7 @@  discard block
 block discarded – undo
439 437
         $data->set('map_list', $map_list);
440 438
     
441 439
         $gen_details = array(0 => I18N::translate('All'));
442
-        for($i = 1; $i <= 10 ; $i++) $gen_details[$i] = $i;
440
+        for ($i = 1; $i <= 10; $i++) $gen_details[$i] = $i;
443 441
         $data->set('generation_details', $gen_details);
444 442
     
445 443
         ViewFactory::make('GeoAnalysisEdit', $this, $controller, $data)->render();
Please login to merge, or discard this patch.
Braces   +14 added lines, -13 removed lines patch added patch discarded remove patch
@@ -78,7 +78,9 @@  discard block
 block discarded – undo
78 78
         
79 79
         $other_trees = array();
80 80
         foreach (Tree::getAll() as $tree) {
81
-            if($tree->getTreeId() != $wt_tree->getTreeId()) $other_trees[] = $tree;
81
+            if($tree->getTreeId() != $wt_tree->getTreeId()) {
82
+            	$other_trees[] = $tree;
83
+            }
82 84
         }      
83 85
         $data->set('other_trees', $other_trees);
84 86
         
@@ -177,7 +179,9 @@  discard block
 block discarded – undo
177 179
         
178 180
         // Generate an AJAX/JSON response for datatables to load a block of rows
179 181
         $search = Filter::postArray('search');
180
-        if($search) $search = $search['value'];
182
+        if($search) {
183
+        	$search = $search['value'];
184
+        }
181 185
         $start  = Filter::postInteger('start');
182 186
         $length = Filter::postInteger('length');
183 187
         $order  = Filter::postArray('order');
@@ -263,8 +267,7 @@  discard block
 block discarded – undo
263 267
     		            $datum[7] .= $top_level;
264 268
     		        }
265 269
     		        $datum[7] .= '</span>';
266
-		        }
267
-		        else {
270
+		        } else {
268 271
 		            $datum[6] = I18N::translate('Error when loading map.');
269 272
 		        }
270 273
 		    }
@@ -339,8 +342,7 @@  discard block
 block discarded – undo
339 342
                     if($use_map) {
340 343
                         $options->setMap(new OutlineMap($map_file));
341 344
                         $options->setMapLevel($map_top_level + 1);
342
-                    }
343
-                    else {
345
+                    } else {
344 346
                         $options->setMap(null);
345 347
                     }
346 348
                 }
@@ -351,8 +353,7 @@  discard block
 block discarded – undo
351 353
 					Log::addConfigurationLog('Module '.$this->module->getName().' : Geo Analysis ID “'.$res->getId().'” has been updated.');
352 354
 					$ga = $res;
353 355
 					$success = true;
354
-				}
355
-				else {
356
+				} else {
356 357
 					FlashMessages::addMessage(I18N::translate('An error occured while updating the geographical dispersion analysis “%s”', $ga->getTitle()), 'danger');
357 358
 					Log::addConfigurationLog('Module '.$this->module->getName().' : Geo Analysis ID “'. $ga->getId() .'” could not be updated. See error log.');
358 359
 				}
@@ -370,8 +371,7 @@  discard block
 block discarded – undo
370 371
 				FlashMessages::addMessage(I18N::translate('The geographical dispersion analysis “%s” has been successfully added.', $ga->getTitle()), 'success');
371 372
 				Log::addConfigurationLog('Module '.$this->module->getName().' : Geo Analysis ID “'.$ga->getId().'” has been added.');
372 373
 				$success = true;
373
-			}
374
-			else {
374
+			} else {
375 375
 				FlashMessages::addMessage(I18N::translate('An error occured while adding the geographical dispersion analysis “%s”', $description), 'danger');
376 376
 				Log::addConfigurationLog('Module '.$this->module->getName().' : Geo Analysis “'.$description.'” could not be added. See error log.');
377 377
 			}
@@ -381,8 +381,7 @@  discard block
 block discarded – undo
381 381
         if(!$success) {			
382 382
             if($ga) {
383 383
                 $redirection_url = 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig@edit&ga_id='. $ga->getId() .'&ged=' . $wt_tree->getNameUrl();
384
-            }
385
-            else {
384
+            } else {
386 385
                 $redirection_url = 'module.php?mod=' . $this->module->getName() . '&mod_action=AdminConfig@add&ged=' . $wt_tree->getNameUrl();
387 386
             }
388 387
         }        
@@ -439,7 +438,9 @@  discard block
 block discarded – undo
439 438
         $data->set('map_list', $map_list);
440 439
     
441 440
         $gen_details = array(0 => I18N::translate('All'));
442
-        for($i = 1; $i <= 10 ; $i++) $gen_details[$i] = $i;
441
+        for($i = 1; $i <= 10 ; $i++) {
442
+        	$gen_details[$i] = $i;
443
+        }
443 444
         $data->set('generation_details', $gen_details);
444 445
     
445 446
         ViewFactory::make('GeoAnalysisEdit', $this, $controller, $data)->render();
Please login to merge, or discard this patch.
src/Webtrees/Module/PatronymicLineage/Model/LineageRootNode.php 1 patch
Indentation   +58 added lines, -58 removed lines patch added patch discarded remove patch
@@ -24,68 +24,68 @@
 block discarded – undo
24 24
 class LineageRootNode extends LineageNode
25 25
 {
26 26
     
27
-    /**
28
-     * @var Collection $places Places for the lineage node
29
-     */
30
-    private $places;
27
+	/**
28
+	 * @var Collection $places Places for the lineage node
29
+	 */
30
+	private $places;
31 31
    
32
-    /**
33
-     * @var int $nb_children Number of node childs
34
-     */
35
-    private $nb_children;
32
+	/**
33
+	 * @var int $nb_children Number of node childs
34
+	 */
35
+	private $nb_children;
36 36
   
37
-    /**
38
-     * Constructor for LineageRootNode
39
-     *
40
-     * @param Individual|null $node_indi
41
-     */
42
-    public function __construct(?Individual $node_indi = null)
43
-    {
44
-        parent::__construct($node_indi, $this);
45
-        $this->places = new Collection();
46
-        $this->nb_children = 0;
47
-    }
37
+	/**
38
+	 * Constructor for LineageRootNode
39
+	 *
40
+	 * @param Individual|null $node_indi
41
+	 */
42
+	public function __construct(?Individual $node_indi = null)
43
+	{
44
+		parent::__construct($node_indi, $this);
45
+		$this->places = new Collection();
46
+		$this->nb_children = 0;
47
+	}
48 48
    
49
-    /**
50
-     * Adds a place to the list of lineage's place
51
-     *
52
-     * @param Place $place
53
-     */
54
-    public function addPlace(Place $place): void
55
-    {
56
-        $place_name = $place->gedcomName();
57
-        if (mb_strlen($place_name) > 0) {
58
-            $this->places->put($place_name, $this->places->get($place_name, 0) + 1);
59
-        }
60
-    }
49
+	/**
50
+	 * Adds a place to the list of lineage's place
51
+	 *
52
+	 * @param Place $place
53
+	 */
54
+	public function addPlace(Place $place): void
55
+	{
56
+		$place_name = $place->gedcomName();
57
+		if (mb_strlen($place_name) > 0) {
58
+			$this->places->put($place_name, $this->places->get($place_name, 0) + 1);
59
+		}
60
+	}
61 61
     
62
-    /**
63
-     * Returns the number of child nodes.
64
-     * This number is more to be used as indication rather than an accurate one.
65
-     *
66
-     * @return int
67
-     */
68
-    public function numberChildNodes(): int
69
-    {
70
-        return $this->nb_children;
71
-    }
62
+	/**
63
+	 * Returns the number of child nodes.
64
+	 * This number is more to be used as indication rather than an accurate one.
65
+	 *
66
+	 * @return int
67
+	 */
68
+	public function numberChildNodes(): int
69
+	{
70
+		return $this->nb_children;
71
+	}
72 72
    
73
-    /**
74
-     * Increments the number of child nodes by one
75
-     *
76
-     */
77
-    public function incrementChildNodes(): void
78
-    {
79
-        $this->nb_children++;
80
-    }
73
+	/**
74
+	 * Increments the number of child nodes by one
75
+	 *
76
+	 */
77
+	public function incrementChildNodes(): void
78
+	{
79
+		$this->nb_children++;
80
+	}
81 81
    
82
-    /**
83
-     * Returns the list of place for the lineage
84
-     *
85
-     * @return Collection
86
-     */
87
-    public function places(): Collection
88
-    {
89
-        return $this->places;
90
-    }
82
+	/**
83
+	 * Returns the list of place for the lineage
84
+	 *
85
+	 * @return Collection
86
+	 */
87
+	public function places(): Collection
88
+	{
89
+		return $this->places;
90
+	}
91 91
 }
Please login to merge, or discard this patch.
src/Webtrees/Module/PatronymicLineage/Model/LineageNode.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -68,7 +68,7 @@  discard block
 block discarded – undo
68 68
     public function addFamily(Family $fams): object
69 69
     {
70 70
         if (!$this->linked_fams->has($fams->xref())) {
71
-            $this->linked_fams->put($fams->xref(), (object) [
71
+            $this->linked_fams->put($fams->xref(), (object)[
72 72
                 'family'   =>  $fams,
73 73
                 'children' =>  new Collection()
74 74
             ]);
@@ -135,6 +135,6 @@  discard block
 block discarded – undo
135 135
      */
136 136
     public function hasFollowUpSurname(): bool
137 137
     {
138
-        return mb_strlen($this->followUpSurname()) > 0 ;
138
+        return mb_strlen($this->followUpSurname()) > 0;
139 139
     }
140 140
 }
Please login to merge, or discard this patch.
Indentation   +113 added lines, -113 removed lines patch added patch discarded remove patch
@@ -25,117 +25,117 @@
 block discarded – undo
25 25
 class LineageNode
26 26
 {
27 27
 
28
-    /**
29
-     * @var Collection $linked_fams Spouse families linked to the node
30
-     */
31
-    private $linked_fams;
32
-
33
-    /**
34
-     * @var ?Individual $node_indi Reference individual for the node
35
-     */
36
-    private $node_indi;
37
-
38
-    /**
39
-     * @var LineageRootNode $root_node Root node of the lineage
40
-     */
41
-    private $root_node;
42
-
43
-    /**
44
-     * @var ?string $alt_surname Linked surname, used to link to another lineage
45
-     */
46
-    private $alt_surname;
47
-
48
-    /**
49
-     * Constructor for Lineage node
50
-     *
51
-     * @param Individual $node_indi Main individual
52
-     * @param LineageRootNode $root_node Node of the lineage root
53
-     * @param null|string $alt_surname Follow-up surname
54
-     */
55
-    public function __construct(?Individual $node_indi = null, LineageRootNode $root_node, $alt_surname = null)
56
-    {
57
-        $this->node_indi = $node_indi;
58
-        $this->root_node = $root_node;
59
-        $this->alt_surname = $alt_surname;
60
-        $this->linked_fams = new Collection();
61
-    }
62
-
63
-    /**
64
-     * Add a spouse family to the node
65
-     *
66
-     * @param Family $fams
67
-     * @return stdClass
68
-     */
69
-    public function addFamily(Family $fams): object
70
-    {
71
-        if (!$this->linked_fams->has($fams->xref())) {
72
-            $this->linked_fams->put($fams->xref(), (object) [
73
-                'family'   =>  $fams,
74
-                'children' =>  new Collection()
75
-            ]);
76
-        }
77
-        return $this->linked_fams->get($fams->xref());
78
-    }
79
-
80
-    /**
81
-     * Add a child LineageNode to the node
82
-     *
83
-     * @param Family $fams
84
-     * @param LineageNode $child
85
-     */
86
-    public function addChild(Family $fams, LineageNode $child = null): void
87
-    {
88
-        $this->addFamily($fams)->children->push($child);
89
-        $this->root_node->incrementChildNodes();
90
-    }
91
-
92
-    /**
93
-     * Returns the node individual
94
-     *
95
-     * @return Individual|NULL
96
-     */
97
-    public function individual(): ?Individual
98
-    {
99
-        return $this->node_indi;
100
-    }
101
-
102
-    /**
103
-     * Returns the lineage root node individual
104
-     *
105
-     * @return LineageRootNode
106
-     */
107
-    public function rootNode(): LineageRootNode
108
-    {
109
-        return $this->root_node;
110
-    }
111
-
112
-    /**
113
-     * Returns the spouse families linked to the node
114
-     *
115
-     * @return Collection
116
-     */
117
-    public function families(): Collection
118
-    {
119
-        return $this->linked_fams;
120
-    }
121
-
122
-    /**
123
-     * Returns the follow-up surname
124
-     *
125
-     * @return string
126
-     */
127
-    public function followUpSurname(): string
128
-    {
129
-        return $this->alt_surname ?? '';
130
-    }
131
-
132
-    /**
133
-     * Indicates whether the node has a follow up surname
134
-     *
135
-     * @return boolean
136
-     */
137
-    public function hasFollowUpSurname(): bool
138
-    {
139
-        return mb_strlen($this->followUpSurname()) > 0 ;
140
-    }
28
+	/**
29
+	 * @var Collection $linked_fams Spouse families linked to the node
30
+	 */
31
+	private $linked_fams;
32
+
33
+	/**
34
+	 * @var ?Individual $node_indi Reference individual for the node
35
+	 */
36
+	private $node_indi;
37
+
38
+	/**
39
+	 * @var LineageRootNode $root_node Root node of the lineage
40
+	 */
41
+	private $root_node;
42
+
43
+	/**
44
+	 * @var ?string $alt_surname Linked surname, used to link to another lineage
45
+	 */
46
+	private $alt_surname;
47
+
48
+	/**
49
+	 * Constructor for Lineage node
50
+	 *
51
+	 * @param Individual $node_indi Main individual
52
+	 * @param LineageRootNode $root_node Node of the lineage root
53
+	 * @param null|string $alt_surname Follow-up surname
54
+	 */
55
+	public function __construct(?Individual $node_indi = null, LineageRootNode $root_node, $alt_surname = null)
56
+	{
57
+		$this->node_indi = $node_indi;
58
+		$this->root_node = $root_node;
59
+		$this->alt_surname = $alt_surname;
60
+		$this->linked_fams = new Collection();
61
+	}
62
+
63
+	/**
64
+	 * Add a spouse family to the node
65
+	 *
66
+	 * @param Family $fams
67
+	 * @return stdClass
68
+	 */
69
+	public function addFamily(Family $fams): object
70
+	{
71
+		if (!$this->linked_fams->has($fams->xref())) {
72
+			$this->linked_fams->put($fams->xref(), (object) [
73
+				'family'   =>  $fams,
74
+				'children' =>  new Collection()
75
+			]);
76
+		}
77
+		return $this->linked_fams->get($fams->xref());
78
+	}
79
+
80
+	/**
81
+	 * Add a child LineageNode to the node
82
+	 *
83
+	 * @param Family $fams
84
+	 * @param LineageNode $child
85
+	 */
86
+	public function addChild(Family $fams, LineageNode $child = null): void
87
+	{
88
+		$this->addFamily($fams)->children->push($child);
89
+		$this->root_node->incrementChildNodes();
90
+	}
91
+
92
+	/**
93
+	 * Returns the node individual
94
+	 *
95
+	 * @return Individual|NULL
96
+	 */
97
+	public function individual(): ?Individual
98
+	{
99
+		return $this->node_indi;
100
+	}
101
+
102
+	/**
103
+	 * Returns the lineage root node individual
104
+	 *
105
+	 * @return LineageRootNode
106
+	 */
107
+	public function rootNode(): LineageRootNode
108
+	{
109
+		return $this->root_node;
110
+	}
111
+
112
+	/**
113
+	 * Returns the spouse families linked to the node
114
+	 *
115
+	 * @return Collection
116
+	 */
117
+	public function families(): Collection
118
+	{
119
+		return $this->linked_fams;
120
+	}
121
+
122
+	/**
123
+	 * Returns the follow-up surname
124
+	 *
125
+	 * @return string
126
+	 */
127
+	public function followUpSurname(): string
128
+	{
129
+		return $this->alt_surname ?? '';
130
+	}
131
+
132
+	/**
133
+	 * Indicates whether the node has a follow up surname
134
+	 *
135
+	 * @return boolean
136
+	 */
137
+	public function hasFollowUpSurname(): bool
138
+	{
139
+		return mb_strlen($this->followUpSurname()) > 0 ;
140
+	}
141 141
 }
Please login to merge, or discard this patch.
src/Webtrees/Module/PatronymicLineage/Model/LineageBuilder.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -107,7 +107,7 @@
 block discarded – undo
107 107
             }
108 108
         }
109 109
       
110
-        return $root_lineages->sort(function (LineageRootNode $a, LineageRootNode $b) {
110
+        return $root_lineages->sort(function(LineageRootNode $a, LineageRootNode $b) {
111 111
 
112 112
             if ($a->numberChildNodes() == $b->numberChildNodes()) {
113 113
                 return 0;
Please login to merge, or discard this patch.
Indentation   +216 added lines, -216 removed lines patch added patch discarded remove patch
@@ -29,220 +29,220 @@
 block discarded – undo
29 29
 class LineageBuilder
30 30
 {
31 31
 
32
-    /**
33
-     * @var string $surname Reference surname
34
-     */
35
-    private $surname;
36
-
37
-    /**
38
-     * @var Tree $tree Reference tree
39
-     */
40
-    private $tree;
41
-
42
-    /**
43
-     * @var IndividualListModule $indilist_module
44
-     */
45
-    private $indilist_module;
46
-
47
-    /**
48
-     * @var Collection $used_indis Individuals already processed
49
-     */
50
-    private $used_indis;
51
-
52
-    /**
53
-     * Constructor for Lineage Builder
54
-     *
55
-     * @param string $surname Reference surname
56
-     * @param Tree $tree Gedcom tree
57
-     */
58
-    public function __construct($surname, Tree $tree, IndividualListModule $indilist_module)
59
-    {
60
-        $this->surname = $surname;
61
-        $this->tree = $tree;
62
-        $this->indilist_module = $indilist_module;
63
-        $this->used_indis = new Collection();
64
-    }
65
-
66
-    /**
67
-     * Build all patronymic lineages for the reference surname.
68
-     *
69
-     * @return Collection|NULL List of root patronymic lineages
70
-     */
71
-    public function buildLineages(): ?Collection
72
-    {
73
-        if ($this->indilist_module === null) {
74
-            return null;
75
-        }
76
-
77
-        $indis = $this->indilist_module->individuals($this->tree, $this->surname, '', '', false, false, I18N::locale());
78
-        //Warning - the IndividualListModule returns a clone of individuals objects. Cannot be used for object equality
79
-        if (count($indis) == 0) {
80
-            return null;
81
-        }
82
-
83
-        $root_lineages = new Collection();
84
-
85
-        foreach ($indis as $indi) {
86
-            /** @var Individual $indi */
87
-            if ($this->used_indis->get($indi->xref(), false) === false) {
88
-                $indi_first = $this->getLineageRootIndividual($indi);
89
-                if ($indi_first !== null) {
90
-                    // The root lineage needs to be recreated from the Factory, to retrieve the proper object
91
-                    $indi_first = Registry::individualFactory()->make($indi_first->xref(), $this->tree);
92
-                }
93
-                if ($indi_first === null) {
94
-                    continue;
95
-                }
96
-                $this->used_indis->put($indi_first->xref(), true);
97
-                if ($indi_first->canShow()) {
98
-                    //Check if the root individual has brothers and sisters, without parents
99
-                    $indi_first_child_family = $indi_first->childFamilies()->first();
100
-                    if ($indi_first_child_family !== null) {
101
-                        $root_node = new LineageRootNode(null);
102
-                        $root_node->addFamily($indi_first_child_family);
103
-                    } else {
104
-                        $root_node = new LineageRootNode($indi_first);
105
-                    }
106
-                    $root_node = $this->buildLineage($root_node);
107
-                    $root_lineages->add($root_node);
108
-                }
109
-            }
110
-        }
111
-
112
-        return $root_lineages->sort(function (LineageRootNode $a, LineageRootNode $b) {
113
-
114
-            if ($a->numberChildNodes() == $b->numberChildNodes()) {
115
-                return 0;
116
-            }
117
-            return ($a->numberChildNodes() > $b->numberChildNodes()) ? -1 : 1;
118
-        });
119
-    }
120
-
121
-    /**
122
-     * Retrieve the root individual, from any individual, by recursion.
123
-     * The Root individual is the individual without a father, or without a mother holding the same name.
124
-     *
125
-     * @param Individual $indi
126
-     * @return Individual|NULL Root individual
127
-     */
128
-    private function getLineageRootIndividual(Individual $indi): ?Individual
129
-    {
130
-        $child_families = $indi->childFamilies();
131
-        if ($this->used_indis->get($indi->xref(), false) !== false) {
132
-            return null;
133
-        }
134
-
135
-        foreach ($child_families as $child_family) {
136
-            /** @var Family $child_family */
137
-            $child_family->husband();
138
-            if (($husb = $child_family->husband()) !== null) {
139
-                if ($husb->isPendingAddition() && $husb->privatizeGedcom(Auth::PRIV_HIDE) == '') {
140
-                    return $indi;
141
-                }
142
-                return $this->getLineageRootIndividual($husb);
143
-            } elseif (($wife = $child_family->wife()) !== null) {
144
-                if (!($wife->isPendingAddition() && $wife->privatizeGedcom(Auth::PRIV_HIDE) == '')) {
145
-                    $indi_surname = $indi->getAllNames()[$indi->getPrimaryName()]['surname'];
146
-                    $wife_surname = $wife->getAllNames()[$wife->getPrimaryName()]['surname'];
147
-                    if (
148
-                        $indi->canShowName()
149
-                        && $wife->canShowName()
150
-                        && I18N::strcasecmp($indi_surname, $wife_surname) == 0
151
-                    ) {
152
-                            return $this->getLineageRootIndividual($wife);
153
-                    }
154
-                }
155
-                return $indi;
156
-            }
157
-        }
158
-        return $indi;
159
-    }
160
-
161
-    /**
162
-     * Computes descendent Lineage from a node.
163
-     * Uses recursion to build the lineage tree
164
-     *
165
-     * @param LineageNode $node
166
-     * @return LineageNode Computed lineage
167
-     */
168
-    private function buildLineage(LineageNode $node): LineageNode
169
-    {
170
-        $indi_surname = '';
171
-
172
-        $indi_node = $node->individual();
173
-        if ($indi_node !== null) {
174
-            if ($node->families()->count() == 0) {
175
-                foreach ($indi_node->spouseFamilies() as $spouse_family) {
176
-                    $node->addFamily($spouse_family);
177
-                }
178
-            }
179
-
180
-            $indi_surname = $indi_node->getAllNames()[$indi_node->getPrimaryName()]['surname'] ?? '';
181
-            $node->rootNode()->addPlace($indi_node->getBirthPlace());
182
-
183
-            //Tag the individual as used
184
-            $this->used_indis->put($indi_node->xref(), true);
185
-        }
186
-
187
-        foreach ($node->families() as $family_node) {
188
-            /** @var Family $spouse_family */
189
-            $spouse_family = $family_node->family;
190
-            $spouse_surname = '';
191
-            $spouse = null;
192
-            if (
193
-                $indi_node !== null &&
194
-                ($spouse = $spouse_family->spouse($indi_node)) !== null && $spouse->canShowName()
195
-            ) {
196
-                $spouse_surname = $spouse->getAllNames()[$spouse->getPrimaryName()]['surname'] ?? '';
197
-            }
198
-
199
-            $nb_children = $nb_natural = 0;
200
-
201
-            foreach ($spouse_family->children() as $child) {
202
-                if (!($child->isPendingAddition() && $child->privatizeGedcom(Auth::PRIV_HIDE) == '')) {
203
-                    $child_surname = $child->getAllNames()[$child->getPrimaryName()]['surname'] ?? '';
204
-
205
-                    $nb_children++;
206
-                    if ($indi_node !== null && $indi_node->sex() == 'F') { //If the root individual is the mother
207
-                        //Print only lineages of children with the same surname as their mother
208
-                        //(supposing they are natural children)
209
-                        if (
210
-                            $spouse === null ||
211
-                            ($spouse_surname !== '' && I18N::strcasecmp($child_surname, $spouse_surname) != 0)
212
-                        ) {
213
-                            if (I18N::strcasecmp($child_surname, $indi_surname) == 0) {
214
-                                $nb_natural++;
215
-                                $node_child = new LineageNode($child, $node->rootNode());
216
-                                $node_child = $this->buildLineage($node_child);
217
-                                $node->addChild($spouse_family, $node_child);
218
-                            }
219
-                        }
220
-                    } else { //If the root individual is the father
221
-                        $nb_natural++;
222
-                        //Print if the children does not bear the same name as his mother
223
-                        //(and different from his father)
224
-                        if (
225
-                            mb_strlen($child_surname) == 0 ||
226
-                            mb_strlen($indi_surname) == 0 || mb_strlen($spouse_surname) == 0 ||
227
-                            I18N::strcasecmp($child_surname, $indi_surname) == 0 ||
228
-                            I18N::strcasecmp($child_surname, $spouse_surname) != 0
229
-                        ) {
230
-                            $node_child = new LineageNode($child, $node->rootNode());
231
-                            $node_child = $this->buildLineage($node_child);
232
-                        } else {
233
-                            $node_child = new LineageNode($child, $node->rootNode(), $child_surname);
234
-                        }
235
-                        $node->addChild($spouse_family, $node_child);
236
-                    }
237
-                }
238
-            }
239
-
240
-            //Do not print other children
241
-            if (($nb_children - $nb_natural) > 0) {
242
-                $node->addChild($spouse_family, null);
243
-            }
244
-        }
245
-
246
-        return $node;
247
-    }
32
+	/**
33
+	 * @var string $surname Reference surname
34
+	 */
35
+	private $surname;
36
+
37
+	/**
38
+	 * @var Tree $tree Reference tree
39
+	 */
40
+	private $tree;
41
+
42
+	/**
43
+	 * @var IndividualListModule $indilist_module
44
+	 */
45
+	private $indilist_module;
46
+
47
+	/**
48
+	 * @var Collection $used_indis Individuals already processed
49
+	 */
50
+	private $used_indis;
51
+
52
+	/**
53
+	 * Constructor for Lineage Builder
54
+	 *
55
+	 * @param string $surname Reference surname
56
+	 * @param Tree $tree Gedcom tree
57
+	 */
58
+	public function __construct($surname, Tree $tree, IndividualListModule $indilist_module)
59
+	{
60
+		$this->surname = $surname;
61
+		$this->tree = $tree;
62
+		$this->indilist_module = $indilist_module;
63
+		$this->used_indis = new Collection();
64
+	}
65
+
66
+	/**
67
+	 * Build all patronymic lineages for the reference surname.
68
+	 *
69
+	 * @return Collection|NULL List of root patronymic lineages
70
+	 */
71
+	public function buildLineages(): ?Collection
72
+	{
73
+		if ($this->indilist_module === null) {
74
+			return null;
75
+		}
76
+
77
+		$indis = $this->indilist_module->individuals($this->tree, $this->surname, '', '', false, false, I18N::locale());
78
+		//Warning - the IndividualListModule returns a clone of individuals objects. Cannot be used for object equality
79
+		if (count($indis) == 0) {
80
+			return null;
81
+		}
82
+
83
+		$root_lineages = new Collection();
84
+
85
+		foreach ($indis as $indi) {
86
+			/** @var Individual $indi */
87
+			if ($this->used_indis->get($indi->xref(), false) === false) {
88
+				$indi_first = $this->getLineageRootIndividual($indi);
89
+				if ($indi_first !== null) {
90
+					// The root lineage needs to be recreated from the Factory, to retrieve the proper object
91
+					$indi_first = Registry::individualFactory()->make($indi_first->xref(), $this->tree);
92
+				}
93
+				if ($indi_first === null) {
94
+					continue;
95
+				}
96
+				$this->used_indis->put($indi_first->xref(), true);
97
+				if ($indi_first->canShow()) {
98
+					//Check if the root individual has brothers and sisters, without parents
99
+					$indi_first_child_family = $indi_first->childFamilies()->first();
100
+					if ($indi_first_child_family !== null) {
101
+						$root_node = new LineageRootNode(null);
102
+						$root_node->addFamily($indi_first_child_family);
103
+					} else {
104
+						$root_node = new LineageRootNode($indi_first);
105
+					}
106
+					$root_node = $this->buildLineage($root_node);
107
+					$root_lineages->add($root_node);
108
+				}
109
+			}
110
+		}
111
+
112
+		return $root_lineages->sort(function (LineageRootNode $a, LineageRootNode $b) {
113
+
114
+			if ($a->numberChildNodes() == $b->numberChildNodes()) {
115
+				return 0;
116
+			}
117
+			return ($a->numberChildNodes() > $b->numberChildNodes()) ? -1 : 1;
118
+		});
119
+	}
120
+
121
+	/**
122
+	 * Retrieve the root individual, from any individual, by recursion.
123
+	 * The Root individual is the individual without a father, or without a mother holding the same name.
124
+	 *
125
+	 * @param Individual $indi
126
+	 * @return Individual|NULL Root individual
127
+	 */
128
+	private function getLineageRootIndividual(Individual $indi): ?Individual
129
+	{
130
+		$child_families = $indi->childFamilies();
131
+		if ($this->used_indis->get($indi->xref(), false) !== false) {
132
+			return null;
133
+		}
134
+
135
+		foreach ($child_families as $child_family) {
136
+			/** @var Family $child_family */
137
+			$child_family->husband();
138
+			if (($husb = $child_family->husband()) !== null) {
139
+				if ($husb->isPendingAddition() && $husb->privatizeGedcom(Auth::PRIV_HIDE) == '') {
140
+					return $indi;
141
+				}
142
+				return $this->getLineageRootIndividual($husb);
143
+			} elseif (($wife = $child_family->wife()) !== null) {
144
+				if (!($wife->isPendingAddition() && $wife->privatizeGedcom(Auth::PRIV_HIDE) == '')) {
145
+					$indi_surname = $indi->getAllNames()[$indi->getPrimaryName()]['surname'];
146
+					$wife_surname = $wife->getAllNames()[$wife->getPrimaryName()]['surname'];
147
+					if (
148
+						$indi->canShowName()
149
+						&& $wife->canShowName()
150
+						&& I18N::strcasecmp($indi_surname, $wife_surname) == 0
151
+					) {
152
+							return $this->getLineageRootIndividual($wife);
153
+					}
154
+				}
155
+				return $indi;
156
+			}
157
+		}
158
+		return $indi;
159
+	}
160
+
161
+	/**
162
+	 * Computes descendent Lineage from a node.
163
+	 * Uses recursion to build the lineage tree
164
+	 *
165
+	 * @param LineageNode $node
166
+	 * @return LineageNode Computed lineage
167
+	 */
168
+	private function buildLineage(LineageNode $node): LineageNode
169
+	{
170
+		$indi_surname = '';
171
+
172
+		$indi_node = $node->individual();
173
+		if ($indi_node !== null) {
174
+			if ($node->families()->count() == 0) {
175
+				foreach ($indi_node->spouseFamilies() as $spouse_family) {
176
+					$node->addFamily($spouse_family);
177
+				}
178
+			}
179
+
180
+			$indi_surname = $indi_node->getAllNames()[$indi_node->getPrimaryName()]['surname'] ?? '';
181
+			$node->rootNode()->addPlace($indi_node->getBirthPlace());
182
+
183
+			//Tag the individual as used
184
+			$this->used_indis->put($indi_node->xref(), true);
185
+		}
186
+
187
+		foreach ($node->families() as $family_node) {
188
+			/** @var Family $spouse_family */
189
+			$spouse_family = $family_node->family;
190
+			$spouse_surname = '';
191
+			$spouse = null;
192
+			if (
193
+				$indi_node !== null &&
194
+				($spouse = $spouse_family->spouse($indi_node)) !== null && $spouse->canShowName()
195
+			) {
196
+				$spouse_surname = $spouse->getAllNames()[$spouse->getPrimaryName()]['surname'] ?? '';
197
+			}
198
+
199
+			$nb_children = $nb_natural = 0;
200
+
201
+			foreach ($spouse_family->children() as $child) {
202
+				if (!($child->isPendingAddition() && $child->privatizeGedcom(Auth::PRIV_HIDE) == '')) {
203
+					$child_surname = $child->getAllNames()[$child->getPrimaryName()]['surname'] ?? '';
204
+
205
+					$nb_children++;
206
+					if ($indi_node !== null && $indi_node->sex() == 'F') { //If the root individual is the mother
207
+						//Print only lineages of children with the same surname as their mother
208
+						//(supposing they are natural children)
209
+						if (
210
+							$spouse === null ||
211
+							($spouse_surname !== '' && I18N::strcasecmp($child_surname, $spouse_surname) != 0)
212
+						) {
213
+							if (I18N::strcasecmp($child_surname, $indi_surname) == 0) {
214
+								$nb_natural++;
215
+								$node_child = new LineageNode($child, $node->rootNode());
216
+								$node_child = $this->buildLineage($node_child);
217
+								$node->addChild($spouse_family, $node_child);
218
+							}
219
+						}
220
+					} else { //If the root individual is the father
221
+						$nb_natural++;
222
+						//Print if the children does not bear the same name as his mother
223
+						//(and different from his father)
224
+						if (
225
+							mb_strlen($child_surname) == 0 ||
226
+							mb_strlen($indi_surname) == 0 || mb_strlen($spouse_surname) == 0 ||
227
+							I18N::strcasecmp($child_surname, $indi_surname) == 0 ||
228
+							I18N::strcasecmp($child_surname, $spouse_surname) != 0
229
+						) {
230
+							$node_child = new LineageNode($child, $node->rootNode());
231
+							$node_child = $this->buildLineage($node_child);
232
+						} else {
233
+							$node_child = new LineageNode($child, $node->rootNode(), $child_surname);
234
+						}
235
+						$node->addChild($spouse_family, $node_child);
236
+					}
237
+				}
238
+			}
239
+
240
+			//Do not print other children
241
+			if (($nb_children - $nb_natural) > 0) {
242
+				$node->addChild($spouse_family, null);
243
+			}
244
+		}
245
+
246
+		return $node;
247
+	}
248 248
 }
Please login to merge, or discard this patch.
src/Webtrees/Module/AbstractModuleMaj.php 3 patches
Indentation   +72 added lines, -72 removed lines patch added patch discarded remove patch
@@ -26,89 +26,89 @@
 block discarded – undo
26 26
  */
27 27
 abstract class AbstractModuleMaj extends AbstractModule implements ModuleCustomInterface
28 28
 {    
29
-    use ModuleCustomTrait;
29
+	use ModuleCustomTrait;
30 30
     
31
-    /**
32
-     * {@inheritDoc}
33
-     * @see \Fisharebest\Webtrees\Module\AbstractModule::boot()
34
-     */
35
-    public function boot() : void
36
-    {
37
-        View::registerNamespace($this->name(), $this->resourcesFolder() . 'views/');
31
+	/**
32
+	 * {@inheritDoc}
33
+	 * @see \Fisharebest\Webtrees\Module\AbstractModule::boot()
34
+	 */
35
+	public function boot() : void
36
+	{
37
+		View::registerNamespace($this->name(), $this->resourcesFolder() . 'views/');
38 38
         
39
-        $this->loadRoutes(app(RouterContainer::class)->getMap());
40
-    }
39
+		$this->loadRoutes(app(RouterContainer::class)->getMap());
40
+	}
41 41
     
42
-    /**
43
-     * {@inheritDoc}
44
-     * @see \Fisharebest\Webtrees\Module\AbstractModule::resourcesFolder()
45
-     */
46
-    public function resourcesFolder(): string
47
-    {
48
-        return Webtrees::MODULES_DIR . trim($this->name(), '_') . '/resources/';
49
-    }
42
+	/**
43
+	 * {@inheritDoc}
44
+	 * @see \Fisharebest\Webtrees\Module\AbstractModule::resourcesFolder()
45
+	 */
46
+	public function resourcesFolder(): string
47
+	{
48
+		return Webtrees::MODULES_DIR . trim($this->name(), '_') . '/resources/';
49
+	}
50 50
     
51
-    /**
52
-     * {@inheritDoc}
53
-     * @see \Fisharebest\Webtrees\Module\ModuleCustomInterface::customModuleAuthorName()
54
-     */
55
-    public function customModuleAuthorName() : string
56
-    {
57
-        return 'Jonathan Jaubart';
58
-    }
51
+	/**
52
+	 * {@inheritDoc}
53
+	 * @see \Fisharebest\Webtrees\Module\ModuleCustomInterface::customModuleAuthorName()
54
+	 */
55
+	public function customModuleAuthorName() : string
56
+	{
57
+		return 'Jonathan Jaubart';
58
+	}
59 59
     
60
-    /**
61
-     * {@inheritDoc}
62
-     * @see \Fisharebest\Webtrees\Module\ModuleCustomInterface::customModuleSupportUrl()
63
-     */
64
-    public function customModuleSupportUrl() : string
65
-    {
66
-        return 'https://github.com/jon48/webtrees-lib';
67
-    }
60
+	/**
61
+	 * {@inheritDoc}
62
+	 * @see \Fisharebest\Webtrees\Module\ModuleCustomInterface::customModuleSupportUrl()
63
+	 */
64
+	public function customModuleSupportUrl() : string
65
+	{
66
+		return 'https://github.com/jon48/webtrees-lib';
67
+	}
68 68
     
69
-    /**
70
-     * {@inheritDoc}
71
-     * @see \Fisharebest\Webtrees\Module\ModuleCustomInterface::customTranslations()
72
-     */
73
-    public function customTranslations(string $language) : array
74
-    {
75
-        $translation_file = $this->resourcesFolder() . 'lang/' . $language . '/messages.php';
69
+	/**
70
+	 * {@inheritDoc}
71
+	 * @see \Fisharebest\Webtrees\Module\ModuleCustomInterface::customTranslations()
72
+	 */
73
+	public function customTranslations(string $language) : array
74
+	{
75
+		$translation_file = $this->resourcesFolder() . 'lang/' . $language . '/messages.php';
76 76
         
77
-        try {
78
-            $translation  = new Translation($translation_file);
79
-            return $translation->asArray();
80
-        } catch (\Exception $e) { }
77
+		try {
78
+			$translation  = new Translation($translation_file);
79
+			return $translation->asArray();
80
+		} catch (\Exception $e) { }
81 81
         
82
-        return array();
83
-    }
82
+		return array();
83
+	}
84 84
     
85
-    /**
86
-     * Add module routes to webtrees route loader
87
-     * 
88
-     * @param Map $router
89
-     */
90
-    public abstract function loadRoutes(Map $router) : void;
85
+	/**
86
+	 * Add module routes to webtrees route loader
87
+	 * 
88
+	 * @param Map $router
89
+	 */
90
+	public abstract function loadRoutes(Map $router) : void;
91 91
     
92
-    /**
93
-     * Returns the URL of the module specific stylesheets.
94
-     * It will look for a CSS file matching the theme name (e.g. xenea.min.css),
95
-     * and fallback to default.min.css if none are found
96
-     * 
97
-     * @return string
98
-     */
99
-    public function moduleCssUrl() : string
100
-    {
101
-        /** @var ModuleThemeInterface $theme */
102
-        $theme = app(ModuleThemeInterface::class);
103
-        $css_file = $this->resourcesFolder() . 'css/' . $theme->name() . '.min.css';
92
+	/**
93
+	 * Returns the URL of the module specific stylesheets.
94
+	 * It will look for a CSS file matching the theme name (e.g. xenea.min.css),
95
+	 * and fallback to default.min.css if none are found
96
+	 * 
97
+	 * @return string
98
+	 */
99
+	public function moduleCssUrl() : string
100
+	{
101
+		/** @var ModuleThemeInterface $theme */
102
+		$theme = app(ModuleThemeInterface::class);
103
+		$css_file = $this->resourcesFolder() . 'css/' . $theme->name() . '.min.css';
104 104
         
105
-        if(file_exists($css_file)) {
106
-            return $this->assetUrl('css/' . $theme->name() . '.min.css');
107
-        }
108
-        else {
109
-            return $this->assetUrl('css/default.min.css');
110
-        }
111
-    }
105
+		if(file_exists($css_file)) {
106
+			return $this->assetUrl('css/' . $theme->name() . '.min.css');
107
+		}
108
+		else {
109
+			return $this->assetUrl('css/default.min.css');
110
+		}
111
+	}
112 112
     
113 113
 }
114 114
  
115 115
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -34,7 +34,7 @@  discard block
 block discarded – undo
34 34
      */
35 35
     public function boot() : void
36 36
     {
37
-        View::registerNamespace($this->name(), $this->resourcesFolder() . 'views/');
37
+        View::registerNamespace($this->name(), $this->resourcesFolder().'views/');
38 38
         
39 39
         $this->loadRoutes(app(RouterContainer::class)->getMap());
40 40
     }
@@ -45,7 +45,7 @@  discard block
 block discarded – undo
45 45
      */
46 46
     public function resourcesFolder(): string
47 47
     {
48
-        return Webtrees::MODULES_DIR . trim($this->name(), '_') . '/resources/';
48
+        return Webtrees::MODULES_DIR.trim($this->name(), '_').'/resources/';
49 49
     }
50 50
     
51 51
     /**
@@ -72,7 +72,7 @@  discard block
 block discarded – undo
72 72
      */
73 73
     public function customTranslations(string $language) : array
74 74
     {
75
-        $translation_file = $this->resourcesFolder() . 'lang/' . $language . '/messages.php';
75
+        $translation_file = $this->resourcesFolder().'lang/'.$language.'/messages.php';
76 76
         
77 77
         try {
78 78
             $translation  = new Translation($translation_file);
@@ -100,10 +100,10 @@  discard block
 block discarded – undo
100 100
     {
101 101
         /** @var ModuleThemeInterface $theme */
102 102
         $theme = app(ModuleThemeInterface::class);
103
-        $css_file = $this->resourcesFolder() . 'css/' . $theme->name() . '.min.css';
103
+        $css_file = $this->resourcesFolder().'css/'.$theme->name().'.min.css';
104 104
         
105
-        if(file_exists($css_file)) {
106
-            return $this->assetUrl('css/' . $theme->name() . '.min.css');
105
+        if (file_exists($css_file)) {
106
+            return $this->assetUrl('css/'.$theme->name().'.min.css');
107 107
         }
108 108
         else {
109 109
             return $this->assetUrl('css/default.min.css');
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -104,8 +104,7 @@
 block discarded – undo
104 104
         
105 105
         if(file_exists($css_file)) {
106 106
             return $this->assetUrl('css/' . $theme->name() . '.min.css');
107
-        }
108
-        else {
107
+        } else {
109 108
             return $this->assetUrl('css/default.min.css');
110 109
         }
111 110
     }
Please login to merge, or discard this patch.