diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index 5bf3fef4a3f..6d279074ed9 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -326,25 +326,8 @@ if (empty($reshook)) if ($result >= 0 && ! count($object->errors)) { - // Categories association - // First we delete all categories association - $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'categorie_member'; - $sql .= ' WHERE fk_member = ' . $object->id; - $resql = $db->query($sql); - if (! $resql) dol_print_error($db); - - // Then we add the associated categories $categories = GETPOST('memcats', 'array'); - - if (! empty($categories)) - { - $cat = new Categorie($db); - foreach ($categories as $id_category) - { - $cat->fetch($id_category); - $cat->add_type($object, 'member'); - } - } + $object->setCategories($categories); // Logo/Photo save $dir= $conf->adherent->dir_output . '/' . get_exdir($object->id,2,0,1,$object,'member').'/photos'; @@ -560,15 +543,7 @@ if (empty($reshook)) { // Categories association $memcats = GETPOST('memcats', 'array'); - if (! empty($memcats)) - { - $cat = new Categorie($db); - foreach ($memcats as $id_category) - { - $cat->fetch($id_category); - $cat->add_type($object, 'member'); - } - } + $object->setCategories($memcats); $db->commit(); $rowid=$object->id; diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 4628c64251b..29cc0aac249 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -1959,6 +1959,49 @@ class Adherent extends CommonObject } } + /** + * Sets object to supplied categories. + * + * Deletes object from existing categories not supplied. + * Adds it to non existing supplied categories. + * Existing categories are left untouch. + * + * @param int[]|int $categories Category or categories IDs + */ + public function setCategories($categories) + { + // Handle single category + if (!is_array($categories)) { + $categories = array($categories); + } + + // Get current categories + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; + $c = new Categorie($this->db); + $existing = $c->containing($this->id, Categorie::TYPE_MEMBER, 'id'); + + // Diff + if (is_array($existing)) { + $to_del = array_diff($existing, $categories); + $to_add = array_diff($categories, $existing); + } else { + $to_del = array(); // Nothing to delete + $to_add = $categories; + } + + // Process + foreach ($to_del as $del) { + $c->fetch($del); + $c->del_type($this, 'member'); + } + foreach ($to_add as $add) { + $c->fetch($add); + $c->add_type($this, 'member'); + } + + return; + } + /** * Function used to replace a thirdparty id with another one. * diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 66db4144f91..f632492a59d 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -1222,7 +1222,7 @@ class Categorie extends CommonObject * @param string $type Type of category ('customer', 'supplier', 'contact', 'product', 'member'). Old mode * (0, 1, 2, ...) is deprecated. * @param string $mode 'object'=Get array of fetched category instances, 'label'=Get array of category - * labels + * labels, 'id'= Get array of category IDs * * @return mixed Array of category objects or < 0 if KO */ @@ -1239,7 +1239,7 @@ class Categorie extends CommonObject $type = $map_type[$type]; } - $sql = "SELECT ct.fk_categorie, c.label"; + $sql = "SELECT ct.fk_categorie, c.label, c.rowid"; $sql .= " FROM " . MAIN_DB_PREFIX . "categorie_" . $this->MAP_CAT_TABLE[$type] . " as ct, " . MAIN_DB_PREFIX . "categorie as c"; $sql .= " WHERE ct.fk_categorie = c.rowid AND ct.fk_" . $this->MAP_CAT_FK[$type] . " = " . $id . " AND c.type = " . $this->MAP_ID[$type]; $sql .= " AND c.entity IN (" . getEntity( 'category', 1 ) . ")"; @@ -1249,11 +1249,11 @@ class Categorie extends CommonObject { while ($obj = $this->db->fetch_object($res)) { - if ($mode == 'label') - { + if ($mode == 'id') { + $cats[] = $obj->rowid; + } else if ($mode == 'label') { $cats[] = $obj->label; - } - else { + } else { $cat = new Categorie($this->db); $cat->fetch($obj->fk_categorie); $cats[] = $cat; diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index 9778d0c8a71..7570bf7d886 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -224,13 +224,7 @@ if (empty($reshook)) } else { // Categories association $contcats = GETPOST( 'contcats', 'array' ); - if (!empty( $contcats )) { - $cat = new Categorie( $db ); - foreach ($contcats as $id_category) { - $cat->fetch( $id_category ); - $cat->add_type( $object, 'contact' ); - } - } + $object->setCategories($contcats); } } @@ -333,13 +327,8 @@ if (empty($reshook)) // Then we add the associated categories $categories = GETPOST( 'contcats', 'array' ); - if (!empty( $categories )) { - $cat = new Categorie( $db ); - foreach ($categories as $id_category) { - $cat->fetch( $id_category ); - $cat->add_type( $object, 'contact' ); - } - } + $object->setCategories($categories); + $object->old_lastname=''; $object->old_firstname=''; $action = 'view'; diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index f3c0b9bd3f5..c48408ab281 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -1123,6 +1123,49 @@ class Contact extends CommonObject } } + /** + * Sets object to supplied categories. + * + * Deletes object from existing categories not supplied. + * Adds it to non existing supplied categories. + * Existing categories are left untouch. + * + * @param int[]|int $categories Category or categories IDs + */ + public function setCategories($categories) + { + // Handle single category + if (!is_array($categories)) { + $categories = array($categories); + } + + // Get current categories + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; + $c = new Categorie($this->db); + $existing = $c->containing($this->id, Categorie::TYPE_CONTACT, 'id'); + + // Diff + if (is_array($existing)) { + $to_del = array_diff($existing, $categories); + $to_add = array_diff($categories, $existing); + } else { + $to_del = array(); // Nothing to delete + $to_add = $categories; + } + + // Process + foreach ($to_del as $del) { + $c->fetch($del); + $c->del_type($this, 'contact'); + } + foreach ($to_add as $add) { + $c->fetch($add); + $c->add_type($this, 'contact'); + } + + return; + } + /** * Function used to replace a thirdparty id with another one. * diff --git a/htdocs/product/card.php b/htdocs/product/card.php index ffa4370ac30..b5dca48674f 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -284,13 +284,7 @@ if (empty($reshook)) { // Category association $categories = GETPOST('categories'); - if(!empty($categories)) { - $cat = new Categorie($db); - foreach($categories as $id_category) { - $cat->fetch($id_category); - $cat->add_type($object, 'product'); - } - } + $object->setCategories($categories); header("Location: ".$_SERVER['PHP_SELF']."?id=".$id); exit; @@ -379,21 +373,8 @@ if (empty($reshook)) if ($object->update($object->id, $user) > 0) { // Category association - // First we delete all categories association - $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_product"; - $sql .= " WHERE fk_product = ".$object->id; - $db->query($sql); - - // Then we add the associated categories $categories = GETPOST('categories'); - if(!empty($categories)) { - $cat = new Categorie($db); - - foreach($categories as $id_category) { - $cat->fetch($id_category); - $cat->add_type($object, 'product'); - } - } + $object->setCategories($categories); $action = 'view'; } diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 28e05ddd521..a51a1a77c7b 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -3944,6 +3944,49 @@ class Product extends CommonObject return $maxpricesupplier; } + + /** + * Sets object to supplied categories. + * + * Deletes object from existing categories not supplied. + * Adds it to non existing supplied categories. + * Existing categories are left untouch. + * + * @param int[]|int $categories Category or categories IDs + */ + public function setCategories($categories) { + // Handle single category + if (! is_array($categories)) { + $categories = array($categories); + } + + // Get current categories + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; + $c = new Categorie($this->db); + $existing = $c->containing($this->id, Categorie::TYPE_PRODUCT, 'id'); + + // Diff + if (is_array($existing)) { + $to_del = array_diff($existing, $categories); + $to_add = array_diff($categories, $existing); + } else { + $to_del = array(); // Nothing to delete + $to_add = $categories; + } + + // Process + foreach($to_del as $del) { + $c->fetch($del); + $c->del_type($this, 'product'); + } + foreach ($to_add as $add) { + $c->fetch($add); + $c->add_type($this, 'product'); + } + + return; + } + /** * Function used to replace a thirdparty id with another one. * diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 0145ff10b1c..a3bb701a259 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -3342,6 +3342,65 @@ class Societe extends CommonObject } + /** + * Sets object to supplied categories. + * + * Deletes object from existing categories not supplied. + * Adds it to non existing supplied categories. + * Existing categories are left untouch. + * + * @param int[]|int $categories Category or categories IDs + * @param string $type Category type (customer or supplier) + */ + public function setCategories($categories, $type) + { + // Decode type + if ($type == 'customer') { + $type_id = Categorie::TYPE_CUSTOMER; + $type_text = 'customer'; + } elseif ($type == 'supplier') { + $type_id = Categorie::TYPE_SUPPLIER; + $type_text = 'supplier'; + } else { + dol_syslog(__METHOD__ . ': Type ' . $type . 'is an unknown company category type. Done nothing.', LOG_ERR); + return; + } + + // Handle single category + if (!is_array($categories)) { + $categories = array($categories); + } + + // Get current categories + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; + $c = new Categorie($this->db); + $existing = $c->containing($this->id, $type_id, 'id'); + + // Diff + if (is_array($existing)) { + var_dump($existing); + var_dump($categories); + $to_del = array_diff($existing, $categories); + $to_add = array_diff($categories, $existing); + } else { + $to_del = array(); // Nothing to delete + $to_add = $categories; + } + + // Process + foreach ($to_del as $del) { + $c->fetch($del); + $c->del_type($this, $type_text); + } + foreach ($to_add as $add) { + $c->fetch($add); + $c->add_type($this, $type_text); + } + + return; + } + + /** * Function used to replace a thirdparty id with another one. * It must be used within a transaction to avoid trouble diff --git a/htdocs/societe/soc.php b/htdocs/societe/soc.php index 771c8aa87e8..aca4fcc9e4e 100644 --- a/htdocs/societe/soc.php +++ b/htdocs/societe/soc.php @@ -415,23 +415,11 @@ if (empty($reshook)) // Customer categories association $custcats = GETPOST( 'custcats', 'array' ); - if (!empty( $custcats )) { - $cat = new Categorie( $db ); - foreach ($custcats as $id_category) { - $cat->fetch( $id_category ); - $cat->add_type( $object, 'customer' ); - } - } + $object->setCategories($custcats, 'customer'); // Supplier categories association $suppcats = GETPOST('suppcats', 'array'); - if (!empty($suppcats)) { - $cat = new Categorie($db); - foreach ($suppcats as $id_category) { - $cat->fetch($id_category); - $cat->add_type($object, 'supplier'); - } - } + $object->setCategories($suppcats, 'supplier'); // Logo/Photo save $dir = $conf->societe->multidir_output[$conf->entity]."/".$object->id."/logos/"; @@ -538,36 +526,12 @@ if (empty($reshook)) } // Customer categories association - // First we delete all categories association - $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'categorie_societe'; - $sql .= ' WHERE fk_soc = ' . $object->id; - $db->query( $sql ); - - // Then we add the associated categories $categories = GETPOST( 'custcats', 'array' ); - if (!empty( $categories )) { - $cat = new Categorie( $db ); - foreach ($categories as $id_category) { - $cat->fetch( $id_category ); - $cat->add_type( $object, 'customer' ); - } - } + $object->setCategories($categories, 'customer'); // Supplier categories association - // First we delete all categories association - $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'categorie_fournisseur'; - $sql .= ' WHERE fk_soc = ' . $object->id; - $db->query($sql); - - // Then we add the associated categories $categories = GETPOST('suppcats', 'array'); - if (!empty($categories)) { - $cat = new Categorie($db); - foreach ($categories as $id_category) { - $cat->fetch($id_category); - $cat->add_type($object, 'supplier'); - } - } + $object->setCategories($categories, 'supplier'); // Logo/Photo save $dir = $conf->societe->multidir_output[$object->entity]."/".$object->id."/logos";