Issues (2811)

public/htdocs/projet/contact.php (1 issue)

Labels
Severity
1
<?php
2
3
/* Copyright (C) 2010       Regis Houssin               <[email protected]>
4
 * Copyright (C) 2012-2015  Laurent Destailleur         <[email protected]>
5
 * Copyright (C) 2024		MDW							<[email protected]>
6
 * Copyright (C) 2024       Frédéric France             <[email protected]>
7
 * Copyright (C) 2024       Rafael San José             <[email protected]>
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21
 */
22
23
use Dolibarr\Code\Core\Classes\Form;
24
use Dolibarr\Code\Core\Classes\FormCompany;
25
use Dolibarr\Code\Projet\Classes\Project;
26
use Dolibarr\Code\Projet\Classes\Task;
27
use Dolibarr\Code\User\Classes\User;
28
use Dolibarr\Code\User\Classes\UserGroup;
29
use Dolibarr\Lib\ViewMain;
30
31
/**
32
 *       \file       htdocs/projet/contact.php
33
 *       \ingroup    project
34
 *       \brief      List of all contacts of a project
35
 */
36
37
use Dolibarr\Code\Categories\Classes\Categorie;
38
use Dolibarr\Code\Contact\Classes\Contact;
39
40
// Load Dolibarr environment
41
require constant('DOL_DOCUMENT_ROOT') . '/main.inc.php';
42
43
// Load translation files required by the page
44
$langsLoad = array('projects', 'companies');
45
if (isModEnabled('eventorganization')) {
46
    $langsLoad[] = 'eventorganization';
47
}
48
49
$langs->loadLangs($langsLoad);
50
51
$id = GETPOSTINT('id');
52
$ref = GETPOST('ref', 'alpha');
53
$lineid = GETPOSTINT('lineid');
54
$socid = GETPOSTINT('socid');
55
$action = GETPOST('action', 'aZ09');
56
57
$mine = GETPOST('mode') == 'mine' ? 1 : 0;
58
//if (! $user->rights->projet->all->lire) $mine=1;  // Special for projects
59
60
$object = new Project($db);
61
62
include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be include, not include_once
63
if (getDolGlobalString('PROJECT_ALLOW_COMMENT_ON_PROJECT') && method_exists($object, 'fetchComments') && empty($object->comments)) {
64
    $object->fetchComments();
65
}
66
67
// Security check
68
$socid = 0;
69
//if ($user->socid > 0) $socid = $user->socid;    // For external user, no check is done on company because readability is managed by public status of project and assignment.
70
$result = restrictedArea($user, 'projet', $id, 'projet&project');
71
72
$hookmanager->initHooks(array('projectcontactcard', 'globalcard'));
73
74
75
/*
76
 * Actions
77
 */
