Passed
Push — master ( 451fb6...e51e88 )
by Andreas
28:25
created

org_openpsa_contacts_duplicates_check_person   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 98
Duplicated Lines 0 %

Test Coverage

Coverage 26.67%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 50
c 1
b 0
f 0
dl 0
loc 98
ccs 12
cts 45
cp 0.2667
rs 10
wmc 17

4 Methods

Rating   Name   Duplication   Size   Complexity  
A load_memberships() 0 9 2
C p_duplicate() 0 62 13
A get_class() 0 3 1
A get_fields() 0 3 1
1
<?php
2
/**
3
 * @package org.openpsa.contacts
4
 * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
5
 * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
6
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License
7
 */
8
9
/**
10
 * Search for duplicate persons and groups in database
11
 *
12
 * @package org.openpsa.contacts
13
 */
14
class org_openpsa_contacts_duplicates_check_person extends org_openpsa_contacts_duplicates_check
15
{
16
    /**
17
     * Cache memberships when possible
18
     */
19
    private $membership_cache = [];
20
21 1
    protected function get_class() : string
22
    {
23 1
        return org_openpsa_contacts_person_dba::class;
24
    }
25
26 1
    protected function get_fields() : array
27
    {
28 1
        return ['firstname', 'lastname', 'email', 'handphone', 'city', 'street', 'homephone', 'id'];
29
    }
30
31
    /**
32
     * Calculates P for the given two persons being duplicates
33
     *
34
     * @return array with overall P and matched checks
35
     */
36 1
    protected function p_duplicate(array $person1, array $person2) : array
37
    {
38
        $ret = [
39 1
            'p' => 0,
40
            'email_match' => false,
41
            'handphone_match' => false,
42
            'fname_lname_city_match' => false,
43
            'fname_lname_street_match' => false,
44
            'fname_hphone_match' => false,
45
            'fname_lname_company_match' => false
46
        ];
47
48
        //TODO: read weight values from configuration
49 1
        if ($this->match('email', $person1, $person2)) {
50 1
            $ret['email_match'] = true;
51 1
            $ret['p'] += 1;
52
        } elseif (!empty($person1['lastname'])) {
53
            // if user's lastname is part of the email address, check to see if the difference is only in the domain part
54
            $email1 = preg_replace('/@.+/', '', $person1['email']);
55
            $email2 = preg_replace('/@.+/', '', $person2['email']);
56
            if (   str_contains($email1, $person1['lastname'])
57
                && $email1 == $email2) {
58
                $ret['email_match'] = true;
59
                $ret['p'] += 0.5;
60
            }
61
        }
62
63 1
        if ($this->match('handphone', $person1, $person2)) {
64
            $ret['handphone_match'] = true;
65
            $ret['p'] += 1;
66
        }
67
68 1
        if ($this->match('firstname', $person1, $person2)) {
69
            if ($this->match('homephone', $person1, $person2)) {
70
                $ret['fname_hphone_match'] = true;
71
                $ret['p'] += 0.7;
72
            }
73
            if ($this->match('lastname', $person1, $person2)) {
74
                if ($this->match('city', $person1, $person2)) {
75
                    $ret['fname_lname_city_match'] = true;
76
                    $ret['p'] += 0.5;
77
                }
78
                if ($this->match('street', $person1, $person2)) {
79
                    $ret['fname_lname_street_match'] = true;
80
                    $ret['p'] += 0.9;
81
                }
82
83
                // We cannot do this check if person1 hasn't been created yet...
84
                if (!empty($person1['guid'])) {
85
                    $person1_memberships = $this->load_memberships($person1['id']);
86
                    $person2_memberships = $this->load_memberships($person2['id']);
87
                    $matches = array_intersect($person1_memberships, $person2_memberships);
88
                    if (!empty($matches)) {
89
                        $ret['fname_lname_company_match'] = true;
90
                        $ret['p'] += (count($matches) * 0.5);
91
                    }
92
                }
93
            }
94
        }
95
96
        // All checks done, return
97 1
        return $ret;
98
    }
99
100
    /**
101
     * Get membership maps
102
     */
103
    private function load_memberships(int $id) : array
104
    {
105
        if (!isset($this->membership_cache[$id])) {
106
            $this->membership_cache[$id] = [];
107
            $mc = midcom_db_member::new_collector('uid', $id);
108
            $mc->add_constraint('gid.orgOpenpsaObtype', '<>', org_openpsa_contacts_group_dba::MYCONTACTS);
109
            $this->membership_cache[$id] = $mc->get_values('gid');
110
        }
111
        return $this->membership_cache[$id];
112
    }
113
}
114