Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Okay, so you have two options. The quick and not so flexible SKU pattern way of matching products, or you could add a whole new product link relation to Magento. Obviously the last option costs more time but gives you the possibility to handle the relation from the admin and determine a display order within the batch.</p> <p><strong>Option 1: Matching on SKU (easy, quick, perhaps a bit dirty)</strong></p> <p>You could write a method that, let's say, takes the first 4 characters of your current product and then uses that to match the rest of the product database.</p> <p>Underneath is a mock-up version of how that code might look:</p> <pre><code>$match = substr($product-&gt;getSku(), 0, 4); $resource = Mage::getModel('core/resource'); $read = $resource-&gt;getConnection('core_read'); $select = $read-&gt;select() -&gt;from(array('e'=&gt;$resource-&gt;getTableName('catalog/product')), 'entity_id') -&gt;where("e.sku LIKE '" . $match . "%'"); $ids = $read-&gt;fetchAll($select); </code></pre> <p>This will retrieve the ID's of the matching products. Then these id's can be loaded in a product collection, like:</p> <pre><code>$_productCollection = Mage::getModel('catalog/product')-&gt;getCollection() -&gt;addAttributeToSelect('&lt;your_needed_product_attributes&gt;') -&gt;addAttributeToFilter('entity_id',array('in'=&gt; &lt;your_array_of_productids&gt;)); Mage::getSingleton('catalog/product_status')-&gt;addSaleableFilterToCollection($_productCollection); Mage::getSingleton('catalog/product_visibility')-&gt;addVisibleInCatalogFilterToCollection($_productCollection); $_productCollection-&gt;addStoreFilter()-&gt;load(); </code></pre> <p>Now you only have to loop through the collection and build your HTML.</p> <p><strong>Option 2: Adding a new product relation</strong></p> <p>Magento uses the table <code>catalog_product_link</code> to store all types of product relations. In <code>catalog_product_link_type</code> you add a new link type. This is needed to be able to insert new link type data in <code>catalog_product_link</code>. This new link type should be added via an upgrade script in your module.</p> <p>From this point on we need to make adjustments and additions to the Magento admin. Since this is a place for answers and not full blown module solutions I'm going to only mark the places which need our attention to add the new link type. Though, with the following information I don't think you will have too much trouble getting your new relation up and running.</p> <p>1) Adding a tab for the new type to the menu on the product edit admin page.</p> <p>Like in <code>Mage_Adminhtml_Block_Catalog_Product_Edit_Tabs</code> we need to create a new tab for our link type.</p> <pre><code> $this-&gt;addTab('combine', array( 'label' =&gt; Mage::helper('catalog')-&gt;__('Combine'), 'url' =&gt; $this-&gt;getUrl('*/*/combine', array('_current' =&gt; true)), 'class' =&gt; 'ajax', )); </code></pre> <p><code>*/*/combine</code> will route to the combine action of the <code>Mage_Adminhtml_Catalog_ProductController</code> controller. You probably want to use a different route to your own module, but I will stick to this one for this example.</p> <p>2) To handle the page request <code>*/*/combine/</code> we need make this action available in a controller. You will find your code references in <code>Mage_Adminhtml_Catalog_ProductController</code> for this.</p> <pre><code>/** * Get combine products grid and serializer block */ public function combineAction() { $this-&gt;_initProduct(); $this-&gt;loadLayout(); $this-&gt;getLayout()-&gt;getBlock('catalog.product.edit.tab.combine') -&gt;setProductsUpsell($this-&gt;getRequest()-&gt;getPost('products_combine', null)); $this-&gt;renderLayout(); } </code></pre> <p>We also need a action for handling later grid actions within this tab.</p> <pre><code>/** * Get upsell products grid */ public function combineGridAction() { $this-&gt;_initProduct(); $this-&gt;loadLayout(); $this-&gt;getLayout()-&gt;getBlock('catalog.product.edit.tab.combine') -&gt;setProductsRelated($this-&gt;getRequest()-&gt;getPost('products_combine', null)); $this-&gt;renderLayout(); } </code></pre> <p>Furthermore this controller also houses a <code>-&gt;_initProductSave()</code> method in which product relations are fetched from the request and added to the 'to-be-saved' product object.</p> <p>You will need to add the underneath snippet by either extending the controller or using an observer for this. Your call. A <code>catalog_product_before_save</code> observer is the best way to do this.</p> <pre><code> if (isset($links['combine']) &amp;&amp; !$product-&gt;getCombineReadonly()) { $product-&gt;setCombineLinkData(Mage::helper('adminhtml/js')-&gt;decodeGridSerializedInput($links['combine'])); } </code></pre> <p>In step 5 this data will again be picked up for further saving the new relations into the earlier mentioned <code>catalog_product_link</code> table.</p> <p>3) The layout we try to build in step 2 won't do a lot without the following XML handles.</p> <pre><code>&lt;adminhtml_catalog_product_combine&gt; &lt;block type="core/text_list" name="root"&gt; &lt;block type="&lt;your_own_custom_block_for_product_link_type&gt;" name="catalog.product.edit.tab.combine"/&gt; &lt;block type="adminhtml/widget_grid_serializer" name="upsell_grid_serializer"&gt; &lt;reference name="upsell_grid_serializer"&gt; &lt;action method="initSerializerBlock"&gt; &lt;grid_block_name&gt;catalog.product.edit.tab.combine&lt;/grid_block_name&gt; &lt;data_callback&gt;getSelectedCombineProducts&lt;/data_callback&gt; &lt;hidden_input_name&gt;links[combine]&lt;/hidden_input_name&gt; &lt;reload_param_name&gt;products_combine&lt;/reload_param_name&gt; &lt;/action&gt; &lt;action method="addColumnInputName"&gt; &lt;input_name&gt;position&lt;/input_name&gt; &lt;/action&gt; &lt;/reference&gt; &lt;/block&gt; &lt;/block&gt; &lt;/adminhtml_catalog_product_combine&gt; &lt;adminhtml_catalog_product_combinegrid&gt; &lt;block type="core/text_list" name="root"&gt; &lt;block type="&lt;your_own_custom_block_for_product_link_type&gt;" name="catalog.product.edit.tab.combine"/&gt; &lt;/block&gt; &lt;/adminhtml_catalog_product_combinegrid&gt; </code></pre> <p>4) With all that in place we need to create the block for our 'combine' type.</p> <p>This step is <code>fairly</code> easy. Take <code>Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Upsell</code> as a reference. We almost need an exact copy of this file. So place it in your module and rename all upsell to 'combine', or whatever name you are using for this relation. You need to place this block type at <code>&lt;your_own_custom_block_for_product_link_type&gt;</code> in step 3.</p> <p>5) Extending Mage_Catalog_Model_Product_Link</p> <p><code>Mage_Catalog_Model_Product_Link</code> is the file that holds all data regarding relation types. For instance which types are available and some logic for saving and loading the relation types.</p> <p>In your extend you need at least the following stuff:</p> <ul> <li>A constant to define your relation type <code>const LINK_TYPE_COMBINE = 6;</code></li> <li>A <code>useCombineLinks</code> method like <code>useUpsellLinks</code></li> <li><p>A extend of the <code>saveProductRelations</code> method with the underneath addition. Though this is probably also doable via an proper event observer.</p> <pre><code>$data = $product-&gt;getCombineLinkData(); if (!is_null($data)) { $this-&gt;_getResource()-&gt;saveProductLinks($product, $data, self::LINK_TYPE_COMBINE); } </code></pre></li> </ul> <p>This snippet eventually will be triggered after a product is being saved.</p> <p>6) Adding new relation logic to product model The last step to get the admin up and running is some logic that needs to be added to the product model (<code>Mage_Catalog_Model_Product</code>). You probably want to add these methods via an extend from your module on this model.</p> <p>You will need to add 4 methods, you can take the following as a reference, copy and rename them to your relation name.</p> <ul> <li><code>getUpSellProducts</code></li> <li><code>getUpSellProductIds</code></li> <li><code>getUpSellProductCollection</code></li> <li><code>getUpSellLinkCollection</code></li> </ul> <p>When you followed the above steps you should have a working admin for adding and handling this new product relation. Only thing left is having a block to use in the 'frontend' layout of your page. Again a good reference for this is <code>Mage_Catalog_Block_Product_List_Upsell</code>.</p> <p>I hope this gives you some good information to start with. Your choice which way to go. As said the second option is more work but gives your more flexibility through the admin and is a more robust solution.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload