Posting in the Magento forums has been disabled pending the implementation of a new and improved forum solution which should better serve the community.

For new questions please post at magento.stackexchange.com, the community-run support site for the Magento community. We will be providing updates on the new forum solution soon. For questions or concerns please email community@magento.com.

Magento Forum

Page 1 of 2
new product relationship: how to create another custom kind of related product
 
mauricioprado00
Member
 
Avatar
Total Posts:  63
Joined:  2009-03-11
Argentina
 

The following post explains how to add a module to create one aditional type of product relationship between products.
If you need to create multiple product relations and assign them to attribute sets you could use this extension:

http://www.magentocommerce.com/magento-connect/custom-product-relations.html

Which is fully compatible with any magento version.

here is the post:

Magento, adding a new kind of relation for the products.

I had the need to add a new kind of relation when some client needed to show a new block in the product’s page that shows the accesories of the product.
So this couldt be done with the normal ‘related product’ of magento, cause we already use that to show other related products that wasnt accesories of that product.
So my options was to do some extrange thing like add some weird attribute that links the related products or in the other hand do something nice done after dig some code of magento.
At the moment ive seen enought to do it, ive the time, and so here it is:
(this is just fresh code, so i dont know if some bug is going to hang on your or my magento)

Here is the steps, with 0 (zero) explaining, because its mosly search-copy-rename with my editor and after that just a comparation of code with the holly winmerge and after that just some couple of inheritation.
But i also spect to understand before i have this all in one place.

* create the file/path (from now on this means to create the whole path, every directory need to make the path) . app\code\local\Yourmodule\Adminhtml\Block\Catalog\Product\Edit\Tab\Related2.php
* open the file (Related2.php)
* paste this code into it

<?php
class Yourmodule_Adminhtml_Block_Catalog_Product_Edit_Tab_Related2 extends Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Related
{
    
public function __construct()
    {
        parent
::__construct();
        
$this->setId('related2_product_grid');
    
}

    
protected function _prepareCollection()
    
{
        $collection 
Mage::getModel('catalog/product_link')->useRelated2Links()
            ->
getProductCollection()
            ->
setProduct($this->_getProduct())
            ->
addAttributeToSelect('*');

        
$this->setCollection($collection);
        return 
parent::_prepareCollection();
    
}

    
public function getGridUrl()
    
{
        
return $this->getData('grid_url') ? $this->getData('grid_url') : $this->getUrl('*/*/related2', array('_current'=>true));
    
}

    
protected function _getSelectedProducts()
    
{
        $products 
$this->getRequest()->getPost('products'null);
        if (!
is_array($products)) {
            $products 
$this->_getProduct()->getRelated2ProductIds();
        
}
        
return $products;
    
}
}

* save the file (Related2.php)
* create the file/path (from now on this means to create the whole path, every directory need to make the path) . app\code\local\Yourmodule\Adminhtml\Block\Catalog\Product\Edit\Tabs.php
* open the file created
* paste this code into it

