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/bom/class/api_boms.class.php b/htdocs/bom/class/api_boms.class.php index e199650be30..1a42e17d875 100644 --- a/htdocs/bom/class/api_boms.class.php +++ b/htdocs/bom/class/api_boms.class.php @@ -370,7 +370,7 @@ class Boms extends DolibarrApi * * @url PUT {id}/lines/{lineid} * - * @return array|bool + * @return object|bool */ public function putLine($id, $lineid, $request_data = null) { diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index ae0858ca4de..d30d88e9c37 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -4264,7 +4264,7 @@ abstract class CommonObject * @param string $field_select name of field we need to get a list * @param string $field_where name of field of object we need to get linked items * @param string $table_element name of association table - * @return array Array of record + * @return array|int Array of record, -1 if empty */ public static function getAllItemsLinkedByObjectID($fk_object_where, $field_select, $field_where, $table_element) { diff --git a/htdocs/core/db/sqlite3.class.php b/htdocs/core/db/sqlite3.class.php index 8c10c26d464..40d0f10baa8 100644 --- a/htdocs/core/db/sqlite3.class.php +++ b/htdocs/core/db/sqlite3.class.php @@ -316,7 +316,7 @@ class DoliDBSqlite3 extends DoliDB * @param string $passwd password * @param string $name name of database (not used for mysql, used for pgsql) * @param integer $port Port of database server - * @return SQLite3 Database access handler + * @return SQLite3|string Database access handler * @see close() */ public function connect($host, $login, $passwd, $name, $port = 0) 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/don/class/api_donations.class.php b/htdocs/don/class/api_donations.class.php index f9af0568bf0..eee681cea7b 100644 --- a/htdocs/don/class/api_donations.class.php +++ b/htdocs/don/class/api_donations.class.php @@ -295,7 +295,7 @@ class Donations extends DolibarrApi * @throws RestException 404 * @throws RestException 500 System error * - * @return array + * @return object */ public function validate($id, $idwarehouse = 0, $notrigger = 0) { diff --git a/htdocs/ecm/class/ecmdirectory.class.php b/htdocs/ecm/class/ecmdirectory.class.php index fb9b2a35dd0..21a43565a25 100644 --- a/htdocs/ecm/class/ecmdirectory.class.php +++ b/htdocs/ecm/class/ecmdirectory.class.php @@ -633,7 +633,7 @@ class EcmDirectory extends CommonObject * level Level of line (Added by buildPathFromId call) * * @param int $force Force reload of full arbo even if already loaded in cache $this->cats - * @return array Tableau de array + * @return array|int Tableau de array if OK, -1 if KO */ public function get_full_arbo($force = 0) { diff --git a/htdocs/expedition/class/api_shipments.class.php b/htdocs/expedition/class/api_shipments.class.php index 450fe943d7e..6a753a24cdb 100644 --- a/htdocs/expedition/class/api_shipments.class.php +++ b/htdocs/expedition/class/api_shipments.class.php @@ -502,7 +502,7 @@ class Shipments extends DolibarrApi * * @url POST {id}/validate * - * @return array + * @return object * \todo An error 403 is returned if the request has an empty body. * Error message: "Forbidden: Content type `text/plain` is not supported." * Workaround: send this in the body @@ -630,7 +630,7 @@ class Shipments extends DolibarrApi * * @url POST {id}/close * - * @return int + * @return object */ public function close($id, $notrigger = 0) { diff --git a/htdocs/fichinter/class/api_interventions.class.php b/htdocs/fichinter/class/api_interventions.class.php index 14fc9f16fcf..78b324c288d 100644 --- a/htdocs/fichinter/class/api_interventions.class.php +++ b/htdocs/fichinter/class/api_interventions.class.php @@ -336,9 +336,10 @@ class Interventions extends DolibarrApi * * @param int $id Intervention ID * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return Object Object with cleaned properties * * @url POST {id}/validate + * + * @return Object */ public function validate($id, $notrigger = 0) { @@ -371,9 +372,10 @@ class Interventions extends DolibarrApi * Close an intervention * * @param int $id Intervention ID - * @return Object Object with cleaned properties * * @url POST {id}/close + * + * @return Object */ public function closeFichinter($id) { diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index a01c8ec00d3..4245afe62b5 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -673,7 +673,7 @@ class ProductFournisseur extends Product * @param int $limit Limit * @param int $offset Offset * @param int $socid Filter on a third party id - * @return array Array of ProductFournisseur with new properties to define supplier price + * @return array|int Array of ProductFournisseur with new properties to define supplier price */ public function list_product_fournisseur_price($prodid, $sortfield = '', $sortorder = '', $limit = 0, $offset = 0, $socid = 0) { @@ -1042,7 +1042,7 @@ class ProductFournisseur extends Product * @param string $sortorder Sort order * @param int $limit Limit * @param int $offset Offset - * @return array Array of Log prices + * @return array|int Array of Log prices */ public function listProductFournisseurPriceLog($product_fourn_price_id, $sortfield = '', $sortorder = '', $limit = 0, $offset = 0) { 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) { diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 9706ffedb76..90e520cea25 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1234,7 +1234,7 @@ SetupDescription4=%s -> %s

This software is a suite of m SetupDescription5=Other Setup menu entries manage optional parameters. SetupDescriptionLink=%s - %s SetupDescription3b=Basic parameters used to customize the default behavior of your application (e.g for country-related features). -SetupDescription4b=This software is a suite of many modules/applications. The modules related to your needs must be enabled and configured. Menu entries will appears with the activation of these modules. +SetupDescription4b=This software is a suite of many modules/applications. The modules related to your needs must be activated. Menu entries will appears with the activation of these modules. AuditedSecurityEvents=Security events that are audited NoSecurityEventsAreAduited=No security events are audited. You can enable them from menu %s Audit=Security events diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 93f3e34bf2b..6f62e8f142c 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -1994,8 +1994,9 @@ if ($dirins && $action == 'addright' && !empty($module) && empty($cancel)) { $existRight = 0; $allObject = array(); - $nbOfPermissions = count($permissions); - for ($i =0; $i<$nbOfPermissions; $i++) { + $countPerms = count($permissions); + + for ($i =0; $i<$countPerms; $i++) { if ($permissions[$i][4] == $objectForPerms) { $counter++; if (count($permsForObject) < 3) { @@ -2004,9 +2005,10 @@ if ($dirins && $action == 'addright' && !empty($module) && empty($cancel)) { } $allObject[] = $permissions[$i][4]; } - $nbOfpermsInObj = count($permsForObject); + // check if label of object already exists - for ($j = 0; $j<$nbOfpermsInObj; $j++) { + $countPermsObj = count($permsForObject); + for ($j = 0; $j<$countPermsObj; $j++) { if (in_array($label, $permsForObject[$j])) { $existRight++; setEventMessages($langs->trans("ErrorExistingPermission", $langs->transnoentities($label), $langs->transnoentities($objectForPerms)), null, 'errors'); @@ -2037,6 +2039,7 @@ if ($dirins && $action == 'addright' && !empty($module) && empty($cancel)) { "; $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php'; if (!$existRight) { + //var_dump(1);exit; dolReplaceInFile($moduledescriptorfile, array('/*END '.strtoupper($objectForPerms).'*/' => $rightToAdd.'/*END '.strtoupper($objectForPerms).'*/')); setEventMessages($langs->trans('PermissionAddedSuccesfuly'), null); } @@ -2099,13 +2102,18 @@ if ($dirins && GETPOST('action') == 'update_right' && GETPOST('modifyright')&& e $x1 = $permissions[$r-1][1]; $x2 = $permissions[$r-1][4]; $x3 = $permissions[$r-1][5]; - //check existing object permission - $permsForObject =array(); + //check existing object permission + $counter = 0; + $permsForObject =array(); + $permissions = $moduleobj->rights; + $firstRight = 0; + $existRight = 0; + $allObject = array(); - $allObject = array(); - $nbOfPermissions = count($permissions); - for ($i =0; $i<$nbOfPermissions; $i++) { + $countPerms = count($permissions); + for ($i =0; $i<$countPerms; $i++) { if ($permissions[$i][4] == $objectForPerms) { + $counter++; if (count($permsForObject) < 3) { $permsForObject[] = $permissions[$i]; } @@ -2114,8 +2122,8 @@ if ($dirins && GETPOST('action') == 'update_right' && GETPOST('modifyright')&& e } if ($label != $x1 && $crud != $x3) { - $x = count($permsForObject); - for ($j = 0; $j<$x; $j++) { + $countPermsObj = count($permsForObject); + for ($j = 0; $j<$countPermsObj; $j++) { if (in_array($label, $permsForObject[$j])) { $error++; setEventMessages($langs->trans("ErrorExistingPermission", $langs->transnoentities($label), $langs->transnoentities($objectForPerms)), null, 'errors'); @@ -2158,6 +2166,70 @@ if ($dirins && GETPOST('action') == 'update_right' && GETPOST('modifyright')&& e exit; } } +// Delete permission +if ($dirins && $action == 'confirm_deleteright' && !empty($module) && GETPOST('permskey', 'int')) { + $error = 0; + // load class and check if right exist + $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; + dol_include_once($pathtofile); + $class = 'mod'.$module; + if (class_exists($class)) { + try { + $moduleobj = new $class($db); + } catch (Exception $e) { + $error++; + dol_print_error($db, $e->getMessage()); + } + } + + $permissions = $moduleobj->rights; + $key = (int) GETPOST('permskey', 'int')-1; + //get permission want to delete from permissions array + $x1 = $permissions[$key][1]; + $x2 = $permissions[$key][4]; + $x3 = $permissions[$key][5]; + //prepare right want to delete + $rightTodelete = " + \$this->rights[\$r][0] = \$this->numero . sprintf('%02d', \$r + 1); + \$this->rights[\$r][1] = '$x1'; + \$this->rights[\$r][4] = '$x2'; + \$this->rights[\$r][5] = '$x3'; + \$r++; + "; + + + $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php'; + $check = dolReplaceInFile($moduledescriptorfile, array($rightTodelete => ''."\n\t\t")); + if ($check > 0) { + //check if all permissions of object was deleted + $permsForObj = array(); + foreach ($permissions as $perms) { + $permsForObj[] = $perms[4]; + } + $permsForObj = array_count_values($permsForObj); + if ($permsForObj[$permissions[$key][4]] == 1) { + $delObjStart = dolReplaceInFile($moduledescriptorfile, array('/*'.strtoupper($permissions[$key][4].'*/') => '','/*END '.strtoupper($permissions[$key][4].'*/') => '')); + } + } + if (!$error) { + // check if module is enabled + if (isModEnabled(strtolower($module))) { + $result = unActivateModule(strtolower($module)); + dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity); + if ($result) { + setEventMessages($result, null, 'errors'); + } + header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module); + setEventMessages($langs->trans('PermissionDeletedSuccesfuly'), null); + setEventMessages($langs->trans('WarningModuleNeedRefrech', $langs->transnoentities($module)), null, 'warnings'); + exit; + } else { + header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module); + setEventMessages($langs->trans('PermissionDeletedSuccesfuly'), null); + exit; + } + } +} // Save file if ($action == 'savefile' && empty($cancel)) { $relofcustom = basename($dirins); diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 60de90d819d..b2a4caa6f86 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4869,7 +4869,7 @@ class Product extends CommonObject /** * Return all parent products for current product (first level only) * - * @return array Array of product + * @return array|int Array of product * @see hasFatherOrChild() */ public function getFather() @@ -4911,7 +4911,7 @@ class Product extends CommonObject * @param int $firstlevelonly Return only direct child * @param int $level Level of recursing call (start to 1) * @param array $parents Array of all parents of $id - * @return array Return array(prodid=>array(0=prodid, 1=>qty, 2=>product type, 3=>label, 4=>incdec, 5=>product ref) + * @return array|int Return array(prodid=>array(0=prodid, 1=>qty, 2=>product type, 3=>label, 4=>incdec, 5=>product ref) */ public function getChildsArbo($id, $firstlevelonly = 0, $level = 1, $parents = array()) { diff --git a/htdocs/product/dynamic_price/class/price_global_variable_updater.class.php b/htdocs/product/dynamic_price/class/price_global_variable_updater.class.php index 317bc7fb5fd..d43a2e3bf56 100644 --- a/htdocs/product/dynamic_price/class/price_global_variable_updater.class.php +++ b/htdocs/product/dynamic_price/class/price_global_variable_updater.class.php @@ -367,7 +367,7 @@ class PriceGlobalVariableUpdater /** * List all price global variables * - * @return array Array of price global variable updaters + * @return array|int Array of price global variable updaters */ public function listUpdaters() { @@ -404,7 +404,7 @@ class PriceGlobalVariableUpdater /** * List all updaters which need to be processed * - * @return array Array of price global variable updaters + * @return array|int Array of price global variable updaters */ public function listPendingUpdaters() { diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php index 3ce244a4bb1..66cccc55489 100644 --- a/htdocs/product/stock/class/entrepot.class.php +++ b/htdocs/product/stock/class/entrepot.class.php @@ -577,7 +577,7 @@ class Entrepot extends CommonObject /** * Return number of unique different product into a warehouse * - * @return Array Array('nb'=>Nb, 'value'=>Value) + * @return array|int Array('nb'=>Nb, 'value'=>Value) */ public function nb_different_products() { @@ -608,7 +608,7 @@ class Entrepot extends CommonObject /** * Return stock and value of warehosue * - * @return Array Array('nb'=>Nb, 'value'=>Value) + * @return array|int Array('nb'=>Nb, 'value'=>Value) */ public function nb_products() { diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 6eb7384c11d..51bae7ab6e9 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -2313,4 +2313,28 @@ class Project extends CommonObject $this->lines = $taskstatic->getTasksArray(0, $user, $this->id, 0, 0, '', '-1', '', 0, 0, array(), 0, array(), 0, $loadRoleMode); } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Function sending an email to the current member with the text supplied in parameter. + * + * @param string $text Content of message (not html entities encoded) + * @param string $subject Subject of message + * @param array $filename_list Array of attached files + * @param array $mimetype_list Array of mime types of attached files + * @param array $mimefilename_list Array of public names of attached files + * @param string $addr_cc Email cc + * @param string $addr_bcc Email bcc + * @param int $deliveryreceipt Ask a delivery receipt + * @param int $msgishtml 1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection + * @param string $errors_to erros to + * @param string $moreinheader Add more html headers + * @return int <0 if KO, >0 if OK + */ + public function send_an_email($text, $subject, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = -1, $errors_to = '', $moreinheader = '') + { + // phpcs:enable + global $conf, $langs; + // TODO EMAIL + } } diff --git a/htdocs/public/project/new.php b/htdocs/public/project/new.php index c44002340d6..726a318c99f 100644 --- a/htdocs/public/project/new.php +++ b/htdocs/public/project/new.php @@ -368,7 +368,6 @@ if (empty($reshook) && $action == 'add') { complete_substitutions_array($substitutionarray, $outputlangs, $object); $subjecttosend = make_substitutions($subject, $substitutionarray, $outputlangs); $texttosend = make_substitutions($msg, $substitutionarray, $outputlangs); - if ($subjecttosend && $texttosend) { $moreinheader = 'X-Dolibarr-Info: send_an_email by public/lead/new.php'."\r\n"; diff --git a/htdocs/reception/class/api_receptions.class.php b/htdocs/reception/class/api_receptions.class.php index ca46cb8909c..5e4c68fe468 100644 --- a/htdocs/reception/class/api_receptions.class.php +++ b/htdocs/reception/class/api_receptions.class.php @@ -499,10 +499,10 @@ class Receptions extends DolibarrApi * * @param int $id Reception ID * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * @return Object Object with cleaned properties * * @url POST {id}/validate * + * @return Object * \todo An error 403 is returned if the request has an empty body. * Error message: "Forbidden: Content type `text/plain` is not supported." * Workaround: send this in the body @@ -627,9 +627,10 @@ class Receptions extends DolibarrApi * * @param int $id Reception ID * @param int $notrigger Disabled triggers - * @return Object Object with cleaned properties * * @url POST {id}/close + * + * @return Object */ public function close($id, $notrigger = 0) { diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index 9921167d00c..1a1b3818848 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -523,8 +523,8 @@ class Thirdparties extends DolibarrApi /** * Delete thirdparty * - * @param int $id Thirdparty ID - * @return array + * @param int $id Thirdparty ID + * @return array */ public function delete($id) { @@ -1351,10 +1351,10 @@ class Thirdparties extends DolibarrApi /** * Generate a Document from a bank account record (like SEPA mandate) * - * @param int $id Thirdparty id - * @param int $companybankid Companybank id - * @param string $model Model of document to generate - * @return array + * @param int $id Thirdparty id + * @param int $companybankid Companybank id + * @param string $model Model of document to generate + * @return array * * @url GET {id}/generateBankAccountDocument/{companybankid}/{model} */ diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index f2e6d19afa8..55f2eab63d9 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -1944,7 +1944,7 @@ class SupplierProposal extends CommonObject * @param int $offset For pagination * @param string $sortfield Sort criteria * @param string $sortorder Sort order - * @return int -1 if KO, array with result if OK + * @return array|int -1 if KO, array with result if OK */ public function liste_array($shortlist = 0, $draft = 0, $notcurrentuser = 0, $socid = 0, $limit = 0, $offset = 0, $sortfield = 'p.datec', $sortorder = 'DESC') { @@ -2225,7 +2225,7 @@ class SupplierProposal extends CommonObject * * @param User $user Object user * @param int $mode "opened" for askprice to close, "signed" for proposal to invoice - * @return int <0 if KO, >0 if OK + * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK */ public function load_board($user, $mode) {