Passed
Push — EXTRACT_CLASSES ( 231cec...0382f2 )
by Rafael
65:54 queued 05:18
created

Members   F

Complexity

Total Complexity 116

Size/Duplication

Total Lines 846
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 339
dl 0
loc 846
rs 2
c 0
b 0
f 0
wmc 116

20 Methods

Rating   Name   Duplication   Size   Complexity  
B putType() 0 42 11
A _validateType() 0 13 3
A getType() 0 17 4
A getByThirdparty() 0 17 4
A createSubscription() 0 13 3
A getByThirdpartyBarcode() 0 23 5
A getSubscriptions() 0 17 4
B indexType() 0 49 10
A _validate() 0 15 3
A getCategories() 0 15 3
A __construct() 0 4 1
A _cleanObjectDatas() 0 64 3
A get() 0 21 6
D put() 0 61 18
A postType() 0 22 5
A post() 0 22 5
C index() 0 59 13
A delete() 0 25 5
A getByThirdpartyEmail() 0 23 5
A deleteType() 0 24 5

How to fix   Complexity   

Complex Class

Complex classes like Members 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 Members, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/* Copyright (C) 2016       Xebax Christy               <[email protected]>
4
 * Copyright (C) 2017	    Regis Houssin	            <[email protected]>
5
 * Copyright (C) 2020	    Thibault FOUCART            <[email protected]>
6
 * Copyright (C) 2020	    Frédéric France	            <[email protected]>
7
 * Copyright (C) 2024		MDW							<[email protected]>
8
 * Copyright (C) 2024       Rafael San José             <[email protected]>
9
 *
10
 * This program is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; either version 3 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22
 */
23
24
namespace Dolibarr\Code\Adherents\Api;
25
26
use Luracast\Restler\RestException;
27
28
require_once constant('DOL_DOCUMENT_ROOT') . '/societe/class/societe.class.php';
29
require_once constant('DOL_DOCUMENT_ROOT') . '/adherents/class/adherent.class.php';
30
require_once constant('DOL_DOCUMENT_ROOT') . '/adherents/class/subscription.class.php';
31
require_once constant('DOL_DOCUMENT_ROOT') . '/categories/class/categorie.class.php';
32
require_once constant('DOL_DOCUMENT_ROOT') . '/adherents/class/adherent_type.class.php';
33
34
35
/**
36
 * API class for members
37
 *
38
 * @access protected
39
 * @class  DolibarrApiAccess {@requires user,external}
40
 */
