HEX
Server: Apache
System: Linux srv13.cpanelhost.cl 3.10.0-962.3.2.lve1.5.38.el7.x86_64 #1 SMP Thu Jun 18 05:28:41 EDT 2020 x86_64
User: cca63905 (4205)
PHP: 7.3.20
Disabled: NONE
Upload Files
File: //proc/self/cwd/nueva/src/Core/Form/IdentifiableObject/DataProvider/ProductFormDataProvider.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)
 */

declare(strict_types=1);

namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider;

use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface;
use PrestaShop\PrestaShop\Core\Domain\Manufacturer\ValueObject\NoManufacturerId;
use PrestaShop\PrestaShop\Core\Domain\Product\Customization\Query\GetProductCustomizationFields;
use PrestaShop\PrestaShop\Core\Domain\Product\Customization\QueryResult\CustomizationField;
use PrestaShop\PrestaShop\Core\Domain\Product\FeatureValue\Query\GetProductFeatureValues;
use PrestaShop\PrestaShop\Core\Domain\Product\FeatureValue\QueryResult\ProductFeatureValue;
use PrestaShop\PrestaShop\Core\Domain\Product\Query\GetProductForEditing;
use PrestaShop\PrestaShop\Core\Domain\Product\QueryResult\LocalizedTags;
use PrestaShop\PrestaShop\Core\Domain\Product\QueryResult\ProductForEditing;
use PrestaShop\PrestaShop\Core\Domain\Product\Supplier\Query\GetProductSupplierOptions;
use PrestaShop\PrestaShop\Core\Domain\Product\Supplier\QueryResult\ProductSupplierOptions;
use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\DeliveryTimeNoteType;
use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductCondition;
use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductType;
use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductVisibility;
use PrestaShop\PrestaShop\Core\Util\DateTime\DateTime;

/**
 * Provides the data that is used to prefill the Product form
 */
final class ProductFormDataProvider implements FormDataProviderInterface
{
    /**
     * @var CommandBusInterface
     */
    private $queryBus;

    /**
     * @var bool
     */
    private $defaultProductActivation;

    /**
     * @var int
     */
    private $mostUsedTaxRulesGroupId;

    /**
     * @var int
     */
    private $defaultCategoryId;

    /**
     * @param CommandBusInterface $queryBus
     * @param bool $defaultProductActivation
     * @param int $mostUsedTaxRulesGroupId
     * @param int $defaultCategoryId
     */
    public function __construct(
        CommandBusInterface $queryBus,
        bool $defaultProductActivation,
        int $mostUsedTaxRulesGroupId,
        int $defaultCategoryId
    ) {
        $this->queryBus = $queryBus;
        $this->defaultProductActivation = $defaultProductActivation;
        $this->mostUsedTaxRulesGroupId = $mostUsedTaxRulesGroupId;
        $this->defaultCategoryId = $defaultCategoryId;
    }

    /**
     * {@inheritdoc}
     */
    public function getData($id)
    {
        $productId = (int) $id;
        /** @var ProductForEditing $productForEditing */
        $productForEditing = $this->queryBus->handle(new GetProductForEditing($productId));

        $productData = [
            'id' => $productId,
            'header' => $this->extractHeaderData($productForEditing),
            'basic' => $this->extractBasicData($productForEditing),
            'stock' => $this->extractStockData($productForEditing),
            'pricing' => $this->extractPricingData($productForEditing),
            'seo' => $this->extractSEOData($productForEditing),
            'shipping' => $this->extractShippingData($productForEditing),
            'options' => $this->extractOptionsData($productForEditing),
            'categories' => $this->extractCategoriesData($productForEditing),
            'footer' => [
                'active' => $productForEditing->getOptions()->isActive(),
            ],
        ];

        return $this->addShortcutData($productData);
    }

