Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NEW : Factoring and Fix external module elementType limit #21674

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
1116653
Remove deprecated on future feature...
Oct 21, 2021
e97903a
Merge branch 'develop' of github.com:Dolibarr/dolibarr into remove_de…
Dec 4, 2021
f10c644
free db
Aug 3, 2022
7dff5dc
Merge branch '16.0' of github.com:Dolibarr/dolibarr into remove_depre…
Aug 3, 2022
068871e
Merge branch 'remove_deprecated_of_future' of github.com:atm-john/dol…
Aug 3, 2022
ff9bf7c
Merge branch 'develop' of github.com:Dolibarr/dolibarr into remove_de…
Aug 3, 2022
d34427f
Factoring fetch object from element
Aug 5, 2022
4d3e896
Fix mysql element element size for module builder
Aug 5, 2022
89a154c
Doc
Aug 5, 2022
567b3ff
Update htdocs/core/class/commonobject.class.php
Aug 6, 2022
e9a2243
Use already existing function
Aug 8, 2022
3ebc548
Use already existing function
Aug 8, 2022
50d77b8
Use already existing function
Aug 8, 2022
20c9c64
Use already existing function
Aug 8, 2022
74fb2c0
Add llx element type table
Aug 8, 2022
ba33594
Update htdocs/install/mysql/tables/llx_element_type.sql
Aug 9, 2022
96a2dc7
Update htdocs/install/mysql/migration/16.0.0-17.0.0.sql
Aug 15, 2022
75aa755
Update htdocs/install/mysql/migration/16.0.0-17.0.0.sql
Aug 15, 2022
ccf7600
Merge branch 'develop' into fix_module_builder_element_element_needs
Aug 15, 2022
80a30ff
Add class element properties
Sep 1, 2022
d3225ef
Merge branch 'develop' of github.com:Dolibarr/dolibarr into fix_modul…
Sep 1, 2022
b935d4d
Merge branch 'fix_module_builder_element_element_needs' of github.com…
Sep 1, 2022
7df3b8d
Merge branch 'fix_module_builder_element_element_needs_add_class_Elem…
Sep 1, 2022
8b504c5
Class element properties
Sep 1, 2022
a09eb7c
Add mysql migrattion crete table for element properties
Sep 1, 2022
840173c
Change sql file comment
Sep 1, 2022
dc029cb
fix fetch all
Sep 1, 2022
03cc1c3
Merge branch 'remove_deprecated_of_future' of github.com:atm-john/dol…
Sep 1, 2022
0fd5be8
Update htdocs/core/class/commonobject.class.php
Sep 1, 2022
5ec8e96
Update htdocs/core/class/elementproperties.class.php
Sep 1, 2022
ced8cf5
Fix sql create
Sep 1, 2022
34d34e1
Merge branch 'fix_module_builder_element_element_needs' of github.com…
Sep 1, 2022
aa787d2
Free memory
Sep 1, 2022
36ac817
Add todo Comment
Sep 1, 2022
5472b32
update sql
Sep 12, 2022
e5b8e90
Remove element properties class and replace by hook
Oct 24, 2022
6a6d222
Merge branch 'develop' of github.com:Dolibarr/dolibarr into fix_modul…
Oct 26, 2022
a9786cd
Fix hook
Oct 26, 2022
7f46bc2
Update htdocs/core/lib/functions.lib.php
Jul 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 23 additions & 88 deletions htdocs/core/class/commonobject.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -3828,11 +3828,9 @@ public function add_object_linked($origin = null, $origin_id = null, $f_user = n
$origin = 'order_supplier';
}

// 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', 'asset');
// 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
$targettype = $this->getElementType();

$parameters = array('targettype'=>$targettype);
// Hook for explicitly set the targettype if it must be differtent than $this->element
Expand Down Expand Up @@ -3882,6 +3880,19 @@ public function add_object_linked($origin = null, $origin_id = null, $f_user = n
}
}