41
class Members extends DolibarrApi
42
{
43
    /**
44
     * @var array   $FIELDS     Mandatory fields, checked when create and update object
45
     */
46
    public static $FIELDS = array(
47
        'morphy',
48
        'typeid'
49
    );
50
51
    /**
52
     * Constructor
53
     */
54
    public function __construct()
55
    {
56
        global $db;
57
        $this->db = $db;
58
    }
59
60
    /**
61
     * Get properties of a member object
62
     *
63
     * Return an array with member information
64
     *
65
     * @param   int     $id             ID of member
66
     * @return  Object                  Object with cleaned properties
67
     *
68
     * @throws  RestException   403     Access denied
69
     * @throws  RestException   404     Member not found
70
     */
71
    public function get($id)
72
    {
73
        if (!DolibarrApiAccess::$user->hasRight('adherent', 'lire')) {
74
            throw new RestException(403);
75
        }
76
77
        $member = new Adherent($this->db);
78
        if ($id == 0) {
79
            $result = $member->initAsSpecimen();
80
        } else {
81
            $result = $member->fetch($id);
82
        }
83
        if (!$result) {
84
            throw new RestException(404, 'member not found');
85
        }
86
87
        if (!DolibarrApi::_checkAccessToResource('adherent', $member->id) && $id > 0) {
88
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
89
        }
90
91
        return $this->_cleanObjectDatas($member);
92
    }
93
94
    /**
95
     * Get properties of a member object by linked thirdparty
96
     *
97
     * Return an array with member information
98
     *
99
     * @param     int     $thirdparty   ID of third party
100
     *
101
     * @return Object                   Data without useless information
102
     *
103
     * @url GET thirdparty/{thirdparty}
104
     *
105
     * @throws  RestException   403     Access denied
106
     * @throws  RestException   404     Member not found
107
     */
108
    public function getByThirdparty($thirdparty)
109
    {
110
        if (!DolibarrApiAccess::$user->hasRight('adherent', 'lire')) {
111
            throw new RestException(403);
112
        }
113
114
        $member = new Adherent($this->db);
115
        $result = $member->fetch('', '', $thirdparty);
116
        if (!$result) {
117
            throw new RestException(404, 'member not found');
118
        }
119
120
        if (!DolibarrApi::_checkAccessToResource('adherent', $member->id)) {
121
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
122
        }
123
124
        return $this->_cleanObjectDatas($member);
125
    }
126
127
    /**
128
     * Get properties of a member object by linked thirdparty email
129
     *
130
     * Return an array with member information
131
     *
132
     * @param  string $email            Email of third party
133
     *
134
     * @return Object                   Data without useless information
135
     *
136
     * @url GET thirdparty/email/{email}
137
     *
138
     * @throws  RestException   403     Access denied
139
     * @throws  RestException   404     Member or ThirdParty not found
140
     */
141
    public function getByThirdpartyEmail($email)
142
    {
143
        if (!DolibarrApiAccess::$user->hasRight('adherent', 'lire')) {
144
            throw new RestException(403);
145
        }
146
147
        $thirdparty = new Societe($this->db);
0 ignored issues
show
Bug introduced by
The type Dolibarr\Code\Adherents\Api\Societe was not found. Did you mean Societe? If so, make sure to prefix the type with \.
Loading history...
148
        $result = $thirdparty->fetch('', '', '', '', '', '', '', '', '', '', $email);
149
        if (!$result) {
150
            throw new RestException(404, 'thirdparty not found');
151
        }
152
153
        $member = new Adherent($this->db);
154
        $result = $member->fetch('', '', $thirdparty->id);
155
        if (!$result) {
156
            throw new RestException(404, 'member not found');
157
        }
158
159
        if (!DolibarrApi::_checkAccessToResource('adherent', $member->id)) {
160
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
161
        }
162
163
        return $this->_cleanObjectDatas($member);
164
    }
165
166
    /**
167
     * Get properties of a member object by linked thirdparty barcode
168
     *
169
     * Return an array with member information
170
     *
171
     * @param  string $barcode          Barcode of third party
172
     *
173
     * @return Object                   Data without useless information
174
     *
175
     * @url GET thirdparty/barcode/{barcode}
176
     *
177
     * @throws  RestException   403     Access denied
178
     * @throws  RestException   404     Member or ThirdParty not found
179
     */
180
    public function getByThirdpartyBarcode($barcode)
181
    {
182
        if (!DolibarrApiAccess::$user->hasRight('adherent', 'lire')) {
183
            throw new RestException(403);
184
        }
185
186
        $thirdparty = new Societe($this->db);
187
        $result = $thirdparty->fetch('', '', '', $barcode);
188
        if (!$result) {
189
            throw new RestException(404, 'thirdparty not found');
190
        }
191
192
        $member = new Adherent($this->db);
193
        $result = $member->fetch('', '', $thirdparty->id);
194
        if (!$result) {
195
            throw new RestException(404, 'member not found');
196
        }
197
198
        if (!DolibarrApi::_checkAccessToResource('adherent', $member->id)) {
199
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
200
        }
201
202
        return $this->_cleanObjectDatas($member);
203
    }
204
205
    /**
206
     * List members
207
     *
208
     * Get a list of members
209
     *
210
     * @param string    $sortfield  Sort field
211
     * @param string    $sortorder  Sort order
212
     * @param int       $limit      Limit for list
213
     * @param int       $page       Page number
214
     * @param string    $typeid     ID of the type of member
215
     * @param int       $category   Use this param to filter list by category
216
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma.
217
     *                              Example: "(t.ref:like:'SO-%') and ((t.date_creation:<:'20160101') or (t.nature:is:NULL))"
218
     * @param string    $properties Restrict the data returned to these properties. Ignored if empty. Comma separated list of properties names
219
     * @return array                Array of member objects
220
     *
221
     * @throws  RestException   400     Error on SQL filters
222
     * @throws  RestException   403     Access denied
223
     * @throws  RestException   404     No Member found
224
     * @throws  RestException   503     Error when retrieving Member list
225
     */
226
    public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $typeid = '', $category = 0, $sqlfilters = '', $properties = '')
