Passed
Push — master ( 284492...2c3033 )
by Alxarafe
27:10
created

AlixarModel::fetchObjectLinked()   F

Complexity

Conditions 58
Paths 14688

Size

Total Lines 166
Code Lines 120

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 58
eloc 120
nc 14688
nop 8
dl 0
loc 166
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

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:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
4
namespace Alixar\Base;
5
6
7
use Alxarafe\Base\Table;
8
9
class AlixarModel extends Table
10
{
11
    /**
12
     * @var string    The type of originating object ('commande', 'facture', ...)
13
     * @see fetch_origin()
14
     */
15
    public $origin;
16
17
    /**
18
     * @var DoliDb        Database handler (result of a new DoliDB)
0 ignored issues
show
Bug introduced by alxarafe
The type Alixar\Base\DoliDb was not found. Did you mean DoliDb? If so, make sure to prefix the type with \.
Loading history...
19
     */
20
    public $db;
21
22
    /**
23
     * @var int The object identifier
24
     */
25
    public $id;
26
27
    /**
28
     * @var string        Error string
29
     * @see             errors
30
     */
31
    public $error;
32
33
    /**
34
     * @var string[]    Array of error strings
35
     */
36
    public $errors = array();
37
38
    /**
39
     * @var string ID to identify managed object
40
     */
41
    public $element;
42
43
    /**
44
     * @var string Name of table without prefix where object is stored
45
     */
46
    public $table_element;
47
48
    /**
49
     * @var int    Name of subtable line
50
     */
51
    public $table_element_line = '';
52
53
    /**
54
     * @var string        Key value used to track if data is coming from import wizard
55
     */
56
    public $import_key;
57
58
    /**
59
     * @var mixed        Contains data to manage extrafields
60
     */
61
    public $array_options = array();
62
63
    /**
64
     * @var int[][]        Array of linked objects ids. Loaded by ->fetchObjectLinked
65
     */
66
    public $linkedObjectsIds;
67
68
    /**
69
     * @var mixed        Array of linked objects. Loaded by ->fetchObjectLinked
70
     */
71
    public $linkedObjects;
72
73
    /**
74
     * @var Object      To store a cloned copy of object before to edit it and keep track of old properties
75
     */
76
    public $oldcopy;
77
    /**
78
     * @var array<string,mixed>        Can be used to pass information when only object is provided to method
79
     */
80
    public $context = array();
81
82
83
    // Following vars are used by some objects only. We keep this property here in CommonObject to be able to provide common method using them.
84
    /**
85
     * @var string        Contains canvas name if record is an alternative canvas record
86
     */
87
    public $canvas;
88
    /**
89
     * @var Project The related project
0 ignored issues
show
Bug introduced by alxarafe
The type Alixar\Base\Project was not found. Did you mean Project? If so, make sure to prefix the type with \.
Loading history...
90
     * @see fetch_projet()
91
     */
92
    public $project;
93
    /**
94
     * @var int The related project ID
95
     * @see setProject(), project
96
     */
97
    public $fk_project;
98
    /**
99
     * @deprecated
100
     * @see project
101
     */
102
    public $projet;
103
    /**
104
     * @var Contact a related contact
0 ignored issues
show
Bug introduced by alxarafe
The type Alixar\Base\Contact was not found. Did you mean Contact? If so, make sure to prefix the type with \.
Loading history...
105
     * @see fetch_contact()
106
     */
107
    public $contact;
108
    /**
109
     * @var int The related contact ID
110
     * @see fetch_contact()
111
     */
112
    public $contact_id;
113
    /**
114
     * @var Societe A related thirdparty
0 ignored issues
show
Bug introduced by alxarafe
The type Alixar\Base\Societe was not found. Did you mean Societe? If so, make sure to prefix the type with \.
Loading history...
115
     * @see fetch_thirdparty()
116
     */
117
    public $thirdparty;
118
    /**
119
     * @var User A related user
120
     * @see fetch_user()
121
     */
122
    public $user;
123
    /**
124
     * @var int    The id of originating object
125
     * @see fetch_origin()
126
     */
127
    public $origin_id;
128
    /**
129
     * @var string The object's reference
130
     */
131
    public $ref;
132
    /**
133
     * @var string The object's previous reference
134
     */
135
    public $ref_previous;
136
    /**
137
     * @var string The object's next reference
138
     */
139
    public $ref_next;
140
    /**
141
     * @var string An external reference for the object
142
     */
143
    public $ref_ext;
144
    /**
145
     * @var int The object's status
146
     * @see setStatut()
147
     */
148
    public $statut;
149
    /**
150
     * @var string
151
     * @see getFullAddress()
152
     */
153
    public $country;
154
    /**
155
     * @var int
156
     * @see getFullAddress(), country
157
     */
158
    public $country_id;
159
    /**
160
     * @var string
161
     * @see getFullAddress(), isInEEC(), country
162
     */
163
    public $country_code;
164
    /**
165
     * @var string
166
     * @see getFullAddress()
167
     */
168
    public $state;
169
    /**
170
     * @var int
171
     * @see getFullAddress(), state
172
     */
173
    public $state_id;
174
    /**
175
     * @var string
176
     * @see getFullAddress(), state
177
     */
178
    public $state_code;
179
    /**
180
     * @var string
181
     * @see getFullAddress(), region
182
     */
183
    public $region;
184
    /**
185
     * @var string
186
     * @see getFullAddress(), region
187
     */
188
    public $region_code;
189
    /**
190
     * @var int
191
     * @see fetch_barcode()
192
     */
193
    public $barcode_type;
194
    /**
195
     * @var string
196
     * @see fetch_barcode(), barcode_type
197
     */
198
    public $barcode_type_code;
199
    /**
200
     * @var string
201
     * @see fetch_barcode(), barcode_type
202
     */
203
    public $barcode_type_label;
204
    /**
205
     * @var string
206
     * @see fetch_barcode(), barcode_type
207
     */
208
    public $barcode_type_coder;
209
    /**
210
     * @var int Payment method ID (cheque, cash, ...)
211
     * @see setPaymentMethods()
212
     */
213
    public $mode_reglement_id;
214
    /**
215
     * @var int Payment terms ID
216
     * @see setPaymentTerms()
217
     */
218
    public $cond_reglement_id;
219
    /**
220
     * @var int Payment terms ID
221
     * @deprecated Kept for compatibility
222
     * @see cond_reglement_id;
223
     */
224
    public $cond_reglement;
225
    /**
226
     * @var int Delivery address ID
227
     * @deprecated
228
     * @see setDeliveryAddress()
229
     */
230
    public $fk_delivery_address;
231
    /**
232
     * @var int Shipping method ID
233
     * @see setShippingMethod()
234
     */
235
    public $shipping_method_id;
236
    /**
237
     * @var string
238
     * @see SetDocModel()
239
     */
240
    public $modelpdf;
241
    /**
242
     * @var int Bank account ID
243
     * @see SetBankAccount()
244
     */
245
    public $fk_account;
246
    /**
247
     * @var string Public note
248
     * @see update_note()
249
     */
250
    public $note_public;
251
    /**
252
     * @var string Private note
253
     * @see update_note()
254
     */
255
    public $note_private;
256
    /**
257
     * @deprecated
258
     * @see note_public
259
     */
260
    public $note;
261
    /**
262
     * @var float Total amount before taxes
263
     * @see update_price()
264
     */
265
    public $total_ht;
266
    /**
267
     * @var float Total VAT amount
268
     * @see update_price()
269
     */
270
    public $total_tva;
271
    /**
272
     * @var float Total local tax 1 amount
273
     * @see update_price()
274
     */
275
    public $total_localtax1;
276
    /**
277
     * @var float Total local tax 2 amount
278
     * @see update_price()
279
     */
280
    public $total_localtax2;
281
    /**
282
     * @var float Total amount with taxes
283
     * @see update_price()
284
     */
285
    public $total_ttc;
286
    /**
287
     * @var CommonObjectLine[]
288
     */
289
    public $lines;
290
    /**
291
     * @var mixed        Contains comments
292
     * @see fetchComments()
293
     */
294
    public $comments = array();
295
    /**
296
     * @var int
297
     * @see setIncoterms()
298
     */
299
    public $fk_incoterms;
300
    /**
301
     * @var string
302
     * @see SetIncoterms()
303
     */
304
    public $libelle_incoterms;
305
    /**
306
     * @var string
307
     * @see display_incoterms()
308
     */
309
    public $location_incoterms;
310
    public $name;
311
    public $lastname;
312
    public $firstname;
313
    public $civility_id;
314
    public $date_creation;
315
316
    // Dates
317
    public $date_validation;            // Date creation
318
    public $date_modification;        // Date validation
319
    /**
320
     * @var string        Column name of the ref field.
321
     */
322
    protected $table_ref_field = '';        // Date last change (tms field)
323
324
325
    // No constructor as it is an abstract class
326
327
    /**
328
     * Check an object id/ref exists
329
     * If you don't need/want to instantiate object and just need to know if object exists, use this method instead of fetch
330
     *
331
     * @param string $element String of element ('product', 'facture', ...)
332
     * @param int $id Id of object
333
     * @param string $ref Ref of object to check
334
     * @param string $ref_ext Ref ext of object to check
335
     * @return int                <0 if KO, 0 if OK but not found, >0 if OK and exists
336
     */
337
    static function isExistingObject($element, $id, $ref = '', $ref_ext = '')
338
    {
339
        global $db, $conf;
340
341
        $sql = "SELECT rowid, ref, ref_ext";
342
        $sql .= " FROM " . MAIN_DB_PREFIX . $element;
343
        $sql .= " WHERE entity IN (" . getEntity($element) . ")";
344
345
        if ($id > 0) $sql .= " AND rowid = " . $db->escape($id);
346
        else if ($ref) $sql .= " AND ref = '" . $db->escape($ref) . "'";
347
        else if ($ref_ext) $sql .= " AND ref_ext = '" . $db->escape($ref_ext) . "'";
348
        else {
349
            $error = 'ErrorWrongParameters';
350
            dol_print_error(get_class() . "::isExistingObject " . $error, LOG_ERR);
351
            return -1;
352
        }
353
        if ($ref || $ref_ext) $sql .= " AND entity = " . $conf->entity;
354
355
        dol_syslog(get_class() . "::isExistingObject", LOG_DEBUG);
356
        $resql = $db->query($sql);
357
        if ($resql) {
358
            $num = $db->num_rows($resql);
359
            if ($num > 0) return 1;
360
            else return 0;
361
        }
362
        return -1;
363
    }
364
365
    /**
366
     * Function used to replace a thirdparty id with another one.
367
     * This function is meant to be called from replaceThirdparty with the appropiate tables
368
     * Column name fk_soc MUST be used to identify thirdparties
369
     *
370
     * @param DoliDB $db Database handler
371
     * @param int $origin_id Old thirdparty id (the thirdparty to delete)
372
     * @param int $dest_id New thirdparty id (the thirdparty that will received element of the other)
373
     * @param string[] $tables Tables that need to be changed
374
     * @param int $ignoreerrors Ignore errors. Return true even if errors. We need this when replacement can fails like for categories (categorie of old thirdparty may already exists on new one)
375
     * @return bool                          True if success, False if error
376
     */
377
    public static function commonReplaceThirdparty(DoliDB $db, $origin_id, $dest_id, array $tables, $ignoreerrors = 0)
0 ignored issues
show
Bug introduced by alxarafe
The type Alixar\Base\DoliDB was not found. Did you mean DoliDB? If so, make sure to prefix the type with \.
Loading history...
378
    {
379
        foreach ($tables as $table) {
380
            $sql = 'UPDATE ' . MAIN_DB_PREFIX . $table . ' SET fk_soc = ' . $dest_id . ' WHERE fk_soc = ' . $origin_id;
381
382
            if (!$db->query($sql)) {
383
                if ($ignoreerrors) return true;        // TODO Not enough. If there is A-B on kept thirdarty and B-C on old one, we must get A-B-C after merge. Not A-B.
384
                //$this->errors = $db->lasterror();
385
                return false;
386
            }
387
        }
388
389
        return true;
390
    }
391
392
    /**
393
     * Method to output saved errors
394
     *
395
     * @return    string        String with errors
396
     */
397
    function errorsToString()
398
    {
399
        return $this->error . (is_array($this->errors) ? (($this->error != '' ? ', ' : '') . join(', ', $this->errors)) : '');
400
    }
401
402
    /**
403
     *    Return full address for banner
404
     *
405
     * @param string $htmlkey HTML id to make banner content unique
406
     * @param Object $object Object (thirdparty, thirdparty of contact for contact, null for a member)
407
     * @return        string                            Full address string
408
     */
409
    function getBannerAddress($htmlkey, $object)
410
    {
411
        global $conf, $langs;
412
413
        $countriesusingstate = array('AU', 'US', 'IN', 'GB', 'ES', 'UK', 'TR');    // See also option MAIN_FORCE_STATE_INTO_ADDRESS
414
415
        $contactid = 0;
416
        $thirdpartyid = 0;
417
        if ($this->element == 'societe') {
418
            $thirdpartyid = $this->id;
419
        }
420
        if ($this->element == 'contact') {
421
            $contactid = $this->id;
422
            $thirdpartyid = $object->fk_soc;
423
        }
424
        if ($this->element == 'user') {
425
            $contactid = $this->contact_id;
426
            $thirdpartyid = $object->fk_soc;
427
        }
428
429
        $out = '<!-- BEGIN part to show address block -->';
430
431
        $outdone = 0;
432
        $coords = $this->getFullAddress(1, ', ', $conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT);
433
        if ($coords) {
434
            if (!empty($conf->use_javascript_ajax)) {
435
                $namecoords = $this->getFullName($langs, 1) . '<br>' . $coords;
436
                // hideonsmatphone because copyToClipboard call jquery dialog that does not work with jmobile
437
                $out .= '<a href="#" class="hideonsmartphone" onclick="return copyToClipboard(\'' . dol_escape_js($namecoords) . '\',\'' . dol_escape_js($langs->trans("HelpCopyToClipboard")) . '\');">';
438
                $out .= img_picto($langs->trans("Address"), 'object_address.png');
439
                $out .= '</a> ';
440
            }
441
            $out .= dol_print_address($coords, 'address_' . $htmlkey . '_' . $this->id, $this->element, $this->id, 1, ', ');
442
            $outdone++;
443
            $outdone++;
444
        }
445
446
        if (!in_array($this->country_code, $countriesusingstate) && empty($conf->global->MAIN_FORCE_STATE_INTO_ADDRESS)   // If MAIN_FORCE_STATE_INTO_ADDRESS is on, state is already returned previously with getFullAddress
447
            && empty($conf->global->SOCIETE_DISABLE_STATE) && $this->state) {
448
            if (!empty($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT) && $conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 1 && $this->region) {
449
                $out .= ($outdone ? ' - ' : '') . $this->region . ' - ' . $this->state;
450
            } else {
451
                $out .= ($outdone ? ' - ' : '') . $this->state;
452
            }
453
            $outdone++;
454
        }
455
456
        if (!empty($this->phone) || !empty($this->phone_pro) || !empty($this->phone_mobile) || !empty($this->phone_perso) || !empty($this->fax) || !empty($this->office_phone) || !empty($this->user_mobile) || !empty($this->office_fax)) $out .= ($outdone ? '<br>' : '');
457
        if (!empty($this->phone) && empty($this->phone_pro)) {        // For objects that store pro phone into ->phone
458
            $out .= dol_print_phone($this->phone, $this->country_code, $contactid, $thirdpartyid, 'AC_TEL', '&nbsp;', 'phone', $langs->trans("PhonePro"));
459
            $outdone++;
460
        }
461
        if (!empty($this->phone_pro)) {
462
            $out .= dol_print_phone($this->phone_pro, $this->country_code, $contactid, $thirdpartyid, 'AC_TEL', '&nbsp;', 'phone', $langs->trans("PhonePro"));
463
            $outdone++;
464
        }
465
        if (!empty($this->phone_mobile)) {
466
            $out .= dol_print_phone($this->phone_mobile, $this->country_code, $contactid, $thirdpartyid, 'AC_TEL', '&nbsp;', 'mobile', $langs->trans("PhoneMobile"));
467
            $outdone++;
468
        }
469
        if (!empty($this->phone_perso)) {
470
            $out .= dol_print_phone($this->phone_perso, $this->country_code, $contactid, $thirdpartyid, 'AC_TEL', '&nbsp;', 'phone', $langs->trans("PhonePerso"));
471
            $outdone++;
472
        }
473
        if (!empty($this->office_phone)) {
474
            $out .= dol_print_phone($this->office_phone, $this->country_code, $contactid, $thirdpartyid, 'AC_TEL', '&nbsp;', 'phone', $langs->trans("PhonePro"));
475
            $outdone++;
476
        }
477
        if (!empty($this->user_mobile)) {
478
            $out .= dol_print_phone($this->user_mobile, $this->country_code, $contactid, $thirdpartyid, 'AC_TEL', '&nbsp;', 'mobile', $langs->trans("PhoneMobile"));
479
            $outdone++;
480
        }
481
        if (!empty($this->fax)) {
482
            $out .= dol_print_phone($this->fax, $this->country_code, $contactid, $thirdpartyid, 'AC_FAX', '&nbsp;', 'fax', $langs->trans("Fax"));
483
            $outdone++;
484
        }
485
        if (!empty($this->office_fax)) {
486
            $out .= dol_print_phone($this->office_fax, $this->country_code, $contactid, $thirdpartyid, 'AC_FAX', '&nbsp;', 'fax', $langs->trans("Fax"));
487
            $outdone++;
488
        }
489
490
        $out .= '<div style="clear: both;"></div>';
491
        $outdone = 0;
492
        if (!empty($this->email)) {
493
            $out .= dol_print_email($this->email, $this->id, $object->id, 'AC_EMAIL', 0, 0, 1);
494
            $outdone++;
495
        }
496
        if (!empty($this->url)) {
497
            $out .= dol_print_url($this->url, '_goout', 0, 1);
498
            $outdone++;
499
        }
500
        $out .= '<div style="clear: both;">';
501
        if (!empty($conf->socialnetworks->enabled)) {
502
            if ($this->skype) $out .= dol_print_socialnetworks($this->skype, $this->id, $object->id, 'skype');
503
            $outdone++;
504
            if ($this->jabberid) $out .= dol_print_socialnetworks($this->jabberid, $this->id, $object->id, 'jabber');
505
            $outdone++;
506
            if ($this->twitter) $out .= dol_print_socialnetworks($this->twitter, $this->id, $object->id, 'twitter');
507
            $outdone++;
508
            if ($this->facebook) $out .= dol_print_socialnetworks($this->facebook, $this->id, $object->id, 'facebook');
509
            $outdone++;
510
        }
511
        $out .= '</div>';
512
513
        $out .= '<!-- END Part to show address block -->';
514
515
        return $out;
516
    }
517
518
    /**
519
     *    Return full address of contact
520
     *
521
     * @param int $withcountry 1=Add country into address string
522
     * @param string $sep Separator to use to build string
523
     * @param int $withregion 1=Add region into address string
524
     * @return        string                            Full address string
525
     */
526
    function getFullAddress($withcountry = 0, $sep = "\n", $withregion = 0)
527
    {
528
        if ($withcountry && $this->country_id && (empty($this->country_code) || empty($this->country))) {
529
            require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
530
            $tmparray = getCountry($this->country_id, 'all');
531
            $this->country_code = $tmparray['code'];
532
            $this->country = $tmparray['label'];
533
        }
534
535
        if ($withregion && $this->state_id && (empty($this->state_code) || empty($this->state) || empty($this->region) || empty($this->region_cpde))) {
536
            require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
537
            $tmparray = getState($this->state_id, 'all', 0, 1);
538
            $this->state_code = $tmparray['code'];
539
            $this->state = $tmparray['label'];
540
            $this->region_code = $tmparray['region_code'];
541
            $this->region = $tmparray['region'];
542
        }
543
544
        return dol_format_address($this, $withcountry, $sep);
545
    }
546
547
    /**
548
     *    Return full name (civility+' '+name+' '+lastname)
549
     *
550
     * @param Translate $langs Language object for translation of civility (used only if option is 1)
551
     * @param int $option 0=No option, 1=Add civility
552
     * @param int $nameorder -1=Auto, 0=Lastname+Firstname, 1=Firstname+Lastname, 2=Firstname
553
     * @param int $maxlen Maximum length
554
     * @return    string                        String with full name
555
     */
556
    function getFullName($langs, $option = 0, $nameorder = -1, $maxlen = 0)
557
    {
558
        //print "lastname=".$this->lastname." name=".$this->name." nom=".$this->nom."<br>\n";
559
        $lastname = $this->lastname;
560
        $firstname = $this->firstname;
561
        if (empty($lastname)) $lastname = (isset($this->lastname) ? $this->lastname : (isset($this->name) ? $this->name : (isset($this->nom) ? $this->nom : (isset($this->societe) ? $this->societe : (isset($this->company) ? $this->company : '')))));
562
563
        $ret = '';
564
        if ($option && $this->civility_id) {
565
            if ($langs->transnoentitiesnoconv("Civility" . $this->civility_id) != "Civility" . $this->civility_id) $ret .= $langs->transnoentitiesnoconv("Civility" . $this->civility_id) . ' ';
566
            else $ret .= $this->civility_id . ' ';
567
        }
568
569
        $ret .= dolGetFirstLastname($firstname, $lastname, $nameorder);
570
571
        return dol_trunc($ret, $maxlen);
572
    }
573
574
575
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
576
577
    /**
578
     * Return the link of last main doc file for direct public download.
579
     *
580
     * @param string $modulepart Module related to document
581
     * @param int $initsharekey Init the share key if it was not yet defined
582
     * @param int $relativelink 0=Return full external link, 1=Return link relative to root of file
583
     * @return    string                        Link or empty string if there is no download link
584
     */
585
    function getLastMainDocLink($modulepart, $initsharekey = 0, $relativelink = 0)
586
    {
587
        global $user, $dolibarr_main_url_root;
588
589
        if (empty($this->last_main_doc)) {
590
            return '';        // No way to known which document name to use
591
        }
592
593
        include_once DOL_DOCUMENT_ROOT . '/ecm/class/ecmfiles.class.php';
594
        $ecmfile = new EcmFiles($this->db);
0 ignored issues
show
Bug introduced by alxarafe
The type Alixar\Base\EcmFiles was not found. Did you mean EcmFiles? If so, make sure to prefix the type with \.
Loading history...
595
        $result = $ecmfile->fetch(0, '', $this->last_main_doc);
596
        if ($result < 0) {
597
            $this->error = $ecmfile->error;
598
            $this->errors = $ecmfile->errors;
599
            return -1;
600
        }
601
602
        if (empty($ecmfile->id)) {
603
            // Add entry into index
604
            if ($initsharekey) {
605
                require_once DOL_DOCUMENT_ROOT . '/core/lib/security2.lib.php';
606
                // TODO We can't, we dont' have full path of file, only last_main_doc adn ->element, so we must rebuild full path first
607
                /*
608
				$ecmfile->filepath = $rel_dir;
609
				$ecmfile->filename = $filename;
610
				$ecmfile->label = md5_file(dol_osencode($destfull));	// hash of file content
611
				$ecmfile->fullpath_orig = '';
612
				$ecmfile->gen_or_uploaded = 'generated';
613
				$ecmfile->description = '';    // indexed content
614
				$ecmfile->keyword = '';        // keyword content
615
				$ecmfile->share = getRandomPassword(true);
616
				$result = $ecmfile->create($user);
617
				if ($result < 0)
618
				{
619
					$this->error = $ecmfile->error;
620
					$this->errors = $ecmfile->errors;
621
				}
622
				*/
623
            } else return '';
624
        } elseif (empty($ecmfile->share)) {
625
            // Add entry into index
626
            if ($initsharekey) {
627
                require_once DOL_DOCUMENT_ROOT . '/core/lib/security2.lib.php';
628
                $ecmfile->share = getRandomPassword(true);
629
                $ecmfile->update($user);
630
            } else return '';
631
        }
632
633
        // Define $urlwithroot
634
        $urlwithouturlroot = preg_replace('/' . preg_quote(DOL_URL_ROOT, '/') . '$/i', '', trim($dolibarr_main_url_root));
635
        $urlwithroot = $urlwithouturlroot . DOL_URL_ROOT;        // This is to use external domain name found into config file
636
        //$urlwithroot=DOL_MAIN_URL_ROOT;					// This is to use same domain name than current
637
638
        $forcedownload = 0;
639
640
        $paramlink = '';
641
        //if (! empty($modulepart)) $paramlink.=($paramlink?'&':'').'modulepart='.$modulepart;		// For sharing with hash (so public files), modulepart is not required.
642
        //if (! empty($ecmfile->entity)) $paramlink.='&entity='.$ecmfile->entity; 					// For sharing with hash (so public files), entity is not required.
643
        //$paramlink.=($paramlink?'&':'').'file='.urlencode($filepath);								// No need of name of file for public link, we will use the hash
644
        if (!empty($ecmfile->share)) $paramlink .= ($paramlink ? '&' : '') . 'hashp=' . $ecmfile->share;            // Hash for public share
645
        if ($forcedownload) $paramlink .= ($paramlink ? '&' : '') . 'attachment=1';
646
647
        if ($relativelink) {
648
            $linktoreturn = 'document.php' . ($paramlink ? '?' . $paramlink : '');
649
        } else {
650
            $linktoreturn = $urlwithroot . '/document.php' . ($paramlink ? '?' . $paramlink : '');
651
        }
652
653
        // Here $ecmfile->share is defined
654
        return $linktoreturn;
655
    }
656
657
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
658
659
    /**
660
     *    Copy contact from one element to current
661
     *
662
     * @param CommonObject $objFrom Source element
0 ignored issues
show
Bug introduced by alxarafe
The type Alixar\Base\CommonObject was not found. Did you mean CommonObject? If so, make sure to prefix the type with \.
Loading history...
663
     * @param string $source Nature of contact ('internal' or 'external')
664
     * @return   int                         >0 if OK, <0 if KO
665
     */
666
    function copy_linked_contact($objFrom, $source = 'internal')
667
    {
668
        // phpcs:enable
669
        $contacts = $objFrom->liste_contact(-1, $source);
670
        foreach ($contacts as $contact) {
671
            if ($this->add_contact($contact['id'], $contact['fk_c_type_contact'], $contact['source']) < 0) {
672
                $this->error = $this->db->lasterror();
673
                return -1;
674
            }
675
        }
676
        return 1;
677
    }
678
679
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
680
681
    /**
682
     *  Add a link between element $this->element and a contact
683
     *
684
     * @param int $fk_socpeople Id of thirdparty contact (if source = 'external') or id of user (if souce = 'internal') to link
685
     * @param int $type_contact Type of contact (code or id). Must be id or code found into table llx_c_type_contact. For example: SALESREPFOLL
686
     * @param string $source external=Contact extern (llx_socpeople), internal=Contact intern (llx_user)
687
     * @param int $notrigger Disable all triggers
688
     * @return int                        <0 if KO, >0 if OK
689
     */
690
    function add_contact($fk_socpeople, $type_contact, $source = 'external', $notrigger = 0)
691
    {
692
        // phpcs:enable
693
        global $user, $langs;
694
695
696
        dol_syslog(get_class($this) . "::add_contact $fk_socpeople, $type_contact, $source, $notrigger");
697
698
        // Check parameters
699
        if ($fk_socpeople <= 0) {
700
            $langs->load("errors");
701
            $this->error = $langs->trans("ErrorWrongValueForParameterX", "1");
702
            dol_syslog(get_class($this) . "::add_contact " . $this->error, LOG_ERR);
703
            return -1;
704
        }
705
        if (!$type_contact) {
706
            $langs->load("errors");
707
            $this->error = $langs->trans("ErrorWrongValueForParameterX", "2");
708
            dol_syslog(get_class($this) . "::add_contact " . $this->error, LOG_ERR);
709
            return -2;
710
        }
711
712
        $id_type_contact = 0;
713
        if (is_numeric($type_contact)) {
714
            $id_type_contact = $type_contact;
715
        } else {
716
            // We look for id type_contact
717
            $sql = "SELECT tc.rowid";
718
            $sql .= " FROM " . MAIN_DB_PREFIX . "c_type_contact as tc";
719
            $sql .= " WHERE tc.element='" . $this->db->escape($this->element) . "'";
720
            $sql .= " AND tc.source='" . $this->db->escape($source) . "'";
721
            $sql .= " AND tc.code='" . $this->db->escape($type_contact) . "' AND tc.active=1";
722
            //print $sql;
723
            $resql = $this->db->query($sql);
724
            if ($resql) {
725
                $obj = $this->db->fetch_object($resql);
726
                if ($obj) $id_type_contact = $obj->rowid;
727
            }
728
        }
729
730
        if ($id_type_contact == 0) {
731
            $this->error = 'CODE_NOT_VALID_FOR_THIS_ELEMENT';
732
            dol_syslog("CODE_NOT_VALID_FOR_THIS_ELEMENT: Code type of contact '" . $type_contact . "' does not exists or is not active for element " . $this->element . ", we can ignore it");
733
            return -3;
734
        }
735
736
        $datecreate = dol_now();
737
738
        // Socpeople must have already been added by some trigger, then we have to check it to avoid DB_ERROR_RECORD_ALREADY_EXISTS error
739
        $TListeContacts = $this->liste_contact(-1, $source);
740
        $already_added = false;
741
        if (!empty($TListeContacts)) {
742
            foreach ($TListeContacts as $array_contact) {
743
                if ($array_contact['status'] == 4 && $array_contact['id'] == $fk_socpeople && $array_contact['fk_c_type_contact'] == $id_type_contact) {
744
                    $already_added = true;
745
                    break;
746
                }
747
            }
748
        }
749
750
        if (!$already_added) {
751
752
            $this->db->begin();
753
754
            // Insert into database
755
            $sql = "INSERT INTO " . MAIN_DB_PREFIX . "element_contact";
756
            $sql .= " (element_id, fk_socpeople, datecreate, statut, fk_c_type_contact) ";
757
            $sql .= " VALUES (" . $this->id . ", " . $fk_socpeople . " , ";
758
            $sql .= "'" . $this->db->idate($datecreate) . "'";
759
            $sql .= ", 4, " . $id_type_contact;
760
            $sql .= ")";
761
762
            $resql = $this->db->query($sql);
763
            if ($resql) {
764
                if (!$notrigger) {
765
                    $result = $this->call_trigger(strtoupper($this->element) . '_ADD_CONTACT', $user);
766
                    if ($result < 0) {
767
                        $this->db->rollback();
768
                        return -1;
769
                    }
770
                }
771
772
                $this->db->commit();
773
                return 1;
774
            } else {
775
                if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
776
                    $this->error = $this->db->errno();
777
                    $this->db->rollback();
778
                    echo 'err rollback';
779
                    return -2;
780
                } else {
781
                    $this->error = $this->db->error();
782
                    $this->db->rollback();
783
                    return -1;
784
                }
785
            }
786
        } else return 0;
787
    }
