xref: /webtrees/app/Http/RequestHandlers/MergeTreesAction.php (revision 6fd01894a78d321fac365dd0291a2fc52129fa03)
1*6fd01894SGreg Roach<?php
2*6fd01894SGreg Roach
3*6fd01894SGreg Roach/**
4*6fd01894SGreg Roach * webtrees: online genealogy
5*6fd01894SGreg Roach * Copyright (C) 2020 webtrees development team
6*6fd01894SGreg Roach * This program is free software: you can redistribute it and/or modify
7*6fd01894SGreg Roach * it under the terms of the GNU General Public License as published by
8*6fd01894SGreg Roach * the Free Software Foundation, either version 3 of the License, or
9*6fd01894SGreg Roach * (at your option) any later version.
10*6fd01894SGreg Roach * This program is distributed in the hope that it will be useful,
11*6fd01894SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
12*6fd01894SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13*6fd01894SGreg Roach * GNU General Public License for more details.
14*6fd01894SGreg Roach * You should have received a copy of the GNU General Public License
15*6fd01894SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
16*6fd01894SGreg Roach */
17*6fd01894SGreg Roach
18*6fd01894SGreg Roachdeclare(strict_types=1);
19*6fd01894SGreg Roach
20*6fd01894SGreg Roachnamespace Fisharebest\Webtrees\Http\RequestHandlers;
21*6fd01894SGreg Roach
22*6fd01894SGreg Roachuse Fisharebest\Webtrees\FlashMessages;
23*6fd01894SGreg Roachuse Fisharebest\Webtrees\Header;
24*6fd01894SGreg Roachuse Fisharebest\Webtrees\I18N;
25*6fd01894SGreg Roachuse Fisharebest\Webtrees\Services\AdminService;
26*6fd01894SGreg Roachuse Fisharebest\Webtrees\Services\TreeService;
27*6fd01894SGreg Roachuse Fisharebest\Webtrees\Tree;
28*6fd01894SGreg Roachuse Illuminate\Database\Capsule\Manager as DB;
29*6fd01894SGreg Roachuse Illuminate\Database\Query\Builder;
30*6fd01894SGreg Roachuse Illuminate\Database\Query\Expression;
31*6fd01894SGreg Roachuse Psr\Http\Message\ResponseInterface;
32*6fd01894SGreg Roachuse Psr\Http\Message\ServerRequestInterface;
33*6fd01894SGreg Roachuse Psr\Http\Server\RequestHandlerInterface;
34*6fd01894SGreg Roach
35*6fd01894SGreg Roachuse function redirect;
36*6fd01894SGreg Roachuse function route;
37*6fd01894SGreg Roach
38*6fd01894SGreg Roach/**
39*6fd01894SGreg Roach * Merge two family trees.
40*6fd01894SGreg Roach */
41*6fd01894SGreg Roachclass MergeTreesAction implements RequestHandlerInterface
42*6fd01894SGreg Roach{
43*6fd01894SGreg Roach    /** @var AdminService */
44*6fd01894SGreg Roach    private $admin_service;
45*6fd01894SGreg Roach
46*6fd01894SGreg Roach    /** @var TreeService */
47*6fd01894SGreg Roach    private $tree_service;
48*6fd01894SGreg Roach
49*6fd01894SGreg Roach    /**
50*6fd01894SGreg Roach     * AdminTreesController constructor.
51*6fd01894SGreg Roach     *
52*6fd01894SGreg Roach     * @param AdminService $admin_service
53*6fd01894SGreg Roach     * @param TreeService  $tree_service
54*6fd01894SGreg Roach     */
55*6fd01894SGreg Roach    public function __construct(AdminService $admin_service, TreeService $tree_service)
56*6fd01894SGreg Roach    {
57*6fd01894SGreg Roach        $this->admin_service = $admin_service;
58*6fd01894SGreg Roach        $this->tree_service  = $tree_service;
59*6fd01894SGreg Roach    }
60*6fd01894SGreg Roach
61*6fd01894SGreg Roach    /**
62*6fd01894SGreg Roach     * @param ServerRequestInterface $request
63*6fd01894SGreg Roach     *
64*6fd01894SGreg Roach     * @return ResponseInterface
65*6fd01894SGreg Roach     */
66*6fd01894SGreg Roach    public function handle(ServerRequestInterface $request): ResponseInterface
67*6fd01894SGreg Roach    {
68*6fd01894SGreg Roach        $params     = (array) $request->getParsedBody();
69*6fd01894SGreg Roach        $tree1_name = $params['tree1_name'] ?? '';
70*6fd01894SGreg Roach        $tree2_name = $params['tree2_name'] ?? '';
71*6fd01894SGreg Roach
72*6fd01894SGreg Roach        $tree1 = $this->tree_service->all()->get($tree1_name);
73*6fd01894SGreg Roach        $tree2 = $this->tree_service->all()->get($tree2_name);
74*6fd01894SGreg Roach
75*6fd01894SGreg Roach        if ($tree1 instanceof Tree && $tree2 instanceof Tree && $tree1 !== $tree2 && $this->admin_service->countCommonXrefs($tree1, $tree2) === 0) {
76*6fd01894SGreg Roach            (new Builder(DB::connection()))->from('individuals')->insertUsing([
77*6fd01894SGreg Roach                'i_file',
78*6fd01894SGreg Roach                'i_id',
79*6fd01894SGreg Roach                'i_rin',
80*6fd01894SGreg Roach                'i_sex',
81*6fd01894SGreg Roach                'i_gedcom',
82*6fd01894SGreg Roach            ], static function (Builder $query) use ($tree1, $tree2): void {
83*6fd01894SGreg Roach                $query->select([
84*6fd01894SGreg Roach                    new Expression($tree2->id()),
85*6fd01894SGreg Roach                    'i_id',
86*6fd01894SGreg Roach                    'i_rin',
87*6fd01894SGreg Roach                    'i_sex',
88*6fd01894SGreg Roach                    'i_gedcom',
89*6fd01894SGreg Roach                ])->from('individuals')
90*6fd01894SGreg Roach                    ->where('i_file', '=', $tree1->id());
91*6fd01894SGreg Roach            });
92*6fd01894SGreg Roach
93*6fd01894SGreg Roach            (new Builder(DB::connection()))->from('families')->insertUsing([
94*6fd01894SGreg Roach                'f_file',
95*6fd01894SGreg Roach                'f_id',
96*6fd01894SGreg Roach                'f_husb',
97*6fd01894SGreg Roach                'f_wife',
98*6fd01894SGreg Roach                'f_gedcom',
99*6fd01894SGreg Roach                'f_numchil',
100*6fd01894SGreg Roach            ], static function (Builder $query) use ($tree1, $tree2): void {
101*6fd01894SGreg Roach                $query->select([
102*6fd01894SGreg Roach                    new Expression($tree2->id()),
103*6fd01894SGreg Roach                    'f_id',
104*6fd01894SGreg Roach                    'f_husb',
105*6fd01894SGreg Roach                    'f_wife',
106*6fd01894SGreg Roach                    'f_gedcom',
107*6fd01894SGreg Roach                    'f_numchil',
108*6fd01894SGreg Roach                ])->from('families')
109*6fd01894SGreg Roach                    ->where('f_file', '=', $tree1->id());
110*6fd01894SGreg Roach            });
111*6fd01894SGreg Roach
112*6fd01894SGreg Roach            (new Builder(DB::connection()))->from('sources')->insertUsing([
113*6fd01894SGreg Roach                's_file',
114*6fd01894SGreg Roach                's_id',
115*6fd01894SGreg Roach                's_name',
116*6fd01894SGreg Roach                's_gedcom',
117*6fd01894SGreg Roach            ], static function (Builder $query) use ($tree1, $tree2): void {
118*6fd01894SGreg Roach                $query->select([
119*6fd01894SGreg Roach                    new Expression($tree2->id()),
120*6fd01894SGreg Roach                    's_id',
121*6fd01894SGreg Roach                    's_name',
122*6fd01894SGreg Roach                    's_gedcom',
123*6fd01894SGreg Roach                ])->from('sources')
124*6fd01894SGreg Roach                    ->where('s_file', '=', $tree1->id());
125*6fd01894SGreg Roach            });
126*6fd01894SGreg Roach
127*6fd01894SGreg Roach            (new Builder(DB::connection()))->from('media')->insertUsing([
128*6fd01894SGreg Roach                'm_file',
129*6fd01894SGreg Roach                'm_id',
130*6fd01894SGreg Roach                'm_gedcom',
131*6fd01894SGreg Roach            ], static function (Builder $query) use ($tree1, $tree2): void {
132*6fd01894SGreg Roach                $query->select([
133*6fd01894SGreg Roach                    new Expression($tree2->id()),
134*6fd01894SGreg Roach                    'm_id',
135*6fd01894SGreg Roach                    'm_gedcom',
136*6fd01894SGreg Roach                ])->from('media')
137*6fd01894SGreg Roach                    ->where('m_file', '=', $tree1->id());
138*6fd01894SGreg Roach            });
139*6fd01894SGreg Roach
140*6fd01894SGreg Roach            (new Builder(DB::connection()))->from('media_file')->insertUsing([
141*6fd01894SGreg Roach                'm_file',
142*6fd01894SGreg Roach                'm_id',
143*6fd01894SGreg Roach                'multimedia_file_refn',
144*6fd01894SGreg Roach                'multimedia_format',
145*6fd01894SGreg Roach                'source_media_type',
146*6fd01894SGreg Roach                'descriptive_title',
147*6fd01894SGreg Roach            ], static function (Builder $query) use ($tree1, $tree2): void {
148*6fd01894SGreg Roach                $query->select([
149*6fd01894SGreg Roach                    new Expression($tree2->id()),
150*6fd01894SGreg Roach                    'm_id',
151*6fd01894SGreg Roach                    'multimedia_file_refn',
152*6fd01894SGreg Roach                    'multimedia_format',
153*6fd01894SGreg Roach                    'source_media_type',
154*6fd01894SGreg Roach                    'descriptive_title',
155*6fd01894SGreg Roach                ])->from('media_file')
156*6fd01894SGreg Roach                    ->where('m_file', '=', $tree1->id());
157*6fd01894SGreg Roach            });
158*6fd01894SGreg Roach
159*6fd01894SGreg Roach            (new Builder(DB::connection()))->from('other')->insertUsing([
160*6fd01894SGreg Roach                'o_file',
161*6fd01894SGreg Roach                'o_id',
162*6fd01894SGreg Roach                'o_type',
163*6fd01894SGreg Roach                'o_gedcom',
164*6fd01894SGreg Roach            ], static function (Builder $query) use ($tree1, $tree2): void {
165*6fd01894SGreg Roach                $query->select([
166*6fd01894SGreg Roach                    new Expression($tree2->id()),
167*6fd01894SGreg Roach                    'o_id',
168*6fd01894SGreg Roach                    'o_type',
169*6fd01894SGreg Roach                    'o_gedcom',
170*6fd01894SGreg Roach                ])->from('other')
171*6fd01894SGreg Roach                    ->whereNotIn('o_type', [Header::RECORD_TYPE, 'TRLR'])
172*6fd01894SGreg Roach                    ->where('o_file', '=', $tree1->id());
173*6fd01894SGreg Roach            });
174*6fd01894SGreg Roach
175*6fd01894SGreg Roach            (new Builder(DB::connection()))->from('name')->insertUsing([
176*6fd01894SGreg Roach                'n_file',
177*6fd01894SGreg Roach                'n_id',
178*6fd01894SGreg Roach                'n_num',
179*6fd01894SGreg Roach                'n_type',
180*6fd01894SGreg Roach                'n_sort',
181*6fd01894SGreg Roach                'n_full',
182*6fd01894SGreg Roach                'n_surname',
183*6fd01894SGreg Roach                'n_surn',
184*6fd01894SGreg Roach                'n_givn',
185*6fd01894SGreg Roach                'n_soundex_givn_std',
186*6fd01894SGreg Roach                'n_soundex_surn_std',
187*6fd01894SGreg Roach                'n_soundex_givn_dm',
188*6fd01894SGreg Roach                'n_soundex_surn_dm',
189*6fd01894SGreg Roach            ], static function (Builder $query) use ($tree1, $tree2): void {
190*6fd01894SGreg Roach                $query->select([
191*6fd01894SGreg Roach                    new Expression($tree2->id()),
192*6fd01894SGreg Roach                    'n_id',
193*6fd01894SGreg Roach                    'n_num',
194*6fd01894SGreg Roach                    'n_type',
195*6fd01894SGreg Roach                    'n_sort',
196*6fd01894SGreg Roach                    'n_full',
197*6fd01894SGreg Roach                    'n_surname',
198*6fd01894SGreg Roach                    'n_surn',
199*6fd01894SGreg Roach                    'n_givn',
200*6fd01894SGreg Roach                    'n_soundex_givn_std',
201*6fd01894SGreg Roach                    'n_soundex_surn_std',
202*6fd01894SGreg Roach                    'n_soundex_givn_dm',
203*6fd01894SGreg Roach                    'n_soundex_surn_dm',
204*6fd01894SGreg Roach                ])->from('name')
205*6fd01894SGreg Roach                    ->where('n_file', '=', $tree1->id());
206*6fd01894SGreg Roach            });
207*6fd01894SGreg Roach
208*6fd01894SGreg Roach            (new Builder(DB::connection()))->from('dates')->insertUsing([
209*6fd01894SGreg Roach                'd_file',
210*6fd01894SGreg Roach                'd_gid',
211*6fd01894SGreg Roach                'd_day',
212*6fd01894SGreg Roach                'd_month',
213*6fd01894SGreg Roach                'd_mon',
214*6fd01894SGreg Roach                'd_year',
215*6fd01894SGreg Roach                'd_julianday1',
216*6fd01894SGreg Roach                'd_julianday2',
217*6fd01894SGreg Roach                'd_fact',
218*6fd01894SGreg Roach                'd_type',
219*6fd01894SGreg Roach            ], static function (Builder $query) use ($tree1, $tree2): void {
220*6fd01894SGreg Roach                $query->select([
221*6fd01894SGreg Roach                    new Expression($tree2->id()),
222*6fd01894SGreg Roach                    'd_gid',
223*6fd01894SGreg Roach                    'd_day',
224*6fd01894SGreg Roach                    'd_month',
225*6fd01894SGreg Roach                    'd_mon',
226*6fd01894SGreg Roach                    'd_year',
227*6fd01894SGreg Roach                    'd_julianday1',
228*6fd01894SGreg Roach                    'd_julianday2',
229*6fd01894SGreg Roach                    'd_fact',
230*6fd01894SGreg Roach                    'd_type',
231*6fd01894SGreg Roach                ])->from('dates')
232*6fd01894SGreg Roach                    ->where('d_file', '=', $tree1->id());
233*6fd01894SGreg Roach            });
234*6fd01894SGreg Roach
235*6fd01894SGreg Roach            (new Builder(DB::connection()))->from('link')->insertUsing([
236*6fd01894SGreg Roach                'l_file',
237*6fd01894SGreg Roach                'l_from',
238*6fd01894SGreg Roach                'l_type',
239*6fd01894SGreg Roach                'l_to',
240*6fd01894SGreg Roach            ], static function (Builder $query) use ($tree1, $tree2): void {
241*6fd01894SGreg Roach                $query->select([
242*6fd01894SGreg Roach                    new Expression($tree2->id()),
243*6fd01894SGreg Roach                    'l_from',
244*6fd01894SGreg Roach                    'l_type',
245*6fd01894SGreg Roach                    'l_to',
246*6fd01894SGreg Roach                ])->from('link')
247*6fd01894SGreg Roach                    ->whereNotIn('l_from', [Header::RECORD_TYPE, 'TRLR'])
248*6fd01894SGreg Roach                    ->where('l_file', '=', $tree1->id());
249*6fd01894SGreg Roach            });
250*6fd01894SGreg Roach
251*6fd01894SGreg Roach            FlashMessages::addMessage(I18N::translate('The family trees have been merged successfully.'), 'success');
252*6fd01894SGreg Roach
253*6fd01894SGreg Roach            $url = route(ManageTrees::class, ['tree' => $tree2->name()]);
254*6fd01894SGreg Roach        } else {
255*6fd01894SGreg Roach            $url = route(MergeTreesPage::class, [
256*6fd01894SGreg Roach                'tree1_name' => $tree1->name(),
257*6fd01894SGreg Roach                'tree2_name' => $tree2->name(),
258*6fd01894SGreg Roach            ]);
259*6fd01894SGreg Roach        }
260*6fd01894SGreg Roach
261*6fd01894SGreg Roach        return redirect($url);
262*6fd01894SGreg Roach    }
263*6fd01894SGreg Roach}
264