0

I have looked everywhere high and low, and tried every "solution" I could find, but could not figure out what's wrong with my code.

We have an XML feed which gets imported to a local folder, and then gets processed.

We have an insert and update script. The insert script seems to work okay ,though it's quite slow. But when it comes to updating, I get one of the following things;

  • Unique constraint violation found
  • Database lock wait timeout

And none of the products actually gets updated.

Here's the insert script;

private function createNewProduct($product)
{
    // Categorieen aanmaken
    $categoryId = $this->createCategories($product->Cat_Level01, $product->Cat_Level02, $product->Cat_Level03, $product->Cat_Level04);
    $inStock    = 0;

    if ((int) $product->VoorraadWeb > 0) {
        $inStock = 1;
    }

    include('app/bootstrap.php');

    $bootstrap     = Bootstrap::create(BP, $_SERVER);
    $objectManager = $bootstrap->getObjectManager();

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

    $tierPrices = $this->fixTierPrices($product);

    $_product = $objectManager->create('Magento\Catalog\Model\Product');

    $_product->setName($product->Omschrijving);
    $_product->setTypeId('simple');
    $_product->setStatus(1);
    $_product->setAttributeSetId(4);
    $_product->setSku($product->Artikelcode);
    $_product->setTaxClassId(1);
    $_product->setWebsiteIds(array(0, 1, 3));
    $_product->setVisibility(4);
    $_product->setPrice($product->Verkoopprijs);
    $_product->setCategoryIds($categoryId);
    $_product->setTierPrice($tierPrices);

    $_product->setDescription($product->Omschrijving);
    $_product->setShortDescription($product->Omschrijving);

    if (! empty($product->LinkPicture)) {
        $image = $this->downloadImage(str_replace('\\', '/', $product->LinkPicture));
        $_product->addImageToMediaGallery($image, array('image', 'small_image', 'thumbnail'), false, false);
    }

    $_product->save();

    $stockItem = $this->stockRegistry->getStockItemBySku($product->Artikelcode);
    $stockItem->setQty($product->VoorraadWeb);
    $stockItem->setIsInStock((bool) $product->VoorraadWeb);
    $stockItem->setManageStock(true);
    $stockItem->setUseConfigManageStock(false);
    $stockItem->setMaxSaleQty(999);

    $this->stockRegistry->updateStockItemBySku($product->Artikelcode, $stockItem);
}

And here's the update part. The $products->Artikel comes from the XML file, and is an array with all products;

foreach ($products->Artikel as $product) {
        // Kijken of deze producten verwerkt moeten worden.
        if ($counter < $offset) {
            $counter++;
            continue;
        } elseif ($counter == $max) {
            $this->_redirect($newUrl);
        }

        // Bestaat het product al, en heeft het een update nodig?
        $productEntity = $this->getProductEntity($product->Artikelcode);

        try {
            // Bestaat product al?
            if (! empty($productEntity)) {
                // Update nodig?
                if ($this->productNeedsUpdate($productEntity, $product)) {
                    // Update
                    $SKU        = (string) $product->Artikelcode;
                    $categoryId = $this->createCategories($product->Cat_Level01, $product->Cat_Level02, $product->Cat_Level03, $product->Cat_Level04);
                    $image      = null;
                    $tierPrices = $this->fixTierPrices($product);

                    $updateProduct = $this->productData($SKU)
                        ->setStatus(1)
                        ->setSpecialPrice(null)
                        ->setCategoryIds($categoryId)
                        ->setVisibility(4)
                        ->setTierPrice($tierPrices)
                        ->setWebsiteIds([0, 1, 3]);

                    if (! empty($product->LinkPicture)) {
                        $this->deleteExistingMediaEntries($this->productData($SKU)->getId());

                        $image = $this->downloadImage(str_replace('\\', '/', $product->LinkPicture));

                        $updateProduct->addImageToMediaGallery($image, array('image', 'small_image', 'thumbnail'), false, false);
                        $this->log($SKU, '', 'Image updated', 'message');
                    }

                    $updateProduct->save();

                    $productId   = $this->productFactory->create()->getIdBySku($SKU);
                    $productRepo = $this->productFactory->create()->load($productId);

                    $productRepo->addAttributeUpdate('ean', $product->EAN, 0);

                    $stockItem = $this->stockRegistry->getStockItemBySku($SKU);
                    $stockItem->setQty($product->VoorraadWeb);
                    $stockItem->setIsInStock((bool) $product->VoorraadWeb);
                    $stockItem->setManageStock(true);
                    $stockItem->setUseConfigManageStock(false);
                    $stockItem->setMaxSaleQty(999);

                    $this->stockRegistry->updateStockItemBySku($SKU, $stockItem);

                    $this->log($SKU, '', 'Item updated', 'message');
                }
            } else {
                // Nieuw product
                if ($this->needsSkip($product)) {
                    continue;
                }

                $this->createNewProduct($product);
            }
        } catch (\Exception $e) {
            $this->log($product->Artikelcode, $this->getBottomLevelCategory($product), $e->getMessage(), 'error');
            header('Location: http://localhost/kikgoes.nl/' . $newUrl);
            die();
        }

        $counter++;
    }

This is the createCatory function for reference. The categories are delivered in the XML in separate fields..

private function createCategories($category1, $category2 = null, $category3 = null, $category4 = null)
{
    // Check if category exists
    $mainCategory = $this->categoryExists($category1);

    if ($mainCategory === false) {
        $mainCategory = $this->createCategory($category1);
    }

    $category2 = trim($category2);
    $category3 = trim($category3);
    $category4 = trim($category4);

    if (! empty($category2)) {
        $secondCategory = $this->categoryExists($category2);

        if ($secondCategory === false) {
            $secondCategory = $this->createCategory($category2, $mainCategory, $mainCategory);
        }

        if (! empty($category3)) {
            $thirdCategory = $this->categoryExists($category3);

            if ($thirdCategory === false) {
                $thirdCategory = $this->createCategory($category3, $mainCategory . '/' . $secondCategory, $secondCategory);
            }

            if (! empty($category4)) {
                $fourthCategory = $this->categoryExists($category4);

                if ($fourthCategory === false) {
                    $fourthCategory = $this->createCategory($category3, $mainCategory . '/' . $secondCategory . '/' . $thirdCategory, $thirdCategory);
                }
            }
        }
    }

    if (isset($fourthCategory)) {
        return $fourthCategory;
    } elseif (isset($thirdCategory)) {
        return $thirdCategory;
    } elseif (isset($secondCategory)) {
        return $secondCategory;
    } else {
        return $mainCategory;
    }
}

Your Answer

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

Browse other questions tagged or ask your own question.