dolibarr 23.0.4
contact.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2002-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be>
4 * Copyright (C) 2004-2013 Laurent Destailleur <eldy@users.sourceforge.net>
5 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2007 Franky Van Liedekerke <franky.van.liedekerker@telenet.be>
7 * Copyright (C) 2008 Raphael Bertrand (Resultic) <raphael.bertrand@resultic.fr>
8 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
9 * Copyright (C) 2013 Alexandre Spangaro <aspangaro@open-dsi.fr>
10 * Copyright (C) 2013 Juanjo Menent <jmenent@2byte.es>
11 * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
12 * Copyright (C) 2019 Nicolas ZABOURI <info@inovea-conseil.com>
13 * Copyright (C) 2020 Open-Dsi <support@open-dsi.fr>
14 * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
15 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 3 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program. If not, see <https://www.gnu.org/licenses/>.
29 */
30
36require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
37require_once DOL_DOCUMENT_ROOT.'/core/class/commonsocialnetworks.class.php';
38require_once DOL_DOCUMENT_ROOT.'/core/class/commonpeople.class.php';
39
40
44class Contact extends CommonObject
45{
47 use CommonPeople;
48
53 public $TRIGGER_PREFIX = 'CONTACT';
54
58 public $element = 'contact';
59
63 public $table_element = 'socpeople';
64
68 public $picto = 'contact';
69
94 // BEGIN MODULEBUILDER PROPERTIES
98 public $fields = array(
99 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -2, 'noteditable' => 1, 'notnull' => 1, 'index' => 1, 'position' => 1, 'comment' => 'Id', 'css' => 'left'),
100 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => 3, 'notnull' => 1, 'position' => 30, 'index' => 1),
101 'ref_ext' => array('type' => 'varchar(255)', 'label' => 'RefExt', 'enabled' => 1, 'visible' => 0, 'position' => 35),
102 'civility' => array('type' => 'varchar(6)', 'label' => 'Civility', 'enabled' => 1, 'visible' => 3, 'position' => 40),
103 'lastname' => array('type' => 'varchar(50)', 'label' => 'Lastname', 'enabled' => 1, 'visible' => 1, 'position' => 45, 'showoncombobox' => 1, 'searchall' => 1),
104 'name_alias' => array('type' => 'varchar(255)', 'label' => 'Name alias', 'enabled' => 1, 'visible' => -1, 'position' => 46, 'searchall' => 1),
105 'firstname' => array('type' => 'varchar(50)', 'label' => 'Firstname', 'enabled' => 1, 'visible' => 1, 'position' => 50, 'showoncombobox' => 1, 'searchall' => 1),
106 'poste' => array('type' => 'varchar(80)', 'label' => 'PostOrFunction', 'enabled' => 1, 'visible' => -1, 'position' => 52),
107 'address' => array('type' => 'varchar(255)', 'label' => 'Address', 'enabled' => 1, 'visible' => -1, 'position' => 55),
108 'zip' => array('type' => 'varchar(25)', 'label' => 'Zip', 'enabled' => 1, 'visible' => -1, 'position' => 60),
109 'town' => array('type' => 'varchar(50)', 'label' => 'Town', 'enabled' => 1, 'visible' => -1, 'position' => 65),
110 'fk_departement' => array('type' => 'integer', 'label' => 'Fk departement', 'enabled' => 1, 'visible' => 3, 'position' => 70),
111 'fk_pays' => array('type' => 'integer', 'label' => 'Fk pays', 'enabled' => 1, 'visible' => 3, 'position' => 75),
112 'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'enabled' => 1, 'visible' => 1, 'position' => 77, 'searchall' => 1),
113 'birthday' => array('type' => 'date', 'label' => 'Birthday', 'enabled' => 1, 'visible' => -1, 'position' => 80),
114 'phone' => array('type' => 'varchar(30)', 'label' => 'Phone', 'enabled' => 1, 'visible' => 1, 'position' => 90, 'searchall' => 1),
115 'phone_perso' => array('type' => 'varchar(30)', 'label' => 'PhonePerso', 'enabled' => 1, 'visible' => -1, 'position' => 95, 'searchall' => 1),
116 'phone_mobile' => array('type' => 'varchar(30)', 'label' => 'PhoneMobile', 'enabled' => 1, 'visible' => 1, 'position' => 100, 'searchall' => 1),
117 'fax' => array('type' => 'varchar(30)', 'label' => 'Fax', 'enabled' => 1, 'visible' => -1, 'position' => 105, 'searchall' => 1),
118 'email' => array('type' => 'varchar(255)', 'label' => 'Email', 'enabled' => 1, 'visible' => 1, 'position' => 110, 'searchall' => 1),
119 'socialnetworks' => array('type' => 'text', 'label' => 'SocialNetworks', 'enabled' => 1, 'visible' => 3, 'position' => 115),
120 'photo' => array('type' => 'varchar(255)', 'label' => 'Photo', 'enabled' => 1, 'visible' => 3, 'position' => 170),
121 'priv' => array('type' => 'smallint(6)', 'label' => 'ContactVisibility', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 175),
122 'fk_stcommcontact' => array('type' => 'integer', 'label' => 'ProspectStatus', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 220),
123 'fk_prospectcontactlevel' => array('type' => 'varchar(12)', 'label' => 'ProspectLevel', 'enabled' => 1, 'visible' => -1, 'position' => 255),
124 //no more used. Replace by a scan of email into mailing_unsubscribe. 'no_email' =>array('type'=>'smallint(6)', 'label'=>'No_Email', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>180),
125 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 195, 'searchall' => 1),
126 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 200, 'searchall' => 1),
127 'default_lang' => array('type' => 'varchar(6)', 'label' => 'Default lang', 'enabled' => 1, 'visible' => 3, 'position' => 205),
128 'canvas' => array('type' => 'varchar(32)', 'label' => 'Canvas', 'enabled' => 1, 'visible' => 3, 'position' => 210),
129 'ip' => array('type' => 'ip', 'label' => 'IPAddress', 'enabled' => '1', 'position' => 700, 'notnull' => 0, 'visible' => '-2', 'comment' => 'ip used to create record (for public submission page)'),
130 'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 300),
131 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 305),
132 'fk_user_creat' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'visible' => 3, 'position' => 310),
133 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'visible' => 3, 'position' => 315),
134 'statut' => array('type' => 'tinyint(4)', 'label' => 'Status', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 500),
135 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -1, 'position' => 1000),
136 );
137
141 public $civility_id; // In fact we store civility_code
145 public $civility_code;
149 public $civility;
150
154 public $gender;
155
159 public $birthday_alert;
160
166 public $civilite;
167
171 public $fullname;
172
176 public $name_alias;
177
181 public $address;
182
186 public $zip;
187
191 public $town;
192
196 public $state_id;
197
201 public $state_code;
202
206 public $state;
207
211 public $poste;
212
216 public $socid; // both socid and fk_soc are used
220 public $fk_soc; // both socid and fk_soc are used
221
225 public $socname;
226
231 public $statut;
232
236 public $code;
237
242 public $email;
243
250 public $mail;
251
256 public $url;
257
263 public $no_email;
264
269 public $socialnetworks;
270
274 public $photo;
275
279 public $phone_pro;
280
284 public $phone_perso;
285
289 public $phone_mobile;
290
294 public $fax;
295
300 public $priv;
301
305 public $birthday;
306
310 public $default_lang;
311
315 public $ref_facturation;
316
320 public $ref_contrat;
321
325 public $ref_commande;
326
330 public $ref_propal;
331
335 public $user_id;
336
340 public $user_login;
341
345 public $ip;
346 // END MODULEBUILDER PROPERTIES
347
351 public $roles;
352
356 public $cacheprospectstatus = array();
357
361 public $fk_prospectlevel;
362
366 public $stcomm_id;
367
371 public $statut_commercial;
372
376 public $stcomm_picto;
377
378
384 public function __construct($db)
385 {
386 $this->db = $db;
387 $this->statut = 1; // By default, status is enabled
388 $this->status = 1; // By default, status is enabled
389 $this->ismultientitymanaged = 1;
390 $this->isextrafieldmanaged = 1;
391
392 $this->fields['ref_ext']['visible'] = getDolGlobalInt('MAIN_LIST_SHOW_REF_EXT');
393
394 if (!isModEnabled('mailing')) {
395 $this->fields['no_email']['enabled'] = 0;
396 }
397 // typical ['s.nom'] is used for third-parties
398 if (!getDolGlobalString('SOCIETE_DISABLE_CONTACTS')) {
399 $this->fields['fk_soc']['enabled'] = 0;
400 $this->fields['fk_soc']['searchall'] = 0;
401 }
402
403 // If THIRDPARTY_ENABLE_PROSPECTION_ON_ALTERNATIVE_ADRESSES not set, there is no prospect level on contact level, only on thirdparty
404 if (getDolGlobalString('SOCIETE_DISABLE_PROSPECTS') || !getDolGlobalString('THIRDPARTY_ENABLE_PROSPECTION_ON_ALTERNATIVE_ADRESSES')) { // Default behaviour
405 $this->fields['fk_stcommcontact']['enabled'] = 0;
406 $this->fields['fk_prospectcontactlevel']['enabled'] = 0;
407 }
408
409 // Unset fields that are disabled
410 foreach ($this->fields as $key => $val) {
411 if (isset($val['enabled']) && empty($val['enabled'])) {
412 unset($this->fields[$key]);
413 }
414 }
415
416 // Translate some data of arrayofkeyval
417 /*if (is_object($langs))
418 {
419 foreach($this->fields as $key => $val)
420 {
421 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval']))
422 {
423 foreach($val['arrayofkeyval'] as $key2 => $val2)
424 {
425 $this->fields[$key]['arrayofkeyval'][$key2]=$langs->trans($val2);
426 }
427 }
428 }
429 }*/
430 }
431
437 public function loadStateBoard()
438 {
439 global $user, $hookmanager;
440
441 $this->nb = array();
442 $clause = "WHERE";
443
444 $sql = "SELECT count(sp.rowid) as nb";
445 $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as sp";
446 if (!$user->hasRight('societe', 'client', 'voir')) {
447 $sql .= ", ".MAIN_DB_PREFIX."societe as s";
448 $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
449 $sql .= " WHERE sp.fk_soc = s.rowid AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
450 $clause = "AND";
451 }
452 $sql .= " ".$clause." sp.entity IN (".getEntity($this->element).")";
453 $sql .= " AND (sp.priv='0' OR (sp.priv='1' AND sp.fk_user_creat = ".((int) $user->id)."))";
454 if ($user->socid > 0) {
455 $sql .= " AND sp.fk_soc = ".((int) $user->socid);
456 }
457 // Add where from hooks
458 if (is_object($hookmanager)) {
459 $parameters = array();
460 $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $this); // Note that $action and $object may have been modified by hook
461 $sql .= $hookmanager->resPrint;
462 }
463
464 $resql = $this->db->query($sql);
465 if ($resql) {
466 while ($obj = $this->db->fetch_object($resql)) {
467 $this->nb["contacts"] = $obj->nb;
468 }
469 $this->db->free($resql);
470 return 1;
471 } else {
472 dol_print_error($this->db);
473 $this->error = $this->db->lasterror();
474 return -1;
475 }
476 }
477
485 public function create($user, $notrigger = 0)
486 {
487 global $conf;
488
489 $error = 0;
490 $now = dol_now();
491
492 if (empty($this->date_creation)) {
493 $this->date_creation = $now;
494 }
495
496 $this->db->begin();
497
498 // Clean parameters
499 $this->name_alias = trim($this->name_alias);
500 $this->lastname = $this->lastname ? trim($this->lastname) : trim($this->name);
501 $this->firstname = trim($this->firstname);
502 $this->setUpperOrLowerCase();
503 if (empty($this->socid)) {
504 $this->socid = 0;
505 }
506 if (empty($this->priv)) {
507 $this->priv = 0;
508 }
509 if (!empty($this->statut) && empty($this->status)) {
510 $this->status = 1;
511 }
512 if (empty($this->status)) {
513 $this->status = 0; // This is to convert '' into '0' to avoid bad sql request
514 $this->statut = 0; // This is to convert '' into '0' to avoid bad sql request
515 }
516
517 // setEntity will set entity with the right value if empty or change it for the right value if multicompany module is active
518 $this->entity = setEntity($this);
519
520 $sql = "INSERT INTO ".MAIN_DB_PREFIX."socpeople (";
521 $sql .= " datec";
522 $sql .= ", fk_soc";
523 $sql .= ", name_alias";
524 $sql .= ", lastname";
525 $sql .= ", firstname";
526 $sql .= ", fk_user_creat";
527 $sql .= ", priv";
528 $sql .= ", fk_stcommcontact";
529 $sql .= ", statut";
530 $sql .= ", canvas";
531 $sql .= ", entity";
532 $sql .= ", ref_ext";
533 $sql .= ", import_key";
534 $sql .= ", ip";
535 $sql .= ") VALUES (";
536 $sql .= "'".$this->db->idate($now)."',";
537 if ($this->socid > 0) {
538 $sql .= " ".((int) $this->socid).",";
539 } else {
540 $sql .= "null,";
541 }
542 $sql .= "'".$this->db->escape($this->name_alias)."',";
543 $sql .= "'".$this->db->escape($this->lastname)."',";
544 $sql .= "'".$this->db->escape($this->firstname)."',";
545 $sql .= " ".($user->id > 0 ? ((int) $user->id) : "null").",";
546 $sql .= " ".((int) $this->priv).",";
547 $sql .= " 0,";
548 $sql .= " ".((int) $this->status).",";
549 $sql .= " ".(!empty($this->canvas) ? "'".$this->db->escape($this->canvas)."'" : "null").",";
550 $sql .= " ".((int) $this->entity).",";
551 $sql .= "'".$this->db->escape($this->ref_ext)."',";
552 $sql .= " ".(!empty($this->import_key) ? "'".$this->db->escape($this->import_key)."'" : "null").",";
553 $sql .= " ".(!empty($this->ip) ? "'".$this->db->escape($this->ip)."'" : "null");
554 $sql .= ")";
555
556 dol_syslog(get_class($this)."::create", LOG_DEBUG);
557 $resql = $this->db->query($sql);
558 if ($resql) {
559 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."socpeople");
560
561 $result = $this->update($this->id, $user, 1, 'add'); // This include updateRoles(), ...
562 if ($result < 0) {
563 $error++;
564 $this->error = $this->db->lasterror();
565 }
566
567 if (!$error) {
568 $result = $this->update_perso($this->id, $user, 1); // TODO Remove function update_perso, should be same than update
569 if ($result < 0) {
570 $error++;
571 $this->error = $this->db->lasterror();
572 }
573 }
574
575 if (!$error && !$notrigger) {
576 // Call trigger
577 $result = $this->call_trigger('CONTACT_CREATE', $user);
578 if ($result < 0) {
579 $error++;
580 }
581 // End call triggers
582 }
583
584 if (!$error) {
585 $this->db->commit();
586 return $this->id;
587 } else {
588 $this->db->rollback();
589 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
590 return -2;
591 }
592 } else {
593 $this->error = $this->db->lasterror();
594
595 $this->db->rollback();
596 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
597 return -1;
598 }
599 }
600
611 public function update($id, $user = null, $notrigger = 0, $action = 'update', $nosyncuser = 0)
612 {
613 global $conf;
614
615 if (empty($this->country_id) && !empty($this->country_code)) {
616 $country_id = getCountry($this->country_code, '3');
617 $this->country_id = is_int($country_id) ? $country_id : 0;
618 }
619
620 $error = 0;
621
622 $this->id = $id;
623
624 $this->entity = ((isset($this->entity) && is_numeric($this->entity)) ? $this->entity : $conf->entity);
625
626 // Clean parameters
627 $this->ref_ext = (empty($this->ref_ext) ? '' : trim($this->ref_ext));
628 $this->name_alias = trim($this->name_alias);
629 $this->lastname = trim($this->lastname) ? trim($this->lastname) : trim($this->lastname);
630 $this->firstname = trim($this->firstname);
631 $this->email = trim($this->email ?? '');
632 $this->phone_pro = trim($this->phone_pro);
633 $this->phone_perso = trim($this->phone_perso);
634 $this->phone_mobile = trim($this->phone_mobile);
635 $this->photo = trim($this->photo);
636 $this->fax = trim($this->fax);
637 $this->zip = (empty($this->zip) ? '' : trim($this->zip));
638 $this->town = (empty($this->town) ? '' : trim($this->town));
639 $this->country_id = (empty($this->country_id) || $this->country_id < 0) ? 0 : $this->country_id;
640 if (!empty($this->statut) && empty($this->status)) {
641 $this->status = 1;
642 }
643 if (empty($this->status)) {
644 $this->status = 0;
645 $this->statut = 0;
646 }
647 if (empty($this->civility_code) && !is_numeric($this->civility_id)) {
648 $this->civility_code = $this->civility_id; // For backward compatibility
649 }
650 $this->setUpperOrLowerCase();
651
652 $this->db->begin();
653
654 $sql = "UPDATE ".MAIN_DB_PREFIX."socpeople SET";
655 if ($this->socid > 0) {
656 $sql .= " fk_soc = ".((int) $this->socid).",";
657 } elseif ($this->socid == -1) {
658 $sql .= " fk_soc = NULL,";
659 }
660 $sql .= " civility='".$this->db->escape($this->civility_code)."'";
661 $sql .= ", name_alias='".$this->db->escape($this->name_alias)."'";
662 $sql .= ", lastname='".$this->db->escape($this->lastname)."'";
663 $sql .= ", firstname='".$this->db->escape($this->firstname)."'";
664 $sql .= ", address='".$this->db->escape((string) $this->address)."'";
665 $sql .= ", zip='".$this->db->escape($this->zip)."'";
666 $sql .= ", town='".$this->db->escape($this->town)."'";
667 $sql .= ", ref_ext = ".(!empty($this->ref_ext) ? "'".$this->db->escape($this->ref_ext)."'" : "NULL");
668 $sql .= ", fk_pays=".($this->country_id > 0 ? $this->country_id : 'NULL');
669 $sql .= ", fk_departement=".($this->state_id > 0 ? $this->state_id : 'NULL');
670 $sql .= ", poste='".$this->db->escape($this->poste)."'";
671 $sql .= ", fax='".$this->db->escape($this->fax)."'";
672 $sql .= ", email='".$this->db->escape($this->email)."'";
673 $sql .= ", socialnetworks = '".$this->db->escape(json_encode($this->socialnetworks))."'";
674 $sql .= ", photo='".$this->db->escape($this->photo)."'";
675 $sql .= ", birthday=".($this->birthday ? "'".$this->db->idate($this->birthday)."'" : "null");
676 $sql .= ", note_private = ".(isset($this->note_private) ? "'".$this->db->escape($this->note_private)."'" : "NULL");
677 $sql .= ", note_public = ".(isset($this->note_public) ? "'".$this->db->escape($this->note_public)."'" : "NULL");
678 $sql .= ", phone = ".(isset($this->phone_pro) ? "'".$this->db->escape($this->phone_pro)."'" : "NULL");
679 $sql .= ", phone_perso = ".(isset($this->phone_perso) ? "'".$this->db->escape($this->phone_perso)."'" : "NULL");
680 $sql .= ", phone_mobile = ".(isset($this->phone_mobile) ? "'".$this->db->escape($this->phone_mobile)."'" : "NULL");
681 $sql .= ", priv = ".((int) $this->priv);
682 $sql .= ", fk_prospectlevel = '".$this->db->escape($this->fk_prospectlevel)."'";
683 if (isset($this->stcomm_id)) {
684 $sql .= ", fk_stcommcontact = ".($this->stcomm_id > 0 || $this->stcomm_id == -1 ? $this->stcomm_id : "0");
685 }
686 $sql .= ", statut = ".((int) $this->status);
687 $sql .= ", fk_user_modif=".($user->id > 0 ? "'".$this->db->escape((string) $user->id)."'" : "NULL");
688 $sql .= ", default_lang=".($this->default_lang ? "'".$this->db->escape($this->default_lang)."'" : "NULL");
689 $sql .= ", entity = ".((int) $this->entity);
690 $sql .= " WHERE rowid = ".((int) $id);
691
692 dol_syslog(get_class($this)."::update", LOG_DEBUG);
693 $result = $this->db->query($sql);
694 if ($result) {
695 unset($this->country_code);
696 unset($this->country);
697 unset($this->state_code);
698 unset($this->state);
699
700 $action = 'update';
701
702 // Actions on extra fields
703 $result = $this->insertExtraFields();
704 if ($result < 0) {
705 $error++;
706 }
707
708 if (!$error) {
709 $result = $this->updateRoles();
710 if ($result < 0) {
711 $error++;
712 }
713 }
714
715 if (!$error && $this->user_id > 0) {
716 // If contact is linked to a user
717 $tmpobj = new User($this->db);
718 $tmpobj->fetch($this->user_id);
719 $usermustbemodified = 0;
720 if ($tmpobj->office_phone != $this->phone_pro) {
721 $tmpobj->office_phone = $this->phone_pro;
722 $usermustbemodified++;
723 }
724 if ($tmpobj->office_fax != $this->fax) {
725 $tmpobj->office_fax = $this->fax;
726 $usermustbemodified++;
727 }
728 if ($tmpobj->address != $this->address) {
729 $tmpobj->address = $this->address;
730 $usermustbemodified++;
731 }
732 if ($tmpobj->town != $this->town) {
733 $tmpobj->town = $this->town;
734 $usermustbemodified++;
735 }
736 if ($tmpobj->zip != $this->zip) {
737 $tmpobj->zip = $this->zip;
738 $usermustbemodified++;
739 }
740 if ($tmpobj->state_id != $this->state_id) {
741 $tmpobj->state_id = $this->state_id;
742 $usermustbemodified++;
743 }
744 if ($tmpobj->country_id != $this->country_id) {
745 $tmpobj->country_id = $this->country_id;
746 $usermustbemodified++;
747 }
748 if ($tmpobj->email != $this->email) {
749 $tmpobj->email = $this->email;
750 $usermustbemodified++;
751 }
752 $usersocialnetworks = (is_array($tmpobj->socialnetworks) ? $tmpobj->socialnetworks : array());
753 $contactsocialnetworks = (is_array($this->socialnetworks) ? $this->socialnetworks : array());
754 // Compare in both directions, so a network added on the contact is also seen as a difference
755 if (!empty(array_diff_assoc($usersocialnetworks, $contactsocialnetworks)) || !empty(array_diff_assoc($contactsocialnetworks, $usersocialnetworks))) {
756 $tmpobj->socialnetworks = $this->socialnetworks;
757 $usermustbemodified++;
758 }
759 if ($usermustbemodified) {
760 $result = $tmpobj->update($user, 0, 1, 1, 1);
761 if ($result < 0) {
762 $error++;
763 }
764 }
765 }
766
767 if (!$error && !$notrigger) {
768 // Call trigger
769 $result = $this->call_trigger('CONTACT_MODIFY', $user);
770 if ($result < 0) {
771 $error++;
772 }
773 // End call triggers
774 }
775
776 if (!$error) {
777 $this->db->commit();
778 return 1;
779 } else {
780 dol_syslog(get_class($this)."::update Error ".$this->error, LOG_ERR);
781 $this->db->rollback();
782 return -$error;
783 }
784 } else {
785 $this->error = $this->db->lasterror().' sql='.$sql;
786 $this->db->rollback();
787 return -1;
788 }
789 }
790
791
792 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
793 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
803 public function _load_ldap_dn($info, $mode = 0)
804 {
805 // phpcs:enable
806 global $conf;
807 $dn = '';
808 if ($mode == 0) {
809 $dn = getDolGlobalString('LDAP_KEY_CONTACTS') . "=".$info[getDolGlobalString('LDAP_KEY_CONTACTS')]."," . getDolGlobalString('LDAP_CONTACT_DN');
810 } elseif ($mode == 1) {
811 $dn = getDolGlobalString('LDAP_CONTACT_DN');
812 } elseif ($mode == 2) {
813 $dn = getDolGlobalString('LDAP_KEY_CONTACTS') . "=".$info[getDolGlobalString('LDAP_KEY_CONTACTS')];
814 }
815 return $dn;
816 }
817
818
819 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
820 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
826 public function _load_ldap_info()
827 {
828 // phpcs:enable
829 global $conf, $langs;
830
831 $info = array();
832
833 // Object classes
834 $info["objectclass"] = explode(',', getDolGlobalString('LDAP_CONTACT_OBJECT_CLASS'));
835
836 $this->fullname = $this->getFullName($langs);
837
838 // Fields
839 if ($this->fullname && getDolGlobalString('LDAP_CONTACT_FIELD_FULLNAME')) {
840 $info[getDolGlobalString('LDAP_CONTACT_FIELD_FULLNAME')] = $this->fullname;
841 }
842 if ($this->lastname && getDolGlobalString('LDAP_CONTACT_FIELD_NAME')) {
843 $info[getDolGlobalString('LDAP_CONTACT_FIELD_NAME')] = $this->lastname;
844 }
845 if ($this->firstname && getDolGlobalString('LDAP_CONTACT_FIELD_FIRSTNAME')) {
846 $info[getDolGlobalString('LDAP_CONTACT_FIELD_FIRSTNAME')] = $this->firstname;
847 }
848
849 if ($this->poste) {
850 $info["title"] = $this->poste;
851 }
852 if ($this->socid > 0) {
853 $soc = new Societe($this->db);
854 $soc->fetch($this->socid);
855
856 $info[getDolGlobalString('LDAP_CONTACT_FIELD_COMPANY')] = $soc->name;
857 if ($soc->client == 1) {
858 $info["businessCategory"] = "Customers";
859 }
860 if ($soc->client == 2) {
861 $info["businessCategory"] = "Prospects";
862 }
863 if ($soc->fournisseur == 1) {
864 $info["businessCategory"] = "Suppliers";
865 }
866 }
867 if ($this->address && getDolGlobalString('LDAP_CONTACT_FIELD_ADDRESS')) {
868 $info[getDolGlobalString('LDAP_CONTACT_FIELD_ADDRESS')] = $this->address;
869 }
870 if ($this->zip && getDolGlobalString('LDAP_CONTACT_FIELD_ZIP')) {
871 $info[getDolGlobalString('LDAP_CONTACT_FIELD_ZIP')] = $this->zip;
872 }
873 if ($this->town && getDolGlobalString('LDAP_CONTACT_FIELD_TOWN')) {
874 $info[getDolGlobalString('LDAP_CONTACT_FIELD_TOWN')] = $this->town;
875 }
876 if ($this->country_code && getDolGlobalString('LDAP_CONTACT_FIELD_COUNTRY')) {
877 $info[getDolGlobalString('LDAP_CONTACT_FIELD_COUNTRY')] = $this->country_code;
878 }
879 if ($this->phone_pro && getDolGlobalString('LDAP_CONTACT_FIELD_PHONE')) {
880 $info[getDolGlobalString('LDAP_CONTACT_FIELD_PHONE')] = $this->phone_pro;
881 }
882 if ($this->phone_perso && getDolGlobalString('LDAP_CONTACT_FIELD_HOMEPHONE')) {
883 $info[getDolGlobalString('LDAP_CONTACT_FIELD_HOMEPHONE')] = $this->phone_perso;
884 }
885 if ($this->phone_mobile && getDolGlobalString('LDAP_CONTACT_FIELD_MOBILE')) {
886 $info[getDolGlobalString('LDAP_CONTACT_FIELD_MOBILE')] = $this->phone_mobile;
887 }
888 if ($this->fax && getDolGlobalString('LDAP_CONTACT_FIELD_FAX')) {
889 $info[getDolGlobalString('LDAP_CONTACT_FIELD_FAX')] = $this->fax;
890 }
891 if ($this->note_private && getDolGlobalString('LDAP_CONTACT_FIELD_DESCRIPTION')) {
892 $info[getDolGlobalString('LDAP_CONTACT_FIELD_DESCRIPTION')] = dol_string_nohtmltag($this->note_private, 2);
893 }
894 if ($this->email && getDolGlobalString('LDAP_CONTACT_FIELD_MAIL')) {
895 $info[getDolGlobalString('LDAP_CONTACT_FIELD_MAIL')] = $this->email;
896 }
897
898 if (getDolGlobalString('LDAP_SERVER_TYPE') == 'egroupware') {
899 $info["objectclass"][4] = "phpgwContact"; // compatibilite egroupware
900
901 $info['uidnumber'] = $this->id;
902
903 $info['phpgwTz'] = 0;
904 $info['phpgwMailType'] = 'INTERNET';
905 $info['phpgwMailHomeType'] = 'INTERNET';
906
907 $info["phpgwContactTypeId"] = 'n';
908 $info["phpgwContactCatId"] = 0;
909 $info["phpgwContactAccess"] = "public";
910
911 $info["phpgwContactOwner"] = 1;
912
913 if ($this->email) {
914 $info["rfc822Mailbox"] = $this->email;
915 }
916 if ($this->phone_mobile) {
917 $info["phpgwCellTelephoneNumber"] = $this->phone_mobile;
918 }
919 }
920
921 return $info;
922 }
923
924
925 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
934 public function update_perso($id, $user = null, $notrigger = 0)
935 {
936 // phpcs:enable
937 $error = 0;
938 $result = false;
939
940 $this->db->begin();
941
942 // Update the contact
943 $sql = "UPDATE ".MAIN_DB_PREFIX."socpeople SET";
944 $sql .= " birthday = ".($this->birthday ? "'".$this->db->idate($this->birthday)."'" : "null");
945 $sql .= ", photo = ".($this->photo ? "'".$this->db->escape($this->photo)."'" : "null");
946 if ($user) {
947 $sql .= ", fk_user_modif = ".((int) $user->id);
948 }
949 $sql .= " WHERE rowid = ".((int) $id);
950
951 dol_syslog(get_class($this)."::update_perso this->birthday=".$this->birthday." -", LOG_DEBUG);
952 $resql = $this->db->query($sql);
953 if (!$resql) {
954 $error++;
955 $this->error = $this->db->lasterror();
956 }
957
958 if ($user) {
959 // Update birthday alert
960 if (!empty($this->birthday_alert)) {
961 //check existing
962 $sql_check = "SELECT rowid FROM " . MAIN_DB_PREFIX . "user_alert WHERE type = 1 AND fk_contact = " . ((int) $id) . " AND fk_user = " . ((int) $user->id);
963 $result_check = $this->db->query($sql_check);
964 if (!$result_check || ($this->db->num_rows($result_check) < 1)) {
965 //insert
966 $sql = "INSERT INTO " . MAIN_DB_PREFIX . "user_alert(type, fk_contact, fk_user) ";
967 $sql .= "VALUES (1," . ((int) $id) . "," . ((int) $user->id) . ")";
968 $result = $this->db->query($sql);
969 if (!$result) {
970 $error++;
971 $this->error = $this->db->lasterror();
972 }
973 } else {
974 $result = true;
975 }
976 } else {
977 $sql = "DELETE FROM " . MAIN_DB_PREFIX . "user_alert ";
978 $sql .= "WHERE type=1 AND fk_contact=" . ((int) $id) . " AND fk_user=" . ((int) $user->id);
979 $result = $this->db->query($sql);
980 if (!$result) {
981 $error++;
982 $this->error = $this->db->lasterror();
983 }
984 }
985
986 if (!$error && !$notrigger) {
987 // Call trigger
988 $result = $this->call_trigger('CONTACT_MODIFY', $user);
989 if ($result < 0) {
990 $error++;
991 }
992 // End call triggers
993 }
994 }
995
996 if (!$error) {
997 $this->db->commit();
998 return 1;
999 } else {
1000 dol_syslog(get_class($this)."::update Error ".$this->error, LOG_ERR);
1001 $this->db->rollback();
1002 return -$error;
1003 }
1004 }
1005
1006
1018 public function fetch($id, $user = null, $ref_ext = '', $email = '', $loadalsoroles = 0, $socid = 0)
1019 {
1020 global $langs;
1021
1022 dol_syslog(get_class($this)."::fetch id=".$id." ref_ext=".$ref_ext." email=".$email, LOG_DEBUG);
1023
1024 if (empty($id) && empty($ref_ext) && empty($email)) {
1025 $this->error = 'BadParameter';
1026 return -1;
1027 }
1028
1029 $langs->loadLangs(array("dict", "companies"));
1030
1031 $sql = "SELECT c.rowid, c.entity, c.fk_soc, c.ref_ext, c.civility as civility_code, c.name_alias, c.lastname, c.firstname,";
1032 $sql .= " c.address, c.statut as status, c.zip, c.town,";
1033 $sql .= " c.fk_pays as country_id,";
1034 $sql .= " c.fk_departement as state_id,";
1035 $sql .= " c.birthday,";
1036 $sql .= " c.poste, c.phone, c.phone_perso, c.phone_mobile, c.fax, c.email,";
1037 $sql .= " c.socialnetworks,";
1038 $sql .= " c.photo,";
1039 $sql .= " c.priv, c.note_private, c.note_public, c.default_lang, c.canvas,";
1040 $sql .= " c.fk_prospectlevel, c.fk_stcommcontact, st.libelle as stcomm, st.picto as stcomm_picto,";
1041 $sql .= " c.import_key,";
1042 $sql .= " c.datec as date_creation, GREATEST(c.tms, COALESCE(cef.tms, c.tms)) as date_modification, c.fk_user_creat, c.fk_user_modif,";
1043 $sql .= " co.label as country, co.code as country_code,";
1044 $sql .= " d.nom as state, d.code_departement as state_code,";
1045 $sql .= " u.rowid as user_id, u.login as user_login,";
1046 $sql .= " s.nom as socname, s.address as socaddress, s.zip as soccp, s.town as soccity, s.default_lang as socdefault_lang";
1047 $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as c";
1048 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople_extrafields as cef ON cef.fk_object=c.rowid";
1049 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as co ON c.fk_pays = co.rowid";
1050 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as d ON c.fk_departement = d.rowid";
1051 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON c.rowid = u.fk_socpeople";
1052 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON c.fk_soc = s.rowid";
1053 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_stcommcontact as st ON c.fk_stcommcontact = st.id';
1054 if ($id) {
1055 $sql .= " WHERE c.rowid = ".((int) $id);
1056 } else {
1057 $sql .= " WHERE c.entity IN (".getEntity($this->element).")";
1058 if ($ref_ext) {
1059 $sql .= " AND c.ref_ext = '".$this->db->escape($ref_ext)."'";
1060 }
1061 if ($email) {
1062 $sql .= " AND c.email = '".$this->db->escape($email)."'";
1063 }
1064 if ($socid) {
1065 $sql .= " AND c.fk_soc = ".((int) $socid);
1066 }
1067 }
1068
1069 $resql = $this->db->query($sql);
1070 if ($resql) {
1071 $num = $this->db->num_rows($resql);
1072 if ($num > 1) {
1073 $this->error = 'Fetch found several records. Rename one of contact to avoid duplicate.';
1074 dol_syslog($this->error, LOG_ERR);
1075
1076 return 2;
1077 } elseif ($num) { // $num = 1
1078 $obj = $this->db->fetch_object($resql);
1079
1080 $this->id = $obj->rowid;
1081 $this->entity = $obj->entity;
1082 $this->ref = $obj->rowid;
1083 $this->ref_ext = $obj->ref_ext;
1084
1085 $this->civility_code = $obj->civility_code;
1086 $this->civility = $obj->civility_code ? ($langs->trans("Civility".$obj->civility_code) != "Civility".$obj->civility_code ? $langs->trans("Civility".$obj->civility_code) : $obj->civility_code) : '';
1087
1088 $this->name_alias = $obj->name_alias;
1089 $this->lastname = $obj->lastname;
1090 $this->firstname = $obj->firstname;
1091 $this->address = $obj->address;
1092 $this->zip = $obj->zip;
1093 $this->town = $obj->town;
1094
1095 $this->date_creation = $this->db->jdate($obj->date_creation);
1096 $this->date_modification = $this->db->jdate($obj->date_modification);
1097 $this->user_creation_id = $obj->fk_user_creat;
1098 $this->user_modification_id = $obj->fk_user_modif;
1099
1100 $this->state_id = $obj->state_id;
1101 $this->state_code = $obj->state_code;
1102 $this->state = $obj->state;
1103
1104 $this->country_id = $obj->country_id;
1105 $this->country_code = $obj->country_id ? $obj->country_code : '';
1106 $this->country = $obj->country_id ? ($langs->trans('Country'.$obj->country_code) != 'Country'.$obj->country_code ? $langs->transnoentities('Country'.$obj->country_code) : $obj->country) : '';
1107
1108 $this->fk_soc = $obj->fk_soc; // Both fk_soc and socid are used
1109 $this->socid = $obj->fk_soc; // Both fk_soc and socid are used
1110 $this->socname = $obj->socname;
1111 $this->poste = $obj->poste;
1112 $this->status = $obj->status;
1113 $this->statut = $obj->status; // deprecated
1114
1115 $this->fk_prospectlevel = $obj->fk_prospectlevel;
1116
1117 $transcode = $langs->trans('StatusProspect'.$obj->fk_stcommcontact);
1118 $libelle = ($transcode != 'StatusProspect'.$obj->fk_stcommcontact ? $transcode : $obj->stcomm);
1119 $this->stcomm_id = $obj->fk_stcommcontact; // id statut commercial
1120 $this->statut_commercial = $libelle; // libelle statut commercial
1121 $this->stcomm_picto = $obj->stcomm_picto; // Picto statut commercial
1122
1123 $this->phone_pro = trim($obj->phone);
1124 $this->fax = trim($obj->fax);
1125 $this->phone_perso = trim($obj->phone_perso);
1126 $this->phone_mobile = trim($obj->phone_mobile);
1127
1128 $this->email = $obj->email;
1129 $this->socialnetworks = ($obj->socialnetworks ? (array) json_decode($obj->socialnetworks, true) : array());
1130 $this->photo = $obj->photo;
1131 $this->priv = $obj->priv;
1132 $this->mail = $obj->email;
1133
1134 $this->birthday = $this->db->jdate($obj->birthday);
1135 $this->note = $obj->note_private; // deprecated
1136 $this->note_private = $obj->note_private;
1137 $this->note_public = $obj->note_public;
1138 $this->default_lang = $obj->default_lang;
1139 $this->user_id = $obj->user_id;
1140 $this->user_login = $obj->user_login;
1141 $this->canvas = $obj->canvas;
1142
1143 $this->import_key = $obj->import_key;
1144
1145 // Define gender according to civility
1146 $this->setGenderFromCivility();
1147
1148 // Search Dolibarr user linked to this contact
1149 $sql = "SELECT u.rowid ";
1150 $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
1151 $sql .= " WHERE u.fk_socpeople = ".((int) $this->id);
1152
1153 $resql = $this->db->query($sql);
1154 if ($resql) {
1155 if ($this->db->num_rows($resql)) {
1156 $uobj = $this->db->fetch_object($resql);
1157
1158 $this->user_id = $uobj->rowid;
1159 }
1160 $this->db->free($resql);
1161 } else {
1162 $this->error = $this->db->error();
1163 return -1;
1164 }
1165
1166 // Retrieve all extrafield
1167 // fetch optionals attributes and labels
1168 $this->fetch_optionals();
1169
1170 // Load also alerts of this user
1171 if ($user) {
1172 $sql = "SELECT fk_user";
1173 $sql .= " FROM ".MAIN_DB_PREFIX."user_alert";
1174 $sql .= " WHERE fk_user = ".((int) $user->id)." AND fk_contact = ".((int) $id);
1175
1176 $resql = $this->db->query($sql);
1177 if ($resql) {
1178 if ($this->db->num_rows($resql)) {
1179 $obj = $this->db->fetch_object($resql);
1180
1181 $this->birthday_alert = 1;
1182 }
1183 $this->db->free($resql);
1184 } else {
1185 $this->error = $this->db->error();
1186 return -1;
1187 }
1188 }
1189
1190 // Load also roles of this address
1191 if ($loadalsoroles) {
1192 $resultRole = $this->fetchRoles();
1193 if ($resultRole < 0) {
1194 return $resultRole;
1195 }
1196 }
1197
1198 return $this->id;
1199 } else {
1200 $langs->load('errors');
1201 $this->error = $langs->trans("ErrorRecordNotFound");
1202 return 0;
1203 }
1204 } else {
1205 $this->error = $this->db->error();
1206 return -1;
1207 }
1208 }
1209
1223 public function findNearest($id = 0, $lastname = '', $firstname = '', $ref_ext = '', $email = '', $ref_alias = '', $socid = 0)
1224 {
1225 // A rowid is known, it is a unique key so we found it
1226 if ($id) {
1227 return $id;
1228 }
1229
1230 // We try to find the contact with exact matching on all fields
1231 // TODO Replace this with step by step search
1232 // Then search on email
1233 // Then search on lastname + firstname
1234 // Then search ref_ext or alias with a OR
1235 $tmpcontact = new Contact($this->db);
1236 $result = $tmpcontact->fetch($id, null, $ref_ext, $email, 0, $socid);
1237
1238 return $result;
1239 }
1240
1241
1242
1249 public function setGenderFromCivility()
1250 {
1251 unset($this->gender);
1252
1253 if (in_array($this->civility_id, array('MR')) || in_array($this->civility_code, array('MR'))) {
1254 $this->gender = 'man';
1255 } elseif (in_array($this->civility_id, array('MME', 'MLE')) || in_array($this->civility_code, array('MME', 'MLE'))) {
1256 $this->gender = 'woman';
1257 }
1258 }
1259
1260 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1270 public function load_ref_elements()
1271 {
1272 // phpcs:enable
1273 // Count the elements for which it is contact
1274 $sql = "SELECT tc.element, count(ec.rowid) as nb";
1275 $sql .= " FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as tc";
1276 $sql .= " WHERE ec.fk_c_type_contact = tc.rowid";
1277 $sql .= " AND fk_socpeople = ".((int) $this->id);
1278 $sql .= " AND tc.source = 'external'";
1279 $sql .= " GROUP BY tc.element";
1280
1281 dol_syslog(get_class($this)."::load_ref_elements", LOG_DEBUG);
1282
1283 $resql = $this->db->query($sql);
1284 if ($resql) {
1285 while ($obj = $this->db->fetch_object($resql)) {
1286 if ($obj->nb) {
1287 if ($obj->element == 'facture') {
1288 $this->ref_facturation = $obj->nb;
1289 } elseif ($obj->element == 'contrat') {
1290 $this->ref_contrat = $obj->nb;
1291 } elseif ($obj->element == 'commande') {
1292 $this->ref_commande = $obj->nb;
1293 } elseif ($obj->element == 'propal') {
1294 $this->ref_propal = $obj->nb;
1295 }
1296 }
1297 }
1298 $this->db->free($resql);
1299 return 0;
1300 } else {
1301 $this->error = $this->db->lasterror();
1302 return -1;
1303 }
1304 }
1305
1313 public function delete($user, $notrigger = 0)
1314 {
1315 global $conf;
1316
1317 $error = 0;
1318
1319 $this->db->begin();
1320
1321 if (!$notrigger) {
1322 // Call trigger
1323 $result = $this->call_trigger('CONTACT_DELETE', $user);
1324 if ($result < 0) {
1325 $error++;
1326 }
1327 // End call triggers
1328 }
1329
1330 if (!$error) {
1331 // Get all rowid of element_contact linked to a type that is link to llx_socpeople
1332 $sql = "SELECT ec.rowid";
1333 $sql .= " FROM ".MAIN_DB_PREFIX."element_contact ec,";
1334 $sql .= " ".MAIN_DB_PREFIX."c_type_contact tc";
1335 $sql .= " WHERE ec.fk_socpeople=".((int) $this->id);
1336 $sql .= " AND ec.fk_c_type_contact=tc.rowid";
1337 $sql .= " AND tc.source='external'";
1338 dol_syslog(__METHOD__, LOG_DEBUG);
1339 $resql = $this->db->query($sql);
1340 if ($resql) {
1341 $num = $this->db->num_rows($resql);
1342
1343 $i = 0;
1344 while ($i < $num && !$error) {
1345 $obj = $this->db->fetch_object($resql);
1346
1347 $sqldel = "DELETE FROM ".MAIN_DB_PREFIX."element_contact";
1348 $sqldel .= " WHERE rowid = ".((int) $obj->rowid);
1349 dol_syslog(__METHOD__, LOG_DEBUG);
1350 $result = $this->db->query($sqldel);
1351 if (!$result) {
1352 $error++;
1353 $this->error = $this->db->error().' sql='.$sqldel;
1354 }
1355
1356 $i++;
1357 }
1358 } else {
1359 $error++;
1360 $this->error = $this->db->error().' sql='.$sql;
1361 }
1362 }
1363
1364 if (!$error) {
1365 // Remove Roles
1366 $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_contacts WHERE fk_socpeople = ".((int) $this->id);
1367 dol_syslog(__METHOD__, LOG_DEBUG);
1368 $resql = $this->db->query($sql);
1369 if (!$resql) {
1370 $error++;
1371 $this->error .= $this->db->lasterror();
1372 $errorflag = -1;
1373 }
1374 }
1375
1376 if (!$error) {
1377 // Remove Notifications
1378 $sql = "DELETE FROM ".MAIN_DB_PREFIX."notify_def WHERE fk_contact = ".((int) $this->id);
1379 dol_syslog(__METHOD__, LOG_DEBUG);
1380 $resql = $this->db->query($sql);
1381 if (!$resql) {
1382 $error++;
1383 $this->error .= $this->db->lasterror();
1384 $errorflag = -1;
1385 }
1386 }
1387
1388 if (!$error) {
1389 // Remove category
1390 $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_contact WHERE fk_socpeople = ".((int) $this->id);
1391 dol_syslog(__METHOD__, LOG_DEBUG);
1392 $resql = $this->db->query($sql);
1393 if (!$resql) {
1394 $error++;
1395 $this->error .= $this->db->lasterror();
1396 $errorflag = -1;
1397 }
1398 }
1399
1400 if (!$error) {
1401 // Remove the birthday alerts set by users on this contact
1402 $sql = "DELETE FROM ".MAIN_DB_PREFIX."user_alert WHERE fk_contact = ".((int) $this->id);
1403 dol_syslog(__METHOD__, LOG_DEBUG);
1404 $resql = $this->db->query($sql);
1405 if (!$resql) {
1406 $error++;
1407 $this->error .= $this->db->lasterror();
1408 }
1409 }
1410
1411 if (!$error) {
1412 // Remove the link of the user created from this contact (the user is kept)
1413 $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_socpeople = NULL WHERE fk_socpeople = ".((int) $this->id);
1414 dol_syslog(__METHOD__, LOG_DEBUG);
1415 $resql = $this->db->query($sql);
1416 if (!$resql) {
1417 $error++;
1418 $this->error .= $this->db->lasterror();
1419 }
1420 }
1421
1422 if (!$error) {
1423 // Remove the links with other objects
1424 $result = $this->deleteObjectLinked();
1425 if ($result < 0) {
1426 $error++;
1427 }
1428 }
1429
1430 // Remove the index of the documents of the contact (the files are removed after the commit)
1431 $dirofdocuments = '';
1432 if ($this->id > 0 && !empty($conf->societe->multidir_output[$this->entity])) {
1433 $dirofdocuments = $conf->societe->multidir_output[$this->entity].'/contact/'.dol_sanitizeFileName((string) $this->id);
1434 }
1435 if (!$error && $dirofdocuments) {
1436 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1437 if (deleteFilesIntoDatabaseIndex($dirofdocuments, '', '') < 0 || !$this->deleteEcmFiles(1)) {
1438 $error++;
1439 $this->error .= $this->db->lasterror();
1440 }
1441 }
1442
1443 if (!$error) {
1444 $sql = "DELETE FROM ".MAIN_DB_PREFIX."socpeople";
1445 $sql .= " WHERE rowid = ".((int) $this->id);
1446 dol_syslog(__METHOD__, LOG_DEBUG);
1447 $result = $this->db->query($sql);
1448 if (!$result) {
1449 $error++;
1450 $this->error = $this->db->error().' sql='.$sql;
1451 }
1452 }
1453
1454 // Remove extrafields
1455 if (!$error) {
1456 // For avoid conflicts if trigger used
1457 $result = $this->deleteExtraFields();
1458 if ($result < 0) {
1459 $error++;
1460 }
1461 }
1462
1463 if (!$error) {
1464 $this->db->commit();
1465
1466 // Delete the directory of the documents of the contact
1467 if ($dirofdocuments) {
1468 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1469 if (dol_is_dir($dirofdocuments)) {
1470 dol_delete_dir_recursive($dirofdocuments);
1471 }
1472 }
1473
1474 return 1;
1475 } else {
1476 $this->db->rollback();
1477 dol_syslog("Error ".$this->error, LOG_ERR);
1478 return -1;
1479 }
1480 }
1481
1482
1489 public function info($id)
1490 {
1491 $sql = "SELECT c.rowid, c.datec as datec, c.fk_user_creat,";
1492 $sql .= " GREATEST(c.tms, COALESCE(cef.tms, c.tms)) as tms, c.fk_user_modif";
1493 $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as c";
1494 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople_extrafields as cef ON cef.fk_object=c.rowid";
1495 $sql .= " WHERE c.rowid = ".((int) $id);
1496
1497 $resql = $this->db->query($sql);
1498 if ($resql) {
1499 if ($this->db->num_rows($resql)) {
1500 $obj = $this->db->fetch_object($resql);
1501
1502 $this->id = $obj->rowid;
1503
1504 $this->user_creation_id = $obj->fk_user_creat;
1505 $this->user_modification_id = $obj->fk_user_modif;
1506 $this->date_creation = $this->db->jdate($obj->datec);
1507 $this->date_modification = $this->db->jdate($obj->tms);
1508 }
1509
1510 $this->db->free($resql);
1511 } else {
1512 print $this->db->error();
1513 }
1514 }
1515
1521 public function getNbOfEMailings()
1522 {
1523 $sql = "SELECT count(mc.email) as nb";
1524 $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc, ".MAIN_DB_PREFIX."mailing as m";
1525 $sql .= " WHERE mc.fk_mailing=m.rowid AND mc.email = '".$this->db->escape($this->email)."' ";
1526 $sql .= " AND m.entity IN (".getEntity($this->element).") AND mc.statut NOT IN (-1,0)"; // -1 error, 0 not sent, 1 sent with success
1527
1528 $resql = $this->db->query($sql);
1529 if ($resql) {
1530 $obj = $this->db->fetch_object($resql);
1531 $nb = (int) $obj->nb;
1532
1533 $this->db->free($resql);
1534 return $nb;
1535 } else {
1536 $this->error = $this->db->error();
1537 return -1;
1538 }
1539 }
1540
1547 public function getTooltipContentArray($params)
1548 {
1549 global $conf, $langs, $user;
1550
1551 $datas = [];
1552
1553 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1554 return ['optimize' => $langs->trans("ShowContact")];
1555 }
1556 if (!empty($this->photo) && class_exists('Form')) {
1557 $photo = '<div class="photointooltip floatright">';
1558 $photo .= Form::showphoto('contact', $this, 0, 40, 0, 'photoref', 'mini', 0); // Important, we must force height so image will have height tags and if image is inside a tooltip, the tooltip manager can calculate height and position correctly the tooltip.
1559 $photo .= '</div>';
1560 $datas['photo'] = $photo;
1561 }
1562
1563 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Contact").'</u> ' . $this->getLibStatut(4);
1564 $datas['name'] = '<br><b>'.$langs->trans("Name").':</b> '.$this->getFullName($langs);
1565 // if ($this->civility_id) $datas['civility'] = '<br><b>' . $langs->trans("Civility") . ':</b> '.$this->civility_id; // TODO Translate civilty_id code
1566 if (!empty($this->poste)) {
1567 $datas['job'] = '<br><b>'.$langs->trans("Poste").':</b> '.$this->poste;
1568 }
1569 $datas['email'] = '<br><b>'.$langs->trans("EMail").':</b> '.$this->email;
1570 $phonelist = array();
1571 $country_code = empty($this->country_code) ? '' : $this->country_code;
1572 if ($this->phone_pro) {
1573 $phonelist[] = dol_print_phone($this->phone_pro, $country_code, $this->id, 0, '', '&nbsp;', 'phone');
1574 }
1575 if ($this->phone_mobile) {
1576 $phonelist[] = dol_print_phone($this->phone_mobile, $country_code, $this->id, 0, '', '&nbsp;', 'mobile');
1577 }
1578 if ($this->phone_perso) {
1579 $phonelist[] = dol_print_phone($this->phone_perso, $country_code, $this->id, 0, '', '&nbsp;', 'phone');
1580 }
1581 $datas['phonelist'] = '<br><b>'.$langs->trans("Phone").':</b> '.implode('&nbsp;', $phonelist);
1582 $datas['address'] = '<br><b>'.$langs->trans("Address").':</b> '.dol_format_address($this, 1, ' ', $langs);
1583
1584 return $datas;
1585 }
1586
1600 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $moreparam = '', $save_lastsearch_value = -1, $maxlen = 0, $morecss = 'valignmiddle')
1601 {
1602 global $conf, $langs, $hookmanager;
1603
1604 if (!empty($conf->dol_no_mouse_hover)) {
1605 $notooltip = 1; // Force disable tooltips
1606 }
1607
1608 $result = '';
1609 $params = [
1610 'id' => $this->id,
1611 'objecttype' => $this->element,
1612 'option' => $option,
1613 ];
1614 $classfortooltip = 'classfortooltip';
1615 $dataparams = '';
1616 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1617 $classfortooltip = 'classforajaxtooltip';
1618 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1619 $label = '';
1620 } else {
1621 $label = implode($this->getTooltipContentArray($params));
1622 }
1623
1624 $baseurl = DOL_URL_ROOT . '/contact/card.php';
1625 $query = ['id' => $this->id];
1626 if ($option !== 'nolink') {
1627 // Add param to save lastsearch_values or not
1628 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1629 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1630 $add_save_lastsearch_values = 1;
1631 }
1632 if ($add_save_lastsearch_values) {
1633 $query = array_merge($query, ['save_lastsearch_values' => 1]);
1634 }
1635 }
1636 $url = dolBuildUrl($baseurl, $query);
1637
1638 $url .= $moreparam;
1639
1640 $linkclose = '';
1641 if (empty($notooltip)) {
1642 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1643 $label = $langs->trans("ShowContact");
1644 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
1645 }
1646 $linkclose .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
1647 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1648 } else {
1649 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1650 }
1651
1652 if ($option == 'nolink') {
1653 $linkstart = '<span';
1654 } else {
1655 $linkstart = '<a href="'.$url.'"';
1656 }
1657 $linkstart .= $linkclose.'>';
1658 if ($option == 'nolink') {
1659 $linkend = '</span>';
1660 } else {
1661 $linkend = '</a>';
1662 }
1663
1664 $result .= $linkstart;
1665
1666 if ($withpicto) {
1667 if ($withpicto < 0) {
1668 $result .= '<!-- picto photo contact --><span class="nopadding userimg'.($morecss ? ' '.$morecss : '').'">'.Form::showphoto('contact', $this, 0, 0, 0, 'userphoto'.($withpicto == -3 ? 'small' : ''), 'mini', 0, 1).'</span>';
1669 if ($withpicto != 2 && $withpicto != -2) {
1670 $result .= ' ';
1671 }
1672 } else {
1673 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="pictofixedwidth valignmiddle"' : '') : 'class="'.(($withpicto != 2) ? 'pictofixedwidth valignmiddle' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1674 }
1675 }
1676 if ($withpicto != 2 && $withpicto != -2) {
1677 $result .= '<span class="valignmiddle">'.($maxlen ? dol_trunc($this->getFullName($langs), $maxlen) : $this->getFullName($langs)).'</span>';
1678 }
1679
1680 $result .= $linkend;
1681
1682 global $action;
1683 $hookmanager->initHooks(array('contactdao'));
1684 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1685 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1686 if ($reshook > 0) {
1687 $result = $hookmanager->resPrint;
1688 } else {
1689 $result .= $hookmanager->resPrint;
1690 }
1691
1692 return $result;
1693 }
1694
1700 public function getCivilityLabel()
1701 {
1702 global $langs;
1703
1704 $code = ($this->civility_code ? $this->civility_code : (!empty($this->civility_id) ? $this->civility : (!empty($this->civilite) ? $this->civilite : '')));
1705 if (empty($code)) {
1706 return '';
1707 }
1708
1709 $langs->load("dict");
1710 return $langs->getLabelFromKey($this->db, "Civility".$code, "c_civility", "code", "label", $code);
1711 }
1712
1719 public function getLibStatut($mode)
1720 {
1721 return $this->LibStatut($this->status, $mode);
1722 }
1723
1724 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1732 public function LibStatut($status, $mode)
1733 {
1734 // phpcs:enable
1735 global $langs;
1736
1737 $labelStatus = array(
1738 0 => 'ActivityCeased',
1739 1 => 'InActivity',
1740 4 => 'InActivity',
1741 5 => 'ActivityCeased',
1742 );
1743 $labelStatusShort = array(
1744 0 => 'ActivityCeased',
1745 1 => 'InActivity',
1746 4 => 'InActivity',
1747 5 => 'ActivityCeased',
1748 );
1749
1750 $statusType = 'status4';
1751 if ($status == 0 || $status == 5) {
1752 $statusType = 'status5';
1753 }
1754
1755 $label = $langs->transnoentitiesnoconv($labelStatus[$status]);
1756 $labelshort = $langs->transnoentitiesnoconv($labelStatusShort[$status]);
1757
1758 return dolGetStatus($label, $labelshort, '', $statusType, $mode);
1759 }
1760
1761
1762 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1769 public function LibPubPriv($status)
1770 {
1771 // phpcs:enable
1772 global $langs;
1773 if ($status == '1') {
1774 return $langs->trans('ContactPrivate');
1775 } else {
1776 return $langs->trans('ContactPublic');
1777 }
1778 }
1779
1780
1788 public function initAsSpecimen()
1789 {
1790 // Get first id of existing company and save it into $socid
1791 $socid = 0;
1792 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe ORDER BY rowid LIMIT 1";
1793 $resql = $this->db->query($sql);
1794 if ($resql) {
1795 $obj = $this->db->fetch_object($resql);
1796 if ($obj) {
1797 $socid = $obj->rowid;
1798 }
1799 }
1800
1801 // Initialise parameters
1802 $this->id = 0;
1803 $this->entity = 1;
1804 $this->specimen = 1;
1805 $this->lastname = 'DOLIBARR';
1806 $this->firstname = 'SPECIMEN';
1807 $this->address = '21 jump street';
1808 $this->zip = '99999';
1809 $this->town = 'MyTown';
1810 $this->country_id = 1;
1811 $this->country_code = 'FR';
1812 $this->country = 'France';
1813 $this->email = 'specimen@specimen.com';
1814 $this->socialnetworks = array(
1815 'skype' => 'tom.hanson',
1816 'twitter' => 'tomhanson',
1817 'linkedin' => 'tomhanson',
1818 );
1819 $this->phone_pro = '0909090901';
1820 $this->phone_perso = '0909090902';
1821 $this->phone_mobile = '0909090903';
1822 $this->fax = '0909090909';
1823
1824 $this->note_public = 'This is a comment (public)';
1825 $this->note_private = 'This is a comment (private)';
1826
1827 $this->socid = $socid;
1828 $this->status = 1;
1829
1830 return 1;
1831 }
1832
1839 public function setstatus($status)
1840 {
1841 global $conf, $langs, $user;
1842
1843 $error = 0;
1844
1845 // Check parameters
1846 if (!empty($this->statut) && empty($this->status)) {
1847 $this->status = 1;
1848 }
1849 if ($this->status == $status) {
1850 return 0;
1851 } else {
1852 $this->status = $status;
1853 $this->statut = $status;
1854 }
1855
1856 $this->db->begin();
1857
1858 // User disable
1859 $sql = "UPDATE ".MAIN_DB_PREFIX."socpeople";
1860 $sql .= " SET statut = ".((int) $this->status);
1861 $sql .= ", fk_user_modif = ".((int) $user->id);
1862 $sql .= " WHERE rowid = ".((int) $this->id);
1863 $result = $this->db->query($sql);
1864
1865 dol_syslog(get_class($this)."::setstatus", LOG_DEBUG);
1866 if ($result) {
1867 // Call trigger
1868 $result = $this->call_trigger('CONTACT_ENABLEDISABLE', $user);
1869 if ($result < 0) {
1870 $error++;
1871 }
1872 // End call triggers
1873 }
1874
1875 if ($error) {
1876 $this->db->rollback();
1877 return -$error;
1878 } else {
1879 $this->db->commit();
1880 return 1;
1881 }
1882 }
1883
1895 public function setCategories($categories, $remove_existing = true)
1896 {
1897 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1898 return parent::setCategoriesCommon($categories, Categorie::TYPE_CONTACT, $remove_existing);
1899 }
1900
1909 public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
1910 {
1911 $tables = array(
1912 'socpeople', 'societe_contacts'
1913 );
1914
1915 return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
1916 }
1917
1925 public function fetchRoles()
1926 {
1927 global $langs;
1928 $error = 0;
1929 $num = 0;
1930
1931 $sql = "SELECT tc.rowid, tc.element, tc.source, tc.code, tc.libelle as label, sc.rowid as contactroleid, sc.fk_soc as socid";
1932 $sql .= " FROM ".MAIN_DB_PREFIX."societe_contacts as sc, ".MAIN_DB_PREFIX."c_type_contact as tc";
1933 $sql .= " WHERE tc.rowid = sc.fk_c_type_contact";
1934 $sql .= " AND tc.source = 'external' AND tc.active=1";
1935 $sql .= " AND sc.fk_socpeople = ".((int) $this->id);
1936 $sql .= " AND sc.entity IN (".getEntity('societe').')';
1937
1938 $resql = $this->db->query($sql);
1939 if ($resql) {
1940 $this->roles = array();
1941
1942 $num = $this->db->num_rows($resql);
1943 if ($num > 0) {
1944 while ($obj = $this->db->fetch_object($resql)) {
1945 $transkey = "TypeContact_".$obj->element."_".$obj->source."_".$obj->code;
1946 $libelle_element = $langs->trans('ContactDefault_'.$obj->element);
1947 $this->roles[$obj->contactroleid] = array('id' => $obj->rowid, 'socid' => $obj->socid, 'element' => $obj->element, 'source' => $obj->source, 'code' => $obj->code, 'label' => $libelle_element.' - '.($langs->trans($transkey) != $transkey ? $langs->trans($transkey) : $obj->label));
1948 }
1949 }
1950 } else {
1951 $error++;
1952 $this->error = $this->db->lasterror();
1953 $this->errors[] = $this->db->lasterror();
1954 }
1955
1956 if (empty($error)) {
1957 return $num;
1958 } else {
1959 return $error * -1;
1960 }
1961 }
1962
1970 public function getContactRoles($element = '')
1971 {
1972 $tab = array();
1973
1974 if ($element == 'action') {
1975 $element = 'agenda';
1976 }
1977
1978 $sql = "SELECT sc.fk_socpeople as id, sc.fk_c_type_contact";
1979 $sql .= " FROM ".MAIN_DB_PREFIX."c_type_contact tc";
1980 $sql .= ", ".MAIN_DB_PREFIX."societe_contacts sc";
1981 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."socpeople sp";
1982 $sql .= " ON sc.fk_socpeople = sp.rowid AND sp.statut = 1";
1983 $sql .= " WHERE sc.fk_soc = ".((int) $this->socid);
1984 $sql .= " AND sc.fk_c_type_contact=tc.rowid";
1985 $sql .= " AND tc.element = '".$this->db->escape($element)."'";
1986 $sql .= " AND sp.entity IN (".getEntity('contact').")";
1987 $sql .= " AND tc.active = 1";
1988
1989 $resql = $this->db->query($sql);
1990 if ($resql) {
1991 $num = $this->db->num_rows($resql);
1992 $i = 0;
1993 while ($i < $num) {
1994 $obj = $this->db->fetch_object($resql);
1995 $tab[$obj->id] = array('fk_socpeople' => $obj->id, 'type_contact' => $obj->fk_c_type_contact);
1996
1997 $i++;
1998 }
1999
2000 return $tab;
2001 } else {
2002 $this->error = $this->db->error();
2003 dol_print_error($this->db);
2004 return -1;
2005 }
2006 }
2007
2015 public function updateRoles()
2016 {
2017 global $conf;
2018
2019 $error = 0;
2020
2021 if (!isset($this->roles)) {
2022 return 0; // Avoid to loose roles when property not set
2023 }
2024
2025 $this->db->begin();
2026
2027 $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_contacts WHERE fk_socpeople=".((int) $this->id)." AND entity IN (".getEntity("contact").")";
2028
2029 $result = $this->db->query($sql);
2030 if (!$result) {
2031 $this->errors[] = $this->db->lasterror().' sql='.$sql;
2032 $error++;
2033 } else {
2034 if (count($this->roles) > 0) {
2035 foreach ($this->roles as $keyRoles => $valRoles) {
2036 if (empty($valRoles)) {
2037 continue;
2038 }
2039 $idrole = 0;
2040 if (is_array($valRoles)) {
2041 $idrole = $valRoles['id'];
2042 } else {
2043 $idrole = $valRoles;
2044 }
2045
2046 $socid = 0;
2047 if (is_array($valRoles)) {
2048 $socid = $valRoles['socid'];
2049 } else {
2050 $socid = $this->socid;
2051 }
2052
2053 if ($socid > 0) {
2054 $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_contacts";
2055 $sql .= " (entity,";
2056 $sql .= "date_creation,";
2057 $sql .= "fk_soc,";
2058 $sql .= "fk_c_type_contact,";
2059 $sql .= "fk_socpeople) ";
2060 $sql .= " VALUES (".$conf->entity.",";
2061 $sql .= "'".$this->db->idate(dol_now())."',";
2062 $sql .= $socid.", ";
2063 $sql .= $idrole." , ";
2064 $sql .= $this->id;
2065 $sql .= ")";
2066
2067 $result = $this->db->query($sql);
2068 if (!$result) {
2069 $this->errors[] = $this->db->lasterror().' sql='.$sql;
2070 $error++;
2071 }
2072 }
2073 }
2074 }
2075 }
2076 if (empty($error)) {
2077 $this->db->commit();
2078 return 1;
2079 } else {
2080 $this->error = implode(' ', $this->errors);
2081 $this->db->rollback();
2082 return $error * -1;
2083 }
2084 }
2085
2092 public function loadCacheOfProspStatus($active = 1)
2093 {
2094 global $langs;
2095
2096 $sql = "SELECT id, code, libelle as label, picto FROM ".MAIN_DB_PREFIX."c_stcommcontact";
2097 if ($active >= 0) {
2098 $sql .= " WHERE active = ".((int) $active);
2099 }
2100 $resql = $this->db->query($sql);
2101 $num = $this->db->num_rows($resql);
2102 $i = 0;
2103 while ($i < $num) {
2104 $obj = $this->db->fetch_object($resql);
2105 $this->cacheprospectstatus[$obj->id] = array('id' => $obj->id, 'code' => $obj->code, 'label' => ($langs->trans("ST_".strtoupper($obj->code)) == "ST_".strtoupper($obj->code)) ? $obj->label : $langs->trans("ST_".strtoupper($obj->code)), 'picto' => $obj->picto);
2106 $i++;
2107 }
2108 return 1;
2109 }
2110
2116 public function getLibProspLevel()
2117 {
2118 return $this->libProspLevel($this->fk_prospectlevel);
2119 }
2120
2127 public function libProspLevel($fk_prospectlevel)
2128 {
2129 global $langs;
2130
2131 $lib = $langs->trans("ProspectLevel".$fk_prospectlevel);
2132 // If lib not found in language file, we get label from cache/database
2133 if ($lib == "ProspectLevel".$fk_prospectlevel) {
2134 $lib = $langs->getLabelFromKey($this->db, $fk_prospectlevel, 'c_prospectlevel', 'code', 'label');
2135 }
2136 return $lib;
2137 }
2138
2139
2147 public function setProspectLevel(User $user)
2148 {
2149 return $this->update($this->id, $user);
2150 }
2151
2159 public function getLibProspCommStatut($mode = 0, $label = '')
2160 {
2161 return $this->libProspCommStatut($this->stcomm_id, $mode, $label, $this->stcomm_picto);
2162 }
2163
2177 public function libProspCommStatut($statut, $mode = 0, $label = '', $picto = '')
2178 {
2179 global $langs;
2180 $langs->load('customers');
2181
2182 if ($mode == 2) {
2183 if ($statut == '-1' || $statut == 'ST_NO') {
2184 return img_action($langs->trans("StatusProspect-1"), '-1', $picto).' '.$langs->trans("StatusProspect-1");
2185 } elseif ($statut == '0' || $statut == 'ST_NEVER') {
2186 return img_action($langs->trans("StatusProspect0"), '0', $picto).' '.$langs->trans("StatusProspect0");
2187 } elseif ($statut == '1' || $statut == 'ST_TODO') {
2188 return img_action($langs->trans("StatusProspect1"), '1', $picto).' '.$langs->trans("StatusProspect1");
2189 } elseif ($statut == '2' || $statut == 'ST_PEND') {
2190 return img_action($langs->trans("StatusProspect2"), '2', $picto).' '.$langs->trans("StatusProspect2");
2191 } elseif ($statut == '3' || $statut == 'ST_DONE') {
2192 return img_action($langs->trans("StatusProspect3"), '3', $picto).' '.$langs->trans("StatusProspect3");
2193 } else {
2194 return img_action(($langs->trans("StatusProspect".$statut) != "StatusProspect".$statut) ? $langs->trans("StatusProspect".$statut) : $label, '0', $picto).' '.(($langs->trans("StatusProspect".$statut) != "StatusProspect".$statut) ? $langs->trans("StatusProspect".$statut) : $label);
2195 }
2196 }
2197 if ($mode == 3) {
2198 if ($statut == '-1' || $statut == 'ST_NO') {
2199 return img_action($langs->trans("StatusProspect-1"), '-1', $picto);
2200 } elseif ($statut == '0' || $statut == 'ST_NEVER') {
2201 return img_action($langs->trans("StatusProspect0"), '0', $picto);
2202 } elseif ($statut == '1' || $statut == 'ST_TODO') {
2203 return img_action($langs->trans("StatusProspect1"), '1', $picto);
2204 } elseif ($statut == '2' || $statut == 'ST_PEND') {
2205 return img_action($langs->trans("StatusProspect2"), '2', $picto);
2206 } elseif ($statut == '3' || $statut == 'ST_DONE') {
2207 return img_action($langs->trans("StatusProspect3"), '3', $picto);
2208 } else {
2209 return img_action(($langs->trans("StatusProspect".$statut) != "StatusProspect".$statut) ? $langs->trans("StatusProspect".$statut) : $label, '0', $picto);
2210 }
2211 }
2212 if ($mode == 4) {
2213 if ($statut == '-1' || $statut == 'ST_NO') {
2214 return img_action($langs->trans("StatusProspect-1"), '-1', $picto).' '.$langs->trans("StatusProspect-1");
2215 } elseif ($statut == '0' || $statut == 'ST_NEVER') {
2216 return img_action($langs->trans("StatusProspect0"), '0', $picto).' '.$langs->trans("StatusProspect0");
2217 } elseif ($statut == '1' || $statut == 'ST_TODO') {
2218 return img_action($langs->trans("StatusProspect1"), '1', $picto).' '.$langs->trans("StatusProspect1");
2219 } elseif ($statut == '2' || $statut == 'ST_PEND') {
2220 return img_action($langs->trans("StatusProspect2"), '2', $picto).' '.$langs->trans("StatusProspect2");
2221 } elseif ($statut == '3' || $statut == 'ST_DONE') {
2222 return img_action($langs->trans("StatusProspect3"), '3', $picto).' '.$langs->trans("StatusProspect3");
2223 } else {
2224 return img_action(($langs->trans("StatusProspect".$statut) != "StatusProspect".$statut) ? $langs->trans("StatusProspect".$statut) : $label, '0', $picto).' '.(($langs->trans("StatusProspect".$statut) != "StatusProspect".$statut) ? $langs->trans("StatusProspect".$statut) : $label);
2225 }
2226 }
2227
2228 return "Error, mode/status not found";
2229 }
2230
2231
2238 public function setNoEmail($no_email)
2239 {
2240 $error = 0;
2241
2242 // Update mass emailing flag into table mailing_unsubscribe
2243 if ($this->email) {
2244 $this->db->begin();
2245
2246 if ($no_email) {
2247 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE entity IN (".getEntity('mailing', 0).") AND email = '".$this->db->escape($this->email)."'";
2248 $resql = $this->db->query($sql);
2249 if ($resql) {
2250 $obj = $this->db->fetch_object($resql);
2251 $noemail = $obj->nb;
2252 if (empty($noemail)) {
2253 $sql = "INSERT INTO ".MAIN_DB_PREFIX."mailing_unsubscribe(email, entity, date_creat) VALUES ('".$this->db->escape($this->email)."', ".getEntity('mailing', 0).", '".$this->db->idate(dol_now())."')";
2254 $resql = $this->db->query($sql);
2255 if (!$resql) {
2256 $error++;
2257 $this->error = $this->db->lasterror();
2258 $this->errors[] = $this->error;
2259 }
2260 }
2261 } else {
2262 $error++;
2263 $this->error = $this->db->lasterror();
2264 $this->errors[] = $this->error;
2265 }
2266 } else {
2267 $sql = "DELETE FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE email = '".$this->db->escape($this->email)."' AND entity IN (".getEntity('mailing', 0).")";
2268 $resql = $this->db->query($sql);
2269 if (!$resql) {
2270 $error++;
2271 $this->error = $this->db->lasterror();
2272 $this->errors[] = $this->error;
2273 }
2274 }
2275
2276 if (empty($error)) {
2277 $this->no_email = $no_email;
2278 $this->db->commit();
2279 return 1;
2280 } else {
2281 $this->db->rollback();
2282 return $error * -1;
2283 }
2284 }
2285
2286 return 0;
2287 }
2288
2295 public function getNoEmail()
2296 {
2297 if ($this->email) {
2298 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE entity IN (".getEntity('mailing').") AND email = '".$this->db->escape($this->email)."'";
2299 $resql = $this->db->query($sql);
2300 if ($resql) {
2301 $obj = $this->db->fetch_object($resql);
2302 $this->no_email = $obj->nb;
2303 return 1;
2304 } else {
2305 $this->error = $this->db->lasterror();
2306 $this->errors[] = $this->error;
2307 return -1;
2308 }
2309 }
2310 return 0;
2311 }
2312
2313
2321 public function getKanbanView($option = '', $arraydata = null)
2322 {
2323 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
2324
2325 $return = '<div class="box-flex-item box-flex-grow-zero">';
2326 $return .= '<div class="info-box info-box-sm">';
2327 $return .= '<span class="info-box-icon bg-infobox-action">';
2328 if (!is_null($this->photo)) {
2329 $return .= Form::showphoto('contact', $this, 0, 60, 0, 'photokanban photoref photowithmargin photologintooltip', 'small', 0, 1);
2330 } else {
2331 $return .= img_picto('', $this->picto);
2332 }
2333 $return .= '</span>';
2334 $return .= '<div class="info-box-content">';
2335 $return .= '<div class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . $this->getNomUrl(0) . '</div>';
2336 if ($selected >= 0) {
2337 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
2338 }
2339 if (is_object($this->thirdparty)) {
2340 $return .= '<div class="info-box-ref tdoverflowmax150">'.$this->thirdparty->getNomUrl(1).'</div>';
2341 }
2342 /*if (property_exists($this, 'phone_pro') && !empty($this->phone_pro)) {
2343 $return .= '<br>'.img_picto($langs->trans("Phone"), 'phone');
2344 $return .= ' <span class="info-box-label">'.$this->phone_pro.'</span>';
2345 }*/
2346 /*if (method_exists($this, 'LibPubPriv')) {
2347 $return .= '<br><span class="info-box-label opacitymedium">'.$langs->trans("Visibility").'</span>';
2348 $return .= '<span> : '.$this->LibPubPriv($this->priv).'</span>';
2349 }*/
2350 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
2351 $return .= '</div>';
2352 $return .= '</div>';
2353 $return .= '</div>';
2354 return $return;
2355 }
2356}
$object ref
Definition info.php:90
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
deleteEcmFiles($mode=0)
Delete related files of object in database.
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid=0, $f_user=null, $notrigger=0)
Delete all links between an object $this.
deleteExtraFields()
Delete all extra fields values for the current object.
static commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
Class to manage contact/addresses.
static replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
__construct($db)
Constructor.
update_perso($id, $user=null, $notrigger=0)
Update field alert birthday.
getLibProspCommStatut($mode=0, $label='')
Return status of prospect.
$fields
'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter...
create($user, $notrigger=0)
Add a contact into database.
loadStateBoard()
Load indicators into this->nb for board.
getNoEmail()
get "blacklist" mailing status set no_email attribute to 1 or 0
getNomUrl($withpicto=0, $option='', $notooltip=0, $moreparam='', $save_lastsearch_value=-1, $maxlen=0, $morecss='valignmiddle')
Return name of contact with link (and eventually picto) Use $this->id, $this->lastname,...
getNbOfEMailings()
Return number of mass Emailing received by these contacts with its email.
libProspCommStatut($statut, $mode=0, $label='', $picto='')
Return label of a given status.
getTooltipContentArray($params)
getTooltipContentArray
libProspLevel($fk_prospectlevel)
Return label of prospect level.
getCivilityLabel()
Return civility label of contact.
setProspectLevel(User $user)
Set prospect level.
fetch($id, $user=null, $ref_ext='', $email='', $loadalsoroles=0, $socid=0)
Load object contact.
getKanbanView($option='', $arraydata=null)
Return clickable link of object (with eventually picto)
load_ref_elements()
Load number of elements the contact is used as a link for ref_facturation ref_contrat ref_commande (f...
getLibProspLevel()
Return prospect level.
fetchRoles()
Fetch roles (default contact of some companies) for the current contact.
setCategories($categories, $remove_existing=true)
Sets object to supplied categories.
getContactRoles($element='')
Get thirdparty contact roles of a given contact.
_load_ldap_dn($info, $mode=0)
Return DN string complete in the LDAP directory for the object.
LibStatut($status, $mode)
Return the label of a given status.
setGenderFromCivility()
Set the property "gender" of this class, based on the property "civility_id" or use property "civilit...
update($id, $user=null, $notrigger=0, $action='update', $nosyncuser=0)
Update information into database.
setstatus($status)
Change status of a user.
loadCacheOfProspStatus($active=1)
Load array of prospect status.
_load_ldap_info()
Initialize info table (LDAP attributes table)
updateRoles()
Updates all roles (default contact for companies) according to values inside the ->roles array.
info($id)
Load contact information from the database.
initAsSpecimen()
Initialise an instance with random values.
getLibStatut($mode)
Return the label of the status.
setNoEmail($no_email)
Set "blacklist" mailing status.
LibPubPriv($status)
Return translated label of Public or Private.
findNearest($id=0, $lastname='', $firstname='', $ref_ext='', $email='', $ref_alias='', $socid=0)
Search the contact that match the most the provided parameters.
Class to manage Dolibarr database access.
static showphoto($modulepart, $object, $width=100, $height=0, $caneditfield=0, $cssclass='photowithmargin', $imagesize='', $addlinktofullsize=1, $cache=0, $forcecapture='', $noexternsourceoverwrite=0, $usesharelinkifavailable=0)
Return HTML code to output a photo.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:171
getFullName($langs, $option=0, $nameorder=-1, $maxlen=0)
Return full name (civility+' '+name+' '+lastname)
setUpperOrLowerCase()
Set to upper or ucwords/lower if needed.
trait CommonSocialNetworks
Superclass for social networks.
getCountry($searchkey, $withcode='', $dbtouse=null, $outputlangs=null, $entconv=1, $searchlabel='')
Return country label, code or id from an id, code or label.
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as p label as s rowid as s nom as s email
Sender: Who sends the email ("Sender" has sent emails on behalf of "From").
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0, $level=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_is_dir($folder)
Test if filename is a directory.
deleteFilesIntoDatabaseIndex($dir, $file, $mode='uploaded', $object=null)
Delete files into database index using search criteria.
dol_now($mode='gmt')
Return date for now.
setEntity($currentobject)
Set entity id to use when to create an object.
dol_print_phone($phone, $countrycode='', $contactid=0, $socid=0, $addlink='', $separ="&nbsp;", $withpicto='', $titlealt='', $adddivfloat=0, $morecss='paddingright')
Format phone numbers according to country.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
dol_format_address($object, $withcountry=0, $sep="\n", $outputlangs=null, $mode=0, $extralangcode='')
Return a formatted address (part address/zip/town/state) according to country rules.
dolBuildUrl($url, $params=[], $addtoken=false)
Return path of url.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
img_action($titlealt, $numaction, $picto='', $moreatt='')
Show logo action.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
div refaddress div address
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:135