788
789
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
790
791
    /**
792
     *    Get array of all contacts for an object
793
     *
794
     * @param int $statut Status of links to get (-1=all)
795
     * @param string $source Source of contact: external or thirdparty (llx_socpeople) or internal (llx_user)
796
     * @param int $list 0:Return array contains all properties, 1:Return array contains just id
797
     * @param string $code Filter on this code of contact type ('SHIPPING', 'BILLING', ...)
798
     * @return    array|int                Array of contacts, -1 if error
799
     */
800
    function liste_contact($statut = -1, $source = 'external', $list = 0, $code = '')
801
    {
802
        // phpcs:enable
803
        global $langs;
804
805
        $tab = array();
806
807
        $sql = "SELECT ec.rowid, ec.statut as statuslink, ec.fk_socpeople as id, ec.fk_c_type_contact";    // This field contains id of llx_socpeople or id of llx_user
808
        if ($source == 'internal') $sql .= ", '-1' as socid, t.statut as statuscontact, t.login, t.photo";
809
        if ($source == 'external' || $source == 'thirdparty') $sql .= ", t.fk_soc as socid, t.statut as statuscontact";
810
        $sql .= ", t.civility as civility, t.lastname as lastname, t.firstname, t.email";
811
        $sql .= ", tc.source, tc.element, tc.code, tc.libelle";
812
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_type_contact tc";
813
        $sql .= ", " . MAIN_DB_PREFIX . "element_contact ec";
814
        if ($source == 'internal') $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "user t on ec.fk_socpeople = t.rowid";
815
        if ($source == 'external' || $source == 'thirdparty') $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "socpeople t on ec.fk_socpeople = t.rowid";
816
        $sql .= " WHERE ec.element_id =" . $this->id;
817
        $sql .= " AND ec.fk_c_type_contact=tc.rowid";
818
        $sql .= " AND tc.element='" . $this->db->escape($this->element) . "'";
819
        if ($code) $sql .= " AND tc.code = '" . $this->db->escape($code) . "'";
820
        if ($source == 'internal') $sql .= " AND tc.source = 'internal'";
821
        if ($source == 'external' || $source == 'thirdparty') $sql .= " AND tc.source = 'external'";
822
        $sql .= " AND tc.active=1";
823
        if ($statut >= 0) $sql .= " AND ec.statut = '" . $statut . "'";
824
        $sql .= " ORDER BY t.lastname ASC";
825
826
        dol_syslog(get_class($this) . "::liste_contact", LOG_DEBUG);
827
        $resql = $this->db->query($sql);
828
        if ($resql) {
829
            $num = $this->db->num_rows($resql);
830
            $i = 0;
831
            while ($i < $num) {
832
                $obj = $this->db->fetch_object($resql);
833
834
                if (!$list) {
835
                    $transkey = "TypeContact_" . $obj->element . "_" . $obj->source . "_" . $obj->code;
836
                    $libelle_type = ($langs->trans($transkey) != $transkey ? $langs->trans($transkey) : $obj->libelle);
837
                    $tab[$i] = array('source' => $obj->source, 'socid' => $obj->socid, 'id' => $obj->id,
838
                        'nom' => $obj->lastname,      // For backward compatibility
839
                        'civility' => $obj->civility, 'lastname' => $obj->lastname, 'firstname' => $obj->firstname, 'email' => $obj->email, 'login' => $obj->login, 'photo' => $obj->photo, 'statuscontact' => $obj->statuscontact,
840
                        'rowid' => $obj->rowid, 'code' => $obj->code, 'libelle' => $libelle_type, 'status' => $obj->statuslink, 'fk_c_type_contact' => $obj->fk_c_type_contact);
841
                } else {
842
                    $tab[$i] = $obj->id;
843
                }
844
845
                $i++;
846
            }
847
848
            return $tab;
849
        } else {
850
            $this->error = $this->db->lasterror();
851
            dol_print_error($this->db);
852
            return -1;
853
        }
854
    }
