From 6c82b1d0e1bd57e65e4f2c4e426c566ba10df51d Mon Sep 17 00:00:00 2001 From: Indelog Date: Tue, 5 Oct 2021 11:18:42 +0200 Subject: [PATCH 1/7] Fix creataing invoice originating for custom module This fix the invoice create form when we provide `origin` element in url. The actual create form overide the value for origin field with `$objectsrc->element`. This make creation of invoice originating from a custom module module impossible because we need the module part to instantiate the class for the custom module object. This also modify Common Object::fetch Object Linked() to append the module part for `$sourcetype` and `$targettype` if it not set and object have module property and it not in core module. --- htdocs/compta/facture/card.php | 6 ++++-- htdocs/core/class/commonobject.class.php | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 6ea03d8bd23..1e2eb0bd8bb 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -3730,8 +3730,10 @@ if ($action == 'create') { print ''."\n"; print ''."\n"; print ''."\n"; - print ''; - print ''; + // The lines below override the parameters set by GET or POST for origin value and also be present in $origin and $originid variables (it make creation of invoice originating from an external module object impossible because for get an external module class we also need to know the name of the module in addition of the name of the element). + // This input fields already printed above at the
begin. + //print ''; + //print ''; switch (get_class($objectsrc)) { case 'Propal': diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index ab258d736ff..c4564ddcd6d 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3708,10 +3708,23 @@ abstract class CommonObject } } + // Elements of the core modules which have `$module` property but may to which we don't want to prefix module part to the element name for finding the linked object in llx_element_element. + // It's because an entry for this element may be exist in llx_element_element before this modification (version <=14.2) and ave named only with their element name in fk_source or fk_target. + $coremodule = array('knowledgemanagement', 'partnership', 'workstation', 'ticket', 'recruitment', 'eventorganization'); + $sourceid = (!empty($sourceid) ? $sourceid : $this->id); $targetid = (!empty($targetid) ? $targetid : $this->id); - $sourcetype = (!empty($sourcetype) ? $sourcetype : $this->element); - $targettype = (!empty($targettype) ? $targettype : $this->element); + // For module whit + if (empty($sourcetype)) { + // If empty $sourcetype and no core module, add module part for searching element in llx_element_element (needed for external module). + if (!empty($this->module) && ! in_array($this->module, $coremodule)) $sourcetype = $this->module.'_'.$this->element; + else $sourcetype = $this->element; + } + if (empty($targettype)) { + // If empty $targettype and no core module, add module part for searching element in llx_element_element (needed for external module). + if (!empty($this->module) && ! in_array($this->module, $coremodule)) $targettype = $this->module.'_'.$this->element; + else $targettype = $this->element; + } /*if (empty($sourceid) && empty($targetid)) { From 39cc2ca5b6142252e5bf942f0ab40f2caaa74c96 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Tue, 5 Oct 2021 09:42:52 +0000 Subject: [PATCH 2/7] Fixing style errors. --- htdocs/compta/facture/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 1e2eb0bd8bb..0eb2a503e42 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -3731,7 +3731,7 @@ if ($action == 'create') { print ''."\n"; print ''."\n"; // The lines below override the parameters set by GET or POST for origin value and also be present in $origin and $originid variables (it make creation of invoice originating from an external module object impossible because for get an external module class we also need to know the name of the module in addition of the name of the element). - // This input fields already printed above at the begin. + // This input fields already printed above at the begin. //print ''; //print ''; From fb775e2c6eb5f0e92e59b70536fd758fb63d2074 Mon Sep 17 00:00:00 2001 From: Indelog Date: Wed, 6 Oct 2021 12:14:46 +0200 Subject: [PATCH 3/7] Fix Add module part in llx_element_element on CommonObject::add_object_linked() Add module part to target type if object has $module property and is'nt in core modules. --- htdocs/core/class/commonobject.class.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index c4564ddcd6d..9cb83668df9 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3623,6 +3623,12 @@ abstract class CommonObject $this->db->begin(); $error = 0; + // Elements of the core modules which have `$module` property but may to which we don't want to prefix module part to the element name for finding the linked object in llx_element_element. + // It's because an entry for this element may be exist in llx_element_element before this modification (version <=14.2) and ave named only with their element name in fk_source or fk_target. + $coremodule = array('knowledgemanagement', 'partnership', 'workstation', 'ticket', 'recruitment', 'eventorganization'); + // Add module part to target type if object has $module property and isn't in core modules. + $targettype = ((!empty($this->module) && ! in_array($this->module, $coremodule)) ? $this->module.'_' : '').$this->element; + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "element_element ("; $sql .= "fk_source"; $sql .= ", sourcetype"; @@ -3632,7 +3638,7 @@ abstract class CommonObject $sql .= ((int) $origin_id); $sql .= ", '" . $this->db->escape($origin) . "'"; $sql .= ", " . ((int) $this->id); - $sql .= ", '" . $this->db->escape($this->element) . "'"; + $sql .= ", '" . $this->db->escape($targettype) . "'"; $sql .= ")"; dol_syslog(get_class($this) . "::add_object_linked", LOG_DEBUG); @@ -3714,7 +3720,6 @@ abstract class CommonObject $sourceid = (!empty($sourceid) ? $sourceid : $this->id); $targetid = (!empty($targetid) ? $targetid : $this->id); - // For module whit if (empty($sourcetype)) { // If empty $sourcetype and no core module, add module part for searching element in llx_element_element (needed for external module). if (!empty($this->module) && ! in_array($this->module, $coremodule)) $sourcetype = $this->module.'_'.$this->element; From 45e6ea45dc6b6b749e73d267e8bd703dc9437ec1 Mon Sep 17 00:00:00 2001 From: Indelog Date: Wed, 6 Oct 2021 12:19:10 +0200 Subject: [PATCH 4/7] Fix stickler --- htdocs/core/class/commonobject.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 9cb83668df9..d41fd96edf1 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3626,8 +3626,8 @@ abstract class CommonObject // Elements of the core modules which have `$module` property but may to which we don't want to prefix module part to the element name for finding the linked object in llx_element_element. // It's because an entry for this element may be exist in llx_element_element before this modification (version <=14.2) and ave named only with their element name in fk_source or fk_target. $coremodule = array('knowledgemanagement', 'partnership', 'workstation', 'ticket', 'recruitment', 'eventorganization'); - // Add module part to target type if object has $module property and isn't in core modules. - $targettype = ((!empty($this->module) && ! in_array($this->module, $coremodule)) ? $this->module.'_' : '').$this->element; + // Add module part to target type if object has $module property and isn't in core modules. + $targettype = ((!empty($this->module) && ! in_array($this->module, $coremodule)) ? $this->module.'_' : '').$this->element; $sql = "INSERT INTO " . MAIN_DB_PREFIX . "element_element ("; $sql .= "fk_source"; From 18fb3a352b2105e13c594ca41cd75e75c216329a Mon Sep 17 00:00:00 2001 From: Indelog Date: Wed, 6 Oct 2021 17:18:45 +0200 Subject: [PATCH 5/7] Add hook to overide sourcetype and targettype for linked object This add hook `setLinkedObjectSourceTargetType` in `CommonObject::showLinkToObjectBlock()` and in `CommonObject::fetchObjectLinked()` to allow overiding sourcetype and targettype by custom modules. --- htdocs/core/class/commonobject.class.php | 54 +++++++++++------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index d41fd96edf1..1de8d8cd752 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3602,7 +3602,7 @@ abstract class CommonObject public function add_object_linked($origin = null, $origin_id = null, $f_user = null, $notrigger = 0) { // phpcs:enable - global $user; + global $user, $hookmanager, $action; $origin = (!empty($origin) ? $origin : $this->origin); $origin_id = (!empty($origin_id) ? $origin_id : $this->origin_id); $f_user = isset($f_user) ? $f_user : $user; @@ -3620,8 +3620,16 @@ abstract class CommonObject if ($origin == 'supplierorder') { $origin = 'order_supplier'; } - $this->db->begin(); - $error = 0; + + $targettype = $this->element; + + $parameters = array('sourcetype'=>$sourcetype, 'sourceid'=>$sourceid, 'targettype'=>$targettype, 'targetid'=>$targetid); + // Hook for explicitly set the targettype if it must be differtent than $this->element + $reshook = $hookmanager->executeHooks('setLinkedObjectSourceTargetType', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + if (!empty($hookmanager->resArray['targettype'])) $targettype = $hookmanager->resArray['targettype']; + if (!empty($hookmanager->resArray['sourcetype'])) $sourcetype = $hookmanager->resArray['sourcetype']; + } // Elements of the core modules which have `$module` property but may to which we don't want to prefix module part to the element name for finding the linked object in llx_element_element. // It's because an entry for this element may be exist in llx_element_element before this modification (version <=14.2) and ave named only with their element name in fk_source or fk_target. @@ -3629,6 +3637,9 @@ abstract class CommonObject // Add module part to target type if object has $module property and isn't in core modules. $targettype = ((!empty($this->module) && ! in_array($this->module, $coremodule)) ? $this->module.'_' : '').$this->element; + $this->db->begin(); + $error = 0; + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "element_element ("; $sql .= "fk_source"; $sql .= ", sourcetype"; @@ -3691,7 +3702,7 @@ abstract class CommonObject */ public function fetchObjectLinked($sourceid = null, $sourcetype = '', $targetid = null, $targettype = '', $clause = 'OR', $alsosametype = 1, $orderby = 'sourcetype', $loadalsoobjects = 1) { - global $conf; + global $conf, $hookmanager, $action; $this->linkedObjectsIds = array(); $this->linkedObjects = array(); @@ -3701,34 +3712,17 @@ abstract class CommonObject $withtargettype = false; $withsourcetype = false; - if (!empty($sourceid) && !empty($sourcetype) && empty($targetid)) { - $justsource = true; // the source (id and type) is a search criteria - if (!empty($targettype)) { - $withtargettype = true; - } - } - if (!empty($targetid) && !empty($targettype) && empty($sourceid)) { - $justtarget = true; // the target (id and type) is a search criteria - if (!empty($sourcetype)) { - $withsourcetype = true; - } - } - - // Elements of the core modules which have `$module` property but may to which we don't want to prefix module part to the element name for finding the linked object in llx_element_element. - // It's because an entry for this element may be exist in llx_element_element before this modification (version <=14.2) and ave named only with their element name in fk_source or fk_target. - $coremodule = array('knowledgemanagement', 'partnership', 'workstation', 'ticket', 'recruitment', 'eventorganization'); - $sourceid = (!empty($sourceid) ? $sourceid : $this->id); $targetid = (!empty($targetid) ? $targetid : $this->id); - if (empty($sourcetype)) { - // If empty $sourcetype and no core module, add module part for searching element in llx_element_element (needed for external module). - if (!empty($this->module) && ! in_array($this->module, $coremodule)) $sourcetype = $this->module.'_'.$this->element; - else $sourcetype = $this->element; - } - if (empty($targettype)) { - // If empty $targettype and no core module, add module part for searching element in llx_element_element (needed for external module). - if (!empty($this->module) && ! in_array($this->module, $coremodule)) $targettype = $this->module.'_'.$this->element; - else $targettype = $this->element; + $sourcetype = (!empty($sourcetype) ? $sourcetype : $this->element); + $targettype = (!empty($targettype) ? $targettype : $this->element); + + $parameters = array('sourcetype'=>$sourcetype, 'sourceid'=>$sourceid, 'targettype'=>$targettype, 'targetid'=>$targetid); + // Hook for explicitly set the targettype if it must be differtent than $this->element + $reshook = $hookmanager->executeHooks('setLinkedObjectSourceTargetType', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + if (!empty($hookmanager->resArray['sourcetype'])) $sourcetype = $hookmanager->resArray['sourcetype']; + if (!empty($hookmanager->resArray['targettype'])) $targettype = $hookmanager->resArray['targettype']; } /*if (empty($sourceid) && empty($targetid)) From 94875cdc77fa541ffe4cabc9a497b7ec95249887 Mon Sep 17 00:00:00 2001 From: Indelog Date: Mon, 11 Oct 2021 13:37:37 +0200 Subject: [PATCH 6/7] Fix : Re-add bloc to set `$withtargettype` and `$withsourcetype` --- htdocs/core/class/commonobject.class.php | 25 +++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 1de8d8cd752..864e2cdf337 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3712,19 +3712,34 @@ abstract class CommonObject $withtargettype = false; $withsourcetype = false; - $sourceid = (!empty($sourceid) ? $sourceid : $this->id); - $targetid = (!empty($targetid) ? $targetid : $this->id); - $sourcetype = (!empty($sourcetype) ? $sourcetype : $this->element); - $targettype = (!empty($targettype) ? $targettype : $this->element); - $parameters = array('sourcetype'=>$sourcetype, 'sourceid'=>$sourceid, 'targettype'=>$targettype, 'targetid'=>$targetid); // Hook for explicitly set the targettype if it must be differtent than $this->element $reshook = $hookmanager->executeHooks('setLinkedObjectSourceTargetType', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { if (!empty($hookmanager->resArray['sourcetype'])) $sourcetype = $hookmanager->resArray['sourcetype']; + if (!empty($hookmanager->resArray['sourceid'])) $sourceid = $hookmanager->resArray['sourceid']; if (!empty($hookmanager->resArray['targettype'])) $targettype = $hookmanager->resArray['targettype']; + if (!empty($hookmanager->resArray['targetid'])) $targetid = $hookmanager->resArray['targetid']; } + if (!empty($sourceid) && !empty($sourcetype) && empty($targetid)) { + $justsource = true; // the source (id and type) is a search criteria + if (!empty($targettype)) { + $withtargettype = true; + } + } + if (!empty($targetid) && !empty($targettype) && empty($sourceid)) { + $justtarget = true; // the target (id and type) is a search criteria + if (!empty($sourcetype)) { + $withsourcetype = true; + } + } + + $sourceid = (!empty($sourceid) ? $sourceid : $this->id); + $targetid = (!empty($targetid) ? $targetid : $this->id); + $sourcetype = (!empty($sourcetype) ? $sourcetype : $this->element); + $targettype = (!empty($targettype) ? $targettype : $this->element); + /*if (empty($sourceid) && empty($targetid)) { dol_syslog('Bad usage of function. No source nor target id defined (nor as parameter nor as object id)', LOG_ERR); From b29bd325fe3563537ace041e1f82b4921aa8e22c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 11 Oct 2021 15:25:25 +0200 Subject: [PATCH 7/7] Update card.php --- htdocs/compta/facture/card.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 0eb2a503e42..5b68f9f4a29 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -3730,8 +3730,7 @@ if ($action == 'create') { print ''."\n"; print ''."\n"; print ''."\n"; - // The lines below override the parameters set by GET or POST for origin value and also be present in $origin and $originid variables (it make creation of invoice originating from an external module object impossible because for get an external module class we also need to know the name of the module in addition of the name of the element). - // This input fields already printed above at the begin. + // The commented lines below are fields already added as hidden parameters before //print ''; //print '';