dolibarr 21.0.0-alpha
modules.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2003-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org>
4 * Copyright (C) 2004-2017 Laurent Destailleur <eldy@users.sourceforge.net>
5 * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
6 * Copyright (C) 2005-2017 Regis Houssin <regis.houssin@inodbox.com>
7 * Copyright (C) 2011-2023 Juanjo Menent <jmenent@2byte.es>
8 * Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
9 * Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
10 * Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
11 * Copyright (C) 2021-2024 Frédéric France <frederic.france@free.fr>
12 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program. If not, see <https://www.gnu.org/licenses/>.
26 */
27
33if (!defined('CSRFCHECK_WITH_TOKEN') && (empty($_GET['action']) || $_GET['action'] != 'reset')) { // We force security except to disable modules so we can do it if a problem occurs on a module
34 define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
35}
36
37// Load Dolibarr environment
38require '../main.inc.php';
39require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
40require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
41require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
42require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
43require_once DOL_DOCUMENT_ROOT.'/admin/dolistore/class/dolistore.class.php';
44
45// Load translation files required by the page
46$langs->loadLangs(array("errors", "admin", "modulebuilder"));
47
48// if we set another view list mode, we keep it (till we change one more time)
49if (GETPOSTISSET('mode')) {
50 $mode = GETPOST('mode', 'alpha');
51 if ($mode == 'common' || $mode == 'commonkanban') {
52 dolibarr_set_const($db, "MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT", $mode, 'chaine', 0, '', $conf->entity);
53 }
54} else {
55 $mode = (!getDolGlobalString('MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT') ? 'commonkanban' : $conf->global->MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT);
56}
57
58$action = GETPOST('action', 'aZ09');
59$value = GETPOST('value', 'alpha');
60$page_y = GETPOSTINT('page_y');
61$search_keyword = GETPOST('search_keyword', 'alpha');
62$search_status = GETPOST('search_status', 'alpha');
63$search_nature = GETPOST('search_nature', 'alpha');
64$search_version = GETPOST('search_version', 'alpha');
65
66
67// For dolistore search
68$options = array();
69$options['per_page'] = 20;
70$options['categorie'] = ((int) (GETPOSTINT('categorie') ? GETPOSTINT('categorie') : 0));
71$options['start'] = ((int) (GETPOSTINT('start') ? GETPOSTINT('start') : 0));
72$options['end'] = ((int) (GETPOSTINT('end') ? GETPOSTINT('end') : 0));
73$options['search'] = GETPOST('search_keyword', 'alpha');
74$dolistore = new Dolistore(false);
75
76
77if (!$user->admin) {
79}
80
81$familyinfo = array(
82 'hr' => array('position' => '001', 'label' => $langs->trans("ModuleFamilyHr")),
83 'crm' => array('position' => '006', 'label' => $langs->trans("ModuleFamilyCrm")),
84 'srm' => array('position' => '007', 'label' => $langs->trans("ModuleFamilySrm")),
85 'financial' => array('position' => '009', 'label' => $langs->trans("ModuleFamilyFinancial")),
86 'products' => array('position' => '012', 'label' => $langs->trans("ModuleFamilyProducts")),
87 'projects' => array('position' => '015', 'label' => $langs->trans("ModuleFamilyProjects")),
88 'ecm' => array('position' => '018', 'label' => $langs->trans("ModuleFamilyECM")),
89 'technic' => array('position' => '021', 'label' => $langs->trans("ModuleFamilyTechnic")),
90 'portal' => array('position' => '040', 'label' => $langs->trans("ModuleFamilyPortal")),
91 'interface' => array('position' => '050', 'label' => $langs->trans("ModuleFamilyInterface")),
92 'base' => array('position' => '060', 'label' => $langs->trans("ModuleFamilyBase")),
93 'other' => array('position' => '100', 'label' => $langs->trans("ModuleFamilyOther")),
94);
95
96$param = '';
97if (!GETPOST('buttonreset', 'alpha')) {
98 if ($search_keyword) {
99 $param .= '&search_keyword='.urlencode($search_keyword);
100 }
101 if ($search_status && $search_status != '-1') {
102 $param .= '&search_status='.urlencode($search_status);
103 }
104 if ($search_nature && $search_nature != '-1') {
105 $param .= '&search_nature='.urlencode($search_nature);
106 }
107 if ($search_version && $search_version != '-1') {
108 $param .= '&search_version='.urlencode($search_version);
109 }
110}
111
112$dirins = DOL_DOCUMENT_ROOT.'/custom';
113$urldolibarrmodules = 'https://www.dolistore.com/';
114
115// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
116$hookmanager->initHooks(array('adminmodules', 'globaladmin'));
117
118// Increase limit of time. Works only if we are not in safe mode
119$max_execution_time_for_deploy = getDolGlobalInt('MODULE_UPLOAD_MAX_EXECUTION_TIME', 300); // 5mn if not defined
120if (!empty($max_execution_time_for_deploy)) {
121 $err = error_reporting();
122 error_reporting(0); // Disable all errors
123 //error_reporting(E_ALL);
124 @set_time_limit($max_execution_time_for_deploy);
125 error_reporting($err);
126}
127// Other method - TODO is this required ?
128$max_time = @ini_get("max_execution_time");
129if ($max_time && $max_time < $max_execution_time_for_deploy) {
130 dol_syslog("max_execution_time=".$max_time." is lower than max_execution_time_for_deploy=".$max_execution_time_for_deploy.". We try to increase it dynamically.");
131 @ini_set("max_execution_time", $max_execution_time_for_deploy); // This work only if safe mode is off. also web servers has timeout of 300
132}
133
134
135$dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
136$allowonlineinstall = true;
137$allowfromweb = 1;
138if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
139 $allowonlineinstall = false;
140}
141
142
143/*
144 * Actions
145 */
146
147$formconfirm = '';
148
149$parameters = array();
150$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
151if ($reshook < 0) {
152 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
153}
154
155if (GETPOST('buttonreset', 'alpha')) {
156 $search_keyword = '';
157 $search_status = '';
158 $search_nature = '';
159 $search_version = '';
160}
161
162if ($action == 'install' && $allowonlineinstall) {
163 $error = 0;
164
165 // $original_file should match format module_modulename-x.y[.z].zip
166 $original_file = basename($_FILES["fileinstall"]["name"]);
167 $original_file = preg_replace('/\s*\‍(\d+\‍)\.zip$/i', '.zip', $original_file);
168 $newfile = $conf->admin->dir_temp.'/'.$original_file.'/'.$original_file;
169
170 if (!$original_file) {
171 $langs->load("Error");
172 setEventMessages($langs->trans("ErrorModuleFileRequired"), null, 'warnings');
173 $error++;
174 } else {
175 if (!$error && !preg_match('/\.zip$/i', $original_file)) {
176 $langs->load("errors");
177 setEventMessages($langs->trans("ErrorFileMustBeADolibarrPackage", $original_file), null, 'errors');
178 $error++;
179 }
180 if (!$error && !preg_match('/^(module[a-zA-Z0-9]*|theme)_.*\-([0-9][0-9\.]*)\.zip$/i', $original_file)) {
181 $langs->load("errors");
182 setEventMessages($langs->trans("ErrorFilenameDosNotMatchDolibarrPackageRules", $original_file, 'module_*-x.y*.zip'), null, 'errors');
183 $error++;
184 }
185 if (empty($_FILES['fileinstall']['tmp_name'])) {
186 $langs->load("errors");
187 setEventMessages($langs->trans("ErrorFileNotUploaded"), null, 'errors');
188 $error++;
189 }
190 }
191
192 if (!$error) {
193 if ($original_file) {
194 @dol_delete_dir_recursive($conf->admin->dir_temp.'/'.$original_file);
195 dol_mkdir($conf->admin->dir_temp.'/'.$original_file);
196 }
197
198 $tmpdir = preg_replace('/\.zip$/i', '', $original_file).'.dir';
199 if ($tmpdir) {
200 @dol_delete_dir_recursive($conf->admin->dir_temp.'/'.$tmpdir);
201 dol_mkdir($conf->admin->dir_temp.'/'.$tmpdir);
202 }
203
204 $result = dol_move_uploaded_file($_FILES['fileinstall']['tmp_name'], $newfile, 1, 0, $_FILES['fileinstall']['error']);
205 if ($result > 0) {
206 $result = dol_uncompress($newfile, $conf->admin->dir_temp.'/'.$tmpdir);
207
208 if (!empty($result['error'])) {
209 $langs->load("errors");
210 setEventMessages($langs->trans($result['error'], $original_file), null, 'errors');
211 $error++;
212 } else {
213 // Now we move the dir of the module
214 $modulename = preg_replace('/module_/', '', $original_file);
215 $modulename = preg_replace('/\-([0-9][0-9\.]*)\.zip$/i', '', $modulename);
216 // Search dir $modulename
217 $modulenamedir = $conf->admin->dir_temp.'/'.$tmpdir.'/'.$modulename; // Example ./mymodule
218
219 if (!dol_is_dir($modulenamedir)) {
220 $modulenamedir = $conf->admin->dir_temp.'/'.$tmpdir.'/htdocs/'.$modulename; // Example ./htdocs/mymodule
221 //var_dump($modulenamedir);
222 if (!dol_is_dir($modulenamedir)) {
223 setEventMessages($langs->trans("ErrorModuleFileSeemsToHaveAWrongFormat").'<br>'.$langs->trans("ErrorModuleFileSeemsToHaveAWrongFormat2", $modulename, 'htdocs/'.$modulename), null, 'errors');
224 $error++;
225 }
226 }
227
228 if (!$error) {
229 // TODO Make more test
230 }
231
232 dol_syslog("Uncompress of module file is a success.");
233
234 // We check if this is a metapackage
235 $modulenamearrays = array();
236 if (dol_is_file($modulenamedir.'/metapackage.conf')) {
237 // This is a meta package
238 $metafile = file_get_contents($modulenamedir.'/metapackage.conf');
239 $modulenamearrays = explode("\n", $metafile);
240 }
241 $modulenamearrays[$modulename] = $modulename;
242 //var_dump($modulenamearrays);exit;
243
244 // Lop on each package of the metapackage
245 foreach ($modulenamearrays as $modulenameval) {
246 if (strpos($modulenameval, '#') === 0) {
247 continue; // Discard comments
248 }
249 if (strpos($modulenameval, '//') === 0) {
250 continue; // Discard comments
251 }
252 if (!trim($modulenameval)) {
253 continue;
254 }
255
256 // Now we install the module
257 if (!$error) {
258 @dol_delete_dir_recursive($dirins.'/'.$modulenameval); // delete the target directory
259 $submodulenamedir = $conf->admin->dir_temp.'/'.$tmpdir.'/'.$modulenameval;
260 if (!dol_is_dir($submodulenamedir)) {
261 $submodulenamedir = $conf->admin->dir_temp.'/'.$tmpdir.'/htdocs/'.$modulenameval;
262 }
263 dol_syslog("We copy now directory ".$submodulenamedir." into target dir ".$dirins.'/'.$modulenameval);
264 $result = dolCopyDir($submodulenamedir, $dirins.'/'.$modulenameval, '0444', 1);
265 if ($result <= 0) {
266 dol_syslog('Failed to call dolCopyDir result='.$result." with param ".$submodulenamedir." and ".$dirins.'/'.$modulenameval, LOG_WARNING);
267 $langs->load("errors");
268 setEventMessages($langs->trans("ErrorFailToCopyDir", $submodulenamedir, $dirins.'/'.$modulenameval), null, 'errors');
269 $error++;
270 }
271 }
272 }
273 }
274 } else {
275 setEventMessages($langs->trans("ErrorFailToRenameFile", $_FILES['fileinstall']['tmp_name'], $newfile), null, 'errors');
276 $error++;
277 }
278 }
279
280 if (!$error) {
281 $message = $langs->trans("SetupIsReadyForUse", DOL_URL_ROOT.'/admin/modules.php?mainmenu=home', $langs->transnoentitiesnoconv("Home").' - '.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("Modules"));
282 setEventMessages($message, null, 'warnings');
283 }
284} elseif ($action == 'install' && !$allowonlineinstall) {
285 httponly_accessforbidden("You try to bypass the protection to disallow deployment of an external module. Hack attempt ?");
286}
287
288if ($action == 'set' && $user->admin) {
289 $checkOldValue = getDolGlobalInt('CHECKLASTVERSION_EXTERNALMODULE');
290 $csrfCheckOldValue = getDolGlobalInt('MAIN_SECURITY_CSRF_WITH_TOKEN');
291 $resarray = activateModule($value);
292 if ($checkOldValue != getDolGlobalInt('CHECKLASTVERSION_EXTERNALMODULE')) {
293 setEventMessage($langs->trans('WarningModuleHasChangedLastVersionCheckParameter', $value), 'warnings');
294 }
295 if ($csrfCheckOldValue != getDolGlobalInt('MAIN_SECURITY_CSRF_WITH_TOKEN')) {
296 setEventMessage($langs->trans('WarningModuleHasChangedSecurityCsrfParameter', $value), 'warnings');
297 }
298 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", getDolGlobalInt('MAIN_IHM_PARAMS_REV') + 1, 'chaine', 0, '', $conf->entity);
299 if (!empty($resarray['errors'])) {
300 setEventMessages('', $resarray['errors'], 'errors');
301 } else {
302 //var_dump($resarray);exit;
303 if ($resarray['nbperms'] > 0) {
304 $tmpsql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."user WHERE admin <> 1";
305 $resqltmp = $db->query($tmpsql);
306 if ($resqltmp) {
307 $obj = $db->fetch_object($resqltmp);
308 //var_dump($obj->nb);exit;
309 if ($obj && $obj->nb > 1) {
310 $msg = $langs->trans('ModuleEnabledAdminMustCheckRights');
311 setEventMessages($msg, null, 'warnings');
312 }
313 } else {
314 dol_print_error($db);
315 }
316 }
317 }
318 header("Location: ".$_SERVER["PHP_SELF"]."?mode=".$mode.$param.($page_y ? '&page_y='.$page_y : ''));
319 exit;
320} elseif ($action == 'reset' && $user->admin && GETPOST('confirm') == 'yes') {
321 $result = unActivateModule($value);
322 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", getDolGlobalInt('MAIN_IHM_PARAMS_REV') + 1, 'chaine', 0, '', $conf->entity);
323 if ($result) {
324 setEventMessages($result, null, 'errors');
325 }
326 header("Location: ".$_SERVER["PHP_SELF"]."?mode=".$mode.$param.($page_y ? '&page_y='.$page_y : ''));
327 exit;
328} elseif (getDolGlobalInt("MAIN_FEATURES_LEVEL") > 1 && $action == 'reload' && $user->admin && GETPOST('confirm') == 'yes') {
329 $result = unActivateModule($value, 0);
330 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity);
331 if ($result) {
332 setEventMessages($result, null, 'errors');
333 header("Location: ".$_SERVER["PHP_SELF"]."?mode=".$mode.$param.($page_y ? '&page_y='.$page_y : ''));
334 }
335 $resarray = activateModule($value, 0, 1);
336 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity);
337 if (!empty($resarray['errors'])) {
338 setEventMessages('', $resarray['errors'], 'errors');
339 } else {
340 if ($resarray['nbperms'] > 0) {
341 $tmpsql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."user WHERE admin <> 1";
342 $resqltmp = $db->query($tmpsql);
343 if ($resqltmp) {
344 $obj = $db->fetch_object($resqltmp);
345 if ($obj && $obj->nb > 1) {
346 $msg = $langs->trans('ModuleEnabledAdminMustCheckRights');
347 setEventMessages($msg, null, 'warnings');
348 }
349 } else {
350 dol_print_error($db);
351 }
352 }
353 }
354 header("Location: ".$_SERVER["PHP_SELF"]."?mode=".$mode.$param.($page_y ? '&page_y='.$page_y : ''));
355 exit;
356}
357
358
359
360
361/*
362 * View
363 */
364
365$form = new Form($db);
366
367$morejs = array();
368$morecss = array("/admin/dolistore/css/dolistore.css");
369
370// Set dir where external modules are installed
371if (!dol_is_dir($dirins)) {
372 dol_mkdir($dirins);
373}
374$dirins_ok = (dol_is_dir($dirins));
375
376$help_url = 'EN:First_setup|FR:Premiers_paramétrages|ES:Primeras_configuraciones';
377llxHeader('', $langs->trans("Setup"), $help_url, '', 0, 0, $morejs, $morecss, 0, 'mod-admin page-modules');
378
379
380// Search modules dirs
381$modulesdir = dolGetModulesDirs();
382
383$arrayofnatures = array(
384 'core' => array('label' => $langs->transnoentitiesnoconv("NativeModules")),
385 'external' => array('label' => $langs->transnoentitiesnoconv("External").' - ['.$langs->trans("AllPublishers").']')
386);
387$arrayofwarnings = array(); // Array of warning each module want to show when activated
388$arrayofwarningsext = array(); // Array of warning each module want to show when we activate an external module
389$filename = array();
390$modules = array();
391$orders = array();
392$categ = array();
393$publisherlogoarray = array();
394
395$i = 0; // is a sequencer of modules found
396$j = 0; // j is module number. Automatically affected if module number not defined.
397$modNameLoaded = array();
398
399foreach ($modulesdir as $dir) {
400 // Load modules attributes in arrays (name, numero, orders) from dir directory
401 //print $dir."\n<br>";
402 dol_syslog("Scan directory ".$dir." for module descriptor files (modXXX.class.php)");
403 $handle = @opendir($dir);
404 if (is_resource($handle)) {
405 while (($file = readdir($handle)) !== false) {
406 //print "$i ".$file."\n<br>";
407 if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod' && substr($file, dol_strlen($file) - 10) == '.class.php') {
408 $modName = substr($file, 0, dol_strlen($file) - 10);
409
410 if ($modName) {
411 if (!empty($modNameLoaded[$modName])) { // In cache of already loaded modules ?
412 $mesg = "Error: Module ".$modName." was found twice: Into ".$modNameLoaded[$modName]." and ".$dir.". You probably have an old file on your disk.<br>";
413 setEventMessages($mesg, null, 'warnings');
414 dol_syslog($mesg, LOG_ERR);
415 continue;
416 }
417
418 try {
419 $res = include_once $dir.$file; // A class already exists in a different file will send a non catchable fatal error.
420 if (class_exists($modName)) {
421 $objMod = new $modName($db);
422 '@phan-var-force DolibarrModules $objMod';
423 $modNameLoaded[$modName] = $dir;
424 if (!$objMod->numero > 0 && $modName != 'modUser') {
425 dol_syslog('The module descriptor '.$modName.' must have a numero property', LOG_ERR);
426 }
427 $j = $objMod->numero;
428
429 $modulequalified = 1;
430
431 // We discard modules according to features level (PS: if module is activated we always show it)
432 $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i', '', get_class($objMod)));
433 if ($objMod->version == 'development' && (!getDolGlobalString($const_name) && (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2))) {
434 $modulequalified = 0;
435 }
436 if ($objMod->version == 'experimental' && (!getDolGlobalString($const_name) && (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1))) {
437 $modulequalified = 0;
438 }
439 if (preg_match('/deprecated/', $objMod->version) && (!getDolGlobalString($const_name) && (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 0))) {
440 $modulequalified = 0;
441 }
442
443 // We discard modules according to property ->hidden
444 if (!empty($objMod->hidden)) {
445 $modulequalified = 0;
446 }
447
448 if ($modulequalified > 0) {
449 $publisher = dol_escape_htmltag($objMod->getPublisher());
450 $external = ($objMod->isCoreOrExternalModule() == 'external');
451 if ($external) {
452 if ($publisher) {
453 // Check if there is a logo forpublisher
454 /* Do not show the company logo in combo. Make combo list dirty.
455 if (!empty($objMod->editor_squarred_logo)) {
456 $publisherlogoarray['external_'.$publisher] = img_picto('', $objMod->editor_squarred_logo, 'class="publisherlogoinline"');
457 }
458 $publisherlogo = empty($publisherlogoarray['external_'.$publisher]) ? '' : $publisherlogoarray['external_'.$publisher];
459 */
460 $arrayofnatures['external_'.$publisher] = array('label' => $langs->trans("External").' - '.$publisher, 'data-html' => $langs->trans("External").' - <span class="opacitymedium inine-block valignmiddle">'.$publisher.'</span>');
461 } else {
462 $arrayofnatures['external_'] = array('label' => $langs->trans("External").' - ['.$langs->trans("UnknownPublishers").']');
463 }
464 }
465 ksort($arrayofnatures);
466
467 // Define an array $categ with categ with at least one qualified module
468 $filename[$i] = $modName;
469 $modules[$modName] = $objMod;
470
471 // Gives the possibility to the module, to provide his own family info and position of this family
472 if (is_array($objMod->familyinfo) && !empty($objMod->familyinfo)) {
473 $familyinfo = array_merge($familyinfo, $objMod->familyinfo);
474 $familykey = key($objMod->familyinfo);
475 } else {
476 $familykey = $objMod->family;
477 }
478 '@phan-var-force string $familykey'; // if not, phan considers $familykey may be null
479
480 $moduleposition = ($objMod->module_position ? $objMod->module_position : '50');
481 if ($objMod->isCoreOrExternalModule() == 'external' && $moduleposition < 100000) {
482 // an external module should never return a value lower than '80'.
483 $moduleposition = '80'; // External modules at end by default
484 }
485
486 // Add list of warnings to show into arrayofwarnings and arrayofwarningsext
487 if (!empty($objMod->warnings_activation)) {
488 $arrayofwarnings[$modName] = $objMod->warnings_activation;
489 }
490 if (!empty($objMod->warnings_activation_ext)) {
491 $arrayofwarningsext[$modName] = $objMod->warnings_activation_ext;
492 }
493
494 $familyposition = (empty($familyinfo[$familykey]['position']) ? '0' : $familyinfo[$familykey]['position']);
495 $listOfOfficialModuleGroups = array('hr', 'technic', 'interface', 'technic', 'portal', 'financial', 'crm', 'base', 'products', 'srm', 'ecm', 'projects', 'other');
496 if ($external && !in_array($familykey, $listOfOfficialModuleGroups)) {
497 // If module is extern and into a custom group (not into an official predefined one), it must appear at end (custom groups should not be before official groups).
498 if (is_numeric($familyposition)) {
499 $familyposition = sprintf("%03d", (int) $familyposition + 100);
500 }
501 }
502
503 $orders[$i] = $familyposition."_".$familykey."_".$moduleposition."_".$j; // Sort by family, then by module position then number
504
505 // Set categ[$i]
506 $specialstring = 'unknown';
507 if ($objMod->version == 'development' || $objMod->version == 'experimental') {
508 $specialstring = 'expdev';
509 }
510 if (isset($categ[$specialstring])) {
511 $categ[$specialstring]++; // Array of all different modules categories
512 } else {
513 $categ[$specialstring] = 1;
514 }
515 $j++;
516 $i++;
517 } else {
518 dol_syslog("Module ".get_class($objMod)." not qualified");
519 }
520 } else {
521 print info_admin("admin/modules.php Warning bad descriptor file : ".$dir.$file." (Class ".$modName." not found into file)", 0, 0, '1', 'warning');
522 }
523 } catch (Exception $e) {
524 dol_syslog("Failed to load ".$dir.$file." ".$e->getMessage(), LOG_ERR);
525 }
526 }
527 }
528 }
529 closedir($handle);
530 } else {
531 dol_syslog("htdocs/admin/modules.php: Failed to open directory ".$dir.". See permission and open_basedir option.", LOG_WARNING);
532 }
533}
534
535if ($action == 'reset_confirm' && $user->admin) {
536 if (!empty($modules[$value])) {
537 $objMod = $modules[$value];
538
539 if (!empty($objMod->langfiles)) {
540 $langs->loadLangs($objMod->langfiles);
541 }
542
543 $form = new Form($db);
544 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?value='.$value.'&mode='.$mode.$param, $langs->trans('ConfirmUnactivation'), $langs->trans(GETPOST('confirm_message_code')), 'reset', '', 'no', 1);
545 }
546}
547
548if ($action == 'reload_confirm' && $user->admin) {
549 if (!empty($modules[$value])) {
550 $objMod = $modules[$value];
551
552 if (!empty($objMod->langfiles)) {
553 $langs->loadLangs($objMod->langfiles);
554 }
555
556 $form = new Form($db);
557 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?value='.$value.'&mode='.$mode.$param, $langs->trans('ConfirmReload'), $langs->trans(GETPOST('confirm_message_code')), 'reload', '', 'no', 1);
558 }
559}
560
561print $formconfirm;
562
563asort($orders);
564//var_dump($orders);
565//var_dump($categ);
566//var_dump($modules);
567
568$nbofactivatedmodules = count($conf->modules);
569
570// Define $nbmodulesnotautoenabled - TODO This code is at different places
571$nbmodulesnotautoenabled = count($conf->modules);
572$listofmodulesautoenabled = array('agenda', 'fckeditor', 'export', 'import');
573foreach ($listofmodulesautoenabled as $moduleautoenable) {
574 if (in_array($moduleautoenable, $conf->modules)) {
575 $nbmodulesnotautoenabled--;
576 }
577}
578
579print load_fiche_titre($langs->trans("ModulesSetup"), '', 'title_setup');
580
581// Start to show page
582$deschelp = '';
583if ($mode == 'common' || $mode == 'commonkanban') {
584 $desc = $langs->trans("ModulesDesc", '{picto}');
585 $desc .= ' '.$langs->trans("ModulesDesc2", '{picto2}');
586 $desc = str_replace('{picto}', img_picto('', 'switch_off', 'class="size15x"'), $desc);
587 $desc = str_replace('{picto2}', img_picto('', 'setup', 'class="size15x"'), $desc);
588 if ($nbmodulesnotautoenabled <= getDolGlobalInt('MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING', 1)) { // If only minimal initial modules enabled
589 $deschelp .= '<div class="info hideonsmartphone">'.$desc."<br></div>\n";
590 }
591 if (getDolGlobalString('MAIN_SETUP_MODULES_INFO')) { // Show a custom message
592 $deschelp .= '<div class="info">'.$langs->trans(getDolGlobalString('MAIN_SETUP_MODULES_INFO'))."<br></div>\n";
593 }
594 if ($deschelp) {
595 $deschelp .= '<br>';
596 }
597}
598if ($mode == 'marketplace') {
599 //$deschelp = '<div class="info hideonsmartphone">'.$langs->trans("ModulesMarketPlaceDesc")."<br></div><br>\n";
600}
601if ($mode == 'deploy') {
602 $deschelp = '<div class="info hideonsmartphone">'.$langs->trans("ModulesDeployDesc", $langs->transnoentitiesnoconv("AvailableModules"))."<br></div><br>\n";
603}
604if ($mode == 'develop') {
605 $deschelp = '<div class="info hideonsmartphone">'.$langs->trans("ModulesDevelopDesc")."<br></div><br>\n";
606}
607
608$head = modules_prepare_head($nbofactivatedmodules, count($modules), $nbmodulesnotautoenabled);
609
610
611if ($mode == 'common' || $mode == 'commonkanban') {
612 dol_set_focus('#search_keyword');
613
614 print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
615 print '<input type="hidden" name="token" value="'.newToken().'">';
616 if (isset($optioncss) && $optioncss != '') {
617 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
618 }
619 if (isset($sortfield) && $sortfield != '') {
620 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
621 }
622 if (isset($sortorder) && $sortorder != '') {
623 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
624 }
625 if (isset($page) && $page != '') {
626 print '<input type="hidden" name="page" value="'.$page.'">';
627 }
628 print '<input type="hidden" name="mode" value="'.$mode.'">';
629
630 print dol_get_fiche_head($head, 'modules', '', -1);
631
632 print $deschelp;
633
634 $moreforfilter = '<div class="valignmiddle">';
635
636 $moreforfilter .= '<div class="floatright right pagination paddingtop --module-list"><ul><li>';
637 $moreforfilter .= dolGetButtonTitle($langs->trans('CheckForModuleUpdate'), $langs->trans('CheckForModuleUpdate').'<br>'.$langs->trans('CheckForModuleUpdateHelp'), 'fa fa-sync', $_SERVER["PHP_SELF"].'?action=checklastversion&token='.newToken().'&mode='.$mode.$param, '', 1, array('morecss' => 'reposition'));
638 $moreforfilter .= dolGetButtonTitleSeparator();
639 $moreforfilter .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.$param, '', ($mode == 'common' ? 2 : 1), array('morecss' => 'reposition'));
640 $moreforfilter .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=commonkanban'.$param, '', ($mode == 'commonkanban' ? 2 : 1), array('morecss' => 'reposition'));
641 $moreforfilter .= '</li></ul></div>';
642
643 $moreforfilter .= '<div class="divfilteralone colorbacktimesheet float valignmiddle">';
644 $moreforfilter .= '<div class="divsearchfield paddingtop paddingbottom valignmiddle inline-block">';
645 $moreforfilter .= img_picto($langs->trans("Filter"), 'filter', 'class="paddingright opacityhigh hideonsmartphone"').'<input type="text" id="search_keyword" name="search_keyword" class="maxwidth125" value="'.dol_escape_htmltag($search_keyword).'" placeholder="'.dol_escape_htmltag($langs->trans('Keyword')).'">';
646 $moreforfilter .= '</div>';
647 $moreforfilter .= '<div class="divsearchfield paddingtop paddingbottom valignmiddle inline-block">';
648 $moreforfilter .= $form->selectarray('search_nature', $arrayofnatures, dol_escape_htmltag($search_nature), $langs->trans('Origin'), 0, 0, '', 0, 0, 0, '', 'maxwidth250', 1);
649 $moreforfilter .= '</div>';
650
651 if (getDolGlobalInt('MAIN_FEATURES_LEVEL')) {
652 $array_version = array('stable' => $langs->transnoentitiesnoconv("Stable"));
653 if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 0) {
654 $array_version['deprecated'] = $langs->trans("Deprecated");
655 }
656 if (getDolGlobalInt('MAIN_FEATURES_LEVEL') > 0) {
657 $array_version['experimental'] = $langs->trans("Experimental");
658 }
659 if (getDolGlobalInt('MAIN_FEATURES_LEVEL') > 1) {
660 $array_version['development'] = $langs->trans("Development");
661 }
662 $moreforfilter .= '<div class="divsearchfield paddingtop paddingbottom valignmiddle inline-block">';
663 $moreforfilter .= $form->selectarray('search_version', $array_version, $search_version, $langs->transnoentitiesnoconv('Version'), 0, 0, '', 0, 0, 0, '', 'maxwidth150', 1);
664 $moreforfilter .= '</div>';
665 }
666 $array_status = array('active' => $langs->transnoentitiesnoconv("Enabled"), 'disabled' => $langs->transnoentitiesnoconv("Disabled"));
667 $moreforfilter .= '<div class="divsearchfield paddingtop paddingbottom valignmiddle inline-block">';
668 $moreforfilter .= $form->selectarray('search_status', $array_status, $search_status, $langs->transnoentitiesnoconv('Status'), 0, 0, '', 0, 0, 0, '', 'maxwidth150', 1);
669 $moreforfilter .= '</div>';
670 $moreforfilter .= ' ';
671 $moreforfilter .= '<div class="divsearchfield valignmiddle inline-block">';
672 $moreforfilter .= '<input type="submit" name="buttonsubmit" class="button small nomarginleft" value="'.dol_escape_htmltag($langs->trans("Refresh")).'">';
673 if ($search_keyword || ($search_nature && $search_nature != '-1') || ($search_version && $search_version != '-1') || ($search_status && $search_status != '-1')) {
674 $moreforfilter .= ' ';
675 $moreforfilter .= '<input type="submit" name="buttonreset" class="buttonreset noborderbottom" value="'.dol_escape_htmltag($langs->trans("Reset")).'">';
676 }
677 $moreforfilter .= '</div>';
678 $moreforfilter .= '</div>';
679
680 $moreforfilter .= '</div>';
681
682 if (!empty($moreforfilter)) {
683 print $moreforfilter;
684 $parameters = array();
685 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
686 print $hookmanager->resPrint;
687 }
688
689 $moreforfilter = '';
690
691 print '<div class="clearboth"></div><br>';
692
693 $object = new stdClass();
694 $parameters = array();
695 $reshook = $hookmanager->executeHooks('insertExtraHeader', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
696 if ($reshook < 0) {
697 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
698 }
699
700 $disabled_modules = array();
701 if (!empty($_SESSION["disablemodules"])) {
702 $disabled_modules = explode(',', $_SESSION["disablemodules"]);
703 }
704
705 // Show list of modules
706 $oldfamily = '';
707 $foundoneexternalmodulewithupdate = 0;
708 $linenum = 0;
709 $atleastonequalified = 0;
710 $atleastoneforfamily = 0;
711
712 foreach ($orders as $key => $value) {
713 $linenum++;
714 $tab = explode('_', $value);
715 $familykey = $tab[1];
716 $module_position = $tab[2];
717
718 $modName = $filename[$key];
719
721 $objMod = $modules[$modName];
722
723 //print $objMod->name." - ".$key." - ".$objMod->version."<br>";
724 if ($mode == 'expdev' && $objMod->version != 'development' && $objMod->version != 'experimental') {
725 continue; // Discard if not for current tab
726 }
727
728 if (!$objMod->getName()) {
729 dol_syslog("Error for module ".$key." - Property name of module looks empty", LOG_WARNING);
730 continue;
731 }
732
733 $modulenameshort = strtolower(preg_replace('/^mod/i', '', get_class($objMod)));
734 $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i', '', get_class($objMod)));
735
736 // Check filters
737 $modulename = $objMod->getName();
738 $moduletechnicalname = $objMod->name;
739 $moduledesc = $objMod->getDesc();
740 $moduledesclong = $objMod->getDescLong();
741 $moduleauthor = $objMod->getPublisher();
742
743 // We discard showing according to filters
744 if ($search_keyword) {
745 $qualified = 0;
746 if (preg_match('/'.preg_quote($search_keyword, '/').'/i', $modulename)
747 || preg_match('/'.preg_quote($search_keyword, '/').'/i', $moduletechnicalname)
748 || ($moduledesc && preg_match('/'.preg_quote($search_keyword, '/').'/i', $moduledesc))
749 || ($moduledesclong && preg_match('/'.preg_quote($search_keyword, '/').'/i', $moduledesclong))
750 || ($moduleauthor && preg_match('/'.preg_quote($search_keyword, '/').'/i', $moduleauthor))
751 ) {
752 $qualified = 1;
753 }
754 if (!$qualified) {
755 continue;
756 }
757 }
758 if ($search_status) {
759 if ($search_status == 'active' && !getDolGlobalString($const_name)) {
760 continue;
761 }
762 if ($search_status == 'disabled' && getDolGlobalString($const_name)) {
763 continue;
764 }
765 }
766 if ($search_nature) {
767 if (preg_match('/^external/', $search_nature) && $objMod->isCoreOrExternalModule() != 'external') {
768 continue;
769 }
770 $reg = array();
771 if (preg_match('/^external_(.*)$/', $search_nature, $reg)) {
772 //print $reg[1].'-'.dol_escape_htmltag($objMod->getPublisher());
773 $publisher = dol_escape_htmltag($objMod->getPublisher());
774 if ($reg[1] && dol_escape_htmltag($reg[1]) != $publisher) {
775 continue;
776 }
777 if (!$reg[1] && !empty($publisher)) {
778 continue;
779 }
780 }
781 if ($search_nature == 'core' && $objMod->isCoreOrExternalModule() == 'external') {
782 continue;
783 }
784 }
785 if ($search_version) {
786 if (($objMod->version == 'development' || $objMod->version == 'experimental' || preg_match('/deprecated/', $objMod->version)) && $search_version == 'stable') {
787 continue;
788 }
789 if ($objMod->version != 'development' && ($search_version == 'development')) {
790 continue;
791 }
792 if ($objMod->version != 'experimental' && ($search_version == 'experimental')) {
793 continue;
794 }
795 if (!preg_match('/deprecated/', $objMod->version) && ($search_version == 'deprecated')) {
796 continue;
797 }
798 }
799
800 $atleastonequalified++;
801
802 // Load all language files of the qualified module
803 if (isset($objMod->langfiles) && is_array($objMod->langfiles)) {
804 foreach ($objMod->langfiles as $domain) {
805 $langs->load($domain);
806 }
807 }
808
809 // Print a separator if we change family
810 if ($familykey != $oldfamily) {
811 if ($oldfamily) {
812 print '</table></div><br>';
813 }
814
815 $familytext = empty($familyinfo[$familykey]['label']) ? $familykey : $familyinfo[$familykey]['label'];
816
817 print load_fiche_titre($familytext, '', '', 0, '', 'modulefamilygroup');
818
819 if ($mode == 'commonkanban') {
820 print '<div class="box-flex-container kanban">';
821 } else {
822 print '<div class="div-table-responsive">';
823 print '<table class="tagtable liste" summary="list_of_modules">'."\n";
824 }
825
826 $atleastoneforfamily = 0;
827 }
828
829 $atleastoneforfamily++;
830
831 if ($familykey != $oldfamily) {
832 $familytext = empty($familyinfo[$familykey]['label']) ? $familykey : $familyinfo[$familykey]['label'];
833 $oldfamily = $familykey;
834 }
835
836 // Version (with picto warning or not)
837 $version = $objMod->getVersion(0);
838 $versiontrans = '';
839 $warningstring = '';
840 if (preg_match('/development/i', $version)) {
841 $warningstring = $langs->trans("Development");
842 }
843 if (preg_match('/experimental/i', $version)) {
844 $warningstring = $langs->trans("Experimental");
845 }
846 if (preg_match('/deprecated/i', $version)) {
847 $warningstring = $langs->trans("Deprecated");
848 }
849
850 if ($objMod->isCoreOrExternalModule() == 'external' || preg_match('/development|experimental|deprecated/i', $version)) {
851 $versiontrans .= $objMod->getVersion(1);
852 }
853
854 if ($objMod->isCoreOrExternalModule() == 'external'
855 && (
856 $action == 'checklastversion'
857 // This is a bad practice to activate a check on an external access during the building of the admin page. 1 external module can hang the application.
858 // Adding a cron job could be a good idea: see DolibarrModules::checkForUpdate()
859 || getDolGlobalString('CHECKLASTVERSION_EXTERNALMODULE')
860 )
861 ) {
862 $checkRes = $objMod->checkForUpdate();
863 if ($checkRes > 0) {
864 setEventMessage($objMod->getName().' : '.$versiontrans.' -> '.$objMod->lastVersion);
865 } elseif ($checkRes < 0) {
866 setEventMessage($objMod->getName().' '.$langs->trans('CheckVersionFail'), 'warnings');
867 }
868 }
869
870 // Define imginfo
871 $imginfo = "info";
872 if ($objMod->isCoreOrExternalModule() == 'external') {
873 $imginfo = "info_black";
874 }
875
876 $codeenabledisable = '';
877 $codetoconfig = '';
878
879 // Force disable of module disabled into session (for demo for example)
880 if (in_array($modulenameshort, $disabled_modules)) {
881 $objMod->disabled = true;
882 }
883
884 // Activate/Disable and Setup (2 columns)
885 if (getDolGlobalString($const_name)) { // If module is already activated
886 // Set $codeenabledisable
887 $disableSetup = 0;
888 if (!empty($arrayofwarnings[$modName])) {
889 $codeenabledisable .= '<!-- This module has a warning to show when we activate it (note: your country is '.$mysoc->country_code.') -->'."\n";
890 }
891
892 if (!empty($objMod->disabled)) {
893 $codeenabledisable .= $langs->trans("Disabled");
894 } elseif (!empty($objMod->always_enabled) || ((isModEnabled('multicompany') && $objMod->core_enabled) && ($user->entity || $conf->entity != 1))) {
895 // @phan-suppress-next-line PhanUndeclaredMethodCall
896 if (method_exists($objMod, 'alreadyUsed') && $objMod->alreadyUsed()) {
897 $codeenabledisable .= $langs->trans("Used");
898 } else {
899 $codeenabledisable .= img_picto($langs->trans("Required"), 'switch_on', '', false, 0, 0, '', 'opacitymedium valignmiddle');
900 //print $langs->trans("Required");
901 }
902 if (isModEnabled('multicompany') && $user->entity) {
903 $disableSetup++;
904 }
905 } else {
906 // @phan-suppress-next-line PhanUndeclaredMethodCall
907 if (!empty($objMod->warnings_unactivation[$mysoc->country_code]) && method_exists($objMod, 'alreadyUsed') && $objMod->alreadyUsed()) {
908 $codeenabledisable .= '<a class="reposition valignmiddle" href="'.$_SERVER["PHP_SELF"].'?id='.$objMod->numero.'&amp;token='.newToken().'&amp;module_position='.$module_position.'&amp;action=reset_confirm&amp;confirm_message_code='.urlencode($objMod->warnings_unactivation[$mysoc->country_code]).'&amp;value='.$modName.'&amp;mode='.$mode.$param.'">';
909 $codeenabledisable .= img_picto($langs->trans("Activated").($warningstring ? ' '.$warningstring : ''), 'switch_on');
910 $codeenabledisable .= '</a>';
911 if (getDolGlobalInt("MAIN_FEATURES_LEVEL") > 1) {
912 $codeenabledisable .= '&nbsp;';
913 $codeenabledisable .= '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$objMod->numero.'&amp;token='.newToken().'&amp;module_position='.$module_position.'&amp;action=reload_confirm&amp;value='.$modName.'&amp;mode='.$mode.'&amp;confirm=yes'.$param.'">';
914 $codeenabledisable .= img_picto($langs->trans("Reload"), 'refresh', 'class="opacitymedium"');
915 $codeenabledisable .= '</a>';
916 }
917 } else {
918 $codeenabledisable .= '<a class="reposition valignmiddle" href="'.$_SERVER["PHP_SELF"].'?id='.$objMod->numero.'&amp;token='.newToken().'&amp;module_position='.$module_position.'&amp;action=reset&amp;value='.$modName.'&amp;mode='.$mode.'&amp;confirm=yes'.$param.'">';
919 $codeenabledisable .= img_picto($langs->trans("Activated").($warningstring ? ' '.$warningstring : ''), 'switch_on');
920 $codeenabledisable .= '</a>';
921 if (getDolGlobalInt("MAIN_FEATURES_LEVEL") > 1) {
922 $codeenabledisable .= '&nbsp;';
923 $codeenabledisable .= '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$objMod->numero.'&amp;token='.newToken().'&amp;module_position='.$module_position.'&amp;action=reload&amp;value='.$modName.'&amp;mode='.$mode.'&amp;confirm=yes'.$param.'">';
924 $codeenabledisable .= img_picto($langs->trans("Reload"), 'refresh', 'class="opacitymedium"');
925 $codeenabledisable .= '</a>';
926 }
927 }
928 }
929
930 // Set $codetoconfig
931 if (!empty($objMod->config_page_url) && !$disableSetup) {
932 $backtourlparam = '';
933 if ($search_keyword != '') {
934 $backtourlparam .= ($backtourlparam ? '&' : '?').'search_keyword='.urlencode($search_keyword); // No urlencode here, done later
935 }
936 if ($search_nature > -1) {
937 $backtourlparam .= ($backtourlparam ? '&' : '?').'search_nature='.urlencode($search_nature); // No urlencode here, done later
938 }
939 if ($search_version > -1) {
940 $backtourlparam .= ($backtourlparam ? '&' : '?').'search_version='.urlencode($search_version); // No urlencode here, done later
941 }
942 if ($search_status > -1) {
943 $backtourlparam .= ($backtourlparam ? '&' : '?').'search_status='.urlencode($search_status); // No urlencode here, done later
944 }
945 $backtourl = $_SERVER["PHP_SELF"].$backtourlparam;
946
947 $regs = array();
948 if (is_array($objMod->config_page_url)) {
949 $i = 0;
950 foreach ($objMod->config_page_url as $page) {
951 $urlpage = $page;
952 if ($i++) {
953 $codetoconfig .= '<a href="'.$urlpage.'" title="'.$langs->trans($page).'">'.img_picto(ucfirst($page), "setup").'</a>';
954 // print '<a href="'.$page.'">'.ucfirst($page).'</a>&nbsp;';
955 } else {
956 if (preg_match('/^([^@]+)@([^@]+)$/i', $urlpage, $regs)) {
957 $urltouse = dol_buildpath('/'.$regs[2].'/admin/'.$regs[1], 1);
958 $codetoconfig .= '<a href="'.$urltouse.(preg_match('/\?/', $urltouse) ? '&' : '?').'save_lastsearch_values=1&backtopage='.urlencode($backtourl).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"), "setup", 'style="padding-right: 6px"', false, 0, 0, '', 'fa-15').'</a>';
959 } else {
960 $urltouse = $urlpage;
961 $codetoconfig .= '<a href="'.$urltouse.(preg_match('/\?/', $urltouse) ? '&' : '?').'save_lastsearch_values=1&backtopage='.urlencode($backtourl).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"), "setup", 'style="padding-right: 6px"', false, 0, 0, '', 'fa-15').'</a>';
962 }
963 }
964 }
965 } elseif (preg_match('/^([^@]+)@([^@]+)$/i', (string) $objMod->config_page_url, $regs)) {
966 $codetoconfig .= '<a class="valignmiddle" href="'.dol_buildpath('/'.$regs[2].'/admin/'.$regs[1], 1).'?save_lastsearch_values=1&backtopage='.urlencode($backtourl).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"), "setup", 'style="padding-right: 6px"', false, 0, 0, '', 'fa-15').'</a>';
967 } else {
968 $codetoconfig .= '<a class="valignmiddle" href="'.((string) $objMod->config_page_url).'?save_lastsearch_values=1&backtopage='.urlencode($backtourl).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"), "setup", 'style="padding-right: 6px"', false, 0, 0, '', 'fa-15').'</a>';
969 }
970 } else {
971 $codetoconfig .= img_picto($langs->trans("NothingToSetup"), "setup", 'class="opacitytransp" style="padding-right: 6px"', false, 0, 0, '', 'fa-15');
972 }
973 } else { // Module not yet activated
974 // Set $codeenabledisable
975 if (!empty($objMod->always_enabled)) {
976 // A 'always_enabled' module should not never be disabled. If this happen, we keep a link to re-enable it.
977 $codeenabledisable .= '<!-- Message to show: an always_enabled module has been disabled -->'."\n";
978 $codeenabledisable .= '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$objMod->numero.'&token='.newToken().'&module_position='.$module_position.'&action=set&token='.newToken().'&value='.$modName.'&mode='.$mode.$param.'"';
979 $codeenabledisable .= '>';
980 $codeenabledisable .= img_picto($langs->trans("Disabled"), 'switch_off');
981 $codeenabledisable .= "</a>\n";
982 } elseif (!empty($objMod->disabled)) {
983 $codeenabledisable .= $langs->trans("Disabled");
984 } else {
985 // Module qualified for activation
986 $warningmessage = '';
987 if (!empty($arrayofwarnings[$modName])) {
988 $codeenabledisable .= '<!-- This module is a core module and it may have a warning to show when we activate it (note: your country is '.$mysoc->country_code.') -->'."\n";
989 foreach ($arrayofwarnings[$modName] as $keycountry => $cursorwarningmessage) {
990 if (preg_match('/^always/', $keycountry) || ($mysoc->country_code && preg_match('/^'.$mysoc->country_code.'/', $keycountry))) {
991 $warningmessage .= ($warningmessage ? "\n" : "").$langs->trans($cursorwarningmessage, $objMod->getName(), $mysoc->country_code);
992 }
993 }
994 }
995 if ($objMod->isCoreOrExternalModule() == 'external' && !empty($arrayofwarningsext)) {
996 $codeenabledisable .= '<!-- This module is an external module and it may have a warning to show (note: your country is '.$mysoc->country_code.') -->'."\n";
997 foreach ($arrayofwarningsext as $keymodule => $arrayofwarningsextbycountry) {
998 $keymodulelowercase = strtolower(preg_replace('/^mod/', '', $keymodule));
999 if (in_array($keymodulelowercase, $conf->modules)) { // If module that request warning is on
1000 foreach ($arrayofwarningsextbycountry as $keycountry => $cursorwarningmessage) {
1001 if (preg_match('/^always/', $keycountry) || ($mysoc->country_code && preg_match('/^'.$mysoc->country_code.'/', $keycountry))) {
1002 $warningmessage .= ($warningmessage ? "\n" : "").$langs->trans($cursorwarningmessage, $objMod->getName(), $mysoc->country_code, $modules[$keymodule]->getName());
1003 $warningmessage .= ($warningmessage ? "\n" : "").($warningmessage ? "\n" : "").$langs->trans("Module").' : '.$objMod->getName();
1004 if (!empty($objMod->editor_name)) {
1005 $warningmessage .= ($warningmessage ? "\n" : "").$langs->trans("Publisher").' : '.$objMod->editor_name;
1006 }
1007 if (!empty($objMod->editor_name)) {
1008 $warningmessage .= ($warningmessage ? "\n" : "").$langs->trans("ModuleTriggeringThisWarning").' : '.$modules[$keymodule]->getName();
1009 }
1010 }
1011 }
1012 }
1013 }
1014 }
1015 $codeenabledisable .= '<!-- Message to show: '.$warningmessage.' -->'."\n";
1016 $codeenabledisable .= '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$objMod->numero.'&token='.newToken().'&module_position='.$module_position.'&action=set&token='.newToken().'&value='.$modName.'&mode='.$mode.$param.'"';
1017 if ($warningmessage) {
1018 $codeenabledisable .= ' onclick="return confirm(\''.dol_escape_js($warningmessage).'\');"';
1019 }
1020 $codeenabledisable .= '>';
1021 $codeenabledisable .= img_picto($langs->trans("Disabled"), 'switch_off');
1022 $codeenabledisable .= "</a>\n";
1023 }
1024
1025 // Set $codetoconfig
1026 $codetoconfig .= img_picto($langs->trans("NothingToSetup"), "setup", 'class="opacitytransp" style="padding-right: 6px"');
1027 }
1028
1029 if ($mode == 'commonkanban') {
1030 // Output Kanban
1031 print $objMod->getKanbanView($codeenabledisable, $codetoconfig);
1032 } else {
1033 print '<tr class="oddeven'.($warningstring ? ' info-box-content-warning' : '').'">'."\n";
1034 if (getDolGlobalString('MAIN_MODULES_SHOW_LINENUMBERS')) {
1035 print '<td class="width50">'.$linenum.'</td>';
1036 }
1037
1038 // Picto + Name of module
1039 print ' <td class="tdoverflowmax200 minwidth200imp" title="'.dol_escape_htmltag($objMod->getName()).'">';
1040 $alttext = '';
1041 //if (is_array($objMod->need_dolibarr_version)) $alttext.=($alttext?' - ':'').'Dolibarr >= '.join('.',$objMod->need_dolibarr_version);
1042 //if (is_array($objMod->phpmin)) $alttext.=($alttext?' - ':'').'PHP >= '.join('.',$objMod->phpmin);
1043 if (!empty($objMod->picto)) {
1044 if (preg_match('/^\//i', $objMod->picto)) {
1045 print img_picto($alttext, $objMod->picto, 'class="valignmiddle pictomodule paddingrightonly"', 1);
1046 } else {
1047 print img_object($alttext, $objMod->picto, 'class="valignmiddle pictomodule paddingrightonly"');
1048 }
1049 } else {
1050 print img_object($alttext, 'generic', 'class="valignmiddle paddingrightonly"');
1051 }
1052 print ' <span class="valignmiddle">'.$objMod->getName().'</span>';
1053 print "</td>\n";
1054
1055 // Desc
1056 print '<td class="valignmiddle tdoverflowmax300 minwidth200imp">';
1057 print nl2br($objMod->getDesc());
1058 print "</td>\n";
1059
1060 // Help
1061 print '<td class="center nowrap" style="width: 82px;">';
1062 //print $form->textwithpicto('', $text, 1, $imginfo, 'minheight20', 0, 2, 1);
1063 print '<a href="javascript:document_preview(\''.DOL_URL_ROOT.'/admin/modulehelp.php?id='.((int) $objMod->numero).'\',\'text/html\',\''.dol_escape_js($langs->trans("Module")).'\')">'.img_picto(($objMod->isCoreOrExternalModule() == 'external' ? $langs->trans("ExternalModule").' - ' : '').$langs->trans("ClickToShowDescription"), $imginfo).'</a>';
1064 print '</td>';
1065
1066 // Version
1067 print '<td class="center nowrap width150" title="'.dol_escape_htmltag(dol_string_nohtmltag($versiontrans)).'">';
1068 if ($objMod->needUpdate) {
1069 $versionTitle = $langs->trans('ModuleUpdateAvailable').' : '.$objMod->lastVersion;
1070 print '<span class="badge badge-warning classfortooltip" title="'.dol_escape_htmltag($versionTitle).'">'.$versiontrans.'</span>';
1071 } else {
1072 print $versiontrans;
1073 }
1074 print "</td>\n";
1075
1076 // Link enable/disable
1077 print '<td class="center valignmiddle left nowraponall" width="60px">';
1078 print $codeenabledisable;
1079 print "</td>\n";
1080
1081 // Link config
1082 print '<td class="tdsetuppicto right valignmiddle" width="60px">';
1083 print $codetoconfig;
1084 print '</td>';
1085
1086 print "</tr>\n";
1087 }
1088 if ($objMod->needUpdate) {
1089 $foundoneexternalmodulewithupdate++;
1090 }
1091 }
1092
1093 if ($action == 'checklastversion') {
1094 if ($foundoneexternalmodulewithupdate) {
1095 setEventMessages($langs->trans("ModuleUpdateAvailable"), null, 'mesgs');
1096 } else {
1097 setEventMessages($langs->trans("NoExternalModuleWithUpdate"), null, 'mesgs');
1098 }
1099 }
1100
1101 if ($oldfamily) {
1102 if ($mode == 'commonkanban') {
1103 print '</div>';
1104 } else {
1105 print "</table>\n";
1106 print '</div>';
1107 }
1108 }
1109
1110 if (!$atleastonequalified) {
1111 print '<br><span class="opacitymedium">'.$langs->trans("NoDeployedModulesFoundWithThisSearchCriteria").'</span><br><br>';
1112 }
1113
1114 print dol_get_fiche_end();
1115
1116 print '<br>';
1117
1118 // Show warning about external users
1119 print info_admin(showModulesExludedForExternal($modules))."\n";
1120
1121 print '</form>';
1122}
1123
1124if ($mode == 'marketplace') {
1125 print dol_get_fiche_head($head, $mode, '', -1);
1126
1127 print $deschelp;
1128
1129 print '<br>';
1130
1131 // Marketplace
1132 print '<div class="div-table-responsive-no-min">';
1133 print '<table summary="list_of_modules" class="noborder centpercent">'."\n";
1134 print '<tr class="liste_titre">'."\n";
1135 print '<td class="hideonsmartphone">'.$form->textwithpicto($langs->trans("Provider"), $langs->trans("WebSiteDesc")).'</td>';
1136 print '<td></td>';
1137 print '<td>'.$langs->trans("URL").'</td>';
1138 print '</tr>';
1139
1140 print '<tr class="oddeven">'."\n";
1141 $url = 'https://www.dolistore.com';
1142 print '<td class="hideonsmartphone"><a href="'.$url.'" target="_blank" rel="noopener noreferrer external"><img border="0" class="imgautosize imgmaxwidth180" src="'.DOL_URL_ROOT.'/theme/dolistore_logo.png"></a></td>';
1143 print '<td><span class="opacitymedium">'.$langs->trans("DoliStoreDesc").'</span></td>';
1144 print '<td><a href="'.$url.'" target="_blank" rel="noopener noreferrer external">'.$url.'</a></td>';
1145 print '</tr>';
1146
1147 print "</table>\n";
1148 print '</div>';
1149
1150 print dol_get_fiche_end();
1151
1152 print '<br>';
1153
1154 if (!getDolGlobalString('MAIN_DISABLE_DOLISTORE_SEARCH') && getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 1) {
1155 // $options is array with filter criteria
1156 //var_dump($options);
1157 $dolistore->getRemoteCategories();
1158 $dolistore->getRemoteProducts($options);
1159
1160 print '<span class="opacitymedium">'.$langs->trans('DOLISTOREdescriptionLong').'</span><br><br>';
1161
1162 $previouslink = $dolistore->get_previous_link();
1163 $nextlink = $dolistore->get_next_link();
1164
1165 print '<div class="liste_titre liste_titre_bydiv centpercent"><div class="divsearchfield">';
1166
1167 print '<form method="POST" class="centpercent" id="searchFormList" action="'.$dolistore->url.'">'; ?>
1168 <input type="hidden" name="token" value="<?php echo newToken(); ?>">
1169 <input type="hidden" name="mode" value="marketplace">
1170 <div class="divsearchfield">
1171 <input name="search_keyword" placeholder="<?php echo $langs->trans('Keyword') ?>" id="search_keyword" type="text" class="minwidth200" value="<?php echo dol_escape_htmltag($options['search']) ?>"><br>
1172 </div>
1173 <div class="divsearchfield">
1174 <input class="button buttongen" value="<?php echo $langs->trans('Rechercher') ?>" type="submit">
1175 <a class="buttonreset" href="<?php echo urlencode($dolistore->url) ?>"><?php echo $langs->trans('Reset') ?></a>
1176
1177 &nbsp;
1178 </div>
1179 <?php
1180 print $previouslink;
1181 print $nextlink;
1182 print '</form>';
1183
1184 print '</div></div>';
1185 print '<div class="clearboth"></div>';
1186 ?>
1187
1188 <div id="category-tree-left">
1189 <ul class="tree">
1190 <?php
1191 echo $dolistore->get_categories(); // Do not use dol_escape_htmltag here, it is already a structured content?>
1192 </ul>
1193 </div>
1194 <div id="listing-content">
1195 <table summary="list_of_modules" id="list_of_modules" class="productlist centpercent">
1196 <tbody id="listOfModules">
1197 <?php echo $dolistore->get_products(); ?>
1198 </tbody>
1199 </table>
1200 </div>
1201 <?php
1202 }
1203}
1204
1205
1206// Install external module
1207
1208if ($mode == 'deploy') {
1209 print dol_get_fiche_head($head, $mode, '', -1);
1210
1211 $fullurl = '<a href="'.$urldolibarrmodules.'" target="_blank" rel="noopener noreferrer">'.$urldolibarrmodules.'</a>';
1212 $message = '';
1213 if ($allowonlineinstall) {
1214 if (!in_array('/custom', explode(',', $dolibarr_main_url_root_alt))) {
1215 $message = info_admin($langs->trans("ConfFileMustContainCustom", DOL_DOCUMENT_ROOT.'/custom', DOL_DOCUMENT_ROOT));
1216 $allowfromweb = -1;
1217 } else {
1218 if ($dirins_ok) {
1219 if (!is_writable(dol_osencode($dirins))) {
1220 $langs->load("errors");
1221 $message = info_admin($langs->trans("ErrorFailedToWriteInDir", $dirins), 0, 0, '1', 'warning');
1222 $allowfromweb = 0;
1223 }
1224 } else {
1225 $message = info_admin($langs->trans("NotExistsDirect", $dirins).$langs->trans("InfDirAlt").$langs->trans("InfDirExample"));
1226 $allowfromweb = 0;
1227 }
1228 }
1229 } else {
1230 if (getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) {
1231 // Show clean message
1232 if (!is_numeric(getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US'))) {
1233 $message = info_admin($langs->trans(getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')), 0, 0, 'warning');
1234 } else {
1235 $message = info_admin($langs->trans('InstallModuleFromWebHasBeenDisabledContactUs'), 0, 0, 'warning');
1236 }
1237 } else {
1238 // Show technical message
1239 $message = info_admin($langs->trans("InstallModuleFromWebHasBeenDisabledByFile", $dolibarrdataroot.'/installmodules.lock'), 0, 0, 'warning');
1240 }
1241 $allowfromweb = 0;
1242 }
1243
1244 print $deschelp;
1245
1246 if ($allowfromweb < 1) {
1247 print $langs->trans("SomethingMakeInstallFromWebNotPossible");
1248 print $message;
1249 //print $langs->trans("SomethingMakeInstallFromWebNotPossible2");
1250 print '<br>';
1251 }
1252
1253 print '<br>';
1254
1255 // $allowfromweb = -1 if installation or setup not correct, 0 if not allowed, 1 if allowed
1256 if ($allowfromweb >= 0) {
1257 if ($allowfromweb == 1) {
1258 //print $langs->trans("ThisIsProcessToFollow").'<br>';
1259 } else {
1260 print $langs->trans("ThisIsAlternativeProcessToFollow").'<br>';
1261 print '<b>'.$langs->trans("StepNb", 1).'</b>: ';
1262 print str_replace('{s1}', $fullurl, $langs->trans("FindPackageFromWebSite", '{s1}')).'<br>';
1263 print '<b>'.$langs->trans("StepNb", 2).'</b>: ';
1264 print str_replace('{s1}', $fullurl, $langs->trans("DownloadPackageFromWebSite", '{s1}')).'<br>';
1265 print '<b>'.$langs->trans("StepNb", 3).'</b>: ';
1266 }
1267
1268 if ($allowfromweb == 1) {
1269 print '<form enctype="multipart/form-data" method="POST" class="noborder" action="'.$_SERVER["PHP_SELF"].'" name="forminstall">';
1270 print '<input type="hidden" name="token" value="'.newToken().'">';
1271 print '<input type="hidden" name="action" value="install">';
1272 print '<input type="hidden" name="mode" value="deploy">';
1273
1274 print $langs->trans("YouCanSubmitFile").'<br><br>';
1275
1276 $max = getDolGlobalString('MAIN_UPLOAD_DOC'); // In Kb
1277 $maxphp = @ini_get('upload_max_filesize'); // In unknown
1278 if (preg_match('/k$/i', $maxphp)) {
1279 $maxphp = preg_replace('/k$/i', '', $maxphp);
1280 $maxphp *= 1;
1281 }
1282 if (preg_match('/m$/i', $maxphp)) {
1283 $maxphp = preg_replace('/m$/i', '', $maxphp);
1284 $maxphp *= 1024;
1285 }
1286 if (preg_match('/g$/i', $maxphp)) {
1287 $maxphp = preg_replace('/g$/i', '', $maxphp);
1288 $maxphp *= 1024 * 1024;
1289 }
1290 if (preg_match('/t$/i', $maxphp)) {
1291 $maxphp = preg_replace('/t$/i', '', $maxphp);
1292 $maxphp *= 1024 * 1024 * 1024;
1293 }
1294 $maxphp2 = @ini_get('post_max_size'); // In unknown
1295 if (preg_match('/k$/i', $maxphp2)) {
1296 $maxphp2 = preg_replace('/k$/i', '', $maxphp2);
1297 $maxphp2 *= 1;
1298 }
1299 if (preg_match('/m$/i', $maxphp2)) {
1300 $maxphp2 = preg_replace('/m$/i', '', $maxphp2);
1301 $maxphp2 *= 1024;
1302 }
1303 if (preg_match('/g$/i', $maxphp2)) {
1304 $maxphp2 = preg_replace('/g$/i', '', $maxphp2);
1305 $maxphp2 *= 1024 * 1024;
1306 }
1307 if (preg_match('/t$/i', $maxphp2)) {
1308 $maxphp2 = preg_replace('/t$/i', '', $maxphp2);
1309 $maxphp2 *= 1024 * 1024 * 1024;
1310 }
1311 // Now $max and $maxphp and $maxphp2 are in Kb
1312 $maxmin = $max;
1313 $maxphptoshow = $maxphptoshowparam = '';
1314 if ($maxphp > 0) {
1315 $maxmin = min($max, $maxphp);
1316 $maxphptoshow = $maxphp;
1317 $maxphptoshowparam = 'upload_max_filesize';
1318 }
1319 if ($maxphp2 > 0) {
1320 $maxmin = min($max, $maxphp2);
1321 if ($maxphp2 < $maxphp) {
1322 $maxphptoshow = $maxphp2;
1323 $maxphptoshowparam = 'post_max_size';
1324 }
1325 }
1326
1327 if ($maxmin > 0) {
1328 print '<script type="text/javascript">
1329 $(document).ready(function() {
1330 jQuery("#fileinstall").on("change", function() {
1331 if(this.files[0].size > '.($maxmin * 1024).') {
1332 alert("'.dol_escape_js($langs->trans("ErrorFileSizeTooLarge")).'");
1333 this.value = "";
1334 }
1335 });
1336 });
1337 </script>'."\n";
1338 // MAX_FILE_SIZE doit précéder le champ input de type file
1339 print '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">';
1340 }
1341
1342 print '<input class="flat minwidth400" type="file" name="fileinstall" id="fileinstall"> ';
1343
1344 print '<input type="submit" name="send" value="'.dol_escape_htmltag($langs->trans("Upload")).'" class="button small">';
1345
1346 if (getDolGlobalString('MAIN_UPLOAD_DOC')) {
1347 if ($user->admin) {
1348 $langs->load('other');
1349 print ' ';
1350 print info_admin($langs->trans("ThisLimitIsDefinedInSetup", $max, $maxphptoshow, $maxphptoshowparam), 1);
1351 }
1352 } else {
1353 print ' ('.$langs->trans("UploadDisabled").')';
1354 }
1355
1356 print '</form>';
1357
1358 print '<br>';
1359 print '<br>';
1360
1361 print '<div class="center"><div class="logo_setup"></div></div>';
1362 } else {
1363 print $langs->trans("UnpackPackageInModulesRoot", $dirins).'<br>';
1364 print '<b>'.$langs->trans("StepNb", 4).'</b>: ';
1365 print $langs->trans("SetupIsReadyForUse", DOL_URL_ROOT.'/admin/modules.php?mainmenu=home', $langs->transnoentitiesnoconv("Home").' - '.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("Modules")).'<br>';
1366 }
1367 }
1368
1369 if (!empty($result['return'])) {
1370 print '<br>';
1371
1372 foreach ($result['return'] as $value) {
1373 echo $value.'<br>';
1374 }
1375 }
1376
1377 print dol_get_fiche_end();
1378}
1379
1380if ($mode == 'develop') {
1381 print dol_get_fiche_head($head, $mode, '', -1);
1382
1383 print $deschelp;
1384
1385 print '<br>';
1386
1387 // Marketplace
1388 print '<table summary="list_of_modules" class="noborder centpercent">'."\n";
1389 print '<tr class="liste_titre">'."\n";
1390 //print '<td>'.$langs->trans("Logo").'</td>';
1391 print '<td colspan="2">'.$langs->trans("DevelopYourModuleDesc").'</td>';
1392 print '<td>'.$langs->trans("URL").'</td>';
1393 print '</tr>';
1394
1395 print '<tr class="oddeven" height="80">'."\n";
1396 print '<td class="center">';
1397 print '<div class="imgmaxheight50 logo_setup"></div>';
1398 print '</td>';
1399 print '<td>'.$langs->trans("TryToUseTheModuleBuilder", $langs->transnoentitiesnoconv("ModuleBuilder")).'</td>';
1400 print '<td class="maxwidth300">';
1401 if (isModEnabled('modulebuilder')) {
1402 print $langs->trans("SeeTopRightMenu");
1403 } else {
1404 print '<span class="opacitymedium">'.$langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("ModuleBuilder")).'</span>';
1405 }
1406 print '</td>';
1407 print '</tr>';
1408
1409 print '<tr class="oddeven" height="80">'."\n";
1410 $url = 'https://partners.dolibarr.org';
1411 print '<td class="center">';
1412 print'<a href="'.$url.'" target="_blank" rel="noopener noreferrer external"><img border="0" class="imgautosize imgmaxwidth180" src="'.DOL_URL_ROOT.'/theme/dolibarr_preferred_partner.png"></a>';
1413 print '</td>';
1414 print '<td>'.$langs->trans("DoliPartnersDesc").'</td>';
1415 print '<td><a href="'.$url.'" target="_blank" rel="noopener noreferrer external">';
1416 print img_picto('', 'url', 'class="pictofixedwidth"');
1417 print $url.'</a></td>';
1418 print '</tr>';
1419
1420 print "</table>\n";
1421
1422 print dol_get_fiche_end();
1423}
1424
1425// End of page
1426llxFooter();
1427$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
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).
unActivateModule($value, $requiredby=1)
Disable a module.
activateModule($value, $withdeps=1, $noconfverification=0)
Enable a module.
modules_prepare_head($nbofactivatedmodules, $nboftotalmodules, $nbmodulesnotautoenabled)
Prepare array with list of tabs.
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:70
Class Dolistore.
Class to manage generation of HTML components Only common components must be here.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan=0, $uploaderrorcode=0, $nohook=0, $varfiles='addedfile', $upload_dir='')
Check validity of a file upload from an GUI page, and move it to its final destination.
dol_uncompress($inputfile, $outputdir)
Uncompress a file.
dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayreplacement=null, $excludesubdir=0, $excludefileext=null, $excludearchivefiles=0)
Copy a dir to another dir.
dol_is_file($pathoffile)
Return if path is a file.
dol_is_dir($folder)
Test if filename is a directory.
dolGetModulesDirs($subdir='')
Return list of directories that contain modules.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
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)
Show tabs of a record.
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
setEventMessage($mesgs, $style='mesgs', $noduplicate=0)
Set event message in dol_events session object.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_set_focus($selector)
Set focus onto field with selector (similar behaviour of 'autofocus' HTML5 tag)
dolGetButtonTitleSeparator($moreClass="")
Add space between dolGetButtonTitle.
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.
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_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
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...
treeview li table
No Email.
ui state ui widget content ui state ui widget header ui state a ui button
0 = Do not include form tag and submit button -1 = Do not include form tag but include submit button
document_preview(file, type, title)
Function show document preview.
httponly_accessforbidden($message='1', $http_response_code=403, $stringalreadysanitized=0)
Show a message to say access is forbidden and stop program.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.