855
856
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
857
858
    /**
859
     * Call trigger based on this instance.
860
     * Some context information may also be provided into array property this->context.
861
     * NB:  Error from trigger are stacked in interface->errors
862
     * NB2: If return code of triggers are < 0, action calling trigger should cancel all transaction.
863
     *
864
     * @param string $trigger_name trigger's name to execute
865
     * @param User $user Object user
866
     * @return  int                       Result of run_triggers
867
     */
868
    function call_trigger($trigger_name, $user)
869
    {
870
        // phpcs:enable
871
        global $langs, $conf;
872
873
        include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
874
        $interface = new Interfaces($this->db);
0 ignored issues
show
Bug introduced by alxarafe
The type Alixar\Base\Interfaces was not found. Did you mean Interfaces? If so, make sure to prefix the type with \.
Loading history...
875
        $result = $interface->run_triggers($trigger_name, $this, $user, $langs, $conf);
876
877
        if ($result < 0) {
878
            if (!empty($this->errors)) {
879
                $this->errors = array_unique(array_merge($this->errors, $interface->errors));   // We use array_unique because when a trigger call another trigger on same object, this->errors is added twice.
880
            } else {
881
                $this->errors = $interface->errors;
882
            }
883
        }
884
        return $result;
885
    }
886
887
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
888
889
    /**
890
     *    Delete a link to contact line
891
     *
892
     * @param int $rowid Id of contact link line to delete
893
     * @param int $notrigger Disable all triggers
894
     * @return   int                        >0 if OK, <0 if KO
895
     */
896
    function delete_contact($rowid, $notrigger = 0)
897
    {
898
        // phpcs:enable
899
        global $user;
900
901
902
        $this->db->begin();
903
904
        $sql = "DELETE FROM " . MAIN_DB_PREFIX . "element_contact";
905
        $sql .= " WHERE rowid =" . $rowid;
906
907
        dol_syslog(get_class($this) . "::delete_contact", LOG_DEBUG);
908
        if ($this->db->query($sql)) {
909
            if (!$notrigger) {
910
                $result = $this->call_trigger(strtoupper($this->element) . '_DELETE_CONTACT', $user);
911
                if ($result < 0) {
912
                    $this->db->rollback();
913
                    return -1;
914
                }
915
            }
916
917
            $this->db->commit();
918
            return 1;
919
        } else {
920
            $this->error = $this->db->lasterror();
921
            $this->db->rollback();
922
            return -1;
923
        }
924
    }
925
926
    /**
927
     *    Delete all links between an object $this and all its contacts
928
     *
929
     * @param string $source '' or 'internal' or 'external'
930
     * @param string $code Type of contact (code or id)
931
     * @return   int                    >0 if OK, <0 if KO
932
     */
933
    function delete_linked_contact($source = '', $code = '')
934
    {
935
        // phpcs:enable
936
        $temp = array();
937
        $typeContact = $this->liste_type_contact($source, '', 0, 0, $code);
938
939
        foreach ($typeContact as $key => $value) {
940
            array_push($temp, $key);
941
        }
942
        $listId = implode(",", $temp);
943
944
        $sql = "DELETE FROM " . MAIN_DB_PREFIX . "element_contact";
945
        $sql .= " WHERE element_id = " . $this->id;
946
        if ($listId)
947
            $sql .= " AND fk_c_type_contact IN (" . $listId . ")";
948
949
        dol_syslog(get_class($this) . "::delete_linked_contact", LOG_DEBUG);
950
        if ($this->db->query($sql)) {
951
            return 1;
952
        } else {
953
            $this->error = $this->db->lasterror();
954
            return -1;
955
        }
956
    }
