xref: /webtrees/app/Services/ClipboardService.php (revision c0dc1dc8776d0d9214741483e39305c5e08e2358)
1*c0dc1dc8SGreg Roach<?php
2*c0dc1dc8SGreg Roach/**
3*c0dc1dc8SGreg Roach * webtrees: online genealogy
4*c0dc1dc8SGreg Roach * Copyright (C) 2018 webtrees development team
5*c0dc1dc8SGreg Roach * This program is free software: you can redistribute it and/or modify
6*c0dc1dc8SGreg Roach * it under the terms of the GNU General Public License as published by
7*c0dc1dc8SGreg Roach * the Free Software Foundation, either version 3 of the License, or
8*c0dc1dc8SGreg Roach * (at your option) any later version.
9*c0dc1dc8SGreg Roach * This program is distributed in the hope that it will be useful,
10*c0dc1dc8SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
11*c0dc1dc8SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12*c0dc1dc8SGreg Roach * GNU General Public License for more details.
13*c0dc1dc8SGreg Roach * You should have received a copy of the GNU General Public License
14*c0dc1dc8SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
15*c0dc1dc8SGreg Roach */
16*c0dc1dc8SGreg Roachdeclare(strict_types=1);
17*c0dc1dc8SGreg Roach
18*c0dc1dc8SGreg Roachnamespace Fisharebest\Webtrees\Services;
19*c0dc1dc8SGreg Roach
20*c0dc1dc8SGreg Roachuse Fisharebest\Webtrees\Fact;
21*c0dc1dc8SGreg Roachuse Fisharebest\Webtrees\GedcomRecord;
22*c0dc1dc8SGreg Roachuse Fisharebest\Webtrees\Session;
23*c0dc1dc8SGreg Roach
24*c0dc1dc8SGreg Roach/**
25*c0dc1dc8SGreg Roach * Copy and past facts between records.
26*c0dc1dc8SGreg Roach */
27*c0dc1dc8SGreg Roachclass ClipboardService
28*c0dc1dc8SGreg Roach{
29*c0dc1dc8SGreg Roach    // Maximum number of entries in the clipboard.
30*c0dc1dc8SGreg Roach    private const CLIPBOARD_SIZE = 10;
31*c0dc1dc8SGreg Roach
32*c0dc1dc8SGreg Roach    /**
33*c0dc1dc8SGreg Roach     * Copy a fact to the clipboard.
34*c0dc1dc8SGreg Roach     *
35*c0dc1dc8SGreg Roach     * @param Fact $fact
36*c0dc1dc8SGreg Roach     */
37*c0dc1dc8SGreg Roach    public function copyFact(Fact $fact): void {
38*c0dc1dc8SGreg Roach        $clipboard = Session::get('clipboard', []);
39*c0dc1dc8SGreg Roach
40*c0dc1dc8SGreg Roach        switch ($fact->getTag()) {
41*c0dc1dc8SGreg Roach            case 'NOTE':
42*c0dc1dc8SGreg Roach            case 'SOUR':
43*c0dc1dc8SGreg Roach            case 'OBJE':
44*c0dc1dc8SGreg Roach                // paste this anywhere
45*c0dc1dc8SGreg Roach                $type = 'all';
46*c0dc1dc8SGreg Roach                break;
47*c0dc1dc8SGreg Roach            default:
48*c0dc1dc8SGreg Roach                // paste only to the same record type
49*c0dc1dc8SGreg Roach                $type = $fact->record()::RECORD_TYPE;
50*c0dc1dc8SGreg Roach                break;
51*c0dc1dc8SGreg Roach        }
52*c0dc1dc8SGreg Roach
53*c0dc1dc8SGreg Roach        // If we are copying the same fact twice, make sure the new one is at the top.
54*c0dc1dc8SGreg Roach        $fact_id = $fact->id();
55*c0dc1dc8SGreg Roach
56*c0dc1dc8SGreg Roach        unset($clipboard[$fact_id]);
57*c0dc1dc8SGreg Roach
58*c0dc1dc8SGreg Roach        $clipboard[$fact_id] = [
59*c0dc1dc8SGreg Roach            'type'    => $type,
60*c0dc1dc8SGreg Roach            'factrec' => $fact->gedcom(),
61*c0dc1dc8SGreg Roach            'fact'    => $fact->getTag(),
62*c0dc1dc8SGreg Roach        ];
63*c0dc1dc8SGreg Roach
64*c0dc1dc8SGreg Roach        // The clipboard only holds a limited number of facts.
65*c0dc1dc8SGreg Roach        $clipboard = array_slice($clipboard, -self::CLIPBOARD_SIZE);
66*c0dc1dc8SGreg Roach
67*c0dc1dc8SGreg Roach        Session::put('clipboard', $clipboard);
68*c0dc1dc8SGreg Roach    }
69*c0dc1dc8SGreg Roach
70*c0dc1dc8SGreg Roach    /**
71*c0dc1dc8SGreg Roach     * Copy a fact from the clipboard to a record.
72*c0dc1dc8SGreg Roach     *
73*c0dc1dc8SGreg Roach     * @param string       $fact_id
74*c0dc1dc8SGreg Roach     * @param GedcomRecord $record
75*c0dc1dc8SGreg Roach     *
76*c0dc1dc8SGreg Roach     * @return bool
77*c0dc1dc8SGreg Roach     */
78*c0dc1dc8SGreg Roach    public function pasteFact(string $fact_id, GedcomRecord $record): bool {
79*c0dc1dc8SGreg Roach        $clipboard = Session::get('clipboard');
80*c0dc1dc8SGreg Roach
81*c0dc1dc8SGreg Roach        if (isset($clipboard[$fact_id])) {
82*c0dc1dc8SGreg Roach            $record->createFact($clipboard[$fact_id]['factrec'], true);
83*c0dc1dc8SGreg Roach            return true;
84*c0dc1dc8SGreg Roach        }
85*c0dc1dc8SGreg Roach
86*c0dc1dc8SGreg Roach        return false;
87*c0dc1dc8SGreg Roach    }
88*c0dc1dc8SGreg Roach
89*c0dc1dc8SGreg Roach    /**
90*c0dc1dc8SGreg Roach     * Createa a list of facts that can be pasted into a given record
91*c0dc1dc8SGreg Roach     *
92*c0dc1dc8SGreg Roach     * @param GedcomRecord $gedcom_record
93*c0dc1dc8SGreg Roach     *
94*c0dc1dc8SGreg Roach     * @return Fact[]
95*c0dc1dc8SGreg Roach     */
96*c0dc1dc8SGreg Roach    public function pastableFacts(GedcomRecord $gedcom_record): array {
97*c0dc1dc8SGreg Roach        // The facts are stored in the session.
98*c0dc1dc8SGreg Roach        $clipboard = Session::get('clipboard', []);
99*c0dc1dc8SGreg Roach
100*c0dc1dc8SGreg Roach        // Put the most recently copied fact at the top of the list.
101*c0dc1dc8SGreg Roach        $clipboard = array_reverse($clipboard);
102*c0dc1dc8SGreg Roach
103*c0dc1dc8SGreg Roach        // Only include facts that can be pasted onto this record.
104*c0dc1dc8SGreg Roach        $clipboard = array_filter($clipboard, function(array $clipping) use ($gedcom_record): bool {
105*c0dc1dc8SGreg Roach            return $clipping['type'] == $gedcom_record::RECORD_TYPE || $clipping['type'] == 'all';
106*c0dc1dc8SGreg Roach        });
107*c0dc1dc8SGreg Roach
108*c0dc1dc8SGreg Roach        // Create facts for the record.
109*c0dc1dc8SGreg Roach        $facts = array_map(function(array $clipping) use ($gedcom_record): Fact {
110*c0dc1dc8SGreg Roach            return new Fact($clipping['factrec'], $gedcom_record, md5($clipping['factrec']));
111*c0dc1dc8SGreg Roach        }, $clipboard);
112*c0dc1dc8SGreg Roach
113*c0dc1dc8SGreg Roach        return $facts;
114*c0dc1dc8SGreg Roach    }
115*c0dc1dc8SGreg Roach}
116