Passed
Push — master ( ac4e12...523107 )
by Andreas
25:53
created

load_next()   B

Complexity

Conditions 11
Paths 13

Size

Total Lines 49
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 40.0615

Importance

Changes 0
Metric Value
cc 11
eloc 37
nc 13
nop 0
dl 0
loc 49
ccs 14
cts 37
cp 0.3784
crap 40.0615
rs 7.3166
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @package org.openpsa.contacts
4
 * @author The Midgard Project, http://www.midgard-project.org
5
 * @copyright The Midgard Project, http://www.midgard-project.org
6
 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
7
 */
8
9
use Symfony\Component\HttpFoundation\Request;
10
11
/**
12
 * Duplicates handler
13
 *
14
 * @todo This cannot work in 8.09, since metadata fields like creator are read-only.
15
 * Also, deleting persons isn't supported (although it works if you just call delete())
16
 * @package org.openpsa.contacts
17
 */
18
class org_openpsa_contacts_handler_duplicates extends midcom_baseclasses_components_handler
19
{
20
    private $notfound = false;
21
22
    private $mode;
23
24 1
    public function _handler_person(Request $request, array &$data)
25
    {
26 1
        $this->mode = 'person';
27 1
        return $this->handle($request, $data);
28
    }
29
30 1
    public function _handler_group(Request $request, array &$data)
31
    {
32 1
        $this->mode = 'group';
33 1
        return $this->handle($request, $data);
34
    }
35
36 2
    private function handle(Request $request, array &$data)
37
    {
38 2
        $data['loop_i'] = 0;
39
40 2
        if ($request->request->has('org_openpsa_contacts_handler_duplicates_object_loop_i')) {
41
            $data['loop_i'] = $request->request->getInt('org_openpsa_contacts_handler_duplicates_object_loop_i');
42
            if ($request->request->has('org_openpsa_contacts_handler_duplicates_object_decide_later')) {
43
                $data['loop_i']++;
44
            }
45
        }
46 2
        $this->process_submit($request);
47
48 2
        $this->load_next();
49
50 2
        $title = sprintf($this->_l10n->get('merge %s'), $this->_l10n->get($this->mode . 's'));
51 2
        midcom::get()->head->set_pagetitle($title);
52 2
        $this->add_breadcrumb('', $title);
53
54 2
        if (!$this->notfound) {
55
            return $this->show('show-duplicate-' . $this->mode . 's');
56
        }
57 2
        return $this->show('show-duplicate-notfound');
58
    }
59
60 2
    private function load_next()
61
    {
62 2
        $i =& $this->_request_data['loop_i'];
63 2
        while ($i < 100) {
64 2
            debug_add("Loop iteration {$i}");
65 2
            $qb = new midgard_query_builder('midgard_parameter');
66 2
            $qb->add_constraint('domain', '=', 'org.openpsa.contacts.duplicates:possible_duplicate');
67 2
            $qb->add_order('name', 'ASC');
68 2
            $qb->set_limit(1);
69 2
            if ($i > 0) {
70
                $qb->set_offset($i);
71
            }
72 2
            $ret = $qb->execute();
73
74 2
            if (empty($ret)) {
75 2
                debug_add("No more results to be had, setting notfound and breaking out of loop");
76 2
                $this->notfound = true;
77 2
                break;
78
            }
79
80
            $param = $ret[0];
81
            debug_add("Found duplicate mark on object {$param->parentguid} for object {$param->name}");
82
            try {
83
                $object1 = $this->load($param->parentguid);
84
                $object2 = $this->load($param->name);
85
            } catch (midcom_error $e) {
86
                $i++;
87
                continue;
88
            }
89
            // Make sure we actually have enough rights to do this
90
            if (   !$object1->can_do('midgard:update')
91
                || !$object1->can_do('midgard:delete')
92
                || !$object2->can_do('midgard:update')
93
                || !$object2->can_do('midgard:delete')) {
94
                debug_add("Insufficient rights to merge these two, continuing to see if we have more");
95
                $i++;
96
                continue;
97
            }
98
            // Extra sanity check (in case of semi-successful not-duplicate mark)
99
            if (   $object1->get_parameter('org.openpsa.contacts.duplicates:not_duplicate', $object2->guid)
100
                || $object2->get_parameter('org.openpsa.contacts.duplicates:not_duplicate', $object1->guid)) {
101
                debug_add("It seems these two (#{$object1->id} and #{$object2->id}) have also marked as not duplicates, some cleanup might be a good thing", MIDCOM_LOG_WARN);
102
                $i++;
103
                continue;
104
            }
105
106
            $this->_request_data['object1'] = $object1;
107
            $this->_request_data['object2'] = $object2;
108
            break;
109
        }
110 2
    }
111
112
    private function load(string $guid) : midcom_core_dbaobject
113
    {
114
        if ($this->mode == 'person') {
115
            return new org_openpsa_contacts_person_dba($guid);
116
        }
117
        return new org_openpsa_contacts_group_dba($guid);
118
    }
119
120 2
    private function process_submit(Request $request)
121
    {
122 2
        $keep = $request->request->get('org_openpsa_contacts_handler_duplicates_object_keep');
123 2
        $options = $request->request->get('org_openpsa_contacts_handler_duplicates_object_options');
124 2
        if (!empty($keep) && count($options) == 2) {
125
            $option1 = $this->load($options[1]);
126
            $option2 = $this->load($options[2]);
127
            $keep = key($keep);
128
            if ($keep == 'both') {
129
                $option1->require_do('midgard:update');
130
                $option2->require_do('midgard:update');
131
                if (   $option1->set_parameter('org.openpsa.contacts.duplicates:not_duplicate', $option2->guid, time())
132
                    && $option2->set_parameter('org.openpsa.contacts.duplicates:not_duplicate', $option1->guid, time())) {
133
                    // Clear the possible duplicate parameters
134
                    $option1->delete_parameter('org.openpsa.contacts.duplicates:possible_duplicate', $option2->guid);
135
                    $option2->delete_parameter('org.openpsa.contacts.duplicates:possible_duplicate', $option1->guid);
136
137
                    // TODO: Localize
138
                    midcom::get()->uimessages->add($this->_l10n->get('org.openpsa.contacts'), "Keeping both \"{$option1->name}\" and \"{$option2->name}\", they will not be marked as duplicates in the future", 'ok');
139
                } else {
140
                    $errstr = midcom_connection::get_error_string();
141
                    // Failed to set as not duplicate, clear parameter that might have been set (could have only been the first)
142
                    $option1->delete_parameter('org.openpsa.contacts.duplicates:not_duplicate', $option2->guid);
143
144
                    // TODO: Localize
145
                    midcom::get()->uimessages->add($this->_l10n->get('org.openpsa.contacts'), "Failed to mark #{$option1->id} and # {$option2->id} as not duplicates, errstr: {$errstr}", 'error');
146
                }
147
            } else {
148
                if ($keep == $option1->guid) {
149
                    $object1 =& $option1;
150
                    $object2 =& $option2;
151
                } elseif ($keep == $option2->guid) {
152
                    $object1 =& $option2;
153
                    $object2 =& $option1;
154
                } else {
155
                    throw new midcom_error('Something weird happened (basically we got bogus data)');
156
                }
157
                $object1->require_do('midgard:update');
158
                $object2->require_do('midgard:delete');
159
160
                try {
161
                    $merger = new org_openpsa_contacts_duplicates_merge($this->mode, $this->_config);
162
                    $merger->merge_delete($object1, $object2);
163
                } catch (midcom_error $e) {
164
                    // TODO: Localize
165
                    midcom::get()->uimessages->add($this->_l10n->get('org.openpsa.contacts'), 'Merge failed, errstr: ' . $e->getMessage(), 'error');
166
                }
167
            }
168
169
            //PONDER: redirect to avoid reloading the POST in case user presses reload ??
170
        }
171 2
    }
172
}
173