diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index f5a05e2bf97..2ab753d4272 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -8024,6 +8024,7 @@ class Form
$InfoFieldList = array();
if ($objectfield) { // We must retreive the objectdesc from the field or extrafield
+ // Example: $objectfield = 'product:options_package'
$tmparray = explode(':', $objectfield);
$objectdesc = '';
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 90e8faf65ed..601723d506c 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -12148,7 +12148,17 @@ function fetchObjectByElement($element_id, $element_type, $element_ref = '')
$element_prop = getElementProperties($element_type);
- if (is_array($element_prop) && isModEnabled($element_prop['module'])) {
+ if ($element_prop['module'] == 'product' || $element_prop['module'] == 'service') {
+ // For example, for an extrafield 'product' (shared for both product and service) that is a link to an object,
+ // this is called with $element_type = 'product' when we need element properties of a service, we must return a product. If we create the
+ // extrafield for a service, it is not supported and not found when editing the product/service card. So we must keep 'product' for extrafields
+ // of service and we will return properties of a product.
+ $ismodenabled = (isModEnabled('product') || isModEnabled('service'));
+ } else {
+ $ismodenabled = isModEnabled($element_prop['module']);
+ }
+
+ if (is_array($element_prop) && $ismodenabled) {
dol_include_once('/'.$element_prop['classpath'].'/'.$element_prop['classfile'].'.class.php');
if (class_exists($element_prop['classname'])) {
diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php
index 7b8786baae8..ce34604cc32 100644
--- a/test/phpunit/FunctionsLibTest.php
+++ b/test/phpunit/FunctionsLibTest.php
@@ -1781,4 +1781,20 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase
return true;
}
+
+ /**
+ * testFetchObjectByElement
+ *
+ * @return boolean;
+ */
+ public function testFetchObjectByElement()
+ {
+ global $conf, $langs;
+
+ $result = fetchObjectByElement(0, 'product');
+
+ $this->assertTrue(is_object($result));
+
+ return true;
+ }
}