Current path: home/webdevt/www/schtroumpf.fr/src/Core/Form/IdentifiableObject/CommandBuilder/Product/
?? Go up: /home/webdevt/www/schtroumpf.fr/src/Core/Form/IdentifiableObject/CommandBuilder
<?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)
*/
declare(strict_types=1);
namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\CommandBuilder\Product;
use PrestaShop\PrestaShop\Core\Domain\Product\Command\UpdateProductCommand;
use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductId;
use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductType;
use PrestaShop\PrestaShop\Core\Domain\Shop\ValueObject\ShopConstraint;
use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\CommandBuilder\CommandBuilder;
use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\CommandBuilder\CommandBuilderConfig;
use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\CommandBuilder\DataField;
use PrestaShopBundle\Form\Admin\Extension\DisablingSwitchExtension;
/**
* Builds @see UpdateProductCommand for both single and All shops
*/
class UpdateProductCommandsBuilder implements ProductCommandsBuilderInterface
{
/**
* @var string
*/
private $modifyAllNamePrefix;
/**
* @param string $modifyAllNamePrefix
*/
public function __construct(string $modifyAllNamePrefix)
{
$this->modifyAllNamePrefix = $modifyAllNamePrefix;
}
/**
* {@inheritdoc}
*/
public function buildCommands(ProductId $productId, array $formData, ShopConstraint $singleShopConstraint): array
{
$config = new CommandBuilderConfig($this->modifyAllNamePrefix);
$this
->configureBasicInformation($config)
->configureOptions($config, $formData)
->configurePrices($config)
->configureSeo($config)
->configureDetails($config)
->configureShipping($config)
->configureStockInformation($config, $formData)
;
$config->addMultiShopField('[header][active]', 'setActive', DataField::TYPE_BOOL);
$commandBuilder = new CommandBuilder($config);
$shopCommand = new UpdateProductCommand($productId->getValue(), $singleShopConstraint);
$allShopsCommand = new UpdateProductCommand($productId->getValue(), ShopConstraint::allShops());
$this->setNameDependingOnStatus($formData, $shopCommand);
return $commandBuilder->buildCommands($formData, $shopCommand, $allShopsCommand);
}
/**
* @param CommandBuilderConfig $config
*
* @return self
*/
private function configureBasicInformation(CommandBuilderConfig $config): self
{
$config
->addMultiShopField('[header][name]', 'setLocalizedNames', DataField::TYPE_ARRAY)
->addMultiShopField('[description][description]', 'setLocalizedDescriptions', DataField::TYPE_ARRAY)
->addMultiShopField('[description][description_short]', 'setLocalizedShortDescriptions', DataField::TYPE_ARRAY)
;
return $this;
}
/**
* @param CommandBuilderConfig $config
*
* @return self
*/
private function configureOptions(CommandBuilderConfig $config, array $formData): self
{
$config
->addField('[description][manufacturer]', 'setManufacturerId', DataField::TYPE_INT)
->addMultiShopField('[options][visibility][online_only]', 'setOnlineOnly', DataField::TYPE_BOOL)
->addMultiShopField('[options][visibility][visibility]', 'setVisibility', DataField::TYPE_STRING)
->addMultiShopField('[options][visibility][available_for_order]', 'setAvailableForOrder', DataField::TYPE_BOOL)
->addMultiShopField('[options][visibility][show_price]', 'setShowPrice', DataField::TYPE_BOOL)
->addMultiShopField('[details][show_condition]', 'setShowCondition', DataField::TYPE_BOOL)
;
// based on show_condition value, the condition field can be disabled, in that case "condition" won't exist in request
// and will end up being "" in command if added into config without this if, which causes constraint error
if (!empty($formData['details']['condition'])) {
$config->addMultiShopField('[details][condition]', 'setCondition', DataField::TYPE_STRING);
}
return $this;
}
/**
* @param CommandBuilderConfig $config
*
* @return self
*/
private function configurePrices(CommandBuilderConfig $config): self
{
$config
->addMultiShopField('[pricing][retail_price][price_tax_excluded]', 'setPrice', DataField::TYPE_STRING)
->addMultiShopField('[pricing][retail_price][ecotax_tax_excluded]', 'setEcotax', DataField::TYPE_STRING)
->addMultiShopField('[pricing][retail_price][tax_rules_group_id]', 'setTaxRulesGroupId', DataField::TYPE_INT)
->addMultiShopField('[pricing][on_sale]', 'setOnSale', DataField::TYPE_BOOL)
->addMultiShopField('[pricing][wholesale_price]', 'setWholesalePrice', DataField::TYPE_STRING)
->addMultiShopField('[pricing][unit_price][price_tax_excluded]', 'setUnitPrice', DataField::TYPE_STRING)
->addMultiShopField('[pricing][unit_price][unity]', 'setUnity', DataField::TYPE_STRING)
;
return $this;
}
/**
* @param CommandBuilderConfig $config
*
* @return self
*/
private function configureSeo(CommandBuilderConfig $config): self
{
$config
->addMultiShopField('[seo][meta_title]', 'setLocalizedMetaTitles', DataField::TYPE_ARRAY)
->addMultiShopField('[seo][meta_description]', 'setLocalizedMetaDescriptions', DataField::TYPE_ARRAY)
->addMultiShopField('[seo][link_rewrite]', 'setLocalizedLinkRewrites', DataField::TYPE_ARRAY)
->addMultiShopCompoundField('setRedirectOption', [
'[seo][redirect_option][type]' => DataField::TYPE_STRING,
'[seo][redirect_option][target][id]' => [
'type' => DataField::TYPE_INT,
'default' => 0,
],
])
;
return $this;
}
/**
* @param CommandBuilderConfig $config
*
* @return self
*/
private function configureDetails(CommandBuilderConfig $config): self
{
$config
->addField('[details][references][reference]', 'setReference', DataField::TYPE_STRING)
->addField('[details][references][mpn]', 'setMpn', DataField::TYPE_STRING)
->addField('[details][references][upc]', 'setUpc', DataField::TYPE_STRING)
->addField('[details][references][ean_13]', 'setEan13', DataField::TYPE_STRING)
->addField('[details][references][isbn]', 'setIsbn', DataField::TYPE_STRING)
;
return $this;
}
/**
* @param CommandBuilderConfig $config
*
* @return self
*/
private function configureShipping(CommandBuilderConfig $config): self
{
$config
->addField('[shipping][dimensions][width]', 'setWidth', DataField::TYPE_STRING)
->addField('[shipping][dimensions][height]', 'setHeight', DataField::TYPE_STRING)
->addField('[shipping][dimensions][depth]', 'setDepth', DataField::TYPE_STRING)
->addField('[shipping][dimensions][weight]', 'setWeight', DataField::TYPE_STRING)
->addField('[shipping][delivery_time_note_type]', 'setDeliveryTimeNoteType', DataField::TYPE_INT)
->addMultiShopField('[shipping][additional_shipping_cost]', 'setAdditionalShippingCost', DataField::TYPE_STRING)
->addMultiShopField('[shipping][delivery_time_notes][in_stock]', 'setLocalizedDeliveryTimeInStockNotes', DataField::TYPE_ARRAY)
->addMultiShopField('[shipping][delivery_time_notes][out_of_stock]', 'setLocalizedDeliveryTimeOutOfStockNotes', DataField::TYPE_ARRAY)
;
return $this;
}
private function configureStockInformation(CommandBuilderConfig $config, array $formData): self
{
$config
->addMultiShopField('[stock][quantities][minimal_quantity]', 'setMinimalQuantity', DataField::TYPE_INT)
->addMultiShopField('[stock][pack_stock_type]', 'setPackStockType', DataField::TYPE_INT)
->addMultiShopField('[stock][availability][available_date]', 'setAvailableDate', DataField::TYPE_DATETIME)
;
$lowStockThresholdSwitchKey = sprintf('%slow_stock_threshold', DisablingSwitchExtension::FIELD_PREFIX);
if (
// if low stock threshold switch is falsy, then we must set lowStockThreshold to its disabled value
// which will end up being 0 after falsy bool to int conversion
isset($formData['stock']['options'][$lowStockThresholdSwitchKey]) &&
!$formData['stock']['options'][$lowStockThresholdSwitchKey]
) {
$config->addMultiShopField(sprintf('[stock][options][%s]', $lowStockThresholdSwitchKey), 'setLowStockThreshold', DataField::TYPE_INT);
} else {
// else we simply set the low stock threshold value from the form
$config->addMultiShopField('[stock][options][low_stock_threshold]', 'setLowStockThreshold', DataField::TYPE_INT);
}
$productType = $formData['header']['type'] ?? ProductType::TYPE_STANDARD;
if ($productType === ProductType::TYPE_COMBINATIONS) {
$config
->addMultiShopField('[combinations][availability][available_now_label]', 'setLocalizedAvailableNowLabels', DataField::TYPE_ARRAY)
->addMultiShopField('[combinations][availability][available_later_label]', 'setLocalizedAvailableLaterLabels', DataField::TYPE_ARRAY)
;
} else {
$config
->addMultiShopField('[stock][availability][available_now_label]', 'setLocalizedAvailableNowLabels', DataField::TYPE_ARRAY)
->addMultiShopField('[stock][availability][available_later_label]', 'setLocalizedAvailableLaterLabels', DataField::TYPE_ARRAY)
;
}
return $this;
}
/**
* Name and status are related - when name is not filled, then product cannot be enabled.
* When name is being updated for all shops, but status only for single shop, then status would be filled into
* single shop command while name only in all shops command. Since single shop command is always executed first,
* it will try to enable product before name is inserted in allShopsCommand and will end up throwing
* error about name being empty.
*
* So to solve that, we check if status is being updated for single shop,
* and if that is the case, then we manually fill the name into single shop command too.
* So at the end it will end up updating name twice - with single shop command and with all shops command,
* but at least it won't throw the error.
*
* @param array<string, mixed> $formData
* @param UpdateProductCommand $singleShopCommand
*
* @return void
*/
private function setNameDependingOnStatus(array $formData, UpdateProductCommand $singleShopCommand): void
{
if (
!empty($formData['header']['active']) &&
empty($formData['header'][$this->modifyAllNamePrefix . 'active']) &&
isset($formData['header']['name'])
) {
$singleShopCommand->setLocalizedNames($formData['header']['name']);
}
}
}