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

2 Answers 2

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));
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.

1
  • what was the issue, we are not using toString anywhere in the code Commented Dec 1, 2018 at 12:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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