78
79
$parameters = array('id' => $id);
80
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action);
81
if ($reshook < 0) {
82
    setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
83
}
84
85
if (empty($reshook)) {
86
    // Test if we can add contact to the tasks at the same times, if not or not required, make a redirect
87
    $formconfirmtoaddtasks = '';
88
    if ($action == 'addcontact') {
89
        $form = new Form($db);
90
91
        $source = GETPOST("source", 'aZ09');
92
93
        $taskstatic = new Task($db);
94
        $task_array = $taskstatic->getTasksArray(0, 0, $object->id, 0, 0);
95
        $nbTasks = count($task_array);
96
97
        //If no task available, redirec to to add confirm
98
        $type_to = (GETPOST('typecontact') ? 'typecontact=' . GETPOST('typecontact') : 'type=' . GETPOST('type'));
99
        $personToAffect = (GETPOST('userid') ? GETPOSTINT('userid') : GETPOSTINT('contactid'));
100
        $affect_to = (GETPOST('userid') ? 'userid=' . $personToAffect : 'contactid=' . $personToAffect);
101
        $url_redirect = '?id=' . $object->id . '&' . $affect_to . '&' . $type_to . '&source=' . $source;
102
103
        if ($personToAffect > 0 && (!getDolGlobalString('PROJECT_HIDE_TASKS') || $nbTasks > 0)) {
104
            $text = $langs->trans('AddPersonToTask');
105
            $textbody = $text . ' (<a href="#" class="selectall">' . $langs->trans("SelectAll") . '</a>)';
106
            $formquestion = array('text' => $textbody);
107
108
            $task_to_affect = array();
109
            foreach ($task_array as $task) {
110
                $task_already_affected = false;
111
                $personsLinked = $task->liste_contact(-1, $source);
112
                if (!is_array($personsLinked) && count($personsLinked) < 0) {
113
                    setEventMessage($object->error, 'errors');
114
                } else {
115
                    foreach ($personsLinked as $person) {
116
                        if ($person['id'] == $personToAffect) {
117
                            $task_already_affected = true;
118
                            break;
119
                        }
120
                    }
121
                    if (!$task_already_affected) {
122
                        $task_to_affect[$task->id] = $task->id;
123
                    }
124
                }
125
            }
126
127
            if (empty($task_to_affect)) {
128
                $action = 'addcontact_confirm';
129
            } else {
130
                $formcompany = new FormCompany($db);
131
                foreach ($task_array as $task) {
132
                    $key = $task->id;
133
                    $val = $task->ref . ' ' . dol_trunc($task->label);
134
                    $formquestion[] = array(
135
                        'type' => 'other',
136
                        'name' => 'person_' . $key . ',person_role_' . $key,
137
                        'label' => '<input type="checkbox" class="flat' . (in_array($key, $task_to_affect) ? ' taskcheckboxes"' : '" checked disabled') . ' id="person_' . $key . '" name="person_' . $key . '" value="1"> <label for="person_' . $key . '">' . $val . '<label>',
138
                        'value' => $formcompany->selectTypeContact($taskstatic, '', 'person_role_' . $key, $source, 'position', 0, 'minwidth100imp', 0, 1)
139
                    );
140
                }
141
                $formquestion[] = array('type' => 'other', 'name' => 'tasksavailable', 'label' => '', 'value' => '<input type="hidden" id="tasksavailable" name="tasksavailable" value="' . implode(',', array_keys($task_to_affect)) . '">');
142
            }
143
144
            $formconfirmtoaddtasks = $form->formconfirm($_SERVER['PHP_SELF'] . $url_redirect, $text, '', 'addcontact_confirm', $formquestion, '', 1, 300, 590);
145
            $formconfirmtoaddtasks .= '
146
			 <script>
147
			 $(document).ready(function() {
148
				var saveprop = false;
149
			 	$(".selectall").click(function(){
150
					console.log("We click on select all with "+saveprop);
151
					if (!saveprop) {
152
						$(".taskcheckboxes").prop("checked", true);
153
						saveprop = true;
154
					} else {
155
						$(".taskcheckboxes").prop("checked", false);
156
						saveprop = false;
157
					}
158
				});
159
			 });
160
			 </script>';
161
        } else {
162
            $action = 'addcontact_confirm';
163
        }
164
    }
165
166
    // Add new contact
167
    if ($action == 'addcontact_confirm' && $user->hasRight('projet', 'creer')) {
168
        if (GETPOST('confirm', 'alpha') == 'no') {
169
            header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
170
            exit;
171
        }
172
173
        $contactid = (GETPOST('userid') ? GETPOSTINT('userid') : GETPOSTINT('contactid'));
174
        $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
175
        $groupid = GETPOSTINT('groupid');
176
        $contactarray = array();
177
        $errorgroup = 0;
178
        $errorgrouparray = array();
179
180
        if ($groupid > 0) {
181
            $usergroup = new UserGroup($db);
182
            $result = $usergroup->fetch($groupid);
183
            if ($result > 0) {
184
                $tmpcontactarray = $usergroup->listUsersForGroup();
185
                if ($contactarray <= 0) {
186
                    $error++;
187
                } else {
188
                    foreach ($tmpcontactarray as $tmpuser) {
189
                        $contactarray[] = $tmpuser->id;
190
                    }
191
                }
192
            } else {
193
                $error++;
194
            }
195
        } elseif (!($contactid > 0)) {
196
            $error++;
197
            $langs->load("errors");
198
            setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Contact")), null, 'errors');
199
        } else {
200
            $contactarray[] = $contactid;
201
        }
202
203
        $result = 0;
204
        $result = $object->fetch($id);
205
        if (!$error && $result > 0 && $id > 0) {
206
            foreach ($contactarray as $key => $contactid) {
207
                $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09'));
208
209
                if ($result == 0) {
210
                    if ($groupid > 0) {
211
                        $errorgroup++;
212
                        $errorgrouparray[] = $contactid;
213
                    } else {
214
                        $langs->load("errors");
215
                        setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
216
                    }
217
                } elseif ($result < 0) {
218
                    if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
219
                        if ($groupid > 0) {
220
                            $errorgroup++;
221
                            $errorgrouparray[] = $contactid;
222
                        } else {
223
                            $langs->load("errors");
224
                            setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
225
                        }
226
                    } else {
227
                        setEventMessages($object->error, $object->errors, 'errors');
228
                    }
229
                }
230
231
                $affecttotask = GETPOST('tasksavailable', 'intcomma');
232
                if (!empty($affecttotask)) {
233
                    $task_to_affect = explode(',', $affecttotask);
234
                    if (!empty($task_to_affect)) {
235
                        foreach ($task_to_affect as $task_id) {
236
                            if (GETPOSTISSET('person_' . $task_id) && GETPOST('person_' . $task_id, 'san_alpha')) {
237
                                $tasksToAffect = new Task($db);
238
                                $result = $tasksToAffect->fetch($task_id);
239
                                if ($result < 0) {
240
                                    setEventMessages($tasksToAffect->error, null, 'errors');
241
                                } else {
242
                                    $result = $tasksToAffect->add_contact($contactid, GETPOST('person_role_' . $task_id), GETPOST("source", 'aZ09'));
243
                                    if ($result < 0) {
244
                                        if ($tasksToAffect->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
245
                                            $langs->load("errors");
246
                                            setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
247
                                        } else {
248
                                            setEventMessages($tasksToAffect->error, $tasksToAffect->errors, 'errors');
249
                                        }
250
                                    }
251
                                }
252
                            }
253
                        }
254
                    }
255
                }
256
            }
257
        }
258
        if ($errorgroup > 0) {
259
            $langs->load("errors");
260
            if ($errorgroup == count($contactarray)) {
261
                setEventMessages($langs->trans("ErrorThisGroupIsAlreadyDefinedAsThisType"), null, 'errors');
262
            } else {
263
                $tmpuser = new User($db);
264
                foreach ($errorgrouparray as $key => $value) {
265
                    $tmpuser->fetch($value);
266
                    setEventMessages($langs->trans("ErrorThisContactXIsAlreadyDefinedAsThisType", dolGetFirstLastname($tmpuser->firstname, $tmpuser->lastname)), null, 'errors');
267
                }
268
            }
269
        }
270
271
        if ($result >= 0) {
272
            header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
273
            exit;
274
        }
275
    }