227
    {
228
        $obj_ret = array();
229
230
        if (!DolibarrApiAccess::$user->hasRight('adherent', 'lire')) {
231
            throw new RestException(403);
232
        }
233
234
        $sql = "SELECT t.rowid";
235
        $sql .= " FROM " . MAIN_DB_PREFIX . "adherent AS t LEFT JOIN " . MAIN_DB_PREFIX . "adherent_extrafields AS ef ON (ef.fk_object = t.rowid)"; // Modification VMR Global Solutions to include extrafields as search parameters in the API GET call
236
        if ($category > 0) {
237
            $sql .= ", " . MAIN_DB_PREFIX . "categorie_member as c";
238
        }
239
        $sql .= ' WHERE t.entity IN (' . getEntity('adherent') . ')';
240
        if (!empty($typeid)) {
241
            $sql .= ' AND t.fk_adherent_type=' . ((int) $typeid);
242
        }
243
        // Select members of given category
244
        if ($category > 0) {
245
            $sql .= " AND c.fk_categorie = " . ((int) $category);
246
            $sql .= " AND c.fk_member = t.rowid";
247
        }
248
        // Add sql filters
249
        if ($sqlfilters) {
250
            $errormessage = '';
251
            $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
252
            if ($errormessage) {
253
                throw new RestException(400, 'Error when validating parameter sqlfilters -> ' . $errormessage);
254
            }
255
        }
256
257
        $sql .= $this->db->order($sortfield, $sortorder);
258
        if ($limit) {
259
            if ($page < 0) {
260
                $page = 0;
261
            }
262
            $offset = $limit * $page;
263
264
            $sql .= $this->db->plimit($limit + 1, $offset);
265
        }
266
267
        $result = $this->db->query($sql);
268
        if ($result) {
269
            $i = 0;
270
            $num = $this->db->num_rows($result);
271
            $min = min($num, ($limit <= 0 ? $num : $limit));
272
            while ($i < $min) {
273
                $obj = $this->db->fetch_object($result);
274
                $member = new Adherent($this->db);
275
                if ($member->fetch($obj->rowid)) {
276
                    $obj_ret[] = $this->_filterObjectProperties($this->_cleanObjectDatas($member), $properties);
277
                }
278
                $i++;
279
            }
280
        } else {
281
            throw new RestException(503, 'Error when retrieve member list : ' . $this->db->lasterror());
282
        }
283
284
        return $obj_ret;
285
    }
286
287
    /**
288
     * Create member object
289
     *
290
     * @param array $request_data   Request data
291
     * @return int  ID of member
292
     *
293
     * @throws  RestException   403     Access denied
294
     * @throws  RestException   500     Error when creating Member
295
     */
296
    public function post($request_data = null)