/**
* return element type string formated like element_element target_type and source_type
* @return string
*/
public function getElementType()
{
// Elements of the core modules having a `$module` property but for which we may not not want to prefix the element name with the module name for finding the linked object in llx_element_element.
// It's because existing llx_element_element entries inserted prior to this modification (version <=14.2) may already use the element name alone in fk_source or fk_target (without the module name prefix).
$coremodule = array('knowledgemanagement', 'partnership', 'workstation', 'ticket', 'recruitment', 'eventorganization', 'asset');
// Add module part to target type if object has $module property and isn't in core modules.
return ((!empty($this->module) && ! in_array($this->module, $coremodule)) ? $this->module.'_' : '').$this->element;
}

/**
* Fetch array of objects linked to current object (object of enabled modules only). Links are loaded into
* this->linkedObjectsIds array +
Expand Down Expand Up @@ -4008,95 +4019,19 @@ public function fetchObjectLinked($sourceid = null, $sourcetype = '', $targetid
if (!empty($this->linkedObjectsIds)) {
$tmparray = $this->linkedObjectsIds;
foreach ($tmparray as $objecttype => $objectids) { // $objecttype is a module name ('facture', 'mymodule', ...) or a module name with a suffix ('project_task', 'mymodule_myobj', ...)
// Parse element/subelement (ex: project_task, cabinetmed_consultation, ...)
$module = $element = $subelement = $objecttype;
$regs = array();
if ($objecttype != 'supplier_proposal' && $objecttype != 'order_supplier' && $objecttype != 'invoice_supplier'
&& preg_match('/^([^_]+)_([^_]+)/i', $objecttype, $regs)) {
$module = $element = $regs[1];
$subelement = $regs[2];
}
$element_properties = getElementProperties($objecttype);
$element = $element_properties['element'];
$classpath = $element_properties['classpath'];
$classfile = $element_properties['classfile'];
$classname = $element_properties['classname'];
$module = $element_properties['module'];

$classpath = $element.'/class';
// To work with non standard classpath or module name
if ($objecttype == 'facture') {
$classpath = 'compta/facture/class';
} elseif ($objecttype == 'facturerec') {
$classpath = 'compta/facture/class';
$module = 'facture';
} elseif ($objecttype == 'propal') {
$classpath = 'comm/propal/class';
} elseif ($objecttype == 'supplier_proposal') {
$classpath = 'supplier_proposal/class';
} elseif ($objecttype == 'shipping') {
$classpath = 'expedition/class';
$subelement = 'expedition';
$module = 'expedition_bon';
} elseif ($objecttype == 'delivery') {
$classpath = 'delivery/class';
$subelement = 'delivery';
$module = 'delivery_note';
} elseif ($objecttype == 'invoice_supplier' || $objecttype == 'order_supplier') {
$classpath = 'fourn/class';
$module = 'fournisseur';
} elseif ($objecttype == 'fichinter') {
$classpath = 'fichinter/class';
$subelement = 'fichinter';
$module = 'ficheinter';
} elseif ($objecttype == 'subscription') {
$classpath = 'adherents/class';
$module = 'adherent';
} elseif ($objecttype == 'contact') {
$module = 'societe';
}
// Set classfile
$classfile = strtolower($subelement);
$classname = ucfirst($subelement);

if ($objecttype == 'order') {
$classfile = 'commande';
$classname = 'Commande';
} elseif ($objecttype == 'invoice_supplier') {
$classfile = 'fournisseur.facture';
$classname = 'FactureFournisseur';
} elseif ($objecttype == 'order_supplier') {
$classfile = 'fournisseur.commande';
$classname = 'CommandeFournisseur';
} elseif ($objecttype == 'supplier_proposal') {
$classfile = 'supplier_proposal';
$classname = 'SupplierProposal';
} elseif ($objecttype == 'facturerec') {
$classfile = 'facture-rec';
$classname = 'FactureRec';
} elseif ($objecttype == 'subscription') {
$classfile = 'subscription';
$classname = 'Subscription';
} elseif ($objecttype == 'project' || $objecttype == 'projet') {
$classpath = 'projet/class';
$classfile = 'project';
$classname = 'Project';
} elseif ($objecttype == 'conferenceorboothattendee') {
$classpath = 'eventorganization/class';
$classfile = 'conferenceorboothattendee';
$classname = 'ConferenceOrBoothAttendee';
$module = 'eventorganization';
} elseif ($objecttype == 'conferenceorbooth') {
$classpath = 'eventorganization/class';
$classfile = 'conferenceorbooth';
$classname = 'ConferenceOrBooth';
$module = 'eventorganization';
} elseif ($objecttype == 'mo') {
$classpath = 'mrp/class';
$classfile = 'mo';
$classname = 'Mo';
$module = 'mrp';
}

// Here $module, $classfile and $classname are set, we can use them.
if (isModEnabled($module) && (($element != $this->element) || $alsosametype)) {
if ($loadalsoobjects && (is_numeric($loadalsoobjects) || ($loadalsoobjects === $objecttype))) {
dol_include_once('/'.$classpath.'/'.$classfile.'.class.php');
//print '/'.$classpath.'/'.$classfile.'.class.php '.class_exists($classname);

if (class_exists($classname)) {
foreach ($objectids as $i => $objectid) { // $i is rowid into llx_element_element
$object = new $classname($this->db);
Expand Down
4 changes: 3 additions & 1 deletion htdocs/core/db/DoliDB.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ public function getRow($sql)
if ($res) {
$obj = $this->fetch_object($res);
if ($obj) {
$this->free($res);
return $obj;
} else {
return 0;
Expand All @@ -375,7 +376,6 @@ public function getRow($sql)
*
* @param string $sql The sql query string
* @return bool|array Result
* @deprecated
*/
public function getRows($sql)
{
Expand All @@ -387,6 +387,8 @@ public function getRows($sql)
$results[] = $obj;
}
}