957
958
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
959
960
    /**
961
     *      Return array with list of possible values for type of contacts
962
     *
963
     * @param string $source 'internal', 'external' or 'all'
964
     * @param string $order Sort order by : 'position', 'code', 'rowid'...
965
     * @param int $option 0=Return array id->label, 1=Return array code->label
966
     * @param int $activeonly 0=all status of contact, 1=only the active
967
     * @param string $code Type of contact (Example: 'CUSTOMER', 'SERVICE')
968
     * @return array            Array list of type of contacts (id->label if option=0, code->label if option=1)
969
     */
970
    function liste_type_contact($source = 'internal', $order = 'position', $option = 0, $activeonly = 0, $code = '')
971
    {
972
        // phpcs:enable
973
        global $langs;
974
975
        if (empty($order)) $order = 'position';
976
        if ($order == 'position') $order .= ',code';
977
978
        $tab = array();
979
        $sql = "SELECT DISTINCT tc.rowid, tc.code, tc.libelle, tc.position";
980
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_type_contact as tc";
981
        $sql .= " WHERE tc.element='" . $this->db->escape($this->element) . "'";
982
        if ($activeonly == 1) $sql .= " AND tc.active=1"; // only the active types
983
        if (!empty($source) && $source != 'all') $sql .= " AND tc.source='" . $this->db->escape($source) . "'";
984
        if (!empty($code)) $sql .= " AND tc.code='" . $this->db->escape($code) . "'";
985
        $sql .= $this->db->order($order, 'ASC');
986
987
        //print "sql=".$sql;
988
        $resql = $this->db->query($sql);
989
        if ($resql) {
990
            $num = $this->db->num_rows($resql);
991
            $i = 0;
992
            while ($i < $num) {
993
                $obj = $this->db->fetch_object($resql);
994
995
                $transkey = "TypeContact_" . $this->element . "_" . $source . "_" . $obj->code;
996
                $libelle_type = ($langs->trans($transkey) != $transkey ? $langs->trans($transkey) : $obj->libelle);
997
                if (empty($option)) $tab[$obj->rowid] = $libelle_type;
998
                else $tab[$obj->code] = $libelle_type;
999
                $i++;
1000
            }
1001
            return $tab;
1002
        } else {
1003
            $this->error = $this->db->lasterror();
1004
            //dol_print_error($this->db);
1005
            return null;
1006
        }
1007
    }
