Passed
Push — main ( b1e4ca...d8f8f2 )
by Rafael
44:33
created

AdherentTypeController   A

Complexity

Total Complexity 42

Size/Duplication

Total Lines 240
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 165
dl 0
loc 240
rs 9.0399
c 1
b 0
f 0
wmc 42

1 Method

Rating   Name   Duplication   Size   Complexity  
F index() 0 233 42

How to fix   Complexity   

Complex Class

Complex classes like AdherentTypeController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AdherentTypeController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/* Copyright (C) 2001-2002  Rodolphe Quiedeville    <[email protected]>
4
 * Copyright (C) 2003		Jean-Louis Bergamo		<[email protected]>
5
 * Copyright (C) 2004-2011	Laurent Destailleur		<[email protected]>
6
 * Copyright (C) 2005-2017	Regis Houssin			<[email protected]>
7
 * Copyright (C) 2013		Florian Henry			<[email protected]>
8
 * Copyright (C) 2015		Alexandre Spangaro		<[email protected]>
9
 * Copyright (C) 2019-2022	Thibault Foucart		<[email protected]>
10
 * Copyright (C) 2020		Josep Lluís Amador		<[email protected]>
11
 * Copyright (C) 2021		Waël Almoman			<[email protected]>
12
 * Copyright (C) 2024		MDW						<[email protected]>
13
 * Copyright (C) 2024       Rafael San José         <[email protected]>
14
 *
15
 * This program is free software; you can redistribute it and/or modify
16
 * it under the terms of the GNU General Public License as published by
17
 * the Free Software Foundation; either version 3 of the License, or
18
 * (at your option) any later version.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 * GNU General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU General Public License
26
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
27
 */
28
29
namespace DoliModules\Adherent\Controller;
30
31
global $conf;
32
global $db;
33
global $user;
34
global $hookmanager;
35
global $user;
36
global $menumanager;
37
global $langs;
38
global $mysoc;
39
40
// Load Dolibarr environment
41
require_once BASE_PATH . '/main.inc.php';
42
43
use DoliCore\Base\DolibarrController;
44
use DoliCore\Lib\ExtraFields;
45
use DoliModules\Adherent\Model\AdherentType;
46
47
class AdherentTypeController extends DolibarrController
48
{
49
    /**
50
     *      \file       htdocs/adherents/type.php
51
     *      \ingroup    member
52
     *      \brief      Member's type setup
53
     */
54
    public function index($executeActions = true): bool
55
    {
56
        global $conf;
57
        global $db;
58
        global $user;
59
        global $hookmanager;
60
        global $user;
61
        global $menumanager;
62
        global $langs;
63
64
        // Load translation files required by the page
65
        $this->langs->load("members");
66
67
        $action = GETPOST('action', 'aZ09');
68
        if ($action === 'create') {
69
            $this->template = '/page/adherent/type_edit';
70
            return true;
71
        }
72
73
        if ($action === 'cancel') {
74
            $this->template = '/page/adherent/type_list';
75
            return true;
76
        }
77
78
        $rowid = GETPOSTINT('rowid');
79
        $massaction = GETPOST('massaction', 'alpha');
80
        $cancel = GETPOST('cancel', 'alpha');
81
        $toselect = GETPOST('toselect', 'array');
82
        $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)) . basename(__FILE__, '.php')); // To manage different context of search
83
        $backtopage = GETPOST('backtopage', 'alpha');
84
        $mode = GETPOST('mode', 'alpha');
85
86
        $sall = GETPOST("sall", "alpha");
87
        $filter = GETPOST("filter", 'alpha');
88
        $search_ref = GETPOST('search_ref', 'alpha');
89
        $search_lastname = GETPOST('search_lastname', 'alpha');
90
        $search_login = GETPOST('search_login', 'alpha');
91
        $search_email = GETPOST('search_email', 'alpha');
92
        $type = GETPOST('type', 'intcomma');
93
        $status = GETPOST('status', 'alpha');
94
        $optioncss = GETPOST('optioncss', 'alpha');
95
96
        // Load variable for pagination
97
        $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
98
        $sortfield = GETPOST('sortfield', 'aZ09comma');
99
        $sortorder = GETPOST('sortorder', 'aZ09comma');
100
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
101
        if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
102
            // If $page is not defined, or '' or -1 or if we click on clear filters
103
            $page = 0;
104
        }
105
        $offset = $limit * $page;
106
        $pageprev = $page - 1;
107
        $pagenext = $page + 1;
108
        if (!$sortorder) {
109
            $sortorder = "DESC";
110
        }
111
        if (!$sortfield) {
112
            $sortfield = "d.lastname";
113
        }
114
115
        $label = GETPOST("label", "alpha");
116
        $morphy = GETPOST("morphy", "alpha");
117
        $status = GETPOSTINT("status");
118
        $subscription = GETPOSTINT("subscription");
119
        $amount = GETPOST('amount', 'alpha');
120
        $duration_value = GETPOSTINT('duration_value');
121
        $duration_unit = GETPOST('duration_unit', 'alpha');
122
        $vote = GETPOSTINT("vote");
123
        $comment = GETPOST("comment", 'restricthtml');
124
        $mail_valid = GETPOST("mail_valid", 'restricthtml');
125
        $caneditamount = GETPOSTINT("caneditamount");
126
127
        // Initialize technical objects
128
        $object = new AdherentType($this->db);
129
        $extrafields = new ExtraFields($this->db);
130
        $this->hookmanager->initHooks(['membertypecard', 'globalcard']);
0 ignored issues
show
Bug introduced by
The method initHooks() does not exist on null. ( Ignorable by Annotation )

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

130
        $this->hookmanager->/** @scrutinizer ignore-call */ 