    /**
     * {@inheritdoc}
     */
    public function getDefaultData()
    {
        return $this->addShortcutData([
            'header' => [
                'type' => ProductType::TYPE_STANDARD,
            ],
            'basic' => [
                'manufacturer' => NoManufacturerId::NO_MANUFACTURER_ID,
            ],
            'stock' => [
                'quantities' => [
                    'quantity' => 0,
                    'minimal_quantity' => 0,
                ],
            ],
            'pricing' => [
                'retail_price' => [
                    'price_tax_excluded' => 0,
                    'price_tax_included' => 0,
                ],
                'tax_rules_group_id' => $this->mostUsedTaxRulesGroupId,
                'wholesale_price' => 0,
                'unit_price' => [
                    'price' => 0,
                ],
            ],
            'shipping' => [
                'dimensions' => [
                    'width' => 0,
                    'height' => 0,
                    'depth' => 0,
                    'weight' => 0,
                ],
                'additional_shipping_cost' => 0,
                'delivery_time_note_type' => DeliveryTimeNoteType::TYPE_DEFAULT,
            ],
            'options' => [
                'visibility' => [
                    'visibility' => ProductVisibility::VISIBLE_EVERYWHERE,
                ],
                'condition' => ProductCondition::NEW,
            ],
            'categories' => [
                'product_categories' => [
                    $this->defaultCategoryId => [
                        'is_associated' => true,
                        'is_default' => true,
                    ],
                ],
            ],
            'footer' => [
                'active' => $this->defaultProductActivation,
            ],
        ]);
    }

    /**
     * Returned product data with shortcut data that is picked from existing data.
     *
     * @param array $productData
     *
     * @return array
     */
    private function addShortcutData(array $productData): array
    {
        $productData['shortcuts'] = [
            'retail_price' => [
                'price_tax_excluded' => $productData['pricing']['retail_price']['price_tax_excluded'],
                'price_tax_included' => $productData['pricing']['retail_price']['price_tax_included'],
                'tax_rules_group_id' => $productData['pricing']['tax_rules_group_id'],
            ],
            'stock' => [
                'quantity' => $productData['stock']['quantities']['quantity'],
            ],
        ];

        return $productData;
    }

    /**
     * @param ProductForEditing $productForEditing
     *
     * @return array
     */
    private function extractCategoriesData(ProductForEditing $productForEditing): array
    {
        $categoriesInformation = $productForEditing->getCategoriesInformation();
        $categories = [];
        foreach ($categoriesInformation->getCategoryIds() as $categoryId) {
            $categories[$categoryId] = [
                'is_associated' => true,
                'is_default' => $categoryId === $categoriesInformation->getDefaultCategoryId(),
            ];
        }

        return [
            'product_categories' => $categories,
        ];
    }

    /**
     * @param ProductForEditing $productForEditing
     *
     * @return array<string, mixed>
     */
    private function extractVirtualProductFileData(ProductForEditing $productForEditing): array
    {
        $data = [
            'has_file' => false,
        ];
        $virtualProductFile = $productForEditing->getVirtualProductFile();

        if (null !== $virtualProductFile) {
            $data = [
                'has_file' => true,
                'virtual_product_file_id' => $virtualProductFile->getId(),
                'name' => $virtualProductFile->getDisplayName(),
                'download_times_limit' => $virtualProductFile->getDownloadTimesLimit(),
                'access_days_limit' => $virtualProductFile->getAccessDays(),
                'expiration_date' => $virtualProductFile->getExpirationDate() ?
                    $virtualProductFile->getExpirationDate()->format(DateTime::DEFAULT_DATE_FORMAT) :
                    null,
            ];
        }

        return $data;
    }

    /**
     * @param ProductForEditing $productForEditing
     *
     * @return array<string, mixed>
     */
    private function extractHeaderData(ProductForEditing $productForEditing): array
    {
        return [
            'type' => $productForEditing->getType(),
            'name' => $productForEditing->getBasicInformation()->getLocalizedNames(),
        ];
    }

    /**
     * @param ProductForEditing $productForEditing
     *
     * @return array<string, mixed>
     */
    private function extractBasicData(ProductForEditing $productForEditing): array
    {
        return [
            'description' => $productForEditing->getBasicInformation()->getLocalizedDescriptions(),
            'description_short' => $productForEditing->getBasicInformation()->getLocalizedShortDescriptions(),
            'features' => $this->extractFeatureValues($productForEditing->getProductId()),
            'manufacturer' => $productForEditing->getOptions()->getManufacturerId(),
        ];
    }

