diff --git a/htdocs/admin/index.php b/htdocs/admin/index.php index 87b49c95468..8a563191303 100644 --- a/htdocs/admin/index.php +++ b/htdocs/admin/index.php @@ -105,10 +105,15 @@ print '
'; print '
'; +$nbmodulesnotautoenabled = count($conf->modules); +if (in_array('fckeditor', $conf->modules)) $nbmodulesnotautoenabled--; +if (in_array('export', $conf->modules)) $nbmodulesnotautoenabled--; +if (in_array('import', $conf->modules)) $nbmodulesnotautoenabled--; + // Show info setup module print img_picto('', 'cog', 'class="paddingright valignmiddle double"').' '.$langs->trans("SetupDescriptionLink", DOL_URL_ROOT.'/admin/modules.php?mainmenu=home', $langs->transnoentities("Setup"), $langs->transnoentities("Modules")); print '

'.$langs->trans("SetupDescription4b"); -if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only minimal initial modules enabled +if ($nbmodulesnotautoenabled <= getDolGlobalInt('MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING', 1)) { // If only minimal initial modules enabled $langs->load("errors"); $warnpicto = img_warning($langs->trans("WarningEnableYourModulesApplications"), 'style="padding-right: 6px;"'); print '
'.$warnpicto.$langs->trans("WarningEnableYourModulesApplications").'
'; diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 837c76adadf..a42ecc5c34d 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -379,99 +379,95 @@ foreach ($modulesdir as $dir) { try { $res = include_once $dir.$file; // A class already exists in a different file will send a non catchable fatal error. if (class_exists($modName)) { - try { - $objMod = new $modName($db); - $modNameLoaded[$modName] = $dir; - if (!$objMod->numero > 0 && $modName != 'modUser') { - dol_syslog('The module descriptor '.$modName.' must have a numero property', LOG_ERR); - } - $j = $objMod->numero; + $objMod = new $modName($db); + $modNameLoaded[$modName] = $dir; + if (!$objMod->numero > 0 && $modName != 'modUser') { + dol_syslog('The module descriptor '.$modName.' must have a numero property', LOG_ERR); + } + $j = $objMod->numero; - $modulequalified = 1; + $modulequalified = 1; - // We discard modules according to features level (PS: if module is activated we always show it) - $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i', '', get_class($objMod))); - if ($objMod->version == 'development' && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL < 2))) { - $modulequalified = 0; - } - if ($objMod->version == 'experimental' && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL < 1))) { - $modulequalified = 0; - } - if (preg_match('/deprecated/', $objMod->version) && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL >= 0))) { - $modulequalified = 0; - } + // We discard modules according to features level (PS: if module is activated we always show it) + $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i', '', get_class($objMod))); + if ($objMod->version == 'development' && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL < 2))) { + $modulequalified = 0; + } + if ($objMod->version == 'experimental' && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL < 1))) { + $modulequalified = 0; + } + if (preg_match('/deprecated/', $objMod->version) && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL >= 0))) { + $modulequalified = 0; + } - // We discard modules according to property ->hidden - if (!empty($objMod->hidden)) { - $modulequalified = 0; - } + // We discard modules according to property ->hidden + if (!empty($objMod->hidden)) { + $modulequalified = 0; + } - if ($modulequalified > 0) { - $publisher = dol_escape_htmltag($objMod->getPublisher()); - $external = ($objMod->isCoreOrExternalModule() == 'external'); - if ($external) { - if ($publisher) { - $arrayofnatures['external_'.$publisher] = $langs->trans("External").' - '.$publisher; - } else { - $arrayofnatures['external_'] = $langs->trans("External").' - '.$langs->trans("UnknownPublishers"); - } - } - ksort($arrayofnatures); - - // Define array $categ with categ with at least one qualified module - $filename[$i] = $modName; - $modules[$modName] = $objMod; - - // Gives the possibility to the module, to provide his own family info and position of this family - if (is_array($objMod->familyinfo) && !empty($objMod->familyinfo)) { - $familyinfo = array_merge($familyinfo, $objMod->familyinfo); - $familykey = key($objMod->familyinfo); + if ($modulequalified > 0) { + $publisher = dol_escape_htmltag($objMod->getPublisher()); + $external = ($objMod->isCoreOrExternalModule() == 'external'); + if ($external) { + if ($publisher) { + $arrayofnatures['external_'.$publisher] = $langs->trans("External").' - '.$publisher; } else { - $familykey = $objMod->family; + $arrayofnatures['external_'] = $langs->trans("External").' - '.$langs->trans("UnknownPublishers"); } + } + ksort($arrayofnatures); - $moduleposition = ($objMod->module_position ? $objMod->module_position : '50'); - if ($objMod->isCoreOrExternalModule() == 'external' && $moduleposition < 100000) { - // an external module should never return a value lower than '80'. - $moduleposition = '80'; // External modules at end by default - } + // Define array $categ with categ with at least one qualified module + $filename[$i] = $modName; + $modules[$modName] = $objMod; - // Add list of warnings to show into arrayofwarnings and arrayofwarningsext - if (!empty($objMod->warnings_activation)) { - $arrayofwarnings[$modName] = $objMod->warnings_activation; - } - if (!empty($objMod->warnings_activation_ext)) { - $arrayofwarningsext[$modName] = $objMod->warnings_activation_ext; - } - - $familyposition = (empty($familyinfo[$familykey]['position']) ? 0 : $familyinfo[$familykey]['position']); - $listOfOfficialModuleGroups = array('hr', 'technic', 'interface', 'technic', 'portal', 'financial', 'crm', 'base', 'products', 'srm', 'ecm', 'projects', 'other'); - if ($external && !in_array($familykey, $listOfOfficialModuleGroups)) { - // 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). - if (is_numeric($familyposition)) { - $familyposition = sprintf("%03d", (int) $familyposition + 100); - } - } - - $orders[$i] = $familyposition."_".$familykey."_".$moduleposition."_".$j; // Sort by family, then by module position then number - - // Set categ[$i] - $specialstring = 'unknown'; - if ($objMod->version == 'development' || $objMod->version == 'experimental') { - $specialstring = 'expdev'; - } - if (isset($categ[$specialstring])) { - $categ[$specialstring]++; // Array of all different modules categories - } else { - $categ[$specialstring] = 1; - } - $j++; - $i++; + // Gives the possibility to the module, to provide his own family info and position of this family + if (is_array($objMod->familyinfo) && !empty($objMod->familyinfo)) { + $familyinfo = array_merge($familyinfo, $objMod->familyinfo); + $familykey = key($objMod->familyinfo); } else { - dol_syslog("Module ".get_class($objMod)." not qualified"); + $familykey = $objMod->family; } - } catch (Exception $e) { - dol_syslog("Failed to load ".$dir.$file." ".$e->getMessage(), LOG_ERR); + + $moduleposition = ($objMod->module_position ? $objMod->module_position : '50'); + if ($objMod->isCoreOrExternalModule() == 'external' && $moduleposition < 100000) { + // an external module should never return a value lower than '80'. + $moduleposition = '80'; // External modules at end by default + } + + // Add list of warnings to show into arrayofwarnings and arrayofwarningsext + if (!empty($objMod->warnings_activation)) { + $arrayofwarnings[$modName] = $objMod->warnings_activation; + } + if (!empty($objMod->warnings_activation_ext)) { + $arrayofwarningsext[$modName] = $objMod->warnings_activation_ext; + } + + $familyposition = (empty($familyinfo[$familykey]['position']) ? 0 : $familyinfo[$familykey]['position']); + $listOfOfficialModuleGroups = array('hr', 'technic', 'interface', 'technic', 'portal', 'financial', 'crm', 'base', 'products', 'srm', 'ecm', 'projects', 'other'); + if ($external && !in_array($familykey, $listOfOfficialModuleGroups)) { + // 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). + if (is_numeric($familyposition)) { + $familyposition = sprintf("%03d", (int) $familyposition + 100); + } + } + + $orders[$i] = $familyposition."_".$familykey."_".$moduleposition."_".$j; // Sort by family, then by module position then number + + // Set categ[$i] + $specialstring = 'unknown'; + if ($objMod->version == 'development' || $objMod->version == 'experimental') { + $specialstring = 'expdev'; + } + if (isset($categ[$specialstring])) { + $categ[$specialstring]++; // Array of all different modules categories + } else { + $categ[$specialstring] = 1; + } + $j++; + $i++; + } else { + dol_syslog("Module ".get_class($objMod)." not qualified"); } } else { print "Warning bad descriptor file : ".$dir.$file." (Class ".$modName." not found into file)
"; @@ -523,12 +519,10 @@ asort($orders); $nbofactivatedmodules = count($conf->modules); -//$conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING = 1000; -/*$moreinfo = $langs->trans("TitleNumberOfActivatedModules"); -$moreinfo2 = ''.($nbofactivatedmodules - 1).' / '.count($modules).''; -if ($nbofactivatedmodules <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { - $moreinfo2 .= ' '.img_warning($langs->trans("YouMustEnableOneModule")); -}*/ +$nbmodulesnotautoenabled = count($conf->modules); +if (in_array('fckeditor', $conf->modules)) $nbmodulesnotautoenabled--; +if (in_array('export', $conf->modules)) $nbmodulesnotautoenabled--; +if (in_array('import', $conf->modules)) $nbmodulesnotautoenabled--; print load_fiche_titre($langs->trans("ModulesSetup"), '', 'title_setup'); @@ -539,7 +533,7 @@ if ($mode == 'common' || $mode == 'commonkanban') { $desc .= ' '.$langs->trans("ModulesDesc2", '{picto2}'); $desc = str_replace('{picto}', img_picto('', 'switch_off', 'class="size15x"'), $desc); $desc = str_replace('{picto2}', img_picto('', 'setup', 'class="size15x"'), $desc); - if (!count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only minimal initial modules enabled + if ($nbmodulesnotautoenabled <= getDolGlobalInt('MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING', 1)) { // If only minimal initial modules enabled $deschelp = '
'.$desc."