131
                            initHooks(['membertypecard', 'globalcard']);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
131
132
        // Fetch optionals attributes and labels
133
        $extrafields->fetch_name_optionals_label($object->table_element);
134
135
        /*
136
         *  Actions
137
         */
138
139
        if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
140
            $search_ref = "";
141
            $search_lastname = "";
142
            $search_login = "";
143
            $search_email = "";
144
            $type = "";
145
            $sall = "";
146
        }
147
148
        if (GETPOST('cancel', 'alpha')) {
149
            $action = 'list';
150
            $massaction = '';
151
        }
152
153
        if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
154
            $massaction = '';
155
        }
156
157
        if ($cancel) {
158
            $action = '';
159
160
            if (!empty($backtopage)) {
161
                header("Location: " . $backtopage);
162
                exit;
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return boolean. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
163
            }
164
        }
165
166
        if ($action == 'add' && $user->hasRight('adherent', 'configurer')) {
167
            $object->label = trim($label);
168
            $object->morphy = trim($morphy);
169
            $object->status = (int) $status;
170
            $object->subscription = (int) $subscription;
171
            $object->amount = ($amount == '' ? '' : price2num($amount, 'MT'));
172
            $object->caneditamount = $caneditamount;
173
            $object->duration_value = $duration_value;
174
            $object->duration_unit = $duration_unit;
175
            $object->note_public = trim($comment);
176
            $object->note_private = '';
177
            $object->mail_valid = trim($mail_valid);
178
            $object->vote = (int) $vote;
179
180
            // Fill array 'array_options' with data from add form
181
            $ret = $extrafields->setOptionalsFromPost(null, $object);
182
            if ($ret < 0) {
183
                $error++;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $error seems to be never defined.
Loading history...
184
            }
185
186
            if (empty($object->label)) {
187
                $error++;
188
                setEventMessages($this->langs->trans("ErrorFieldRequired", $this->langs->transnoentities("Label")), null, 'errors');
189
            } else {
190
                $sql = "SELECT libelle FROM " . MAIN_DB_PREFIX . "adherent_type WHERE libelle = '" . $this->db->escape($object->label) . "'";
191
                $sql .= " WHERE entity IN (" . getEntity('member_type') . ")";
192
                $result = $this->db->query($sql);
193
                $num = null;
194
                if ($result) {
195
                    $num = $this->db->num_rows($result);
196
                }
197
                if ($num) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $num of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
198
                    $error++;
199
                    $this->langs->load("errors");
200
                    setEventMessages($this->langs->trans("ErrorLabelAlreadyExists", $login), null, 'errors');
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $login seems to be never defined.
Loading history...
201
                }
202
            }
203
204
            if (!$error) {
205
                $id = $object->create($user);
206
                if ($id > 0) {
207
                    header("Location: " . $_SERVER['PHP_SELF']);
208
                    exit;
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return boolean. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
209
                } else {
210
                    setEventMessages($object->error, $object->errors, 'errors');
211
                    $action = 'create';
212
                }
213
            } else {
214
                $action = 'create';
215
            }
216
        }
217
218
        if ($action == 'update' && $user->hasRight('adherent', 'configurer')) {
219
            $object->fetch($rowid);
220
221
            $object->oldcopy = dol_clone($object, 2);
222
223
            $object->label = trim($label);
224
            $object->morphy = trim($morphy);
225
            $object->status = (int) $status;
226
            $object->subscription = (int) $subscription;
227
            $object->amount = ($amount == '' ? '' : price2num($amount, 'MT'));
228
            $object->caneditamount = $caneditamount;
229
            $object->duration_value = $duration_value;
230
            $object->duration_unit = $duration_unit;
231
            $object->note_public = trim($comment);
232
            $object->note_private = '';
233
            $object->mail_valid = trim($mail_valid);
234
            $object->vote = (bool) trim($vote);
235
236
            // Fill array 'array_options' with data from add form
237
            $ret = $extrafields->setOptionalsFromPost(null, $object, '@GETPOSTISSET');
238
            if ($ret < 0) {
239
                $error++;
240
            }
241
242
            $ret = $object->update($user);
243
244
            if ($ret >= 0 && !count($object->errors)) {
245
                setEventMessages($this->langs->trans("MemberTypeModified"), null, 'mesgs');
246
            } else {
247
                setEventMessages($object->error, $object->errors, 'errors');
248
            }
249
250
            header("Location: " . $_SERVER['PHP_SELF'] . "?rowid=" . $object->id);
251
            exit;
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return boolean. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
252
        }
253
254
        if ($action == 'confirm_delete' && $user->hasRight('adherent', 'configurer')) {
255
            $object->fetch($rowid);
256
            $res = $object->delete($user);
257
258
            if ($res > 0) {
259
                setEventMessages($this->langs->trans("MemberTypeDeleted"), null, 'mesgs');
260
                header("Location: " . $_SERVER['PHP_SELF']);
261
                exit;
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return boolean. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
262
            } else {
263
                setEventMessages($this->langs->trans("MemberTypeCanNotBeDeleted"), null, 'errors');
264
                $action = '';
265
            }
266
        }
267
268
        $this->db->close();
269
270
        $this->template = '/page/adherent/type_list';
271
272
        $this->menu = [];
273
        foreach ($menu as $item) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $menu seems to be never defined.
Loading history...
274
            if ($item['type'] === 'left' || !$item['enabled']) {
275
                continue;
276
            }
277
            $this->menu[] = [
278
                'name' => $item['mainmenu'],
279
                'href' => BASE_URL . $item['url'],
280
                'prefix' => $item['prefix'],
281
                'title' => $item['titre'],
282
                'selected' => false,
283
            ];
284
        }
285
286
        return true;
287
    }
288
}
289