    /**
     * @param int $productId
     *
     * @return array<string, array<int, array<string, int|array<int, string>>>>
     */
    private function extractFeatureValues(int $productId): array
    {
        /** @var ProductFeatureValue[] $featureValues */
        $featureValues = $this->queryBus->handle(new GetProductFeatureValues($productId));
        if (empty($featureValues)) {
            return [];
        }

        $productFeatureValues = [];
        foreach ($featureValues as $featureValue) {
            $productFeatureValue = [
                'feature_id' => $featureValue->getFeatureId(),
                'feature_value_id' => $featureValue->getFeatureValueId(),
            ];
            if ($featureValue->isCustom()) {
                $productFeatureValue['custom_value'] = $featureValue->getLocalizedValues();
                $productFeatureValue['custom_value_id'] = $featureValue->getFeatureValueId();
            }

            $productFeatureValues[] = $productFeatureValue;
        }

        return [
            'feature_values' => $productFeatureValues,
        ];
    }

    /**
     * @param ProductForEditing $productForEditing
     *
     * @return array<string, mixed>
     */
    private function extractStockData(ProductForEditing $productForEditing): array
    {
        $stockInformation = $productForEditing->getStockInformation();
        $availableDate = $stockInformation->getAvailableDate();

        return [
            'quantities' => [
                'quantity' => $stockInformation->getQuantity(),
                'minimal_quantity' => $stockInformation->getMinimalQuantity(),
            ],
            'options' => [
                'stock_location' => $stockInformation->getLocation(),
                'low_stock_threshold' => $stockInformation->getLowStockThreshold() ?: null,
                'low_stock_alert' => $stockInformation->isLowStockAlertEnabled(),
            ],
            'virtual_product_file' => $this->extractVirtualProductFileData($productForEditing),
            'pack_stock_type' => $stockInformation->getPackStockType(),
            'availability' => [
                'out_of_stock_type' => $stockInformation->getOutOfStockType(),
                'available_now_label' => $stockInformation->getLocalizedAvailableNowLabels(),
                'available_later_label' => $stockInformation->getLocalizedAvailableLaterLabels(),
                'available_date' => $availableDate ? $availableDate->format(DateTime::DEFAULT_DATE_FORMAT) : '',
            ],
        ];
    }

    /**
     * @param ProductForEditing $productForEditing
     *
     * @return array<string, mixed>
     */
    private function extractPricingData(ProductForEditing $productForEditing): array
    {
        return [
            'retail_price' => [
                'price_tax_excluded' => (float) (string) $productForEditing->getPricesInformation()->getPrice(),
                'price_tax_included' => (float) (string) $productForEditing->getPricesInformation()->getPriceTaxIncluded(),
                'ecotax' => (float) (string) $productForEditing->getPricesInformation()->getEcotax(),
            ],
            'tax_rules_group_id' => $productForEditing->getPricesInformation()->getTaxRulesGroupId(),
            'on_sale' => $productForEditing->getPricesInformation()->isOnSale(),
            'wholesale_price' => (float) (string) $productForEditing->getPricesInformation()->getWholesalePrice(),
            'unit_price' => [
                'price' => (float) (string) $productForEditing->getPricesInformation()->getUnitPrice(),
                'unity' => $productForEditing->getPricesInformation()->getUnity(),
            ],
        ];
    }

    /**
     * @param ProductForEditing $productForEditing
     *
     * @return array
     */
    private function extractSEOData(ProductForEditing $productForEditing): array
    {
        $seoOptions = $productForEditing->getProductSeoOptions();

        return [
            'meta_title' => $seoOptions->getLocalizedMetaTitles(),
            'meta_description' => $seoOptions->getLocalizedMetaDescriptions(),
            'link_rewrite' => $seoOptions->getLocalizedLinkRewrites(),
            'redirect_option' => $this->extractRedirectOptionData($productForEditing),
        ];
    }

    /**
     * @param ProductForEditing $productForEditing
     *
     * @return array<string, int|string>
     */
    private function extractRedirectOptionData(ProductForEditing $productForEditing): array
    {
        $seoOptions = $productForEditing->getProductSeoOptions();

        return [
            'type' => $seoOptions->getRedirectType(),
            'target' => $seoOptions->getRedirectTargetId(),
        ];
    }