1008
1009
    /**
1010
     *        Update status of a contact linked to object
1011
     *
1012
     * @param int $rowid Id of link between object and contact
1013
     * @return    int                    <0 if KO, >=0 if OK
1014
     */
1015
    function swapContactStatus($rowid)
1016
    {
1017
        $sql = "SELECT ec.datecreate, ec.statut, ec.fk_socpeople, ec.fk_c_type_contact,";
1018
        $sql .= " tc.code, tc.libelle";
1019
        //$sql.= ", s.fk_soc";
1020
        $sql .= " FROM (" . MAIN_DB_PREFIX . "element_contact as ec, " . MAIN_DB_PREFIX . "c_type_contact as tc)";
1021
        //$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople as s ON ec.fk_socpeople=s.rowid";	// Si contact de type external, alors il est lie a une societe
1022
        $sql .= " WHERE ec.rowid =" . $rowid;
1023
        $sql .= " AND ec.fk_c_type_contact=tc.rowid";
1024
        $sql .= " AND tc.element = '" . $this->db->escape($this->element) . "'";
1025
1026
        dol_syslog(get_class($this) . "::swapContactStatus", LOG_DEBUG);
1027
        $resql = $this->db->query($sql);
1028
        if ($resql) {
1029
            $obj = $this->db->fetch_object($resql);
1030
            $newstatut = ($obj->statut == 4) ? 5 : 4;
1031
            $result = $this->update_contact($rowid, $newstatut);
1032
            $this->db->free($resql);
1033
            return $result;
1034
        } else {
1035
            $this->error = $this->db->error();
1036
            dol_print_error($this->db);
1037
            return -1;
1038
        }
1039
    }
