dolibarr 25.0.0-alpha
project.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2010-2014 Regis Houssin <regis.houssin@inodbox.com>
3 * Copyright (C) 2011-2016 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2011-2015 Juanjo Menent <jmenent@2byte.es>
5 * Copyright (C) 2011-2018 Philippe Grand <philippe.grand@atoo-net.com>
6 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
7 * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
8 * Copyright (C) 2018 Ferran Marcet <fmarcet@2byte.es>
9 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
10 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24 */
25
32// Load Dolibarr environment
33require '../../main.inc.php';
34require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
35require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
36require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
37require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
38
48// Load translation files required by the page
49$langs->loadLangs(array('admin', 'errors', 'other', 'projects'));
50
51if (!$user->admin) {
53}
54
55$action = GETPOST('action', 'aZ09');
56$modulepart = GETPOST('modulepart', 'aZ09');
57
58$value = GETPOST('value', 'alpha');
59$label = GETPOST('label', 'alpha');
60$scandir = GETPOST('scan_dir', 'alpha');
61$type = 'project';
62
63
64/*
65 * Actions
66 */
67$error = 0;
68include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
69
70if ($action == 'updateMask') {
71 $maskconstproject = GETPOST('maskconstproject', 'aZ09');
72 $maskproject = GETPOST('maskproject', 'alpha');
73
74 $res = -1;
75 if ($maskconstproject && preg_match('/_MASK$/', $maskconstproject)) {
76 $res = dolibarr_set_const($db, $maskconstproject, $maskproject, 'chaine', 0, '', $conf->entity);
77 }
78
79 if (!($res > 0)) {
80 $error++;
81 }
82
83 if (!$error) {
84 setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
85 } else {
86 setEventMessages($langs->trans("Error"), null, 'errors');
87 }
88}
89
90if ($action == 'updateMaskTask') {
91 $maskconstmasktask = GETPOST('maskconsttask', 'aZ09');
92 $masktaskt = GETPOST('masktask', 'alpha');
93 $res = 0;
94 if ($maskconstmasktask && preg_match('/_MASK$/', $maskconstmasktask)) {
95 $res = dolibarr_set_const($db, $maskconstmasktask, $masktaskt, 'chaine', 0, '', $conf->entity);
96 }
97
98 if (!($res > 0)) {
99 $error++;
100 }
101
102 if (!$error) {
103 setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
104 } else {
105 setEventMessages($langs->trans("Error"), null, 'errors');
106 }
107} elseif ($action == 'specimen') {
108 $modele = GETPOST('module', 'alpha');
109
110 $project = new Project($db);
111 $project->initAsSpecimen();
112
113 // Search template files
114 $file = '';
115 $classname = '';
116 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
117 foreach ($dirmodels as $reldir) {
118 $file = dol_buildpath($reldir."core/modules/project/doc/pdf_".$modele.".modules.php", 0);
119 if (file_exists($file)) {
120 $classname = "pdf_".$modele;
121 break;
122 }
123 }
124
125 if ($classname !== '') {
126 require_once $file;
127
128 $module = new $classname($db);
129 '@phan-var-force ModelePDFProjects $module';
132 if ($module->write_file($project, $langs) > 0) {
133 header("Location: ".DOL_URL_ROOT."/document.php?modulepart=project&file=SPECIMEN.pdf");
134 return;
135 } else {
136 setEventMessages($module->error, $module->errors, 'errors');
137 dol_syslog($module->error, LOG_ERR);
138 }
139 } else {
140 setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors');
141 dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR);
142 }
143} elseif ($action == 'specimentask') {
144 $modele = GETPOST('module', 'alpha');
145
146 $project = new Project($db);
147 $project->initAsSpecimen();
148
149 // Search template files
150 $file = '';
151 $classname = '';
152 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
153 foreach ($dirmodels as $reldir) {
154 $file = dol_buildpath($reldir."core/modules/project/task/doc/pdf_".$modele.".modules.php", 0);
155 if (file_exists($file)) {
156 $classname = "pdf_".$modele;
157 break;
158 }
159 }
160
161 if ($classname !== '') {
162 require_once $file;
163
164 $module = new $classname($db);
165 '@phan-var-force ModelePDFTask $module';
168 if ($module->write_file($project, $langs) > 0) {
169 header("Location: ".DOL_URL_ROOT."/document.php?modulepart=project_task&file=SPECIMEN.pdf");
170 return;
171 } else {
172 setEventMessages($module->error, $module->errors, 'errors');
173 dol_syslog($module->error, LOG_ERR);
174 }
175 } else {
176 setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors');
177 dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR);
178 }
179} elseif ($action == 'set') {
180 // Activate a model
181 $ret = addDocumentModel($value, $type, $label, $scandir);
182} elseif ($action == 'settask') {
183 // Activate a model for task
184 $ret = addDocumentModel($value, 'project_task', $label, $scandir);
185} elseif ($action == 'del') {
186 $ret = delDocumentModel($value, $type);
187 if ($ret > 0) {
188 if (getDolGlobalString('PROJECT_ADDON_PDF') == "$value") {
189 dolibarr_del_const($db, 'PROJECT_ADDON_PDF', $conf->entity);
190 }
191 }
192} elseif ($action == 'deltask') {
193 $ret = delDocumentModel($value, 'project_task');
194 if ($ret > 0) {
195 if (getDolGlobalString('PROJECT_TASK_ADDON_PDF') == "$value") {
196 dolibarr_del_const($db, 'PROJECT_TASK_ADDON_PDF', $conf->entity);
197 }
198 }
199} elseif ($action == 'setdoc') {
200 // Set default model
201 dolibarr_set_const($db, "PROJECT_ADDON_PDF", $value, 'chaine', 0, '', $conf->entity);
202
203 // We also enable the template
204 $ret = delDocumentModel($value, $type);
205 if ($ret > 0) {
206 $ret = addDocumentModel($value, $type, $label, $scandir);
207 }
208} elseif ($action == 'unsetdoc') {
209 // Set default model
210 dolibarr_del_const($db, "PROJECT_ADDON_PDF", $conf->entity);
211} elseif ($action == 'setdoctask') {
212 if (dolibarr_set_const($db, "PROJECT_TASK_ADDON_PDF", $value, 'chaine', 0, '', $conf->entity)) {
213 // The constant that was read before the new set
214 // so we go through a variable to get a consistent display
215 $conf->global->PROJECT_TASK_ADDON_PDF = $value;
216 }
217
218 // On active le modele
219 $ret = delDocumentModel($value, 'project_task');
220 if ($ret > 0) {
221 $ret = addDocumentModel($value, 'project_task', $label, $scandir);
222 }
223} elseif ($action == 'unsetdoctask') {
224 // Set default model
225 dolibarr_del_const($db, "PROJECT_TASK_ADDON_PDF", $conf->entity);
226} elseif ($action == 'setmod') {
227 // TODO Verifier si module numerotation choisi peut etre active
228 // par appel methode canBeActivated
229
230 dolibarr_set_const($db, "PROJECT_ADDON", $value, 'chaine', 0, '', $conf->entity);
231} elseif ($action == 'setmodtask') {
232 // TODO Verifier si module numerotation choisi peut etre active
233 // par appel methode canBeActivated
234
235 dolibarr_set_const($db, "PROJECT_TASK_ADDON", $value, 'chaine', 0, '', $conf->entity);
236} elseif ($action == 'updateoptions') {
237 if (GETPOST('PROJECT_USE_SEARCH_TO_SELECT')) {
238 $companysearch = GETPOST('activate_PROJECT_USE_SEARCH_TO_SELECT', 'alpha');
239 if (dolibarr_set_const($db, "PROJECT_USE_SEARCH_TO_SELECT", $companysearch, 'chaine', 0, '', $conf->entity)) {
240 $conf->global->PROJECT_USE_SEARCH_TO_SELECT = $companysearch;
241 }
242 }
243 if (GETPOST('PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY')) {
244 $projectToSelect = GETPOST('projectToSelect', 'alpha');
245 dolibarr_set_const($db, 'PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY', $projectToSelect, 'chaine', 0, '', $conf->entity); //Allow to disable this configuration if empty value
246 }
247 if (GETPOST('PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS')) {
248 $timesheetFreezeDuration = GETPOST('timesheetFreezeDuration', 'alpha');
249 dolibarr_set_const($db, 'PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS', intval($timesheetFreezeDuration), 'chaine', 0, '', $conf->entity); //Allow to disable this configuration if empty value
250 }
251} elseif (preg_match('/^(set|del)_?([A-Z_]+)$/', $action, $reg)) {
252 // Set boolean (on/off) constants
253 if (!dolibarr_set_const($db, $reg[2], ($reg[1] === 'set' ? '1' : '0'), 'chaine', 0, '', $conf->entity) > 0) {
254 dol_print_error($db);
255 }
256}
257
258/*
259 * View
260 */
261
262$form = new Form($db);
263
264$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
265
266llxHeader("", $langs->trans("ProjectsSetup"), '', '', 0, 0, '', '', '', 'mod-project page-admin');
267
268$form = new Form($db);
269
270$linkback = '<a href="'.dolBuildUrl(DOL_URL_ROOT.'/admin/modules.php', ['restore_lastsearch_values' => 1]).'">'.img_picto($langs->trans("BackToModuleList"), 'back', 'class="pictofixedwidth"').'<span class="hideonsmartphone">'.$langs->trans("BackToModuleList").'</span></a>';
271print load_fiche_titre($langs->trans("ProjectsSetup"), $linkback, 'title_setup');
272
274
275print dol_get_fiche_head($head, 'project', $langs->trans("Projects"), -1, 'project');
276
277print '<br>';
278
279// Main options
280
281print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
282print '<input type="hidden" name="token" value="'.newToken().'">';
283print '<input type="hidden" name="action" value="setmainoptions">';
284
285print '<table class="noborder centpercent">';
286print '<tr class="liste_titre">';
287print "<td>".$langs->trans("Parameters")."</td>\n";
288print '<td class="right" width="60">'.$langs->trans("Value").'</td>'."\n";
289print '<td width="80">&nbsp;</td></tr>'."\n";
290
291print '<tr class="oddeven">';
292print '<td width="80%">'.$langs->trans("ManageOpportunitiesStatus").'</td>';
293print '<td width="60" class="right">';
294print ajax_constantonoff("PROJECT_USE_OPPORTUNITIES", array(), null, 0, 0, 1);
295print '</td><td class="right">';
296print "</td>";
297print '</tr>';
298
299
300print '<tr class="oddeven">';
301print '<td width="80%">'.$langs->trans("ManageTasks").'</td>';
302print '<td width="60" class="right">';
303print ajax_constantonoff("PROJECT_HIDE_TASKS", array(), null, 1);
304print '</td><td class="right">';
305print "</td>";
306print '</tr>';
307
308print '</table></form>';
309
310print '<br>';
311
312
313
314/*
315 * Projects Numbering model
316 */
317
318$project = new Project($db);
319$project->initAsSpecimen();
320
321printNumberingModuleList('project', 'mod_project_', 'PROJECT_ADDON', $langs->trans("ProjectsNumberingModules"), $project);
322
323print '<br>';
324
325if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
326 // Task numbering module
327 $project = new Project($db);
328 $project->initAsSpecimen();
329
330 printNumberingModuleList('project/task', 'mod_task_', 'PROJECT_TASK_ADDON', $langs->trans("TasksNumberingModules"), $project, 'setmodtask');
331
332 print '<br>';
333}
334
335
336/*
337 * Document templates generators
338 */
339
340printDocumentModelList($type, 'project', 'PROJECT_ADDON_PDF', $langs->trans("ProjectsModelModule"), array(
341 'Logo' => 'option_logo',
342), false, '', 1, 'unsetdoc');
343print '<br>';
344
345
346
347if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
348 /*
349 * Modeles documents for Task
350 */
351
352 print load_fiche_titre($langs->trans("TaskModelModule"), '', '');
353
354 // Define array def of model
355 $type = 'project_task';
356 $def = array();
357
358 $sql = "SELECT nom";
359 $sql .= " FROM ".MAIN_DB_PREFIX."document_model";
360 $sql .= " WHERE type = '".$db->escape($type)."'";
361 $sql .= " AND entity = ".((int) $conf->entity);
362
363 $resql = $db->query($sql);
364 if ($resql) {
365 $i = 0;
366 $num_rows = $db->num_rows($resql);
367 while ($i < $num_rows) {
368 $array = $db->fetch_array($resql);
369 if (is_array($array)) {
370 array_push($def, $array[0]);
371 }
372 $i++;
373 }
374 } else {
375 dol_print_error($db);
376 }
377
378 print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
379 print '<table class="noborder" width="100%">'."\n";
380 print '<tr class="liste_titre">'."\n";
381 print ' <td width="100">'.$langs->trans("Name")."</td>\n";
382 print " <td>".$langs->trans("Description")."</td>\n";
383 print '<td class="center" width="60">'.$langs->trans("Activated")."</td>\n";
384 print '<td class="center" width="60">'.$langs->trans("Default")."</td>\n";
385 print '<td class="center" width="80">'.$langs->trans("ShortInfo").'</td>';
386 print '<td class="center" width="80">'.$langs->trans("Preview").'</td>';
387 print "</tr>\n";
388
389 clearstatcache();
390
391 foreach ($dirmodels as $reldir) {
392 foreach (array('', '/doc') as $valdir) {
393 $dir = dol_buildpath($reldir."core/modules/project/task/".$valdir);
394
395 if (is_dir($dir)) {
396 $handle = opendir($dir);
397 if (is_resource($handle)) {
398 $filelist = array();
399 while (($file = readdir($handle)) !== false) {
400 $filelist[] = $file;
401 }
402 closedir($handle);
403 arsort($filelist);
404
405 foreach ($filelist as $file) {
406 if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) {
407 if (file_exists($dir.'/'.$file)) {
408 $name = dol_substr($file, 4, dol_strlen($file) - 16);
409 $classname = dol_substr($file, 0, dol_strlen($file) - 12);
410
411 require_once $dir.'/'.$file;
412 $module = new $classname($db);
413 '@phan-var-force ModelePDFTask $module';
414
415 $modulequalified = 1;
416 if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
417 $modulequalified = 0;
418 }
419 if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
420 $modulequalified = 0;
421 }
422
423 if ($modulequalified) {
424 print '<tr class="oddeven"><td width="100">';
425 print(empty($module->name) ? $name : $module->name);
426 print "</td><td>\n";
427 if (method_exists($module, 'info')) {
428 print $module->info($langs); // @phan-suppress-current-line PhanUndeclaredMethod
429 } else {
430 print $module->description;
431 }
432 print "</td>\n";
433
434 // Active
435 if (in_array($name, $def)) {
436 print '<td class="center">'."\n";
437 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=deltask&token='.newToken().'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'">';
438 print img_picto($langs->trans("Enabled"), 'switch_on');
439 print '</a>';
440 print "</td>";
441 } else {
442 print '<td class="center">'."\n";
443 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=settask&token='.newToken().'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>';
444 print "</td>";
445 }
446
447 // Default
448 print '<td class="center">';
449 if (getDolGlobalString("PROJECT_TASK_ADDON_PDF", $name)) {
450 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=unsetdoctask&token='.newToken().'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'on').'</a>';
451 } else {
452 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=setdoctask&token='.newToken().'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').'</a>';
453 }
454 print '</td>';
455
456 // Info
457 $htmltooltip = ''.$langs->trans("Name").': '.$module->name;
458 $htmltooltip .= '<br>'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown"));
459 if ($module->type == 'pdf') {
460 $htmltooltip .= '<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
461 }
462 $htmltooltip .= '<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
463 $htmltooltip .= '<br>'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1);
464
465 print '<td class="center">';
466 print $form->textwithpicto('', $htmltooltip, 1, 'info');
467 print '</td>';
468
469 // Preview
470 print '<td class="center">';
471 if ($module->type == 'pdf') {
472 print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimentask&token='.newToken().'&module='.$name.'">'.img_object($langs->trans("Preview"), 'bill').'</a>';
473 } else {
474 print img_object($langs->transnoentitiesnoconv("PreviewNotAvailable"), 'generic');
475 }
476 print '</td>';
477 print "</tr>\n";
478 }
479 }
480 }
481 }
482 }
483 }
484 }
485 }
486
487 print '</table>';
488 print '</div>';
489 print '<br>';
490}
491
492
493print load_fiche_titre($langs->trans("Other"), '', '');
494
495// Other options
496$form = new Form($db);
497
498print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
499print '<input type="hidden" name="token" value="'.newToken().'">';
500print '<input type="hidden" name="action" value="updateoptions">';
501print '<input type="hidden" name="page_y" value="">';
502
503print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
504print '<table class="noborder centpercent">';
505print '<tr class="liste_titre">';
506print "<td>".$langs->trans("Parameters")."</td>\n";
507print '<td></td>';
508print '</tr>'."\n";
509
510print '<tr class="oddeven">';
511print '<td>'.$langs->trans("UseSearchToSelectProject").'</td>';
512if (!$conf->use_javascript_ajax) {
513 print '<td class="nowrap right">';
514 print $langs->trans("NotAvailableWhenAjaxDisabled");
515 print "</td>";
516} else {
517 print '<td class="right">';
518 $arrval = array(
519 0 => array('label' => $langs->trans("No")),
520 1 => array('label' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 1).')', 'labelhtml' => $langs->trans("Yes").' <span class="opacitymedium small">('.$langs->trans("NumberOfKeyToSearch", 1).')</span>'),
521 2 => array('label' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 2).')', 'labelhtml' => $langs->trans("Yes").' <span class="opacitymedium small">('.$langs->trans("NumberOfKeyToSearch", 2).')</span>'),
522 3 => array('label' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 3).')', 'labelhtml' => $langs->trans("Yes").' <span class="opacitymedium small">('.$langs->trans("NumberOfKeyToSearch", 3).')</span>'),
523 );
524 print $form->selectarray("activate_PROJECT_USE_SEARCH_TO_SELECT", $arrval, getDolGlobalString("PROJECT_USE_SEARCH_TO_SELECT"));
525 print '<input type="submit" class="button small reposition" name="PROJECT_USE_SEARCH_TO_SELECT" value="'.$langs->trans("Modify").'">';
526 print "</td>";
527}
528print '</tr>';
529
530print '<tr class="oddeven">';
531print '<td>'.$langs->trans("AllowToSelectProjectFromOtherCompany").'</td>';
532print '<td class="right">';
533print '<input type="text" id="projectToSelect" name="projectToSelect" value="' . getDolGlobalString('PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY').'"/>&nbsp;';
534print $form->textwithpicto('', $langs->trans('AllowToLinkFromOtherCompany'));
535print '<input type="submit" class="button small reposition" name="PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY" value="'.$langs->trans("Modify").'">';
536print '</td>';
537print '</tr>';
538
539$key = 'PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE';
540echo '<tr class="oddeven">',
541'<td class="left">',
542$form->textwithpicto($langs->transnoentities($key), $langs->transnoentities($key . '_help')),
543'</td>',
544'<td class="right">',
545ajax_constantonoff($key),
546'</td>',
547'</tr>';
548
549print '<tr class="oddeven">';
550print '<td>'.$langs->trans("TimesheetPreventAfterFollowingMonths").'</td>';
551print '<td class="right">';
552print '<input type="number" class="width50" id="timesheetFreezeDuration" name="timesheetFreezeDuration" min="0" step="1" value="' . getDolGlobalString('PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS').'"/>&nbsp;';
553print '<input type="submit" class="button small reposition" name="PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS" value="'.$langs->trans("Modify").'">';
554print '</td>';
555print '</tr>';
556
557/* Generates a lot of confusion for users. Not visible by default.
558print '<tr class="oddeven">';
559print '<td class="left">';
560print $form->textwithpicto($langs->transnoentities('PROJECT_DISPLAY_LINKED_BY_CONTACT'), $langs->transnoentities('PROJECT_DISPLAY_LINKED_BY_CONTACT_help'));
561print '</td>';
562print '<td class="right">';
563print ajax_constantonoff('PROJECT_DISPLAY_LINKED_BY_CONTACT');
564print '</td>';
565print '</tr>';
566*/
567
568print '</table>';
569print '</div>';
570
571print '</form>';
572
573// End of page
574llxFooter();
575$db->close();
addDocumentModel($name, $type, $label='', $description='')
Add document model used by doc generator.
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
dolibarr_del_const($db, $name, $entity=1)
Delete a constant.
delDocumentModel($name, $type)
Delete document model used by doc generator.
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
Class to manage generation of HTML components Only common components must be here.
Class to manage projects.
if(! $sortfield) if(! $sortorder) $module
Definition list.php:193
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
dol_substr($string, $start, $length=null, $stringencoding='', $trunconbytes=0)
Make a substring.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
Definition html.lib.php:540
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
project_admin_prepare_head()
Prepare array with list of tabs.
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:140
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.