0

I am working on a mass action to 'add a category'. I have most of the peripheral things set up correctly. I added 'add a category' to the mass action dropdown and I am returning a full list of my categories in a new dropdown similar to the way the change Status mass action works. I now need to get an Action function working to append categoryids to products.

Heres my module code with the ProductController last

Renderer to use in my observer to ouput categories

 class Clr_Categorymassaction_Block_Catalog_Product_Grid_Render_Category extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
{
    public function render(Varien_Object $row)
    {
        $product = Mage::getModel('catalog/product')->load($row->getEntityId());
        $cats = $product->getCategoryIds();
        $allCats = '';
        foreach($cats as $key => $cat)
        {
            $_category = Mage::getModel('catalog/category')->load($cat);
            $allCats.= $_category->getName();
            if($key < count($cats)-1)
                $allCats.= ',<br />';
        }
        return $allCats;
    }

}

Building the category tree

class Clr_Categorymassaction_Model_System_Config_Source_Category
{
    public function toOptionArray($addEmpty = true)
    {
        $options = array();
        foreach ($this->load_tree() as $category) {
            $options[$category['value']] =  $category['label'];
        }

        return $options;
    }



    public function buildCategoriesMultiselectValues(Varien_Data_Tree_Node $node, $values, $level = 0)
    {
        $level++;

        $values[$node->getId()]['value'] =  $node->getId();
        $values[$node->getId()]['label'] = str_repeat("--", $level) . $node->getName();

        foreach ($node->getChildren() as $child)
        {
            $values = $this->buildCategoriesMultiselectValues($child, $values, $level);
        }

        return $values;
    }

    public function load_tree()
    {
        $store = Mage::app()->getFrontController()->getRequest()->getParam('store', 0);
        $parentId = $store ? Mage::app()->getStore($store)->getRootCategoryId() : 1;  // Current store root category

        $tree = Mage::getResourceSingleton('catalog/category_tree')->load();

        $root = $tree->getNodeById($parentId);

        if($root && $root->getId() == 1)
        {
            $root->setName(Mage::helper('catalog')->__('Root'));
        }

        $collection = Mage::getModel('catalog/category')->getCollection()
        ->setStoreId($store)
        ->addAttributeToSelect('name')
        ->addAttributeToSelect('is_active');

        $tree->addCollectionData($collection, true);

        return $this->buildCategoriesMultiselectValues($root, array());
    }
}

Config.xml

<config>
    <modules>
        <Clr_Categorymassaction>
            <version>1.0.0</version>
        </Clr_Categorymassaction>
    </modules>
    <global>
        <models>
            <Categorymassaction>
                <class>Clr_Categorymassaction_Model</class>
            </Categorymassaction>
        </models>
        <helpers>
            <Categorymassaction>
                <class>Clr_Categorymassaction_Helper</class>
            </Categorymassaction>
        </helpers>
        <blocks>
            <Categorymassaction>
                <class>Clr_Categorymassaction_Block</class>
            </Categorymassaction>
        </blocks>
    </global>
    <adminhtml>
        <events>
            <adminhtml_block_html_before><!--<core_block_abstract_prepare_layout_before>-->
                <observers>
                    <thisisauniquekey>
                        <type>singleton</type>
                        <class>Clr_Categorymassaction_Model_Observer</class>
                        <method>addCategoryMassAction</method>
                    </thisisauniquekey>
                </observers>
            </adminhtml_block_html_before><!--</core_block_abstract_prepare_layout_before>-->
        </events>
    </adminhtml>
    <admin>
        <routers>
            <adminhtml>
                <args>
                    <modules>
                        <Clr_Categorymassaction before="Mage_Adminhtml">Clr_Categorymassaction_Adminhtml</Clr_Categorymassaction>
                    </modules>
                </args>
            </adminhtml>
        </routers>
    </admin>
</config>

Just in case I need to use

class Clr_Categorymassaction_Helper_Data extends Mage_Core_Helper_Abstract
{

}

Observer

<?php

class Clr_Categorymassaction_Model_Observer {
    public function addCategoryMassAction(Varien_Event_Observer $observer)
    {
        $block = $observer ->getBlock();
        if ($block instanceof Mage_Adminhtml_Block_Catalog_Product_Grid) {
            $block->getMassactionBlock()->addItem('Clr_Categorymassaction', array(
                'label'     =>  Mage::helper('catalog')->__('Add to Category'),
                'url'       =>  $block->getUrl('*/*/massCategory', array('_current' => true)),
                'additional'=> array(
                    'visibility'    => array(
                        'name'          =>'Category',
                        'class'         =>'required-entry',
                        'label'         =>Mage::helper('catalog')->__('Categories'),
                        'type'          => 'select',
                        'values'        => Mage::getModel('Categorymassaction/system_config_source_category')->toOptionArray(),
                        'renderer'      => 'Categorymassaction/catalog_product_grid_render_category',

                        )
                    )
                ));
        };
    }


}

ProductController

class Clr_Categorymassaction_Adminhtml_Catalog_ProductController extends Mage_Adminhtml_Controller_Action
{
    public function massCategoryAction()
    {
        $category = Mage::getModel('catalog/category');
        $productIds = $this->getRequest()->getParam('product');
        $cat = $this->getRequest()->getParam('Category');
        if (!is_array($productIds)) {
            $this->_getSession()->addError($this->__('Please select product(s).'));
            $this->_redirect('*/*/index');
        }
        else {
            //convert $cat -> categoryid eg:
            //$this = $category['label']->getCategoryId();
            try {
                foreach($productIds as $product) {
                    // append categoryId to $productId
                    //$product->setCategoryIds($cat);
                    //$product->save();
                   // $cat->setPostedProducts($product);
                }
               //$cat->save();
                //Save product
                }
                catch (Exception $e){
                  $this->_getSession()->addError($e->getMessage());
                  $this->_redirect('*/*/index'); 
                }
            }

I know my controller is in a pitiful state, any direction for how I can get the productIds assigned to the $cat category would be a life saver. Thanks for digging in to the bottom.

0

Try this in your controller:

$productIds = $this->getRequest()->getParam('product');
if (!is_array($productIds)) {
    $this->_getSession()->addError($this->__('Please select product(s).'));
    $this->_redirect('*/*/index');
}

$catId = $this->getRequest()->getParam('Category');
$category = Mage::getModel('catalog/category')->load($catId);

if (!$category->getId()) {
    $this->_getSession()->addError($this->__('Category not found.'));
    $this->_redirect('*/*/index');
}

try {
    foreach($productIds as $productId) {
        $product = Mage::getModel('catalog/product')->load($productId);

        if (!$product->getId()) {
            continue;
        }

        $productCats = $product->getCategoryIds();
        $productCats = array_unique(array_merge($productCats, array($catId)));

        $product->setCategoryIds($productCats)->save();
    }
} catch (Exception $e){
    $this->_getSession()->addError($e->getMessage());
    $this->_redirect('*/*/index');
}
  • StackExchange to the rescue! The only thing I had to add was a redirect back to the catalog product page. $this->_redirect('adminhtml/catalog_product/index/', array()); Thanks Tyler – Chris May 11 '15 at 12:37
  • So I understand this entire controller except. if (!$product->getId()) { continue; }. What is this doing? – Chris May 11 '15 at 13:32
  • @Chris That's a sanity check that's making sure the product was found and loaded by that ID. If $product is set to an empty instance of the Mage_Catalog_Model_Product class, then $product->getId() will resolve as false. In that case, continue; just skips ahead to the next iteration of the foreach – Tyler V. May 13 '15 at 1:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.