276
277
    // Change contact's status
278
    if ($action == 'swapstatut' && $user->hasRight('projet', 'creer')) {
279
        if ($object->fetch($id)) {
280
            $result = $object->swapContactStatus(GETPOSTINT('ligne'));
281
        } else {
282
            dol_print_error($db);
283
        }
284
    }
285
286
    // Delete a contact
287
    if (($action == 'deleteline' || $action == 'deletecontact') && $user->hasRight('projet', 'creer')) {
288
        $object->fetch($id);
289
        $result = $object->delete_contact(GETPOSTINT("lineid"));
290
291
        if ($result >= 0) {
292
            header("Location: contact.php?id=" . $object->id);
293
            exit;
294
        } else {
295
            dol_print_error($db);
296
        }
297
    }
298
}
299
300
301
/*
302
 * View
303
 */
304
305
$form = new Form($db);
306
$contactstatic = new Contact($db);
307
$userstatic = new User($db);
308
309
$title = $langs->trans('ProjectContact') . ' - ' . $object->ref . ' ' . $object->name;
310
if (getDolGlobalString('MAIN_HTML_TITLE') && preg_match('/projectnameonly/', getDolGlobalString('MAIN_HTML_TITLE')) && $object->name) {
311
    $title = $object->ref . ' ' . $object->name . ' - ' . $langs->trans('ProjectContact');
312
}
313
314
$help_url = 'EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos|DE:Modul_Projekte';
315
316
ViewMain::llxHeader('', $title, $help_url);
317
318
319
if ($id > 0 || !empty($ref)) {
320
    /*
321
     * View
322
     */
323
    if (getDolGlobalString('PROJECT_ALLOW_COMMENT_ON_PROJECT') && method_exists($object, 'fetchComments') && empty($object->comments)) {
324
        $object->fetchComments();
325
    }
326
    // To verify role of users
327
    //$userAccess = $object->restrictedProjectArea($user,'read');
328
    $userWrite = $object->restrictedProjectArea($user, 'write');
329
    //$userDelete = $object->restrictedProjectArea($user,'delete');
330
    //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete;
331
332
    $head = project_prepare_head($object);
333
    print dol_get_fiche_head($head, 'contact', $langs->trans("Project"), -1, ($object->public ? 'projectpub' : 'project'));
334
335
    $formconfirm = $formconfirmtoaddtasks;
336
337
    // Call Hook formConfirm
338
    $parameters = array('formConfirm' => $formconfirm);
339
    $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
340
    if (empty($reshook)) {
341
        $formconfirm .= $hookmanager->resPrint;
342
    } elseif ($reshook > 0) {
343
        $formconfirm = $hookmanager->resPrint;
344
    }
345
346
    // Print form confirm
347
    print $formconfirm;
348
349
    // Project card
350
351
    if (!empty($_SESSION['pageforbacktolist']) && !empty($_SESSION['pageforbacktolist']['project'])) {
352
        $tmpurl = $_SESSION['pageforbacktolist']['project'];
353
        $tmpurl = preg_replace('/__SOCID__/', (string)$object->socid, $tmpurl);
354
        $linkback = '<a href="' . $tmpurl . (preg_match('/\?/', $tmpurl) ? '&' : '?') . 'restore_lastsearch_values=1">' . $langs->trans("BackToList") . '</a>';
355
    } else {
356
        $linkback = '<a href="' . constant('BASE_URL') . '/projet/list.php?restore_lastsearch_values=1">' . $langs->trans("BackToList") . '</a>';
357
    }
358
359
    $morehtmlref = '<div class="refidno">';
360
    // Title
361
    $morehtmlref .= dol_escape_htmltag($object->title);
362
    $morehtmlref .= '<br>';
363
    // Thirdparty
364
    if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) {
365
        $morehtmlref .= $object->thirdparty->getNomUrl(1, 'project');
0 ignored issues
show
The method getNomUrl() does not exist on null. ( Ignorable by Annotation )

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

365
        $morehtmlref .= $object->thirdparty->/** @scrutinizer ignore-call */ getNomUrl(1, 'project');

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

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

Loading history...
366
    }
