Passed
Branch feature/2.0 (d2af8f)
by Jonathan
13:07
created

SosaCalculatorService   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 42
c 1
b 0
f 0
dl 0
loc 122
rs 10
wmc 19

5 Methods

Rating   Name   Duplication   Size   Complexity  
C addNode() 0 23 10
A __construct() 0 6 1
A computeAll() 0 10 2
A computeFromIndividual() 0 9 2
A flushTmpSosaTable() 0 5 4
1
<?php
2
3
/**
4
 * webtrees-lib: MyArtJaub library for webtrees
5
 *
6
 * @package MyArtJaub\Webtrees
7
 * @subpackage Sosa
8
 * @author Jonathan Jaubart <[email protected]>
9
 * @copyright Copyright (c) 2009-2020, 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\Sosa\Services;
16
17
use Fisharebest\Webtrees\Individual;
18
use Fisharebest\Webtrees\Registry;
19
use Fisharebest\Webtrees\Tree;
20
use Fisharebest\Webtrees\User;
21
22
/**
23
 * Service for Sosa ancestors calculations
24
 *
25
 */
26
class SosaCalculatorService
27
{
28
    /**
29
     * Maximium size for the temporary Sosa table
30
     * @var int TMP_SOSA_TABLE_LIMIT
31
     */
32
    private const TMP_SOSA_TABLE_LIMIT = 1000;
33
    
34
    /**
35
     * @var SosaRecordsService $sosa_records_service
36
     */
37
    private $sosa_records_service;
38
    
39
    /**
40
     * Reference user
41
     * @var User $user
42
     */
43
    private $user;
44
    
45
    /**
46
     * Reference tree
47
     * @var Tree $tree
48
     */
49
    private $tree;
50
    
51
    /**
52
     * Temporary Sosa table, used during construction
53
     * @var array<string,mixed> $tmp_sosa_table
54
     */
55
    private $tmp_sosa_table;
56
    
57
    /**
58
     * Constructor for the Sosa Calculator
59
     * 
60
     * @param SosaRecordsService $sosa_records_service
61
     * @param Tree $tree
62
     * @param User $user
63
     */
64
    public function __construct(SosaRecordsService $sosa_records_service, Tree $tree, User $user)
65
    {
66
        $this->sosa_records_service = $sosa_records_service;
67
        $this->tree = $tree;
68
        $this->user = $user;
69
        $this->tmp_sosa_table = array();
70
    }
71
    
72
    /**
73
     * Compute all Sosa ancestors from the user's root individual.
74
     * 
75
     * @return bool Result of the computation
76
     */
77
    public function computeAll(): bool
78
    {
79
        $root_id = $this->tree->getUserPreference($this->user, 'MAJ_SOSA_ROOT_ID');
80
        if($indi = Registry::individualFactory()->make($root_id, $this->tree)) {
81
            $this->sosa_records_service->deleteAll($this->tree, $this->user);
82
            $this->addNode($indi, 1);
83
            $this->flushTmpSosaTable(true);
84
            return true;
85
        }
86
        return false;
87
    }
88
    
89
    /**
90
     * Compute all Sosa Ancestors from a specified Individual
91
     * 
92
     * @param Individual $indi
93
     * @return bool
94
     */
95
    public function computeFromIndividual(Individual $indi) : bool
96
    {
97
        $current_sosas = $this->sosa_records_service->getSosaNumbers($indi);
0 ignored issues
show
Bug introduced by
The call to MyArtJaub\Webtrees\Modul...rvice::getSosaNumbers() has too few arguments starting with user. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

97
        /** @scrutinizer ignore-call */ 
98
        $current_sosas = $this->sosa_records_service->getSosaNumbers($indi);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
Bug introduced by
$indi of type Fisharebest\Webtrees\Individual is incompatible with the type Fisharebest\Webtrees\Tree expected by parameter $tree of MyArtJaub\Webtrees\Modul...rvice::getSosaNumbers(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

97
        $current_sosas = $this->sosa_records_service->getSosaNumbers(/** @scrutinizer ignore-type */ $indi);
Loading history...
98
        foreach(array_keys($current_sosas) as $sosa) {
99
            $this->sosa_records_service->deleteAncestorsFrom($this->tree, $this->user, $sosa);
100
            $this->addNode($indi, $sosa);
101
        }
102
        $this->flushTmpSosaTable(true);
103
        return true;
104
    }
105
    
106
    /**
107
     * Recursive method to add individual to the Sosa table, and flush it regularly
108
     * 
109
     * @param Individual $indi Individual to add
110
     * @param int $sosa Individual's sosa
111
     */
112
    private function addNode(Individual $indi, int $sosa) : void
113
    {
114
        $birth_year = $indi->getBirthDate()->gregorianYear();
115
        $birth_year_est = $birth_year === 0 ? $indi->getEstimatedBirthDate()->gregorianYear() : $birth_year;
116
        
117
        $death_year = $indi->getDeathDate()->gregorianYear();
118
        $death_year_est = $death_year === 0 ? $indi->getEstimatedDeathDate()->gregorianYear() : $death_year;
119
        
120
        $this->tmp_sosa_table[] = array(
121
            'indi' => $indi->xref(),
122
            'sosa' => $sosa,
123
            'birth_year' => $birth_year === 0 ? null : $birth_year,
124
            'birth_year_est' => $birth_year_est === 0 ? null : $birth_year_est,
125
            'death_year' => $death_year === 0 ? null : $death_year,
126
            'death_year_est' => $death_year_est === 0 ? null : $death_year_est
127
        );
128
        
129
        $this->flushTmpSosaTable();
130
        
131
        if(($fam = $indi->childFamilies()->first()) !== null) {
132
            /** @var \Fisharebest\Webtrees\Family $fam */
133
            if($husb = $fam->husband()) $this->addNode($husb, 2 * $sosa);
134
            if($wife = $fam->wife()) $this->addNode($wife, 2 * $sosa + 1);
135
        }
136
    }
137
    
138
    /**
139
     * Write sosas in the table, if the number of items is superior to the limit, or if forced.
140
     *
141
     * @param bool $force Should the flush be forced
142
     */
143
    private function flushTmpSosaTable($force = false) {
144
        if( count($this->tmp_sosa_table)> 0 &&
145
            ($force ||  count($this->tmp_sosa_table) >= self::TMP_SOSA_TABLE_LIMIT)){
146
                $this->sosa_records_service->insertOrUpdate($this->tree, $this->user, $this->tmp_sosa_table);
147
                $this->tmp_sosa_table = array();
148
        }
149
    }
150
}
151