Help with Magento and related products - magento

I have a customer product page that literally lives beside the catalog/product/view.phtml page. It's basically identical to that page with a few small exceptions. It's basically a 'product of the day' type page so I can't combine it with the regular product page since I have to fetch the data from the DB and perform a load to get the product information
$_product = Mage::getModel('catalog/product')->load($row['productid']);
To make a long story short, everything works (including all children html blocks) with the singular exception of the related products.
After the load I save the product into the registry with
Mage::register('product', $_product);
and then attempt to load the related products with:
echo $this->getLayout()->createBlock('catalog/product_view')->setTemplate('catalog/product/list/related.phtml')->toHtml();`
All of which give back the error:
Fatal error: Call to a member function getSize() on a non-object in catalog/product/list/related.phtml on line 29`,
and line 29 is
<?php if($this->getItems()->getSize()): ?>`.
Any help getting the relateds to load would be appreicated.

I didn't quite follow what you're trying to do, but I know why you're getting your errors. You're creating a block whose class-alias/class is
catalog/product_view
Mage_Catalog_Block_Product_View
but you're setting this block's template as
catalog/product/list/related.phtml
The stock catalog/product/list/related.phtml template was built to be used with a catalog/product_list_related Block only, and not a catalog/product_view Block.
If you take a look at the class definition for a catalog/product_list_related Block (which is a Mage_Catalog_Block_Product_List_Related), you can see that there's a getItems() method.
public function getItems()
{
return $this->_itemCollection;
}
which returns a collection. The collection is set in the _prepareData method
protected function _prepareData()
{
$product = Mage::registry('product');
/* #var $product Mage_Catalog_Model_Product */
$this->_itemCollection = $product->getRelatedProductCollection()
...
This collection is never set with a catalog/product_view Block, which is why you're getting your errors.
In your code above, if you switch to creating a catalog/product_list_related block, your errors should go away.

public function relatedproductsAction(){
$this->loadLayout();
$relatedBlock = "";
$rec_prod_id = Mage::getSingleton('checkout/session')->getLastAddedProductId(true);
$_product = Mage::getModel('catalog/product')->load($rec_prod_id);
Mage::register('product', $_product);
$relatedBlock = $this->getLayout()->createBlock('catalog/product_list_related')->setTemplate('catalog/product/related.phtml')->toHtml();
echo $relatedBlock;
exit;
}
Getting html of related block through ajax call, right after when product is added to cart. might be relatively helpful.

Related

Can't pass variable in block directive from transactional email template

I've loaded New Order transactional email to insert a custom block. I inserted it under the order items table layout handle call, and try to pass it $order variable.
{{layout handle="sales_email_order_items" order=$order}}
...
{{block type="mymodule/sales_order_email_description" order=$order}}
In Mymodule_Block_Sales_Order_Email_Description class I wrote:
protected function _construct() {
$this->setTemplate('email/order/description.phtml');
}
And finally in description.phtml I try to access order:
$order = $this->getOrder();
...
$order->getId()
At this point, exception rise:
Fatal error: Call to a member function getId() on a non-object ... ...
I followed several tutorials, like this magento email templates but I'm still stuck with this fatal error.
Any ideas?
Let's take a look;
You can define the block with a template, the construct isn't needed any more.
{{block type="mymodule/sales_order_email_description" template="email/order/description.phtml" order=$order}}
Indeed you could get the parameter values with $this->getOrder(). But $order->getId() may not work, $order->getEntityId().
Maybe you could try a var_dump to see if there is any order data.
Try this in your .phtml file:
$order = $this->getData('order');
As described here: http://www.webspeaks.in/2011/06/customize-new-order-email-template-in-magento.html

magento get custom attribute label

I've a problem, I want to show the label of a custom attribute in the product page.
I explain me better, starting from this link because is what I want to do:
http://www.customy.com/blog/how-to-display-video-on-magento-product-page/
I want a video product in the sidebar of the product page, so I create a new custompage.phtml and i put this in the sidebar from catalog.xml, in my custompage.phtml I put this code to have the custom label:
getResource()->getAttribute('video')->getStoreLabel();?>
but I have this error:
"Fatal error: Call to a member function getResource() on a non-object in ..path//"
I have try different code but still have this problem.
I think that I forget to put something in my .phtml but I'm new of Magento and I don't know what!
Thank in advance!
Since $_product didn't work then you'll need to load the object before attempting to access the attribute. Try this:
$product_id = Mage::registry('current_product')->getId();
$_product=Mage::getModel('catalog/product')->load($product_id);
echo $_product->getResource()->getAttribute('video')->getStoreLabel();
If you don't have access to the product model, I wrote a small query to get it from DB. This could be done better, but should be a decent starting point for your class:
protected $_dbConn;
public function __construct()
{
$this->_dbConn = Mage::getSingleton('core/resource')->getConnection('core_read');
}
public function getAttributeLabel($code)
{
$query = "
SELECT b.value
FROM eav_attribute a
JOIN eav_attribute_label b
ON a.attribute_id = b.attribute_id
WHERE a.attribute_code = '".$code."'";
return $this->_dbConn->fetchOne($query);
}

getting random testimonial in magento not working due to cache

I am trying to display random testimonials, but due to magento cache the random is not working, i have to flush the cache each time to see the testimonials change, my code
public function getTestimonialsLast(){
$collection = Mage::getModel('testimonial/testimonial')->getCollection();
$collection->getSelect()->order(new Zend_Db_Expr('RAND()'));
$collection->addFieldToFilter('status',1);
$collection->setPageSize(5);
return $collection;
}
how can i make it work , how can i make it so that whenever the page is refreshed the collection is randomized.
Any help is greatly appreciated.
Thank you in advance,
One possibility is in the view file:
You can stop Magento from caching the block by adding a false parameter when you implement the block.
<?php echo $this->getChildHtml('testimonials', false) ?>
Because of
Method Summary
string getChildHtml ([string $name = ‘’], [boolean $useCache = true], [ $sorted = true])
Or you could add the cache lifetime to your testimonial class:
public function getCacheLifetime() { return null; }
Are you caching the block within the modules public function __construct()
It would have information on 'cache_lifetime'
Removing the cache block would prevent it from being cached and perform a fresh call each time.

Magento - getting data from an order or invoice

I'm trying to write a Magento (CE 1.4) extension to export order data once an order has been paid for. I’ve set up an observer that hooks in to the sales_order_invoice_save_after event, and that is working properly - my function gets executed when an invoice is generated. But I’m having trouble getting information about the order, such as the shipping address, billing address, items ordered, order total, etc.
This is my attempt:
class Lightbulb_Blastramp_Model_Observer {
public function sendOrderToBlastramp(Varien_Event_Observer $observer) {
$invoice = $observer->getEvent()->getInvoice();
$order = $invoice->getOrder();
$shipping_address = $order->getShippingAddress();
$billing_address = $order->getBillingAddress();
$items = $invoice->getAllItems();
$total = $invoice->getGrandTotal();
return $this;
}
}
I tried doing a print_r on all those variables, and ended up getting a lot of data back. Could someone point me in the right direction of getting the shipping address of an order?
Thanks!
Many Magento objects are based on Varien_Object, which has a method called getData() to get just the usually interesting data of the object (excluding the tons of other, but mostly useless data).
With your code you could either go for all the data at once:
$shipping_address = $order->getShippingAddress();
var_dump($shipping_address->getData());
or directly for specific single properties like this:
$shipping_address = $order->getShippingAddress();
var_dump(
$shipping_address->getFirstname(),
$shipping_address->getLastname(),
$shipping_address->getCity()
);
To understand how this works, I'd recommend to make yourself more familiar with the Varien_Object and read a bit about PHPs magic methods, like __call(), __get() and __set().
Try print_r($shipping_address->toArray());

Magento createBlock method not working, displaying static block data

Ok so Ive created static blocks in my CMS area, and Im trying to output them inside of a custom homepage template Ive built.
Every document I can find says to output the block as follows
<?php echo $this->getLayout()->createBlock('cms/block')->setBlockId('my-block-identifier')->toHtml() ?>
That didnt work for me, so then I tried another way. --
<?php $block = Mage::getSingleton('core/layout')->createBlock('cms/block')->setBlockId('my-block-identifier');
echo $block->toHtml();
All the sites referencing this tell me to use the actual blocks identifier to get the block. So then I decide to manually lookup the block_id in my cms_block table and see if using the block_id number in place of the literal my-block-identifier name will work - and it did. So I am confused... Can anyone tell me how I can get the block by the actual identifier, or look up the blocks id by the identifier so that I can grab the block by block name?
Any help much appreciated.
Looking at the cms/block block source, those tutorials have mislead you, or you misinterpreted them.
#File: app/code/core/Mage/Cms/Block/Block.php
class Mage_Cms_Block_Block extends Mage_Core_Block_Abstract
{
protected function _toHtml()
{
if (!$this->_beforeToHtml()) {
return '';
}
$html = '';
if ($blockId = $this->getBlockId()) {
$block = Mage::getModel('cms/block')
->setStoreId(Mage::app()->getStore()->getId())
->load($blockId);
if (!$block->getIsActive()) {
$html = '';
} else {
$content = $block->getContent();
$processor = Mage::getModel('core/email_template_filter');
$html = $processor->filter($content);
}
}
return $html;
}
}
The block content is always loaded with ->load($blockId); -- load with one parameter always means loding by a database ID.
So, with no supported way of doing this built into the block, you'll need to look up the block ID.
$model = Mage::getModel('cms/block')->getCollection()
->addFieldToFilter('identifier','footer_links')
->getFirstItem();
var_dump($model->getBlockId());
In the admin, when you are editing the contents of the static block, you will see a field called Identifier second from the top. Copy the value of that field, and insert it into your code. So if your Block is called contact-info in the admin, then your code will look like:
<?php echo $this->getLayout()->createBlock('cms/block')->setBlockId('contact-info')->toHtml() ?>
The value in that Identifier textbox in the admin is also what will be saved into the cms_block table, as you're worked out.
HTH,
JD

Resources