1

I need to change all my product URLs and I would like to use a code snippet to use it. All I need is a simple code which is Magento 2 compatible and will change the URL for one product then saves it. I have this so far:

<?php
use \Magento\Framework\App\Bootstrap;
include('/var/www/html/app/bootstrap.php');

$bootstrap = Bootstrap::create(BP, $_SERVER);  
$obj = $bootstrap->getObjectManager();
$deploymentConfig = $obj->get('Magento\Framework\App\DeploymentConfig');

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();

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

$product = $objectManager->create('\Magento\Catalog\Model\Product')->load(2933);
$name = $product->getName();
print $name;
$url="new-product-url";
$product ->setUrlKey($url);
$objectManager->get('\Magento\Catalog\Model\Product')->save($product);
#$product->save(); 
?>

The code goes as far as the URL change then it fails with:

PHP Fatal error:  Uncaught Magento\Framework\Exception\LocalizedException: Area code is not set in /var/www/html/vendor/magento/framework/App/State.php:153
Stack trace:
#0 /var/www/html/vendor/magento/module-catalog/Model/Product.php(2415): Magento\Framework\App\State->getAreaCode()
#1 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Catalog\Model\Product->getIdentities()
#2 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Catalog\Model\Product\Interceptor->___callParent('getIdentities', Array)
#3 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Catalog\Model\Product\Interceptor->Magento\Framework\Interception\{closure}()
#4 /var/www/html/generated/code/Magento/Catalog/Model/Product/Interceptor.php(52): Magento\Catalog\Model\Product\Interceptor->___callPlugins('getIdentities', Array, Array)
#5 /var/www/html/vendor/magento/framework/App/Cache/Tag/Strategy/Identifier.php(25): Magento\Catalog\Model\Product\Interceptor->getIdentities( in /var/www/html/vendor/magento/framework/App/State.php on line 153


I am unsure why would I be defining any area codes when I am only changing a product not an order or a customer?!

1

You need to set Area code in your root file. Add this below code and run your script :

$state = $objectManager->get('\Magento\Framework\App\State');
$state->setAreaCode('frontend');
| improve this answer | |
  • 1
    Many thanks for the straightforward answer, this is exactly what I needed. – Zoltan veress Nov 13 '19 at 3:02
0

You always need to set an area code if you want to modify some data in Magento2 and for a lot of other stuff.

Setting the area code can be done by injecting, or in your case using the objectmanager to get an instance of the class \Magento\Framework\App\State and calling the method setAreaCode with one of the areas provided as constants in \Magento\Framework\App\Area.

If you create custom console commands for Magento2 you may run into the same issue, also for this one you can set the area code manually like described here: 'Area code not set' issue in custom CLI commands in Magento 2.

You still need to take care, that the area code is not set already, because setting the area code, if it is already set, will also throw an exception. So checking this by getting the area code first, is in my opinion recommended.

I also would not recommend to write Magento2 shell scripts like this, because you can usually run into a lot of issues you may not occur when creating a small module around a script.

| improve this answer | |
  • Hello, thanks for the answer. What issues can this cause exactly? – Zoltan veress Nov 13 '19 at 3:04
  • i just related to all the stuff you may do wrong, when initializing bootstrap, using accidentially create instead of get on the objectmanager to create a new instance instead of using an existing one, or something similar. You dont need to take care of things like this from within a module. – Ekk4rd Nov 13 '19 at 10:11
0

I have finalized the code adding command line parameters such as

  • new url
  • store id
  • product id

Run this from inside your magento 2 root directory to change an url. Also I added support for create permanent redirect to the old url as by default it is not set.

<?php

use \Magento\Framework\App\Bootstrap;
include('/var/www/html/app/bootstrap.php');

$url=$argv[1];
$storeid=$argv[2];
$productid=$argv[3];

$bootstrap = Bootstrap::create(BP, $_SERVER);  
$obj = $bootstrap->getObjectManager();
$deploymentConfig = $obj->get('Magento\Framework\App\DeploymentConfig');

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();

#Setting area code, it won't work without this
$state = $objectManager->get('\Magento\Framework\App\State');
$state->setAreaCode('frontend');

#Load product using the product id 
$product = $objectManager->create('\Magento\Catalog\Model\Product')->load($productid);
$name = $product->getName();
$urlcode = $product->getUrlKey();

print $name."\n";
print $urlcode."\n";

#Setting store id, important of you have multiple stores
$product ->setStoreId($storeid);
#Setting the URL
$product ->setUrlKey($url);
#Setting Create Permanent Redirect for old URL
$product ->setData('save_rewrites_history',1);
#Saving Product
$product->save($product); 

?>

The syntax of the script would be:

php urlchange.php new-url-you-want-to-set your-store-id productid

Example:

php urlchange.php dell-inspiron-14500 3 1222

I hope this will help others.

| improve this answer | |

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.