Passed
Push — master ( dec352...b4a2f8 )
by Greg
05:56
created

XrefFactory   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 51
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 21
c 1
b 0
f 0
dl 0
loc 51
rs 10
wmc 8

2 Methods

Rating   Name   Duplication   Size   Complexity  
B generate() 0 31 7
A make() 0 3 1
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
18
declare(strict_types=1);
19
20
namespace Fisharebest\Webtrees\Factories;
21
22
use Fisharebest\Webtrees\Contracts\XrefFactoryInterface;
23
use Fisharebest\Webtrees\Site;
24
use Illuminate\Database\Capsule\Manager as DB;
25
26
/**
27
 * Make an XREF.
28
 */
29
class XrefFactory implements XrefFactoryInterface
30
{
31
    /**
32
     * Create a new XREF.
33
     *
34
     * @param string $record_type
35
     *
36
     * @return string
37
     */
38
    public function make(string $record_type): string
39
    {
40
        return $this->generate('X', '');
41
    }
42
43
    /**
44
     * @param string $prefix
45
     * @param string $suffix
46
     *
47
     * @return string
48
     */
49
    protected function generate(string $prefix, string $suffix): string
50
    {
51
        // Lock the row, so that only one new XREF may be generated at a time.
52
        DB::table('site_setting')
53
            ->where('setting_name', '=', 'next_xref')
54
            ->lockForUpdate()
55
            ->get();
56
57
        $increment = 1.0;
58
        do {
59
            $num = (int) Site::getPreference('next_xref') + (int) $increment;
60
61
            // This exponential increment allows us to scan over large blocks of
62
            // existing data in a reasonable time.
63
            $increment *= 1.01;
64
65
            $xref = $prefix . $num . $suffix;
66
67
            // Records may already exist with this sequence number.
68
            $already_used =
69
                DB::table('individuals')->where('i_id', '=', $xref)->exists() ||
70
                DB::table('families')->where('f_id', '=', $xref)->exists() ||
71
                DB::table('sources')->where('s_id', '=', $xref)->exists() ||
72
                DB::table('media')->where('m_id', '=', $xref)->exists() ||
73
                DB::table('other')->where('o_id', '=', $xref)->exists() ||
74
                DB::table('change')->where('xref', '=', $xref)->exists();
75
        } while ($already_used);
76
77
        Site::setPreference('next_xref', (string) $num);
78
79
        return $xref;
80
    }
81
}
82