1b4a2f885SGreg Roach<?php 2b4a2f885SGreg Roach 3b4a2f885SGreg Roach/** 4b4a2f885SGreg Roach * webtrees: online genealogy 5d11be702SGreg Roach * Copyright (C) 2023 webtrees development team 6b4a2f885SGreg Roach * This program is free software: you can redistribute it and/or modify 7b4a2f885SGreg Roach * it under the terms of the GNU General Public License as published by 8b4a2f885SGreg Roach * the Free Software Foundation, either version 3 of the License, or 9b4a2f885SGreg Roach * (at your option) any later version. 10b4a2f885SGreg Roach * This program is distributed in the hope that it will be useful, 11b4a2f885SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 12b4a2f885SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13b4a2f885SGreg Roach * GNU General Public License for more details. 14b4a2f885SGreg Roach * You should have received a copy of the GNU General Public License 1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>. 16b4a2f885SGreg Roach */ 17b4a2f885SGreg Roach 18b4a2f885SGreg Roachdeclare(strict_types=1); 19b4a2f885SGreg Roach 20b4a2f885SGreg Roachnamespace Fisharebest\Webtrees\Factories; 21b4a2f885SGreg Roach 22b4a2f885SGreg Roachuse Fisharebest\Webtrees\Contracts\XrefFactoryInterface; 23*6f4ec3caSGreg Roachuse Fisharebest\Webtrees\DB; 24b4a2f885SGreg Roachuse Fisharebest\Webtrees\Site; 25b4a2f885SGreg Roach 26b4a2f885SGreg Roach/** 27b4a2f885SGreg Roach * Make an XREF. 28b4a2f885SGreg Roach */ 29b4a2f885SGreg Roachclass XrefFactory implements XrefFactoryInterface 30b4a2f885SGreg Roach{ 31b4a2f885SGreg Roach /** 32b4a2f885SGreg Roach * Create a new XREF. 33b4a2f885SGreg Roach * 34b4a2f885SGreg Roach * @param string $record_type 35b4a2f885SGreg Roach * 36b4a2f885SGreg Roach * @return string 37b4a2f885SGreg Roach */ 38b4a2f885SGreg Roach public function make(string $record_type): string 39b4a2f885SGreg Roach { 40b4a2f885SGreg Roach return $this->generate('X', ''); 41b4a2f885SGreg Roach } 42b4a2f885SGreg Roach 43b4a2f885SGreg Roach /** 44b4a2f885SGreg Roach * @param string $prefix 45b4a2f885SGreg Roach * @param string $suffix 46b4a2f885SGreg Roach * 47b4a2f885SGreg Roach * @return string 48b4a2f885SGreg Roach */ 49b4a2f885SGreg Roach protected function generate(string $prefix, string $suffix): string 50b4a2f885SGreg Roach { 51b4a2f885SGreg Roach // Lock the row, so that only one new XREF may be generated at a time. 528a0b11f9SGreg Roach $num = (int) DB::table('site_setting') 53b4a2f885SGreg Roach ->where('setting_name', '=', 'next_xref') 54b4a2f885SGreg Roach ->lockForUpdate() 558a0b11f9SGreg Roach ->value('setting_value'); 56b4a2f885SGreg Roach 57b4a2f885SGreg Roach $increment = 1.0; 5813598780SGreg Roach 59b4a2f885SGreg Roach do { 6013598780SGreg Roach $num += (int) $increment; 61b4a2f885SGreg Roach 62b4a2f885SGreg Roach // This exponential increment allows us to scan over large blocks of 63b4a2f885SGreg Roach // existing data in a reasonable time. 64b4a2f885SGreg Roach $increment *= 1.01; 65b4a2f885SGreg Roach 66b4a2f885SGreg Roach $xref = $prefix . $num . $suffix; 67b4a2f885SGreg Roach 68b4a2f885SGreg Roach // Records may already exist with this sequence number. 69b4a2f885SGreg Roach $already_used = 70b4a2f885SGreg Roach DB::table('individuals')->where('i_id', '=', $xref)->exists() || 71b4a2f885SGreg Roach DB::table('families')->where('f_id', '=', $xref)->exists() || 72b4a2f885SGreg Roach DB::table('sources')->where('s_id', '=', $xref)->exists() || 73b4a2f885SGreg Roach DB::table('media')->where('m_id', '=', $xref)->exists() || 74b4a2f885SGreg Roach DB::table('other')->where('o_id', '=', $xref)->exists() || 75b4a2f885SGreg Roach DB::table('change')->where('xref', '=', $xref)->exists(); 76b4a2f885SGreg Roach } while ($already_used); 77b4a2f885SGreg Roach 78b4a2f885SGreg Roach Site::setPreference('next_xref', (string) $num); 79b4a2f885SGreg Roach 80b4a2f885SGreg Roach return $xref; 81b4a2f885SGreg Roach } 82b4a2f885SGreg Roach} 83