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