297
    {
298
        if (!DolibarrApiAccess::$user->hasRight('adherent', 'creer')) {
299
            throw new RestException(403);
300
        }
301
        // Check mandatory fields
302
        $result = $this->_validate($request_data);
303
304
        $member = new Adherent($this->db);
305
        foreach ($request_data as $field => $value) {
306
            if ($field === 'caller') {
307
                // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
308
                $member->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
309
                continue;
310
            }
311
312
            $member->$field = $this->_checkValForAPI($field, $value, $member);
313
        }
314
        if ($member->create(DolibarrApiAccess::$user) < 0) {
315
            throw new RestException(500, 'Error creating member', array_merge(array($member->error), $member->errors));
316
        }
317
        return $member->id;
318
    }
319
320
    /**
321
     * Update member
322
     *
323
     * @param   int         $id             ID of member to update
324
     * @param   array       $request_data   Datas
325
     * @return  Object                      Updated object
326
     *
327
     * @throws  RestException   403     Access denied
328
     * @throws  RestException   404     Member not found
329
     * @throws  RestException   500     Error when resiliating, validating, excluding, updating a Member
330
     */
331
    public function put($id, $request_data = null)
332
    {
333
        if (!DolibarrApiAccess::$user->hasRight('adherent', 'creer')) {
334
            throw new RestException(403);
335
        }
336
337
        $member = new Adherent($this->db);
338
        $result = $member->fetch($id);
339
        if (!$result) {
340
            throw new RestException(404, 'member not found');
341
        }
342
343
        if (!DolibarrApi::_checkAccessToResource('member', $member->id)) {
344
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
345
        }
346
347
        foreach ($request_data as $field => $value) {
348
            if ($field == 'id') {
349
                continue;
350
            }
351
            if ($field === 'caller') {
352
                // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
353
                $member->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
354
                continue;
355
            }
356
            if ($field == 'array_options' && is_array($value)) {
357
                foreach ($value as $index => $val) {
358
                    $member->array_options[$index] = $val;
359
                }
360
                continue;
361
            }
362
            // Process the status separately because it must be updated using
363
            // the validate(), resiliate() and exclude() methods of the class Adherent.
364
            if ($field == 'statut') {
365
                if ($value == '0') {
366
                    $result = $member->resiliate(DolibarrApiAccess::$user);
367
                    if ($result < 0) {
368
                        throw new RestException(500, 'Error when resiliating member: ' . $member->error);
369
                    }
370
                } elseif ($value == '1') {
371
                    $result = $member->validate(DolibarrApiAccess::$user);
372
                    if ($result < 0) {
373
                        throw new RestException(500, 'Error when validating member: ' . $member->error);
374
                    }
375
                } elseif ($value == '-2') {
376
                    $result = $member->exclude(DolibarrApiAccess::$user);
377
                    if ($result < 0) {
378
                        throw new RestException(500, 'Error when excluding member: ' . $member->error);
379
                    }
380
                }
381
            } else {
382
                $member->$field = $this->_checkValForAPI($field, $value, $member);
383
            }
384
        }
385
386
        // If there is no error, update() returns the number of affected rows
387
        // so if the update is a no op, the return value is zero.
388
        if ($member->update(DolibarrApiAccess::$user) >= 0) {
389
            return $this->get($id);
390
        } else {
391
            throw new RestException(500, 'Error when updating member: ' . $member->error);
392
        }
393
    }
394
395
    /**
396
     * Delete member
397
     *
398
     * @param int $id   member ID
399
     * @return array
400
     *
401
     * @throws  RestException   403     Access denied
402
     * @throws  RestException   404     Member not found
403
     * @throws  RestException   500     Error when deleting a Member
404
     */
405
    public function delete($id)
406
    {
407
        if (!DolibarrApiAccess::$user->hasRight('adherent', 'supprimer')) {
408
            throw new RestException(403);
409
        }
410
        $member = new Adherent($this->db);
411
        $result = $member->fetch($id);
412
        if (!$result) {
413
            throw new RestException(404, 'member not found');
414
        }
415
416
        if (!DolibarrApi::_checkAccessToResource('member', $member->id)) {
417
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
418
        }
419
420
421
        $res = $member->delete(DolibarrApiAccess::$user);
422
        if ($res < 0) {
423
            throw new RestException(500, "Can't delete, error occurs");
424
        }
425
426
        return array(
427
            'success' => array(
428
                'code' => 200,
429
                'message' => 'Member deleted'
430
            )
431
        );
432
    }