367
    $morehtmlref .= '</div>';
368
369
    // Define a complementary filter for search of next/prev ref.
370
    if (!$user->hasRight('projet', 'all', 'lire')) {
371
        $objectsListId = $object->getProjectsAuthorizedForUser($user, 0, 0);
372
        $object->next_prev_filter = "rowid IN (" . $db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0') . ")";
373
    }
374
375
    dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
376
377
378
    print '<div class="fichecenter">';
379
    print '<div class="fichehalfleft">';
380
    print '<div class="underbanner clearboth"></div>';
381
382
    print '<table class="border tableforfield centpercent">';
383
384
    // Usage
385
    if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') || !getDolGlobalString('PROJECT_HIDE_TASKS') || isModEnabled('eventorganization')) {
386
        print '<tr><td class="tdtop">';
387
        print $langs->trans("Usage");
388
        print '</td>';
389
        print '<td>';
390
        if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
391
            print '<input type="checkbox" disabled name="usage_opportunity"' . (GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_opportunity ? ' checked="checked"' : '')) . '"> ';
392
            $htmltext = $langs->trans("ProjectFollowOpportunity");
393
            print $form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext);
394
            print '<br>';
395
        }
396
        if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
397
            print '<input type="checkbox" disabled name="usage_task"' . (GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_task ? ' checked="checked"' : '')) . '"> ';
398
            $htmltext = $langs->trans("ProjectFollowTasks");
399
            print $form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext);
400
            print '<br>';
401
        }
402
        if (!getDolGlobalString('PROJECT_HIDE_TASKS') && getDolGlobalString('PROJECT_BILL_TIME_SPENT')) {
403
            print '<input type="checkbox" disabled name="usage_bill_time"' . (GETPOSTISSET('usage_bill_time') ? (GETPOST('usage_bill_time', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_bill_time ? ' checked="checked"' : '')) . '"> ';
404
            $htmltext = $langs->trans("ProjectBillTimeDescription");
405
            print $form->textwithpicto($langs->trans("BillTime"), $htmltext);
406
            print '<br>';
407
        }
408
        if (isModEnabled('eventorganization')) {
409
            print '<input type="checkbox" disabled name="usage_organize_event"' . (GETPOSTISSET('usage_organize_event') ? (GETPOST('usage_organize_event', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_organize_event ? ' checked="checked"' : '')) . '"> ';
410
            $htmltext = $langs->trans("EventOrganizationDescriptionLong");
411
            print $form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext);
412
        }
413
        print '</td></tr>';
414
    }
