M.E.
M.E.

Reputation: 86

Add product price to all products on plugin activation

I want to add a further product price to all existing products on plugin activation. But the activation process stops after about 5 seconds and so the product price is only added to 24 of 60 products. The plugin activation fails.

I don't know why the activation process stops. How can I solve this problem and add the price to all products?

Here is my code:

public function activate(ActivateContext $activateContext): void
{
    // Get rule
    $ruleRepository = $this->container->get('rule.repository');
    $criteria = new Criteria();
    $criteria->addFilter(new EqualsFilter('name', 'XYZ'));
    /** @var RuleEntity $rule */
    $rule = $ruleRepository->search($criteria, $activateContext->getContext())->first();
    $ruleId = $rule->getId();

    // Add pricing rule to all products
    $productRepository = $this->container->get('product.repository');
    $products = $productRepository->search(new Criteria(), $activateContext->getContext());
    $productPriceRepository = $this->container->get('product_price.repository');
    /** @var ProductEntity $product */
    foreach ($products as $product) {
        $productPriceRepository->create([[
            'id' => Uuid::randomHex(),
            'productId' => $product->getId(),
            'quantityStart' => 1,
            'ruleId' => $ruleId,
            'price' => [
                [
                    'currencyId' => Defaults::CURRENCY,
                    'gross' => $product->getCurrencyPrice(Defaults::CURRENCY)->getGross(),
                    'net' => $product->getCurrencyPrice(Defaults::CURRENCY)->getNet(),
                    'linked' => true
                ]
            ],
        ]], $activateContext->getContext());
    }
}

Upvotes: 1

Views: 215

Answers (2)

dnaumann
dnaumann

Reputation: 474

I think the code needs to much memory, cause the shopware 6 dal is very expensive on memory. As Michael T said, you should avoid such expensive operations in the installation or activation process of a plugin. The best practices would be to write a) a CLI command which needs to be executed manually after installation (https://developer.shopware.com/docs/guides/plugins/plugins/plugin-fundamentals/add-custom-commands), or b) if you dont want manual actions create entries in a queue which are handled by a message handler (https://developer.shopware.com/docs/guides/plugins/plugins/framework/message-queue/add-message-handler)

Upvotes: 3

dneustadt
dneustadt

Reputation: 13161

The lifecycle events of plugins really are not supposed to handle large scale write operations like that. Without knowing the quantity of products this could easily be an issue caused by memory exhaustion. To verify that you could set a reasonable limit to your criteria:

$criteria = new Criteria(); 
$criteria->setLimit(50);

Aside from that ProductEntity::getCurrencyPrice() returns ?Price, so you want to check if it returns null before calling getGross and getNet. I'd recommend taking this code out of the lifecycle handler and to add it to a custom CLI command instead.

Upvotes: 3

Related Questions