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