dolibarr 23.0.3
modulehelp.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2017 Regis Houssin <regis.houssin@inodbox.com>
4 * Copyright (C) 2022 Charlene Benke <charlene@patas-monkey.com>
5 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
6 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
27if (!defined('NOREQUIREMENU')) {
28 define('NOREQUIREMENU', '1'); // If there is no need to load and show top and left menu
29}
30if (!defined('NOTOKENRENEWAL')) {
31 define('NOTOKENRENEWAL', '1'); // Disabled because this page is into a popup on module search page and we want to avoid to have an Anti CSRF token error (done if MAIN_SECURITY_CSRF_WITH_TOKEN is on) when we make a second search after closing popup.
32}
33
34
35// Load Dolibarr environment
36require '../main.inc.php';
44require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
45require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
46require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
47
48// Load translation files required by the page
49$langs->loadLangs(array('errors', 'admin', 'modulebuilder', 'exports'));
50
51$mode = GETPOST('mode', 'alpha');
52$action = GETPOST('action', 'aZ09');
53$id = GETPOSTINT('id');
54if (empty($mode)) {
55 $mode = 'desc';
56}
57
58if (empty($user->admin)) {
60}
61
62
63
64/*
65 * Actions
66 */
67
68// Nothing
69
70
71/*
72 * View
73 */
74
75$form = new Form($db);
76
77$help_url = 'EN:First_setup|FR:Premiers_paramétrages|ES:Primeras_configuraciones';
78llxHeader('', $langs->trans("Setup"), $help_url, '', 0, 0, '', '', '', 'mod-admin page-modulehelp');
79
80print '<!-- Force style container -->'."\n".'<style>
81.id-container {
82 width: 100%;
83}
84#id-right {
85 padding-left: unset;
86}
87</style>';
88
89$arrayofnatures = array('core' => $langs->transnoentitiesnoconv("Core"), 'external' => $langs->transnoentitiesnoconv("External").' - '.$langs->trans("AllPublishers"));
90
91// Search modules dirs
92$modulesdir = dolGetModulesDirs();
93
94
95$filename = array();
96'@phan-var-force DolibarrModules[] $modules';
97$modules = array();
98$orders = array();
99$categ = array();
100$dirmod = array();
101$i = 0; // is a sequencer of modules found
102$j = 0; // j is module number. Automatically affected if module number not defined.
103$modNameLoaded = array();
104$familyinfo = array();
105
106foreach ($modulesdir as $dir) {
107 // Load modules attributes in arrays (name, numero, orders) from dir directory
108 //print $dir."\n<br>";
109 dol_syslog("Scan directory ".$dir." for module descriptor files (modXXX.class.php)");
110 $handle = @opendir($dir);
111 if (is_resource($handle)) {
112 while (($file = readdir($handle)) !== false) {
113 //print "$i ".$file."\n<br>";
114 if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod' && substr($file, dol_strlen($file) - 10) == '.class.php') {
115 $modName = substr($file, 0, dol_strlen($file) - 10);
116
117 if ($modName) {
118 if (!empty($modNameLoaded[$modName])) {
119 $mesg = "Error: Module ".$modName." was found twice: Into ".$modNameLoaded[$modName]." and ".$dir.". You probably have an old file on your disk.<br>";
120 setEventMessages($mesg, null, 'warnings');
121 dol_syslog($mesg, LOG_ERR);
122 continue;
123 }
124
125 try {
126 $res = include_once $dir.$file;
127 if (class_exists($modName)) {
128 try {
129 $objMod = new $modName($db);
130 '@phan-var-force DolibarrModules $objMod';
131 $modNameLoaded[$modName] = $dir;
132
133 if (!$objMod->numero > 0 && $modName != 'modUser') {
134 dol_syslog('The module descriptor '.$modName.' must have a numero property', LOG_ERR);
135 }
136 $j = $objMod->numero;
137
138 $modulequalified = 1;
139
140 // We discard modules according to features level (PS: if module is activated we always show it)
141 $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i', '', get_class($objMod)));
142 if ($objMod->version == 'development' && (!getDolGlobalString($const_name) && (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2))) {
143 $modulequalified = 0;
144 }
145 if ($objMod->version == 'experimental' && (!getDolGlobalString($const_name) && (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1))) {
146 $modulequalified = 0;
147 }
148 if (preg_match('/deprecated/', $objMod->version) && (!getDolGlobalString($const_name) && (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 0))) {
149 $modulequalified = 0;
150 }
151
152 // We discard modules according to property disabled
153 //if (!empty($objMod->hidden)) $modulequalified=0;
154
155 if ($modulequalified > 0) {
156 $publisher = dol_escape_htmltag($objMod->getPublisher());
157 $external = ($objMod->isCoreOrExternalModule() == 'external');
158 if ($external) {
159 if ($publisher) {
160 $arrayofnatures['external_'.$publisher] = $langs->trans("External").' - '.$publisher;
161 } else {
162 $arrayofnatures['external_'] = $langs->trans("External").' - '.$langs->trans("UnknownPublishers");
163 }
164 }
165 ksort($arrayofnatures);
166 }
167
168 // Define an array $categ with categ with at least one qualified module
169 if ($modulequalified > 0) {
170 $modules[$i] = $objMod;
171 $filename[$i] = $modName;
172
173 // Gives the possibility to the module, to provide his own family info and position of this family
174 if (is_array($objMod->familyinfo) && !empty($objMod->familyinfo)) {
175 $familyinfo = array_merge($familyinfo, $objMod->familyinfo);
176 $familykey = key($objMod->familyinfo);
177 } else {
178 $familykey = $objMod->family;
179 }
180 if (empty($familykey) || $familykey === null) {
181 $familykey = 'other';
182 }
183
184 $moduleposition = ($objMod->module_position ? $objMod->module_position : '50');
185 if ($moduleposition == '50' && ($objMod->isCoreOrExternalModule() == 'external')) {
186 $moduleposition = '80'; // External modules at end by default
187 }
188
189 if (empty($familyinfo[$familykey]['position'])) {
190 $familyinfo[$familykey]['position'] = '0';
191 }
192
193 $orders[$i] = $familyinfo[$familykey]['position']."_".$familykey."_".$moduleposition."_".$j; // Sort by family, then by module position then number
194 $dirmod[$i] = $dir;
195 //print $i.'-'.$dirmod[$i].'<br>';
196 // Set categ[$i]
197 $specialstring = 'unknown';
198 if ($objMod->version == 'development' || $objMod->version == 'experimental') {
199 $specialstring = 'expdev';
200 }
201 if (isset($categ[$specialstring])) {
202 $categ[$specialstring]++; // Array of all different modules categories
203 } else {
204 $categ[$specialstring] = 1;
205 }
206 $j++;
207 $i++;
208 } else {
209 dol_syslog("Module ".get_class($objMod)." not qualified");
210 }
211 } catch (Exception $e) {
212 dol_syslog("Failed to load ".$dir.$file." ".$e->getMessage(), LOG_ERR);
213 }
214 } else {
215 print info_admin("Warning bad descriptor file : ".$dir.$file." (Class ".$modName." not found into file)", 0, 0, '1', 'warning');
216 }
217 } catch (Exception $e) {
218 dol_syslog("Failed to load ".$dir.$file." ".$e->getMessage(), LOG_ERR);
219 }
220 }
221 }
222 }
223 closedir($handle);
224 } else {
225 dol_syslog("htdocs/admin/modulehelp.php: Failed to open directory ".$dir.". See permission and open_basedir option.", LOG_WARNING);
226 }
227}
228
229asort($orders);
230//var_dump($orders);
231//var_dump($categ);
232//var_dump($modules);
233
234
235$objMod = null;
236$dirofmodule = null;
237$key = -1;
238$i = 0;
239foreach ($orders as $tmpkey => $tmpvalue) {
240 $tmpMod = $modules[$tmpkey];
241 '@phan-var-force DolibarrModules $tmpMod';
242 if ($tmpMod->numero == $id) {
243 $key = $i;
244 $modName = $filename[$tmpkey];
245 $dirofmodule = $dirmod[$tmpkey];
246 $objMod = $tmpMod;
247 break;
248 }
249 $i++;
250}
251if (!is_object($objMod)) {
252 $msg = __FILE__." Module with no found for id:".$id;
253 dol_syslog($msg, LOG_ERR);
254 return;
255}
256
257$value = $orders[$key];
258$tab = explode('_', $value);
259$familyposition = $tab[0];
260$familykey = $tab[1];
261$module_position = $tab[2];
262$numero = $tab[3];
263
264
265
266$head = modulehelp_prepare_head($objMod);
267
268// Check filters
269$modulename = $objMod->getName();
270$moduledesc = $objMod->getDesc(1);
271$moduleauthor = $objMod->getPublisher();
272$moduledir = strtolower(preg_replace('/^mod/i', '', get_class($objMod)));
273
274$const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i', '', get_class($objMod)));
275
276$text = '<span class="opacitymedium">'.$langs->trans("LastActivationDate").':</span> ';
277if (getDolGlobalString($const_name)) {
278 $text .= dol_print_date($objMod->getLastActivationDate(), 'dayhour');
279} else {
280 $text .= $langs->trans("Disabled");
281}
282$tmp = $objMod->getLastActivationInfo();
283$authorid = (empty($tmp['authorid']) ? '' : $tmp['authorid']);
284if ($authorid > 0) {
285 $tmpuser = new User($db);
286 $tmpuser->fetch($authorid);
287 $text .= '<br><span class="opacitymedium">'.$langs->trans("LastActivationAuthor").':</span> ';
288 $text .= $tmpuser->getNomUrl(-1);
289}
290$ip = (empty($tmp['ip']) ? '' : $tmp['ip']);
291if ($ip) {
292 $text .= '<br><span class="opacitymedium">'.$langs->trans("LastActivationIP").':</span> ';
293 $text .= $ip;
294}
295$lastactivationversion = (empty($tmp['lastactivationversion']) ? '' : $tmp['lastactivationversion']);
296if ($lastactivationversion && $lastactivationversion != 'dolibarr') {
297 $text .= '<br><span class="opacitymedium">'.$langs->trans("LastActivationVersion").':</span> ';
298 $text .= $lastactivationversion;
299}
300
301$moreinfo = $text;
302
303$title = ($modulename ? $modulename : $moduledesc);
304
305print '<div class="centpercent">';
306
307$picto = 'object_'.$objMod->picto;
308
309print load_fiche_titre($title, $moreinfo, $picto, 0, '', 'titlemodulehelp');
310print '<br>';
311
312print dol_get_fiche_head($head, $mode, '', -1);
313
314if (!$modulename) {
315 dol_syslog("Error for module ".$key." - Property name of module looks empty", LOG_WARNING);
316}
317
318// Load all lang files of module
319if (isset($objMod->langfiles) && is_array($objMod->langfiles)) {
320 foreach ($objMod->langfiles as $domain) {
321 $langs->load($domain);
322 }
323}
324
325
326
327
328// Version (with picto warning or not)
329$version = $objMod->getVersion(0);
330$versiontrans = '';
331if (preg_match('/development/i', $version)) {
332 $versiontrans .= img_warning($langs->trans("Development"), 'style="float: left"');
333}
334if (preg_match('/experimental/i', $version)) {
335 $versiontrans .= img_warning($langs->trans("Experimental"), 'style="float: left"');
336}
337if (preg_match('/deprecated/i', $version)) {
338 $versiontrans .= img_warning($langs->trans("Deprecated"), 'style="float: left"');
339}
340$versiontrans .= $objMod->getVersion(1);
341
342// Define imginfo
343$imginfo = "info";
344if ($objMod->isCoreOrExternalModule() == 'external') {
345 $imginfo = "info_black";
346}
347
348// Define text of description of module
349$text = '';
350
351if ($mode == 'desc') {
352 if ($moduledesc) {
353 $text .= '<br>'.$moduledesc.'<br><br><br>';
354 }
355
356 $moduledescriptorfile = get_class($objMod).'.class.php';
357 $text .= '<span class="opacitymedium">'.$langs->trans("DescriptorFile").':</span> '.$moduledescriptorfile;
358
359 $text .= '<br><span class="opacitymedium">'.$langs->trans("IdModule").':</span> '.$objMod->numero;
360
361 $textexternal = '';
362 if ($objMod->isCoreOrExternalModule() == 'external') {
363 $tmpdirofmoduletoshow = preg_replace('/^'.preg_quote(DOL_DOCUMENT_ROOT, '/').'/', '', (string) $dirofmodule);
364 $textexternal .= '<br><span class="opacitymedium">'.$langs->trans("Origin").':</span> '.$langs->trans("ExternalModule").' - '.$langs->trans("InstalledInto", $tmpdirofmoduletoshow);
365
366 $installmoduleslock = DOL_DATA_ROOT.'/installmodules.lock';
367 global $dolibarr_allow_download_external_modules;
368 if ((!file_exists($installmoduleslock) || !empty($dolibarr_allow_download_external_modules)) && preg_match('/\/custom\//', (string) $dirofmodule)) {
369 // Add a link to download a zip of the module
370 $textexternal .= ' <a href="'.DOL_URL_ROOT.'/admin/tools/export_files.php?export_type=externalmodule&what='.urlencode($moduledir).'&compression=zip&zipfilename_template=module_'.$moduledir.'-'.$version.'.notorig" target="_blank" rel="noopener">'.img_picto('', 'download').'</a>';
371 } else {
372 // Add a link to download a zip of the module
373 $textexternal .= img_picto($langs->trans("DownloadOfModuleFileDisallowed"), 'download', 'class="opacitymedium paddingleft"');
374 }
375
376 if ($objMod->editor_name != 'dolibarr') {
377 $textexternal .= '<br><span class="opacitymedium">'.$langs->trans("Publisher").':</span> '.(empty($objMod->editor_name) ? $langs->trans("Unknown") : $objMod->editor_name);
378 }
379 $editor_url = $objMod->editor_url;
380 if (!preg_match('/^http/', $editor_url)) {
381 $editor_url = 'https://'.$editor_url;
382 }
383 $editor_url_to_show = preg_replace('/(utm_[a-z_]+|origin)=[a-z0-9_]+/i', '', $editor_url);
384 $editor_url_to_show = preg_replace('/[\/\?]+$/', '', $editor_url_to_show);
385 if (!empty($objMod->editor_url) && !preg_match('/dolibarr\.org/i', $objMod->editor_url)) {
386 $textexternal .= ($objMod->editor_name != 'dolibarr' ? ' - ' : '').img_picto('', 'globe').' <a href="'.$editor_url.'" target="_blank" rel="noopener noreferrer external">'.$editor_url_to_show.'</a>';
387 }
388 $text .= $textexternal;
389 } else {
390 $text .= '<br><span class="opacitymedium">'.$langs->trans("Origin").':</span> '.$langs->trans("Core");
391 if (empty($objMod->numero)) {
392 $text .= ' &nbsp; <span class="italic opacitymedium">('.$langs->trans("AlwaysEnabled").')</span>';
393 } elseif (!empty($objMod->enabled_bydefault)) {
394 $text .= ' &nbsp; <span class="italic opacitymedium">('.$langs->trans("EnabledByDefaultAtInstall").')</span>';
395 }
396 }
397
398 $text .= '<br><span class="opacitymedium">'.$langs->trans("Version").':</span> '.$version;
399
400 $text .= '<br>';
401
402 $moduledesclong = $objMod->getDescLong();
403 if ($moduledesclong) {
404 $text .= '<br><hr><div class="moduledesclong">'.$moduledesclong.'<div>';
405 }
406}
407
408if ($mode == 'feature') {
409 $text .= '<br><strong>'.$langs->trans("DependsOn").':</strong> ';
410 if (is_array($objMod->depends) && count($objMod->depends)) {
411 $i = 0;
412 foreach ($objMod->depends as $modulestringorarray) {
413 if (is_array($modulestringorarray)) {
414 $text .= ($i ? ', ' : img_picto('', 'tick', 'class="pictofixedwidth"')).implode(', ', $modulestringorarray);
415 } else {
416 $text .= ($i ? ', ' : img_picto('', 'tick', 'class="pictofixedwidth"')).$modulestringorarray;
417 }
418 $i++;
419 }
420 } else {
421 $text .= '<span class="opacitymedium">'.$langs->trans("None").'</span>';
422 }
423 $text .= '<br>';
424
425 $text .= '<br><strong>'.$langs->trans("RequiredBy").':</strong> ';
426 if (is_array($objMod->requiredby) && count($objMod->requiredby)) {
427 $i = 0;
428 foreach ($objMod->requiredby as $modulestringorarray) {
429 if (is_array($modulestringorarray)) {
430 $text .= ($i ? ', ' : img_picto('', 'tick', 'class="pictofixedwidth"')).implode(', ', $modulestringorarray);
431 } else {
432 $text .= ($i ? ', ' : img_picto('', 'tick', 'class="pictofixedwidth"')).$modulestringorarray;
433 }
434 $i++;
435 }
436 } else {
437 $text .= '<span class="opacitymedium">'.$langs->trans("None").'</span>';
438 }
439
440 $text .= '<br><br>';
441
442 $text .= '<br><strong>'.$langs->trans("AddDataTables").':</strong> ';
443 $listofsqlfiles1 = dol_dir_list(DOL_DOCUMENT_ROOT.'/install/mysql/tables/', 'files', 0, 'llx.*-'.$moduledir.'\.sql', array('\.key\.sql', '\.sql\.back'));
444 $listofsqlfiles2 = dol_dir_list(dol_buildpath($moduledir.'/sql/'), 'files', 0, 'llx.*\.sql', array('\.key\.sql', '\.sql\.back'));
445 $sqlfiles = array_merge($listofsqlfiles1, $listofsqlfiles2);
446
447 if (count($sqlfiles) > 0) {
448 $i = 0;
449 foreach ($sqlfiles as $val) {
450 $text .= ($i ? ', ' : img_picto('', 'tick', 'class="pictofixedwidth"')).preg_replace('/\-'.$moduledir.'$/', '', preg_replace('/\.sql$/', '', preg_replace('/llx_/', '', $val['name'])));
451 $i++;
452 }
453 } else {
454 $text .= '<span class="opacitymedium">'.$langs->trans("No").'</span>';
455 }
456
457 $text .= '<br>';
458
459 $text .= '<br><strong>'.$langs->trans("AddDictionaries").':</strong> ';
460 if (isset($objMod->dictionaries) && isset($objMod->dictionaries['tablib']) && is_array($objMod->dictionaries['tablib']) && count($objMod->dictionaries['tablib'])) {
461 $i = 0;
462 foreach ($objMod->dictionaries['tablib'] as $val) {
463 $text .= ($i ? ', ' : img_picto('', 'tick', 'class="pictofixedwidth"')).$val;
464 $i++;
465 }
466 } else {
467 $text .= '<span class="opacitymedium">'.$langs->trans("No").'</span>';
468 }
469
470 $text .= '<br>';
471
472 $text .= '<br><strong>'.$langs->trans("AddData").':</strong> ';
473 $filedata = dol_buildpath($moduledir.'/sql/data.sql');
474 if (dol_is_file($filedata)) {
475 $text .= img_picto('', 'tick', 'class="pictofixedwidth"').$langs->trans("Yes").' <span class="opacitymedium">('.$moduledir.'/sql/data.sql)</span>';
476 } else {
477 $text .= '<span class="opacitymedium">'.$langs->trans("No").'</span>';
478 }
479
480 $text .= '<br>';
481
482 $text .= '<br><strong>'.$langs->trans("AddRemoveTabs").':</strong> ';
483 if (isset($objMod->tabs) && is_array($objMod->tabs) && count($objMod->tabs)) {
484 $i = 0;
485 foreach ($objMod->tabs as $val) {
486 if (is_array($val)) {
487 $val = $val['data'];
488 }
489 if (is_string($val)) {
490 $tmp = explode(':', $val, 3);
491 $text .= ($i ? ', ' : '').$tmp[0].':'.$tmp[1];
492 $i++;
493 }
494 }
495 } else {
496 $text .= '<span class="opacitymedium">'.$langs->trans("No").'</span>';
497 }
498
499 $text .= '<br>';
500
501 $text .= '<br><strong>'.$langs->trans("AddModels").':</strong> ';
502 if (isset($objMod->module_parts) && isset($objMod->module_parts['models']) && $objMod->module_parts['models']) {
503 $text .= img_picto('', 'tick', 'class="pictofixedwidth"').$langs->trans("Yes");
504 } else {
505 $text .= '<span class="opacitymedium">'.$langs->trans("No").'</span>';
506 }
507
508 $text .= '<br>';
509
510 $text .= '<br><strong>'.$langs->trans("AddSubstitutions").':</strong> ';
511 if (isset($objMod->module_parts) && isset($objMod->module_parts['substitutions']) && $objMod->module_parts['substitutions']) {
512 $text .= img_picto('', 'tick', 'class="pictofixedwidth"').$langs->trans("Yes");
513 } else {
514 $text .= '<span class="opacitymedium">'.$langs->trans("No").'</span>';
515 }
516
517 $text .= '<br>';
518
519 $text .= '<br><strong>'.$langs->trans("AddSheduledJobs").':</strong> ';
520 if (isset($objMod->cronjobs) && is_array($objMod->cronjobs) && count($objMod->cronjobs)) {
521 $i = 0;
522 foreach ($objMod->cronjobs as $val) {
523 $text .= ($i ? ', ' : img_picto('', 'tick', 'class="pictofixedwidth"')).$langs->trans($val['label']);
524 $i++;
525 }
526 } else {
527 $text .= '<span class="opacitymedium">'.$langs->trans("No").'</span>';
528 }
529
530 $text .= '<br>';
531
532 $text .= '<br><strong>'.$langs->trans("AddTriggers").':</strong> ';
533 $moreinfoontriggerfile = '';
534 if (isset($objMod->module_parts) && isset($objMod->module_parts['triggers']) && $objMod->module_parts['triggers']) {
535 $yesno = 'Yes';
536 } else {
537 $yesno = '<span class="opacitymedium">'.$langs->trans("No").'</span>';
538 }
539 require_once DOL_DOCUMENT_ROOT.'/core/class/interfaces.class.php';
540 $interfaces = new Interfaces($db);
541 $triggers = $interfaces->getTriggersList(array((($objMod->isCoreOrExternalModule() == 'external') ? '/'.$moduledir : '').'/core/triggers'));
542 foreach ($triggers as $triggercursor) {
543 if ($triggercursor['module'] == $moduledir) {
544 $yesno = 'Yes';
545 $moreinfoontriggerfile = ' ('.$triggercursor['relpath'].')';
546 }
547 }
548
549 $text .= ($yesno == 'Yes' ? img_picto('', 'tick', 'class="pictofixedwidth"') : '').$langs->trans($yesno).$moreinfoontriggerfile;
550
551 $text .= '<br>';
552
553 $text .= '<br><strong>'.$langs->trans("AddBoxes").':</strong> ';
554 if (isset($objMod->boxes) && is_array($objMod->boxes) && count($objMod->boxes)) {
555 $i = 0;
556 foreach ($objMod->boxes as $val) {
557 $boxstring = (empty($val['file']) ? (empty($val[0]) ? '' : $val[0]) : $val['file']);
558 if ($boxstring) {
559 $text .= ($i ? ', ' : img_picto('', 'tick', 'class="pictofixedwidth"')).$boxstring;
560 }
561 $i++;
562 }
563 } else {
564 $text .= '<span class="opacitymedium">'.$langs->trans("No").'</span>';
565 }
566
567 $text .= '<br>';
568
569 $text .= '<br><strong>'.$langs->trans("AddHooks").':</strong> ';
570 if (isset($objMod->module_parts) && isset($objMod->module_parts['hooks']) && is_array($objMod->module_parts['hooks']) && count($objMod->module_parts['hooks'])) {
571 $i = 0;
572 foreach ($objMod->module_parts['hooks'] as $key => $val) {
573 if ($key === 'entity') {
574 continue;
575 }
576
577 // For special values
578 if ($key === 'data') {
579 if (is_array($val)) {
580 foreach ($val as $value) {
581 $text .= ($i ? ', ' : img_picto('', 'tick', 'class="pictofixedwidth"')).($value);
582 $i++;
583 }
584
585 continue;
586 }
587 }
588
589 $text .= ($i ? ', ' : img_picto('', 'tick', 'class="pictofixedwidth"')).($val);
590 $i++;
591 }
592 } else {
593 $text .= '<span class="opacitymedium">'.$langs->trans("No").'</span>';
594 }
595
596 $text .= '<br>';
597
598 $text .= '<br><strong>'.$langs->trans("AddPermissions").':</strong> ';
599 if (isset($objMod->rights) && is_array($objMod->rights) && count($objMod->rights)) {
600 $i = 0;
601 foreach ($objMod->rights as $val) {
602 $text .= ($i ? ', ' : img_picto('', 'tick', 'class="pictofixedwidth"')).($val[1]);
603 $i++;
604 }
605 } else {
606 $text .= '<span class="opacitymedium">'.$langs->trans("No").'</span>';
607 }
608
609 $text .= '<br>';
610
611 $text .= '<br><strong>'.$langs->trans("AddMenus").':</strong> ';
612 if (isset($objMod->menu) && !empty($objMod->menu)) { // objMod can be an array or just an int 1
613 $text .= img_picto('', 'tick', 'class="pictofixedwidth"').$langs->trans("Yes");
614 } else {
615 $text .= '<span class="opacitymedium">'.$langs->trans("No").'</span>';
616 }
617
618 $text .= '<br>';
619
620 $text .= '<br><strong>'.$langs->trans("AddExportProfiles").':</strong> ';
621 if (isset($objMod->export_label) && is_array($objMod->export_label) && count($objMod->export_label)) {
622 $i = 0;
623 foreach ($objMod->export_label as $val) {
624 $text .= ($i ? ', ' : img_picto('', 'tick', 'class="pictofixedwidth"')).$langs->trans($val);
625 $i++;
626 }
627 } else {
628 $text .= '<span class="opacitymedium">'.$langs->trans("No").'</span>';
629 }
630
631 $text .= '<br>';
632
633 $text .= '<br><strong>'.$langs->trans("AddImportProfiles").':</strong> ';
634 if (isset($objMod->import_label) && is_array($objMod->import_label) && count($objMod->import_label)) {
635 $i = 0;
636 foreach ($objMod->import_label as $val) {
637 $text .= ($i ? ', ' : img_picto('', 'tick', 'class="pictofixedwidth"')).$langs->trans($val);
638 $i++;
639 }
640 } else {
641 $text .= '<span class="opacitymedium">'.$langs->trans("No").'</span>';
642 }
643
644 $text .= '<br>';
645
646 $text .= '<br><strong>'.$langs->trans("AddWebsiteTemplates").':</strong> ';
647 if (isset($objMod->module_parts) && isset($objMod->module_parts['websitetemplates']) && $objMod->module_parts['websitetemplates']) {
648 $text .= img_picto('', 'tick', 'class="pictofixedwidth"').$langs->trans("Yes");
649 } else {
650 $text .= '<span class="opacitymedium">'.$langs->trans("No").'</span>';
651 }
652
653 $text .= '<br>';
654
655 $text .= '<br><strong>'.$langs->trans("AddOtherPagesOrServices").':</strong> ';
656 $text .= '<span class="opacitymedium">'.$langs->trans("DetectionNotPossible").'</span>';
657}
658
659
660if ($mode == 'changelog') {
661 $changelog = $objMod->getChangeLog();
662 if ($changelog) {
663 $text .= '<div class="moduledesclong">'.$changelog.'<div>';
664 } else {
665 $text .= '<div class="moduledesclong"><span class="opacitymedium">'.$langs->trans("NotAvailable").'</span></div>';
666 }
667}
668
669print $text;
670
671
672print dol_get_fiche_end();
673
674print '</div>';
675
676// End of page
677llxFooter();
678$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
modulehelp_prepare_head($object)
Prepare array with list of tabs.
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 triggers.
Class to manage Dolibarr users.
dol_is_file($pathoffile)
Return if path is a file.
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:64
dolGetModulesDirs($subdir='')
Return list of directories that contain modules.
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)
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
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.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
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_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
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.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='')
Show information in HTML for admin users or standard users.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.