dolibarr 21.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 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 if ($maskconstproject && preg_match('/_MASK$/', $maskconstproject)) {
75 $res = dolibarr_set_const($db, $maskconstproject, $maskproject, 'chaine', 0, '', $conf->entity);
76 }
77
78 if (!($res > 0)) {
79 $error++;
80 }
81
82 if (!$error) {
83 setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
84 } else {
85 setEventMessages($langs->trans("Error"), null, 'errors');
86 }
87}
88
89if ($action == 'updateMaskTask') {
90 $maskconstmasktask = GETPOST('maskconsttask', 'aZ09');
91 $masktaskt = GETPOST('masktask', 'alpha');
92 $res = 0;
93 if ($maskconstmasktask && preg_match('/_MASK$/', $maskconstmasktask)) {
94 $res = dolibarr_set_const($db, $maskconstmasktask, $masktaskt, 'chaine', 0, '', $conf->entity);
95 }
96
97 if (!($res > 0)) {
98 $error++;
99 }
100
101 if (!$error) {
102 setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
103 } else {
104 setEventMessages($langs->trans("Error"), null, 'errors');
105 }
106} elseif ($action == 'specimen') {
107 $modele = GETPOST('module', 'alpha');
108
109 $project = new Project($db);
110 $project->initAsSpecimen();
111
112 // Search template files
113 $file = '';
114 $classname = '';
115 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
116 foreach ($dirmodels as $reldir) {
117 $file = dol_buildpath($reldir."core/modules/project/doc/pdf_".$modele.".modules.php", 0);
118 if (file_exists($file)) {
119 $classname = "pdf_".$modele;
120 break;
121 }
122 }
123
124 if ($classname !== '') {
125 require_once $file;
126
127 $module = new $classname($db);
128 '@phan-var-force ModelePDFProjects $module';
131 if ($module->write_file($project, $langs) > 0) {
132 header("Location: ".DOL_URL_ROOT."/document.php?modulepart=project&file=SPECIMEN.pdf");
133 return;
134 } else {
135 setEventMessages($module->error, $module->errors, 'errors');
136 dol_syslog($module->error, LOG_ERR);
137 }
138 } else {
139 setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors');
140 dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR);
141 }
142} elseif ($action == 'specimentask') {
143 $modele = GETPOST('module', 'alpha');
144
145 $project = new Project($db);
146 $project->initAsSpecimen();
147
148 // Search template files
149 $file = '';
150 $classname = '';
151 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
152 foreach ($dirmodels as $reldir) {
153 $file = dol_buildpath($reldir."core/modules/project/task/doc/pdf_".$modele.".modules.php", 0);
154 if (file_exists($file)) {
155 $classname = "pdf_".$modele;
156 break;
157 }
158 }
159
160 if ($classname !== '') {
161 require_once $file;
162
163 $module = new $classname($db);
164 '@phan-var-force ModelePDFTask $module';
167 if ($module->write_file($project, $langs) > 0) {
168 header("Location: ".DOL_URL_ROOT."/document.php?modulepart=project_task&file=SPECIMEN.pdf");
169 return;
170 } else {
171 setEventMessages($module->error, $module->errors, 'errors');
172 dol_syslog($module->error, LOG_ERR);
173 }
174 } else {
175 setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors');
176 dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR);
177 }
178} elseif ($action == 'set') {
179 // Activate a model
180 $ret = addDocumentModel($value, $type, $label, $scandir);
181} elseif ($action == 'settask') {
182 // Activate a model for task
183 $ret = addDocumentModel($value, 'project_task', $label, $scandir);
184} elseif ($action == 'del') {
185 $ret = delDocumentModel($value, $type);
186 if ($ret > 0) {
187 if (getDolGlobalString('PROJECT_ADDON_PDF') == "$value") {
188 dolibarr_del_const($db, 'PROJECT_ADDON_PDF', $conf->entity);
189 }
190 }
191} elseif ($action == 'deltask') {
192 $ret = delDocumentModel($value, 'project_task');
193 if ($ret > 0) {
194 if (getDolGlobalString('PROJECT_TASK_ADDON_PDF') == "$value") {
195 dolibarr_del_const($db, 'PROJECT_TASK_ADDON_PDF', $conf->entity);
196 }
197 }
198} elseif ($action == 'setdoc') {
199 // Set default model
200 dolibarr_set_const($db, "PROJECT_ADDON_PDF", $value, 'chaine', 0, '', $conf->entity);
201
202 // On active le modele
203 $ret = delDocumentModel($value, $type);
204 if ($ret > 0) {
205 $ret = addDocumentModel($value, $type, $label, $scandir);
206 }
207} elseif ($action == 'setdoctask') {
208 if (dolibarr_set_const($db, "PROJECT_TASK_ADDON_PDF", $value, 'chaine', 0, '', $conf->entity)) {
209 // La constante qui a ete lue en avant du nouveau set
210 // on passe donc par une variable pour avoir un affichage coherent
211 $conf->global->PROJECT_TASK_ADDON_PDF = $value;
212 }
213
214 // On active le modele
215 $ret = delDocumentModel($value, 'project_task');
216 if ($ret > 0) {
217 $ret = addDocumentModel($value, 'project_task', $label, $scandir);
218 }
219} elseif ($action == 'setmod') {
220 // TODO Verifier si module numerotation choisi peut etre active
221 // par appel methode canBeActivated
222
223 dolibarr_set_const($db, "PROJECT_ADDON", $value, 'chaine', 0, '', $conf->entity);
224} elseif ($action == 'setmodtask') {
225 // TODO Verifier si module numerotation choisi peut etre active
226 // par appel methode canBeActivated
227
228 dolibarr_set_const($db, "PROJECT_TASK_ADDON", $value, 'chaine', 0, '', $conf->entity);
229} elseif ($action == 'updateoptions') {
230 if (GETPOST('PROJECT_USE_SEARCH_TO_SELECT')) {
231 $companysearch = GETPOST('activate_PROJECT_USE_SEARCH_TO_SELECT', 'alpha');
232 if (dolibarr_set_const($db, "PROJECT_USE_SEARCH_TO_SELECT", $companysearch, 'chaine', 0, '', $conf->entity)) {
233 $conf->global->PROJECT_USE_SEARCH_TO_SELECT = $companysearch;
234 }
235 }
236 if (GETPOST('PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY')) {
237 $projectToSelect = GETPOST('projectToSelect', 'alpha');
238 dolibarr_set_const($db, 'PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY', $projectToSelect, 'chaine', 0, '', $conf->entity); //Allow to disable this configuration if empty value
239 }
240 if (GETPOST('PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS')) {
241 $timesheetFreezeDuration = GETPOST('timesheetFreezeDuration', 'alpha');
242 dolibarr_set_const($db, 'PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS', intval($timesheetFreezeDuration), 'chaine', 0, '', $conf->entity); //Allow to disable this configuration if empty value
243 }
244} elseif (preg_match('/^(set|del)_?([A-Z_]+)$/', $action, $reg)) {
245 // Set boolean (on/off) constants
246 if (!dolibarr_set_const($db, $reg[2], ($reg[1] === 'set' ? '1' : '0'), 'chaine', 0, '', $conf->entity) > 0) {
247 dol_print_error($db);
248 }
249}
250
251/*
252 * View
253 */
254
255$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
256
257llxHeader("", $langs->trans("ProjectsSetup"), '', '', 0, 0, '', '', '', 'mod-project page-admin');
258
259$form = new Form($db);
260
261$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
262print load_fiche_titre($langs->trans("ProjectsSetup"), $linkback, 'title_setup');
263
265
266print dol_get_fiche_head($head, 'project', $langs->trans("Projects"), -1, 'project');
267
268
269
270// Main options
271$form = new Form($db);
272
273print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
274print '<input type="hidden" name="token" value="'.newToken().'">';
275print '<input type="hidden" name="action" value="setmainoptions">';
276
277print '<table class="noborder centpercent">';
278print '<tr class="liste_titre">';
279print "<td>".$langs->trans("Parameters")."</td>\n";
280print '<td class="right" width="60">'.$langs->trans("Value").'</td>'."\n";
281print '<td width="80">&nbsp;</td></tr>'."\n";
282
283print '<tr class="oddeven">';
284print '<td width="80%">'.$langs->trans("ManageOpportunitiesStatus").'</td>';
285print '<td width="60" class="right">';
286print ajax_constantonoff("PROJECT_USE_OPPORTUNITIES", array(), null, 0, 0, 1);
287print '</td><td class="right">';
288print "</td>";
289print '</tr>';
290
291
292print '<tr class="oddeven">';
293print '<td width="80%">'.$langs->trans("ManageTasks").'</td>';
294print '<td width="60" class="right">';
295print ajax_constantonoff("PROJECT_HIDE_TASKS", array(), null, 1);
296print '</td><td class="right">';
297print "</td>";
298print '</tr>';
299
300print '</table></form>';
301
302print '<br>';
303
304
305
306/*
307 * Projects Numbering model
308 */
309
310print load_fiche_titre($langs->trans("ProjectsNumberingModules"), '', '');
311
312print '<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
313print '<table class="noborder centpercent">';
314print '<tr class="liste_titre">';
315print '<td width="100">'.$langs->trans("Name").'</td>';
316print '<td>'.$langs->trans("Description").'</td>';
317print '<td>'.$langs->trans("Example").'</td>';
318print '<td class="center" width="60">'.$langs->trans("Activated").'</td>';
319print '<td class="center" width="80">'.$langs->trans("ShortInfo").'</td>';
320print "</tr>\n";
321
322clearstatcache();
323
324foreach ($dirmodels as $reldir) {
325 $dir = dol_buildpath($reldir."core/modules/project/");
326
327 if (is_dir($dir)) {
328 $handle = opendir($dir);
329 if (is_resource($handle)) {
330 while (($file = readdir($handle)) !== false) {
331 if (preg_match('/^(mod_.*)\.php$/i', $file, $reg)) {
332 $file = $reg[1];
333 $classname = substr($file, 4);
334
335 require_once $dir.$file.'.php';
336
337 $module = new $file();
338 '@phan-var-force ModeleNumRefProjects $module';
339
340 // Show modules according to features level
341 if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
342 continue;
343 }
344 if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
345 continue;
346 }
347
348 if ($module->isEnabled()) {
349 print '<tr class="oddeven"><td>'.$module->name."</td><td>\n";
350 print $module->info($langs);
351 print '</td>';
352
353 // Show example of numbering model
354 print '<td class="nowrap">';
355 $tmp = $module->getExample();
356 if (preg_match('/^Error/', $tmp)) {
357 $langs->load("errors");
358 print '<div class="error">'.$langs->trans($tmp).'</div>';
359 } elseif ($tmp == 'NotConfigured') {
360 print $langs->trans($tmp);
361 } else {
362 print $tmp;
363 }
364 print '</td>'."\n";
365
366 print '<td class="center">';
367 if (getDolGlobalString('PROJECT_ADDON') == 'mod_'.$classname) {
368 print img_picto($langs->trans("Activated"), 'switch_on');
369 } else {
370 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>';
371 }
372 print '</td>';
373
374 $project = new Project($db);
375 $project->initAsSpecimen();
376
377 // Info
378 $htmltooltip = '';
379 $htmltooltip .= ''.$langs->trans("Version").': <b>'.$module->getVersion().'</b><br>';
380 $nextval = $module->getNextValue($mysoc, $project);
381 if ((string) $nextval != $langs->trans("NotAvailable")) {
382 $htmltooltip .= ''.$langs->trans("NextValue").': ';
383 if ($nextval) {
384 $htmltooltip .= $nextval.'<br>';
385 } else {
386 $htmltooltip .= $langs->trans($module->error).'<br>';
387 }
388 }
389
390 print '<td class="center">';
391 print $form->textwithpicto('', $htmltooltip, 1, 0);
392 print '</td>';
393
394 print '</tr>';
395 }
396 }
397 }
398 closedir($handle);
399 }
400 }
401}
402
403print '</table>';
404print '</div>';
405print '<br>';
406
407if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
408 // Task numbering module
409 print load_fiche_titre($langs->trans("TasksNumberingModules"), '', '');
410
411 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
412 print '<table class="noborder centpercent">';
413 print '<tr class="liste_titre">';
414 print '<td width="100">'.$langs->trans("Name").'</td>';
415 print '<td>'.$langs->trans("Description").'</td>';
416 print '<td>'.$langs->trans("Example").'</td>';
417 print '<td class="center" width="60">'.$langs->trans("Activated").'</td>';
418 print '<td class="center" width="80">'.$langs->trans("ShortInfo").'</td>';
419 print "</tr>\n";
420
421 clearstatcache();
422
423 foreach ($dirmodels as $reldir) {
424 $dir = dol_buildpath($reldir."core/modules/project/task/");
425
426 if (is_dir($dir)) {
427 $handle = opendir($dir);
428 if (is_resource($handle)) {
429 while (($file = readdir($handle)) !== false) {
430 if (preg_match('/^(mod_.*)\.php$/i', $file, $reg)) {
431 $file = $reg[1];
432 $classname = substr($file, 4);
433
434 require_once $dir.$file.'.php';
435
436 $module = new $file();
437 '@phan-var-force ModeleNumRefTask $module';
440 // Show modules according to features level
441 if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
442 continue;
443 }
444 if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
445 continue;
446 }
447
448 if ($module->isEnabled()) {
449 print '<tr class="oddeven"><td>'.$module->name."</td><td>\n";
450 print $module->info($langs);
451 print '</td>';
452
453 // Show example of numbering module
454 print '<td class="nowrap">';
455 $tmp = $module->getExample();
456 if (preg_match('/^Error/', $tmp)) {
457 $langs->load("errors");
458 print '<div class="error">'.$langs->trans($tmp).'</div>';
459 } elseif ($tmp == 'NotConfigured') {
460 print $langs->trans($tmp);
461 } else {
462 print $tmp;
463 }
464 print '</td>'."\n";
465
466 print '<td class="center">';
467 if ($conf->global->PROJECT_TASK_ADDON == 'mod_'.$classname) {
468 print img_picto($langs->trans("Activated"), 'switch_on');
469 } else {
470 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>';
471 }
472 print '</td>';
473
474 $project = new Project($db);
475 $project->initAsSpecimen();
476
477 // Info
478 $htmltooltip = '';
479 $htmltooltip .= ''.$langs->trans("Version").': <b>'.$module->getVersion().'</b><br>';
480 $nextval = $module->getNextValue($mysoc, $project);
481 if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval
482 $htmltooltip .= ''.$langs->trans("NextValue").': ';
483 if ($nextval) {
484 $htmltooltip .= $nextval.'<br>';
485 } else {
486 $htmltooltip .= $langs->trans($module->error).'<br>';
487 }
488 }
489
490 print '<td class="center">';
491 print $form->textwithpicto('', $htmltooltip, 1, 0);
492 print '</td>';
493
494 print '</tr>';
495 }
496 }
497 }
498 closedir($handle);
499 }
500 }
501 }
502
503 print '</table>';
504 print '</div>';
505 print '<br>';
506}
507
508
509/*
510 * Document templates generators
511 */
512
513print load_fiche_titre($langs->trans("ProjectsModelModule"), '', '');
514
515// Defini tableau def de modele
516$type = 'project';
517$def = array();
518
519$sql = "SELECT nom";
520$sql .= " FROM ".MAIN_DB_PREFIX."document_model";
521$sql .= " WHERE type = '".$db->escape($type)."'";
522$sql .= " AND entity = ".$conf->entity;
523
524$resql = $db->query($sql);
525if ($resql) {
526 $i = 0;
527 $num_rows = $db->num_rows($resql);
528 while ($i < $num_rows) {
529 $array = $db->fetch_array($resql);
530 if (is_array($array)) {
531 array_push($def, $array[0]);
532 }
533 $i++;
534 }
535} else {
536 dol_print_error($db);
537}
538
539print '<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
540print '<table class="noborder" width="100%">'."\n";
541print '<tr class="liste_titre">'."\n";
542print ' <td width="100">'.$langs->trans("Name")."</td>\n";
543print " <td>".$langs->trans("Description")."</td>\n";
544print '<td class="center" width="60">'.$langs->trans("Activated")."</td>\n";
545print '<td class="center" width="60">'.$langs->trans("Default")."</td>\n";
546print '<td class="center" width="80">'.$langs->trans("ShortInfo").'</td>';
547print '<td class="center" width="80">'.$langs->trans("Preview").'</td>';
548print "</tr>\n";
549
550clearstatcache();
551
552$filelist = array();
553foreach ($dirmodels as $reldir) {
554 foreach (array('', '/doc') as $valdir) {
555 $dir = dol_buildpath($reldir."core/modules/project/".$valdir);
556
557 if (is_dir($dir)) {
558 $handle = opendir($dir);
559 if (is_resource($handle)) {
560 while (($file = readdir($handle)) !== false) {
561 $filelist[] = $file;
562 }
563 closedir($handle);
564 arsort($filelist);
565
566 foreach ($filelist as $file) {
567 if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) {
568 if (file_exists($dir.'/'.$file)) {
569 $name = substr($file, 4, dol_strlen($file) - 16);
570 $classname = substr($file, 0, dol_strlen($file) - 12);
571
572 require_once $dir.'/'.$file;
573 $module = new $classname($db);
574 '@phan-var-force ModelePDFProjects $module';
575
576 $modulequalified = 1;
577 if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
578 $modulequalified = 0;
579 }
580 if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
581 $modulequalified = 0;
582 }
583
584 if ($modulequalified) {
585 print '<tr class="oddeven"><td width="100">';
586 print(empty($module->name) ? $name : $module->name);
587 print "</td><td>\n";
588 if (method_exists($module, 'info')) {
589 print $module->info($langs); // @phan-suppress-current-line PhanUndeclaredMethod
590 } else {
591 print $module->description;
592 }
593 print "</td>\n";
594
595 // Active
596 if (in_array($name, $def)) {
597 print "<td class=\"center\">\n";
598 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=del&token='.newToken().'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'">';
599 print img_picto($langs->trans("Enabled"), 'switch_on');
600 print '</a>';
601 print "</td>";
602 } else {
603 print "<td class=\"center\">\n";
604 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=set&token='.newToken().'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>';
605 print "</td>";
606 }
607
608 // Default
609 print "<td class=\"center\">";
610 if (getDolGlobalString('PROJECT_ADDON_PDF') == "$name") {
611 print img_picto($langs->trans("Default"), 'on');
612 } else {
613 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>';
614 }
615 print '</td>';
616
617 // Info
618 $htmltooltip = ''.$langs->trans("Name").': '.$module->name;
619 $htmltooltip .= '<br>'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown"));
620 if ($module->type == 'pdf') {
621 $htmltooltip .= '<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
622 }
623 $htmltooltip .= '<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
624 $htmltooltip .= '<br>'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1);
625
626 print '<td class="center">';
627 print $form->textwithpicto('', $htmltooltip, 1, 0);
628 print '</td>';
629
630 // Preview
631 print '<td class="center">';
632 if ($module->type == 'pdf') {
633 print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'">'.img_object($langs->trans("Preview"), 'bill').'</a>';
634 } else {
635 print img_object($langs->trans("PreviewNotAvailable"), 'generic');
636 }
637 print '</td>';
638
639 print "</tr>\n";
640 }
641 }
642 }
643 }
644 }
645 }
646 }
647}
648
649print '</table>';
650print '</div>';
651print '<br>';
652
653
654
655if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
656 /*
657 * Modeles documents for Task
658 */
659
660 print load_fiche_titre($langs->trans("TaskModelModule"), '', '');
661
662 // Defini tableau def de modele
663 $type = 'project_task';
664 $def = array();
665
666 $sql = "SELECT nom";
667 $sql .= " FROM ".MAIN_DB_PREFIX."document_model";
668 $sql .= " WHERE type = '".$db->escape($type)."'";
669 $sql .= " AND entity = ".$conf->entity;
670
671 $resql = $db->query($sql);
672 if ($resql) {
673 $i = 0;
674 $num_rows = $db->num_rows($resql);
675 while ($i < $num_rows) {
676 $array = $db->fetch_array($resql);
677 if (is_array($array)) {
678 array_push($def, $array[0]);
679 }
680 $i++;
681 }
682 } else {
683 dol_print_error($db);
684 }
685
686 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
687 print '<table class="noborder" width="100%">'."\n";
688 print '<tr class="liste_titre">'."\n";
689 print ' <td width="100">'.$langs->trans("Name")."</td>\n";
690 print " <td>".$langs->trans("Description")."</td>\n";
691 print '<td class="center" width="60">'.$langs->trans("Activated")."</td>\n";
692 print '<td class="center" width="60">'.$langs->trans("Default")."</td>\n";
693 print '<td class="center" width="80">'.$langs->trans("ShortInfo").'</td>';
694 print '<td class="center" width="80">'.$langs->trans("Preview").'</td>';
695 print "</tr>\n";
696
697 clearstatcache();
698
699 foreach ($dirmodels as $reldir) {
700 foreach (array('', '/doc') as $valdir) {
701 $dir = dol_buildpath($reldir."core/modules/project/task/".$valdir);
702
703 if (is_dir($dir)) {
704 $handle = opendir($dir);
705 if (is_resource($handle)) {
706 while (($file = readdir($handle)) !== false) {
707 $filelist[] = $file;
708 }
709 closedir($handle);
710 arsort($filelist);
711
712 foreach ($filelist as $file) {
713 if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) {
714 if (file_exists($dir.'/'.$file)) {
715 $name = substr($file, 4, dol_strlen($file) - 16);
716 $classname = substr($file, 0, dol_strlen($file) - 12);
717
718 require_once $dir.'/'.$file;
719 $module = new $classname($db);
720 '@phan-var-force ModelePDFTask $module';
721
722 $modulequalified = 1;
723 if ($module->version == 'development' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
724 $modulequalified = 0;
725 }
726 if ($module->version == 'experimental' && getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1) {
727 $modulequalified = 0;
728 }
729
730 if ($modulequalified) {
731 print '<tr class="oddeven"><td width="100">';
732 print(empty($module->name) ? $name : $module->name);
733 print "</td><td>\n";
734 if (method_exists($module, 'info')) {
735 print $module->info($langs); // @phan-suppress-current-line PhanUndeclaredMethod
736 } else {
737 print $module->description;
738 }
739 print "</td>\n";
740
741 // Active
742 if (in_array($name, $def)) {
743 print '<td class="center">'."\n";
744 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=deltask&token='.newToken().'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'">';
745 print img_picto($langs->trans("Enabled"), 'switch_on');
746 print '</a>';
747 print "</td>";
748 } else {
749 print '<td class="center">'."\n";
750 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>';
751 print "</td>";
752 }
753
754 // Default
755 print '<td class="center">';
756 if ($conf->global->PROJECT_TASK_ADDON_PDF == "$name") {
757 print img_picto($langs->trans("Default"), 'on');
758 } else {
759 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>';
760 }
761 print '</td>';
762
763 // Info
764 $htmltooltip = ''.$langs->trans("Name").': '.$module->name;
765 $htmltooltip .= '<br>'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown"));
766 if ($module->type == 'pdf') {
767 $htmltooltip .= '<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
768 }
769 $htmltooltip .= '<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
770 $htmltooltip .= '<br>'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1);
771
772 print '<td class="center">';
773 print $form->textwithpicto('', $htmltooltip, 1, 0);
774 print '</td>';
775
776 // Preview
777 print '<td class="center">';
778 if ($module->type == 'pdf') {
779 print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimentask&module='.$name.'">'.img_object($langs->trans("Preview"), 'bill').'</a>';
780 } else {
781 print img_object($langs->trans("PreviewNotAvailable"), 'generic');
782 }
783 print '</td>';
784 print "</tr>\n";
785 }
786 }
787 }
788 }
789 }
790 }
791 }
792 }
793
794 print '</table>';
795 print '</div>';
796 print '<br>';
797}
798
799
800print load_fiche_titre($langs->trans("Other"), '', '');
801
802// Other options
803$form = new Form($db);
804
805print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
806print '<input type="hidden" name="token" value="'.newToken().'">';
807print '<input type="hidden" name="action" value="updateoptions">';
808print '<input type="hidden" name="page_y" value="">';
809
810print '<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
811print '<table class="noborder centpercent">';
812print '<tr class="liste_titre">';
813print "<td>".$langs->trans("Parameters")."</td>\n";
814print '<td class="right" width="60">'.$langs->trans("Value").'</td>'."\n";
815print '<td width="80">&nbsp;</td></tr>'."\n";
816
817print '<tr class="oddeven">';
818print '<td width="80%">'.$langs->trans("UseSearchToSelectProject").'</td>';
819if (!$conf->use_javascript_ajax) {
820 print '<td class="nowrap right" colspan="2">';
821 print $langs->trans("NotAvailableWhenAjaxDisabled");
822 print "</td>";
823} else {
824 print '<td width="60" class="right">';
825 $arrval = array('0' => $langs->trans("No"),
826 '1' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 1).')',
827 '2' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 2).')',
828 '3' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 3).')',
829 );
830 print $form->selectarray("activate_PROJECT_USE_SEARCH_TO_SELECT", $arrval, getDolGlobalString("PROJECT_USE_SEARCH_TO_SELECT"));
831 print '</td><td class="right">';
832 print '<input type="submit" class="button small reposition" name="PROJECT_USE_SEARCH_TO_SELECT" value="'.$langs->trans("Modify").'">';
833 print "</td>";
834}
835print '</tr>';
836
837print '<tr class="oddeven">';
838print '<td>'.$langs->trans("AllowToSelectProjectFromOtherCompany").'</td>';
839
840print '<td class="right" width="60" colspan="2">';
841print '<input type="text" id="projectToSelect" name="projectToSelect" value="' . getDolGlobalString('PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY').'"/>&nbsp;';
842print $form->textwithpicto('', $langs->trans('AllowToLinkFromOtherCompany'));
843print '<input type="submit" class="button small reposition" name="PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY" value="'.$langs->trans("Modify").'">';
844print '</td>';
845print '</tr>';
846
847$key = 'PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE';
848echo '<tr class="oddeven">',
849'<td class="left">',
850$form->textwithpicto($langs->transnoentities($key), $langs->transnoentities($key . '_help')),
851'</td>',
852'<td class="right" colspan="2">',
853ajax_constantonoff($key),
854'</td>',
855'</tr>';
856
857print '<tr class="oddeven">';
858print '<td>'.$langs->trans("TimesheetPreventAfterFollowingMonths").'</td>';
859
860print '<td class="right" width="60" colspan="2">';
861print '<input type="number" class="width50" id="timesheetFreezeDuration" name="timesheetFreezeDuration" min="0" step="1" value="' . getDolGlobalString('PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS').'"/>&nbsp;';
862print '<input type="submit" class="button small reposition" name="PROJECT_TIMESHEET_PREVENT_AFTER_MONTHS" value="'.$langs->trans("Modify").'">';
863print '</td>';
864print '</tr>';
865
866print '<tr class="oddeven">';
867print '<td class="left">';
868print $form->textwithpicto($langs->transnoentities('PROJECT_DISPLAY_LINKED_BY_CONTACT'), $langs->transnoentities('PROJECT_DISPLAY_LINKED_BY_CONTACT_help'));
869print '</td>';
870print '<td class="right" colspan="2">';
871print ajax_constantonoff('PROJECT_DISPLAY_LINKED_BY_CONTACT');
872print '</td>';
873print '</tr>';
874
875print '</table>';
876print '</div>';
877
878print '</form>';
879
880// End of page
881llxFooter();
882$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.
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:71
Class to manage generation of HTML components Only common components must be here.
Class to manage projects.
llxFooter()
Footer empty.
Definition document.php:107
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
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)
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)
Show tabs of a record.
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'.
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...
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.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
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:152
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.