0

I wanted to do simple price update script, that loads data from xml and passes it to product queried by custom attribute "ean".

I am able to get the product by 2 different ways ProductRepositoryInterface and ProductFactory, when i try to save product using interface i get error that "Class string not found..." when i try to save product by using ProductFactory (save method of product model) then nothing happens.

Using Magento 2.1.5

After long hours of googling and trying i have not seen other types of solutions to retrieve, edit and save product.

I have tried to re-index afterwards to delete cache... ) My code is test.php located in magento2 root directory

<?php
use Magento\Framework\App\Bootstrap;

include('app/bootstrap.php');
$bootstrap = Bootstrap::create(BP, $_SERVER);

error_reporting(E_ALL);
ini_set('display_errors', 'On');

$objectManager = $bootstrap->getObjectManager();

$state = $objectManager->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');

/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productInterface */
$productInterface = $objectManager->get('\Magento\Catalog\Api\ProductRepositoryInterface');

/** @var \Magento\Catalog\Model\Product $productModel */
$productModel = $objectManager->get('\Magento\Catalog\Model\ProductFactory')->create();

$file = dirname(__FILE__) . "/Zasoby.xml";
$xml_content = file_get_contents($file);
$xml_content = str_replace(array("stk:", "lStk:", "rsp:", "typ:"), array("", "", "", ""), $xml_content);
$xml = simplexml_load_string($xml_content);

# Quick switch between interface method and model method
$update_using_interface = false;

foreach ($xml->responsePackItem->listStock->stock as $item):

    $item = $item->stockHeader;

    if (!isset($item->EAN)):
        continue;
    endif;

    /** @var \Magento\Catalog\Model\Product $product */
    $product = $productModel->loadByAttribute("ean", $item->EAN);

    if (!$product):
        continue;
    endif;

    # Product is found so lets start update
    echo "Updating product: " . $product->getName() . "<br/>";

    if ($update_using_interface):
        $product = $productInterface->getById($product->getId(), true);
    endif;

    # Update name and price
    $product->setName($item->name);
    $product->setPrice($item->sellingPrice);

    if ($update_using_interface):
        # Uncaught exception 'ReflectionException' with message 'Class string does not exist'
        $productInterface->save($product);
    else:
        $product->save();
        $product->reindex();
    endif;

endforeach;

Thank you for any suggestions

0

Doing something that would cast it to a string also does this for you.

E.g. trim the value.

$product
    ->setSku(trim($exportProduct->sku))
    ->setName(trim($exportProduct->name));
| improve this answer | |
0

I got the problem, $product->setName($item->name); vs $product->setName($item->name->__toString());

When working with simplexml, it returns object that has magic method __toString() which works fine in nearly any case, for example while loadnig product by attribute ->__toString was not required, it automatically detected. But when setting product data its required, otherwise magento will try to search class "String" instead of doing the __toString() magic.

| improve this answer | |
  • what was the issue, we are not using toString anywhere in the code – jafar pinjar Dec 1 '18 at 12:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.