Passed
Push — feature/code-analysis ( 00c5b4...e321b8 )
by Jonathan
13:27
created

LegacyXrefFactory::generate()   B

Complexity

Conditions 8
Paths 7

Size

Total Lines 38
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 24
nc 7
nop 2
dl 0
loc 38
rs 8.4444
c 1
b 0
f 0
1
<?php
2
3
/**
4
 * webtrees-lib: MyArtJaub library for webtrees
5
 *
6
 * @package MyArtJaub\Webtrees
7
 * @subpackage MiscExtensions
8
 * @author Jonathan Jaubart <[email protected]>
9
 * @copyright Copyright (c) 2022-2025, Jonathan Jaubart
10
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3
11
 */
12
13
declare(strict_types=1);
14
15
namespace MyArtJaub\Webtrees\Module\MiscExtensions\Factories;
16
17
use Fisharebest\Webtrees\Tree;
18
use Fisharebest\Webtrees\Factories\XrefFactory;
19
use Illuminate\Database\Capsule\Manager as DB;
20
21
/**
22
 * Xref generator similar to webtrees 1.0.
23
 */
24
class LegacyXrefFactory extends XrefFactory
25
{
26
    protected const TYPE_TO_PREFIX = [
27
        'INDI' => 'I',
28
        'FAM'  => 'F',
29
        'OBJE' => 'M',
30
        'NOTE' => 'N',
31
        'SOUR' => 'S',
32
        'REPO' => 'R',
33
    ];
34
35
    /**
36
     * {@inheritDoc}
37
     * @see \Fisharebest\Webtrees\Factories\XrefFactory::make()
38
     */
39
    public function make(string $record_type): string
40
    {
41
        $prefix = static::TYPE_TO_PREFIX[$record_type] ?? 'X';
42
43
        return $this->generate($prefix, '');
44
    }
45
46
    /**
47
     * {@inheritDoc}
48
     * @see \Fisharebest\Webtrees\Factories\XrefFactory::generate()
49
     */
50
    protected function generate($prefix, $suffix): string
51
    {
52
        $tree = app(Tree::class);
53
        if (!$tree instanceof Tree) {
0 ignored issues
show
introduced by
$tree is always a sub-type of Fisharebest\Webtrees\Tree.
Loading history...
54
            return parent::generate($prefix, $suffix);
55
        }
56
57
        $setting_name = 'MAJ_MISC_XREF_NEXT_' . $prefix;
58
        // Lock the row, so that only one new XREF may be generated at a time.
59
        $num = (int) DB::table('gedcom_setting')
60
            ->where('gedcom_id', '=', $tree->id())
61
            ->where('setting_name', '=', $setting_name)
62
            ->lockForUpdate()
63
            ->value('setting_value');
64
65
        $increment = 1.0;
66
        do {
67
            $num += (int) $increment;
68
69
            // This exponential increment allows us to scan over large blocks of
70
            // existing data in a reasonable time.
71
            $increment *= 1.01;
72
73
            $xref = $prefix . $num . $suffix;
74
75
            // Records may already exist with this sequence number.
76
            $already_used =
77
                DB::table('individuals')->where('i_file', '=', $tree->id())->where('i_id', '=', $xref)->exists() ||
78
                DB::table('families')->where('f_file', '=', $tree->id())->where('f_id', '=', $xref)->exists() ||
79
                DB::table('sources')->where('s_file', '=', $tree->id())->where('s_id', '=', $xref)->exists() ||
80
                DB::table('media')->where('m_file', '=', $tree->id())->where('m_id', '=', $xref)->exists() ||
81
                DB::table('other')->where('o_file', '=', $tree->id())->where('o_id', '=', $xref)->exists() ||
82
                DB::table('change')->where('gedcom_id', '=', $tree->id())->where('xref', '=', $xref)->exists();
83
        } while ($already_used);
84
85
        $tree->setPreference($setting_name, (string) $num);
86
87
        return $xref;
88
    }
89
}
90