0

I have this script to update product attributes, everything else run fine until i added this line below of code to update visibility to search only. I know i can update it through catalog product grid, but would like to know why this doesn't work.

->setVisibility(3)

or

->setVisibility(search_only)

or

->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_IN_SEARCH)

more details:

 /*check url key*/

 /*holder for new url key in case it's a duplicate*/
//$name = $product->getName();
//$url = preg_replace('#[^0-9a-z]+#i', '-', $name);
//$url = strtolower($url) . 'discontinued';
$currentURL = $product->getUrlKey();
$urlKey = $currentURL;
$storeId = 1;
//echo $storeManager->getStore()->getStoreId() . '<br />'; //here returned 1
    $isUrlDuplicate;
    $urlKey .= '.html';
    $connection = $resource->getConnection(\Magento\Framework\App\ResourceConnection::DEFAULT_CONNECTION);
    $tablename = $connection->getTableName('url_rewrite');
    $sql = $connection->select()->from(
                    ['url_rewrite' => $connection->getTableName('url_rewrite')], ['request_path', 'store_id']
            )->joinLeft(
                    ['cpe' => $connection->getTableName('catalog_product_entity')], "cpe.entity_id = url_rewrite.entity_id"
            )->where('request_path IN (?)', $urlKey)
            ->where('store_id IN (?)', $storeId)
            ->where('cpe.sku not in (?)', $sku);
    $urlKeyDuplicates = $connection->fetchAssoc($sql);
    if (!empty($urlKeyDuplicates)) {
    //  return false;
        $isUrlDuplicate = 0;
    } else {
        //return true;
        $isUrlDuplicate = 1;
        //if is duplicate, add eol to url
        $newURL = $currentURL . '-eol';
        $product->setStoreId(1)->setUrlKey($newURL);
        echo 'setting new url key to ' . $newURL  .'<br />';
    }
echo 'original url key is '.$currentURL . ' is duplicate? ' . ( $isUrlDuplicate > 0 ? 'yes' : 'no') .'<br />';

//$price = trim($data['price']);
echo 'Getting product SKU: '.$sku.', with EOL Status: '.$product->getIsEol().'<br />'; 
echo 'Updating product SKU: '.$sku.', with EOL Status: '.$status.'('.$option_id.')'.'<br />'; // .' and Price:'.$price.'<br />';
$product->setIsEol($option_id)   // use option_id here
->setStoreId(1) // this is needed because if you have multiple store views, each individual store view will get "Use default value" unchecked for multiple attributes - which causes issues.
->setCustomStockStatus($status_id)
->setMetaDescription('Discontinued')
->setVisibility(3)   //this line break the script  //VISIBILITY_IN_SEARCH VISIBILITY_IN_CATALOG VISIBILITY_BOTH
//->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
->save();

error_log

[07-Jun-2019 00:12:42 UTC] PHP Fatal error:  Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'digital-to-analog-audio-converter.html-1' for key 'URL_REWRITE_REQUEST_PATH_STORE_ID' in /home/mystore/public_html/vendor/magento/zendframework1/library/Zend/Db/Statement/Pdo.php:228
Stack trace:
#0 /home/mystore/public_html/vendor/magento/zendframework1/library/Zend/Db/Statement/Pdo.php(228): PDOStatement->execute(Array)
#1 /home/mystore/public_html/vendor/magento/framework/DB/Statement/Pdo/Mysql.php(93): Zend_Db_Statement_Pdo->_execute(Array)
#2 /home/mystore/public_html/vendor/magento/zendframework1/library/Zend/Db/Statement.php(303): Magento\Framework\DB\Statement\Pdo\Mysql->_execute(Array)
#3 /home/mystore/public_html/vendor/magento/zendframework1/library/Zend/Db/Adapter/Abstract.php(480): Zend_Db_Statement->execute(Array)
#4 /home/mystore/public_html/vendor/magento/zendframework1/library/Zend/Db/Adapter/Pdo/Abstract.php(238): Zend_Db_Adapter_Abstract->query('INSERT  INTO `u...', Array)
#5 /home/mystore/public_h in /home/mystore/public_html/vendor/magento/module-url-rewrite/Model/Storage/DbStorage.php on line 220
1

The problem is not the ->setVisibility(3) call itself but the creation of an url rewrite entry for that product which is associated with the changing of the visibility. Most likely the product was 'Not Visible Individually' before and had no entry in url_rewrite table.

If you change the url_key for that product to something unique, the saving operation would work.

To check if a value used for url_key is unique you can use a method like posted in this answer https://magento.stackexchange.com/a/181898/76597

I would suggest to implement such a check in your code.

  • Hi, the original visibility is set to catalog/search, and status is set to disabled. I found another enabled product with the same url key. I added the duplicate check in my script, but when seems like ->setUrlkey( $cuurentURL . 'eol') does not save. can you check my updated code? thanks – Kris Wen Jun 7 at 18:59
  • I'm not sure about that, but your conflict is in store 1 and you check for existing rewrites in store 0. Do you enter the else path in the duplicate check? – HelgeB Jun 7 at 19:45
  • i'm a little confusion about the store ids ( since i only have one store). when i getStoreID(), it returned 1. i updated the scripts. Yes, i did enter the into the else path. – Kris Wen Jun 7 at 21:39
  • this seems to be the issue i am having with magento 2.2.6, i applied the code from here and seems to able to save the products now. github.com/magento/magento2/issues/7298#issuecomment-463532802 – Kris Wen Jun 7 at 21:52

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.