Linux node5458.myfcloud.com 6.10.2-x86_64-linode165 #1 SMP PREEMPT_DYNAMIC Tue Jul 30 15:03:21 EDT 2024 x86_64
Apache
: 45.79.123.194 | : 18.222.97.248
16 Domain
7.4.33
addify5
shells.trxsecurity.org
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
Backdoor Scanner
Backdoor Create
Alfa Webshell
CPANEL RESET
CREATE WP USER
README
+ Create Folder
+ Create File
/
home /
addify5 /
.trash /
src.1 /
Adapter /
Product /
[ HOME SHELL ]
Name
Size
Permission
Action
Attachment
[ DIR ]
drwxr-xr-x
AttributeGroup
[ DIR ]
drwxr-xr-x
Combination
[ DIR ]
drwxr-xr-x
CommandHandler
[ DIR ]
drwxr-xr-x
Customization
[ DIR ]
drwxr-xr-x
FeatureValue
[ DIR ]
drwxr-xr-x
Grid
[ DIR ]
drwxr-xr-x
Image
[ DIR ]
drwxr-xr-x
Options
[ DIR ]
drwxr-xr-x
Pack
[ DIR ]
drwxr-xr-x
QueryHandler
[ DIR ]
drwxr-xr-x
Repository
[ DIR ]
drwxr-xr-x
Shop
[ DIR ]
drwxr-xr-x
SpecificPrice
[ DIR ]
drwxr-xr-x
Stock
[ DIR ]
drwxr-xr-x
Supplier
[ DIR ]
drwxr-xr-x
Update
[ DIR ]
drwxr-xr-x
Validate
[ DIR ]
drwxr-xr-x
VirtualProduct
[ DIR ]
drwxr-xr-x
AbstractProductSupplierHandler...
4.26
KB
-rw-r--r--
AdminProductDataProvider.php
16.73
KB
-rw-r--r--
AdminProductDataUpdater.php
11.3
KB
-rw-r--r--
AdminProductWrapper.php
36.74
KB
-rw-r--r--
AttachmentDataProvider.php
1.69
KB
-rw-r--r--
FilterCategoriesRequestPurifie...
1.9
KB
-rw-r--r--
GeneralConfiguration.php
5.83
KB
-rw-r--r--
ListParametersUpdater.php
4.72
KB
-rw-r--r--
PackItemsManager.php
3.35
KB
-rw-r--r--
PageConfiguration.php
3.21
KB
-rw-r--r--
PaginationConfiguration.php
2.9
KB
-rw-r--r--
PriceCalculator.php
7.15
KB
-rw-r--r--
PriceFormatter.php
1.86
KB
-rw-r--r--
ProductColorsRetriever.php
1.5
KB
-rw-r--r--
ProductDataProvider.php
4.64
KB
-rw-r--r--
ProductDeleter.php
4.05
KB
-rw-r--r--
StockConfiguration.php
4.75
KB
-rw-r--r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : AdminProductWrapper.php
<?php /** * Copyright since 2007 PrestaShop SA and Contributors * PrestaShop is an International Registered Trademark & Property of PrestaShop SA * * NOTICE OF LICENSE * * This source file is subject to the Open Software License (OSL 3.0) * that is bundled with this package in the file LICENSE.md. * It is also available through the world-wide-web at this URL: * https://opensource.org/licenses/OSL-3.0 * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to license@prestashop.com so we can send you a copy immediately. * * DISCLAIMER * * Do not edit or add to this file if you wish to upgrade PrestaShop to newer * versions in the future. If you wish to customize PrestaShop for your * needs please refer to https://devdocs.prestashop.com/ for more information. * * @author PrestaShop SA and Contributors <contact@prestashop.com> * @copyright Since 2007 PrestaShop SA and Contributors * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) */ namespace PrestaShop\PrestaShop\Adapter\Product; use AdminProductsController; use Attachment; use Category; use Combination; use Configuration; use Context; use Customer; use Db; use Hook; use Image; use Language; use ObjectModel; use PrestaShop\PrestaShop\Adapter\Entity\Customization; use PrestaShop\PrestaShop\Core\Foundation\Database\EntityNotFoundException; use PrestaShop\PrestaShop\Core\Localization\Locale; use PrestaShopBundle\Form\Admin\Type\CustomMoneyType; use PrestaShopBundle\Utils\FloatParser; use Product; use ProductDownload; use Shop; use ShopUrl; use SpecificPrice; use SpecificPriceRule; use StockAvailable; use Symfony\Contracts\Translation\TranslatorInterface; use Tax; use Tools; use Validate; /** * @deprecated since 8.1 and will be removed in next major. * * Admin controller wrapper for new Architecture, about Product admin controller. */ class AdminProductWrapper { /** * @var array */ private $errors = []; /** * @var Locale */ private $locale; /** * @var TranslatorInterface */ private $translator; /** * @var array */ private $employeeAssociatedShops; /** * @var FloatParser */ private $floatParser; /** * Constructor : Inject Symfony\Component\Translation Translator. * * @param object $translator * @param array $employeeAssociatedShops * @param Locale $locale * @param FloatParser|null $floatParser */ public function __construct($translator, array $employeeAssociatedShops, Locale $locale, FloatParser $floatParser = null) { $this->translator = $translator; $this->employeeAssociatedShops = $employeeAssociatedShops; $this->locale = $locale; $this->floatParser = $floatParser ?? new FloatParser(); } /** * getInstance * Get the legacy AdminProductsControllerCore instance. * * @return AdminProductsController instance */ public function getInstance() { return new AdminProductsController(); } /** * processProductAttribute * Update a combination. * * @param object $product * @param array $combinationValues the posted values * * @return void */ public function processProductAttribute($product, $combinationValues) { $id_product_attribute = (int) $combinationValues['id_product_attribute']; $images = []; if (!Combination::isFeatureActive() || $id_product_attribute == 0) { return; } if (!isset($combinationValues['attribute_wholesale_price'])) { $combinationValues['attribute_wholesale_price'] = 0; } if (!isset($combinationValues['attribute_price_impact'])) { $combinationValues['attribute_price_impact'] = 0; } if (!isset($combinationValues['attribute_weight_impact'])) { $combinationValues['attribute_weight_impact'] = 0; } // This is VERY UGLY, but since ti ComputingPrecision can never return enough decimals for now we have no // choice but to hard code this one to make sure enough precision is saved in the DB or it results in errors // of 1 cent in the shop $computingPrecision = CustomMoneyType::PRESTASHOP_DECIMALS; if (!isset($combinationValues['attribute_ecotax']) || 0.0 === (float) $combinationValues['attribute_ecotax']) { $combinationValues['attribute_ecotax'] = 0; } else { // Value is displayed tax included but must be saved tax excluded $combinationValues['attribute_ecotax'] = Tools::ps_round( $combinationValues['attribute_ecotax'] / (1 + Tax::getProductEcotaxRate() / 100), $computingPrecision ); } if ((isset($combinationValues['attribute_default']) && $combinationValues['attribute_default'] == 1)) { $product->deleteDefaultAttributes(); } if (!empty($combinationValues['id_image_attr'])) { $images = $combinationValues['id_image_attr']; } else { $combination = new Combination($id_product_attribute); $combination->setImages([]); } if (!isset($combinationValues['attribute_low_stock_threshold'])) { $combinationValues['attribute_low_stock_threshold'] = null; } if (!isset($combinationValues['attribute_low_stock_alert'])) { $combinationValues['attribute_low_stock_alert'] = false; } $product->updateAttribute( $id_product_attribute, $combinationValues['attribute_wholesale_price'], $combinationValues['attribute_price'] * $combinationValues['attribute_price_impact'], $combinationValues['attribute_weight'] * $combinationValues['attribute_weight_impact'], $combinationValues['attribute_unity'] * $combinationValues['attribute_unit_impact'], $combinationValues['attribute_ecotax'], $images, $combinationValues['attribute_reference'], $combinationValues['attribute_ean13'], (isset($combinationValues['attribute_default']) && $combinationValues['attribute_default'] == 1), isset($combinationValues['attribute_location']) ? $combinationValues['attribute_location'] : null, $combinationValues['attribute_upc'], $combinationValues['attribute_minimal_quantity'], $combinationValues['available_date_attribute'], false, [], $combinationValues['attribute_isbn'], $combinationValues['attribute_low_stock_threshold'], $combinationValues['attribute_low_stock_alert'], $combinationValues['attribute_mpn'] ); StockAvailable::setProductDependsOnStock((int) $product->id, $product->depends_on_stock, null, $id_product_attribute); StockAvailable::setProductOutOfStock((int) $product->id, $product->out_of_stock, null, $id_product_attribute); StockAvailable::setLocation((int) $product->id, $combinationValues['attribute_location'], null, $id_product_attribute); $product->checkDefaultAttributes(); if ((isset($combinationValues['attribute_default']) && $combinationValues['attribute_default'] == 1)) { Product::updateDefaultAttribute((int) $product->id); $product->cache_default_attribute = (int) $id_product_attribute; // We need to reload the product because some other calls have modified the database // It's done just for the setAvailableDate to avoid side effects Product::disableCache(); $consistentProduct = new Product($product->id); if ($available_date = $combinationValues['available_date_attribute']) { $consistentProduct->setAvailableDate($available_date); } else { $consistentProduct->setAvailableDate(); } Product::enableCache(); } if (isset($combinationValues['attribute_quantity'])) { $this->processQuantityUpdate($product, $combinationValues['attribute_quantity'], $id_product_attribute); } } /** * Update a quantity for a product or a combination. * * Does not work in Advanced stock management. * * @param Product $product * @param int $quantity * @param int $forAttributeId */ public function processQuantityUpdate(Product $product, $quantity, $forAttributeId = 0) { // Hook triggered by legacy code below: actionUpdateQuantity('id_product', 'id_product_attribute', 'quantity') StockAvailable::setQuantity((int) $product->id, $forAttributeId, $quantity); Hook::exec('actionProductUpdate', ['id_product' => (int) $product->id, 'product' => $product]); } /** * Update the out of stock strategy. * * @param Product $product * @param int $out_of_stock */ public function processProductOutOfStock(Product $product, $out_of_stock) { StockAvailable::setProductOutOfStock((int) $product->id, (int) $out_of_stock); } /** * @param Product $product * @param string $location */ public function processLocation(Product $product, $location) { StockAvailable::setLocation($product->id, $location); } /** * Set if a product depends on stock (ASM). For a product or a combination. * * Does work only in Advanced stock management. * * @param Product $product * @param bool $dependsOnStock * @param int $forAttributeId */ public function processDependsOnStock(Product $product, $dependsOnStock, $forAttributeId = 0) { StockAvailable::setProductDependsOnStock((int) $product->id, $dependsOnStock, null, $forAttributeId); } /** * Add/Update a SpecificPrice object. * * @param int $id_product * @param array $specificPriceValues the posted values * @param int|null $idSpecificPrice if this is an update of an existing specific price, null else * * @return AdminProductsController|array */ public function processProductSpecificPrice($id_product, $specificPriceValues, $idSpecificPrice = null) { // ---- data formatting ---- $id_product_attribute = $specificPriceValues['sp_id_product_attribute'] ?? 0; $id_shop = $specificPriceValues['sp_id_shop'] ? $specificPriceValues['sp_id_shop'] : 0; $id_currency = $specificPriceValues['sp_id_currency'] ? $specificPriceValues['sp_id_currency'] : 0; $id_country = $specificPriceValues['sp_id_country'] ? $specificPriceValues['sp_id_country'] : 0; $id_group = $specificPriceValues['sp_id_group'] ? $specificPriceValues['sp_id_group'] : 0; $id_customer = !empty($specificPriceValues['sp_id_customer']['data']) ? $specificPriceValues['sp_id_customer']['data'][0] : 0; $price = isset($specificPriceValues['leave_bprice']) ? '-1' : $this->floatParser->fromString($specificPriceValues['sp_price']); $from_quantity = $specificPriceValues['sp_from_quantity']; $reduction = $this->floatParser->fromString($specificPriceValues['sp_reduction']); $reduction_tax = $specificPriceValues['sp_reduction_tax']; $reduction_type = !$reduction ? 'amount' : $specificPriceValues['sp_reduction_type']; $reduction_type = $reduction_type == '-' ? 'amount' : $reduction_type; $from = $specificPriceValues['sp_from']; if (!$from) { $from = '0000-00-00 00:00:00'; } $to = $specificPriceValues['sp_to']; if (!$to) { $to = '0000-00-00 00:00:00'; } $isThisAnUpdate = (null !== $idSpecificPrice); // ---- validation ---- if (($price == '-1') && ((float) $reduction == '0')) { $this->errors[] = $this->translator->trans('No reduction value has been submitted.', [], 'Admin.Catalog.Notification'); } elseif ($to != '0000-00-00 00:00:00' && strtotime($to) < strtotime($from)) { $this->errors[] = $this->translator->trans('Invalid date range', [], 'Admin.Catalog.Notification'); } elseif ($reduction_type == 'percentage' && ((float) $reduction <= 0 || (float) $reduction > 100)) { $this->errors[] = $this->translator->trans('The submitted reduction value (0-100) is out-of-range.', [], 'Admin.Catalog.Notification'); } $validationResult = $this->validateSpecificPrice( $id_product, $id_shop, $id_currency, $id_country, $id_group, $id_customer, $price, $from_quantity, $reduction, $reduction_type, $from, $to, $id_product_attribute, $isThisAnUpdate ); if (false === $validationResult || count($this->errors)) { return $this->errors; } // ---- data modification ---- if ($isThisAnUpdate) { $specificPrice = new SpecificPrice($idSpecificPrice); } else { $specificPrice = new SpecificPrice(); } $specificPrice->id_product = (int) $id_product; $specificPrice->id_product_attribute = (int) $id_product_attribute; $specificPrice->id_shop = (int) $id_shop; $specificPrice->id_currency = (int) ($id_currency); $specificPrice->id_country = (int) ($id_country); $specificPrice->id_group = (int) ($id_group); $specificPrice->id_customer = (int) $id_customer; $specificPrice->price = (float) ($price); $specificPrice->from_quantity = (int) ($from_quantity); $specificPrice->reduction = (float) ($reduction_type == 'percentage' ? $reduction / 100 : $reduction); $specificPrice->reduction_tax = $reduction_tax; $specificPrice->reduction_type = $reduction_type; $specificPrice->from = $from; $specificPrice->to = $to; if ($isThisAnUpdate) { $dataSavingResult = $specificPrice->save(); } else { $dataSavingResult = $specificPrice->add(); } if (false === $dataSavingResult) { $this->errors[] = $this->translator->trans('An error occurred while updating the specific price.', [], 'Admin.Catalog.Notification'); } return $this->errors; } /** * Validate a specific price. */ private function validateSpecificPrice( $id_product, $id_shop, $id_currency, $id_country, $id_group, $id_customer, $price, $from_quantity, $reduction, $reduction_type, $from, $to, $id_combination = 0, $isThisAnUpdate = false ) { if (!Validate::isUnsignedId($id_shop) || !Validate::isUnsignedId($id_currency) || !Validate::isUnsignedId($id_country) || !Validate::isUnsignedId($id_group) || !Validate::isUnsignedId($id_customer)) { $this->errors[] = 'Wrong IDs'; } elseif ((!isset($price) && !isset($reduction)) || (isset($price) && !Validate::isNegativePrice($price)) || (isset($reduction) && !Validate::isPrice($reduction))) { $this->errors[] = 'Invalid price/discount amount'; } elseif (!Validate::isUnsignedInt($from_quantity)) { $this->errors[] = 'Invalid quantity'; } elseif ($reduction && !Validate::isReductionType($reduction_type)) { $this->errors[] = 'Please select a discount type (amount or percentage).'; } elseif ($from && $to && (!Validate::isDateFormat($from) || !Validate::isDateFormat($to))) { $this->errors[] = 'The from/to date is invalid.'; } elseif (!$isThisAnUpdate && SpecificPrice::exists((int) $id_product, $id_combination, $id_shop, $id_group, $id_country, $id_currency, $id_customer, $from_quantity, $from, $to, false)) { $this->errors[] = 'A specific price already exists for these parameters.'; } else { return true; } return false; } /** * Get specific prices list for a product. * * @param object $product * @param object $defaultCurrency * @param array $shops Available shops * @param array $currencies Available currencies * @param array $countries Available countries * @param array $groups Available users groups * * @return array */ public function getSpecificPricesList($product, $defaultCurrency, $shops, $currencies, $countries, $groups) { $content = []; $specific_prices = array_merge( SpecificPrice::getByProductId((int) $product->id), SpecificPrice::getByProductId(0) ); $tmp = []; foreach ($shops as $shop) { $tmp[$shop['id_shop']] = $shop; } $shops = $tmp; $tmp = []; foreach ($currencies as $currency) { $tmp[$currency['id_currency']] = $currency; } $currencies = $tmp; $tmp = []; foreach ($countries as $country) { $tmp[$country['id_country']] = $country; } $countries = $tmp; $tmp = []; foreach ($groups as $group) { $tmp[$group['id_group']] = $group; } $groups = $tmp; if (is_array($specific_prices) && count($specific_prices)) { foreach ($specific_prices as $specific_price) { $id_currency = $specific_price['id_currency'] ? $specific_price['id_currency'] : $defaultCurrency->id; if (!isset($currencies[$id_currency])) { continue; } $current_specific_currency = $currencies[$id_currency]; if ($specific_price['reduction_type'] == 'percentage') { $impact = '- ' . ($specific_price['reduction'] * 100) . ' %'; } elseif ($specific_price['reduction'] > 0) { $impact = '- ' . $this->locale->formatPrice($specific_price['reduction'], $current_specific_currency['iso_code']) . ' '; if ($specific_price['reduction_tax']) { $impact .= '(' . $this->translator->trans('Tax incl.', [], 'Admin.Global') . ')'; } else { $impact .= '(' . $this->translator->trans('Tax excl.', [], 'Admin.Global') . ')'; } } else { $impact = '--'; } if ($specific_price['from'] == '0000-00-00 00:00:00' && $specific_price['to'] == '0000-00-00 00:00:00') { $period = $this->translator->trans('Unlimited', [], 'Admin.Global'); } else { $period = $this->translator->trans('From', [], 'Admin.Global') . ' ' . ($specific_price['from'] != '0000-00-00 00:00:00' ? $specific_price['from'] : '0000-00-00 00:00:00') . '<br />' . $this->translator->trans('to', [], 'Admin.Global') . ' ' . ($specific_price['to'] != '0000-00-00 00:00:00' ? $specific_price['to'] : '0000-00-00 00:00:00'); } if ($specific_price['id_product_attribute']) { $combination = new Combination((int) $specific_price['id_product_attribute']); $attributes = $combination->getAttributesName(1); $attributes_name = ''; foreach ($attributes as $attribute) { $attributes_name .= $attribute['name'] . ' - '; } $attributes_name = rtrim($attributes_name, ' - '); } else { $attributes_name = $this->translator->trans('All combinations', [], 'Admin.Catalog.Feature'); } $rule = new SpecificPriceRule((int) $specific_price['id_specific_price_rule']); $rule_name = ($rule->id ? $rule->name : '--'); if ($specific_price['id_customer']) { $customer = new Customer((int) $specific_price['id_customer']); if (Validate::isLoadedObject($customer)) { $customer_full_name = $customer->firstname . ' ' . $customer->lastname; } unset($customer); } if (!$specific_price['id_shop'] || in_array($specific_price['id_shop'], Shop::getContextListShopID())) { $can_delete_specific_prices = true; if (Shop::isFeatureActive()) { $can_delete_specific_prices = (count($this->employeeAssociatedShops) > 1 && !$specific_price['id_shop']) || $specific_price['id_shop']; } $price = Tools::ps_round($specific_price['price'], 2); $fixed_price = (($price == Tools::ps_round($product->price, 2) && $current_specific_currency['id_currency'] == $defaultCurrency->id) || $specific_price['price'] == -1) ? '--' : $this->locale->formatPrice($price, $current_specific_currency['iso_code']); $content[] = [ 'id_specific_price' => $specific_price['id_specific_price'], 'id_product' => $product->id, 'rule_name' => $rule_name, 'attributes_name' => $attributes_name, 'shop' => ($specific_price['id_shop'] ? $shops[$specific_price['id_shop']]['name'] : $this->translator->trans('All stores', [], 'Admin.Global')), 'currency' => ($specific_price['id_currency'] ? $currencies[$specific_price['id_currency']]['name'] : $this->translator->trans('All currencies', [], 'Admin.Global')), 'country' => ($specific_price['id_country'] ? $countries[$specific_price['id_country']]['name'] : $this->translator->trans('All countries', [], 'Admin.Global')), 'group' => ($specific_price['id_group'] ? $groups[$specific_price['id_group']]['name'] : $this->translator->trans('All groups', [], 'Admin.Global')), 'customer' => (isset($customer_full_name) ? $customer_full_name : $this->translator->trans('All customers', [], 'Admin.Global')), 'fixed_price' => $fixed_price, 'impact' => $impact, 'period' => $period, 'from_quantity' => $specific_price['from_quantity'], 'can_delete' => (!$rule->id && $can_delete_specific_prices) ? true : false, 'can_edit' => (!$rule->id && $can_delete_specific_prices) ? true : false, ]; unset($customer_full_name); } } } return $content; } /** * @param int $id * * @return SpecificPrice * * @throws EntityNotFoundException */ public function getSpecificPriceDataById($id) { $price = new SpecificPrice($id); if (null === $price->id) { throw new EntityNotFoundException(sprintf('Cannot find specific price with id %d', $id)); } return $price; } /** * Delete a specific price. * * @param int $id_specific_price * * @return array error & status */ public function deleteSpecificPrice($id_specific_price) { if (!$id_specific_price || !Validate::isUnsignedId($id_specific_price)) { $error = $this->translator->trans('The specific price ID is invalid.', [], 'Admin.Catalog.Notification'); } else { $specificPrice = new SpecificPrice((int) $id_specific_price); if (!$specificPrice->delete()) { $error = $this->translator->trans('An error occurred while attempting to delete the specific price.', [], 'Admin.Catalog.Notification'); } } if (isset($error)) { return [ 'status' => 'error', 'message' => $error, ]; } return [ 'status' => 'ok', 'message' => $this->translator->trans('Successful deletion', [], 'Admin.Notifications.Success'), ]; } /** * Get price priority. * * @param int|null $idProduct * * @return array */ public function getPricePriority($idProduct = null) { if (!$idProduct) { return [ 0 => 'id_shop', 1 => 'id_currency', 2 => 'id_country', 3 => 'id_group', ]; } $specific_price_priorities = SpecificPrice::getPriority((int) $idProduct); // Not use id_customer if ($specific_price_priorities[0] == 'id_customer') { unset($specific_price_priorities[0]); } return array_values($specific_price_priorities); } /** * Process customization collection. * * @param object $product * @param array $data * * @return array<int, int> */ public function processProductCustomization($product, $data) { $customization_ids = []; if ($data) { foreach ($data as $customization) { $customization_ids[] = (int) $customization['id_customization_field']; } } $shopList = Shop::getContextListShopID(); /* Update the customization fields to be deleted in the next step if not used */ $product->softDeleteCustomizationFields($customization_ids); $usedCustomizationIds = $product->getUsedCustomizationFieldsIds(); $usedCustomizationIds = array_column($usedCustomizationIds, 'index'); $usedCustomizationIds = array_map('intval', $usedCustomizationIds); $usedCustomizationIds = array_unique(array_merge($usedCustomizationIds, $customization_ids), SORT_REGULAR); //remove customization field langs for current context shops $productCustomization = $product->getCustomizationFieldIds(); $toDeleteCustomizationIds = []; foreach ($productCustomization as $customizationFiled) { if (!in_array((int) $customizationFiled['id_customization_field'], $usedCustomizationIds)) { $toDeleteCustomizationIds[] = (int) $customizationFiled['id_customization_field']; } //if the customization_field is still in use, only delete the current context shops langs, if (in_array((int) $customizationFiled['id_customization_field'], $customization_ids)) { Customization::deleteCustomizationFieldLangByShop($customizationFiled['id_customization_field'], $shopList); } } //remove unused customization for the product $product->deleteUnusedCustomizationFields($toDeleteCustomizationIds); //create new customizations $countFieldText = 0; $countFieldFile = 0; $productCustomizableValue = 0; $hasRequiredField = false; $new_customization_fields_ids = []; if ($data) { foreach ($data as $key => $customization) { if ($customization['require']) { $hasRequiredField = true; } //create label if (isset($customization['id_customization_field'])) { $id_customization_field = (int) $customization['id_customization_field']; Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'customization_field` SET `required` = ' . ($customization['require'] ? 1 : 0) . ', `type` = ' . (int) $customization['type'] . ' WHERE `id_customization_field` = ' . $id_customization_field); } else { Db::getInstance()->execute( 'INSERT INTO `' . _DB_PREFIX_ . 'customization_field` (`id_product`, `type`, `required`) VALUES (' . (int) $product->id . ', ' . (int) $customization['type'] . ', ' . ($customization['require'] ? 1 : 0) . ')' ); $id_customization_field = (int) Db::getInstance()->Insert_ID(); } $new_customization_fields_ids[$key] = $id_customization_field; // Create multilingual label name $langValues = ''; foreach (Language::getLanguages() as $language) { $name = $customization['label'][$language['id_lang']]; foreach ($shopList as $id_shop) { $langValues .= '(' . (int) $id_customization_field . ', ' . (int) $language['id_lang'] . ', ' . (int) $id_shop . ',\'' . pSQL($name) . '\'), '; } } Db::getInstance()->execute( 'INSERT INTO `' . _DB_PREFIX_ . 'customization_field_lang` (`id_customization_field`, `id_lang`, `id_shop`, `name`) VALUES ' . rtrim( $langValues, ', ' ) ); if ($customization['type'] == Product::CUSTOMIZE_FILE) { ++$countFieldFile; } else { ++$countFieldText; } } $productCustomizableValue = $hasRequiredField ? 2 : 1; } //update product count fields labels Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'product` SET `customizable` = ' . $productCustomizableValue . ', `uploadable_files` = ' . (int) $countFieldFile . ', `text_fields` = ' . (int) $countFieldText . ' WHERE `id_product` = ' . (int) $product->id); //update product_shop count fields labels ObjectModel::updateMultishopTable('product', [ 'customizable' => $productCustomizableValue, 'uploadable_files' => (int) $countFieldFile, 'text_fields' => (int) $countFieldText, ], 'a.id_product = ' . (int) $product->id); Configuration::updateGlobalValue('PS_CUSTOMIZATION_FEATURE_ACTIVE', '1'); return $new_customization_fields_ids; } /** * Update product download. * * @param object $product * @param array $data * * @return ProductDownload */ public function updateDownloadProduct($product, $data) { $id_product_download = ProductDownload::getIdFromIdProduct((int) $product->id, false); $download = new ProductDownload($id_product_download ? $id_product_download : null); if ((int) $data['is_virtual_file'] == 1) { $fileName = null; $file = $data['file']; if (!empty($file)) { $fileName = ProductDownload::getNewFilename(); $file->move(_PS_DOWNLOAD_DIR_, $fileName); } $product->setDefaultAttribute(0); //reset cache_default_attribute $download->id_product = (int) $product->id; $download->display_filename = $data['name']; $download->filename = $fileName ? $fileName : $download->filename; $download->date_add = date('Y-m-d H:i:s'); $download->date_expiration = $data['expiration_date'] ? $data['expiration_date'] . ' 23:59:59' : ''; $download->nb_days_accessible = (int) $data['nb_days']; $download->nb_downloadable = (int) $data['nb_downloadable']; $download->active = true; $download->is_shareable = false; if (!$id_product_download) { $download->save(); } else { $download->update(); } } else { if (!empty($id_product_download)) { $download->date_expiration = date('Y-m-d H:i:s', time() - 1); $download->active = false; $download->update(); } } return $download; } /** * Delete file from a virtual product. * * @param object $product */ public function processDeleteVirtualProductFile($product) { $id_product_download = ProductDownload::getIdFromIdProduct((int) $product->id, false); $download = new ProductDownload($id_product_download ? $id_product_download : null); if (!empty($download->filename)) { unlink(_PS_DOWNLOAD_DIR_ . $download->filename); Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'product_download` SET filename = "" WHERE `id_product_download` = ' . (int) $download->id); } } /** * Delete a virtual product. * * @param object $product */ public function processDeleteVirtualProduct($product) { $id_product_download = ProductDownload::getIdFromIdProduct((int) $product->id, false); $download = new ProductDownload($id_product_download ? $id_product_download : null); if (Validate::isLoadedObject($download)) { $download->delete(true); } } /** * Add attachement file. * * @param object $product * @param array $data * @param array $locales * * @return object|null Attachement */ public function processAddAttachment($product, $data, $locales) { $attachment = null; $file = $data['file']; if (!empty($file)) { $fileName = sha1(microtime()); $attachment = new Attachment(); foreach ($locales as $locale) { $attachment->name[(int) $locale['id_lang']] = $data['name']; $attachment->description[(int) $locale['id_lang']] = $data['description']; } $attachment->file = $fileName; $attachment->mime = $file->getMimeType(); $attachment->file_name = $file->getClientOriginalName(); $file->move(_PS_DOWNLOAD_DIR_, $fileName); if ($attachment->add()) { $attachment->attachProduct($product->id); } } return $attachment; } /** * Process product attachments. * * @param object $product * @param array $data */ public function processAttachments($product, $data) { Attachment::attachToProduct($product->id, $data); } /** * Update images positions. * * @param array $data Indexed array with id product/position */ public function ajaxProcessUpdateImagePosition($data) { foreach ($data as $id => $position) { $img = new Image((int) $id); $img->position = (int) $position; $img->update(); } } /** * Update image legend and cover. * * @param int $idImage * @param array $data * * @return object image */ public function ajaxProcessUpdateImage($idImage, $data) { $img = new Image((int) $idImage); if ($data['cover']) { Image::deleteCover((int) $img->id_product); $img->cover = true; } $img->legend = $data['legend']; $img->update(); return $img; } /** * Generate preview URL. * * @param object $product * @param bool $preview * * @return string|bool Preview url */ public function getPreviewUrl($product, $preview = true) { $context = Context::getContext(); $id_lang = (int) Configuration::get('PS_LANG_DEFAULT', null, null, $context->shop->id); if (!ShopUrl::getMainShopDomain()) { return false; } $is_rewrite_active = (bool) Configuration::get('PS_REWRITING_SETTINGS'); $preview_url = $context->link->getProductLink( $product, $product->link_rewrite[$context->language->id], Category::getLinkRewrite($product->id_category_default, $context->language->id), null, $id_lang, (int) $context->shop->id, 0, $is_rewrite_active ); if (!$product->active && $preview) { $preview_url = $this->getPreviewUrlDeactivate($preview_url); } return $preview_url; } /** * Generate preview URL deactivate. * * @param string $preview_url * * @return string preview url deactivate */ public function getPreviewUrlDeactivate($preview_url) { $context = Context::getContext(); $token = Tools::getAdminTokenLite('AdminProducts'); $admin_dir = dirname($_SERVER['PHP_SELF']); $admin_dir = substr($admin_dir, strrpos($admin_dir, '/') + 1); $preview_url_deactivate = $preview_url . ((strpos($preview_url, '?') === false) ? '?' : '&') . 'adtoken=' . $token . '&ad=' . $admin_dir . '&id_employee=' . (int) $context->employee->id . '&preview=1'; return $preview_url_deactivate; } /** * Generate preview URL. * * @param int $productId * * @return string preview url */ public function getPreviewUrlFromId($productId) { $product = new Product($productId, false); return $this->getPreviewUrl($product); } }
Close