    /**
     * @param ProductForEditing $productForEditing
     *
     * @return array<string, mixed>
     */
    private function extractShippingData(ProductForEditing $productForEditing): array
    {
        $shipping = $productForEditing->getShippingInformation();

        return [
            'dimensions' => [
                'width' => (string) $shipping->getWidth(),
                'height' => (string) $shipping->getHeight(),
                'depth' => (string) $shipping->getDepth(),
                'weight' => (string) $shipping->getWeight(),
            ],
            'additional_shipping_cost' => (string) $shipping->getAdditionalShippingCost(),
            'delivery_time_note_type' => $shipping->getDeliveryTimeNoteType(),
            'delivery_time_notes' => [
                'in_stock' => $shipping->getLocalizedDeliveryTimeInStockNotes(),
                'out_of_stock' => $shipping->getLocalizedDeliveryTimeOutOfStockNotes(),
            ],
            'carriers' => $shipping->getCarrierReferences(),
        ];
    }

    /**
     * @param ProductForEditing $productForEditing
     *
     * @return array<string, mixed>
     */
    private function extractOptionsData(ProductForEditing $productForEditing): array
    {
        $options = $productForEditing->getOptions();
        $details = $productForEditing->getDetails();

        return [
            'visibility' => [
                'visibility' => $options->getVisibility(),
                'available_for_order' => $options->isAvailableForOrder(),
                'show_price' => $options->showPrice(),
                'online_only' => $options->isOnlineOnly(),
            ],
            'tags' => $this->presentTags($productForEditing->getBasicInformation()->getLocalizedTags()),
            'show_condition' => $options->showCondition(),
            'condition' => $options->getCondition(),
            'references' => [
                'mpn' => $details->getMpn(),
                'upc' => $details->getUpc(),
                'ean_13' => $details->getEan13(),
                'isbn' => $details->getIsbn(),
                'reference' => $details->getReference(),
            ],
            'customizations' => $this->extractCustomizationsData($productForEditing),
            'suppliers' => $this->extractSuppliersData($productForEditing),
        ];
    }

    /**
     * @param ProductForEditing $productForEditing
     *
     * @return array<string, array<int, mixed>>
     */
    private function extractCustomizationsData(ProductForEditing $productForEditing): array
    {
        /** @var CustomizationField[] $customizationFields */
        $customizationFields = $this->queryBus->handle(
            new GetProductCustomizationFields($productForEditing->getProductId())
        );

        if (empty($customizationFields)) {
            return [];
        }

        $fields = [];
        foreach ($customizationFields as $customizationField) {
            $fields[] = [
                'id' => $customizationField->getCustomizationFieldId(),
                'name' => $customizationField->getLocalizedNames(),
                'type' => $customizationField->getType(),
                'required' => $customizationField->isRequired(),
            ];
        }

        return [
            'customization_fields' => $fields,
        ];
    }

    /**
     * @param LocalizedTags[] $localizedTagsList
     *
     * @return array<int, string>
     */
    private function presentTags(array $localizedTagsList): array
    {
        $tags = [];
        foreach ($localizedTagsList as $localizedTags) {
            $tags[$localizedTags->getLanguageId()] = implode(',', $localizedTags->getTags());
        }

        return $tags;
    }

    /**
     * @param ProductForEditing $productForEditing
     *
     * @return array<string, int|array<int, int|array<string, string|int>>>
     */
    private function extractSuppliersData(ProductForEditing $productForEditing): array
    {
        /** @var ProductSupplierOptions $productSupplierOptions */
        $productSupplierOptions = $this->queryBus->handle(new GetProductSupplierOptions($productForEditing->getProductId()));

        if (empty($productSupplierOptions->getSuppliersInfo())) {
            return [];
        }

        $defaultSupplierId = $productSupplierOptions->getDefaultSupplierId();
        $suppliersData = [
            'default_supplier_id' => $defaultSupplierId,
        ];

        foreach ($productSupplierOptions->getSuppliersInfo() as $supplierOption) {
            $supplierForEditing = $supplierOption->getProductSupplierForEditing();
            $supplierId = $supplierOption->getSupplierId();

            $suppliersData['supplier_ids'][] = $supplierId;
            $suppliersData['product_suppliers'][$supplierId] = [
                'supplier_id' => $supplierId,
                'supplier_name' => $supplierOption->getSupplierName(),
                'product_supplier_id' => $supplierForEditing->getProductSupplierId(),
                'price_tax_excluded' => $supplierForEditing->getPriceTaxExcluded(),
                'reference' => $supplierForEditing->getReference(),
                'currency_id' => $supplierForEditing->getCurrencyId(),
                'combination_id' => $supplierForEditing->getCombinationId(),
            ];
        }

        return $suppliersData;
    }
}