433
434
    /**
435
     * Validate fields before creating an object
436
     *
437
     * @param array|null    $data   Data to validate
438
     * @return array                Return array with validated mandatory fields and their value
439
     *
440
     * @throws RestException
441
     */
442
    private function _validate($data)
443
    {
444
        $member = array();
445
446
        $mandatoryfields = array(
447
            'morphy',
448
            'typeid'
449
        );
450
        foreach ($mandatoryfields as $field) {
451
            if (!isset($data[$field])) {
452
                throw new RestException(400, "$field field missing");
453
            }
454
            $member[$field] = $data[$field];
455
        }
456
        return $member;
457
    }
458
459
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
460
    /**
461
     * Clean sensible object datas
462
     *
463
     * @param   Object  $object     Object to clean
464
     * @return  Object              Object with cleaned properties
465
     */
466
    protected function _cleanObjectDatas($object)
467
    {
468
		// phpcs:enable
469
        $object = parent::_cleanObjectDatas($object);
470
471
        // Remove the subscriptions because they are handled as a subresource.
472
        if ($object instanceof Adherent) {
473
            unset($object->subscriptions);
474
            unset($object->fk_incoterms);
475
            unset($object->label_incoterms);
476
            unset($object->location_incoterms);
477
            unset($object->fk_delivery_address);
478
            unset($object->shipping_method_id);
479
480
            unset($object->total_ht);
481
            unset($object->total_ttc);
482
            unset($object->total_tva);
483
            unset($object->total_localtax1);
484
            unset($object->total_localtax2);
485
        }
486
487
        if ($object instanceof AdherentType) {
488
            unset($object->linkedObjectsIds);
489
            unset($object->context);
490
            unset($object->canvas);
491
            unset($object->fk_project);
492
            unset($object->contact);
493
            unset($object->contact_id);
494
            unset($object->thirdparty);
495
            unset($object->user);
496
            unset($object->origin);
497
            unset($object->origin_id);
498
            unset($object->ref_ext);
499
            unset($object->country);
500
            unset($object->country_id);
501
            unset($object->country_code);
502
            unset($object->barcode_type);
503
            unset($object->barcode_type_code);
504
            unset($object->barcode_type_label);
505
            unset($object->barcode_type_coder);
506
            unset($object->mode_reglement_id);
507
            unset($object->cond_reglement_id);
508
            unset($object->cond_reglement);
509
            unset($object->fk_delivery_address);
510
            unset($object->shipping_method_id);
511
            unset($object->model_pdf);
512
            unset($object->fk_account);
513
            unset($object->note_public);
514
            unset($object->note_private);
515
            unset($object->fk_incoterms);
516
            unset($object->label_incoterms);
517
            unset($object->location_incoterms);
518
            unset($object->name);
519
            unset($object->lastname);
520
            unset($object->firstname);
521
            unset($object->civility_id);
522
            unset($object->total_ht);
523
            unset($object->total_tva);
524
            unset($object->total_localtax1);
525
            unset($object->total_localtax2);
526
            unset($object->total_ttc);
527
        }
528
529
        return $object;
530
    }
531
532
    /**
533
     * List subscriptions of a member
534
     *
535
     * Get a list of subscriptions
536
     *
537
     * @param int $id ID of member
538
     * @return array Array of subscription objects
539
     *
540
     * @url GET {id}/subscriptions
541
     *
542
     * @throws  RestException   403     Access denied
543
     * @throws  RestException   404     Member not found
544
     */
545
    public function getSubscriptions($id)