$this->free($res);
return $results;
}

Expand Down
97 changes: 88 additions & 9 deletions htdocs/core/lib/functions.lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -10866,6 +10866,7 @@ function dolGetButtonTitle($label, $helpText = '', $iconClass = 'fa fa-file', $u
*/
function getElementProperties($element_type)
{
global $db, $hookmanager;
$regs = array();

$classfile = $classname = $classpath = '';
Expand Down Expand Up @@ -10986,35 +10987,113 @@ function getElementProperties($element_type)
'classfile' => $classfile,
'classname' => $classname
);


// Add hook
if (!is_object($hookmanager)) {
include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
$hookmanager = new HookManager($db);
}
$hookmanager->initHooks(array('elementproperties'));


// Hook params
$parameters = array(
'element_type' => $element_type,
'element_properties' => $element_properties
);

$reshook = $hookmanager->executeHooks('getElementProperties', $parameters);

if ($reshook) {
$element_properties = $hookmanager->resArray;
} else {
foreach ($hookmanager->resArray as $k => $desc) {
$element_properties[$k] = $desc;
}
}

// context of elementproperties doesn't need to exist out of this function so delete it to avoid elementproperties is equal to all
if (($key = array_search('elementproperties', $hookmanager->contextarray)) !== false) {
unset($hookmanager->contextarray[$key]);
}

return $element_properties;
}