<?
class Yourmodule_Adminhtml_Block_Catalog_Product_Edit_Tabs extends Mage_Adminhtml_Block_Catalog_Product_Edit_Tabs
{
    
protected function _prepareLayout()
    {
        $ret 
parent::_prepareLayout();
        
        
$product $this->getProduct();

        if (!(
$setId $product->getAttributeSetId())) {
            $setId 
$this->getRequest()->getParam('set'null);
        
}

        
if ($setId{

            $this
->addTab('related2', array(
                
'label'     => Mage::helper('catalog')->__('Related2 Products'),
                
'url'       => $this->getUrl('*/*/related2', array('_current' => true)),
                
'class'     => 'ajax',
            ));
        
}
        
else {;}
        
return $ret;
    
}
}
?>

* save the file
*create the file/path app\code\local\Yourmodule\Adminhtml\controllers\Catalog\ProductController.php
* open the file created
* paste this code into it

 
Magento Community Magento Community
Magento Community
Magento Community
 
mauricioprado00
Member
 
Avatar
Total Posts:  63
Joined:  2009-03-11
Argentina
 

<?
require_once 'Mage/Adminhtml/controllers/Catalog/ProductController.php';

class 
Yourmodule_Adminhtml_Catalog_ProductController extends Mage_Adminhtml_Catalog_ProductController
{
//    public function __construct(){
//        die();
//    }
    
public function preDispatch()
    
{
        
//var_dump($this->getRequest());die();
        
parent::preDispatch();
        
$this->getRequest()->setRouteName('adminhtml');
      
//$this->setRoute('admin');
      //$this->getRequest()->setRouteName('admin');
      // here check also for $this->getRequest->getActionName()
      // if this is your own action, make sure to do setRouteName('test') 
      // in order to use your own layout
    

    
    
/**
     * Get specified tab grid
     */
    
public function gridOnlyAction()
    
{
        $this
->_initProduct();
        
$this->loadLayout();
        
$module $this->getRequest()->getParam('gridOnlyModule');// this is a little tweak i find out
        
$module $module?$module:'adminhtml'//this is passed in an ajax request (see related2Action in line 36)
        
$this->getResponse()->setBody(
            
$this->getLayout()->createBlock($module.'/catalog_product_edit_tab_' $this->getRequest()->getParam('gridOnlyBlock'))
                ->
toHtml()
        );
    
}

    
public function related2Action()
    
{
        
        $this
->_initProduct();

        
$gridBlock $this->getLayout()->createBlock('yourmodule_adminhtml/catalog_product_edit_tab_related2')
            ->
setGridUrl($this->getUrl('*/*/gridOnly', array('_current' => true'gridOnlyBlock' => 'related2''gridOnlyModule' => 'yourmodule_adminhtml')))
        ;
        
$serializerBlock $this->_createSerializerBlock('links[related2]'$gridBlockMage::registry('product')->getRelated2Products());

        
$this->_outputBlocks($gridBlock$serializerBlock);
    
}
    
protected function _initProduct($block=null){
        
static $product null;
        if(
$block===false){
            $product 
null;
            return;
        
}
        
if(!$product){
            $r 
parent::_initProduct();
            if(
$block===true)
                
$product $r;
            return(
$r);
        
}
        else{
            
return($product);
        
}
    }
    
protected function _initProductSave(){
        $product 
$this->_initProduct(true);
        
$links $this->getRequest()->getPost('links');
        if (isset(
$links['related2'])) {
            $product
->setRelated2LinkData($this->_decodeInput($links['related2']));
        
}
        parent
::_initProductSave();
        
$this->_initProduct(false);
        return(
$product);
    
}
}
?>

* save the file
* create the file/path app\code\local\Yourmodule\Adminhtml\etc\config.xml
* open the file created
* paste this code into it

<?xml version="1.0"?>
<config>
    <
config>
        <
modules>
            <
Yourmodule_Adminhtml>
                <
version>0.1.0</version>
            </
Yourmodule_Adminhtml>
        </
modules>
    </
config>
    <global>
        <
routers>
            <
adminhtml>
                <
rewrite>
                    <
catalog_product>
                        <
to>yourmodule/catalog_product</to>
                        <
override_actions>true</override_actions>
                        <
nueva><to>yourmodule/catalog_product/nueva</to></nueva>
                    </
catalog_product>
                </
rewrite>
            </
adminhtml>
        </
routers>
    <!--  
this is actually the same that the abobe code (the routers one), you ull find it made it in diferents ways and ill be confusing not to knowbasically boths redirects the url to a diferent location (not the http redirecti think its with whe mod_rewrite i dont knowi dont dig in things i dont need)
        <
rewrite>
            <
yourmodule_adminhtml_catalog_product>
                <
from><![CDATA[#^/admin/catalog_product/#]]></from>
                
<to>/yourmodule/catalog_product/</to>
            </
yourmodule_adminhtml_catalog_product>
        </
rewrite>
    -->
        <
blocks>
            <
adminhtml>
                <
rewrite>
                    <
catalog_product_edit_tabs>Yourmodule_Adminhtml_Block_Catalog_Product_Edit_Tabs</catalog_product_edit_tabs>
                </
rewrite>
            </
adminhtml>
            <
yourmodule_adminhtml>
                <class>
Yourmodule_Adminhtml_Block</class>
            </
yourmodule_adminhtml>
        </
blocks>
    </global>
    <
admin><!-- this is where the admin/catalog_product is redirected -->
        <
routers>
            <
yourmodule_adminhtml>
                <!-- 
should be set to "admin" when overloading admin stuff (?) -->
                <use>
admin</use>
                <
args>
                    <
module>Yourmodule_Adminhtml</module>
                    <!-- 
This is used when "catching" the rewrite above -->
                    <
frontName>yourmodule</frontName><!-- this is the name we reference on the -->
                </
args>
            </
yourmodule_adminhtml>
        </
routers>
    </
admin>
</
config>

save the file
create the file/path app\code\local\Yourmodule\Catalog\Model\Product\Link.php
open the file created
paste this code into it

<?
class Yourmodule_Catalog_Model_Product_Link extends Mage_Catalog_Model_Product_Link
{
    
const LINK_TYPE_RELATED2   6;

    public function 
useRelated2Links()
    
{
        $this
->setLinkTypeId(self::LINK_TYPE_RELATED2);
        return 
$this;
    
}
    
    
public function saveProductRelations($product)
    
{
        $data 
$product->getRelated2LinkData();
        if (!
is_null($data)) {
            $this
->_getResource()->saveProductLinks($product$dataself::LINK_TYPE_RELATED2);
        
}
        
return(parent::saveProductRelations($product));
    
}


?>

save the file
create the file/path app\local\Yourmodule\Catalog\Model\Product.php
open the file created
paste this code into it

 
Magento Community Magento Community
Magento Community
Magento Community
 
mauricioprado00
Member
 
Avatar
Total Posts:  63
Joined:  2009-03-11
Argentina
 

<?
class Yourmodule_Catalog_Model_Product extends Mage_Catalog_Model_Product
{
    
    
/**
     * Retrieve array of related2 roducts
     *
     * @return array
     */
    
public function getRelated2Products()
    
{
        
if (!$this->hasRelated2Products()) {
            $products 
= array();
            
$collection $this->getRelated2ProductCollection();
            foreach (
$collection as $product{
                $products[] 
$product;
            
}
            $this
->setRelated2Products($products);
        
}
        
return $this->getData('related2_products');
    
}
    
    
/**
     * Retrieve related products identifiers
     *
     * @return array
     */
    
public function getRelated2ProductIds()
    
{
        
if (!$this->hasRelated2ProductIds()) {
            $ids 
= array();
            foreach (
$this->getRelated2Products() as $product{
                $ids[] 
$product->getId();
            
}
            $this
->setRelated2ProductIds($ids);
        
}
        
return $this->getData('related2_product_ids');
    
}

    
/**
     * Retrieve collection related product
     */
    
public function getRelated2ProductCollection()
    
{
        $collection 
$this->getLinkInstance()->useRelated2Links()
            ->
getProductCollection()
            ->
setIsStrongMode();
        
$collection->setProduct($this);
        return 
$collection;
    
}

    
/**
     * Retrieve collection related2 link
     */
    
public function getRelated2LinkCollection()
    
{
        $collection 
$this->getLinkInstance()->useRelated2Links()
            ->
getLinkCollection();
        
$collection->setProduct($this);
        
$collection->addLinkTypeIdFilter();
        
$collection->addProductIdFilter();
        
$collection->joinAttributes();
        return 
$collection;
    
}
    
    
public function duplicate()
    
{
        $newProduct 
parent::duplicate();
        
        
/* Prepare Related2*/
        
$data = array();
        
$this->getLinkInstance()->useRelated2Links();
        
$attributes = array();
        foreach (
$this->getLinkInstance()->getAttributes() as $_attribute{
            
if (isset($_attribute['code'])) {
                $attributes[]
=$_attribute['code'];
            
}
        }
        
foreach ($this->getRelated2LinkCollection() as $_link{
            $data[$_link
->getLinkedProductId()$_link->toArray($attributes);
        
}
        $newProduct
->setRelated2LinkData($data);
        
        return(
$newProduct);
    
}

}
?>
* save the file
* create the file/path app\code\local\Catalog\etc\config.xml
* open the file created
* paste this code into it
<?xml version="1.0"?>
<config>
    <
config>
        <
modules>
            <
Yourmodule_Catalog>
                <
version>0.1.0</version>
            </
Yourmodule_Catalog>
        </
modules>
    </
config>
    <global>
        <
models>
            <
catalog>
                <
rewrite>
                    <
product_link>Yourmodule_Catalog_Model_Product_Link</product_link>
                    <
product>Yourmodule_Catalog_Model_Product</product>
                </
rewrite>
            </
catalog>
        </
models>
    </global>
</
config>
* save the file
* create the file/path app\etc\Yourmodule_All.xml
* open the file created
* paste this code into it
<?xml version="1.0"?>
<config>
    <
modules>
        <
Yourmodule_Adminhtml>
            <
active>true</active>
            <
codePool>local</codePool>
        </
Yourmodule_Adminhtml>
    </
modules>
</
config>

* save the file
* open the phpmyadmin or mysqlquery, connect, login, select the magento database and execute this query:

insert into mgt_catalog_product_link_type(link_type_id,codevalues(6,'accesory');

now you got a lot of code where you can dive, look at the bright side: you didnt have to recopile all around just searching in the google.

 
Magento Community Magento Community
Magento Community
Magento Community
 
mauricioprado00
Member
 
Avatar
Total Posts:  63
Joined:  2009-03-11
Argentina
 

this works perfectly on a windows, although could be some case-insensitive bugs that dont care in windows.
i will test it soon on a linux and i will update this thread.
(already tested on linux)

This post also shows how to overload the ProductController, i got to tanks “shoo” cause his post helps me, and was the more tricky part about to achieve te objetive. you can watch his post at , its very didactic.

http://www.magentocommerce.com/boards/viewthread/15914/

 
Magento Community Magento Community
Magento Community
Magento Community
 
mauricioprado00
Member
 
Avatar
Total Posts:  63
Joined:  2009-03-11
Argentina
 

Hi everyone, i create a module working almost as plugin for magento 1.4.1.0 at least.
1) decompress into magento instalation (it wont overwrite anything, it has a folderunder app/code/local and a file into app/etc/modules)
2) run this sql:
insert into catalog_product_link_type(link_type_id,code) values(7,’accesories’);

you are all set, now you can relate 2 products the same way that in related product, and in template files its available the method getAccesoriesProducts.

If you create your own module that rewrites the catalog_model_product, then you yould extend from this module class or copy it at least.

File Attachments
useless_newproductrelation.zip  (File Size: 13KB - Downloads: 353)
 
Magento Community Magento Community
Magento Community
Magento Community
 
thangnduy
Jr. Member
 
Total Posts:  1
Joined:  2010-11-01
 

Thanks mauricioprado00, you are just a genius, thanks and thanks again for all your shared experience

 
Magento Community Magento Community
Magento Community
Magento Community
 
bianca.mihai
Jr. Member
 
Total Posts:  2
Joined:  2010-10-15
 

Hi, I downloaded and installed your plugin on magento 1.5.1 but no changes in the admin. Do you know if this plugin is working on 1.5.1 or do you have a recent version? Thank you!

 
Magento Community Magento Community
Magento Community
Magento Community
 
mauricioprado00
Member
 
Avatar
Total Posts:  63
Joined:  2009-03-11
Argentina
 
bianca.mihai - 01 August 2011 12:30 AM

Hi, I downloaded and installed your plugin on magento 1.5.1 but no changes in the admin. Do you know if this plugin is working on 1.5.1 or do you have a recent version? Thank you!

Sorry, I did this back then when magento version was 1.4.1.0. I haven’t updated it because I do not need nor do I have the time yet, if i do i’ll re-post it.

 
Magento Community Magento Community
Magento Community
Magento Community
 
jfvfr
Jr. Member
 
Total Posts:  2
Joined:  2012-05-07
 

Hi mauricioprado00,

Thanks so much for this tuto and files… Looks totaly great and is this excatly the answer of my problem.
But I’m new on Magento and not yet realy experiment developper… I hope you could have few time to give me some help / advice ?

I used your file and place it under my magento Folder (Magento 1.7)… all look good under Admin and DB.
I have the Accesories tab under the product admin and I can totaly add product on this new relationship.

My problem is how to create Frontend block in the View product page to recover theses relationshop informations.
(clearly, how to show it on the frontend product page)

Sorry for this newbies question.

Hope you can help me with some advice or files exemples

Thanks

 
Magento Community Magento Community
Magento Community
Magento Community
 
mauricioprado00
Member
 
Avatar
Total Posts:  63
Joined:  2009-03-11
Argentina
 
jfvfr - 26 September 2012 09:01 PM

Hi mauricioprado00,

Thanks so much for this tuto and files… Looks totaly great and is this excatly the answer of my problem.
But I’m new on Magento and not yet realy experiment developper… I hope you could have few time to give me some help / advice ?

I used your file and place it under my magento Folder (Magento 1.7)… all look good under Admin and DB.
I have the Accesories tab under the product admin and I can totaly add product on this new relationship.

My problem is how to create Frontend block in the View product page to recover theses relationshop informations.
(clearly, how to show it on the frontend product page)

Sorry for this newbies question.

Hope you can help me with some advice or files exemples

Thanks

Hi jfvfr, of course I can help you, is great to hear that this files works on magento 1.7. You dont really have to create a new block, since the new product model has additional methods to retrieve this new kind of relatinships (getRelated2Products, getRelated2ProductIds, getRelated2ProductCollection, getRelated2LinkCollection)
So my first guess is that you could use getRelated2Products to retrieve and cache the products of a product instance. Anyway, you will want to check what the current related block is doing right now:
http://svn.magentocommerce.com/source/branches/1.7/app/design/frontend/base/default/template/catalog/product/list/related.phtml

that is the template that call to getItems, and here is the method that fill those items:
http://svn.magentocommerce.com/source/branches/1.7/app/code/core/Mage/Catalog/Block/Product/List/Related.php

as you can see in the _prepareData method, they use the getRelatedProductCollection to get the collections of related products (beside adding a couple of interesting filters, like visible in catalog, prices, etc)
You would have to do something more or less of what they do in that _prepareData, but instead you would call to getRelated2ProductCollection of course.

well I hope I can help, and thanks for letting me know that this still works on current magento versions, I may create an auto installing module for this.

best regards

 
Magento Community Magento Community
Magento Community
Magento Community
 
jfvfr
Jr. Member
 
Total Posts:  2
Joined:  2012-05-07
 

Hi mauricioprado00,

Thanks for your help and good advices. I totaly works now… You Rock !

Here are step I follow with your recommendation :
I made a copy of Related.phtml Template and the Related.php Class. In the class I made the change to call the correct “Get...ProductCollection”
I remaned thoses file as accesories.phtml and accesories.php.
I copy the accesories.php inside your module folder under Block/Product/List
I copy the accesories.phtml in my frontend under template/catalog/product/list

I add a new block under catalog.xml
<block type="useless_newproductrelation/product_list_accesories" name="catalog.product.accesories" as="accesories" template="catalog/product/list/accesories.phtml"/>

and I call this block in the view.phtml with a <?php echo $this->getChildHtml('accesories')?>

It’s clearly a top great module.

Many Thanks
Cheers

 
Magento Community Magento Community
Magento Community
Magento Community
 
mauricioprado00
Member
 
Avatar
Total Posts:  63
Joined:  2009-03-11
Argentina
 
jfvfr - 28 September 2012 01:18 AM

Hi mauricioprado00,

Thanks for your help and good advices. I totaly works now… You Rock !

Here are step I follow with your recommendation :
I made a copy of Related.phtml Template and the Related.php Class. In the class I made the change to call the correct “Get...ProductCollection”
I remaned thoses file as accesories.phtml and accesories.php.
I copy the accesories.php inside your module folder under Block/Product/List
I copy the accesories.phtml in my frontend under template/catalog/product/list

I add a new block under catalog.xml
<block type="useless_newproductrelation/product_list_accesories" name="catalog.product.accesories" as="accesories" template="catalog/product/list/accesories.phtml"/>

and I call this block in the view.phtml with a <?php echo $this->getChildHtml('accesories')?>

It’s clearly a top great module.

Many Thanks
Cheers

Great Job to get That working!

cheers

 
Magento Community Magento Community
Magento Community
Magento Community
 
ReachMiami
Jr. Member
 
Total Posts:  2
Joined:  2009-04-26
Miami, Fl
 

Hi Maurico,
I think this module is great. I’m using Magento 1.7 and it works perfect!
I have a question though. How would I be able to replicate the effect of this module to designate multiple types of related products. For example, out of the box, your module works great for any Accessories I may want to relate the products in my store to, but what if I need to relate my products to another type of relationship called Learning or Downloads? How would I have to modify your module in order for it to allow me to create multiple types of relationships? I sure hope you can help me and again, great work on this module!!

FM

 
Magento Community Magento Community
Magento Community
Magento Community
 
mikecallow
Member
 
Total Posts:  31
Joined:  2011-02-24
Preston, Lancs
 

First of all, thanks for posting this Mauricio - it’s much appreciated and is a fantastic solution.

I ran into an issue when following what jfvfr had done - after making the changes to Accessories.php class, nothing was being echoed on the frontend. To solve this, I had to change the XML node in catalog.xml to the following:

<block type="catalog/product_list_accesories" name="catalog.product.accesories" as="accesories" template="catalog/product/list/accesories.phtml"/>

Thanks again for this - it’s great!
Mike

 
Magento Community Magento Community
Magento Community
Magento Community
 
mikecallow
Member
 
Total Posts:  31
Joined:  2011-02-24
Preston, Lancs
 

Also, one problem I have run into, is that first of all, the extra related products save just fine. However, if you then edit the product’s other attributes, such as price/pictures and save it, the extra related products are then lost.

To get around this I opened Observer.php and changed the line:

if (!isset($links['accesories']))  {

to:

if (!empty($links['accesories']))  {

and this seems to have fixed this problem.

 
Magento Community Magento Community
Magento Community
Magento Community
 
ManojG
Jr. Member
 
Total Posts:  2
Joined:  2011-03-10
 

Hai jfvfr,

I am very much impressed with this module. But the same is fulfilled by you, as you done with front end(retrieve the selected products). I tried follow your instruction to have display of the products in front end. But i failed to make it possible. At the end i received the error “ Fatal error: Call to a member function addAttributeToSelect() on a non-object in /var/www/REDTAG/magento/app/code/local/Useless/NewProductRelation/Block/Product/List/Accesories.php on line 52 “ . In the Accesories.php i changed the function to $this->_itemCollection = $product->getRelated2Products() under the function _preparedata. Could you please share your Accesories.php file or guide me to make the products displayed in front end.

Thanks in Advance!.

Thanks,
Manoj

 
Magento Community Magento Community
Magento Community
Magento Community
Magento Community
Magento Community
Back to top
Page 1 of 2