xref: /webtrees/app/Services/PendingChangesService.php (revision b5961194694c0b5b2dc4269689207eb972e3b20c)
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