diff --git a/classes/Attribute.php b/classes/Attribute.php index 5950d43a2..3f6803021 100644 --- a/classes/Attribute.php +++ b/classes/Attribute.php @@ -73,33 +73,19 @@ class AttributeCore extends ObjectModel public function delete() { - $result = Db::getInstance()->executeS(' - SELECT `id_product_attribute` - FROM `'._DB_PREFIX_.'product_attribute_combination` - WHERE `'.$this->def['primary'].'` = '.(int)$this->id - ); - - if ($result === false) - return false; - - $combination_ids = array(); - if (Db::getInstance()->numRows()) + if (!$this->hasMultishopEntries()) { - foreach ($result as $row) - $combination_ids[] = (int)$row['id_product_attribute']; - $combinations = new Collection('Combination'); - $combinations->where('id_product', '=', $this->id); + $combinations->where($this->def['primary'], '=', $this->id); foreach ($combinations as $combination) $combination->delete(); - } // Delete associated restrictions on cart rules CartRule::cleanProductRuleIntegrity('attributes', $this->id); - /* Reinitializing position */ - $this->cleanPositions((int)$this->id_attribute_group); - + /* Reinitializing position */ + $this->cleanPositions((int)$this->id_attribute_group); + } $return = parent::delete(); if ($return) Hook::exec('actionAttributeDelete', array('id_attribute' => $this->id)); @@ -357,4 +343,4 @@ class AttributeCore extends ObjectModel return (is_numeric($position)) ? $position : -1; } -} \ No newline at end of file +} diff --git a/classes/AttributeGroup.php b/classes/AttributeGroup.php index 4f8e1458f..97c7ddc37 100644 --- a/classes/AttributeGroup.php +++ b/classes/AttributeGroup.php @@ -110,33 +110,36 @@ class AttributeGroupCore extends ObjectModel public function delete() { - /* Select children in order to find linked combinations */ - $attribute_ids = Db::getInstance()->executeS(' - SELECT `id_attribute` - FROM `'._DB_PREFIX_.'attribute` - WHERE `id_attribute_group` = '.(int)$this->id - ); - if ($attribute_ids === false) - return false; - /* Removing attributes to the found combinations */ - $to_remove = array(); - foreach ($attribute_ids as $attribute) - $to_remove[] = (int)$attribute['id_attribute']; - if (!empty($to_remove) && Db::getInstance()->execute(' - DELETE FROM `'._DB_PREFIX_.'product_attribute_combination` - WHERE `id_attribute` - IN ('.implode(', ', $to_remove).')') === false) - return false; - /* Remove combinations if they do not possess attributes anymore */ - if (!AttributeGroup::cleanDeadCombinations()) - return false; - /* Also delete related attributes */ - if (Db::getInstance()->execute(' - DELETE FROM `'._DB_PREFIX_.'attribute_lang` - WHERE `id_attribute` - IN (SELECT id_attribute FROM `'._DB_PREFIX_.'attribute` WHERE `id_attribute_group` = '.(int)$this->id.')') === false || - Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'attribute` WHERE `id_attribute_group` = '.(int)$this->id) === false) - return false; + if (!$this->hasMultishopEntries()) + { + /* Select children in order to find linked combinations */ + $attribute_ids = Db::getInstance()->executeS(' + SELECT `id_attribute` + FROM `'._DB_PREFIX_.'attribute` + WHERE `id_attribute_group` = '.(int)$this->id + ); + if ($attribute_ids === false) + return false; + /* Removing attributes to the found combinations */ + $to_remove = array(); + foreach ($attribute_ids as $attribute) + $to_remove[] = (int)$attribute['id_attribute']; + if (!empty($to_remove) && Db::getInstance()->execute(' + DELETE FROM `'._DB_PREFIX_.'product_attribute_combination` + WHERE `id_attribute` + IN ('.implode(', ', $to_remove).')') === false) + return false; + /* Remove combinations if they do not possess attributes anymore */ + if (!AttributeGroup::cleanDeadCombinations()) + return false; + /* Also delete related attributes */ + if (Db::getInstance()->execute(' + DELETE FROM `'._DB_PREFIX_.'attribute_lang` + WHERE `id_attribute` + IN (SELECT id_attribute FROM `'._DB_PREFIX_.'attribute` WHERE `id_attribute_group` = '.(int)$this->id.')') === false || + Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'attribute` WHERE `id_attribute_group` = '.(int)$this->id) === false) + return false; + } $return = parent::delete(); if ($return) Hook::exec('actionAttributeGroupDelete', array('id_attribute_group' => $this->id)); diff --git a/classes/Combination.php b/classes/Combination.php index 88b56ff9f..f8626d99c 100644 --- a/classes/Combination.php +++ b/classes/Combination.php @@ -63,7 +63,6 @@ class CombinationCore extends ObjectModel public static $definition = array( 'table' => 'product_attribute', 'primary' => 'id_product_attribute', - 'multishop_specific' => true, 'fields' => array( 'id_product' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true), 'location' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 64), diff --git a/classes/Language.php b/classes/Language.php index b33575970..20bee7f45 100644 --- a/classes/Language.php +++ b/classes/Language.php @@ -465,64 +465,70 @@ class LanguageCore extends ObjectModel public function delete() { - if (empty($this->iso_code)) - $this->iso_code = Language::getIsoById($this->id); - - // Database translations deletion - $result = Db::getInstance()->executeS('SHOW TABLES FROM `'._DB_NAME_.'`'); - foreach ($result as $row) - if (preg_match('/_lang/', $row['Tables_in_'._DB_NAME_])) - if (!Db::getInstance()->execute('DELETE FROM `'.$row['Tables_in_'._DB_NAME_].'` WHERE `id_lang` = '.(int)$this->id)) - return false; - - // Delete tags - Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'tag WHERE id_lang = '.(int)$this->id); - - // Delete search words - Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'search_word WHERE id_lang = '.(int)$this->id); - - // Files deletion - foreach (Language::getFilesList($this->iso_code, _THEME_NAME_, false, false, false, true, true) as $key => $file) - if (file_exists($key)) - unlink($key); - $modList = scandir(_PS_MODULE_DIR_); - foreach ($modList as $mod) + if (!$this->hasMultishopEntries()) { - Language::recurseDeleteDir(_PS_MODULE_DIR_.$mod.'/mails/'.$this->iso_code); - $files = @scandir(_PS_MODULE_DIR_.$mod.'/mails/'); - if (count($files) <= 2) - Language::recurseDeleteDir(_PS_MODULE_DIR_.$mod.'/mails/'); - - if (file_exists(_PS_MODULE_DIR_.$mod.'/'.$this->iso_code.'.php')) + if (empty($this->iso_code)) + $this->iso_code = Language::getIsoById($this->id); + + // Database translations deletion + $result = Db::getInstance()->executeS('SHOW TABLES FROM `'._DB_NAME_.'`'); + foreach ($result as $row) + if (preg_match('/_lang/', $row['Tables_in_'._DB_NAME_])) + if (!Db::getInstance()->execute('DELETE FROM `'.$row['Tables_in_'._DB_NAME_].'` WHERE `id_lang` = '.(int)$this->id)) + return false; + + + // Delete tags + Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'tag WHERE id_lang = '.(int)$this->id); + + // Delete search words + Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'search_word WHERE id_lang = '.(int)$this->id); + + // Files deletion + foreach (Language::getFilesList($this->iso_code, _THEME_NAME_, false, false, false, true, true) as $key => $file) + if (file_exists($key)) + unlink($key); + $modList = scandir(_PS_MODULE_DIR_); + foreach ($modList as $mod) { - unlink(_PS_MODULE_DIR_.$mod.'/'.$this->iso_code.'.php'); - $files = @scandir(_PS_MODULE_DIR_.$mod); + Language::recurseDeleteDir(_PS_MODULE_DIR_.$mod.'/mails/'.$this->iso_code); + $files = @scandir(_PS_MODULE_DIR_.$mod.'/mails/'); if (count($files) <= 2) - Language::recurseDeleteDir(_PS_MODULE_DIR_.$mod); + Language::recurseDeleteDir(_PS_MODULE_DIR_.$mod.'/mails/'); + + if (file_exists(_PS_MODULE_DIR_.$mod.'/'.$this->iso_code.'.php')) + { + unlink(_PS_MODULE_DIR_.$mod.'/'.$this->iso_code.'.php'); + $files = @scandir(_PS_MODULE_DIR_.$mod); + if (count($files) <= 2) + Language::recurseDeleteDir(_PS_MODULE_DIR_.$mod); + } } + + if (file_exists(_PS_MAIL_DIR_.$this->iso_code)) + Language::recurseDeleteDir(_PS_MAIL_DIR_.$this->iso_code); + if (file_exists(_PS_TRANSLATIONS_DIR_.$this->iso_code)) + Language::recurseDeleteDir(_PS_TRANSLATIONS_DIR_.$this->iso_code); } - - if (file_exists(_PS_MAIL_DIR_.$this->iso_code)) - Language::recurseDeleteDir(_PS_MAIL_DIR_.$this->iso_code); - if (file_exists(_PS_TRANSLATIONS_DIR_.$this->iso_code)) - Language::recurseDeleteDir(_PS_TRANSLATIONS_DIR_.$this->iso_code); + if (!parent::delete()) return false; - - // delete images - $files_copy = array('/en.jpg', '/en-default-thickbox.jpg', '/en-default-home.jpg', '/en-default-large.jpg', '/en-default-medium.jpg', '/en-default-small.jpg', '/en-default-large_scene.jpg'); - $tos = array(_PS_CAT_IMG_DIR_, _PS_MANU_IMG_DIR_, _PS_PROD_IMG_DIR_, _PS_SUPP_IMG_DIR_); - foreach ($tos as $to) - foreach ($files_copy as $file) - { - $name = str_replace('/en', ''.$this->iso_code, $file); - - if (file_exists($to.$name)) - unlink($to.$name); - if (file_exists(dirname(__FILE__).'/../img/l/'.$this->id.'.jpg')) - unlink(dirname(__FILE__).'/../img/l/'.$this->id.'.jpg'); - } - + if (!$this->hasMultishopEntries()) + { + // delete images + $files_copy = array('/en.jpg', '/en-default-thickbox.jpg', '/en-default-home.jpg', '/en-default-large.jpg', '/en-default-medium.jpg', '/en-default-small.jpg', '/en-default-large_scene.jpg'); + $tos = array(_PS_CAT_IMG_DIR_, _PS_MANU_IMG_DIR_, _PS_PROD_IMG_DIR_, _PS_SUPP_IMG_DIR_); + foreach ($tos as $to) + foreach ($files_copy as $file) + { + $name = str_replace('/en', ''.$this->iso_code, $file); + + if (file_exists($to.$name)) + unlink($to.$name); + if (file_exists(dirname(__FILE__).'/../img/l/'.$this->id.'.jpg')) + unlink(dirname(__FILE__).'/../img/l/'.$this->id.'.jpg'); + } + } return Tools::generateHtaccess(); } diff --git a/classes/ObjectModel.php b/classes/ObjectModel.php index e42f2455e..8fd9b26c6 100644 --- a/classes/ObjectModel.php +++ b/classes/ObjectModel.php @@ -200,7 +200,7 @@ abstract class ObjectModelCore } // Get shop informations - if (!empty($this->def['multishop_specific'])) + if (Shop::isTableAssociated($this->def['table'])) $sql->leftJoin($this->def['table'].'_shop', 'c', 'a.'.$this->def['primary'].' = c.'.$this->def['primary'].' AND c.id_shop = '.(int)$this->id_shop); Cache::store($cache_id, Db::getInstance()->getRow($sql)); @@ -258,7 +258,7 @@ abstract class ObjectModelCore $fields = $this->formatFields(self::FORMAT_COMMON); // For retro compatibility - if (!empty($this->def['multishop_specific'])) + if (Shop::isTableAssociated($this->def['table'])) $fields = array_merge($fields, $this->getFieldsShop()); // Ensure that we get something to insert @@ -446,14 +446,14 @@ abstract class ObjectModelCore $this->id = Db::getInstance()->Insert_ID(); // Database insertion for multishop fields related to the object - if (!empty($this->def['multishop_specific'])) + if (Shop::isTableAssociated($this->def['table'])) { - $fields = $this->getFieldsShop(); - $fields[$this->def['primary']] = (int)$this->id; - $id_shop_list = Shop::getContextListShopID(); if (count($this->id_shop_list) > 0) - $id_shop_list = $this->id_shop_list; + $id_shop_list = $this->id_shop_list; + + $fields = $this->getFieldsShop(); + $fields[$this->def['primary']] = (int)$this->id; foreach ($id_shop_list as $id_shop) { @@ -461,13 +461,10 @@ abstract class ObjectModelCore $result &= Db::getInstance()->insert($this->def['table'].'_shop', $fields, $null_values); } } - else if (!Shop::isFeatureActive() && Shop::isTableAssociated($this->def['table'])) - $result &= $this->associateTo(Context::getContext()->shop->id); if (!$result) return false; - // Database insertion for multilingual fields related to the object if (!empty($this->def['multilang'])) { @@ -527,7 +524,7 @@ abstract class ObjectModelCore return false; // Database insertion for multishop fields related to the object - if (!empty($this->def['multishop_specific'])) + if (Shop::isTableAssociated($this->def['table'])) { $fields = $this->getFieldsShop(); $fields[$this->def['primary']] = (int)$this->id; @@ -628,9 +625,8 @@ abstract class ObjectModelCore $this->clearCache(); $result = true; - // Remove association to multishop table - if (!empty($this->def['multishop_specific'])) + if (Shop::isTableAssociated($this->def['table'])) { $id_shop_list = Shop::getContextListShopID(); if (count($this->id_shop_list)) @@ -638,11 +634,9 @@ abstract class ObjectModelCore $result &= Db::getInstance()->delete($this->def['table'].'_shop', '`'.$this->def['primary'].'`='.(int)$this->id.' AND id_shop IN ('.implode(', ', $id_shop_list).')'); } - else if (Shop::isTableAssociated($this->def['table'])) - $result &= Db::getInstance()->delete($this->def['table'].'_shop', '`'.$this->def['primary'].'`='.(int)$this->id); // Database deletion - $has_multishop_entries = !empty($this->def['multishop_specific']) ? $this->hasMultishopEntries() : false; + $has_multishop_entries = $this->hasMultishopEntries(); if ($result && !$has_multishop_entries) $result &= Db::getInstance()->delete($this->def['table'], '`'.pSQL($this->def['primary']).'` = '.(int)$this->id); @@ -1154,7 +1148,7 @@ abstract class ObjectModelCore */ public function hasMultishopEntries() { - if (empty($this->def['multishop_specific'])) + if (!Shop::isTableAssociated($this->def['table'])) return false; return (bool)Db::getInstance()->getValue('SELECT COUNT(*) FROM `'._DB_PREFIX_.$this->def['table'].'_shop` WHERE `'.$this->def['primary'].'` = '.(int)$this->id); @@ -1162,7 +1156,7 @@ abstract class ObjectModelCore public function isMultishop() { - return !empty($this->def['multishop_specific']) || !empty($this->def['multilang_shop']); + return Shop::isTableAssociated($this->def['table']) || !empty($this->def['multilang_shop']); } public function isLangMultishop() @@ -1214,26 +1208,29 @@ abstract class ObjectModelCore { if (!$this->id) return false; - - /* Deleting object images and thumbnails (cache) */ - if ($this->image_dir) + + if (!$this->hasMultishopEntries()) { - if (file_exists($this->image_dir.$this->id.'.'.$this->image_format) - && !unlink($this->image_dir.$this->id.'.'.$this->image_format)) + /* Deleting object images and thumbnails (cache) */ + if ($this->image_dir) + { + if (file_exists($this->image_dir.$this->id.'.'.$this->image_format) + && !unlink($this->image_dir.$this->id.'.'.$this->image_format)) + return false; + } + if (file_exists(_PS_TMP_IMG_DIR_.$this->def['table'].'_'.$this->id.'.'.$this->image_format) + && !unlink(_PS_TMP_IMG_DIR_.$this->def['table'].'_'.$this->id.'.'.$this->image_format)) return false; + if (file_exists(_PS_TMP_IMG_DIR_.$this->def['table'].'_mini_'.$this->id.'.'.$this->image_format) + && !unlink(_PS_TMP_IMG_DIR_.$this->def['table'].'_mini_'.$this->id.'.'.$this->image_format)) + return false; + + $types = ImageType::getImagesTypes(); + foreach ($types as $image_type) + if (file_exists($this->image_dir.$this->id.'-'.stripslashes($image_type['name']).'.'.$this->image_format) + && !unlink($this->image_dir.$this->id.'-'.stripslashes($image_type['name']).'.'.$this->image_format)) + return false; } - if (file_exists(_PS_TMP_IMG_DIR_.$this->def['table'].'_'.$this->id.'.'.$this->image_format) - && !unlink(_PS_TMP_IMG_DIR_.$this->def['table'].'_'.$this->id.'.'.$this->image_format)) - return false; - if (file_exists(_PS_TMP_IMG_DIR_.$this->def['table'].'_mini_'.$this->id.'.'.$this->image_format) - && !unlink(_PS_TMP_IMG_DIR_.$this->def['table'].'_mini_'.$this->id.'.'.$this->image_format)) - return false; - - $types = ImageType::getImagesTypes(); - foreach ($types as $image_type) - if (file_exists($this->image_dir.$this->id.'-'.stripslashes($image_type['name']).'.'.$this->image_format) - && !unlink($this->image_dir.$this->id.'-'.stripslashes($image_type['name']).'.'.$this->image_format)) - return false; return true; } diff --git a/classes/Product.php b/classes/Product.php index 765546ec9..a3192839d 100644 --- a/classes/Product.php +++ b/classes/Product.php @@ -235,7 +235,6 @@ class ProductCore extends ObjectModel 'primary' => 'id_product', 'multilang' => true, 'multilang_shop' => true, - 'multishop_specific' => true, 'fields' => array( // Classic fields 'id_manufacturer' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), diff --git a/classes/controller/AdminController.php b/classes/controller/AdminController.php index 21489cb1a..f5cdfe972 100644 --- a/classes/controller/AdminController.php +++ b/classes/controller/AdminController.php @@ -2382,10 +2382,6 @@ class AdminControllerCore extends Controller if (!Shop::isFeatureActive()) return; - $def = ObjectModel::getDefinition($this->className); - if (!empty($def['multishop_specific'])) - return; - if (!Shop::isTableAssociated($this->table)) return; diff --git a/controllers/admin/AdminProductsController.php b/controllers/admin/AdminProductsController.php index 7e2fa4b44..87fe63fd7 100644 --- a/controllers/admin/AdminProductsController.php +++ b/controllers/admin/AdminProductsController.php @@ -1461,7 +1461,13 @@ class AdminProductsControllerCore extends AdminController Hook::exec('actionWatermark', array('id_image' => $id_image, 'id_product' => $id_product)); } } - + + protected function updateAssoShop($id_object) + { + //override AdminController::updateAssoShop() specifically for products because shop association is set with the context in ObjectModel + return; + } + public function processAdd() { $this->checkProduct(); diff --git a/controllers/admin/AdminShopController.php b/controllers/admin/AdminShopController.php index a9d9fe740..9ed4e834f 100755 --- a/controllers/admin/AdminShopController.php +++ b/controllers/admin/AdminShopController.php @@ -474,14 +474,18 @@ class AdminShopControllerCore extends AdminController 'tax_rules_group' => $this->l('Tax rules groups'), 'supplier' => $this->l('Suppliers'), 'referrer' => $this->l('Referrers'), + 'zone' => $this->l('Zones'), + 'cart_rule' => $this->l('Cart rules'), ); - + // Hook for duplication of shop data $modules_list = Hook::getHookModuleExecList('actionShopDataDuplication'); if (is_array($modules_list) && count($modules_list) > 0) foreach ($modules_list as $m) $import_data['Module'.ucfirst($m['module'])] = Module::getModuleName($m['module']); + asort($import_data); + if (!$this->object->id) $this->fields_import_form = array( 'radio' => array(