\n"; } } @@ -553,7 +547,7 @@ if ($mode == 'develop') { $deschelp = '
'.$langs->trans("ModulesDevelopDesc")."

\n"; } -$head = modules_prepare_head($nbofactivatedmodules, count($modules)); +$head = modules_prepare_head($nbofactivatedmodules, count($modules), $nbmodulesnotautoenabled); if ($mode == 'common' || $mode == 'commonkanban') { diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 92895793082..29d9a9710c8 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -696,11 +696,12 @@ function dolibarr_set_const($db, $name, $value, $type = 'chaine', $visible = 0, /** * Prepare array with list of tabs * - * @param int $nbofactivatedmodules Number if activated modules - * @param int $nboftotalmodules Nb of total modules - * @return array Array of tabs to show + * @param int $nbofactivatedmodules Number if activated modules + * @param int $nboftotalmodules Nb of total modules + * @param int $nbmodulesnotautoenabled Nb of modules not auto enabled that are activated + * @return array Array of tabs to show */ -function modules_prepare_head($nbofactivatedmodules, $nboftotalmodules) +function modules_prepare_head($nbofactivatedmodules, $nboftotalmodules, $nbmodulesnotautoenabled) { global $langs, $conf, $user, $form; @@ -711,7 +712,7 @@ function modules_prepare_head($nbofactivatedmodules, $nboftotalmodules) $head = array(); $mode = empty($conf->global->MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT) ? 'commonkanban' : $conf->global->MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT; $head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=".$mode; - if ($nbofactivatedmodules <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only minimal initial modules enabled) + if ($nbmodulesnotautoenabled <= getDolGlobalInt('MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING', 1)) { // If only minimal initial modules enabled) //$head[$h][1] = $form->textwithpicto($langs->trans("AvailableModules"), $desc); $head[$h][1] = $langs->trans("AvailableModules"); $head[$h][1] .= $form->textwithpicto('', $langs->trans("YouMustEnableOneModule").'.

'.$desc.'', 1, 'warning'); diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index a4ca1d290a1..76ee88fda2d 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1087,18 +1087,21 @@ function get_left_menu_home($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu = $newmenu->add("/admin/index.php?mainmenu=home&leftmenu=setup", $langs->trans("Setup"), 0, $user->admin, '', $mainmenu, 'setup', 0, '', '', '', ''); if ($usemenuhider || empty($leftmenu) || $leftmenu == "setup") { + $nbmodulesnotautoenabled = count($conf->modules); + if (in_array('fckeditor', $conf->modules)) $nbmodulesnotautoenabled--; + if (in_array('export', $conf->modules)) $nbmodulesnotautoenabled--; + if (in_array('import', $conf->modules)) $nbmodulesnotautoenabled--; + // Load translation files required by the page $langs->loadLangs(array("admin", "help")); - $warnpicto = ''; if (empty($conf->global->MAIN_INFO_SOCIETE_NOM) || empty($conf->global->MAIN_INFO_SOCIETE_COUNTRY)) { $langs->load("errors"); $warnpicto = img_warning($langs->trans("WarningMandatorySetupNotComplete")); } $newmenu->add("/admin/company.php?mainmenu=home", $langs->trans("MenuCompanySetup").$warnpicto, 1); - $warnpicto = ''; - if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only user module enabled + if ($nbmodulesnotautoenabled <= getDolGlobalInt('MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING', 1)) { // If only user module enabled $langs->load("errors"); $warnpicto = img_warning($langs->trans("WarningMandatorySetupNotComplete")); } diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 8e6bd78632d..e0d7a8741a5 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -365,12 +365,16 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it */ public $phpmin; + public $phpmax; + /** * @var array Minimum version of Dolibarr required by module. * e.g.: Dolibarr ≥ 3.6 = array(3, 6) */ public $need_dolibarr_version; + public $enabled_bydefault; + /** * @var bool Whether to hide the module. */ diff --git a/htdocs/core/modules/modFckeditor.class.php b/htdocs/core/modules/modFckeditor.class.php index 9dd3fce7fcd..76d8ba4eb23 100644 --- a/htdocs/core/modules/modFckeditor.class.php +++ b/htdocs/core/modules/modFckeditor.class.php @@ -63,7 +63,7 @@ class modFckeditor extends DolibarrModules $this->config_page_url = array("fckeditor.php"); // Dependencies - $this->disabled = in_array(constant('JS_CKEDITOR'), array('disabled', 'disabled/')); + $this->disabled = (defined('JS_CKEDITOR') && in_array(constant('JS_CKEDITOR'), array('disabled', 'disabled/'))); $this->depends = array(); $this->requiredby = array('modWebsites'); $this->enabled_bydefault = true; // Will be enabled during install diff --git a/htdocs/index.php b/htdocs/index.php index f1ce8248921..dd1e36d04f8 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -42,12 +42,17 @@ $hookmanager->initHooks(array('index')); * Actions */ +$nbmodulesnotautoenabled = count($conf->modules); +if (in_array('fckeditor', $conf->modules)) $nbmodulesnotautoenabled--; +if (in_array('export', $conf->modules)) $nbmodulesnotautoenabled--; +if (in_array('import', $conf->modules)) $nbmodulesnotautoenabled--; + // Check if company name is defined (first install) if (!isset($conf->global->MAIN_INFO_SOCIETE_NOM) || empty($conf->global->MAIN_INFO_SOCIETE_NOM)) { header("Location: ".DOL_URL_ROOT."/admin/index.php?mainmenu=home&leftmenu=setup&mesg=setupnotcomplete"); exit; } -if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only user module enabled +if ($nbmodulesnotautoenabled <= getDolGlobalString('MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING', 1)) { // If only user module enabled header("Location: ".DOL_URL_ROOT."/admin/index.php?mainmenu=home&leftmenu=setup&mesg=setupnotcomplete"); exit; } diff --git a/htdocs/install/step5.php b/htdocs/install/step5.php index fc0dcf37799..6598843b882 100644 --- a/htdocs/install/step5.php +++ b/htdocs/install/step5.php @@ -29,6 +29,7 @@ * For installation: * It creates the login admin and set the MAIN_SECURITY_SALT to a random value. * It set the value for MAIN_VERSION_LAST_INSTALL + * It activates some modules * It creates the install.lock and shows the final message. * For upgrade: * It updates the value for MAIN_VERSION_LAST_UPGRADE. @@ -42,6 +43,7 @@ if (file_exists($conffile)) { } require_once $dolibarr_main_document_root.'/core/lib/admin.lib.php'; require_once $dolibarr_main_document_root.'/core/lib/security.lib.php'; // for dol_hash +require_once $dolibarr_main_document_root.'/core/lib/functions2.lib.php'; global $langs; @@ -287,6 +289,9 @@ if ($action == "set" || empty($action) || preg_match('/upgrade/i', $action)) { */ } + // List of modules to enable + $tmparray = array(); + // If we ask to force some modules to be enabled if (!empty($force_install_module)) { if (!defined('DOL_DOCUMENT_ROOT') && !empty($dolibarr_main_document_root)) { @@ -294,9 +299,53 @@ if ($action == "set" || empty($action) || preg_match('/upgrade/i', $action)) { } $tmparray = explode(',', $force_install_module); + } + + $modNameLoaded = array(); + + // Search modules dirs + $modulesdir[] = $dolibarr_main_document_root.'/core/modules/'; + + foreach ($modulesdir as $dir) { + // Load modules attributes in arrays (name, numero, orders) from dir directory + //print $dir."\n
"; + dol_syslog("Scan directory ".$dir." for module descriptor files (modXXX.class.php)"); + $handle = @opendir($dir); + if (is_resource($handle)) { + while (($file = readdir($handle)) !== false) { + if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod' && substr($file, dol_strlen($file) - 10) == '.class.php') { + $modName = substr($file, 0, dol_strlen($file) - 10); + if ($modName) { + if (!empty($modNameLoaded[$modName])) { // In cache of already loaded modules ? + $mesg = "Error: Module ".$modName." was found twice: Into ".$modNameLoaded[$modName]." and ".$dir.". You probably have an old file on your disk.
"; + setEventMessages($mesg, null, 'warnings'); + dol_syslog($mesg, LOG_ERR); + continue; + } + + try { + $res = include_once $dir.$file; // A class already exists in a different file will send a non catchable fatal error. + if (class_exists($modName)) { + $objMod = new $modName($db); + $modNameLoaded[$modName] = $dir; + if (!empty($objMod->enabled_bydefault) && !in_array($file, $tmparray)) { + $tmparray[] = $file; + } + } + } catch (Exception $e) { + dol_syslog("Failed to load ".$dir.$file." ".$e->getMessage(), LOG_ERR); + } + } + } + } + } + } + + // Loop on each modules to activate it + if (!empty($tmparray)) { foreach ($tmparray as $modtoactivate) { $modtoactivatenew = preg_replace('/\.class\.php$/i', '', $modtoactivate); - print $langs->trans("ActivateModule", $modtoactivatenew).'
'; + //print $langs->trans("ActivateModule", $modtoactivatenew).'
'; $file = $modtoactivatenew.'.class.php'; dolibarr_install_syslog('step5: activate module file='.$file); @@ -307,8 +356,10 @@ if ($action == "set" || empty($action) || preg_match('/upgrade/i', $action)) { print 'ERROR: failed to activateModule() file='.$file; } } + //print '
'; } + // Now delete the flag to say install is complete dolibarr_install_syslog('step5: remove MAIN_NOT_INSTALLED const'); $resql = $db->query("DELETE FROM ".MAIN_DB_PREFIX."const WHERE ".$db->decrypt('name')." = 'MAIN_NOT_INSTALLED'"); if (!$resql) {