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\Services; 21 22use Fisharebest\Webtrees\Carbon; 23use Fisharebest\Webtrees\Functions\FunctionsImport; 24use Fisharebest\Webtrees\GedcomRecord; 25use Fisharebest\Webtrees\Tree; 26use Illuminate\Database\Capsule\Manager as DB; 27use Illuminate\Database\Query\Builder; 28use Illuminate\Database\Query\Expression; 29 30/** 31 * Manage pending changes 32 */ 33class PendingChangesService 34{ 35 /** 36 * Accept all changes to a tree. 37 * 38 * @param Tree $tree 39 * 40 * @return void 41 */ 42 public function acceptTree(Tree $tree): void 43 { 44 $changes = DB::table('change') 45 ->where('gedcom_id', '=', $tree->id()) 46 ->where('status', '=', 'pending') 47 ->orderBy('change_id') 48 ->get(); 49 50 foreach ($changes as $change) { 51 if ($change->new_gedcom === '') { 52 // delete 53 FunctionsImport::updateRecord($change->old_gedcom, $tree, true); 54 } else { 55 // add/update 56 FunctionsImport::updateRecord($change->new_gedcom, $tree, false); 57 } 58 59 DB::table('change') 60 ->where('change_id', '=', $change->change_id) 61 ->update(['status' => 'accepted']); 62 } 63 } 64 65 /** 66 * Accept all changes to a record. 67 * 68 * @param GedcomRecord $record 69 */ 70 public function acceptRecord(GedcomRecord $record): void 71 { 72 $changes = DB::table('change') 73 ->where('gedcom_id', '=', $record->tree()->id()) 74 ->where('xref', '=', $record->xref()) 75 ->where('status', '=', 'pending') 76 ->orderBy('change_id') 77 ->get(); 78 79 foreach ($changes as $change) { 80 if ($change->new_gedcom === '') { 81 // delete 82 FunctionsImport::updateRecord($change->old_gedcom, $record->tree(), true); 83 } else { 84 // add/update 85 FunctionsImport::updateRecord($change->new_gedcom, $record->tree(), false); 86 } 87 88 DB::table('change') 89 ->where('change_id', '=', $change->change_id) 90 ->update(['status' => 'accepted']); 91 } 92 } 93 94 /** 95 * Accept a change (and previous changes) to a record. 96 * 97 * @param GedcomRecord $record 98 * @param string $change_id 99 */ 100 public function acceptChange(GedcomRecord $record, string $change_id): void 101 { 102 $changes = DB::table('change') 103 ->where('gedcom_id', '=', $record->tree()->id()) 104 ->where('xref', '=', $record->xref()) 105 ->where('change_id', '<=', $change_id) 106 ->where('status', '=', 'pending') 107 ->orderBy('change_id') 108 ->get(); 109 110 foreach ($changes as $change) { 111 if ($change->new_gedcom === '') { 112 // delete 113 FunctionsImport::updateRecord($change->old_gedcom, $record->tree(), true); 114 } else { 115 // add/update 116 FunctionsImport::updateRecord($change->new_gedcom, $record->tree(), false); 117 } 118 119 DB::table('change') 120 ->where('change_id', '=', $change->change_id) 121 ->update(['status' => 'accepted']); 122 } 123 } 124 125 /** 126 * Reject all changes to a tree. 127 * 128 * @param Tree $tree 129 */ 130 public function rejectTree(Tree $tree): void 131 { 132 DB::table('change') 133 ->where('gedcom_id', '=', $tree->id()) 134 ->where('status', '=', 'pending') 135 ->update(['status' => 'rejected']); 136 } 137 138 /** 139 * Reject a change (subsequent changes) to a record. 140 * 141 * @param GedcomRecord $record 142 * @param string $change_id 143 */ 144 public function rejectChange(GedcomRecord $record, string $change_id): void 145 { 146 DB::table('change') 147 ->where('gedcom_id', '=', $record->tree()->id()) 148 ->where('xref', '=', $record->xref()) 149 ->where('change_id', '>=', $change_id) 150 ->where('status', '=', 'pending') 151 ->update(['status' => 'rejected']); 152 } 153 154 /** 155 * Reject all changes to a record. 156 * 157 * @param GedcomRecord $record 158 */ 159 public function rejectRecord(GedcomRecord $record): void 160 { 161 DB::table('change') 162 ->where('gedcom_id', '=', $record->tree()->id()) 163 ->where('xref', '=', $record->xref()) 164 ->where('status', '=', 'pending') 165 ->update(['status' => 'rejected']); 166 } 167 168 /** 169 * Generate a query for filtering the changes log. 170 * 171 * @param string[] $params 172 * 173 * @return Builder 174 */ 175 public function changesQuery(array $params): Builder 176 { 177 $tree = $params['tree']; 178 $from = $params['from'] ?? ''; 179 $to = $params['to'] ?? ''; 180 $type = $params['type'] ?? ''; 181 $oldged = $params['oldged'] ?? ''; 182 $newged = $params['newged'] ?? ''; 183 $xref = $params['xref'] ?? ''; 184 $username = $params['username'] ?? ''; 185 186 $query = DB::table('change') 187 ->leftJoin('user', 'user.user_id', '=', 'change.user_id') 188 ->join('gedcom', 'gedcom.gedcom_id', '=', 'change.gedcom_id') 189 ->select(['change.*', new Expression("COALESCE(user_name, '<none>') AS user_name"), 'gedcom_name']) 190 ->where('gedcom_name', '=', $tree); 191 192 if ($from !== '') { 193 $query->where('change_time', '>=', $from); 194 } 195 196 if ($to !== '') { 197 // before end of the day 198 $query->where('change_time', '<', Carbon::make($to)->addDay()); 199 } 200 201 if ($type !== '') { 202 $query->where('status', '=', $type); 203 } 204 205 if ($oldged !== '') { 206 $query->whereContains('old_gedcom', $oldged); 207 } 208 if ($newged !== '') { 209 $query->whereContains('new_gedcom', $oldged); 210 } 211 212 if ($xref !== '') { 213 $query->where('xref', '=', $xref); 214 } 215 216 if ($username !== '') { 217 $query->whereContains('user_name', $username); 218 } 219 220 return $query; 221 } 222} 223