1040
1041
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1042
1043
    /**
1044
     *      Update a link to contact line
1045
     *
1046
     * @param int $rowid Id of line contact-element
1047
     * @param int $statut New status of link
1048
     * @param int $type_contact_id Id of contact type (not modified if 0)
1049
     * @param int $fk_socpeople Id of soc_people to update (not modified if 0)
1050
     * @return int                        <0 if KO, >= 0 if OK
1051
     */
1052
    function update_contact($rowid, $statut, $type_contact_id = 0, $fk_socpeople = 0)
1053
    {
1054
        // phpcs:enable
1055
        // Insert into database
1056
        $sql = "UPDATE " . MAIN_DB_PREFIX . "element_contact set";
1057
        $sql .= " statut = " . $statut;
1058
        if ($type_contact_id) $sql .= ", fk_c_type_contact = '" . $type_contact_id . "'";
1059
        if ($fk_socpeople) $sql .= ", fk_socpeople = '" . $fk_socpeople . "'";
1060
        $sql .= " where rowid = " . $rowid;
1061
        $resql = $this->db->query($sql);
1062
        if ($resql) {
1063
            return 0;
1064
        } else {
1065
            $this->error = $this->db->lasterror();
1066
            return -1;
1067
        }
1068
    }
1069
1070
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1071
1072
    /**
1073
     *      Return id of contacts for a source and a contact code.
1074
     *      Example: contact client de facturation ('external', 'BILLING')
1075
     *      Example: contact client de livraison ('external', 'SHIPPING')
1076
     *      Example: contact interne suivi paiement ('internal', 'SALESREPFOLL')
1077
     *
1078
     * @param string $source 'external' or 'internal'
1079
     * @param string $code 'BILLING', 'SHIPPING', 'SALESREPFOLL', ...
1080
     * @param int $status limited to a certain status
1081
     * @return array            List of id for such contacts
1082
     */
