1<?php 2 3/** 4 * webtrees: online genealogy 5 * Copyright (C) 2019 webtrees development team 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18declare(strict_types=1); 19 20namespace Fisharebest\Webtrees\Http\RequestHandlers; 21 22use Fisharebest\Webtrees\Carbon; 23use Fisharebest\Webtrees\Family; 24use Fisharebest\Webtrees\Gedcom; 25use Fisharebest\Webtrees\GedcomRecord; 26use Fisharebest\Webtrees\Http\ViewResponseTrait; 27use Fisharebest\Webtrees\I18N; 28use Fisharebest\Webtrees\Individual; 29use Fisharebest\Webtrees\Media; 30use Fisharebest\Webtrees\Note; 31use Fisharebest\Webtrees\Repository; 32use Fisharebest\Webtrees\Services\PendingChangesService; 33use Fisharebest\Webtrees\Services\TreeService; 34use Fisharebest\Webtrees\Source; 35use Fisharebest\Webtrees\Tree; 36use Illuminate\Database\Capsule\Manager as DB; 37use InvalidArgumentException; 38use Psr\Http\Message\ResponseInterface; 39use Psr\Http\Message\ServerRequestInterface; 40use Psr\Http\Server\RequestHandlerInterface; 41 42use function assert; 43use function key; 44use function preg_match; 45use function reset; 46use function route; 47 48/** 49 * Show all pending changes. 50 */ 51class PendingChanges implements RequestHandlerInterface 52{ 53 use ViewResponseTrait; 54 55 /** @var PendingChangesService */ 56 private $pending_changes_service; 57 58 /** @var TreeService */ 59 private $tree_service; 60 61 /** 62 * @param PendingChangesService $pending_changes_service 63 * @param TreeService $tree_service 64 */ 65 public function __construct(PendingChangesService $pending_changes_service, TreeService $tree_service) 66 { 67 $this->pending_changes_service = $pending_changes_service; 68 $this->tree_service = $tree_service; 69 } 70 71 /** 72 * @param ServerRequestInterface $request 73 * 74 * @return ResponseInterface 75 */ 76 public function handle(ServerRequestInterface $request): ResponseInterface 77 { 78 $tree = $request->getAttribute('tree'); 79 assert($tree instanceof Tree, new InvalidArgumentException()); 80 81 $url = $request->getQueryParams()['url'] ?? route('tree-page', ['tree' => $tree->name()]); 82 83 $rows = DB::table('change') 84 ->join('user', 'user.user_id', '=', 'change.user_id') 85 ->join('gedcom', 'gedcom.gedcom_id', '=', 'change.gedcom_id') 86 ->where('status', '=', 'pending') 87 ->orderBy('change.gedcom_id') 88 ->orderBy('change.xref') 89 ->orderBy('change.change_id') 90 ->select(['change.*', 'user.user_name', 'user.real_name', 'gedcom_name']) 91 ->get(); 92 93 $changes = []; 94 foreach ($rows as $row) { 95 $row->change_time = Carbon::make($row->change_time); 96 97 $change_tree = $this->tree_service->all()->get($row->gedcom_name); 98 99 preg_match('/^0 (?:@' . Gedcom::REGEX_XREF . '@ )?(' . Gedcom::REGEX_TAG . ')/', $row->old_gedcom . $row->new_gedcom, $match); 100 101 switch ($match[1]) { 102 case 'INDI': 103 $row->record = new Individual($row->xref, $row->old_gedcom, $row->new_gedcom, $change_tree); 104 break; 105 case 'FAM': 106 $row->record = new Family($row->xref, $row->old_gedcom, $row->new_gedcom, $change_tree); 107 break; 108 case 'SOUR': 109 $row->record = new Source($row->xref, $row->old_gedcom, $row->new_gedcom, $change_tree); 110 break; 111 case 'REPO': 112 $row->record = new Repository($row->xref, $row->old_gedcom, $row->new_gedcom, $change_tree); 113 break; 114 case 'OBJE': 115 $row->record = new Media($row->xref, $row->old_gedcom, $row->new_gedcom, $change_tree); 116 break; 117 case 'NOTE': 118 $row->record = new Note($row->xref, $row->old_gedcom, $row->new_gedcom, $change_tree); 119 break; 120 default: 121 $row->record = new GedcomRecord($row->xref, $row->old_gedcom, $row->new_gedcom, $change_tree); 122 break; 123 } 124 125 $changes[$row->gedcom_id][$row->xref][] = $row; 126 } 127 128 $title = I18N::translate('Pending changes'); 129 130 // If the current tree has changes, activate that tab. Otherwise activate the first tab. 131 if (($changes[$tree->id()] ?? []) === []) { 132 reset($changes); 133 $active_tree_id = key($changes); 134 } else { 135 $active_tree_id = $tree->id(); 136 } 137 138 return $this->viewResponse('pending-changes-page', [ 139 'active_tree_id' => $active_tree_id, 140 'changes' => $changes, 141 'title' => $title, 142 'tree' => $tree, 143 'url' => $url, 144 ]); 145 } 146} 147