122e73debSGreg Roach<?php 222e73debSGreg Roach 322e73debSGreg Roach/** 422e73debSGreg Roach * webtrees: online genealogy 5d11be702SGreg Roach * Copyright (C) 2023 webtrees development team 622e73debSGreg Roach * This program is free software: you can redistribute it and/or modify 722e73debSGreg Roach * it under the terms of the GNU General Public License as published by 822e73debSGreg Roach * the Free Software Foundation, either version 3 of the License, or 922e73debSGreg Roach * (at your option) any later version. 1022e73debSGreg Roach * This program is distributed in the hope that it will be useful, 1122e73debSGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 1222e73debSGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1322e73debSGreg Roach * GNU General Public License for more details. 1422e73debSGreg Roach * You should have received a copy of the GNU General Public License 1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>. 1622e73debSGreg Roach */ 1722e73debSGreg Roach 1822e73debSGreg Roachdeclare(strict_types=1); 1922e73debSGreg Roach 2022e73debSGreg Roachnamespace Fisharebest\Webtrees\Http\RequestHandlers; 2122e73debSGreg Roach 22*5cac87aeSGreg Roachuse DateTimeImmutable; 23*5cac87aeSGreg Roachuse DateTimeZone; 2422e73debSGreg Roachuse Fisharebest\Algorithm\MyersDiff; 25*5cac87aeSGreg Roachuse Fisharebest\Webtrees\Auth; 26*5cac87aeSGreg Roachuse Fisharebest\Webtrees\Contracts\UserInterface; 2722e73debSGreg Roachuse Fisharebest\Webtrees\Gedcom; 2822e73debSGreg Roachuse Fisharebest\Webtrees\I18N; 296b9cb339SGreg Roachuse Fisharebest\Webtrees\Registry; 3022e73debSGreg Roachuse Fisharebest\Webtrees\Services\DatatablesService; 3122e73debSGreg Roachuse Fisharebest\Webtrees\Services\PendingChangesService; 32b55cbc6bSGreg Roachuse Fisharebest\Webtrees\Validator; 3322e73debSGreg Roachuse Psr\Http\Message\ResponseInterface; 3422e73debSGreg Roachuse Psr\Http\Message\ServerRequestInterface; 3522e73debSGreg Roachuse Psr\Http\Server\RequestHandlerInterface; 3622e73debSGreg Roach 3722e73debSGreg Roachuse function e; 3822e73debSGreg Roachuse function explode; 3922e73debSGreg Roachuse function implode; 4022e73debSGreg Roachuse function preg_replace_callback; 4122e73debSGreg Roach 4222e73debSGreg Roach/** 4322e73debSGreg Roach * Find pending changes. 4422e73debSGreg Roach */ 4522e73debSGreg Roachclass PendingChangesLogData implements RequestHandlerInterface 4622e73debSGreg Roach{ 47c4943cffSGreg Roach private DatatablesService $datatables_service; 4822e73debSGreg Roach 49c4943cffSGreg Roach private MyersDiff $myers_diff; 5022e73debSGreg Roach 51c4943cffSGreg Roach private PendingChangesService $pending_changes_service; 5222e73debSGreg Roach 5322e73debSGreg Roach /** 5422e73debSGreg Roach * @param DatatablesService $datatables_service 5522e73debSGreg Roach * @param MyersDiff $myers_diff 5622e73debSGreg Roach * @param PendingChangesService $pending_changes_service 5722e73debSGreg Roach */ 5822e73debSGreg Roach public function __construct( 5922e73debSGreg Roach DatatablesService $datatables_service, 6022e73debSGreg Roach MyersDiff $myers_diff, 61dce3fc17SGreg Roach PendingChangesService $pending_changes_service 620aca0985SScrutinizer Auto-Fixer ) { 6322e73debSGreg Roach $this->datatables_service = $datatables_service; 6422e73debSGreg Roach $this->myers_diff = $myers_diff; 6522e73debSGreg Roach $this->pending_changes_service = $pending_changes_service; 6622e73debSGreg Roach } 6722e73debSGreg Roach 6822e73debSGreg Roach /** 6922e73debSGreg Roach * @param ServerRequestInterface $request 7022e73debSGreg Roach * 7122e73debSGreg Roach * @return ResponseInterface 7222e73debSGreg Roach */ 7322e73debSGreg Roach public function handle(ServerRequestInterface $request): ResponseInterface 7422e73debSGreg Roach { 75b55cbc6bSGreg Roach $tree = Validator::attributes($request)->tree(); 7657bfa969SGreg Roach $params = $request->getQueryParams(); 7757bfa969SGreg Roach $params['tree'] = $tree->name(); 7857bfa969SGreg Roach 7957bfa969SGreg Roach $query = $this->pending_changes_service->changesQuery($params); 8022e73debSGreg Roach 81f70bcff5SGreg Roach $callback = function (object $row) use ($tree): array { 82aaad15c2SGreg Roach $old_lines = $row->old_gedcom === '' ? [] : explode("\n", $row->old_gedcom); 83aaad15c2SGreg Roach $new_lines = $row->new_gedcom === '' ? [] : explode("\n", $row->new_gedcom); 8422e73debSGreg Roach 8522e73debSGreg Roach $differences = $this->myers_diff->calculate($old_lines, $new_lines); 8622e73debSGreg Roach $diff_lines = []; 8722e73debSGreg Roach 8822e73debSGreg Roach foreach ($differences as $difference) { 8922e73debSGreg Roach switch ($difference[1]) { 9022e73debSGreg Roach case MyersDiff::DELETE: 911d4c8286SGreg Roach $diff_lines[] = '<del>' . e($difference[0]) . '</del>'; 9222e73debSGreg Roach break; 9322e73debSGreg Roach case MyersDiff::INSERT: 941d4c8286SGreg Roach $diff_lines[] = '<ins>' . e($difference[0]) . '</ins>'; 9522e73debSGreg Roach break; 9622e73debSGreg Roach default: 971d4c8286SGreg Roach $diff_lines[] = e($difference[0]); 9822e73debSGreg Roach } 9922e73debSGreg Roach } 10022e73debSGreg Roach 10122e73debSGreg Roach // Only convert valid xrefs to links 1026b9cb339SGreg Roach $record = Registry::gedcomRecordFactory()->make($row->xref, $tree); 10322e73debSGreg Roach 104*5cac87aeSGreg Roach $change_time = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $row->change_time, new DateTimeZone('UTC')) 105*5cac87aeSGreg Roach ->setTimezone(new DateTimeZone(Auth::user()->getPreference(UserInterface::PREF_TIME_ZONE, 'UTC'))) 106*5cac87aeSGreg Roach ->format('Y-m-d H:i:s T'); 107*5cac87aeSGreg Roach 10822e73debSGreg Roach return [ 10922e73debSGreg Roach $row->change_id, 110*5cac87aeSGreg Roach $change_time, 11122e73debSGreg Roach I18N::translate($row->status), 11222e73debSGreg Roach $record ? '<a href="' . e($record->url()) . '">' . $record->xref() . '</a>' : $row->xref, 11322e73debSGreg Roach '<div class="gedcom-data" dir="ltr">' . 11422e73debSGreg Roach preg_replace_callback( 11522e73debSGreg Roach '/@(' . Gedcom::REGEX_XREF . ')@/', 11622e73debSGreg Roach static function (array $match) use ($tree): string { 1176b9cb339SGreg Roach $record = Registry::gedcomRecordFactory()->make($match[1], $tree); 11822e73debSGreg Roach 11922e73debSGreg Roach return $record ? '<a href="' . e($record->url()) . '">' . $match[0] . '</a>' : $match[0]; 12022e73debSGreg Roach }, 12122e73debSGreg Roach implode("\n", $diff_lines) 12222e73debSGreg Roach ) . 12322e73debSGreg Roach '</div>', 12422e73debSGreg Roach $row->user_name, 12522e73debSGreg Roach $row->gedcom_name, 12622e73debSGreg Roach ]; 12722e73debSGreg Roach }; 12822e73debSGreg Roach 12913aa75d8SGreg Roach return $this->datatables_service->handleQuery($request, $query, [], [], $callback); 13022e73debSGreg Roach } 13122e73debSGreg Roach} 132