dolibarr 24.0.0-beta
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 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 // La constante qui a ete lue en avant du nouveau set
214 // on passe donc par une variable pour avoir un affichage coherent
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) {
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
318print load_fiche_titre($langs->trans("ProjectsNumberingModules"), '', '');
319
320print '<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
321print '<table class="noborder centpercent">';
322print '<tr class="liste_titre">';
323print '<td width="100">'.$langs->trans("Name").'</td>';
324print '<td>'.$langs->trans("Description").'</td>';
325print '<td>'.$langs->trans("Example").'</td>';
326print '<td class="center" width="60">'.$langs->trans("Activated").'</td>';
327print '<td class="center" width="80">'.$langs->trans("ShortInfo").'</td>';
328print "</tr>\n";
329
330clearstatcache();
331
332foreach ($dirmodels as $reldir) {
333 $dir = dol_buildpath($reldir."core/modules/project/");
334
335 if (is_dir($dir)) {
336 $handle = opendir($dir);
337 if (is_resource($handle)) {
338 while (($file = readdir($handle)) !== false) {
339 if (preg_match('/^(mod_.*)\.php$/i', $file, $reg)) {
340 $file = $reg[1];
341 $classname = substr($file, 4);
342
343 require_once $dir.$file.'.php';
344
345 $module = new $file();
346 '@phan-var-force ModeleNumRefProjects $module';
347
348 // Show modules according to features level
349 if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
350 continue;
351 }
352 if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
353 continue;
354 }
355
356 if ($module->isEnabled()) {
357 print '<tr class="oddeven"><td>'.$module->name."</td><td>\n";
358 print $module->info($langs);
359 print '</td>';
360
361 // Show example of numbering model
362 print '<td class="nowrap">';
363 $tmp = $module->getExample();
364 if (preg_match('/^Error/', $tmp)) {
365 $langs->load("errors");
366 print '<div class="error">'.$langs->trans($tmp).'</div>';
367 } elseif ($tmp == 'NotConfigured') {
368 print $langs->trans($tmp);
369 } else {
370 print $tmp;
371 }
372 print '</td>'."\n";
373
374 print '<td class="center">';
375 if (getDolGlobalString('PROJECT_ADDON') == 'mod_'.$classname) {
376 print img_picto($langs->trans("Activated"), 'switch_on');
377 } else {
378 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=setmod&token='.newToken().'&value=mod_'.$classname.'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>';
379 }
380 print '</td>';
381
382 $project = new Project($db);
383 $project->initAsSpecimen();
384
385 // Info
386 $htmltooltip = '';
387 $htmltooltip .= ''.$langs->trans("Version").': <b>'.$module->getVersion().'</b><br>';
388 $nextval = $module->getNextValue($mysoc, $project);
389 if ((string) $nextval != $langs->trans("NotAvailable")) {
390 $htmltooltip .= ''.$langs->trans("NextValue").': ';
391 if ($nextval) {
392 $htmltooltip .= $nextval.'<br>';
393 } else {
394 $htmltooltip .= $langs->trans($module->error).'<br>';
395 }
396 }
397
398 print '<td class="center">';
399 print $form->textwithpicto('', $htmltooltip, 1, 'info');
400 print '</td>';
401
402 print '</tr>';
403 }
404 }
405 }
406 closedir($handle);
407 }
408 }
409}
410
411print '</table>';
412print '</div>';
413print '<br>';
414
415if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
416 // Task numbering module
417 print load_fiche_titre($langs->trans("TasksNumberingModules"), '', '');
418
419 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
420 print '<table class="noborder centpercent">';
421 print '<tr class="liste_titre">';
422 print '<td width="100">'.$langs->trans("Name").'</td>';
423 print '<td>'.$langs->trans("Description").'</td>';
424 print '<td>'.$langs->trans("Example").'</td>';
425 print '<td class="center" width="60">'.$langs->trans("Activated").'</td>';
426 print '<td class="center" width="80">'.$langs->trans("ShortInfo").'</td>';
427 print "</tr>\n";
428
429 clearstatcache();
430
431 foreach ($dirmodels as $reldir) {
432 $dir = dol_buildpath($reldir."core/modules/project/task/");
433
434 if (is_dir($dir)) {
435 $handle = opendir($dir);
436 if (is_resource($handle)) {
437 while (($file = readdir($handle)) !== false) {
438 if (preg_match('/^(mod_.*)\.php$/i', $file, $reg)) {
439 $file = $reg[1];
440 $classname = substr($file, 4);
441
442 require_once $dir.$file.'.php';
443
444 $module = new $file();
445 '@phan-var-force ModeleNumRefTask $module';
448 // Show modules according to features level
449 if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
450 continue;
451 }
452 if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
453 continue;
454 }
455
456 if ($module->isEnabled()) {
457 print '<tr class="oddeven"><td>'.$module->name."</td><td>\n";
458 print $module->info($langs);
459 print '</td>';
460
461 // Show example of numbering module
462 print '<td class="nowrap">';
463 $tmp = $module->getExample();
464 if (preg_match('/^Error/', $tmp)) {
465 $langs->load("errors");
466 print '<div class="error">'.$langs->trans($tmp).'</div>';
467 } elseif ($tmp == 'NotConfigured') {
468 print $langs->trans($tmp);
469 } else {
470 print $tmp;
471 }
472 print '</td>'."\n";
473
474 print '<td class="center">';
475 if (getDolGlobalString("PROJECT_TASK_ADDON") == 'mod_'.$classname) {
476 print img_picto($langs->trans("Activated"), 'switch_on');
477 } else {
478 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=setmodtask&token='.newToken().'&value=mod_'.$classname.'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>';
479 }
480 print '</td>';
481
482 $project = new Project($db);
483 $project->initAsSpecimen();
484
485 // Info
486 $htmltooltip = '';
487 $htmltooltip .= ''.$langs->trans("Version").': <b>'.$module->getVersion().'</b><br>';
488 $nextval = $module->getNextValue($mysoc, $project);
489 if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval
490 $htmltooltip .= ''.$langs->trans("NextValue").': ';
491 if ($nextval) {
492 $htmltooltip .= $nextval.'<br>';
493 } else {
494 $htmltooltip .= $langs->trans($module->error).'<br>';
495 }
496 }
497
498 print '<td class="center">';
499 print $form->textwithpicto('', $htmltooltip, 1, 'info');
500 print '</td>';
501
502 print '</tr>';
503 }
504 }
505 }
506 closedir($handle);
507 }
508 }
509 }
510
511 print '</table>';
512 print '</div>';
513 print '<br>';
514}
515
516
517/*
518 * Document templates generators
519 */
520
521print load_fiche_titre($langs->trans("ProjectsModelModule"), '', '');
522
523// Defini tableau def de modele
524$type = 'project';
525$def = array();
526// TODO Replace with $def = getListOfModels($db, $type);
527$sql = "SELECT nom";
528$sql .= " FROM ".MAIN_DB_PREFIX."document_model";
529$sql .= " WHERE type = '".$db->escape($type)."'";
530$sql .= " AND entity = ".((int) $conf->entity);
531
532$resql = $db->query($sql);
533if ($resql) {
534 $i = 0;
535 $num_rows = $db->num_rows($resql);
536 while ($i < $num_rows) {
537 $array = $db->fetch_array($resql);
538 if (is_array($array)) {
539 array_push($def, $array[0]);
540 }
541 $i++;
542 }
543} else {
545}
546
547print '<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
548print '<table class="noborder" width="100%">'."\n";
549print '<tr class="liste_titre">'."\n";
550print ' <td width="100">'.$langs->trans("Name")."</td>\n";
551print " <td>".$langs->trans("Description")."</td>\n";
552print '<td class="center" width="60">'.$langs->trans("Activated")."</td>\n";
553print '<td class="center" width="60">'.$langs->trans("Default")."</td>\n";
554print '<td class="center" width="80">'.$langs->trans("ShortInfo").'</td>';
555print '<td class="center" width="80">'.$langs->trans("Preview").'</td>';
556print "</tr>\n";
557
558clearstatcache();
559
560$filelist = array();
561foreach ($dirmodels as $reldir) {
562 foreach (array('', '/doc') as $valdir) {
563 $dir = dol_buildpath($reldir."core/modules/project/".$valdir);
564
565 if (is_dir($dir)) {
566 $handle = opendir($dir);
567 if (is_resource($handle)) {
568 while (($file = readdir($handle)) !== false) {
569 $filelist[] = $file;
570 }
571 closedir($handle);
572 arsort($filelist);
573
574 foreach ($filelist as $file) {
575 if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) {
576 if (file_exists($dir.'/'.$file)) {
577 $name = substr($file, 4, dol_strlen($file) - 16);
578 $classname = substr($file, 0, dol_strlen($file) - 12);
579
580 require_once $dir.'/'.$file;
581 $module = new $classname($db);
582 '@phan-var-force ModelePDFProjects $module';
583
584 $modulequalified = 1;
585 if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
586 $modulequalified = 0;
587 }
588 if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
589 $modulequalified = 0;
590 }
591
592 if ($modulequalified) {
593 print '<tr class="oddeven"><td width="100">';
594 print(empty($module->name) ? $name : $module->name);
595 print "</td><td>\n";
596 if (method_exists($module, 'info')) {
597 print $module->info($langs); // @phan-suppress-current-line PhanUndeclaredMethod
598 } else {
599 print $module->description;
600 }
601 print "</td>\n";
602
603 // Active
604 if (in_array($name, $def)) {
605 print '<td class="center">'."\n";
606 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=del&token='.newToken().'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'">';
607 print img_picto($langs->trans("Enabled"), 'switch_on');
608 print '</a>';
609 print "</td>";
610 } else {
611 print '<td class="center">'."\n";
612 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=set&token='.newToken().'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'">';
613 print img_picto($langs->trans("Disabled"), 'switch_off');
614 print '</a>';
615 print "</td>";
616 }
617
618 // Default
619 print '<td class="center">';
620 if (getDolGlobalString('PROJECT_ADDON_PDF') == "$name") {
621 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=unsetdoc&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>';
622 //print img_picto($langs->trans("Default"), 'on');
623 } else {
624 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=setdoc&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>';
625 }
626 print '</td>';
627
628 // Info
629 $htmltooltip = ''.$langs->trans("Name").': '.$module->name;
630 $htmltooltip .= '<br>'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown"));
631 if ($module->type == 'pdf') {
632 $htmltooltip .= '<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
633 }
634 $htmltooltip .= '<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
635 $htmltooltip .= '<br>'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1);
636
637 print '<td class="center">';
638 print $form->textwithpicto('', $htmltooltip, 1, 'info');
639 print '</td>';
640
641 // Preview
642 print '<td class="center">';
643 if ($module->type == 'pdf') {
644 print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'">'.img_object($langs->trans("Preview"), 'bill').'</a>';
645 } else {
646 print img_object($langs->transnoentitiesnoconv("PreviewNotAvailable"), 'generic');
647 }
648 print '</td>';
649
650 print "</tr>\n";
651 }
652 }
653 }
654 }
655 }
656 }
657 }
658}
659
660print '</table>';
661print '</div>';
662print '<br>';
663
664
665
666if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
667 /*
668 * Modeles documents for Task
669 */
670
671 print load_fiche_titre($langs->trans("TaskModelModule"), '', '');
672
673 // Defini tableau def de modele
674 $type = 'project_task';
675 $def = array();
676
677 $sql = "SELECT nom";
678 $sql .= " FROM ".MAIN_DB_PREFIX."document_model";
679 $sql .= " WHERE type = '".$db->escape($type)."'";
680 $sql .= " AND entity = ".((int) $conf->entity);
681
682 $resql = $db->query($sql);
683 if ($resql) {
684 $i = 0;
685 $num_rows = $db->num_rows($resql);
686 while ($i < $num_rows) {
687 $array = $db->fetch_array($resql);
688 if (is_array($array)) {
689 array_push($def, $array[0]);
690 }
691 $i++;
692 }
693 } else {
695 }
696
697 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
698 print '<table class="noborder" width="100%">'."\n";
699 print '<tr class="liste_titre">'."\n";
700 print ' <td width="100">'.$langs->trans("Name")."</td>\n";
701 print " <td>".$langs->trans("Description")."</td>\n";
702 print '<td class="center" width="60">'.$langs->trans("Activated")."</td>\n";
703 print '<td class="center" width="60">'.$langs->trans("Default")."</td>\n";
704 print '<td class="center" width="80">'.$langs->trans("ShortInfo").'</td>';
705 print '<td class="center" width="80">'.$langs->trans("Preview").'</td>';
706 print "</tr>\n";
707
708 clearstatcache();
709
710 foreach ($dirmodels as $reldir) {
711 foreach (array('', '/doc') as $valdir) {
712 $dir = dol_buildpath($reldir."core/modules/project/task/".$valdir);
713
714 if (is_dir($dir)) {
715 $handle = opendir($dir);
716 if (is_resource($handle)) {
717 while (($file = readdir($handle)) !== false) {
718 $filelist[] = $file;
719 }
720 closedir($handle);
721 arsort($filelist);
722
723 foreach ($filelist as $file) {
724 if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) {
725 if (file_exists($dir.'/'.$file)) {
726 $name = substr($file, 4, dol_strlen($file) - 16);
727 $classname = substr($file, 0, dol_strlen($file) - 12);
728
729 require_once $dir.'/'.$file;
730 $module = new $classname($db);
731 '@phan-var-force ModelePDFTask $module';
732
733 $modulequalified = 1;
734 if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
735 $modulequalified = 0;
736 }
737 if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
738 $modulequalified = 0;
739 }
740
741 if ($modulequalified) {
742 print '<tr class="oddeven"><td width="100">';
743 print(empty($module->name) ? $name : $module->name);
744 print "</td><td>\n";
745 if (method_exists($module, 'info')) {
746 print $module->info($langs); // @phan-suppress-current-line PhanUndeclaredMethod
747 } else {
748 print $module->description;
749 }
750 print "</td>\n";
751
752 // Active
753 if (in_array($name, $def)) {
754 print '<td class="center">'."\n";
755 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=deltask&token='.newToken().'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'">';
756 print img_picto($langs->trans("Enabled"), 'switch_on');
757 print '</a>';
758 print "</td>";
759 } else {
760 print '<td class="center">'."\n";
761 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>';
762 print "</td>";
763 }
764
765 // Default
766 print '<td class="center">';
767 if (getDolGlobalString("PROJECT_TASK_ADDON_PDF", $name)) {
768 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>';
769 } else {
770 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>';
771 }
772 print '</td>';
773
774 // Info
775 $htmltooltip = ''.$langs->trans("Name").': '.$module->name;
776 $htmltooltip .= '<br>'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown"));
777 if ($module->type == 'pdf') {
778 $htmltooltip .= '<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
779 }
780 $htmltooltip .= '<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
781 $htmltooltip .= '<br>'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1);
782
783 print '<td class="center">';
784 print $form->textwithpicto('', $htmltooltip, 1, 'info');
785 print '</td>';
786
787 // Preview
788 print '<td class="center">';
789 if ($module->type == 'pdf') {
790 print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimentask&module='.$name.'">'.img_object($langs->trans("Preview"), 'bill').'</a>';
791 } else {
792 print img_object($langs->transnoentitiesnoconv("PreviewNotAvailable"), 'generic');
793 }
794 print '</td>';
795 print "</tr>\n";
796 }
797 }
798 }
799 }
800 }
801 }
802 }
803 }
804
805 print '</table>';
806 print '</div>';
807 print '<br>';
808}
809
810
811print load_fiche_titre($langs->trans("Other"), '', '');
812
813// Other options
814$form = new Form($db);
815
816print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
817print '<input type="hidden" name="token" value="'.newToken().'">';
818print '<input type="hidden" name="action" value="updateoptions">';
819print '<input type="hidden" name="page_y" value="">';
820
821print '<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
822print '<table class="noborder centpercent">';
823print '<tr class="liste_titre">';
824print "<td>".$langs->trans("Parameters")."</td>\n";
825print '<td></td>';
826print '</tr>'."\n";
827
828print '<tr class="oddeven">';
829print '<td>'.$langs->trans("UseSearchToSelectProject").'</td>';
830if (!$conf->use_javascript_ajax) {
831 print '<td class="nowrap right">';
832 print $langs->trans("NotAvailableWhenAjaxDisabled");
833 print "</td>";
834} else {
835 print '<td class="right">';
836 $arrval = array('0' => $langs->trans("No"),
837 '1' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 1).')',
838 '2' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 2).')',
839 '3' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 3).')',
840 );
841 print $form->selectarray("activate_PROJECT_USE_SEARCH_TO_SELECT", $arrval, getDolGlobalString("PROJECT_USE_SEARCH_TO_SELECT"));
842 print '<input type="submit" class="button small reposition" name="PROJECT_USE_SEARCH_TO_SELECT" value="'.$langs->trans("Modify").'">';
843 print "</td>";
844}
845print '</tr>';
846
847print '<tr class="oddeven">';
848print '<td>'.$langs->trans("AllowToSelectProjectFromOtherCompany").'</td>';
849print '<td class="right">';
850print '<input type="text" id="projectToSelect" name="projectToSelect" value="' . getDolGlobalString('PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY').'"/>&nbsp;';
851print $form->textwithpicto('', $langs->trans('AllowToLinkFromOtherCompany'));
852print '<input type="submit" class="button small reposition" name="PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY" value="'.$langs->trans("Modify").'">';
853print '</td>';
854print '</tr>';
855
856$key = 'PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE';
857echo '<tr class="oddeven">',
858'<td class="left">',
859$form->textwithpicto($langs->transnoentities($key), $langs->transnoentities($key . '_help')),
860'</td>',
861'<td class="right">',
862ajax_constantonoff($key),
863'</td>',
864'</tr>';
865
866print '<tr class="oddeven">';
867print '<td>'.$langs->trans("TimesheetPreventAfterFollowingMonths").'</td>';
868print '<td class="right">';
869print '<input type="number" class="width50" id="timesheetFreezeDuration" name="timesheetFreezeDuration" min="0" step="1" value="' . getDolGlobalString('PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS').'"/>&nbsp;';
870print '<input type="submit" class="button small reposition" name="PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS" value="'.$langs->trans("Modify").'">';
871print '</td>';
872print '</tr>';
873
874/* Generates a lot of confusion for users. Not visible by default.
875print '<tr class="oddeven">';
876print '<td class="left">';
877print $form->textwithpicto($langs->transnoentities('PROJECT_DISPLAY_LINKED_BY_CONTACT'), $langs->transnoentities('PROJECT_DISPLAY_LINKED_BY_CONTACT_help'));
878print '</td>';
879print '<td class="right">';
880print ajax_constantonoff('PROJECT_DISPLAY_LINKED_BY_CONTACT');
881print '</td>';
882print '</tr>';
883*/
884
885print '</table>';
886print '</div>';
887
888print '</form>';
889
890// End of page
891llxFooter();
892$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.
global $mysoc
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
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_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.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
yn($yesno, $format=1, $color=0)
Return yes or no in current language.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
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.
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:133
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.