Passed
Push — feature/code-analysis ( 00c5b4...e321b8 )
by Jonathan
13:27
created
app/Module/PatronymicLineage/Http/RequestHandlers/SurnamesList.php 2 patches
Indentation   +58 added lines, -58 removed lines patch added patch discarded remove patch
@@ -30,70 +30,70 @@
 block discarded – undo
30 30
  */
31 31
 class SurnamesList implements RequestHandlerInterface
32 32
 {
33
-    use ViewResponseTrait;
33
+	use ViewResponseTrait;
34 34
 
35
-    private ?PatronymicLineageModule $module;
35
+	private ?PatronymicLineageModule $module;
36 36
 
37
-    /**
38
-     * Constructor for SurnamesList Request Handler
39
-     *
40
-     * @param ModuleService $module_service
41
-     */
42
-    public function __construct(ModuleService $module_service)
43
-    {
44
-        $this->module = $module_service->findByInterface(PatronymicLineageModule::class)->first();
45
-    }
37
+	/**
38
+	 * Constructor for SurnamesList Request Handler
39
+	 *
40
+	 * @param ModuleService $module_service
41
+	 */
42
+	public function __construct(ModuleService $module_service)
43
+	{
44
+		$this->module = $module_service->findByInterface(PatronymicLineageModule::class)->first();
45
+	}
46 46
 
47
-    /**
48
-     * {@inheritDoc}
49
-     * @see \Psr\Http\Server\RequestHandlerInterface::handle()
50
-     */
51
-    public function handle(ServerRequestInterface $request): ResponseInterface
52
-    {
53
-        if ($this->module === null) {
54
-            throw new HttpNotFoundException(I18N::translate('The attached module could not be found.'));
55
-        }
47
+	/**
48
+	 * {@inheritDoc}
49
+	 * @see \Psr\Http\Server\RequestHandlerInterface::handle()
50
+	 */
51
+	public function handle(ServerRequestInterface $request): ResponseInterface
52
+	{
53
+		if ($this->module === null) {
54
+			throw new HttpNotFoundException(I18N::translate('The attached module could not be found.'));
55
+		}
56 56
 
57
-        $tree = Validator::attributes($request)->tree();
58
-        $initial = Validator::attributes($request)->string('alpha', '');
57
+		$tree = Validator::attributes($request)->tree();
58
+		$initial = Validator::attributes($request)->string('alpha', '');
59 59
 
60
-        $surname_data     = $this->module->surnameData($tree, false, false);
61
-        $all_surnames     = $this->module->allSurnames($surname_data);
62
-        $initials_list = array_filter(
63
-            $this->module->surnameInitials($surname_data),
64
-            static fn (string $x): bool => $x !== '@' && $x !== ',',
65
-            ARRAY_FILTER_USE_KEY
66
-        );
60
+		$surname_data     = $this->module->surnameData($tree, false, false);
61
+		$all_surnames     = $this->module->allSurnames($surname_data);
62
+		$initials_list = array_filter(
63
+			$this->module->surnameInitials($surname_data),
64
+			static fn (string $x): bool => $x !== '@' && $x !== ',',
65
+			ARRAY_FILTER_USE_KEY
66
+		);
67 67
 
68
-        $show_all = Validator::queryParams($request)->string('show_all', 'no') === 'yes';
68
+		$show_all = Validator::queryParams($request)->string('show_all', 'no') === 'yes';
69 69
 
70
-        if ($show_all) {
71
-            $title = I18N::translate('Patronymic Lineages') . ' — ' . I18N::translate('All');
72
-            $surnames = array_filter(
73
-                $all_surnames,
74
-                static fn (string $x): bool => $x !== '' && $x !== Individual::NOMEN_NESCIO,
75
-                ARRAY_FILTER_USE_KEY
76
-            );
77
-        } elseif (array_key_exists($initial, $initials_list)) {
78
-            $title = I18N::translate('Patronymic Lineages') . ' — ' . $initial;
79
-            $surnames = array_filter(
80
-                $all_surnames,
81
-                static fn (string $x): bool => I18N::language()->initialLetter($x) === $initial,
82
-                ARRAY_FILTER_USE_KEY
83
-            );
84
-        } else {
85
-            $title =  I18N::translate('Patronymic Lineages');
86
-            $surnames = [];
87
-        }
70
+		if ($show_all) {
71
+			$title = I18N::translate('Patronymic Lineages') . ' — ' . I18N::translate('All');
72
+			$surnames = array_filter(
73
+				$all_surnames,
74
+				static fn (string $x): bool => $x !== '' && $x !== Individual::NOMEN_NESCIO,
75
+				ARRAY_FILTER_USE_KEY
76
+			);
77
+		} elseif (array_key_exists($initial, $initials_list)) {
78
+			$title = I18N::translate('Patronymic Lineages') . ' — ' . $initial;
79
+			$surnames = array_filter(
80
+				$all_surnames,
81
+				static fn (string $x): bool => I18N::language()->initialLetter($x) === $initial,
82
+				ARRAY_FILTER_USE_KEY
83
+			);
84
+		} else {
85
+			$title =  I18N::translate('Patronymic Lineages');
86
+			$surnames = [];
87
+		}
88 88
 
89
-        return $this->viewResponse($this->module->name() . '::surnames-page', [
90
-            'title'         =>  $title,
91
-            'module'        =>  $this->module,
92
-            'tree'          =>  $tree,
93
-            'initials_list' =>  $initials_list,
94
-            'initial'       =>  $initial,
95
-            'show_all'      =>  $show_all ? 'yes' : 'no',
96
-            'surnames'      =>  $surnames
97
-        ]);
98
-    }
89
+		return $this->viewResponse($this->module->name() . '::surnames-page', [
90
+			'title'         =>  $title,
91
+			'module'        =>  $this->module,
92
+			'tree'          =>  $tree,
93
+			'initials_list' =>  $initials_list,
94
+			'initial'       =>  $initial,
95
+			'show_all'      =>  $show_all ? 'yes' : 'no',
96
+			'surnames'      =>  $surnames
97
+		]);
98
+	}
99 99
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -68,25 +68,25 @@
 block discarded – undo
68 68
         $show_all = Validator::queryParams($request)->string('show_all', 'no') === 'yes';
69 69
 
70 70
         if ($show_all) {
71
-            $title = I18N::translate('Patronymic Lineages') . ' — ' . I18N::translate('All');
71
+            $title = I18N::translate('Patronymic Lineages').' — '.I18N::translate('All');
72 72
             $surnames = array_filter(
73 73
                 $all_surnames,
74 74
                 static fn (string $x): bool => $x !== '' && $x !== Individual::NOMEN_NESCIO,
75 75
                 ARRAY_FILTER_USE_KEY
76 76
             );
77 77
         } elseif (array_key_exists($initial, $initials_list)) {
78
-            $title = I18N::translate('Patronymic Lineages') . ' — ' . $initial;
78
+            $title = I18N::translate('Patronymic Lineages').' — '.$initial;
79 79
             $surnames = array_filter(
80 80
                 $all_surnames,
81 81
                 static fn (string $x): bool => I18N::language()->initialLetter($x) === $initial,
82 82
                 ARRAY_FILTER_USE_KEY
83 83
             );
84 84
         } else {
85
-            $title =  I18N::translate('Patronymic Lineages');
85
+            $title = I18N::translate('Patronymic Lineages');
86 86
             $surnames = [];
87 87
         }
88 88
 
89
-        return $this->viewResponse($this->module->name() . '::surnames-page', [
89
+        return $this->viewResponse($this->module->name().'::surnames-page', [
90 90
             'title'         =>  $title,
91 91
             'module'        =>  $this->module,
92 92
             'tree'          =>  $tree,
Please login to merge, or discard this patch.
app/Module/PatronymicLineage/Http/RequestHandlers/LineagesPage.php 2 patches
Indentation   +71 added lines, -71 removed lines patch added patch discarded remove patch
@@ -32,75 +32,75 @@
 block discarded – undo
32 32
  */
33 33
 class LineagesPage implements RequestHandlerInterface
34 34
 {
35
-    use ViewResponseTrait;
36
-
37
-    /**
38
-     * @var PatronymicLineageModule|null $module
39
-     */
40
-    private $module;
41
-
42
-    /**
43
-     * Constructor for LineagesPage Request handler
44
-     *
45
-     * @param ModuleService $module_service
46
-     */
47
-    public function __construct(ModuleService $module_service)
48
-    {
49
-        $this->module = $module_service->findByInterface(PatronymicLineageModule::class)->first();
50
-    }
51
-
52
-    /**
53
-     * {@inheritDoc}
54
-     * @see \Psr\Http\Server\RequestHandlerInterface::handle()
55
-     */
56
-    public function handle(ServerRequestInterface $request): ResponseInterface
57
-    {
58
-        if ($this->module === null) {
59
-            throw new HttpNotFoundException(I18N::translate('The attached module could not be found.'));
60
-        }
61
-
62
-        $tree = Validator::attributes($request)->tree();
63
-        $surname_attr = Validator::attributes($request)->string('surname', '');
64
-        $surname = I18N::strtoupper(I18N::language()->normalize($surname_attr));
65
-
66
-        if ($surname_attr !== $surname) {
67
-            return Registry::responseFactory()
68
-                ->redirect(LineagesPage::class, ['tree' => $tree->name(), 'surname' => $surname]);
69
-        }
70
-
71
-        if ($surname === '' ||  $surname === Individual::NOMEN_NESCIO) {
72
-            return Registry::responseFactory()->redirect(SurnamesList::class, ['tree' => $tree->name()]);
73
-        }
74
-
75
-        $surn_initial = I18N::language()->initialLetter($surname);
76
-
77
-        $surname_data     = $this->module->surnameData($tree, false, false);
78
-        $all_surnames     = $this->module->allSurnames($surname_data);
79
-        $initials_list = array_filter(
80
-            $this->module->surnameInitials($surname_data),
81
-            static fn (string $x): bool => $x !== '@' && $x !== ',',
82
-            ARRAY_FILTER_USE_KEY
83
-        );
84
-
85
-        $surname_variants = array_keys($all_surnames[$surname] ?? [$surname => $surname]);
86
-        uasort($surname_variants, I18N::comparator());
87
-        $surname_legend = implode('/', $surname_variants);
88
-
89
-        $title = I18N::translate('Patronymic Lineages') . ' — ' . $surname_legend;
90
-
91
-        $lineages = app()->make(LineageBuilder::class, ['surname' => $surname])->buildLineages();
92
-
93
-        return $this->viewResponse($this->module->name() . '::lineages-page', [
94
-            'title'         =>  $title,
95
-            'module'        =>  $this->module,
96
-            'tree'          =>  $tree,
97
-            'initials_list' =>  $initials_list,
98
-            'initial'       =>  $surn_initial,
99
-            'show_all'      =>  'no',
100
-            'surname'       =>  $surname,
101
-            'surname_legend' =>  $surname_legend,
102
-            'lineages'      =>  $lineages,
103
-            'nb_lineages'   =>  $lineages !== null ? $lineages->count() : 0
104
-        ]);
105
-    }
35
+	use ViewResponseTrait;
36
+
37
+	/**
38
+	 * @var PatronymicLineageModule|null $module
39
+	 */
40
+	private $module;
41
+
42
+	/**
43
+	 * Constructor for LineagesPage Request handler
44
+	 *
45
+	 * @param ModuleService $module_service
46
+	 */
47
+	public function __construct(ModuleService $module_service)
48
+	{
49
+		$this->module = $module_service->findByInterface(PatronymicLineageModule::class)->first();
50
+	}
51
+
52
+	/**
53
+	 * {@inheritDoc}
54
+	 * @see \Psr\Http\Server\RequestHandlerInterface::handle()
55
+	 */
56
+	public function handle(ServerRequestInterface $request): ResponseInterface
57
+	{
58
+		if ($this->module === null) {
59
+			throw new HttpNotFoundException(I18N::translate('The attached module could not be found.'));
60
+		}
61
+
62
+		$tree = Validator::attributes($request)->tree();
63
+		$surname_attr = Validator::attributes($request)->string('surname', '');
64
+		$surname = I18N::strtoupper(I18N::language()->normalize($surname_attr));
65
+
66
+		if ($surname_attr !== $surname) {
67
+			return Registry::responseFactory()
68
+				->redirect(LineagesPage::class, ['tree' => $tree->name(), 'surname' => $surname]);
69
+		}
70
+
71
+		if ($surname === '' ||  $surname === Individual::NOMEN_NESCIO) {
72
+			return Registry::responseFactory()->redirect(SurnamesList::class, ['tree' => $tree->name()]);
73
+		}
74
+
75
+		$surn_initial = I18N::language()->initialLetter($surname);
76
+
77
+		$surname_data     = $this->module->surnameData($tree, false, false);
78
+		$all_surnames     = $this->module->allSurnames($surname_data);
79
+		$initials_list = array_filter(
80
+			$this->module->surnameInitials($surname_data),
81
+			static fn (string $x): bool => $x !== '@' && $x !== ',',
82
+			ARRAY_FILTER_USE_KEY
83
+		);
84
+
85
+		$surname_variants = array_keys($all_surnames[$surname] ?? [$surname => $surname]);
86
+		uasort($surname_variants, I18N::comparator());
87
+		$surname_legend = implode('/', $surname_variants);
88
+
89
+		$title = I18N::translate('Patronymic Lineages') . ' — ' . $surname_legend;
90
+
91
+		$lineages = app()->make(LineageBuilder::class, ['surname' => $surname])->buildLineages();
92
+
93
+		return $this->viewResponse($this->module->name() . '::lineages-page', [
94
+			'title'         =>  $title,
95
+			'module'        =>  $this->module,
96
+			'tree'          =>  $tree,
97
+			'initials_list' =>  $initials_list,
98
+			'initial'       =>  $surn_initial,
99
+			'show_all'      =>  'no',
100
+			'surname'       =>  $surname,
101
+			'surname_legend' =>  $surname_legend,
102
+			'lineages'      =>  $lineages,
103
+			'nb_lineages'   =>  $lineages !== null ? $lineages->count() : 0
104
+		]);
105
+	}
106 106
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -68,7 +68,7 @@  discard block
 block discarded – undo
68 68
                 ->redirect(LineagesPage::class, ['tree' => $tree->name(), 'surname' => $surname]);
69 69
         }
70 70
 
71
-        if ($surname === '' ||  $surname === Individual::NOMEN_NESCIO) {
71
+        if ($surname === '' || $surname === Individual::NOMEN_NESCIO) {
72 72
             return Registry::responseFactory()->redirect(SurnamesList::class, ['tree' => $tree->name()]);
73 73
         }
74 74
 
@@ -86,11 +86,11 @@  discard block
 block discarded – undo
86 86
         uasort($surname_variants, I18N::comparator());
87 87
         $surname_legend = implode('/', $surname_variants);
88 88
 
89
-        $title = I18N::translate('Patronymic Lineages') . ' — ' . $surname_legend;
89
+        $title = I18N::translate('Patronymic Lineages').' — '.$surname_legend;
90 90
 
91 91
         $lineages = app()->make(LineageBuilder::class, ['surname' => $surname])->buildLineages();
92 92
 
93
-        return $this->viewResponse($this->module->name() . '::lineages-page', [
93
+        return $this->viewResponse($this->module->name().'::lineages-page', [
94 94
             'title'         =>  $title,
95 95
             'module'        =>  $this->module,
96 96
             'tree'          =>  $tree,
Please login to merge, or discard this patch.
app/Module/PatronymicLineage/PatronymicLineageModule.php 2 patches
Indentation   +172 added lines, -172 removed lines patch added patch discarded remove patch
@@ -39,177 +39,177 @@
 block discarded – undo
39 39
  * Display lineages of people with the same surname.
40 40
  */
41 41
 class PatronymicLineageModule extends IndividualListModule implements
42
-    ModuleMyArtJaubInterface,
43
-    ModuleListInterface,
44
-    ModuleGlobalInterface
42
+	ModuleMyArtJaubInterface,
43
+	ModuleListInterface,
44
+	ModuleGlobalInterface
45 45
 {
46
-    use ModuleMyArtJaubTrait;
47
-    use ModuleListTrait;
48
-    use ModuleGlobalTrait;
49
-
50
-     /**
51
-     * {@inheritDoc}
52
-     * @see \Fisharebest\Webtrees\Module\AbstractModule::title()
53
-     */
54
-    public function title(): string
55
-    {
56
-        return /* I18N: Name of the “Patronymic lineage” module */ I18N::translate('Patronymic Lineages');
57
-    }
58
-
59
-    /**
60
-     * {@inheritDoc}
61
-     * @see \Fisharebest\Webtrees\Module\AbstractModule::description()
62
-     */
63
-    public function description(): string
64
-    {
65
-        //phpcs:ignore Generic.Files.LineLength.TooLong
66
-        return /* I18N: Description of the “Patronymic lineage” module */ I18N::translate('Display lineages of people holding the same surname.');
67
-    }
68
-
69
-    /**
70
-     * {@inheritDoc}
71
-     * @see \MyArtJaub\Webtrees\Module\ModuleMyArtJaubInterface::loadRoutes()
72
-     */
73
-    public function loadRoutes(Map $router): void
74
-    {
75
-        $router->attach('', '', static function (Map $router): void {
76
-
77
-            $router->attach('', '/module-maj/lineages', static function (Map $router): void {
78
-
79
-                $router->attach('', '/Page', static function (Map $router): void {
80
-
81
-                    $router->get(SurnamesList::class, '/{tree}/list{/alpha}', SurnamesList::class);
82
-                    $router->get(LineagesPage::class, '/{tree}/lineage/{surname}', LineagesPage::class);
83
-                });
84
-            });
85
-        });
86
-    }
87
-
88
-    /**
89
-     * {@inheritDoc}
90
-     * @see \Fisharebest\Webtrees\Module\ModuleCustomInterface::customModuleVersion()
91
-     */
92
-    public function customModuleVersion(): string
93
-    {
94
-        return '2.1.18-v.1';
95
-    }
96
-
97
-    /**
98
-     * {@inheritDoc}
99
-     * @see \Fisharebest\Webtrees\Module\ModuleListInterface::listUrl()
100
-     *
101
-     * @param array<bool|int|string|array<mixed>|null> $parameters
102
-     */
103
-    public function listUrl(Tree $tree, array $parameters = []): string
104
-    {
105
-        $surname = $parameters['surname'] ?? null;
106
-        $surname = is_string($surname) ? $surname : null;
107
-
108
-        $request = app(ServerRequestInterface::class);
109
-
110
-        // If a surname is already in the query attribute, use it
111
-        if ($surname === null) {
112
-            $surname_attr =  Validator::attributes($request)->string('surname', '');
113
-            $surname_param =  Validator::queryParams($request)->string('surname', '');
114
-            $surname_body =  Validator::parsedBody($request)->string('surname', '');
115
-            $surname = $surname_attr !== '' ? $surname_attr : (
116
-                $surname_param !== '' ? $surname_param : (
117
-                $surname_body !== '' ? $surname_body : null
118
-            ));
119
-        }
120
-
121
-        // If nothing found, and on an individual page, use its name
122
-        $xref = Validator::attributes($request)->isXref()->string('xref', '');
123
-        if ($xref !== '') {
124
-            $individual = Registry::individualFactory()->make($xref, $tree);
125
-            if ($individual instanceof Individual && $individual->canShow()) {
126
-                $primary_name = $individual->getPrimaryName();
127
-                $surname ??= $individual->getAllNames()[$primary_name]['surn'] ?? null;
128
-            }
129
-        }
130
-
131
-        if (Str::length($surname ?? '') > 0 && $surname !== Individual::NOMEN_NESCIO) {
132
-            return route(LineagesPage::class, [
133
-                'tree'      =>  $tree->name(),
134
-                'surname'   =>  $surname
135
-            ] + $parameters);
136
-        }
137
-        return route(SurnamesList::class, ['tree'  =>  $tree->name() ] + $parameters);
138
-    }
139
-
140
-    /**
141
-     * {@inheritDoc}
142
-     * @see \Fisharebest\Webtrees\Module\ModuleListInterface::listMenuClass()
143
-     */
144
-    public function listMenuClass(): string
145
-    {
146
-        return 'menu-maj-patrolineage';
147
-    }
148
-
149
-    /**
150
-     * {@inheritDoc}
151
-     * @see \Fisharebest\Webtrees\Module\ModuleGlobalInterface::headContent()
152
-     */
153
-    public function headContent(): string
154
-    {
155
-        return '<link rel="stylesheet" href="' . e($this->moduleCssUrl()) . '">';
156
-    }
157
-
158
-    /**
159
-     * {@inheritDoc}
160
-     * @see \Fisharebest\Webtrees\Module\IndividualListModule::individuals()
161
-     *
162
-     * Implemented to set the visibility to public.
163
-     * This should probably be in a service, but this hack allows for reuse of mainstream code.
164
-     */
165
-    public function individuals(
166
-        Tree $tree,
167
-        array $surns_to_show,
168
-        string $galpha,
169
-        bool $marnm,
170
-        bool $fams
171
-    ): Collection {
172
-        return parent::individuals($tree, $surns_to_show, $galpha, $marnm, $fams);
173
-    }
174
-
175
-    /**
176
-     * {@inheritDoc}
177
-     * @see \Fisharebest\Webtrees\Module\IndividualListModule::surnameData()
178
-     *
179
-     * Implemented to set the visibility to public.
180
-     * This should probably be in a service, but this hack allows for reuse of mainstream code.
181
-     *
182
-     * @return array<object{n_surn:string,n_surname:string,total:int}>
183
-     */
184
-    public function surnameData(Tree $tree, bool $marnm, bool $fams): array
185
-    {
186
-        $reflectionMethod = new ReflectionMethod(IndividualListModule::class, 'surnameData');
187
-        $reflectionMethod->setAccessible(true);
188
-
189
-        return $reflectionMethod->invoke($this, $tree, $marnm, $fams);
190
-    }
191
-
192
-    /**
193
-     * {@inheritDoc}
194
-     * @see \Fisharebest\Webtrees\Module\IndividualListModule::allSurnames()
195
-     *
196
-     * Implemented to set the visibility to public.
197
-     * This should probably be in a service, but this hack allows for reuse of mainstream code.
198
-     */
199
-    public function allSurnames(array $surname_data): array
200
-    {
201
-        return parent::allSurnames($surname_data);
202
-    }
203
-
204
-    /**
205
-     * {@inheritDoc}
206
-     * @see \Fisharebest\Webtrees\Module\IndividualListModule::surnameInitials()
207
-     *
208
-     * Implemented to set the visibility to public.
209
-     * This should probably be in a service, but this hack allows for reuse of mainstream code.
210
-     */
211
-    public function surnameInitials(array $surname_data): array
212
-    {
213
-        return parent::surnameInitials($surname_data);
214
-    }
46
+	use ModuleMyArtJaubTrait;
47
+	use ModuleListTrait;
48
+	use ModuleGlobalTrait;
49
+
50
+	 /**
51
+	  * {@inheritDoc}
52
+	  * @see \Fisharebest\Webtrees\Module\AbstractModule::title()
53
+	  */
54
+	public function title(): string
55
+	{
56
+		return /* I18N: Name of the “Patronymic lineage” module */ I18N::translate('Patronymic Lineages');
57
+	}
58
+
59
+	/**
60
+	 * {@inheritDoc}
61
+	 * @see \Fisharebest\Webtrees\Module\AbstractModule::description()
62
+	 */
63
+	public function description(): string
64
+	{
65
+		//phpcs:ignore Generic.Files.LineLength.TooLong
66
+		return /* I18N: Description of the “Patronymic lineage” module */ I18N::translate('Display lineages of people holding the same surname.');
67
+	}
68
+
69
+	/**
70
+	 * {@inheritDoc}
71
+	 * @see \MyArtJaub\Webtrees\Module\ModuleMyArtJaubInterface::loadRoutes()
72
+	 */
73
+	public function loadRoutes(Map $router): void
74
+	{
75
+		$router->attach('', '', static function (Map $router): void {
76
+
77
+			$router->attach('', '/module-maj/lineages', static function (Map $router): void {
78
+
79
+				$router->attach('', '/Page', static function (Map $router): void {
80
+
81
+					$router->get(SurnamesList::class, '/{tree}/list{/alpha}', SurnamesList::class);
82
+					$router->get(LineagesPage::class, '/{tree}/lineage/{surname}', LineagesPage::class);
83
+				});
84
+			});
85
+		});
86
+	}
87
+
88
+	/**
89
+	 * {@inheritDoc}
90
+	 * @see \Fisharebest\Webtrees\Module\ModuleCustomInterface::customModuleVersion()
91
+	 */
92
+	public function customModuleVersion(): string
93
+	{
94
+		return '2.1.18-v.1';
95
+	}
96
+
97
+	/**
98
+	 * {@inheritDoc}
99
+	 * @see \Fisharebest\Webtrees\Module\ModuleListInterface::listUrl()
100
+	 *
101
+	 * @param array<bool|int|string|array<mixed>|null> $parameters
102
+	 */
103
+	public function listUrl(Tree $tree, array $parameters = []): string
104
+	{
105
+		$surname = $parameters['surname'] ?? null;
106
+		$surname = is_string($surname) ? $surname : null;
107
+
108
+		$request = app(ServerRequestInterface::class);
109
+
110
+		// If a surname is already in the query attribute, use it
111
+		if ($surname === null) {
112
+			$surname_attr =  Validator::attributes($request)->string('surname', '');
113
+			$surname_param =  Validator::queryParams($request)->string('surname', '');
114
+			$surname_body =  Validator::parsedBody($request)->string('surname', '');
115
+			$surname = $surname_attr !== '' ? $surname_attr : (
116
+				$surname_param !== '' ? $surname_param : (
117
+				$surname_body !== '' ? $surname_body : null
118
+			));
119
+		}
120
+
121
+		// If nothing found, and on an individual page, use its name
122
+		$xref = Validator::attributes($request)->isXref()->string('xref', '');
123
+		if ($xref !== '') {
124
+			$individual = Registry::individualFactory()->make($xref, $tree);
125
+			if ($individual instanceof Individual && $individual->canShow()) {
126
+				$primary_name = $individual->getPrimaryName();
127
+				$surname ??= $individual->getAllNames()[$primary_name]['surn'] ?? null;
128
+			}
129
+		}
130
+
131
+		if (Str::length($surname ?? '') > 0 && $surname !== Individual::NOMEN_NESCIO) {
132
+			return route(LineagesPage::class, [
133
+				'tree'      =>  $tree->name(),
134
+				'surname'   =>  $surname
135
+			] + $parameters);
136
+		}
137
+		return route(SurnamesList::class, ['tree'  =>  $tree->name() ] + $parameters);
138
+	}
139
+
140
+	/**
141
+	 * {@inheritDoc}
142
+	 * @see \Fisharebest\Webtrees\Module\ModuleListInterface::listMenuClass()
143
+	 */
144
+	public function listMenuClass(): string
145
+	{
146
+		return 'menu-maj-patrolineage';
147
+	}
148
+
149
+	/**
150
+	 * {@inheritDoc}
151
+	 * @see \Fisharebest\Webtrees\Module\ModuleGlobalInterface::headContent()
152
+	 */
153
+	public function headContent(): string
154
+	{
155
+		return '<link rel="stylesheet" href="' . e($this->moduleCssUrl()) . '">';
156
+	}
157
+
158
+	/**
159
+	 * {@inheritDoc}
160
+	 * @see \Fisharebest\Webtrees\Module\IndividualListModule::individuals()
161
+	 *
162
+	 * Implemented to set the visibility to public.
163
+	 * This should probably be in a service, but this hack allows for reuse of mainstream code.
164
+	 */
165
+	public function individuals(
166
+		Tree $tree,
167
+		array $surns_to_show,
168
+		string $galpha,
169
+		bool $marnm,
170
+		bool $fams
171
+	): Collection {
172
+		return parent::individuals($tree, $surns_to_show, $galpha, $marnm, $fams);
173
+	}
174
+
175
+	/**
176
+	 * {@inheritDoc}
177
+	 * @see \Fisharebest\Webtrees\Module\IndividualListModule::surnameData()
178
+	 *
179
+	 * Implemented to set the visibility to public.
180
+	 * This should probably be in a service, but this hack allows for reuse of mainstream code.
181
+	 *
182
+	 * @return array<object{n_surn:string,n_surname:string,total:int}>
183
+	 */
184
+	public function surnameData(Tree $tree, bool $marnm, bool $fams): array
185
+	{
186
+		$reflectionMethod = new ReflectionMethod(IndividualListModule::class, 'surnameData');
187
+		$reflectionMethod->setAccessible(true);
188
+
189
+		return $reflectionMethod->invoke($this, $tree, $marnm, $fams);
190
+	}
191
+
192
+	/**
193
+	 * {@inheritDoc}
194
+	 * @see \Fisharebest\Webtrees\Module\IndividualListModule::allSurnames()
195
+	 *
196
+	 * Implemented to set the visibility to public.
197
+	 * This should probably be in a service, but this hack allows for reuse of mainstream code.
198
+	 */
199
+	public function allSurnames(array $surname_data): array
200
+	{
201
+		return parent::allSurnames($surname_data);
202
+	}
203
+
204
+	/**
205
+	 * {@inheritDoc}
206
+	 * @see \Fisharebest\Webtrees\Module\IndividualListModule::surnameInitials()
207
+	 *
208
+	 * Implemented to set the visibility to public.
209
+	 * This should probably be in a service, but this hack allows for reuse of mainstream code.
210
+	 */
211
+	public function surnameInitials(array $surname_data): array
212
+	{
213
+		return parent::surnameInitials($surname_data);
214
+	}
215 215
 }
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -72,11 +72,11 @@  discard block
 block discarded – undo
72 72
      */
73 73
     public function loadRoutes(Map $router): void
74 74
     {
75
-        $router->attach('', '', static function (Map $router): void {
75
+        $router->attach('', '', static function(Map $router): void {
76 76
 
77
-            $router->attach('', '/module-maj/lineages', static function (Map $router): void {
77
+            $router->attach('', '/module-maj/lineages', static function(Map $router): void {
78 78
 
79
-                $router->attach('', '/Page', static function (Map $router): void {
79
+                $router->attach('', '/Page', static function(Map $router): void {
80 80
 
81 81
                     $router->get(SurnamesList::class, '/{tree}/list{/alpha}', SurnamesList::class);
82 82
                     $router->get(LineagesPage::class, '/{tree}/lineage/{surname}', LineagesPage::class);
@@ -109,9 +109,9 @@  discard block
 block discarded – undo
109 109
 
110 110
         // If a surname is already in the query attribute, use it
111 111
         if ($surname === null) {
112
-            $surname_attr =  Validator::attributes($request)->string('surname', '');
113
-            $surname_param =  Validator::queryParams($request)->string('surname', '');
114
-            $surname_body =  Validator::parsedBody($request)->string('surname', '');
112
+            $surname_attr = Validator::attributes($request)->string('surname', '');
113
+            $surname_param = Validator::queryParams($request)->string('surname', '');
114
+            $surname_body = Validator::parsedBody($request)->string('surname', '');
115 115
             $surname = $surname_attr !== '' ? $surname_attr : (
116 116
                 $surname_param !== '' ? $surname_param : (
117 117
                 $surname_body !== '' ? $surname_body : null
@@ -134,7 +134,7 @@  discard block
 block discarded – undo
134 134
                 'surname'   =>  $surname
135 135
             ] + $parameters);
136 136
         }
137
-        return route(SurnamesList::class, ['tree'  =>  $tree->name() ] + $parameters);
137
+        return route(SurnamesList::class, ['tree'  =>  $tree->name()] + $parameters);
138 138
     }
139 139
 
140 140
     /**
@@ -152,7 +152,7 @@  discard block
 block discarded – undo
152 152
      */
153 153
     public function headContent(): string
154 154
     {
155
-        return '<link rel="stylesheet" href="' . e($this->moduleCssUrl()) . '">';
155
+        return '<link rel="stylesheet" href="'.e($this->moduleCssUrl()).'">';
156 156
     }
157 157
 
158 158
     /**
Please login to merge, or discard this patch.
app/Module/PatronymicLineage/Model/LineageBuilder.php 1 patch
Indentation   +216 added lines, -216 removed lines patch added patch discarded remove patch
@@ -28,220 +28,220 @@
 block discarded – undo
28 28
  */
29 29
 class LineageBuilder
30 30
 {
31
-    private string $surname;
32
-    private Tree $tree;
33
-    private PatronymicLineageModule $patrolineage_module;
34
-
35
-    /**
36
-     * @var Collection<string, bool> $used_indis Individuals already processed
37
-     */
38
-    private Collection $used_indis;
39
-
40
-    /**
41
-     * Constructor for Lineage Builder
42
-     *
43
-     * @param string $surname Reference surname
44
-     * @param Tree $tree Gedcom tree
45
-     */
46
-    public function __construct(string $surname, Tree $tree, PatronymicLineageModule $patrolineage_module)
47
-    {
48
-        $this->surname = I18N::strtoupper(I18N::language()->normalize($surname));
49
-        $this->tree = $tree;
50
-        $this->patrolineage_module = $patrolineage_module;
51
-        $this->used_indis = new Collection();
52
-    }
53
-
54
-    /**
55
-     * Build all patronymic lineages for the reference surname.
56
-     *
57
-     * @return Collection<LineageRootNode>|NULL List of root patronymic lineages
58
-     */
59
-    public function buildLineages(): ?Collection
60
-    {
61
-        $surname_data = $this->patrolineage_module->surnameData($this->tree, false, false);
62
-        $all_surnames = $this->patrolineage_module->allSurnames($surname_data);
63
-        $surname_variants = array_keys($all_surnames[$this->surname] ?? []);
64
-
65
-        if (count($surname_variants) === 0) {
66
-            return null;
67
-        }
68
-
69
-        //Warning - the individuals method returns a clone of individuals objects. Cannot be used for object equality
70
-        $indis = $this->patrolineage_module->individuals(
71
-            $this->tree,
72
-            $surname_variants,
73
-            '',
74
-            false,
75
-            false
76
-        );
77
-
78
-        if (count($indis) === 0) {
79
-            return null;
80
-        }
81
-
82
-        $root_lineages = new Collection();
83
-
84
-        foreach ($indis as $indi) {
85
-            /** @var Individual $indi */
86
-            if ($this->used_indis->get($indi->xref(), false) === false) {
87
-                $indi_first = $this->getLineageRootIndividual($indi);
88
-                if ($indi_first !== null) {
89
-                    // The root lineage needs to be recreated from the Factory, to retrieve the proper object
90
-                    $indi_first = Registry::individualFactory()->make($indi_first->xref(), $this->tree);
91
-                }
92
-                if ($indi_first === null) {
93
-                    continue;
94
-                }
95
-                $this->used_indis->put($indi_first->xref(), true);
96
-                if ($indi_first->canShow()) {
97
-                    //Check if the root individual has brothers and sisters, without parents
98
-                    $indi_first_child_family = $indi_first->childFamilies()->first();
99
-                    if ($indi_first_child_family !== null) {
100
-                        $root_node = new LineageRootNode(null);
101
-                        $root_node->addFamily($indi_first_child_family);
102
-                    } else {
103
-                        $root_node = new LineageRootNode($indi_first);
104
-                    }
105
-                    $root_node = $this->buildLineage($root_node);
106
-                    $root_lineages->add($root_node);
107
-                }
108
-            }
109
-        }
110
-
111
-        return $root_lineages->sort(function (LineageRootNode $a, LineageRootNode $b) {
112
-            if ($a->numberChildNodes() === $b->numberChildNodes()) {
113
-                return 0;
114
-            }
115
-            return ($a->numberChildNodes() > $b->numberChildNodes()) ? -1 : 1;
116
-        })->values();
117
-    }
118
-
119
-    /**
120
-     * Retrieve the root individual, from any individual, by recursion.
121
-     * The Root individual is the individual without a father, or without a mother holding the same name.
122
-     *
123
-     * @param Individual $indi
124
-     * @return Individual|NULL Root individual
125
-     */
126
-    private function getLineageRootIndividual(Individual $indi): ?Individual
127
-    {
128
-        $child_families = $indi->childFamilies();
129
-        if ($this->used_indis->get($indi->xref(), false) !== false) {
130
-            return null;
131
-        }
132
-
133
-        foreach ($child_families as $child_family) {
134
-            /** @var Family $child_family */
135
-            $child_family->husband();
136
-            if (($husb = $child_family->husband()) !== null) {
137
-                if ($husb->isPendingAddition() && $husb->privatizeGedcom(Auth::PRIV_HIDE) === '') {
138
-                    return $indi;
139
-                }
140
-                return $this->getLineageRootIndividual($husb);
141
-            } elseif (($wife = $child_family->wife()) !== null) {
142
-                if (!($wife->isPendingAddition() && $wife->privatizeGedcom(Auth::PRIV_HIDE) === '')) {
143
-                    $indi_surname = $indi->getAllNames()[$indi->getPrimaryName()]['surname'];
144
-                    $wife_surname = $wife->getAllNames()[$wife->getPrimaryName()]['surname'];
145
-                    if (
146
-                        $indi->canShowName()
147
-                        && $wife->canShowName()
148
-                        && I18N::comparator()($indi_surname, $wife_surname) === 0
149
-                    ) {
150
-                            return $this->getLineageRootIndividual($wife);
151
-                    }
152
-                }
153
-                return $indi;
154
-            }
155
-        }
156
-        return $indi;
157
-    }
158
-
159
-    /**
160
-     * Computes descendent Lineage from a node.
161
-     * Uses recursion to build the lineage tree
162
-     *
163
-     * @param LineageNode $node
164
-     * @return LineageNode Computed lineage
165
-     */
166
-    private function buildLineage(LineageNode $node): LineageNode
167
-    {
168
-        $indi_surname = '';
169
-
170
-        $indi_node = $node->individual();
171
-        if ($indi_node !== null) {
172
-            if ($node->families()->count() === 0) {
173
-                foreach ($indi_node->spouseFamilies() as $spouse_family) {
174
-                    $node->addFamily($spouse_family);
175
-                }
176
-            }
177
-
178
-            $indi_surname = $indi_node->getAllNames()[$indi_node->getPrimaryName()]['surname'] ?? '';
179
-            $node->rootNode()->addPlace($indi_node->getBirthPlace());
180
-
181
-            //Tag the individual as used
182
-            $this->used_indis->put($indi_node->xref(), true);
183
-        }
184
-
185
-        foreach ($node->families() as $family_node) {
186
-            /** @var Family $spouse_family */
187
-            $spouse_family = $family_node->family;
188
-            $spouse_surname = '';
189
-            $spouse = null;
190
-            if (
191
-                $indi_node !== null &&
192
-                ($spouse = $spouse_family->spouse($indi_node)) !== null && $spouse->canShowName()
193
-            ) {
194
-                $spouse_surname = $spouse->getAllNames()[$spouse->getPrimaryName()]['surname'] ?? '';
195
-            }
196
-
197
-            $nb_children = $nb_natural = 0;
198
-
199
-            foreach ($spouse_family->children() as $child) {
200
-                if (!($child->isPendingAddition() && $child->privatizeGedcom(Auth::PRIV_HIDE) === '')) {
201
-                    $child_surname = $child->getAllNames()[$child->getPrimaryName()]['surname'] ?? '';
202
-
203
-                    $nb_children++;
204
-                    if ($indi_node !== null && $indi_node->sex() === 'F') { //If the root individual is the mother
205
-                        //Print only lineages of children with the same surname as their mother
206
-                        //(supposing they are natural children)
207
-                        /** @psalm-suppress RedundantCondition */
208
-                        if (
209
-                            $spouse === null ||
210
-                            ($spouse_surname !== '' && I18N::comparator()($child_surname, $spouse_surname) !== 0)
211
-                        ) {
212
-                            if (I18N::comparator()($child_surname, $indi_surname) === 0) {
213
-                                $nb_natural++;
214
-                                $node_child = new LineageNode($child, $node->rootNode());
215
-                                $node_child = $this->buildLineage($node_child);
216
-                                $node->addChild($spouse_family, $node_child);
217
-                            }
218
-                        }
219
-                    } else { //If the root individual is the father
220
-                        $nb_natural++;
221
-                        //Print if the children does not bear the same name as his mother
222
-                        //(and different from his father)
223
-                        if (
224
-                            mb_strlen($child_surname) === 0 ||
225
-                            mb_strlen($indi_surname) === 0 || mb_strlen($spouse_surname) === 0 ||
226
-                            I18N::comparator()($child_surname, $indi_surname) === 0 ||
227
-                            I18N::comparator()($child_surname, $spouse_surname) !== 0
228
-                        ) {
229
-                            $node_child = new LineageNode($child, $node->rootNode());
230
-                            $node_child = $this->buildLineage($node_child);
231
-                        } else {
232
-                            $node_child = new LineageNode($child, $node->rootNode(), $child_surname);
233
-                        }
234
-                        $node->addChild($spouse_family, $node_child);
235
-                    }
236
-                }
237
-            }
238
-
239
-            //Do not print other children
240
-            if (($nb_children - $nb_natural) > 0) {
241
-                $node->addChild($spouse_family, null);
242
-            }
243
-        }
244
-
245
-        return $node;
246
-    }
31
+	private string $surname;
32
+	private Tree $tree;
33
+	private PatronymicLineageModule $patrolineage_module;
34
+
35
+	/**
36
+	 * @var Collection<string, bool> $used_indis Individuals already processed
37
+	 */
38
+	private Collection $used_indis;
39
+
40
+	/**
41
+	 * Constructor for Lineage Builder
42
+	 *
43
+	 * @param string $surname Reference surname
44
+	 * @param Tree $tree Gedcom tree
45
+	 */
46
+	public function __construct(string $surname, Tree $tree, PatronymicLineageModule $patrolineage_module)
47
+	{
48
+		$this->surname = I18N::strtoupper(I18N::language()->normalize($surname));
49
+		$this->tree = $tree;
50
+		$this->patrolineage_module = $patrolineage_module;
51
+		$this->used_indis = new Collection();
52
+	}
53
+
54
+	/**
55
+	 * Build all patronymic lineages for the reference surname.
56
+	 *
57
+	 * @return Collection<LineageRootNode>|NULL List of root patronymic lineages
58
+	 */
59
+	public function buildLineages(): ?Collection
60
+	{
61
+		$surname_data = $this->patrolineage_module->surnameData($this->tree, false, false);
62
+		$all_surnames = $this->patrolineage_module->allSurnames($surname_data);
63
+		$surname_variants = array_keys($all_surnames[$this->surname] ?? []);
64
+
65
+		if (count($surname_variants) === 0) {
66
+			return null;
67
+		}
68
+
69
+		//Warning - the individuals method returns a clone of individuals objects. Cannot be used for object equality
70
+		$indis = $this->patrolineage_module->individuals(
71
+			$this->tree,
72
+			$surname_variants,
73
+			'',
74
+			false,
75
+			false
76
+		);
77
+
78
+		if (count($indis) === 0) {
79
+			return null;
80
+		}
81
+
82
+		$root_lineages = new Collection();
83
+
84
+		foreach ($indis as $indi) {
85
+			/** @var Individual $indi */
86
+			if ($this->used_indis->get($indi->xref(), false) === false) {
87
+				$indi_first = $this->getLineageRootIndividual($indi);
88
+				if ($indi_first !== null) {
89
+					// The root lineage needs to be recreated from the Factory, to retrieve the proper object
90
+					$indi_first = Registry::individualFactory()->make($indi_first->xref(), $this->tree);
91
+				}
92
+				if ($indi_first === null) {
93
+					continue;
94
+				}
95
+				$this->used_indis->put($indi_first->xref(), true);
96
+				if ($indi_first->canShow()) {
97
+					//Check if the root individual has brothers and sisters, without parents
98
+					$indi_first_child_family = $indi_first->childFamilies()->first();
99
+					if ($indi_first_child_family !== null) {
100
+						$root_node = new LineageRootNode(null);
101
+						$root_node->addFamily($indi_first_child_family);
102
+					} else {
103
+						$root_node = new LineageRootNode($indi_first);
104
+					}
105
+					$root_node = $this->buildLineage($root_node);
106
+					$root_lineages->add($root_node);
107
+				}
108
+			}
109
+		}
110
+
111
+		return $root_lineages->sort(function (LineageRootNode $a, LineageRootNode $b) {
112
+			if ($a->numberChildNodes() === $b->numberChildNodes()) {
113
+				return 0;
114
+			}
115
+			return ($a->numberChildNodes() > $b->numberChildNodes()) ? -1 : 1;
116
+		})->values();
117
+	}
118
+
119
+	/**
120
+	 * Retrieve the root individual, from any individual, by recursion.
121
+	 * The Root individual is the individual without a father, or without a mother holding the same name.
122
+	 *
123
+	 * @param Individual $indi
124
+	 * @return Individual|NULL Root individual
125
+	 */
126
+	private function getLineageRootIndividual(Individual $indi): ?Individual
127
+	{
128
+		$child_families = $indi->childFamilies();
129
+		if ($this->used_indis->get($indi->xref(), false) !== false) {
130
+			return null;
131
+		}
132
+
133
+		foreach ($child_families as $child_family) {
134
+			/** @var Family $child_family */
135
+			$child_family->husband();
136
+			if (($husb = $child_family->husband()) !== null) {
137
+				if ($husb->isPendingAddition() && $husb->privatizeGedcom(Auth::PRIV_HIDE) === '') {
138
+					return $indi;
139
+				}
140
+				return $this->getLineageRootIndividual($husb);
141
+			} elseif (($wife = $child_family->wife()) !== null) {
142
+				if (!($wife->isPendingAddition() && $wife->privatizeGedcom(Auth::PRIV_HIDE) === '')) {
143
+					$indi_surname = $indi->getAllNames()[$indi->getPrimaryName()]['surname'];
144
+					$wife_surname = $wife->getAllNames()[$wife->getPrimaryName()]['surname'];
145
+					if (
146
+						$indi->canShowName()
147
+						&& $wife->canShowName()
148
+						&& I18N::comparator()($indi_surname, $wife_surname) === 0
149
+					) {
150
+							return $this->getLineageRootIndividual($wife);
151
+					}
152
+				}
153
+				return $indi;
154
+			}
155
+		}
156
+		return $indi;
157
+	}
158
+
159
+	/**
160
+	 * Computes descendent Lineage from a node.
161
+	 * Uses recursion to build the lineage tree
162
+	 *
163
+	 * @param LineageNode $node
164
+	 * @return LineageNode Computed lineage
165
+	 */
166
+	private function buildLineage(LineageNode $node): LineageNode
167
+	{
168
+		$indi_surname = '';
169
+
170
+		$indi_node = $node->individual();
171
+		if ($indi_node !== null) {
172
+			if ($node->families()->count() === 0) {
173
+				foreach ($indi_node->spouseFamilies() as $spouse_family) {
174
+					$node->addFamily($spouse_family);
175
+				}
176
+			}
177
+
178
+			$indi_surname = $indi_node->getAllNames()[$indi_node->getPrimaryName()]['surname'] ?? '';
179
+			$node->rootNode()->addPlace($indi_node->getBirthPlace());
180
+
181
+			//Tag the individual as used
182
+			$this->used_indis->put($indi_node->xref(), true);
183
+		}
184
+
185
+		foreach ($node->families() as $family_node) {
186
+			/** @var Family $spouse_family */
187
+			$spouse_family = $family_node->family;
188
+			$spouse_surname = '';
189
+			$spouse = null;
190
+			if (
191
+				$indi_node !== null &&
192
+				($spouse = $spouse_family->spouse($indi_node)) !== null && $spouse->canShowName()
193
+			) {
194
+				$spouse_surname = $spouse->getAllNames()[$spouse->getPrimaryName()]['surname'] ?? '';
195
+			}
196
+
197
+			$nb_children = $nb_natural = 0;
198
+
199
+			foreach ($spouse_family->children() as $child) {
200
+				if (!($child->isPendingAddition() && $child->privatizeGedcom(Auth::PRIV_HIDE) === '')) {
201
+					$child_surname = $child->getAllNames()[$child->getPrimaryName()]['surname'] ?? '';
202
+
203
+					$nb_children++;
204
+					if ($indi_node !== null && $indi_node->sex() === 'F') { //If the root individual is the mother
205
+						//Print only lineages of children with the same surname as their mother
206
+						//(supposing they are natural children)
207
+						/** @psalm-suppress RedundantCondition */
208
+						if (
209
+							$spouse === null ||
210
+							($spouse_surname !== '' && I18N::comparator()($child_surname, $spouse_surname) !== 0)
211
+						) {
212
+							if (I18N::comparator()($child_surname, $indi_surname) === 0) {
213
+								$nb_natural++;
214
+								$node_child = new LineageNode($child, $node->rootNode());
215
+								$node_child = $this->buildLineage($node_child);
216
+								$node->addChild($spouse_family, $node_child);
217
+							}
218
+						}
219
+					} else { //If the root individual is the father
220
+						$nb_natural++;
221
+						//Print if the children does not bear the same name as his mother
222
+						//(and different from his father)
223
+						if (
224
+							mb_strlen($child_surname) === 0 ||
225
+							mb_strlen($indi_surname) === 0 || mb_strlen($spouse_surname) === 0 ||
226
+							I18N::comparator()($child_surname, $indi_surname) === 0 ||
227
+							I18N::comparator()($child_surname, $spouse_surname) !== 0
228
+						) {
229
+							$node_child = new LineageNode($child, $node->rootNode());
230
+							$node_child = $this->buildLineage($node_child);
231
+						} else {
232
+							$node_child = new LineageNode($child, $node->rootNode(), $child_surname);
233
+						}
234
+						$node->addChild($spouse_family, $node_child);
235
+					}
236
+				}
237
+			}
238
+
239
+			//Do not print other children
240
+			if (($nb_children - $nb_natural) > 0) {
241
+				$node->addChild($spouse_family, null);
242
+			}
243
+		}
244
+
245
+		return $node;
246
+	}
247 247
 }
Please login to merge, or discard this patch.
app/Module/AdminTasks/Http/RequestHandlers/TaskStatusAction.php 1 patch
Indentation   +55 added lines, -55 removed lines patch added patch discarded remove patch
@@ -32,66 +32,66 @@
 block discarded – undo
32 32
  */
33 33
 class TaskStatusAction implements RequestHandlerInterface
34 34
 {
35
-    private ?AdminTasksModule $module;
36
-    private TaskScheduleService $taskschedules_service;
35
+	private ?AdminTasksModule $module;
36
+	private TaskScheduleService $taskschedules_service;
37 37
 
38
-    /**
39
-     * Constructor for TaskStatusAction Request Handler
40
-     *
41
-     * @param ModuleService $module_service
42
-     * @param TaskScheduleService $taskschedules_service
43
-     */
44
-    public function __construct(ModuleService $module_service, TaskScheduleService $taskschedules_service)
45
-    {
46
-        $this->module = $module_service->findByInterface(AdminTasksModule::class)->first();
47
-        $this->taskschedules_service = $taskschedules_service;
48
-    }
38
+	/**
39
+	 * Constructor for TaskStatusAction Request Handler
40
+	 *
41
+	 * @param ModuleService $module_service
42
+	 * @param TaskScheduleService $taskschedules_service
43
+	 */
44
+	public function __construct(ModuleService $module_service, TaskScheduleService $taskschedules_service)
45
+	{
46
+		$this->module = $module_service->findByInterface(AdminTasksModule::class)->first();
47
+		$this->taskschedules_service = $taskschedules_service;
48
+	}
49 49
 
50
-    /**
51
-     * {@inheritDoc}
52
-     * @see \Psr\Http\Server\RequestHandlerInterface::handle()
53
-     */
54
-    public function handle(ServerRequestInterface $request): ResponseInterface
55
-    {
56
-        if ($this->module === null) {
57
-            FlashMessages::addMessage(
58
-                I18N::translate('The attached module could not be found.'),
59
-                'danger'
60
-            );
61
-            return Registry::responseFactory()->redirect(HomePage::class);
62
-        }
50
+	/**
51
+	 * {@inheritDoc}
52
+	 * @see \Psr\Http\Server\RequestHandlerInterface::handle()
53
+	 */
54
+	public function handle(ServerRequestInterface $request): ResponseInterface
55
+	{
56
+		if ($this->module === null) {
57
+			FlashMessages::addMessage(
58
+				I18N::translate('The attached module could not be found.'),
59
+				'danger'
60
+			);
61
+			return Registry::responseFactory()->redirect(HomePage::class);
62
+		}
63 63
 
64
-        $task_sched_id = Validator::attributes($request)->integer('task', -1);
65
-        $task_schedule = $this->taskschedules_service->find($task_sched_id);
64
+		$task_sched_id = Validator::attributes($request)->integer('task', -1);
65
+		$task_schedule = $this->taskschedules_service->find($task_sched_id);
66 66
 
67
-        if ($task_schedule === null) {
68
-            FlashMessages::addMessage(
69
-                I18N::translate('The task shedule with ID “%s” does not exist.', I18N::number($task_sched_id)),
70
-                'danger'
71
-            );
72
-            return Registry::responseFactory()->redirect(AdminConfigPage::class);
73
-        }
67
+		if ($task_schedule === null) {
68
+			FlashMessages::addMessage(
69
+				I18N::translate('The task shedule with ID “%s” does not exist.', I18N::number($task_sched_id)),
70
+				'danger'
71
+			);
72
+			return Registry::responseFactory()->redirect(AdminConfigPage::class);
73
+		}
74 74
 
75
-        Validator::attributes($request)->boolean('enable', false) ?
76
-            $task_schedule->enable() :
77
-            $task_schedule->disable();
75
+		Validator::attributes($request)->boolean('enable', false) ?
76
+			$task_schedule->enable() :
77
+			$task_schedule->disable();
78 78
 
79
-        if ($this->taskschedules_service->update($task_schedule) > 0) {
80
-            FlashMessages::addMessage(
81
-                I18N::translate('The scheduled task has been successfully updated.'),
82
-                'success'
83
-            );
84
-            //phpcs:ignore Generic.Files.LineLength.TooLong
85
-            Log::addConfigurationLog('Module ' . $this->module->title() . ' : Task Schedule “' . $task_schedule->id() . '” has been updated.');
86
-        } else {
87
-            FlashMessages::addMessage(
88
-                I18N::translate('An error occured while updating the scheduled task.'),
89
-                'danger'
90
-            );
91
-            //phpcs:ignore Generic.Files.LineLength.TooLong
92
-            Log::addConfigurationLog('Module ' . $this->module->title() . ' : Task Schedule “' . $task_schedule->id() . '” could not be updated. See error log.');
93
-        }
79
+		if ($this->taskschedules_service->update($task_schedule) > 0) {
80
+			FlashMessages::addMessage(
81
+				I18N::translate('The scheduled task has been successfully updated.'),
82
+				'success'
83
+			);
84
+			//phpcs:ignore Generic.Files.LineLength.TooLong
85
+			Log::addConfigurationLog('Module ' . $this->module->title() . ' : Task Schedule “' . $task_schedule->id() . '” has been updated.');
86
+		} else {
87
+			FlashMessages::addMessage(
88
+				I18N::translate('An error occured while updating the scheduled task.'),
89
+				'danger'
90
+			);
91
+			//phpcs:ignore Generic.Files.LineLength.TooLong
92
+			Log::addConfigurationLog('Module ' . $this->module->title() . ' : Task Schedule “' . $task_schedule->id() . '” could not be updated. See error log.');
93
+		}
94 94
 
95
-        return Registry::responseFactory()->redirect(AdminConfigPage::class);
96
-    }
95
+		return Registry::responseFactory()->redirect(AdminConfigPage::class);
96
+	}
97 97
 }
Please login to merge, or discard this patch.
app/Module/AdminTasks/Http/RequestHandlers/TaskEditAction.php 1 patch
Indentation   +142 added lines, -142 removed lines patch added patch discarded remove patch
@@ -35,146 +35,146 @@
 block discarded – undo
35 35
  */
36 36
 class TaskEditAction implements RequestHandlerInterface
37 37
 {
38
-    private ?AdminTasksModule $module;
39
-    private TaskScheduleService $taskschedules_service;
40
-
41
-    /**
42
-     * Constructor for TaskEditAction Request Handler
43
-     *
44
-     * @param ModuleService $module_service
45
-     * @param TaskScheduleService $taskschedules_service
46
-     */
47
-    public function __construct(ModuleService $module_service, TaskScheduleService $taskschedules_service)
48
-    {
49
-        $this->module = $module_service->findByInterface(AdminTasksModule::class)->first();
50
-        $this->taskschedules_service = $taskschedules_service;
51
-    }
52
-
53
-    /**
54
-     * {@inheritDoc}
55
-     * @see \Psr\Http\Server\RequestHandlerInterface::handle()
56
-     */
57
-    public function handle(ServerRequestInterface $request): ResponseInterface
58
-    {
59
-        if ($this->module === null) {
60
-            FlashMessages::addMessage(
61
-                I18N::translate('The attached module could not be found.'),
62
-                'danger'
63
-            );
64
-            return Registry::responseFactory()->redirect(HomePage::class);
65
-        }
66
-
67
-        $task_sched_id = Validator::attributes($request)->integer('task', -1);
68
-        $task_schedule = $this->taskschedules_service->find($task_sched_id);
69
-
70
-        if ($task_schedule === null) {
71
-            FlashMessages::addMessage(
72
-                I18N::translate('The task shedule with ID “%s” does not exist.', I18N::number($task_sched_id)),
73
-                'danger'
74
-            );
75
-            return Registry::responseFactory()->redirect(AdminConfigPage::class);
76
-        }
77
-
78
-        $success = $this->updateGeneralSettings($task_schedule, $request);
79
-        $success = $success && $this->updateSpecificSettings($task_schedule, $request);
80
-
81
-        if ($success) {
82
-            FlashMessages::addMessage(
83
-                I18N::translate('The scheduled task has been successfully updated.'),
84
-                'success'
85
-            );
86
-            //phpcs:ignore Generic.Files.LineLength.TooLong
87
-            Log::addConfigurationLog('Module ' . $this->module->title() . ' : Task Schedule “' . $task_schedule->id() . '” has been updated.');
88
-        }
89
-
90
-        return Registry::responseFactory()->redirect(AdminConfigPage::class);
91
-    }
92
-
93
-    /**
94
-     * Update general settings for the task, based on the request parameters
95
-     *
96
-     * @param TaskSchedule $task_schedule
97
-     * @param ServerRequestInterface $request
98
-     * @return bool
99
-     */
100
-    private function updateGeneralSettings(TaskSchedule $task_schedule, ServerRequestInterface $request): bool
101
-    {
102
-        if ($this->module === null) {
103
-            return false;
104
-        }
105
-
106
-        $frequency = Validator::parsedBody($request)->integer('frequency', 0);
107
-        if ($frequency > 0) {
108
-            $task_schedule->setFrequency($frequency);
109
-        } else {
110
-            FlashMessages::addMessage(I18N::translate('The frequency is not in a valid format.'), 'danger');
111
-        }
112
-
113
-        $is_limited = Validator::parsedBody($request)->boolean('is_limited', false);
114
-        $nb_occur = Validator::parsedBody($request)->integer('nb_occur', 1);
115
-        if ($is_limited) {
116
-            if ($nb_occur > 0) {
117
-                $task_schedule->setRemainingOccurrences($nb_occur);
118
-            } else {
119
-                FlashMessages::addMessage(
120
-                    I18N::translate('The number of remaining occurrences is not in a valid format.'),
121
-                    'danger'
122
-                );
123
-            }
124
-        } else {
125
-            $task_schedule->setRemainingOccurrences(0);
126
-        }
127
-
128
-        try {
129
-            $this->taskschedules_service->update($task_schedule);
130
-            return true;
131
-        } catch (Throwable $ex) {
132
-            Log::addErrorLog(
133
-                sprintf(
134
-                    'Error while updating the Task Schedule "%s". Exception: %s',
135
-                    $task_schedule->id(),
136
-                    $ex->getMessage()
137
-                )
138
-            );
139
-        }
140
-
141
-        FlashMessages::addMessage(I18N::translate('An error occured while updating the scheduled task.'), 'danger');
142
-        //@phpcs:ignore Generic.Files.LineLength.TooLong
143
-        Log::addConfigurationLog('Module ' . $this->module->title() . ' : Task Schedule “' . $task_schedule->id() . '” could not be updated. See error log.');
144
-        return false;
145
-    }
146
-
147
-    /**
148
-     * Update general settings for the task, based on the request parameters
149
-     *
150
-     * @param TaskSchedule $task_schedule
151
-     * @param ServerRequestInterface $request
152
-     * @return bool
153
-     */
154
-    private function updateSpecificSettings(TaskSchedule $task_schedule, ServerRequestInterface $request): bool
155
-    {
156
-        if ($this->module === null) {
157
-            return false;
158
-        }
159
-
160
-        $task = $this->taskschedules_service->findTask($task_schedule->taskId());
161
-        if ($task === null || !($task instanceof ConfigurableTaskInterface)) {
162
-            return true;
163
-        }
164
-
165
-        /** @var \MyArtJaub\Webtrees\Contracts\Tasks\TaskInterface&\MyArtJaub\Webtrees\Contracts\Tasks\ConfigurableTaskInterface $task */
166
-        if (!$task->updateConfig($request, $task_schedule)) {
167
-            FlashMessages::addMessage(
168
-                I18N::translate(
169
-                    'An error occured while updating the specific settings of administrative task “%s”.',
170
-                    $task->name()
171
-                ),
172
-                'danger'
173
-            );
174
-            //phpcs:ignore Generic.Files.LineLength.TooLong
175
-            Log::addConfigurationLog('Module ' . $this->module->title() . ' : AdminTask “' . $task->name() . '” specific settings could not be updated. See error log.');
176
-        }
177
-
178
-        return true;
179
-    }
38
+	private ?AdminTasksModule $module;
39
+	private TaskScheduleService $taskschedules_service;
40
+
41
+	/**
42
+	 * Constructor for TaskEditAction Request Handler
43
+	 *
44
+	 * @param ModuleService $module_service
45
+	 * @param TaskScheduleService $taskschedules_service
46
+	 */
47
+	public function __construct(ModuleService $module_service, TaskScheduleService $taskschedules_service)
48
+	{
49
+		$this->module = $module_service->findByInterface(AdminTasksModule::class)->first();
50
+		$this->taskschedules_service = $taskschedules_service;
51
+	}
52
+
53
+	/**
54
+	 * {@inheritDoc}
55
+	 * @see \Psr\Http\Server\RequestHandlerInterface::handle()
56
+	 */
57
+	public function handle(ServerRequestInterface $request): ResponseInterface
58
+	{
59
+		if ($this->module === null) {
60
+			FlashMessages::addMessage(
61
+				I18N::translate('The attached module could not be found.'),
62
+				'danger'
63
+			);
64
+			return Registry::responseFactory()->redirect(HomePage::class);
65
+		}
66
+
67
+		$task_sched_id = Validator::attributes($request)->integer('task', -1);
68
+		$task_schedule = $this->taskschedules_service->find($task_sched_id);
69
+
70
+		if ($task_schedule === null) {
71
+			FlashMessages::addMessage(
72
+				I18N::translate('The task shedule with ID “%s” does not exist.', I18N::number($task_sched_id)),
73
+				'danger'
74
+			);
75
+			return Registry::responseFactory()->redirect(AdminConfigPage::class);
76
+		}
77
+
78
+		$success = $this->updateGeneralSettings($task_schedule, $request);
79
+		$success = $success && $this->updateSpecificSettings($task_schedule, $request);
80
+
81
+		if ($success) {
82
+			FlashMessages::addMessage(
83
+				I18N::translate('The scheduled task has been successfully updated.'),
84
+				'success'
85
+			);
86
+			//phpcs:ignore Generic.Files.LineLength.TooLong
87
+			Log::addConfigurationLog('Module ' . $this->module->title() . ' : Task Schedule “' . $task_schedule->id() . '” has been updated.');
88
+		}
89
+
90
+		return Registry::responseFactory()->redirect(AdminConfigPage::class);
91
+	}
92
+
93
+	/**
94
+	 * Update general settings for the task, based on the request parameters
95
+	 *
96
+	 * @param TaskSchedule $task_schedule
97
+	 * @param ServerRequestInterface $request
98
+	 * @return bool
99
+	 */
100
+	private function updateGeneralSettings(TaskSchedule $task_schedule, ServerRequestInterface $request): bool
101
+	{
102
+		if ($this->module === null) {
103
+			return false;
104
+		}
105
+
106
+		$frequency = Validator::parsedBody($request)->integer('frequency', 0);
107
+		if ($frequency > 0) {
108
+			$task_schedule->setFrequency($frequency);
109
+		} else {
110
+			FlashMessages::addMessage(I18N::translate('The frequency is not in a valid format.'), 'danger');
111
+		}
112
+
113
+		$is_limited = Validator::parsedBody($request)->boolean('is_limited', false);
114
+		$nb_occur = Validator::parsedBody($request)->integer('nb_occur', 1);
115
+		if ($is_limited) {
116
+			if ($nb_occur > 0) {
117
+				$task_schedule->setRemainingOccurrences($nb_occur);
118
+			} else {
119
+				FlashMessages::addMessage(
120
+					I18N::translate('The number of remaining occurrences is not in a valid format.'),
121
+					'danger'
122
+				);
123
+			}
124
+		} else {
125
+			$task_schedule->setRemainingOccurrences(0);
126
+		}
127
+
128
+		try {
129
+			$this->taskschedules_service->update($task_schedule);
130
+			return true;
131
+		} catch (Throwable $ex) {
132
+			Log::addErrorLog(
133
+				sprintf(
134
+					'Error while updating the Task Schedule "%s". Exception: %s',
135
+					$task_schedule->id(),
136
+					$ex->getMessage()
137
+				)
138
+			);
139
+		}
140
+
141
+		FlashMessages::addMessage(I18N::translate('An error occured while updating the scheduled task.'), 'danger');
142
+		//@phpcs:ignore Generic.Files.LineLength.TooLong
143
+		Log::addConfigurationLog('Module ' . $this->module->title() . ' : Task Schedule “' . $task_schedule->id() . '” could not be updated. See error log.');
144
+		return false;
145
+	}
146
+
147
+	/**
148
+	 * Update general settings for the task, based on the request parameters
149
+	 *
150
+	 * @param TaskSchedule $task_schedule
151
+	 * @param ServerRequestInterface $request
152
+	 * @return bool
153
+	 */
154
+	private function updateSpecificSettings(TaskSchedule $task_schedule, ServerRequestInterface $request): bool
155
+	{
156
+		if ($this->module === null) {
157
+			return false;
158
+		}
159
+
160
+		$task = $this->taskschedules_service->findTask($task_schedule->taskId());
161
+		if ($task === null || !($task instanceof ConfigurableTaskInterface)) {
162
+			return true;
163
+		}
164
+
165
+		/** @var \MyArtJaub\Webtrees\Contracts\Tasks\TaskInterface&\MyArtJaub\Webtrees\Contracts\Tasks\ConfigurableTaskInterface $task */
166
+		if (!$task->updateConfig($request, $task_schedule)) {
167
+			FlashMessages::addMessage(
168
+				I18N::translate(
169
+					'An error occured while updating the specific settings of administrative task “%s”.',
170
+					$task->name()
171
+				),
172
+				'danger'
173
+			);
174
+			//phpcs:ignore Generic.Files.LineLength.TooLong
175
+			Log::addConfigurationLog('Module ' . $this->module->title() . ' : AdminTask “' . $task->name() . '” specific settings could not be updated. See error log.');
176
+		}
177
+
178
+		return true;
179
+	}
180 180
 }
Please login to merge, or discard this patch.
app/Module/GeoDispersion/PlaceMappers/CoordinatesPlaceMapper.php 2 patches
Indentation   +180 added lines, -180 removed lines patch added patch discarded remove patch
@@ -36,184 +36,184 @@
 block discarded – undo
36 36
  */
37 37
 class CoordinatesPlaceMapper implements PlaceMapperInterface
38 38
 {
39
-    use PlaceMapperTrait;
40
-
41
-    private ?GeometryEngine $geometry_engine = null;
42
-
43
-    /**
44
-     * {@inheritDoc}
45
-     * @see \MyArtJaub\Webtrees\Contracts\GeoDispersion\PlaceMapperInterface::title()
46
-     */
47
-    public function title(): string
48
-    {
49
-        return I18N::translate('Mapping on place coordinates');
50
-    }
51
-
52
-    /**
53
-     * {@inheritDoc}
54
-     *
55
-     * {@internal The Place is associated to a Point only.
56
-     * PlaceLocation can calculate a BoundingBox.
57
-     * Using a BoundingBox could make the mapping more complex and potentially arbitary.
58
-     * Furthermore, when no coordinate is found for the place or its children, then it bubbles up to the parents.
59
-     * This could create the unwanted side effect of a very large area to consider}
60
-     *
61
-     * @see \MyArtJaub\Webtrees\Contracts\GeoDispersion\PlaceMapperInterface::map()
62
-     */
63
-    public function map(Place $place, string $feature_property): ?string
64
-    {
65
-        $location = new PlaceLocation($place->gedcomName());
66
-        $longitude = $location->longitude();
67
-        $latitude = $location->latitude();
68
-        if ($longitude === null || $latitude === null) {
69
-            return null;
70
-        }
71
-
72
-        $features_index = $this->featuresIndex();
73
-        if ($features_index === null) {
74
-            return null;
75
-        }
76
-
77
-        $place_point = Point::xy($longitude, $latitude, $features_index['SRID']);
78
-        $grid_box = $this->getGridCell(
79
-            $place_point,
80
-            $features_index['map_NE'],
81
-            $features_index['map_SW'],
82
-            $features_index['nb_columns']
83
-        );
84
-        if ($grid_box === null || !$this->setGeometryEngine() || $this->geometry_engine === null) {
85
-            return null;
86
-        }
87
-        $features = $features_index['grid'][$grid_box[0]][$grid_box[1]];
88
-        foreach ($features as $feature) {
89
-            $geometry = $feature->getGeometry();
90
-            if (
91
-                $geometry !== null && $place_point->SRID() === $geometry->SRID() &&
92
-                $this->geometry_engine->contains($geometry, $place_point)
93
-            ) {
94
-                return $feature->getProperty($feature_property);
95
-            }
96
-        }
97
-        return null;
98
-    }
99
-
100
-    /**
101
-     * Return the XY coordinates in a bounded grid of the cell containing a specific point.
102
-     *
103
-     * @param Point $point Point to find
104
-     * @param Point $grid_NE North-East point of the bounded grid
105
-     * @param Point $grid_SW South-West point fo the bounded grid
106
-     * @param int $grid_columns Number of columns/rows in the grid
107
-     * @return int[]|NULL
108
-     */
109
-    protected function getGridCell(Point $point, Point $grid_NE, Point $grid_SW, int $grid_columns): ?array
110
-    {
111
-        list($x, $y) = [$point->x() ?? 0, $point->y() ?? 0];
112
-        list($x_max, $y_max) = [$grid_NE->x() ?? 0, $grid_NE->y() ?? 0];
113
-        list($x_min, $y_min) = [$grid_SW->x() ?? 0, $grid_SW->y() ?? 0];
114
-
115
-        $x_step = ($x_max - $x_min) / $grid_columns;
116
-        $y_step = ($y_max - $y_min) / $grid_columns;
117
-
118
-        if ($x_min <= $x && $x <= $x_max && $y_min <= $y && $y <= $y_max) {
119
-            return [
120
-                $x === $x_max ? $grid_columns - 1 : intval(($x - $x_min) / $x_step),
121
-                $y === $y_max ? $grid_columns - 1 : intval(($y - $y_min) / $y_step)
122
-            ];
123
-        }
124
-        return null;
125
-    }
126
-
127
-    /**
128
-     * Get an indexed array of the features of the map.
129
-     *
130
-     * {@internal The map is divided in a grid, each cell containing the features which bounding box overlaps that cell.
131
-     * The grid is computed once for each map, and cached.}
132
-     *
133
-     * @phpcs:ignore Generic.Files.LineLength.TooLong
134
-     * @return array{grid: array<int, array<int, \Brick\Geo\IO\GeoJSON\Feature[]>>, nb_columns: int, map_NE: \Brick\Geo\Point, map_SW: \Brick\Geo\Point, SRID: int}|NULL
135
-     */
136
-    protected function featuresIndex(): ?array
137
-    {
138
-        $cacheKey = $this->cacheKey();
139
-        if ($cacheKey === null) {
140
-            return null;
141
-        }
142
-        return Registry::cache()->array()->remember($cacheKey, function (): ?array {
143
-            $map_def = $this->data('map');
144
-            if (
145
-                !$this->setGeometryEngine()
146
-                || $map_def === null
147
-                || !($map_def instanceof MapDefinitionInterface)
148
-            ) {
149
-                return null;
150
-            }
151
-            $bounding_boxes = [];
152
-            $map_bounding_box = new BoundingBox();
153
-            $srid = 0;
154
-            foreach ($map_def->features() as $feature) {
155
-                $geometry = $feature->getGeometry();
156
-                if ($geometry === null) {
157
-                    continue;
158
-                }
159
-                $srid = $geometry->SRID();
160
-                $bounding_box = $geometry->getBoundingBox();
161
-                $bounding_boxes[] = [$feature, $bounding_box];
162
-                $map_bounding_box = $map_bounding_box->extendedWithBoundingBox($bounding_box);
163
-            }
164
-            $grid_columns = count($bounding_boxes);
165
-            $grid = array_fill(0, $grid_columns, array_fill(0, $grid_columns, []));
166
-            $map_NE = $map_bounding_box->getNorthEast();
167
-            $map_SW = $map_bounding_box->getSouthWest();
168
-            foreach ($bounding_boxes as $item) {
169
-                $grid_box_SW = $this->getGridCell($item[1]->getSouthWest(), $map_NE, $map_SW, $grid_columns) ?? [1, 1];
170
-                $grid_box_NE = $this->getGridCell($item[1]->getNorthEast(), $map_NE, $map_SW, $grid_columns) ?? [0, 0];
171
-                for ($i = $grid_box_SW[0]; $i <= $grid_box_NE[0]; $i++) {
172
-                    for ($j = $grid_box_SW[1]; $j <= $grid_box_NE[1]; $j++) {
173
-                        $grid[$i][$j][] = $item[0];
174
-                    }
175
-                }
176
-            }
177
-            return [
178
-                'grid'          =>  $grid,
179
-                'nb_columns'    =>  $grid_columns,
180
-                'map_NE'        =>  $map_NE,
181
-                'map_SW'        =>  $map_SW,
182
-                'SRID'          =>  $srid
183
-            ];
184
-        });
185
-    }
186
-
187
-    /**
188
-     * Set the Brick Geo Engine to use the database for geospatial computations.
189
-     * The engine is set only if it has not been set beforehand.
190
-     *
191
-     * @return bool
192
-     */
193
-    protected function setGeometryEngine(): bool
194
-    {
195
-        try {
196
-            if ($this->geometry_engine === null) {
197
-                $this->geometry_engine = new PDOEngine(DB::connection()->getPdo());
198
-            }
199
-            $point = Point::xy(1, 1);
200
-            return $this->geometry_engine->equals($point, $point);
201
-        } catch (Throwable $ex) {
202
-        }
203
-        return false;
204
-    }
205
-
206
-    /**
207
-     * Get the key to cache the indexed grid of features.
208
-     *
209
-     * @return string|NULL
210
-     */
211
-    protected function cacheKey(): ?string
212
-    {
213
-        $map_def = $this->data('map');
214
-        if ($map_def === null || !($map_def instanceof MapDefinitionInterface)) {
215
-            return null;
216
-        }
217
-        return spl_object_id($this) . '-map-' . $map_def->id();
218
-    }
39
+	use PlaceMapperTrait;
40
+
41
+	private ?GeometryEngine $geometry_engine = null;
42
+
43
+	/**
44
+	 * {@inheritDoc}
45
+	 * @see \MyArtJaub\Webtrees\Contracts\GeoDispersion\PlaceMapperInterface::title()
46
+	 */
47
+	public function title(): string
48
+	{
49
+		return I18N::translate('Mapping on place coordinates');
50
+	}
51
+
52
+	/**
53
+	 * {@inheritDoc}
54
+	 *
55
+	 * {@internal The Place is associated to a Point only.
56
+	 * PlaceLocation can calculate a BoundingBox.
57
+	 * Using a BoundingBox could make the mapping more complex and potentially arbitary.
58
+	 * Furthermore, when no coordinate is found for the place or its children, then it bubbles up to the parents.
59
+	 * This could create the unwanted side effect of a very large area to consider}
60
+	 *
61
+	 * @see \MyArtJaub\Webtrees\Contracts\GeoDispersion\PlaceMapperInterface::map()
62
+	 */
63
+	public function map(Place $place, string $feature_property): ?string
64
+	{
65
+		$location = new PlaceLocation($place->gedcomName());
66
+		$longitude = $location->longitude();
67
+		$latitude = $location->latitude();
68
+		if ($longitude === null || $latitude === null) {
69
+			return null;
70
+		}
71
+
72
+		$features_index = $this->featuresIndex();
73
+		if ($features_index === null) {
74
+			return null;
75
+		}
76
+
77
+		$place_point = Point::xy($longitude, $latitude, $features_index['SRID']);
78
+		$grid_box = $this->getGridCell(
79
+			$place_point,
80
+			$features_index['map_NE'],
81
+			$features_index['map_SW'],
82
+			$features_index['nb_columns']
83
+		);
84
+		if ($grid_box === null || !$this->setGeometryEngine() || $this->geometry_engine === null) {
85
+			return null;
86
+		}
87
+		$features = $features_index['grid'][$grid_box[0]][$grid_box[1]];
88
+		foreach ($features as $feature) {
89
+			$geometry = $feature->getGeometry();
90
+			if (
91
+				$geometry !== null && $place_point->SRID() === $geometry->SRID() &&
92
+				$this->geometry_engine->contains($geometry, $place_point)
93
+			) {
94
+				return $feature->getProperty($feature_property);
95
+			}
96
+		}
97
+		return null;
98
+	}
99
+
100
+	/**
101
+	 * Return the XY coordinates in a bounded grid of the cell containing a specific point.
102
+	 *
103
+	 * @param Point $point Point to find
104
+	 * @param Point $grid_NE North-East point of the bounded grid
105
+	 * @param Point $grid_SW South-West point fo the bounded grid
106
+	 * @param int $grid_columns Number of columns/rows in the grid
107
+	 * @return int[]|NULL
108
+	 */
109
+	protected function getGridCell(Point $point, Point $grid_NE, Point $grid_SW, int $grid_columns): ?array
110
+	{
111
+		list($x, $y) = [$point->x() ?? 0, $point->y() ?? 0];
112
+		list($x_max, $y_max) = [$grid_NE->x() ?? 0, $grid_NE->y() ?? 0];
113
+		list($x_min, $y_min) = [$grid_SW->x() ?? 0, $grid_SW->y() ?? 0];
114
+
115
+		$x_step = ($x_max - $x_min) / $grid_columns;
116
+		$y_step = ($y_max - $y_min) / $grid_columns;
117
+
118
+		if ($x_min <= $x && $x <= $x_max && $y_min <= $y && $y <= $y_max) {
119
+			return [
120
+				$x === $x_max ? $grid_columns - 1 : intval(($x - $x_min) / $x_step),
121
+				$y === $y_max ? $grid_columns - 1 : intval(($y - $y_min) / $y_step)
122
+			];
123
+		}
124
+		return null;
125
+	}
126
+
127
+	/**
128
+	 * Get an indexed array of the features of the map.
129
+	 *
130
+	 * {@internal The map is divided in a grid, each cell containing the features which bounding box overlaps that cell.
131
+	 * The grid is computed once for each map, and cached.}
132
+	 *
133
+	 * @phpcs:ignore Generic.Files.LineLength.TooLong
134
+	 * @return array{grid: array<int, array<int, \Brick\Geo\IO\GeoJSON\Feature[]>>, nb_columns: int, map_NE: \Brick\Geo\Point, map_SW: \Brick\Geo\Point, SRID: int}|NULL
135
+	 */
136
+	protected function featuresIndex(): ?array
137
+	{
138
+		$cacheKey = $this->cacheKey();
139
+		if ($cacheKey === null) {
140
+			return null;
141
+		}
142
+		return Registry::cache()->array()->remember($cacheKey, function (): ?array {
143
+			$map_def = $this->data('map');
144
+			if (
145
+				!$this->setGeometryEngine()
146
+				|| $map_def === null
147
+				|| !($map_def instanceof MapDefinitionInterface)
148
+			) {
149
+				return null;
150
+			}
151
+			$bounding_boxes = [];
152
+			$map_bounding_box = new BoundingBox();
153
+			$srid = 0;
154
+			foreach ($map_def->features() as $feature) {
155
+				$geometry = $feature->getGeometry();
156
+				if ($geometry === null) {
157
+					continue;
158
+				}
159
+				$srid = $geometry->SRID();
160
+				$bounding_box = $geometry->getBoundingBox();
161
+				$bounding_boxes[] = [$feature, $bounding_box];
162
+				$map_bounding_box = $map_bounding_box->extendedWithBoundingBox($bounding_box);
163
+			}
164
+			$grid_columns = count($bounding_boxes);
165
+			$grid = array_fill(0, $grid_columns, array_fill(0, $grid_columns, []));
166
+			$map_NE = $map_bounding_box->getNorthEast();
167
+			$map_SW = $map_bounding_box->getSouthWest();
168
+			foreach ($bounding_boxes as $item) {
169
+				$grid_box_SW = $this->getGridCell($item[1]->getSouthWest(), $map_NE, $map_SW, $grid_columns) ?? [1, 1];
170
+				$grid_box_NE = $this->getGridCell($item[1]->getNorthEast(), $map_NE, $map_SW, $grid_columns) ?? [0, 0];
171
+				for ($i = $grid_box_SW[0]; $i <= $grid_box_NE[0]; $i++) {
172
+					for ($j = $grid_box_SW[1]; $j <= $grid_box_NE[1]; $j++) {
173
+						$grid[$i][$j][] = $item[0];
174
+					}
175
+				}
176
+			}
177
+			return [
178
+				'grid'          =>  $grid,
179
+				'nb_columns'    =>  $grid_columns,
180
+				'map_NE'        =>  $map_NE,
181
+				'map_SW'        =>  $map_SW,
182
+				'SRID'          =>  $srid
183
+			];
184
+		});
185
+	}
186
+
187
+	/**
188
+	 * Set the Brick Geo Engine to use the database for geospatial computations.
189
+	 * The engine is set only if it has not been set beforehand.
190
+	 *
191
+	 * @return bool
192
+	 */
193
+	protected function setGeometryEngine(): bool
194
+	{
195
+		try {
196
+			if ($this->geometry_engine === null) {
197
+				$this->geometry_engine = new PDOEngine(DB::connection()->getPdo());
198
+			}
199
+			$point = Point::xy(1, 1);
200
+			return $this->geometry_engine->equals($point, $point);
201
+		} catch (Throwable $ex) {
202
+		}
203
+		return false;
204
+	}
205
+
206
+	/**
207
+	 * Get the key to cache the indexed grid of features.
208
+	 *
209
+	 * @return string|NULL
210
+	 */
211
+	protected function cacheKey(): ?string
212
+	{
213
+		$map_def = $this->data('map');
214
+		if ($map_def === null || !($map_def instanceof MapDefinitionInterface)) {
215
+			return null;
216
+		}
217
+		return spl_object_id($this) . '-map-' . $map_def->id();
218
+	}
219 219
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -139,7 +139,7 @@  discard block
 block discarded – undo
139 139
         if ($cacheKey === null) {
140 140
             return null;
141 141
         }
142
-        return Registry::cache()->array()->remember($cacheKey, function (): ?array {
142
+        return Registry::cache()->array()->remember($cacheKey, function(): ?array {
143 143
             $map_def = $this->data('map');
144 144
             if (
145 145
                 !$this->setGeometryEngine()
@@ -214,6 +214,6 @@  discard block
 block discarded – undo
214 214
         if ($map_def === null || !($map_def instanceof MapDefinitionInterface)) {
215 215
             return null;
216 216
         }
217
-        return spl_object_id($this) . '-map-' . $map_def->id();
217
+        return spl_object_id($this).'-map-'.$map_def->id();
218 218
     }
219 219
 }
Please login to merge, or discard this patch.
app/Module/GeoDispersion/Http/RequestHandlers/MapAdapterEditAction.php 1 patch
Indentation   +72 added lines, -72 removed lines patch added patch discarded remove patch
@@ -36,85 +36,85 @@
 block discarded – undo
36 36
  */
37 37
 class MapAdapterEditAction implements RequestHandlerInterface
38 38
 {
39
-    private ?GeoDispersionModule $module;
40
-    private MapAdapterDataService $mapadapter_data_service;
41
-    private MapDefinitionsService $map_definition_service;
39
+	private ?GeoDispersionModule $module;
40
+	private MapAdapterDataService $mapadapter_data_service;
41
+	private MapDefinitionsService $map_definition_service;
42 42
 
43
-    /**
44
-     * Constructor for MapAdapterEditAction Request Handler
45
-     *
46
-     * @param ModuleService $module_service
47
-     * @param MapAdapterDataService $mapadapter_data_service
48
-     * @param MapDefinitionsService $map_definition_service
49
-     */
50
-    public function __construct(
51
-        ModuleService $module_service,
52
-        MapAdapterDataService $mapadapter_data_service,
53
-        MapDefinitionsService $map_definition_service
54
-    ) {
55
-        $this->module = $module_service->findByInterface(GeoDispersionModule::class)->first();
56
-        $this->mapadapter_data_service = $mapadapter_data_service;
57
-        $this->map_definition_service = $map_definition_service;
58
-    }
43
+	/**
44
+	 * Constructor for MapAdapterEditAction Request Handler
45
+	 *
46
+	 * @param ModuleService $module_service
47
+	 * @param MapAdapterDataService $mapadapter_data_service
48
+	 * @param MapDefinitionsService $map_definition_service
49
+	 */
50
+	public function __construct(
51
+		ModuleService $module_service,
52
+		MapAdapterDataService $mapadapter_data_service,
53
+		MapDefinitionsService $map_definition_service
54
+	) {
55
+		$this->module = $module_service->findByInterface(GeoDispersionModule::class)->first();
56
+		$this->mapadapter_data_service = $mapadapter_data_service;
57
+		$this->map_definition_service = $map_definition_service;
58
+	}
59 59
 
60
-    /**
61
-     * {@inheritDoc}
62
-     * @see \Psr\Http\Server\RequestHandlerInterface::handle()
63
-     */
64
-    public function handle(ServerRequestInterface $request): ResponseInterface
65
-    {
66
-        $tree = Validator::attributes($request)->tree();
60
+	/**
61
+	 * {@inheritDoc}
62
+	 * @see \Psr\Http\Server\RequestHandlerInterface::handle()
63
+	 */
64
+	public function handle(ServerRequestInterface $request): ResponseInterface
65
+	{
66
+		$tree = Validator::attributes($request)->tree();
67 67
 
68
-        if ($this->module === null) {
69
-            FlashMessages::addMessage(
70
-                I18N::translate('The attached module could not be found.'),
71
-                'danger'
72
-            );
73
-            return Registry::responseFactory()->redirect(HomePage::class, ['tree' => $tree->name()]);
74
-        }
68
+		if ($this->module === null) {
69
+			FlashMessages::addMessage(
70
+				I18N::translate('The attached module could not be found.'),
71
+				'danger'
72
+			);
73
+			return Registry::responseFactory()->redirect(HomePage::class, ['tree' => $tree->name()]);
74
+		}
75 75
 
76
-        $adapter_id = Validator::attributes($request)->integer('adapter_id', -1);
77
-        $map_adapter = $this->mapadapter_data_service->find($adapter_id);
76
+		$adapter_id = Validator::attributes($request)->integer('adapter_id', -1);
77
+		$map_adapter = $this->mapadapter_data_service->find($adapter_id);
78 78
 
79
-        $map = $this->map_definition_service->find(Validator::parsedBody($request)->string('map_adapter_map', ''));
80
-        $mapping_property   = Validator::parsedBody($request)->string('map_adapter_property_selected', '');
79
+		$map = $this->map_definition_service->find(Validator::parsedBody($request)->string('map_adapter_map', ''));
80
+		$mapping_property   = Validator::parsedBody($request)->string('map_adapter_property_selected', '');
81 81
 
82
-        $mapper = null;
83
-        try {
84
-            $mapper = app(Validator::parsedBody($request)->string('map_adapter_mapper', ''));
85
-        } catch (BindingResolutionException $ex) {
86
-        }
82
+		$mapper = null;
83
+		try {
84
+			$mapper = app(Validator::parsedBody($request)->string('map_adapter_mapper', ''));
85
+		} catch (BindingResolutionException $ex) {
86
+		}
87 87
 
88
-        if ($map_adapter === null || $map === null || $mapper === null || !($mapper instanceof PlaceMapperInterface)) {
89
-            FlashMessages::addMessage(
90
-                I18N::translate('The parameters for the map configuration are not valid.'),
91
-                'danger'
92
-            );
93
-            return Registry::responseFactory()->redirect(AdminConfigPage::class, ['tree' => $tree->name()]);
94
-        }
88
+		if ($map_adapter === null || $map === null || $mapper === null || !($mapper instanceof PlaceMapperInterface)) {
89
+			FlashMessages::addMessage(
90
+				I18N::translate('The parameters for the map configuration are not valid.'),
91
+				'danger'
92
+			);
93
+			return Registry::responseFactory()->redirect(AdminConfigPage::class, ['tree' => $tree->name()]);
94
+		}
95 95
 
96
-        $mapper->setConfig($mapper->config()->withConfigUpdate($request));
97
-        $new_map_adapter = $map_adapter->with($map, $mapper, $mapping_property);
98
-        try {
99
-            $this->mapadapter_data_service->update($new_map_adapter);
100
-            FlashMessages::addMessage(
101
-                I18N::translate('The map configuration has been successfully updated.'),
102
-                'success'
103
-            );
104
-            //phpcs:ignore Generic.Files.LineLength.TooLong
105
-            Log::addConfigurationLog('Module ' . $this->module->title() . ' : Map Adapter “' . $map_adapter->id() . '” has been updated.');
106
-        } catch (Throwable $ex) {
107
-            FlashMessages::addMessage(
108
-                I18N::translate('An error occured while updating the map configuration.'),
109
-                'danger'
110
-            );
111
-            //phpcs:ignore Generic.Files.LineLength.TooLong
112
-            Log::addErrorLog('Module ' . $this->module->title() . ' : Error when updating Map Adapter “' . $map_adapter->id() . '”: ' . $ex->getMessage());
113
-        }
96
+		$mapper->setConfig($mapper->config()->withConfigUpdate($request));
97
+		$new_map_adapter = $map_adapter->with($map, $mapper, $mapping_property);
98
+		try {
99
+			$this->mapadapter_data_service->update($new_map_adapter);
100
+			FlashMessages::addMessage(
101
+				I18N::translate('The map configuration has been successfully updated.'),
102
+				'success'
103
+			);
104
+			//phpcs:ignore Generic.Files.LineLength.TooLong
105
+			Log::addConfigurationLog('Module ' . $this->module->title() . ' : Map Adapter “' . $map_adapter->id() . '” has been updated.');
106
+		} catch (Throwable $ex) {
107
+			FlashMessages::addMessage(
108
+				I18N::translate('An error occured while updating the map configuration.'),
109
+				'danger'
110
+			);
111
+			//phpcs:ignore Generic.Files.LineLength.TooLong
112
+			Log::addErrorLog('Module ' . $this->module->title() . ' : Error when updating Map Adapter “' . $map_adapter->id() . '”: ' . $ex->getMessage());
113
+		}
114 114
 
115
-        return Registry::responseFactory()->redirect(MapAdapterEditPage::class, [
116
-            'tree' => $tree->name(),
117
-            'adapter_id' => $map_adapter->id()
118
-        ]);
119
-    }
115
+		return Registry::responseFactory()->redirect(MapAdapterEditPage::class, [
116
+			'tree' => $tree->name(),
117
+			'adapter_id' => $map_adapter->id()
118
+		]);
119
+	}
120 120
 }
Please login to merge, or discard this patch.
Module/GeoDispersion/Http/RequestHandlers/MapAdapterDeleteInvalidAction.php 1 patch
Indentation   +65 added lines, -65 removed lines patch added patch discarded remove patch
@@ -36,77 +36,77 @@
 block discarded – undo
36 36
  */
37 37
 class MapAdapterDeleteInvalidAction implements RequestHandlerInterface
38 38
 {
39
-    private ?GeoDispersionModule $module;
40
-    private GeoAnalysisViewDataService $geoview_data_service;
41
-    private MapAdapterDataService $mapadapter_data_service;
39
+	private ?GeoDispersionModule $module;
40
+	private GeoAnalysisViewDataService $geoview_data_service;
41
+	private MapAdapterDataService $mapadapter_data_service;
42 42
 
43
-    /**
44
-     * Constructor for MapAdapterDeleteInvalidAction Request Handler
45
-     *
46
-     * @param ModuleService $module_service
47
-     * @param GeoAnalysisViewDataService $geoview_data_service
48
-     * @param MapAdapterDataService $mapadapter_data_service
49
-     */
50
-    public function __construct(
51
-        ModuleService $module_service,
52
-        GeoAnalysisViewDataService $geoview_data_service,
53
-        MapAdapterDataService $mapadapter_data_service
54
-    ) {
55
-        $this->module = $module_service->findByInterface(GeoDispersionModule::class)->first();
56
-        $this->geoview_data_service = $geoview_data_service;
57
-        $this->mapadapter_data_service = $mapadapter_data_service;
58
-    }
43
+	/**
44
+	 * Constructor for MapAdapterDeleteInvalidAction Request Handler
45
+	 *
46
+	 * @param ModuleService $module_service
47
+	 * @param GeoAnalysisViewDataService $geoview_data_service
48
+	 * @param MapAdapterDataService $mapadapter_data_service
49
+	 */
50
+	public function __construct(
51
+		ModuleService $module_service,
52
+		GeoAnalysisViewDataService $geoview_data_service,
53
+		MapAdapterDataService $mapadapter_data_service
54
+	) {
55
+		$this->module = $module_service->findByInterface(GeoDispersionModule::class)->first();
56
+		$this->geoview_data_service = $geoview_data_service;
57
+		$this->mapadapter_data_service = $mapadapter_data_service;
58
+	}
59 59
 
60
-    /**
61
-     * {@inheritDoc}
62
-     * @see \Psr\Http\Server\RequestHandlerInterface::handle()
63
-     */
64
-    public function handle(ServerRequestInterface $request): ResponseInterface
65
-    {
66
-        $tree = Validator::attributes($request)->tree();
60
+	/**
61
+	 * {@inheritDoc}
62
+	 * @see \Psr\Http\Server\RequestHandlerInterface::handle()
63
+	 */
64
+	public function handle(ServerRequestInterface $request): ResponseInterface
65
+	{
66
+		$tree = Validator::attributes($request)->tree();
67 67
 
68
-        if ($this->module === null) {
69
-            FlashMessages::addMessage(
70
-                I18N::translate('The attached module could not be found.'),
71
-                'danger'
72
-            );
73
-            return Registry::responseFactory()->redirect(HomePage::class, ['tree' => $tree->name()]);
74
-        }
68
+		if ($this->module === null) {
69
+			FlashMessages::addMessage(
70
+				I18N::translate('The attached module could not be found.'),
71
+				'danger'
72
+			);
73
+			return Registry::responseFactory()->redirect(HomePage::class, ['tree' => $tree->name()]);
74
+		}
75 75
 
76
-        $view_id = Validator::attributes($request)->integer('view_id', -1);
77
-        $view = $this->geoview_data_service->find($tree, $view_id);
76
+		$view_id = Validator::attributes($request)->integer('view_id', -1);
77
+		$view = $this->geoview_data_service->find($tree, $view_id);
78 78
 
79
-        if ($view === null || !($view instanceof GeoAnalysisMap)) {
80
-            FlashMessages::addMessage(
81
-                I18N::translate('The view with ID “%s” does not exist.', I18N::number($view_id)),
82
-                'danger'
83
-            );
84
-            return Registry::responseFactory()->redirect(AdminConfigPage::class, ['tree' => $tree->name()]);
85
-        }
79
+		if ($view === null || !($view instanceof GeoAnalysisMap)) {
80
+			FlashMessages::addMessage(
81
+				I18N::translate('The view with ID “%s” does not exist.', I18N::number($view_id)),
82
+				'danger'
83
+			);
84
+			return Registry::responseFactory()->redirect(AdminConfigPage::class, ['tree' => $tree->name()]);
85
+		}
86 86
 
87
-        /** @var \Illuminate\Support\Collection<int> $valid_map_adapters */
88
-        $valid_map_adapters = $this->mapadapter_data_service
89
-            ->allForView($view)
90
-            ->map(fn(GeoAnalysisMapAdapter $map_adapter): int => $map_adapter->id());
87
+		/** @var \Illuminate\Support\Collection<int> $valid_map_adapters */
88
+		$valid_map_adapters = $this->mapadapter_data_service
89
+			->allForView($view)
90
+			->map(fn(GeoAnalysisMapAdapter $map_adapter): int => $map_adapter->id());
91 91
 
92
-        try {
93
-            $this->mapadapter_data_service->deleteInvalid($view, $valid_map_adapters);
94
-            FlashMessages::addMessage(
95
-                I18N::translate('The invalid map configurations have been successfully deleted.'),
96
-                'success'
97
-            );
98
-        } catch (Throwable $ex) {
99
-            FlashMessages::addMessage(
100
-                I18N::translate('An error occured while deleting the invalid map configurations.'),
101
-                'danger'
102
-            );
103
-            //phpcs:ignore Generic.Files.LineLength.TooLong
104
-            Log::addConfigurationLog('Module ' . $this->module->title() . ' : Error when deleting invalid map configurations: ' . $ex->getMessage());
105
-        }
92
+		try {
93
+			$this->mapadapter_data_service->deleteInvalid($view, $valid_map_adapters);
94
+			FlashMessages::addMessage(
95
+				I18N::translate('The invalid map configurations have been successfully deleted.'),
96
+				'success'
97
+			);
98
+		} catch (Throwable $ex) {
99
+			FlashMessages::addMessage(
100
+				I18N::translate('An error occured while deleting the invalid map configurations.'),
101
+				'danger'
102
+			);
103
+			//phpcs:ignore Generic.Files.LineLength.TooLong
104
+			Log::addConfigurationLog('Module ' . $this->module->title() . ' : Error when deleting invalid map configurations: ' . $ex->getMessage());
105
+		}
106 106
 
107
-        return Registry::responseFactory()->redirect(GeoAnalysisViewEditPage::class, [
108
-            'tree'      => $tree->name(),
109
-            'view_id'   => $view_id
110
-        ]);
111
-    }
107
+		return Registry::responseFactory()->redirect(GeoAnalysisViewEditPage::class, [
108
+			'tree'      => $tree->name(),
109
+			'view_id'   => $view_id
110
+		]);
111
+	}
112 112
 }
Please login to merge, or discard this patch.