16fd01894SGreg Roach<?php 26fd01894SGreg Roach 36fd01894SGreg Roach/** 46fd01894SGreg Roach * webtrees: online genealogy 5*89f7189bSGreg Roach * Copyright (C) 2021 webtrees development team 66fd01894SGreg Roach * This program is free software: you can redistribute it and/or modify 76fd01894SGreg Roach * it under the terms of the GNU General Public License as published by 86fd01894SGreg Roach * the Free Software Foundation, either version 3 of the License, or 96fd01894SGreg Roach * (at your option) any later version. 106fd01894SGreg Roach * This program is distributed in the hope that it will be useful, 116fd01894SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 126fd01894SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 136fd01894SGreg Roach * GNU General Public License for more details. 146fd01894SGreg Roach * You should have received a copy of the GNU General Public License 15*89f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>. 166fd01894SGreg Roach */ 176fd01894SGreg Roach 186fd01894SGreg Roachdeclare(strict_types=1); 196fd01894SGreg Roach 206fd01894SGreg Roachnamespace Fisharebest\Webtrees\Http\RequestHandlers; 216fd01894SGreg Roach 226fd01894SGreg Roachuse Fisharebest\Webtrees\FlashMessages; 236fd01894SGreg Roachuse Fisharebest\Webtrees\Header; 246fd01894SGreg Roachuse Fisharebest\Webtrees\I18N; 256fd01894SGreg Roachuse Fisharebest\Webtrees\Services\AdminService; 266fd01894SGreg Roachuse Fisharebest\Webtrees\Services\TreeService; 276fd01894SGreg Roachuse Fisharebest\Webtrees\Tree; 286fd01894SGreg Roachuse Illuminate\Database\Capsule\Manager as DB; 296fd01894SGreg Roachuse Illuminate\Database\Query\Builder; 306fd01894SGreg Roachuse Illuminate\Database\Query\Expression; 316fd01894SGreg Roachuse Psr\Http\Message\ResponseInterface; 326fd01894SGreg Roachuse Psr\Http\Message\ServerRequestInterface; 336fd01894SGreg Roachuse Psr\Http\Server\RequestHandlerInterface; 346fd01894SGreg Roach 356fd01894SGreg Roachuse function redirect; 366fd01894SGreg Roachuse function route; 376fd01894SGreg Roach 386fd01894SGreg Roach/** 396fd01894SGreg Roach * Merge two family trees. 406fd01894SGreg Roach */ 416fd01894SGreg Roachclass MergeTreesAction implements RequestHandlerInterface 426fd01894SGreg Roach{ 436fd01894SGreg Roach /** @var AdminService */ 446fd01894SGreg Roach private $admin_service; 456fd01894SGreg Roach 466fd01894SGreg Roach /** @var TreeService */ 476fd01894SGreg Roach private $tree_service; 486fd01894SGreg Roach 496fd01894SGreg Roach /** 506fd01894SGreg Roach * AdminTreesController constructor. 516fd01894SGreg Roach * 526fd01894SGreg Roach * @param AdminService $admin_service 536fd01894SGreg Roach * @param TreeService $tree_service 546fd01894SGreg Roach */ 556fd01894SGreg Roach public function __construct(AdminService $admin_service, TreeService $tree_service) 566fd01894SGreg Roach { 576fd01894SGreg Roach $this->admin_service = $admin_service; 586fd01894SGreg Roach $this->tree_service = $tree_service; 596fd01894SGreg Roach } 606fd01894SGreg Roach 616fd01894SGreg Roach /** 626fd01894SGreg Roach * @param ServerRequestInterface $request 636fd01894SGreg Roach * 646fd01894SGreg Roach * @return ResponseInterface 656fd01894SGreg Roach */ 666fd01894SGreg Roach public function handle(ServerRequestInterface $request): ResponseInterface 676fd01894SGreg Roach { 686fd01894SGreg Roach $params = (array) $request->getParsedBody(); 696fd01894SGreg Roach $tree1_name = $params['tree1_name'] ?? ''; 706fd01894SGreg Roach $tree2_name = $params['tree2_name'] ?? ''; 716fd01894SGreg Roach 726fd01894SGreg Roach $tree1 = $this->tree_service->all()->get($tree1_name); 736fd01894SGreg Roach $tree2 = $this->tree_service->all()->get($tree2_name); 746fd01894SGreg Roach 756fd01894SGreg Roach if ($tree1 instanceof Tree && $tree2 instanceof Tree && $tree1 !== $tree2 && $this->admin_service->countCommonXrefs($tree1, $tree2) === 0) { 766fd01894SGreg Roach (new Builder(DB::connection()))->from('individuals')->insertUsing([ 776fd01894SGreg Roach 'i_file', 786fd01894SGreg Roach 'i_id', 796fd01894SGreg Roach 'i_rin', 806fd01894SGreg Roach 'i_sex', 816fd01894SGreg Roach 'i_gedcom', 826fd01894SGreg Roach ], static function (Builder $query) use ($tree1, $tree2): void { 836fd01894SGreg Roach $query->select([ 846fd01894SGreg Roach new Expression($tree2->id()), 856fd01894SGreg Roach 'i_id', 866fd01894SGreg Roach 'i_rin', 876fd01894SGreg Roach 'i_sex', 886fd01894SGreg Roach 'i_gedcom', 896fd01894SGreg Roach ])->from('individuals') 906fd01894SGreg Roach ->where('i_file', '=', $tree1->id()); 916fd01894SGreg Roach }); 926fd01894SGreg Roach 936fd01894SGreg Roach (new Builder(DB::connection()))->from('families')->insertUsing([ 946fd01894SGreg Roach 'f_file', 956fd01894SGreg Roach 'f_id', 966fd01894SGreg Roach 'f_husb', 976fd01894SGreg Roach 'f_wife', 986fd01894SGreg Roach 'f_gedcom', 996fd01894SGreg Roach 'f_numchil', 1006fd01894SGreg Roach ], static function (Builder $query) use ($tree1, $tree2): void { 1016fd01894SGreg Roach $query->select([ 1026fd01894SGreg Roach new Expression($tree2->id()), 1036fd01894SGreg Roach 'f_id', 1046fd01894SGreg Roach 'f_husb', 1056fd01894SGreg Roach 'f_wife', 1066fd01894SGreg Roach 'f_gedcom', 1076fd01894SGreg Roach 'f_numchil', 1086fd01894SGreg Roach ])->from('families') 1096fd01894SGreg Roach ->where('f_file', '=', $tree1->id()); 1106fd01894SGreg Roach }); 1116fd01894SGreg Roach 1126fd01894SGreg Roach (new Builder(DB::connection()))->from('sources')->insertUsing([ 1136fd01894SGreg Roach 's_file', 1146fd01894SGreg Roach 's_id', 1156fd01894SGreg Roach 's_name', 1166fd01894SGreg Roach 's_gedcom', 1176fd01894SGreg Roach ], static function (Builder $query) use ($tree1, $tree2): void { 1186fd01894SGreg Roach $query->select([ 1196fd01894SGreg Roach new Expression($tree2->id()), 1206fd01894SGreg Roach 's_id', 1216fd01894SGreg Roach 's_name', 1226fd01894SGreg Roach 's_gedcom', 1236fd01894SGreg Roach ])->from('sources') 1246fd01894SGreg Roach ->where('s_file', '=', $tree1->id()); 1256fd01894SGreg Roach }); 1266fd01894SGreg Roach 1276fd01894SGreg Roach (new Builder(DB::connection()))->from('media')->insertUsing([ 1286fd01894SGreg Roach 'm_file', 1296fd01894SGreg Roach 'm_id', 1306fd01894SGreg Roach 'm_gedcom', 1316fd01894SGreg Roach ], static function (Builder $query) use ($tree1, $tree2): void { 1326fd01894SGreg Roach $query->select([ 1336fd01894SGreg Roach new Expression($tree2->id()), 1346fd01894SGreg Roach 'm_id', 1356fd01894SGreg Roach 'm_gedcom', 1366fd01894SGreg Roach ])->from('media') 1376fd01894SGreg Roach ->where('m_file', '=', $tree1->id()); 1386fd01894SGreg Roach }); 1396fd01894SGreg Roach 1406fd01894SGreg Roach (new Builder(DB::connection()))->from('media_file')->insertUsing([ 1416fd01894SGreg Roach 'm_file', 1426fd01894SGreg Roach 'm_id', 1436fd01894SGreg Roach 'multimedia_file_refn', 1446fd01894SGreg Roach 'multimedia_format', 1456fd01894SGreg Roach 'source_media_type', 1466fd01894SGreg Roach 'descriptive_title', 1476fd01894SGreg Roach ], static function (Builder $query) use ($tree1, $tree2): void { 1486fd01894SGreg Roach $query->select([ 1496fd01894SGreg Roach new Expression($tree2->id()), 1506fd01894SGreg Roach 'm_id', 1516fd01894SGreg Roach 'multimedia_file_refn', 1526fd01894SGreg Roach 'multimedia_format', 1536fd01894SGreg Roach 'source_media_type', 1546fd01894SGreg Roach 'descriptive_title', 1556fd01894SGreg Roach ])->from('media_file') 1566fd01894SGreg Roach ->where('m_file', '=', $tree1->id()); 1576fd01894SGreg Roach }); 1586fd01894SGreg Roach 1596fd01894SGreg Roach (new Builder(DB::connection()))->from('other')->insertUsing([ 1606fd01894SGreg Roach 'o_file', 1616fd01894SGreg Roach 'o_id', 1626fd01894SGreg Roach 'o_type', 1636fd01894SGreg Roach 'o_gedcom', 1646fd01894SGreg Roach ], static function (Builder $query) use ($tree1, $tree2): void { 1656fd01894SGreg Roach $query->select([ 1666fd01894SGreg Roach new Expression($tree2->id()), 1676fd01894SGreg Roach 'o_id', 1686fd01894SGreg Roach 'o_type', 1696fd01894SGreg Roach 'o_gedcom', 1706fd01894SGreg Roach ])->from('other') 1716fd01894SGreg Roach ->whereNotIn('o_type', [Header::RECORD_TYPE, 'TRLR']) 1726fd01894SGreg Roach ->where('o_file', '=', $tree1->id()); 1736fd01894SGreg Roach }); 1746fd01894SGreg Roach 1756fd01894SGreg Roach (new Builder(DB::connection()))->from('name')->insertUsing([ 1766fd01894SGreg Roach 'n_file', 1776fd01894SGreg Roach 'n_id', 1786fd01894SGreg Roach 'n_num', 1796fd01894SGreg Roach 'n_type', 1806fd01894SGreg Roach 'n_sort', 1816fd01894SGreg Roach 'n_full', 1826fd01894SGreg Roach 'n_surname', 1836fd01894SGreg Roach 'n_surn', 1846fd01894SGreg Roach 'n_givn', 1856fd01894SGreg Roach 'n_soundex_givn_std', 1866fd01894SGreg Roach 'n_soundex_surn_std', 1876fd01894SGreg Roach 'n_soundex_givn_dm', 1886fd01894SGreg Roach 'n_soundex_surn_dm', 1896fd01894SGreg Roach ], static function (Builder $query) use ($tree1, $tree2): void { 1906fd01894SGreg Roach $query->select([ 1916fd01894SGreg Roach new Expression($tree2->id()), 1926fd01894SGreg Roach 'n_id', 1936fd01894SGreg Roach 'n_num', 1946fd01894SGreg Roach 'n_type', 1956fd01894SGreg Roach 'n_sort', 1966fd01894SGreg Roach 'n_full', 1976fd01894SGreg Roach 'n_surname', 1986fd01894SGreg Roach 'n_surn', 1996fd01894SGreg Roach 'n_givn', 2006fd01894SGreg Roach 'n_soundex_givn_std', 2016fd01894SGreg Roach 'n_soundex_surn_std', 2026fd01894SGreg Roach 'n_soundex_givn_dm', 2036fd01894SGreg Roach 'n_soundex_surn_dm', 2046fd01894SGreg Roach ])->from('name') 2056fd01894SGreg Roach ->where('n_file', '=', $tree1->id()); 2066fd01894SGreg Roach }); 2076fd01894SGreg Roach 2086fd01894SGreg Roach (new Builder(DB::connection()))->from('dates')->insertUsing([ 2096fd01894SGreg Roach 'd_file', 2106fd01894SGreg Roach 'd_gid', 2116fd01894SGreg Roach 'd_day', 2126fd01894SGreg Roach 'd_month', 2136fd01894SGreg Roach 'd_mon', 2146fd01894SGreg Roach 'd_year', 2156fd01894SGreg Roach 'd_julianday1', 2166fd01894SGreg Roach 'd_julianday2', 2176fd01894SGreg Roach 'd_fact', 2186fd01894SGreg Roach 'd_type', 2196fd01894SGreg Roach ], static function (Builder $query) use ($tree1, $tree2): void { 2206fd01894SGreg Roach $query->select([ 2216fd01894SGreg Roach new Expression($tree2->id()), 2226fd01894SGreg Roach 'd_gid', 2236fd01894SGreg Roach 'd_day', 2246fd01894SGreg Roach 'd_month', 2256fd01894SGreg Roach 'd_mon', 2266fd01894SGreg Roach 'd_year', 2276fd01894SGreg Roach 'd_julianday1', 2286fd01894SGreg Roach 'd_julianday2', 2296fd01894SGreg Roach 'd_fact', 2306fd01894SGreg Roach 'd_type', 2316fd01894SGreg Roach ])->from('dates') 2326fd01894SGreg Roach ->where('d_file', '=', $tree1->id()); 2336fd01894SGreg Roach }); 2346fd01894SGreg Roach 2356fd01894SGreg Roach (new Builder(DB::connection()))->from('link')->insertUsing([ 2366fd01894SGreg Roach 'l_file', 2376fd01894SGreg Roach 'l_from', 2386fd01894SGreg Roach 'l_type', 2396fd01894SGreg Roach 'l_to', 2406fd01894SGreg Roach ], static function (Builder $query) use ($tree1, $tree2): void { 2416fd01894SGreg Roach $query->select([ 2426fd01894SGreg Roach new Expression($tree2->id()), 2436fd01894SGreg Roach 'l_from', 2446fd01894SGreg Roach 'l_type', 2456fd01894SGreg Roach 'l_to', 2466fd01894SGreg Roach ])->from('link') 2476fd01894SGreg Roach ->whereNotIn('l_from', [Header::RECORD_TYPE, 'TRLR']) 2486fd01894SGreg Roach ->where('l_file', '=', $tree1->id()); 2496fd01894SGreg Roach }); 2506fd01894SGreg Roach 2516fd01894SGreg Roach FlashMessages::addMessage(I18N::translate('The family trees have been merged successfully.'), 'success'); 2526fd01894SGreg Roach 2536fd01894SGreg Roach $url = route(ManageTrees::class, ['tree' => $tree2->name()]); 2546fd01894SGreg Roach } else { 2556fd01894SGreg Roach $url = route(MergeTreesPage::class, [ 2566fd01894SGreg Roach 'tree1_name' => $tree1->name(), 2576fd01894SGreg Roach 'tree2_name' => $tree2->name(), 2586fd01894SGreg Roach ]); 2596fd01894SGreg Roach } 2606fd01894SGreg Roach 2616fd01894SGreg Roach return redirect($url); 2626fd01894SGreg Roach } 2636fd01894SGreg Roach} 264