546
    {
547
        if (!DolibarrApiAccess::$user->hasRight('adherent', 'cotisation', 'lire')) {
548
            throw new RestException(403);
549
        }
550
551
        $member = new Adherent($this->db);
552
        $result = $member->fetch($id);
553
        if (!$result) {
554
            throw new RestException(404, 'member not found');
555
        }
556
557
        $obj_ret = array();
558
        foreach ($member->subscriptions as $subscription) {
559
            $obj_ret[] = $this->_cleanObjectDatas($subscription);
560
        }
561
        return $obj_ret;
562
    }
563
564
    /**
565
     * Add a subscription for a member
566
     *
567
     * @param int       $id             ID of member
568
     * @param string    $start_date     Start date {@from body} {@type timestamp}
569
     * @param string    $end_date       End date {@from body} {@type timestamp}
570
     * @param float     $amount         Amount (may be 0) {@from body}
571
     * @param string    $label          Label {@from body}
572
     * @return int  ID of subscription
573
     *
574
     * @url POST {id}/subscriptions
575
     *
576
     * @throws  RestException   403     Access denied
577
     * @throws  RestException   404     Member not found
578
     */
579
    public function createSubscription($id, $start_date, $end_date, $amount, $label = '')
580
    {
581
        if (!DolibarrApiAccess::$user->hasRight('adherent', 'cotisation', 'creer')) {
582
            throw new RestException(403);
583
        }
584
585
        $member = new Adherent($this->db);
586
        $result = $member->fetch($id);
587
        if (!$result) {
588
            throw new RestException(404, 'member not found');
589
        }
590
591
        return $member->subscription($start_date, $amount, 0, '', $label, '', '', '', $end_date);
592
    }
593
594
    /**
595
     * Get categories for a member
596
     *
597
     * @param int       $id         ID of member
598
     * @param string        $sortfield  Sort field
599
     * @param string        $sortorder  Sort order
600
     * @param int       $limit      Limit for list
601
     * @param int       $page       Page number
602
     *
603
     * @return mixed
604
     *
605
     * @url GET {id}/categories
606
     *
607
     * @throws  RestException   403     Access denied
608
     * @throws  RestException   404     Category not found
609
     * @throws  RestException   503     Error when retrieving Category list
610
     */