/**
* Fetch an object from its id and element_type
* Inclusion of classes is automatic
*
* @param int $element_id Element id
* @param string $element_type Element type
* @param string $element_ref Element ref (Use this or element_id but not both)
* @return int|object object || 0 || -1 if error
* @param int $element_id Element id
* @param string $element_type Element type
* @param string $element_ref Element ref (Use this or element_id but not both)
* @param bool $useCache if you want to store object in cache
* @param int $maxCacheByType number of object in cache for this element type
* @return int|object object || 0 || -1 if error
*/
function fetchObjectByElement($element_id, $element_type, $element_ref = '')
function fetchObjectByElement($element_id, $element_type, $element_ref = '', $useCache = false, $maxCacheByType = 10)
{
global $conf, $db;

$element_prop = getElementProperties($element_type);
if (is_array($element_prop) && $conf->{$element_prop['module']}->enabled) {
dol_include_once('/'.$element_prop['classpath'].'/'.$element_prop['classfile'].'.class.php');

$objecttmp = new $element_prop['classname']($db);
$ret = $objecttmp->fetch($element_id, $element_ref);
if ($ret >= 0) {
return $objecttmp;
if ($useCache) {
$objecttmp = fetchObjectFromCache($element_prop['classname'], $element_id, $element_ref, $maxCacheByType);
if (is_object($objecttmp)) {
return $objecttmp;
}
} else {
$objecttmp = new $element_prop['classname']($db);
$ret = $objecttmp->fetch($element_id, $element_ref);
if ($ret >= 0) {
return $objecttmp;
}
}
}
return 0;
}



/**
* return an object stored in memory cache
*
* @param string $objetClassName object cs name
* @param int $objectId object Id
* @param string $objectRef object ref
* @param int $maxCacheByType max number of storable object fore each type
* @return int|object object || 0 || -1 if error
*/
function fetchObjectFromCache($objetClassName, $objectId, $objectRef = false, $maxCacheByType = 10)
{
global $db,$globalCacheForGetObjectFromCache;

if (!class_exists($objetClassName)) {
return -1;
}

if (empty($globalCacheForGetObjectFromCache[$objetClassName][$objectId])) {
$object = new $objetClassName($db);
$res = $object->fetch($objectId, $objectRef);
if ($res <= 0) {
return $res;
}

if (is_array($globalCacheForGetObjectFromCache[$objetClassName]) && count($globalCacheForGetObjectFromCache[$objetClassName]) >= $maxCacheByType) {
array_shift($globalCacheForGetObjectFromCache[$objetClassName]);
}

$globalCacheForGetObjectFromCache[$objetClassName][$objectId] = $object;
} else {
$object = $globalCacheForGetObjectFromCache[$objetClassName][$objectId];
}

return $object;
}

/**
* Return if a file can contains executable content
*
Expand Down
6 changes: 6 additions & 0 deletions htdocs/install/mysql/migration/16.0.0-17.0.0.sql
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ ALTER TABLE llx_ticket ADD email_date datetime after email_msgid;

ALTER TABLE llx_cronjob ADD COLUMN pid integer;


ALTER TABLE llx_element_element MODIFY COLUMN sourcetype VARCHAR(64) NOT NULL;
ALTER TABLE llx_element_element MODIFY COLUMN targettype VARCHAR(64) NOT NULL;
ALTER TABLE llx_c_type_contact MODIFY COLUMN element VARCHAR(64) NOT NULL;


INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-VICTORYDAY', 0, 2, '', 0, 5, 8, 1);
INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-NATIONALDAY', 0, 2, '', 0, 7, 21, 1);
INSERT INTO llx_c_hrm_public_holiday (code, entity, fk_country, dayrule, year, month, day, active) VALUES('BE-ASSOMPTION', 0, 2, '', 0, 8, 15, 1);
Expand Down
2 changes: 1 addition & 1 deletion htdocs/install/mysql/tables/llx_c_type_contact.sql
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
create table llx_c_type_contact
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
element varchar(30) NOT NULL,
element varchar(64) NOT NULL,
source varchar(8) DEFAULT 'external' NOT NULL,
code varchar(32) NOT NULL,
libelle varchar(128) NOT NULL,
Expand Down
4 changes: 2 additions & 2 deletions htdocs/install/mysql/tables/llx_element_element.sql
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ create table llx_element_element
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
fk_source integer NOT NULL,
sourcetype varchar(32) NOT NULL,
sourcetype varchar(64) NOT NULL,
fk_target integer NOT NULL,
targettype varchar(32) NOT NULL
targettype varchar(64) NOT NULL
) ENGINE=innodb;