1

for a relaunch I've been trying to output some 301 redirect for our htaccess (the old system was not magento).

So I've exported an array of 'old_url' => 'product_id' and now I'm trying to loop through it to get our new urls, using something like this:

foreach($arr as $url => $prodId) {

    $oldurl = $url;

    $product = Mage::getModel('catalog/product')
                ->setStoreId($store_id)
                ->loadByAttribute('objektnummer', $prodId);

    $newurl = $product->getProductUrl();            

    echo "Redirect 301 " . $oldurl . "\t\t" . $newurl . "\n";

}

But what I've found is that if a Produkt is not found, the loop breaks. Obviously this is rather tedious if you have 10,000s of URLs to go through.

So my question is this, if loading a product by a product_id that is not found in the database breaks the loop, how can I check it first?

It would be nice if the following returned 'FALSE' or 'NULL' or something rather than just breaking.

$product = Mage::getModel('catalog/product')
            ->setStoreId($store_id)
            ->loadByAttribute('objektnummer', $prodId);

4 Answers 4

1

When you execute following code

$product = Mage::getModel('catalog/product')
        ->setStoreId($store_id)
        ->loadByAttribute('objektnummer', $prodId);

Magento returns object of the product, or if there no such product magento returns FALSE. And the error in your case appear on the next row:

$newurl = $product->getProductUrl();

Because FALSE has no method getProductUrl()

So in that case just check:

        if($product !== false)
        {
            $newurl = $product->getProductUrl();
        }
1
  • Perfect, this is exactly what I was looking for. I did try and check for true / null and false, but I couldn't get it to work. This works perfectly. I suppose it should as I guess it is not much different to if(Mage::getModel('catalog/product')->setStoreId($store_id)->loadByAttribute('objektnummer', $prodId)) { apart from that the call isn't made twice.
    – tecjam
    Apr 10, 2015 at 7:47
0

Try using

foreach($arr as $url => $prodId) {

$oldurl = $url;

$product = Mage::getModel('catalog/product')
            ->setStoreId($store_id)
            ->loadByAttribute('objektnummer', $prodId);

if ($newurl = $product->getProductUrl()) {            
    echo "Redirect 301 " . $oldurl . "\t\t" . $newurl . "\n";
}
}
3
  • I'm afraid this behaves exactly the same and breaks as soon as it gets to a $prodId that it can not find.
    – tecjam
    Apr 9, 2015 at 15:22
  • What is the error you get?
    – mbalparda
    Apr 9, 2015 at 15:32
  • <b>Fatal error</b>: Call to a member function getProductUrl() on a non-object in <b>/html/magento/_do301.php</b> on line <b>4683</b><br /> - The line in question is if($newurl = $product->getProductUrl()) {
    – tecjam
    Apr 9, 2015 at 15:38
0

Ok, I got round it by doing this:

foreach($arr as $url => $prodId) {

    $oldurl = $url;

    if(Mage::getModel('catalog/product')->setStoreId($store_id)->loadByAttribute('objektnummer', $prodId)) {

        $product = Mage::getModel('catalog/product')
                    ->setStoreId($store_id)
                    ->loadByAttribute('objektnummer', $prodId);


        $newurl = $product->getProductUrl();

        echo "Redirect 301 " . $oldurl . "\t\t" . $newurl . "\n";
    }

}
0

It will good idea to use Product collection and filter the collection by products ids. then add Url rewrite manage .it does not break system

$ReverseIndex=array();
foreach($arr as $key=>$value):
$ReverseIndex[$value]=$key;
endforeach;


$collection = Mage::getResourceModel('catalog/product_collection')->addUrlRewrite()->addIdFilter(array_values($arr));

foreach($collection  as $eachPro):
if($ReverseIndex[$eachPro->getId]==$eachPro->getProductUrl()):
 echo "Redirect 301 " . $ReverseIndex[$eachPro->getId] . "\t\t" .$eachPro->getProductUrl() . "\n";
endif;

endforeach;

According you comment as you want to filter using attribute then you can used in condition to collection

$collection = Mage::getResourceModel('catalog/product_collection')->addUrlRewrite()->addAttributeToFilter('objektnummer',array('in' => explode(',', array_values($arr))));

But make sure the attribute is enable at Used In Product at Attribute backed

4
  • Nice, but I am not using the actual product ids, I'm using a custom product attribute 'objektnummer'.
    – tecjam
    Apr 9, 2015 at 15:41
  • I suppose I could have used ->addAttributeToFilter('objektnummer', $prodId); on the collection instead of ->addIdFilter(). Thanks.
    – tecjam
    Apr 9, 2015 at 15:51
  • please check my update answer
    – Amit Bera
    Apr 9, 2015 at 16:32
  • Remove the explode from your code, it already is an array.
    – user4351
    Apr 9, 2015 at 17:28

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.