How to check if a product exists in catalog, rather than deleted, when on Order View page?
-
16-10-2019 - |
Question
Ok, so I've learned how to make the product name a clickable link (when viewing an order as admin) to that product's Edit Page on our Admin Dashboard - here's the post w/ answer.
The answer shows this is the code to add to:
app/design/adminhtml/default/default/template/sales/order/view/items/renderer/default.phtml
<div class="item-text">
<?php $_pullProduct = Mage::getModel('catalog/product')->loadByAttribute('sku', $_item->getData('sku')); ?>
<a target="_blank" rel="external" href="<?php echo Mage::helper('adminhtml')->getUrl('adminhtml/catalog_product/edit', array('id' => $_pullProduct->getId()))?>">
<?php echo $this->getColumnHtml($_item, 'name') ?></a>
</div>
This works perfectly, except for one thing: If the order has a product that has been deleted, that snippet of code that gets the product URL can't find the product, since it's been deleted, and the HTML stops loading at that line, breaking the Order View page for that order.
Orders with products that have not been deleted work fine with this bit of code.
How might I go about only linking to the product URL if the product exists in the product catalog and has not been deleted?
Btw, These products are deleted forever, rather than simply disabled. Disabled products work fine.
Edit/Update:
Thanks for the answers - Both look great, and I believe Fabian's answer was closer to was I was looking for - Here's a question for Fabian's answer, which I attempted to ask in the comment form, and didn't look too good, so I shall ask in a more readable way here:
I'm having a problem figuring out how to implement your answer and is most likely because I'm slowly learning PHP, but I'm not too experience with it since my main job is design, but I do manage to get by with the bit of PHP I've needed to learn. I attempted:
using...
if(!$product->isObjectNew()): do something
and I ended up trying...
<div class="item-text">
<?php echo $this->getColumnHtml($_item, 'name') ?>
<?php if(!$product->isObjectNew()): ?>
<?php $_pullProduct = Mage::getModel('catalog/product')->loadByAttribute('sku', $_item->getData('sku')); ?><a target="_blank" rel="external" href="<?php echo Mage::helper('adminhtml')->getUrl('adminhtml/catalog_product/edit', array('id' => $_pullProduct->getId()))?>">View</a>
<?php endif; ?>
</div>
...and this does not work, and I understand it's because I'm incorporating:
if(!$product->isObjectNew()): do something
improperly.
I'm not sure what my flaw is, even after looking at similar code in other phtml files on the site, attempting to copy what I see, and I'm still unable to figure this out. This is where I could use help from you guys, this would be a great opportunity for me to learn something.
Solution
I appreciate and recommend the second way from philwinkle.
Beside of this you can just check whether the product exists with if(!$product->isObjectNew()): do something
the isObjectNew method checks for an existing id, if the object doesnt have an id, it was not loaded.
OTHER TIPS
Two things:
First:
What you really need here is to pull the sales/order_item
information, rather than loading the product. Unfortunately for you, the sales tables do not capture url_key, the attribute you require. The way in which you're loading the product it should be available via the magic getter $_pullProduct->getUrlKey()
;
The only way that I know how to do this is a multi-step process:
- Add a url_key column to the
sales_flat_order_item
table - Create an observer that will save the url_key data on save of the
sales/order_item
model
Providing this code is probably beyond the scope of this Q&A, but there are many resources online - here are a couple I found on Google:
http://www.npdemers.net/blog/2012/03/magento-adding-custom-attributes-to-orders
http://www.npdemers.net/blog/2012/04/magento-adding-custom-attributes-to-orders-part-ii
Second/Best Practice:
Avoid loading models in view files - it's bad practice. Rather, extend the block with a rewrite (in this case Mage_Adminhtml_Block_Sales_Order_View_Items_Renderer_Default
) and add a method to return this to your template file.
A good example of this practice is found at the top of the template file you're extending -- it calls $this->getItem()
- this corresponds to the method getItem
found in the Block.