Merge branch '11.0' of git@github.com:Dolibarr/dolibarr.git into 12.0

This commit is contained in:
Laurent Destailleur 2020-06-06 21:52:55 +02:00
commit b386400365
3 changed files with 133 additions and 30 deletions

View File

@ -1081,9 +1081,6 @@ class Contact extends CommonObject
$error = 0; $error = 0;
//$this->old_lastname = $obj->lastname;
//$this->old_firstname = $obj->firstname;
$this->db->begin(); $this->db->begin();
if (!$error) if (!$error)
@ -1095,7 +1092,7 @@ class Contact extends CommonObject
$sql .= " WHERE ec.fk_socpeople=".$this->id; $sql .= " WHERE ec.fk_socpeople=".$this->id;
$sql .= " AND ec.fk_c_type_contact=tc.rowid"; $sql .= " AND ec.fk_c_type_contact=tc.rowid";
$sql .= " AND tc.source='external'"; $sql .= " AND tc.source='external'";
dol_syslog(get_class($this)."::delete", LOG_DEBUG); dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if ($resql) if ($resql)
{ {
@ -1108,7 +1105,7 @@ class Contact extends CommonObject
$sqldel = "DELETE FROM ".MAIN_DB_PREFIX."element_contact"; $sqldel = "DELETE FROM ".MAIN_DB_PREFIX."element_contact";
$sqldel .= " WHERE rowid = ".$obj->rowid; $sqldel .= " WHERE rowid = ".$obj->rowid;
dol_syslog(get_class($this)."::delete", LOG_DEBUG); dol_syslog(__METHOD__, LOG_DEBUG);
$result = $this->db->query($sqldel); $result = $this->db->query($sqldel);
if (!$result) if (!$result)
{ {
@ -1130,7 +1127,7 @@ class Contact extends CommonObject
{ {
// Remove Roles // Remove Roles
$sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_contacts WHERE fk_socpeople = ".$this->id; $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_contacts WHERE fk_socpeople = ".$this->id;
dol_syslog(get_class($this)."::delete", LOG_DEBUG); dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if (!$resql) if (!$resql)
{ {
@ -1144,7 +1141,7 @@ class Contact extends CommonObject
{ {
// Remove category // Remove category
$sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_contact WHERE fk_socpeople = ".$this->id; $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_contact WHERE fk_socpeople = ".$this->id;
dol_syslog(get_class($this)."::delete", LOG_DEBUG); dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if (!$resql) if (!$resql)
{ {
@ -1158,7 +1155,7 @@ class Contact extends CommonObject
{ {
$sql = "DELETE FROM ".MAIN_DB_PREFIX."socpeople"; $sql = "DELETE FROM ".MAIN_DB_PREFIX."socpeople";
$sql .= " WHERE rowid=".$this->id; $sql .= " WHERE rowid=".$this->id;
dol_syslog(get_class($this)."::delete", LOG_DEBUG); dol_syslog(__METHOD__, LOG_DEBUG);
$result = $this->db->query($sql); $result = $this->db->query($sql);
if (!$result) if (!$result)
{ {

View File

@ -443,10 +443,14 @@ abstract class CommonObject
public $next_prev_filter; public $next_prev_filter;
/**
* @var array List of child tables. To know object to delete on cascade.
* if name like with @ClassNAme:FilePathClass;ParentFkFieldName' it will
* call method deleteByParentField(parentId,ParentFkFieldName) to fetch and delete child object
*/
protected $childtablesoncascade = array();
// No constructor as it is an abstract class // No constructor as it is an abstract class
/** /**
* Check an object id/ref exists * Check an object id/ref exists
* If you don't need/want to instantiate object and just need to know if object exists, use this method instead of fetch * If you don't need/want to instantiate object and just need to know if object exists, use this method instead of fetch
@ -8297,18 +8301,43 @@ abstract class CommonObject
} }
// Delete cascade first // Delete cascade first
if (!empty($this->childtablesoncascade)) { if (is_array($this->childtablesoncascade) && !empty($this->childtablesoncascade)) {
foreach ($this->childtablesoncascade as $table) foreach ($this->childtablesoncascade as $table)
{ {
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$table.' WHERE '.$this->fk_element.' = '.$this->id; $deleteFromObject = explode(':', $table);
$resql = $this->db->query($sql); if (count($deleteFromObject)>=2) {
if (!$resql) $className = str_replace('@', '', $deleteFromObject[0]);
{ $filePath = $deleteFromObject[1];
$this->error = $this->db->lasterror(); $columnName = $deleteFromObject[2];
$this->errors[] = $this->error; if (dol_include_once($filePath)) {
$this->db->rollback(); $childObject = new $className($this->db);
return -1; if (method_exists($childObject, 'deleteByParentField')) {
} $result = $childObject->deleteByParentField($this->id, $columnName);
if ($result < 0) {
$error++;
$this->errors[] = $childObject->error;
break;
}
} else {
$error++;
$this->errors[] = "You defined a cascade delete on an object $childObject but there is no method deleteByParentField for it";
break;
}
} else {
$error++;
$this->errors[] = 'Cannot include child class file ' .$filePath;
break;
}
} else {
$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $table . ' WHERE ' . $this->fk_element . ' = ' . $this->id;
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->error = $this->db->lasterror();
$this->errors[] = $this->error;
break;
}
}
} }
} }
@ -8348,6 +8377,62 @@ abstract class CommonObject
} }
} }
/**
* Delete all child object from a parent ID
*
* @param int $parentId Parent Id
* @param string $parentField Name of Foreign key parent column
* @return int <0 if KO, >0 if OK
* @throws Exception
*/
public function deleteByParentField($parentId = 0, $parentField = '')
{
global $user;
$error = 0;
$deleted = 0;
if (!empty($parentId) && !empty($parentField)) {
$this->db->begin();
$sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . $this->table_element;
$sql .= ' WHERE '.$parentField.' = ' . (int) $parentId;
$resql = $this->db->query($sql);
if (!$resql) {
$this->errors[] = $this->db->lasterror();
$error++;
} else {
while ($obj = $this->db->fetch_object($resql)) {
$result = $this->fetch($obj->rowid);
if ($result < 0) {
$error++;
$this->errors[] = $this->error;
} else {
$result = $this->delete($user);
if ($result < 0) {
$error++;
$this->errors[] = $this->error;
} else {
$deleted++;
}
}
}
}
if (empty($error)) {
$this->db->commit();
return $deleted;
} else {
$this->error = implode(', ', $this->errors);
$this->db->rollback();
return $error * -1;
}
}
return $deleted;
}
/** /**
* Delete a line of object in database * Delete a line of object in database
* *

View File

@ -83,7 +83,8 @@ class Societe extends CommonObject
); );
/** /**
* @var array List of child tables. To know object to delete on cascade. * @var array List of child tables. To know object to delete on cascade.
* if name like with @ClassNAme:FilePathClass;ParentFkFieldName' it will call method deleteByParentField (with parentId as parameters) and FieldName to fetch and delete child object
*/ */
protected $childtablesoncascade = array( protected $childtablesoncascade = array(
"societe_prices", "societe_prices",
@ -91,7 +92,7 @@ class Societe extends CommonObject
"product_fournisseur_price", "product_fournisseur_price",
"product_customer_price_log", "product_customer_price_log",
"product_customer_price", "product_customer_price",
"socpeople", "@Contact:/contact/class/contact.class.php:fk_soc",
"adherent", "adherent",
"societe_account", "societe_account",
"societe_rib", "societe_rib",
@ -1762,16 +1763,36 @@ class Societe extends CommonObject
} }
} }
foreach ($this->childtablesoncascade as $tabletodelete) if (!$error)
{ {
if (!$error) foreach ($this->childtablesoncascade as $tabletodelete)
{ {
$sql = "DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete; $deleteFromObject=explode(':', $tabletodelete);
$sql .= " WHERE fk_soc = ".$id; if (count($deleteFromObject)>=2) {
if (!$this->db->query($sql)) $className=str_replace('@', '', $deleteFromObject[0]);
{ $filepath=$deleteFromObject[1];
$error++; $columnName=$deleteFromObject[2];
$this->errors[] = $this->db->lasterror(); if (dol_include_once($filepath)) {
$child_object = new $className($this->db);
$result = $child_object->deleteByParentField($id, $columnName);
if ($result < 0) {
$error++;
$this->errors[] = $child_object->error;
break;
}
} else {
$error++;
$this->errors[] = 'Cannot include child class file ' .$filepath;
break;
}
} else {
$sql = "DELETE FROM " . MAIN_DB_PREFIX . $tabletodelete;
$sql .= " WHERE fk_soc = " . $id;
if (!$this->db->query($sql)) {
$error++;
$this->errors[] = $this->db->lasterror();
break;
}
} }
} }
} }