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