1083
    function getIdContact($source, $code, $status = 0)
1084
    {
1085
        global $conf;
1086
1087
        $result = array();
1088
        $i = 0;
1089
        //cas particulier pour les expeditions
1090
        if ($this->element == 'shipping' && $this->origin_id != 0) {
1091
            $id = $this->origin_id;
1092
            $element = 'commande';
1093
        } else if ($this->element == 'reception' && $this->origin_id != 0) {
1094
            $id = $this->origin_id;
1095
            $element = 'order_supplier';
1096
        } else {
1097
            $id = $this->id;
1098
            $element = $this->element;
1099
        }
1100
1101
        $sql = "SELECT ec.fk_socpeople";
1102
        $sql .= " FROM " . MAIN_DB_PREFIX . "element_contact as ec,";
1103
        if ($source == 'internal') $sql .= " " . MAIN_DB_PREFIX . "user as c,";
1104
        if ($source == 'external') $sql .= " " . MAIN_DB_PREFIX . "socpeople as c,";
1105
        $sql .= " " . MAIN_DB_PREFIX . "c_type_contact as tc";
1106
        $sql .= " WHERE ec.element_id = " . $id;
1107
        $sql .= " AND ec.fk_socpeople = c.rowid";
1108
        if ($source == 'internal') $sql .= " AND c.entity IN (" . getEntity('user') . ")";
1109
        if ($source == 'external') $sql .= " AND c.entity IN (" . getEntity('societe') . ")";
1110
        $sql .= " AND ec.fk_c_type_contact = tc.rowid";
1111
        $sql .= " AND tc.element = '" . $element . "'";
1112
        $sql .= " AND tc.source = '" . $source . "'";
1113
        $sql .= " AND tc.code = '" . $code . "'";
1114
        $sql .= " AND tc.active = 1";
1115
        if ($status) $sql .= " AND ec.statut = " . $status;
1116
1117
        dol_syslog(get_class($this) . "::getIdContact", LOG_DEBUG);
1118
        $resql = $this->db->query($sql);
1119
        if ($resql) {
1120
            while ($obj = $this->db->fetch_object($resql)) {
1121
                $result[$i] = $obj->fk_socpeople;
1122
                $i++;
1123
            }
1124
        } else {
1125
            $this->error = $this->db->error();
1126
            return null;
1127
        }