415
416
    // Visibility
417
    print '<tr><td class="titlefield">' . $langs->trans("Visibility") . '</td><td>';
418
    if ($object->public) {
419
        print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
420
        print $langs->trans('SharedProject');
421
    } else {
422
        print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
423
        print $langs->trans('PrivateProject');
424
    }
425
    print '</td></tr>';
426
427
    if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') && !empty($object->usage_opportunity)) {
428
        // Opportunity status
429
        print '<tr><td>' . $langs->trans("OpportunityStatus") . '</td><td>';
430
        $code = dol_getIdFromCode($db, $object->opp_status, 'c_lead_status', 'rowid', 'code');
431
        if ($code) {
432
            print $langs->trans("OppStatus" . $code);
433
        }
434
435
        // Opportunity percent
436
        print ' <span title="' . $langs->trans("OpportunityProbability") . '"> / ';
437
        if (strcmp($object->opp_percent, '')) {
438
            print price($object->opp_percent, 0, $langs, 1, 0) . ' %';
439
        }
440
        print '</span></td></tr>';
441
442
        // Opportunity Amount
443
        print '<tr><td>' . $langs->trans("OpportunityAmount") . '</td><td>';
444
        if (strcmp($object->opp_amount, '')) {
445
            print '<span class="amount">' . price($object->opp_amount, 0, $langs, 1, 0, -1, $conf->currency) . '</span>';
446
            if (strcmp($object->opp_percent, '')) {
447
                print ' &nbsp; &nbsp; &nbsp; <span title="' . dol_escape_htmltag($langs->trans('OpportunityWeightedAmount')) . '"><span class="opacitymedium">' . $langs->trans("OpportunityWeightedAmountShort") . '</span>: <span class="amount">' . price($object->opp_amount * $object->opp_percent / 100, 0, $langs, 1, 0, -1, $conf->currency) . '</span></span>';
448
            }
449
        }
450
        print '</td></tr>';
451
    }
452
453
    // Budget
454
    print '<tr><td>' . $langs->trans("Budget") . '</td><td>';
455
    if (!is_null($object->budget_amount) && strcmp($object->budget_amount, '')) {
456
        print '<span class="amount">' . price($object->budget_amount, 0, $langs, 1, 0, 0, $conf->currency) . '</span>';
457
    }
458
    print '</td></tr>';
459
460
    // Date start - end project
461
    print '<tr><td>' . $langs->trans("Dates") . '</td><td>';
462
    $start = dol_print_date($object->date_start, 'day');
463
    print($start ? $start : '?');
464
    $end = dol_print_date($object->date_end, 'day');
465
    print ' <span class="opacitymedium">-</span> ';
466
    print($end ? $end : '?');
467
    if ($object->hasDelay()) {
468
        print img_warning("Late");
469
    }
470
    print '</td></tr>';
471
472
    // Other attributes
473
    $cols = 2;
474
    include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php';
475
476
    print "</table>";
477
478
    print '</div>';
479
    print '<div class="fichehalfright">';
480
    print '<div class="underbanner clearboth"></div>';
481
482
    print '<table class="border tableforfield centpercent">';
483
484
    // Description
485
    print '<td class="titlefield tdtop">' . $langs->trans("Description") . '</td><td>';
486
    print dol_htmlentitiesbr($object->description);
487
    print '</td></tr>';
488
489
    // Categories
490
    if (isModEnabled('category')) {
491
        print '<tr><td class="valignmiddle">' . $langs->trans("Categories") . '</td><td>';
492
        print $form->showCategories($object->id, Categorie::TYPE_PROJECT, 1);
493
        print "</td></tr>";
494
    }
495
496
    print '</table>';
497
498
    print '</div>';
499
    print '</div>';
500
501
    print '<div class="clearboth"></div>';
502
503
    print dol_get_fiche_end();
504
505
    print '<br>';
506
507
    // Contacts lines (modules that overwrite templates must declare this into descriptor)
508
    $dirtpls = array_merge($conf->modules_parts['tpl'], array('/core/tpl'));
509
    foreach ($dirtpls as $reldir) {
510
        $res = @include dol_buildpath($reldir . '/contacts.tpl.php');
511
        if ($res) {
512
            break;
513
        }
514
    }
515
}
516
517
// End of page
518
ViewMain::llxFooter();
519
$db->close();
520