32 if (!defined(
'CSRFCHECK_WITH_TOKEN') && (empty($_GET[
'action']) || $_GET[
'action'] !=
'reset')) {
33 define(
'CSRFCHECK_WITH_TOKEN',
'1');
36 require
'../main.inc.php';
37 require_once DOL_DOCUMENT_ROOT.
'/core/lib/admin.lib.php';
38 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
39 require_once DOL_DOCUMENT_ROOT.
'/core/lib/geturl.lib.php';
40 require_once DOL_DOCUMENT_ROOT.
'/core/lib/functions2.lib.php';
41 require_once DOL_DOCUMENT_ROOT.
'/admin/dolistore/class/dolistore.class.php';
44 $langs->loadLangs(array(
"errors",
"admin",
"modulebuilder"));
46 $mode =
GETPOSTISSET(
'mode') ?
GETPOST(
'mode',
'alpha') : (empty($conf->global->MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT) ?
'commonkanban' :
'common');
50 $action =
GETPOST(
'action',
'aZ09');
51 $value =
GETPOST(
'value',
'alpha');
52 $page_y =
GETPOST(
'page_y',
'int');
53 $search_keyword =
GETPOST(
'search_keyword',
'alpha');
54 $search_status =
GETPOST(
'search_status',
'alpha');
55 $search_nature =
GETPOST(
'search_nature',
'alpha');
56 $search_version =
GETPOST(
'search_version',
'alpha');
61 $options[
'per_page'] = 20;
62 $options[
'categorie'] = ((
GETPOST(
'categorie',
'int') ?
GETPOST(
'categorie',
'int') : 0) + 0);
63 $options[
'start'] = ((
GETPOST(
'start',
'int') ?
GETPOST(
'start',
'int') : 0) + 0);
64 $options[
'end'] = ((
GETPOST(
'end',
'int') ?
GETPOST(
'end',
'int') : 0) + 0);
65 $options[
'search'] =
GETPOST(
'search_keyword',
'alpha');
74 'hr'=>array(
'position'=>
'001',
'label'=>$langs->trans(
"ModuleFamilyHr")),
75 'crm'=>array(
'position'=>
'006',
'label'=>$langs->trans(
"ModuleFamilyCrm")),
76 'srm'=>array(
'position'=>
'007',
'label'=>$langs->trans(
"ModuleFamilySrm")),
77 'financial'=>array(
'position'=>
'009',
'label'=>$langs->trans(
"ModuleFamilyFinancial")),
78 'products'=>array(
'position'=>
'012',
'label'=>$langs->trans(
"ModuleFamilyProducts")),
79 'projects'=>array(
'position'=>
'015',
'label'=>$langs->trans(
"ModuleFamilyProjects")),
80 'ecm'=>array(
'position'=>
'018',
'label'=>$langs->trans(
"ModuleFamilyECM")),
81 'technic'=>array(
'position'=>
'021',
'label'=>$langs->trans(
"ModuleFamilyTechnic")),
82 'portal'=>array(
'position'=>
'040',
'label'=>$langs->trans(
"ModuleFamilyPortal")),
83 'interface'=>array(
'position'=>
'050',
'label'=>$langs->trans(
"ModuleFamilyInterface")),
84 'base'=>array(
'position'=>
'060',
'label'=>$langs->trans(
"ModuleFamilyBase")),
85 'other'=>array(
'position'=>
'100',
'label'=>$langs->trans(
"ModuleFamilyOther")),
89 if (!
GETPOST(
'buttonreset',
'alpha')) {
90 if ($search_keyword) {
91 $param .=
'&search_keyword='.urlencode($search_keyword);
93 if ($search_status && $search_status !=
'-1') {
94 $param .=
'&search_status='.urlencode($search_status);
96 if ($search_nature && $search_nature !=
'-1') {
97 $param .=
'&search_nature='.urlencode($search_nature);
99 if ($search_version && $search_version !=
'-1') {
100 $param .=
'&search_version='.urlencode($search_version);
104 $dirins = DOL_DOCUMENT_ROOT.
'/custom';
105 $urldolibarrmodules =
'https://www.dolistore.com/';
108 $hookmanager->initHooks(array(
'adminmodules',
'globaladmin'));
117 $parameters = array();
118 $reshook = $hookmanager->executeHooks(
'doActions', $parameters, $object, $action);
123 if (
GETPOST(
'buttonreset',
'alpha')) {
124 $search_keyword =
'';
127 $search_version =
'';
130 if ($action ==
'install') {
134 $original_file = basename($_FILES[
"fileinstall"][
"name"]);
135 $original_file = preg_replace(
'/\s*\(\d+\)\.zip$/i',
'.zip', $original_file);
136 $newfile = $conf->admin->dir_temp.
'/'.$original_file.
'/'.$original_file;
138 if (!$original_file) {
139 $langs->load(
"Error");
140 setEventMessages($langs->trans(
"ErrorModuleFileRequired"),
null,
'warnings');
143 if (!$error && !preg_match(
'/\.zip$/i', $original_file)) {
144 $langs->load(
"errors");
145 setEventMessages($langs->trans(
"ErrorFileMustBeADolibarrPackage", $original_file),
null,
'errors');
148 if (!$error && !preg_match(
'/^(module[a-zA-Z0-9]*|theme)_.*\-([0-9][0-9\.]*)\.zip$/i', $original_file)) {
149 $langs->load(
"errors");
150 setEventMessages($langs->trans(
"ErrorFilenameDosNotMatchDolibarrPackageRules", $original_file,
'module_*-x.y*.zip'),
null,
'errors');
153 if (empty($_FILES[
'fileinstall'][
'tmp_name'])) {
154 $langs->load(
"errors");
161 if ($original_file) {
163 dol_mkdir($conf->admin->dir_temp.
'/'.$original_file);
166 $tmpdir = preg_replace(
'/\.zip$/i',
'', $original_file).
'.dir';
169 dol_mkdir($conf->admin->dir_temp.
'/'.$tmpdir);
172 $result =
dol_move_uploaded_file($_FILES[
'fileinstall'][
'tmp_name'], $newfile, 1, 0, $_FILES[
'fileinstall'][
'error']);
174 $result =
dol_uncompress($newfile, $conf->admin->dir_temp.
'/'.$tmpdir);
176 if (!empty($result[
'error'])) {
177 $langs->load(
"errors");
178 setEventMessages($langs->trans($result[
'error'], $original_file),
null,
'errors');
182 $modulename = preg_replace(
'/module_/',
'', $original_file);
183 $modulename = preg_replace(
'/\-([0-9][0-9\.]*)\.zip$/i',
'', $modulename);
185 $modulenamedir = $conf->admin->dir_temp.
'/'.$tmpdir.
'/'.$modulename;
188 $modulenamedir = $conf->admin->dir_temp.
'/'.$tmpdir.
'/htdocs/'.$modulename;
191 setEventMessages($langs->trans(
"ErrorModuleFileSeemsToHaveAWrongFormat").
'<br>'.$langs->trans(
"ErrorModuleFileSeemsToHaveAWrongFormat2", $modulename,
'htdocs/'.$modulename),
null,
'errors');
200 dol_syslog(
"Uncompress of module file is a success.");
202 $modulenamearrays = array();
203 if (
dol_is_file($modulenamedir.
'/metapackage.conf')) {
205 $metafile = file_get_contents($modulenamedir.
'/metapackage.conf');
206 $modulenamearrays = explode(
"\n", $metafile);
208 $modulenamearrays[$modulename] = $modulename;
211 foreach ($modulenamearrays as $modulenameval) {
212 if (strpos($modulenameval,
'#') === 0) {
215 if (strpos($modulenameval,
'//') === 0) {
218 if (!trim($modulenameval)) {
225 dol_syslog(
"We copy now directory ".$conf->admin->dir_temp.
'/'.$tmpdir.
'/htdocs/'.$modulenameval.
" into target dir ".$dirins.
'/'.$modulenameval);
226 $result =
dolCopyDir($modulenamedir, $dirins.
'/'.$modulenameval,
'0444', 1);
228 dol_syslog(
'Failed to call dolCopyDir result='.$result.
" with param ".$modulenamedir.
" and ".$dirins.
'/'.$modulenameval, LOG_WARNING);
229 $langs->load(
"errors");
230 setEventMessages($langs->trans(
"ErrorFailToCopyDir", $modulenamedir, $dirins.
'/'.$modulenameval),
null,
'errors');
237 setEventMessages($langs->trans(
"ErrorFailToRenameFile", $_FILES[
'fileinstall'][
'tmp_name'], $newfile),
null,
'errors');
243 setEventMessages($langs->trans(
"SetupIsReadyForUse", DOL_URL_ROOT.
'/admin/modules.php?mainmenu=home', $langs->transnoentitiesnoconv(
"Home").
' - '.$langs->transnoentitiesnoconv(
"Setup").
' - '.$langs->transnoentitiesnoconv(
"Modules")),
null,
'warnings');
247 if ($action ==
'set' && $user->admin) {
249 dolibarr_set_const($db,
"MAIN_IHM_PARAMS_REV", (
int) $conf->global->MAIN_IHM_PARAMS_REV + 1,
'chaine', 0,
'', $conf->entity);
250 if (!empty($resarray[
'errors'])) {
254 if ($resarray[
'nbperms'] > 0) {
255 $tmpsql =
"SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX.
"user WHERE admin <> 1";
256 $resqltmp = $db->query($tmpsql);
258 $obj = $db->fetch_object($resqltmp);
260 if ($obj && $obj->nb > 1) {
261 $msg = $langs->trans(
'ModuleEnabledAdminMustCheckRights');
269 header(
"Location: ".$_SERVER[
"PHP_SELF"].
"?mode=".$mode.$param.($page_y ?
'&page_y='.$page_y :
''));
271 } elseif ($action ==
'reset' && $user->admin &&
GETPOST(
'confirm') ==
'yes') {
273 dolibarr_set_const($db,
"MAIN_IHM_PARAMS_REV", (
int) $conf->global->MAIN_IHM_PARAMS_REV + 1,
'chaine', 0,
'', $conf->entity);
277 header(
"Location: ".$_SERVER[
"PHP_SELF"].
"?mode=".$mode.$param.($page_y ?
'&page_y='.$page_y :
''));
290 $morecss = array(
"/admin/dolistore/css/dolistore.css");
298 $help_url =
'EN:First_setup|FR:Premiers_paramétrages|ES:Primeras_configuraciones';
299 llxHeader(
'', $langs->trans(
"Setup"),
$help_url,
'',
'',
'', $morejs, $morecss, 0, 0);
305 $arrayofnatures = array(
'core'=>$langs->transnoentitiesnoconv(
"NativeModules"),
'external'=>$langs->transnoentitiesnoconv(
"External").
' - ['.$langs->trans(
"AllPublishers").
']');
306 $arrayofwarnings = array();
307 $arrayofwarningsext = array();
315 $modNameLoaded = array();
317 foreach ($modulesdir as $dir) {
320 dol_syslog(
"Scan directory ".$dir.
" for module descriptor files (modXXX.class.php)");
321 $handle = @opendir($dir);
322 if (is_resource($handle)) {
323 while (($file = readdir($handle)) !==
false) {
325 if (is_readable($dir.$file) && substr($file, 0, 3) ==
'mod' && substr($file,
dol_strlen($file) - 10) ==
'.class.php') {
326 $modName = substr($file, 0,
dol_strlen($file) - 10);
329 if (!empty($modNameLoaded[$modName])) {
330 $mesg =
"Error: Module ".$modName.
" was found twice: Into ".$modNameLoaded[$modName].
" and ".$dir.
". You probably have an old file on your disk.<br>";
337 $res = include_once $dir.$file;
338 if (class_exists($modName)) {
340 $objMod =
new $modName($db);
341 $modNameLoaded[$modName] = $dir;
342 if (!$objMod->numero > 0 && $modName !=
'modUser') {
343 dol_syslog(
'The module descriptor '.$modName.
' must have a numero property', LOG_ERR);
345 $j = $objMod->numero;
347 $modulequalified = 1;
350 $const_name =
'MAIN_MODULE_'.strtoupper(preg_replace(
'/^mod/i',
'', get_class($objMod)));
351 if ($objMod->version ==
'development' && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL < 2))) {
352 $modulequalified = 0;
354 if ($objMod->version ==
'experimental' && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL < 1))) {
355 $modulequalified = 0;
357 if (preg_match(
'/deprecated/', $objMod->version) && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL >= 0))) {
358 $modulequalified = 0;
362 if (!empty($objMod->hidden)) {
363 $modulequalified = 0;
366 if ($modulequalified > 0) {
368 $external = ($objMod->isCoreOrExternalModule() ==
'external');
371 $arrayofnatures[
'external_'.$publisher] = $langs->trans(
"External").
' - '.$publisher;
373 $arrayofnatures[
'external_'] = $langs->trans(
"External").
' - '.$langs->trans(
"UnknownPublishers");
376 ksort($arrayofnatures);
379 $filename[$i] = $modName;
380 $modules[$modName] = $objMod;
383 if (is_array($objMod->familyinfo) && !empty($objMod->familyinfo)) {
384 $familyinfo = array_merge($familyinfo, $objMod->familyinfo);
385 $familykey = key($objMod->familyinfo);
387 $familykey = $objMod->family;
390 $moduleposition = ($objMod->module_position ? $objMod->module_position :
'50');
391 if ($objMod->isCoreOrExternalModule() ==
'external' && $moduleposition < 100000) {
393 $moduleposition =
'80';
397 if (!empty($objMod->warnings_activation)) {
398 $arrayofwarnings[$modName] = $objMod->warnings_activation;
400 if (!empty($objMod->warnings_activation_ext)) {
401 $arrayofwarningsext[$modName] = $objMod->warnings_activation_ext;
404 $familyposition = (empty($familyinfo[$familykey][
'position']) ? 0 : $familyinfo[$familykey][
'position']);
405 $listOfOfficialModuleGroups = array(
'hr',
'technic',
'interface',
'technic',
'portal',
'financial',
'crm',
'base',
'products',
'srm',
'ecm',
'projects',
'other');
406 if ($external && !in_array($familykey, $listOfOfficialModuleGroups)) {
408 if (is_numeric($familyposition)) {
409 $familyposition = sprintf(
"%03d", (
int) $familyposition + 100);
413 $orders[$i] = $familyposition.
"_".$familykey.
"_".$moduleposition.
"_".$j;
416 $specialstring =
'unknown';
417 if ($objMod->version ==
'development' || $objMod->version ==
'experimental') {
418 $specialstring =
'expdev';
420 if (isset($categ[$specialstring])) {
421 $categ[$specialstring]++;
423 $categ[$specialstring] = 1;
428 dol_syslog(
"Module ".get_class($objMod).
" not qualified");
431 dol_syslog(
"Failed to load ".$dir.$file.
" ".$e->getMessage(), LOG_ERR);
434 print
"Warning bad descriptor file : ".$dir.$file.
" (Class ".$modName.
" not found into file)<br>";
437 dol_syslog(
"Failed to load ".$dir.$file.
" ".$e->getMessage(), LOG_ERR);
444 dol_syslog(
"htdocs/admin/modules.php: Failed to open directory ".$dir.
". See permission and open_basedir option.", LOG_WARNING);
448 if ($action ==
'reset_confirm' && $user->admin) {
449 if (!empty($modules[$value])) {
450 $objMod = $modules[$value];
452 if (!empty($objMod->langfiles)) {
453 $langs->loadLangs($objMod->langfiles);
457 $formconfirm =
$form->formconfirm($_SERVER[
"PHP_SELF"].
'?value='.$value.
'&mode='.$mode.$param, $langs->trans(
'ConfirmUnactivation'), $langs->trans(
GETPOST(
'confirm_message_code')),
'reset',
'',
'no', 1);
468 $nbofactivatedmodules = count($conf->modules);
481 if ($mode ==
'common' || $mode ==
'commonkanban') {
482 $desc = $langs->trans(
"ModulesDesc",
'{picto}');
483 $desc .=
' '.$langs->trans(
"ModulesDesc2",
'{picto2}');
484 $desc = str_replace(
'{picto}',
img_picto(
'',
'switch_off',
'class="size15x"'), $desc);
485 $desc = str_replace(
'{picto2}',
img_picto(
'',
'setup',
'class="size15x"'), $desc);
486 if (!count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) {
487 $deschelp =
'<div class="info hideonsmartphone">'.$desc.
"<br></div><br>\n";
490 if ($mode ==
'marketplace') {
493 if ($mode ==
'deploy') {
494 $deschelp =
'<div class="info hideonsmartphone">'.$langs->trans(
"ModulesDeployDesc", $langs->transnoentitiesnoconv(
"AvailableModules")).
"<br></div><br>\n";
496 if ($mode ==
'develop') {
497 $deschelp =
'<div class="info hideonsmartphone">'.$langs->trans(
"ModulesDevelopDesc").
"<br></div><br>\n";
503 if ($mode ==
'common' || $mode ==
'commonkanban') {
506 print
'<form method="POST" id="searchFormList" action="'.$_SERVER[
"PHP_SELF"].
'">';
507 print
'<input type="hidden" name="token" value="'.newToken().
'">';
508 if (isset($optioncss) && $optioncss !=
'') {
509 print
'<input type="hidden" name="optioncss" value="'.$optioncss.
'">';
511 if (isset($sortfield) && $sortfield !=
'') {
512 print
'<input type="hidden" name="sortfield" value="'.$sortfield.
'">';
514 if (isset($sortorder) && $sortorder !=
'') {
515 print
'<input type="hidden" name="sortorder" value="'.$sortorder.
'">';
517 if (isset($page) && $page !=
'') {
518 print
'<input type="hidden" name="page" value="'.$page.
'">';
520 print
'<input type="hidden" name="mode" value="'.$mode.
'">';
526 $moreforfilter =
'<div class="valignmiddle">';
528 $moreforfilter .=
'<div class="floatright right pagination paddingtop --module-list"><ul><li>';
529 $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'));
531 $moreforfilter .=
dolGetButtonTitle($langs->trans(
'ViewList'),
'',
'fa fa-bars imgforviewmode', $_SERVER[
"PHP_SELF"].
'?mode=common'.$param,
'', ($mode ==
'common' ? 2 : 1), array(
'morecss'=>
'reposition'));
532 $moreforfilter .=
dolGetButtonTitle($langs->trans(
'ViewKanban'),
'',
'fa fa-th-list imgforviewmode', $_SERVER[
"PHP_SELF"].
'?mode=commonkanban'.$param,
'', ($mode ==
'commonkanban' ? 2 : 1), array(
'morecss'=>
'reposition'));
533 $moreforfilter .=
'</li></ul></div>';
537 $moreforfilter .=
'<div class="divfilteralone colorbacktimesheet float valignmiddle">';
538 $moreforfilter .=
'<div class="divsearchfield paddingtop paddingbottom valignmiddle inline-block">';
539 $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')).
'">';
540 $moreforfilter .=
'</div>';
541 $moreforfilter .=
'<div class="divsearchfield paddingtop paddingbottom valignmiddle inline-block">';
542 $moreforfilter .=
$form->selectarray(
'search_nature', $arrayofnatures,
dol_escape_htmltag($search_nature), $langs->trans(
'Origin'), 0, 0,
'', 0, 0, 0,
'',
'maxwidth250', 1);
543 $moreforfilter .=
'</div>';
545 $array_version = array(
'stable'=>$langs->transnoentitiesnoconv(
"Stable"));
546 if ($conf->global->MAIN_FEATURES_LEVEL < 0) {
547 $array_version[
'deprecated'] = $langs->trans(
"Deprecated");
549 if ($conf->global->MAIN_FEATURES_LEVEL > 0) {
550 $array_version[
'experimental'] = $langs->trans(
"Experimental");
552 if ($conf->global->MAIN_FEATURES_LEVEL > 1) {
553 $array_version[
'development'] = $langs->trans(
"Development");
555 $moreforfilter .=
'<div class="divsearchfield paddingtop paddingbottom valignmiddle inline-block">';
556 $moreforfilter .=
$form->selectarray(
'search_version', $array_version, $search_version, $langs->trans(
'Version'), 0, 0,
'', 0, 0, 0,
'',
'maxwidth150', 1);
557 $moreforfilter .=
'</div>';
559 $moreforfilter .=
'<div class="divsearchfield paddingtop paddingbottom valignmiddle inline-block">';
560 $moreforfilter .=
$form->selectarray(
'search_status', array(
'active'=>$langs->transnoentitiesnoconv(
"Enabled"),
'disabled'=>$langs->transnoentitiesnoconv(
"Disabled")), $search_status, $langs->trans(
'Status'), 0, 0,
'', 0, 0, 0,
'',
'maxwidth150', 1);
561 $moreforfilter .=
'</div>';
562 $moreforfilter .=
' ';
563 $moreforfilter .=
'<div class="divsearchfield valignmiddle inline-block">';
564 $moreforfilter .=
'<input type="submit" name="buttonsubmit" class="button small" value="'.dol_escape_htmltag($langs->trans(
"Refresh")).
'">';
565 if ($search_keyword || ($search_nature && $search_nature !=
'-1') || ($search_version && $search_version !=
'-1') || ($search_status && $search_status !=
'-1')) {
566 $moreforfilter .=
' ';
567 $moreforfilter .=
'<input type="submit" name="buttonreset" class="buttonreset noborderbottom" value="'.dol_escape_htmltag($langs->trans(
"Reset")).
'">';
569 $moreforfilter .=
'</div>';
570 $moreforfilter .=
'</div>';
572 $moreforfilter .=
'</div>';
574 if (!empty($moreforfilter)) {
575 print $moreforfilter;
576 $parameters = array();
577 $reshook = $hookmanager->executeHooks(
'printFieldPreListTitle', $parameters);
578 print $hookmanager->resPrint;
583 print
'<div class="clearboth"></div><br>';
585 $object =
new stdClass();
586 $parameters = array();
587 $reshook = $hookmanager->executeHooks(
'insertExtraHeader', $parameters, $object, $action);
592 $disabled_modules = array();
593 if (!empty($_SESSION[
"disablemodules"])) {
594 $disabled_modules = explode(
',', $_SESSION[
"disablemodules"]);
599 $foundoneexternalmodulewithupdate = 0;
601 $atleastonequalified = 0;
602 $atleastoneforfamily = 0;
604 foreach ($orders as $key => $value) {
606 $tab = explode(
'_', $value);
607 $familykey = $tab[1];
608 $module_position = $tab[2];
610 $modName = $filename[$key];
613 $objMod = $modules[$modName];
616 if ($mode ==
'expdev' && $objMod->version !=
'development' && $objMod->version !=
'experimental') {
620 if (!$objMod->getName()) {
621 dol_syslog(
"Error for module ".$key.
" - Property name of module looks empty", LOG_WARNING);
625 $modulenameshort = strtolower(preg_replace(
'/^mod/i',
'', get_class($objMod)));
626 $const_name =
'MAIN_MODULE_'.strtoupper(preg_replace(
'/^mod/i',
'', get_class($objMod)));
629 $modulename = $objMod->getName();
630 $moduletechnicalname = $objMod->name;
631 $moduledesc = $objMod->getDesc();
632 $moduledesclong = $objMod->getDescLong();
633 $moduleauthor = $objMod->getPublisher();
636 if ($search_keyword) {
638 if (preg_match(
'/'.preg_quote($search_keyword).
'/i', $modulename)
639 || preg_match(
'/'.preg_quote($search_keyword).
'/i', $moduletechnicalname)
640 || preg_match(
'/'.preg_quote($search_keyword).
'/i', $moduledesc)
641 || preg_match(
'/'.preg_quote($search_keyword).
'/i', $moduledesclong)
642 || preg_match(
'/'.preg_quote($search_keyword).
'/i', $moduleauthor)
650 if ($search_status) {
651 if ($search_status ==
'active' && empty($conf->global->$const_name)) {
654 if ($search_status ==
'disabled' && !empty($conf->global->$const_name)) {
658 if ($search_nature) {
659 if (preg_match(
'/^external/', $search_nature) && $objMod->isCoreOrExternalModule() !=
'external') {
663 if (preg_match(
'/^external_(.*)$/', $search_nature, $reg)) {
669 if (!$reg[1] && !empty($publisher)) {
673 if ($search_nature ==
'core' && $objMod->isCoreOrExternalModule() ==
'external') {
677 if ($search_version) {
678 if (($objMod->version ==
'development' || $objMod->version ==
'experimental' || preg_match(
'/deprecated/', $objMod->version)) && $search_version ==
'stable') {
681 if ($objMod->version !=
'development' && ($search_version ==
'development')) {
684 if ($objMod->version !=
'experimental' && ($search_version ==
'experimental')) {
687 if (!preg_match(
'/deprecated/', $objMod->version) && ($search_version ==
'deprecated')) {
692 $atleastonequalified++;
695 if (isset($objMod->langfiles) && is_array($objMod->langfiles)) {
696 foreach ($objMod->langfiles as $domain) {
697 $langs->load($domain);
702 if ($familykey != $oldfamily) {
704 print
'</table></div><br>';
707 $familytext = empty($familyinfo[$familykey][
'label']) ? $familykey : $familyinfo[$familykey][
'label'];
711 if ($mode ==
'commonkanban') {
712 print
'<div class="box-flex-container">';
714 print
'<div class="div-table-responsive">';
715 print
'<table class="tagtable liste" summary="list_of_modules">'.
"\n";
718 $atleastoneforfamily = 0;
721 $atleastoneforfamily++;
723 if ($familykey != $oldfamily) {
724 $familytext = empty($familyinfo[$familykey][
'label']) ? $familykey : $familyinfo[$familykey][
'label'];
725 $oldfamily = $familykey;
729 $version = $objMod->getVersion(0);
731 if (preg_match(
'/development/i', $version)) {
732 $versiontrans .=
img_warning($langs->trans(
"Development"),
'',
'floatleft paddingright');
734 if (preg_match(
'/experimental/i', $version)) {
735 $versiontrans .=
img_warning($langs->trans(
"Experimental"),
'',
'floatleft paddingright');
737 if (preg_match(
'/deprecated/i', $version)) {
738 $versiontrans .=
img_warning($langs->trans(
"Deprecated"),
'',
'floatleft paddingright');
740 if ($objMod->isCoreOrExternalModule() ==
'external' || preg_match(
'/development|experimental|deprecated/i', $version)) {
741 $versiontrans .= $objMod->getVersion(1);
744 if ($objMod->isCoreOrExternalModule() ==
'external'
746 $action ==
'checklastversion'
749 || !empty($conf->global->CHECKLASTVERSION_EXTERNALMODULE)
752 $checkRes = $objMod->checkForUpdate();
754 setEventMessage($objMod->getName().
' : '.$versiontrans.
' -> '.$objMod->lastVersion);
755 } elseif ($checkRes < 0) {
756 setEventMessage($objMod->getName().
' '.$langs->trans(
'CheckVersionFail'),
'warnings');
762 if ($objMod->isCoreOrExternalModule() ==
'external') {
763 $imginfo =
"info_black";
766 $codeenabledisable =
'';
770 if (in_array($modulenameshort, $disabled_modules)) {
771 $objMod->disabled =
true;
775 if (!empty($conf->global->$const_name)) {
778 if (!empty($arrayofwarnings[$modName])) {
779 $codeenabledisable .=
'<!-- This module has a warning to show when we activate it (note: your country is '.$mysoc->country_code.
') -->'.
"\n";
782 if (!empty($objMod->disabled)) {
783 $codeenabledisable .= $langs->trans(
"Disabled");
784 } elseif (!empty($objMod->always_enabled) || ((!empty($conf->multicompany->enabled) && $objMod->core_enabled) && ($user->entity || $conf->entity != 1))) {
785 if (method_exists($objMod,
'alreadyUsed') && $objMod->alreadyUsed()) {
786 $codeenabledisable .= $langs->trans(
"Used");
788 $codeenabledisable .=
img_picto($langs->trans(
"Required"),
'switch_on',
'',
false, 0, 0,
'',
'opacitymedium valignmiddle');
791 if (!empty($conf->multicompany->enabled) && $user->entity) {
795 if (!empty($objMod->warnings_unactivation[$mysoc->country_code]) && method_exists($objMod,
'alreadyUsed') && $objMod->alreadyUsed()) {
796 $codeenabledisable .=
'<a class="reposition valignmiddle" href="'.$_SERVER[
"PHP_SELF"].
'?id='.$objMod->numero.
'&token='.
newToken().
'&module_position='.$module_position.
'&action=reset_confirm&confirm_message_code='.urlencode($objMod->warnings_unactivation[$mysoc->country_code]).
'&value='.$modName.
'&mode='.$mode.$param.
'">';
797 $codeenabledisable .=
img_picto($langs->trans(
"Activated"),
'switch_on');
798 $codeenabledisable .=
'</a>';
800 $codeenabledisable .=
'<a class="reposition valignmiddle" href="'.$_SERVER[
"PHP_SELF"].
'?id='.$objMod->numero.
'&token='.
newToken().
'&module_position='.$module_position.
'&action=reset&value='.$modName.
'&mode='.$mode.
'&confirm=yes'.$param.
'">';
801 $codeenabledisable .=
img_picto($langs->trans(
"Activated"),
'switch_on');
802 $codeenabledisable .=
'</a>';
807 if (!empty($objMod->config_page_url) && !$disableSetup) {
808 $backtourlparam =
'';
809 if ($search_keyword !=
'') {
810 $backtourlparam .= ($backtourlparam ?
'&' :
'?').
'search_keyword='.urlencode($search_keyword);
812 if ($search_nature > -1) {
813 $backtourlparam .= ($backtourlparam ?
'&' :
'?').
'search_nature='.urlencode($search_nature);
815 if ($search_version > -1) {
816 $backtourlparam .= ($backtourlparam ?
'&' :
'?').
'search_version='.urlencode($search_version);
818 if ($search_status > -1) {
819 $backtourlparam .= ($backtourlparam ?
'&' :
'?').
'search_status='.urlencode($search_status);
821 $backtourl = $_SERVER[
"PHP_SELF"].$backtourlparam;
824 if (is_array($objMod->config_page_url)) {
826 foreach ($objMod->config_page_url as $page) {
829 $codetoconfig .=
'<a href="'.$urlpage.
'" title="'.$langs->trans($page).
'">'.
img_picto(ucfirst($page),
"setup").
'</a>';
832 if (preg_match(
'/^([^@]+)@([^@]+)$/i', $urlpage, $regs)) {
833 $urltouse =
dol_buildpath(
'/'.$regs[2].
'/admin/'.$regs[1], 1);
834 $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>';
836 $urltouse = $urlpage;
837 $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>';
841 } elseif (preg_match(
'/^([^@]+)@([^@]+)$/i', $objMod->config_page_url, $regs)) {
842 $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>';
844 $codetoconfig .=
'<a class="valignmiddle" href="'.$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>';
847 $codetoconfig .=
img_picto($langs->trans(
"NothingToSetup"),
"setup",
'class="opacitytransp" style="padding-right: 6px"',
false, 0, 0,
'',
'fa-15');
851 if (!empty($objMod->always_enabled)) {
853 } elseif (!empty($objMod->disabled)) {
854 $codeenabledisable .= $langs->trans(
"Disabled");
857 $warningmessage =
'';
858 if (!empty($arrayofwarnings[$modName])) {
859 $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";
860 foreach ($arrayofwarnings[$modName] as $keycountry => $cursorwarningmessage) {
861 if (preg_match(
'/^always/', $keycountry) || ($mysoc->country_code && preg_match(
'/^'.$mysoc->country_code.
'/', $keycountry))) {
862 $warningmessage .= ($warningmessage ?
"\n" :
"").$langs->trans($cursorwarningmessage, $objMod->getName(), $mysoc->country_code);
866 if ($objMod->isCoreOrExternalModule() ==
'external' && !empty($arrayofwarningsext)) {
867 $codeenabledisable .=
'<!-- This module is an external module and it may have a warning to show (note: your country is '.$mysoc->country_code.
') -->'.
"\n";
868 foreach ($arrayofwarningsext as $keymodule => $arrayofwarningsextbycountry) {
869 $keymodulelowercase = strtolower(preg_replace(
'/^mod/',
'', $keymodule));
870 if (in_array($keymodulelowercase, $conf->modules)) {
871 foreach ($arrayofwarningsextbycountry as $keycountry => $cursorwarningmessage) {
872 if (preg_match(
'/^always/', $keycountry) || ($mysoc->country_code && preg_match(
'/^'.$mysoc->country_code.
'/', $keycountry))) {
873 $warningmessage .= ($warningmessage ?
"\n" :
"").$langs->trans($cursorwarningmessage, $objMod->getName(), $mysoc->country_code, $modules[$keymodule]->getName());
874 $warningmessage .= ($warningmessage ?
"\n" :
"").($warningmessage ?
"\n" :
"").$langs->trans(
"Module").
' : '.$objMod->getName();
875 if (!empty($objMod->editor_name)) {
876 $warningmessage .= ($warningmessage ?
"\n" :
"").$langs->trans(
"Publisher").
' : '.$objMod->editor_name;
878 if (!empty($objMod->editor_name)) {
879 $warningmessage .= ($warningmessage ?
"\n" :
"").$langs->trans(
"ModuleTriggeringThisWarning").
' : '.$modules[$keymodule]->getName();
886 $codeenabledisable .=
'<!-- Message to show: '.$warningmessage.
' -->'.
"\n";
887 $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.
'"';
888 if ($warningmessage) {
889 $codeenabledisable .=
' onclick="return confirm(\''.dol_escape_js($warningmessage).
'\');
"';
891 $codeenabledisable .= '>';
892 $codeenabledisable .= img_picto($langs->trans("Disabled
"), 'switch_off');
893 $codeenabledisable .= "</a>\n
";
897 $codetoconfig .= img_picto($langs->trans("NothingToSetup
"), "setup
", 'class="opacitytransp
" style="padding-right: 6px
"');
900 if ($mode == 'commonkanban') {
902 print $objMod->getKanbanView($codeenabledisable, $codetoconfig);
904 print '<tr class="oddeven
">'."\n
";
905 if (!empty($conf->global->MAIN_MODULES_SHOW_LINENUMBERS)) {
906 print '<td class="width50
">'.$linenum.'</td>';
909 // Picto + Name of module
910 print ' <td class="tdoverflowmax300
" title="'.dol_escape_htmltag($objMod->getName()).'">';
912 //if (is_array($objMod->need_dolibarr_version)) $alttext.=($alttext?' - ':'').'Dolibarr >= '.join('.',$objMod->need_dolibarr_version);
913 //if (is_array($objMod->phpmin)) $alttext.=($alttext?' - ':'').'PHP >= '.join('.',$objMod->phpmin);
914 if (!empty($objMod->picto)) {
915 if (preg_match('/^\//i', $objMod->picto)) {
916 print img_picto($alttext, $objMod->picto, 'class="valignmiddle pictomodule paddingrightonly
"', 1);
918 print img_object($alttext, $objMod->picto, 'class="valignmiddle pictomodule paddingrightonly
"');
921 print img_object($alttext, 'generic', 'class="valignmiddle paddingrightonly
"');
923 print ' <span class="valignmiddle
">'.$objMod->getName().'</span>';
927 print '<td class="valignmiddle tdoverflowmax300
">';
928 print nl2br($objMod->getDesc());
932 print '<td class="center nowrap
" style="width: 82px;
">';
933 //print $form->textwithpicto('', $text, 1, $imginfo, 'minheight20', 0, 2, 1);
934 print '<a href="javascript:
document_preview(\
''.DOL_URL_ROOT.
'/admin/modulehelp.php?id='.$objMod->numero.
'\',\
'text/html\',\''.dol_escape_js($langs->trans(
"Module")).
'\')
">'.img_picto(($objMod->isCoreOrExternalModule() == 'external' ? $langs->trans("ExternalModule
").' - ' : '').$langs->trans("ClickToShowDescription
"), $imginfo).'</a>';
938 print '<td class="center nowrap
" width="120px
">';
939 if ($objMod->needUpdate) {
940 $versionTitle = $langs->trans('ModuleUpdateAvailable').' : '.$objMod->lastVersion;
941 print '<span class="badge badge-warning classfortooltip
" title="'.dol_escape_htmltag($versionTitle).'">'.$versiontrans.'</span>';
947 // Link enable/disable
948 print '<td class="center valignmiddle
" width="60px
">';
949 print $codeenabledisable;
953 print '<td class="tdsetuppicto right valignmiddle
" width="60px
">';
959 if ($objMod->needUpdate) {
960 $foundoneexternalmodulewithupdate++;
964 if ($action == 'checklastversion') {
965 if ($foundoneexternalmodulewithupdate) {
966 setEventMessages($langs->trans("ModuleUpdateAvailable
"), null, 'mesgs');
968 setEventMessages($langs->trans("NoExternalModuleWithUpdate
"), null, 'mesgs');
973 if ($mode == 'commonkanban') {
981 if (!$atleastonequalified) {
982 print '<br><span class="opacitymedium
">'.$langs->trans("NoDeployedModulesFoundWithThisSearchCriteria
").'</span><br><br>';
985 print dol_get_fiche_end();
989 // Show warning about external users
990 print info_admin(showModulesExludedForExternal($modules))."\n
";
995 if ($mode == 'marketplace') {
996 print dol_get_fiche_head($head, $mode, '', -1);
1003 print '<div class="div-table-responsive-no-min
">';
1004 print '<table summary="list_of_modules
" class="noborder centpercent
">'."\n
";
1005 print '<tr class="liste_titre
">'."\n
";
1006 print '<td class="hideonsmartphone
">'.$form->textwithpicto($langs->trans("Provider
"), $langs->trans("WebSiteDesc
")).'</td>';
1008 print '<td>'.$langs->trans("URL
").'</td>';
1011 print '<tr class="oddeven
">'."\n
";
1012 $url = 'https://www.dolistore.com';
1013 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>';
1014 print '<td><span class="opacitymedium
">'.$langs->trans("DoliStoreDesc
").'</span></td>';
1015 print '<td><a href="'.$url.'" target="_blank
" rel="noopener noreferrer external
">'.$url.'</a></td>';
1021 print dol_get_fiche_end();
1025 if (empty($conf->global->MAIN_DISABLE_DOLISTORE_SEARCH) && $conf->global->MAIN_FEATURES_LEVEL >= 1) {
1026 // $options is array with filter criterias
1027 //var_dump($options);
1028 $dolistore->getRemoteCategories();
1029 $dolistore->getRemoteProducts($options);
1031 print '<span class="opacitymedium
">'.$langs->trans('DOLISTOREdescriptionLong').'</span><br><br>';
1033 $previouslink = $dolistore->get_previous_link();
1034 $nextlink = $dolistore->get_next_link();
1036 print '<div class="liste_titre liste_titre_bydiv centpercent
"><div class="divsearchfield
">';
1038 print '<form method="POST
" class="centpercent
" id="searchFormList
" action="'.urlencode($dolistore->url).'">';
1040 <input type="hidden
" name="token
" value="<?php echo
newToken(); ?>
">
1041 <input type="hidden
" name="mode
" value="marketplace
">
1042 <div class="divsearchfield
">
1043 <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>
1045 <div class="divsearchfield
">
1046 <input class="button buttongen
" value="<?php echo $langs->trans(
'Rechercher') ?>
" type="submit
">
1047 <a class="buttonreset
" href="<?php echo urlencode($dolistore->url) ?>
"><?php echo $langs->trans('Reset') ?></a>
1052 print $previouslink;
1057 print '</div></div>';
1058 print '<div class="clearboth
"></div>';
1062 <div id="category-tree-left
">
1065 echo $dolistore->get_categories(); // Do not use dol_escape_htmltag here, it is already a structured content
1069 <div id="listing-content
">
1070 <table summary="list_of_modules
" id="list_of_modules
" class="productlist centpercent
">
1071 <tbody id="listOfModules
">
1072 <?php echo $dolistore->get_products(!empty($categorie) ? $categorie: ''); ?>
1082 // Install external module
1084 if ($mode == 'deploy') {
1085 print dol_get_fiche_head($head, $mode, '', -1);
1089 $dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
1090 $allowonlineinstall = true;
1092 if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
1093 $allowonlineinstall = false;
1096 $fullurl = '<a href="'.$urldolibarrmodules.'" target="_blank
" rel="noopener noreferrer
">'.$urldolibarrmodules.'</a>';
1098 if (!empty($allowonlineinstall)) {
1099 if (!in_array('/custom', explode(',', $dolibarr_main_url_root_alt))) {
1100 $message = info_admin($langs->trans("ConfFileMustContainCustom
", DOL_DOCUMENT_ROOT.'/custom', DOL_DOCUMENT_ROOT));
1104 if (!is_writable(dol_osencode($dirins))) {
1105 $langs->load("errors
");
1106 $message = info_admin($langs->trans("ErrorFailedToWriteInDir
", $dirins), 0, 0, '1', 'warning');
1110 $message = info_admin($langs->trans("NotExistsDirect
", $dirins).$langs->trans("InfDirAlt
").$langs->trans("InfDirExample
"));
1115 $message = info_admin($langs->trans("InstallModuleFromWebHasBeenDisabledByFile
", $dolibarrdataroot.'/installmodules.lock'));
1119 if ($allowfromweb < 1) {
1120 print $langs->trans("SomethingMakeInstallFromWebNotPossible
");
1122 //print $langs->trans("SomethingMakeInstallFromWebNotPossible2
");
1128 if ($allowfromweb >= 0) {
1129 if ($allowfromweb == 1) {
1130 //print $langs->trans("ThisIsProcessToFollow
").'<br>';
1132 print $langs->trans("ThisIsAlternativeProcessToFollow
").'<br>';
1133 print '<b>'.$langs->trans("StepNb
", 1).'</b>: ';
1134 print str_replace('{s1}', $fullurl, $langs->trans("FindPackageFromWebSite
", '{s1}')).'<br>';
1135 print '<b>'.$langs->trans("StepNb
", 2).'</b>: ';
1136 print str_replace('{s1}', $fullurl, $langs->trans("DownloadPackageFromWebSite
", '{s1}')).'<br>';
1137 print '<b>'.$langs->trans("StepNb
", 3).'</b>: ';
1140 if ($allowfromweb == 1) {
1141 print '<span class="opacitymedium
">'.$langs->trans("UnpackPackageInModulesRoot
", $dirins).'</span><br>';
1145 print '<form enctype="multipart/form-data
" method="POST
" class="noborder
" action="'.$_SERVER["PHP_SELF"].'" name="forminstall
">';
1146 print '<input type="hidden
" name="token
" value="'.newToken().'">';
1147 print '<input type="hidden
" name="action
" value="install
">';
1148 print '<input type="hidden
" name="mode
" value="deploy
">';
1150 print $langs->trans("YouCanSubmitFile
");
1152 $max = $conf->global->MAIN_UPLOAD_DOC; // In Kb
1153 $maxphp = @ini_get('upload_max_filesize'); // In unknown
1154 if (preg_match('/k$/i', $maxphp)) {
1155 $maxphp = preg_replace('/k$/i', '', $maxphp);
1156 $maxphp = $maxphp * 1;
1158 if (preg_match('/m$/i', $maxphp)) {
1159 $maxphp = preg_replace('/m$/i', '', $maxphp);
1160 $maxphp = $maxphp * 1024;
1162 if (preg_match('/g$/i', $maxphp)) {
1163 $maxphp = preg_replace('/g$/i', '', $maxphp);
1164 $maxphp = $maxphp * 1024 * 1024;
1166 if (preg_match('/t$/i', $maxphp)) {
1167 $maxphp = preg_replace('/t$/i', '', $maxphp);
1168 $maxphp = $maxphp * 1024 * 1024 * 1024;
1170 $maxphp2 = @ini_get('post_max_size'); // In unknown
1171 if (preg_match('/k$/i', $maxphp2)) {
1172 $maxphp2 = preg_replace('/k$/i', '', $maxphp2);
1173 $maxphp2 = $maxphp2 * 1;
1175 if (preg_match('/m$/i', $maxphp2)) {
1176 $maxphp2 = preg_replace('/m$/i', '', $maxphp2);
1177 $maxphp2 = $maxphp2 * 1024;
1179 if (preg_match('/g$/i', $maxphp2)) {
1180 $maxphp2 = preg_replace('/g$/i', '', $maxphp2);
1181 $maxphp2 = $maxphp2 * 1024 * 1024;
1183 if (preg_match('/t$/i', $maxphp2)) {
1184 $maxphp2 = preg_replace('/t$/i', '', $maxphp2);
1185 $maxphp2 = $maxphp2 * 1024 * 1024 * 1024;
1187 // Now $max and $maxphp and $maxphp2 are in Kb
1189 $maxphptoshow = $maxphptoshowparam = '';
1191 $maxmin = min($max, $maxphp);
1192 $maxphptoshow = $maxphp;
1193 $maxphptoshowparam = 'upload_max_filesize';
1196 $maxmin = min($max, $maxphp2);
1197 if ($maxphp2 < $maxphp) {
1198 $maxphptoshow = $maxphp2;
1199 $maxphptoshowparam = 'post_max_size';
1204 print '<script type="text/javascript
">
1205 $(document).ready(function() {
1206 jQuery("#fileinstall
").on("change
", function() {
1207 if(this.files[0].size > '.($maxmin * 1024).'){
1208 alert("'.dol_escape_js($langs->trans("ErrorFileSizeTooLarge")).'");
1214 // MAX_FILE_SIZE doit précéder le champ input de type file
1215 print '<input type="hidden
" name="MAX_FILE_SIZE
" value="'.($maxmin * 1024).'">';
1218 print '<input class="flat minwidth400
" type="file
" name="fileinstall
" id="fileinstall
"> ';
1220 print '<input type="submit
" name="send
" value="'.dol_escape_htmltag($langs->trans("Upload")).'" class="button
">';
1222 if (!empty($conf->global->MAIN_UPLOAD_DOC)) {
1224 $langs->load('other');
1226 print info_admin($langs->trans("ThisLimitIsDefinedInSetup
", $max, $maxphptoshow, $maxphptoshowparam), 1);
1229 print ' ('.$langs->trans("UploadDisabled
").')';
1237 print '<div class="center
"><div class="logo_setup
"></div></div>';
1239 print $langs->trans("UnpackPackageInModulesRoot
", $dirins).'<br>';
1240 print '<b>'.$langs->trans("StepNb
", 4).'</b>: ';
1241 print $langs->trans("SetupIsReadyForUse
").'<br>';
1245 if (!empty($result['return'])) {
1248 foreach ($result['return'] as $value) {
1253 print dol_get_fiche_end();
1256 if ($mode == 'develop') {
1257 print dol_get_fiche_head($head, $mode, '', -1);
1264 print "<table summary=\
"list_of_modules\" class=\"noborder\" width=\"100%\">\n";
1265 print
"<tr class=\"liste_titre\">\n";
1267 print
'<td colspan="2">'.$langs->trans(
"DevelopYourModuleDesc").
'</td>';
1268 print
'<td>'.$langs->trans(
"URL").
'</td>';
1271 print
'<tr class="oddeven" height="80">'.
"\n";
1272 print
'<td class="left">';
1273 print
'<div class="imgmaxheight50 logo_setup"></div>';
1275 print
'<td>'.$langs->trans(
"TryToUseTheModuleBuilder", $langs->transnoentitiesnoconv(
"ModuleBuilder")).
'</td>';
1276 print
'<td class="maxwidth300">';
1277 if (!empty($conf->modulebuilder->enabled)) {
1278 print $langs->trans(
"SeeTopRightMenu");
1280 print
'<span class="opacitymedium">'.$langs->trans(
"ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv(
"ModuleBuilder")).
'</span>';
1285 print
'<tr class="oddeven" height="80">'.
"\n";
1286 $url =
'https://partners.dolibarr.org';
1287 print
'<td class="left">';
1288 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>';
1290 print
'<td>'.$langs->trans(
"DoliPartnersDesc").
'</td>';
1291 print
'<td><a href="'.$url.
'" target="_blank" rel="noopener noreferrer external">'.$url.
'</a></td>';