611
    public function getCategories($id, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
612
    {
613
        if (!DolibarrApiAccess::$user->hasRight('categorie', 'lire')) {
614
            throw new RestException(403);
615
        }
616
617
        $categories = new Categorie($this->db);
0 ignored issues
show
Bug introduced by
The type Dolibarr\Code\Adherents\Api\Categorie was not found. Did you mean Categorie? If so, make sure to prefix the type with \.
Loading history...
618
619
        $result = $categories->getListForItem($id, 'member', $sortfield, $sortorder, $limit, $page);
620
621
        if ($result < 0) {
622
            throw new RestException(503, 'Error when retrieve category list : ' . $categories->error);
623
        }
624
625
        return $result;
626
    }
627
628
629
630
631
    /**
632
     * Get properties of a member type object
633
     *
634
     * Return an array with member type information
635
     *
636
     * @param   int     $id             ID of member type
637
     * @return  Object                  Object with cleaned properties
638
     *
639
     * @url GET /types/{id}
640
     *
641
     * @throws  RestException   403     Access denied
642
     * @throws  RestException   404     No Member Type found
643
     */
644
    public function getType($id)
645
    {
646
        if (!DolibarrApiAccess::$user->hasRight('adherent', 'lire')) {
647
            throw new RestException(403);
648
        }
649
650
        $membertype = new AdherentType($this->db);
651
        $result = $membertype->fetch($id);
652
        if (!$result) {
653
            throw new RestException(404, 'member type not found');
654
        }
655
656
        if (!DolibarrApi::_checkAccessToResource('member', $membertype->id, 'adherent_type')) {
657
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
658
        }
659
660
        return $this->_cleanObjectDatas($membertype);
661
    }
662
663
    /**
664
     * List members types
665
     *
666
     * Get a list of members types
667
     *
668
     * @param string    $sortfield  Sort field
669
     * @param string    $sortorder  Sort order
670
     * @param int       $limit      Limit for list
671
     * @param int       $page       Page number
672
     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.libelle:like:'SO-%') and (t.subscription:=:'1')"
673
     * @param string    $properties Restrict the data returned to these properties. Ignored if empty. Comma separated list of properties names
674
     * @return array                Array of member type objects
675
     *
676
     * @url GET /types/
677
     *
678
     * @throws  RestException   403     Access denied
679
     * @throws  RestException   404     No Member Type found
680
     * @throws  RestException   503     Error when retrieving Member list
681
     */
682
    public function indexType($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '', $properties = '')
683
    {
684
        $obj_ret = array();
685
686
        if (!DolibarrApiAccess::$user->hasRight('adherent', 'lire')) {
687
            throw new RestException(403);
688
        }
689
690
        $sql = "SELECT t.rowid";
691
        $sql .= " FROM " . MAIN_DB_PREFIX . "adherent_type AS t LEFT JOIN " . MAIN_DB_PREFIX . "adherent_type_extrafields AS ef ON (ef.fk_object = t.rowid)"; // Modification VMR Global Solutions to include extrafields as search parameters in the API GET call, so we will be able to filter on extrafields
692
        $sql .= ' WHERE t.entity IN (' . getEntity('member_type') . ')';
693
694
        // Add sql filters
695
        if ($sqlfilters) {
696
            $errormessage = '';
697
            $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
698
            if ($errormessage) {
699
                throw new RestException(503, 'Error when validating parameter sqlfilters -> ' . $errormessage);
700
            }
701
        }
702
703
        $sql .= $this->db->order($sortfield, $sortorder);
704
        if ($limit) {
705
            if ($page < 0) {
706
                $page = 0;
707
            }
708
            $offset = $limit * $page;
709
710
            $sql .= $this->db->plimit($limit + 1, $offset);
711
        }
712
713
        $result = $this->db->query($sql);
714
        if ($result) {
715
            $i = 0;
716
            $num = $this->db->num_rows($result);
717
            $min = min($num, ($limit <= 0 ? $num : $limit));
718
            while ($i < $min) {
719
                $obj = $this->db->fetch_object($result);
720
                $membertype = new AdherentType($this->db);
721
                if ($membertype->fetch($obj->rowid)) {
722
                    $obj_ret[] = $this->_filterObjectProperties($this->_cleanObjectDatas($membertype), $properties);
723
                }
724
                $i++;
725
            }
726
        } else {
727
            throw new RestException(503, 'Error when retrieve member type list : ' . $this->db->lasterror());
728
        }
729
730
        return $obj_ret;
731
    }
732
733
    /**
734
     * Create member type object
735
     *
736
     * @param array $request_data   Request data
737
     * @return int  ID of member type
738
     *
739
     * @url POST /types/
740
     *
741
     * @throws  RestException   403     Access denied
742
     * @throws  RestException   500     Error when creating Member Type
743
     */
744
    public function postType($request_data = null)
745
    {
746
        if (!DolibarrApiAccess::$user->hasRight('adherent', 'configurer')) {
747
            throw new RestException(403);
748
        }
749
        // Check mandatory fields
750
        $result = $this->_validateType($request_data);
751
752
        $membertype = new AdherentType($this->db);
753
        foreach ($request_data as $field => $value) {
754
            if ($field === 'caller') {
755
                // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
756
                $membertype->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
757
                continue;
758
            }
759
760
            $membertype->$field = $this->_checkValForAPI($field, $value, $membertype);
761
        }
762
        if ($membertype->create(DolibarrApiAccess::$user) < 0) {
763
            throw new RestException(500, 'Error creating member type', array_merge(array($membertype->error), $membertype->errors));
764
        }
765
        return $membertype->id;
766
    }
767
768
    /**
769
     * Update member type
770
     *
771
     * @param   int         $id             ID of member type to update
772
     * @param   array       $request_data   Datas
773
     * @return  Object                      Updated object
774
     *
775
     * @url PUT /types/{id}
776
     *
777
     * @throws  RestException   403     Access denied
778
     * @throws  RestException   404     No Member Type found
779
     * @throws  RestException   500     Error when updating Member Type
780
     */
781
    public function putType($id, $request_data = null)
782
    {
783
        if (!DolibarrApiAccess::$user->hasRight('adherent', 'configurer')) {
784
            throw new RestException(403);
785
        }
786
787
        $membertype = new AdherentType($this->db);
788
        $result = $membertype->fetch($id);
789
        if (!$result) {
790
            throw new RestException(404, 'member type not found');
791
        }
792
793
        if (!DolibarrApi::_checkAccessToResource('member', $membertype->id, 'adherent_type')) {
794
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
795
        }
796
797
        foreach ($request_data as $field => $value) {
798
            if ($field == 'id') {
799
                continue;
800
            }
801
            if ($field === 'caller') {
802
                // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
803
                $membertype->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
804
                continue;
805
            }
806
            if ($field == 'array_options' && is_array($value)) {
807
                foreach ($value as $index => $val) {
808
                    $membertype->array_options[$index] = $val;
809
                }
810
                continue;
811
            }
812
            // Process the status separately because it must be updated using
813
            // the validate(), resiliate() and exclude() methods of the class AdherentType.
814
            $membertype->$field = $this->_checkValForAPI($field, $value, $membertype);
815
        }
816
817
        // If there is no error, update() returns the number of affected rows
818
        // so if the update is a no op, the return value is zero.
819
        if ($membertype->update(DolibarrApiAccess::$user) >= 0) {
820
            return $this->get($id);
821
        } else {
822
            throw new RestException(500, 'Error when updating member type: ' . $membertype->error);
823
        }
824
    }
825
826
    /**
827
     * Delete member type
828
     *
829
     * @param int $id   member type ID
830
     * @return array
831
     *
832
     * @url DELETE /types/{id}
833
     *
834
     * @throws  RestException   403     Access denied
835
     * @throws  RestException   404     No Member Type found
836
     * @throws  RestException   500     Error when deleting Member Type
837
     */
838
    public function deleteType($id)
839
    {
840
        if (!DolibarrApiAccess::$user->hasRight('adherent', 'configurer')) {
841
            throw new RestException(403);
842
        }
843
        $membertype = new AdherentType($this->db);
844
        $result = $membertype->fetch($id);
845
        if ($result < 1) {
846
            throw new RestException(404, 'member type not found');
847
        }
848
849
        if (!DolibarrApi::_checkAccessToResource('member', $membertype->id, 'adherent_type')) {
850
            throw new RestException(403, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
851
        }
852
853
        $res = $membertype->delete(DolibarrApiAccess::$user);
854
        if ($res < 0) {
855
            throw new RestException(500, "Can't delete, error occurs");
856
        }
857
858
        return array(
859
            'success' => array(
860
                'code' => 200,
861
                'message' => 'Member type deleted'
862
            )
863
        );
864
    }
865
866
    /**
867
     * Validate fields before creating an object
868
     *
869
     * @param array|null    $data   Data to validate
870
     * @return array
871
     *
872
     * @throws RestException
873
     */
874
    private function _validateType($data)
875
    {
876
        $membertype = array();
877
878
        $mandatoryfields = array('label');
879
880
        foreach ($mandatoryfields as $field) {
881
            if (!isset($data[$field])) {
882
                throw new RestException(400, "$field field missing");
883
            }
884
            $membertype[$field] = $data[$field];
885
        }
886
        return $membertype;
887
    }
888
}
889