dolibarr  7.0.0-beta
modulehelp.php
1 <?php
2 /* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2017 Regis Houssin <regis.houssin@capnetworks.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
24 //if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1');
25 //if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1');
26 //if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1');
27 //if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1');
28 //if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test
29 //if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data
30 //if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test
31 if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu
32 //if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php
33 //if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1');
34 //if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session)
35 
36 require '../main.inc.php';
37 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
38 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
39 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
40 
41 $langs->load("errors");
42 $langs->load("admin");
43 
44 $mode=GETPOST('mode', 'alpha');
45 $action=GETPOST('action','alpha');
46 $id = GETPOST('id', 'int');
47 if (empty($mode)) $mode='desc';
48 
49 if (! $user->admin)
51 
52 
53 
54 /*
55  * Actions
56  */
57 
58 // Nothing
59 
60 
61 /*
62  * View
63  */
64 
65 $form = new Form($db);
66 
67 $help_url='EN:First_setup|FR:Premiers_param├ętrages|ES:Primeras_configuraciones';
68 llxHeader('',$langs->trans("Setup"),$help_url);
69 
70 print '<!-- Force style container -->'."\n".'<style>
71 .id-container {
72  width: 100%;
73 }
74 </style>';
75 
76 $arrayofnatures=array('core'=>$langs->transnoentitiesnoconv("Core"), 'external'=>$langs->transnoentitiesnoconv("External").' - '.$langs->trans("AllPublishers"));
77 
78 // Search modules dirs
79 $modulesdir = dolGetModulesDirs();
80 
81 
82 $filename = array();
83 $modules = array();
84 $orders = array();
85 $categ = array();
86 $dirmod = array();
87 $i = 0; // is a sequencer of modules found
88 $j = 0; // j is module number. Automatically affected if module number not defined.
89 $modNameLoaded=array();
90 
91 foreach ($modulesdir as $dir)
92 {
93  // Load modules attributes in arrays (name, numero, orders) from dir directory
94  //print $dir."\n<br>";
95  dol_syslog("Scan directory ".$dir." for module descriptor files (modXXX.class.php)");
96  $handle=@opendir($dir);
97  if (is_resource($handle))
98  {
99  while (($file = readdir($handle))!==false)
100  {
101  //print "$i ".$file."\n<br>";
102  if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod' && substr($file, dol_strlen($file) - 10) == '.class.php')
103  {
104  $modName = substr($file, 0, dol_strlen($file) - 10);
105 
106  if ($modName)
107  {
108  if (! empty($modNameLoaded[$modName]))
109  {
110  $mesg="Error: Module ".$modName." was found twice: Into ".$modNameLoaded[$modName]." and ".$dir.". You probably have an old file on your disk.<br>";
111  setEventMessages($mesg, null, 'warnings');
112  dol_syslog($mesg, LOG_ERR);
113  continue;
114  }
115 
116  try
117  {
118  $res=include_once $dir.$file;
119  if (class_exists($modName))
120  {
121  try {
122  $objMod = new $modName($db);
123  $modNameLoaded[$modName]=$dir;
124 
125  if (! $objMod->numero > 0 && $modName != 'modUser')
126  {
127  dol_syslog('The module descriptor '.$modName.' must have a numero property', LOG_ERR);
128  }
129  $j = $objMod->numero;
130 
131  $modulequalified=1;
132 
133  // We discard modules according to features level (PS: if module is activated we always show it)
134  $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',get_class($objMod)));
135  if ($objMod->version == 'development' && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL < 2))) $modulequalified=0;
136  if ($objMod->version == 'experimental' && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL < 1))) $modulequalified=0;
137  if (preg_match('/deprecated/', $objMod->version) && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL >= 0))) $modulequalified=0;
138 
139  // We discard modules according to property disabled
140  if (! empty($objMod->hidden)) $modulequalified=0;
141 
142  if ($modulequalified > 0)
143  {
144  $publisher=dol_escape_htmltag($objMod->getPublisher());
145  $external=($objMod->isCoreOrExternalModule() == 'external');
146  if ($external)
147  {
148  if ($publisher)
149  {
150  $arrayofnatures['external_'.$publisher]=$langs->trans("External").' - '.$publisher;
151  }
152  else
153  {
154  $arrayofnatures['external_']=$langs->trans("External").' - '.$langs->trans("UnknownPublishers");
155  }
156  }
157  ksort($arrayofnatures);
158  }
159 
160  // Define array $categ with categ with at least one qualified module
161  if ($modulequalified > 0)
162  {
163  $modules[$i] = $objMod;
164  $filename[$i]= $modName;
165 
166  $special = $objMod->special;
167 
168  // Gives the possibility to the module, to provide his own family info and position of this family
169  if (is_array($objMod->familyinfo) && !empty($objMod->familyinfo)) {
170  if (!is_array($familyinfo)) $familyinfo=array();
171  $familyinfo = array_merge($familyinfo, $objMod->familyinfo);
172  $familykey = key($objMod->familyinfo);
173  } else {
174  $familykey = $objMod->family;
175  }
176 
177  $moduleposition = ($objMod->module_position?$objMod->module_position:'500');
178  if ($moduleposition == 500 && ($objMod->isCoreOrExternalModule() == 'external'))
179  {
180  $moduleposition = 800;
181  }
182 
183  if ($special == 1) $familykey='interface';
184 
185  $orders[$i] = $familyinfo[$familykey]['position']."_".$familykey."_".$moduleposition."_".$j; // Sort by family, then by module position then number
186  $dirmod[$i] = $dir;
187  //print $i.'-'.$dirmod[$i].'<br>';
188  // Set categ[$i]
189  $specialstring = isset($specialtostring[$special])?$specialtostring[$special]:'unknown';
190  if ($objMod->version == 'development' || $objMod->version == 'experimental') $specialstring='expdev';
191  if (isset($categ[$specialstring])) $categ[$specialstring]++; // Array of all different modules categories
192  else $categ[$specialstring]=1;
193  $j++;
194  $i++;
195  }
196  else dol_syslog("Module ".get_class($objMod)." not qualified");
197  }
198  catch(Exception $e)
199  {
200  dol_syslog("Failed to load ".$dir.$file." ".$e->getMessage(), LOG_ERR);
201  }
202  }
203  else
204  {
205  print "Warning bad descriptor file : ".$dir.$file." (Class ".$modName." not found into file)<br>";
206  }
207  }
208  catch(Exception $e)
209  {
210  dol_syslog("Failed to load ".$dir.$file." ".$e->getMessage(), LOG_ERR);
211  }
212  }
213  }
214  }
215  closedir($handle);
216  }
217  else
218  {
219  dol_syslog("htdocs/admin/modulehelp.php: Failed to open directory ".$dir.". See permission and open_basedir option.", LOG_WARNING);
220  }
221 }
222 
223 asort($orders);
224 //var_dump($orders);
225 //var_dump($categ);
226 //var_dump($modules);
227 
228 
229 $i=0;
230 foreach($orders as $tmpkey => $tmpvalue)
231 {
232  $objMod = $modules[$tmpkey];
233  if ($objMod->numero == $id)
234  {
235  $key = $i;
236  $modName = $filename[$tmpkey];
237  $dirofmodule = $dirmod[$tmpkey];
238  break;
239  }
240  $i++;
241 }
242 $value = $orders[$key];
243 $special = $objMod->special;
244 $tab=explode('_',$value);
245 $familyposition=$tab[0]; $familykey=$tab[1]; $module_position=$tab[2]; $numero=$tab[3];
246 
247 
248 
249 $h = 0;
250 
251 $head[$h][0] = DOL_URL_ROOT."/admin/modulehelp.php?id=".$id.'&mode=desc';
252 $head[$h][1] = $langs->trans("Description");
253 $head[$h][2] = 'desc';
254 $h++;
255 
256 $head[$h][0] = DOL_URL_ROOT."/admin/modulehelp.php?id=".$id.'&mode=feature';
257 $head[$h][1] = $langs->trans("TechnicalServicesProvided");
258 $head[$h][2] = 'feature';
259 $h++;
260 
261 if ($objMod->isCoreOrExternalModule() == 'external')
262 {
263  $head[$h][0] = DOL_URL_ROOT."/admin/modulehelp.php?id=".$id.'&mode=changelog';
264  $head[$h][1] = $langs->trans("ChangeLog");
265  $head[$h][2] = 'changelog';
266  $h++;
267 }
268 
269 // Check filters
270 $modulename=$objMod->getName();
271 $moduledesc=$objMod->getDesc();
272 $moduleauthor=$objMod->getPublisher();
273 $moduledir=strtolower(preg_replace('/^mod/i','',get_class($objMod)));
274 
275 
276 print '<div class="centpercent">';
277 
278 print load_fiche_titre(($modulename?$modulename:$moduledesc), $moreinfo, 'object_'.$objMod->picto);
279 print '<br>';
280 
281 dol_fiche_head($head, $mode, $title, -1);
282 
283 if (! $modulename)
284 {
285  dol_syslog("Error for module ".$key." - Property name of module looks empty", LOG_WARNING);
286 }
287 
288 $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',get_class($objMod)));
289 
290 // Load all lang files of module
291 if (isset($objMod->langfiles) && is_array($objMod->langfiles))
292 {
293  foreach($objMod->langfiles as $domain)
294  {
295  $langs->load($domain);
296  }
297 }
298 
299 
300 
301 
302 // Version (with picto warning or not)
303 $version=$objMod->getVersion(0);
304 $versiontrans='';
305 if (preg_match('/development/i', $version)) $versiontrans.=img_warning($langs->trans("Development"), 'style="float: left"');
306 if (preg_match('/experimental/i', $version)) $versiontrans.=img_warning($langs->trans("Experimental"), 'style="float: left"');
307 if (preg_match('/deprecated/i', $version)) $versiontrans.=img_warning($langs->trans("Deprecated"), 'style="float: left"');
308 $versiontrans.=$objMod->getVersion(1);
309 
310 // Define imginfo
311 $imginfo="info";
312 if ($objMod->isCoreOrExternalModule() == 'external')
313 {
314  $imginfo="info_black";
315 }
316 
317 // Define text of description of module
318 $text='';
319 
320 if ($mode == 'desc')
321 {
322  if ($moduledesc) $text.=$moduledesc.'<br><br>';
323 
324  $text.='<strong>'.$langs->trans("Version").':</strong> '.$version;
325 
326  $textexternal='';
327  if ($objMod->isCoreOrExternalModule() == 'external')
328  {
329  $textexternal.='<br><strong>'.$langs->trans("Origin").':</strong> '.$langs->trans("ExternalModule",$dirofmodule);
330  if ($objMod->editor_name != 'dolibarr') $textexternal.='<br><strong>'.$langs->trans("Publisher").':</strong> '.(empty($objMod->editor_name)?$langs->trans("Unknown"):$objMod->editor_name);
331  if (! empty($objMod->editor_url) && ! preg_match('/dolibarr\.org/i',$objMod->editor_url)) $textexternal.='<br><strong>'.$langs->trans("Url").':</strong> <a href="'.$objMod->editor_url.'" target="_blank">'.$objMod->editor_url.'</a>';
332  $text.=$textexternal;
333  $text.='<br>';
334  }
335  else
336  {
337  $text.='<br><strong>'.$langs->trans("Origin").':</strong> '.$langs->trans("Core").'<br>';
338  }
339  $text.='<br><strong>'.$langs->trans("LastActivationDate").':</strong> ';
340  if (! empty($conf->global->$const_name)) $text.=dol_print_date($objMod->getLastActivationDate(), 'dayhour');
341  else $text.=$langs->trans("Disabled");
342  $text.='<br>';
343 
344  $tmp = $objMod->getLastActivationInfo();
345  $authorid = $tmp['authorid'];
346  if ($authorid > 0)
347  {
348  $tmpuser = new User($db);
349  $tmpuser->fetch($authorid);
350  $text.='<strong>'.$langs->trans("LastActivationAuthor").':</strong> ';
351  $text.= $tmpuser->getNomUrl(1);
352  $text.='<br>';
353  }
354  $ip = $tmp['ip'];
355  if ($ip)
356  {
357  $text.='<strong>'.$langs->trans("LastActivationIP").':</strong> ';
358  $text.= $ip;
359  $text.='<br>';
360  }
361 
362  $moduledesclong=$objMod->getDescLong();
363  if ($moduledesclong) $text.='<br><hr><div class="moduledesclong">'.$moduledesclong.'<div>';
364 }
365 
366 if ($mode == 'feature')
367 {
368  $text.='<br><strong>'.$langs->trans("DependsOn").':</strong> ';
369  if (count($objMod->depends)) $text.=join(',', $objMod->depends);
370  else $text.=$langs->trans("None");
371  $text.='<br><strong>'.$langs->trans("RequiredBy").':</strong> ';
372  if (count($objMod->requiredby)) $text.=join(',', $objMod->requiredby);
373  else $text.=$langs->trans("None");
374 
375  $text.='<br><br>';
376 
377  $text.='<br><strong>'.$langs->trans("AddDataTables").':</strong> ';
378  $sqlfiles = dol_dir_list(dol_buildpath($moduledir.'/sql/'), 'files', 0, 'llx.*\.sql', array('\.key\.sql'));
379  if (count($sqlfiles) > 0)
380  {
381  $text.=$langs->trans("Yes").' (';
382  $i=0;
383  foreach($sqlfiles as $val)
384  {
385  $text.=($i?', ':'').preg_replace('/\.sql$/','',preg_replace('/llx_/','',$val['name']));
386  $i++;
387  }
388  $text.=')';
389  }
390  else $text.=$langs->trans("No");
391 
392  $text.='<br>';
393 
394  $text.='<br><strong>'.$langs->trans("AddDictionaries").':</strong> ';
395  if (isset($objMod->dictionaries) && isset($objMod->dictionaries['tablib']) && is_array($objMod->dictionaries['tablib']) && count($objMod->dictionaries['tablib']))
396  {
397  $i=0;
398  foreach($objMod->dictionaries['tablib'] as $val)
399  {
400  $text.=($i?', ':'').$val;
401  $i++;
402  }
403  }
404  else $text.=$langs->trans("No");
405 
406  $text.='<br>';
407 
408  $text.='<br><strong>'.$langs->trans("AddData").':</strong> ';
409  $filedata = dol_buildpath($moduledir.'/sql/data.sql');
410  if (dol_is_file($filedata))
411  {
412  $text.=$langs->trans("Yes").' ('.$moduledir.'/sql/data.sql'.')';
413  }
414  else $text.=$langs->trans("No");
415 
416  $text.='<br>';
417 
418  $text.='<br><strong>'.$langs->trans("AddRemoveTabs").':</strong> ';
419  if (isset($objMod->tabs) && is_array($objMod->tabs) && count($objMod->tabs))
420  {
421  $i=0;
422  foreach($objMod->tabs as $val)
423  {
424  if (is_array($val)) $val=$val['data'];
425  if (is_string($val))
426  {
427  $tmp=explode(':',$val,3);
428  $text.=($i?', ':'').$tmp[0].':'.$tmp[1];
429  $i++;
430  }
431  }
432  }
433  else $text.=$langs->trans("No");
434 
435  $text.='<br>';
436 
437  $text.='<br><strong>'.$langs->trans("AddModels").':</strong> ';
438  if (isset($objMod->module_parts) && isset($objMod->module_parts['models']) && $objMod->module_parts['models'])
439  {
440  $text.=$langs->trans("Yes");
441  }
442  else $text.=$langs->trans("No");
443 
444  $text.='<br>';
445 
446  $text.='<br><strong>'.$langs->trans("AddSubstitutions").':</strong> ';
447  if (isset($objMod->module_parts) && isset($objMod->module_parts['substitutions']) && $objMod->module_parts['substitutions'])
448  {
449  $text.=$langs->trans("Yes");
450  }
451  else $text.=$langs->trans("No");
452 
453  $text.='<br>';
454 
455  $text.='<br><strong>'.$langs->trans("AddSheduledJobs").':</strong> ';
456  if (isset($objMod->cronjobs) && is_array($objMod->cronjobs) && count($objMod->cronjobs))
457  {
458  $i=0;
459  foreach($objMod->cronjobs as $val)
460  {
461  $text.=($i?', ':'').($val['label']);
462  $i++;
463  }
464  }
465  else $text.=$langs->trans("No");
466 
467  $text.='<br>';
468 
469  $text.='<br><strong>'.$langs->trans("AddTriggers").':</strong> ';
470  $moreinfoontriggerfile='';
471  if (isset($objMod->module_parts) && isset($objMod->module_parts['triggers']) && $objMod->module_parts['triggers'])
472  {
473  $yesno='Yes';
474  }
475  else
476  {
477  $yesno='No';
478  }
479  require_once DOL_DOCUMENT_ROOT.'/core/class/interfaces.class.php';
480  $interfaces = new Interfaces($db);
481  $triggers = $interfaces->getTriggersList(array((($objMod->isCoreOrExternalModule() == 'external')?'/'.$moduledir:'').'/core/triggers'));
482  foreach($triggers as $triggercursor)
483  {
484  if ($triggercursor['module'] == $moduledir)
485  {
486  $yesno='Yes';
487  $moreinfoontriggerfile=' ('.$triggercursor['relpath'].')';
488  }
489  }
490 
491  $text.=$langs->trans($yesno).$moreinfoontriggerfile;
492 
493  $text.='<br>';
494 
495  $text.='<br><strong>'.$langs->trans("AddBoxes").':</strong> ';
496  if (isset($objMod->boxes) && is_array($objMod->boxes) && count($objMod->boxes))
497  {
498  $i=0;
499  foreach($objMod->boxes as $val)
500  {
501  $text.=($i?', ':'').($val['file']?$val['file']:$val[0]);
502  $i++;
503  }
504  }
505  else $text.=$langs->trans("No");
506 
507  $text.='<br>';
508 
509  $text.='<br><strong>'.$langs->trans("AddHooks").':</strong> ';
510  if (isset($objMod->module_parts) && is_array($objMod->module_parts['hooks']) && count($objMod->module_parts['hooks']))
511  {
512  $i=0;
513  foreach($objMod->module_parts['hooks'] as $key => $val)
514  {
515  if ($key === 'entity') continue;
516 
517  // For special values
518  if ($key === 'data')
519  {
520  if (is_array($val))
521  {
522  foreach($val as $value)
523  {
524  $text.=($i?', ':'').($value);
525  $i++;
526  }
527 
528  continue;
529  }
530  }
531 
532  $text.=($i?', ':'').($val);
533  $i++;
534  }
535  }
536  else $text.=$langs->trans("No");
537 
538  $text.='<br>';
539 
540  $text.='<br><strong>'.$langs->trans("AddPermissions").':</strong> ';
541  if (isset($objMod->rights) && is_array($objMod->rights) && count($objMod->rights))
542  {
543  $i=0;
544  foreach($objMod->rights as $val)
545  {
546  $text.=($i?', ':'').($val[1]);
547  $i++;
548  }
549  }
550  else $text.=$langs->trans("No");
551 
552  $text.='<br>';
553 
554  $text.='<br><strong>'.$langs->trans("AddMenus").':</strong> ';
555  if (isset($objMod->menu) && ! empty($objMod->menu)) // objMod can be an array or just an int 1
556  {
557  $text.=$langs->trans("Yes");
558  }
559  else $text.=$langs->trans("No");
560 
561  $text.='<br>';
562 
563  $text.='<br><strong>'.$langs->trans("AddExportProfiles").':</strong> ';
564  if (isset($objMod->export_label) && is_array($objMod->export_label) && count($objMod->export_label))
565  {
566  $i=0;
567  foreach($objMod->export_label as $val)
568  {
569  $text.=($i?', ':'').($val);
570  $i++;
571  }
572  }
573  else $text.=$langs->trans("No");
574 
575  $text.='<br>';
576 
577  $text.='<br><strong>'.$langs->trans("AddImportProfiles").':</strong> ';
578  if (isset($objMod->import_label) && is_array($objMod->import_label) && count($objMod->import_label))
579  {
580  $i=0;
581  foreach($objMod->import_label as $val)
582  {
583  $text.=($i?', ':'').($val);
584  $i++;
585  }
586  }
587  else $text.=$langs->trans("No");
588 
589  $text.='<br>';
590 
591  $text.='<br><strong>'.$langs->trans("AddOtherPagesOrServices").':</strong> ';
592  $text.=$langs->trans("DetectionNotPossible");
593 }
594 
595 
596 if ($mode == 'changelog')
597 {
598  $changelog=$objMod->getChangeLog();
599  if ($changelog) $text.='<div class="moduledesclong">'.$changelog.'<div>';
600  else $text.='<div class="moduledesclong">'.$langs->trans("NotAvailable").'</div>';
601 }
602 
603 print $text;
604 
605 
606 dol_fiche_end();
607 
608 print '</div>';
609 
610 
611 llxFooter();
612 
613 $db->close();
llxFooter()
Empty footer.
Definition: wrapper.php:58
setEventMessages($mesg, $mesgs, $style='mesgs')
Set event messages in dol_events session object.
dol_fiche_head($links=array(), $active='0', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='')
Show tab header of a card.
Class to manage Dolibarr users.
Definition: user.class.php:39
dolGetModulesDirs($subdir='')
Return list of modules directories.
if(empty($reshook)) $form
View.
Definition: perms.php:103
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="")
Scan a directory and return a list of files/directories.
Definition: files.lib.php:58
GETPOST($paramname, $check='none', $method=0, $filter=NULL, $options=NULL, $noreplace=0)
Return value of a param into GET or POST supervariable.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0)
Show a message to say access is forbidden and stop program Calling this function terminate execution ...
Class to manage generation of HTML components Only common components must be here.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
img_warning($titlealt= 'default', $moreatt= '')
Show warning logo.
if($_POST["cancel"]==$langs->trans("Cancel")&&!$id) if($action== 'setdatev'&&$user->rights->tax->charges->creer) if($action== 'add'&&$_POST["cancel"]<> $langs->trans("Cancel")) if($action== 'delete') $title
Actions.
Definition: card.php:183
dol_fiche_end($notab=0)
Show tab footer of a card.
load_fiche_titre($titre, $morehtmlright='', $picto='title_generic.png', $pictoisfullpath=0, $id=0, $morecssontable='', $morehtmlcenter='')
Load a title with picto.
llxHeader()
Empty header.
Definition: wrapper.php:46
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:427
dol_print_date($time, $format='', $tzoutput='tzserver', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
print
Draft customers invoices.
Definition: index.php:91
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
Class to manage triggers.