Search code examples
phpmagentoadminmagento-1.5

"Right" Way to Perform Admin Tasks?


I'm trying to put together an admin module that can perform some custom sorting tasks and I've run into a question I can't seem to find an answer to. Basically, I added a section to the Admin config with a few buttons that scan recent orders and set some custom values on the order items that I can use later. To do this, I added a button to the system.xml that redirects to a controller. The controller performs the necessary task (or instantiates a model to do so) and then needs to redirect back to the admin page it came from. This is the part that has me confused. I can't seem to figure out the best way to pass the current URL from the admin section through to the controller so the controller knows where to redirect back to. Sure, I could hard code it, but I'd really rather not. Furthermore, is this even the right way to do it? If there's no layout for the controller and it's only purpose is to do stuff on button click, is there a better way to go about it?

Assuming this is the correct way to go about this, here are some chunks from my files for reference.

system.xml

Here's the section of system.xml that declares the button. Note that I'm using a custom frontend_model class because it was the only way I could get this to work (is there a better way?)

<fields>
    <calcmargin translate="label">
        <label>Calculate Margins</label>
        <comment>
            <![CDATA[Calculates the order margins]]>
        </comment>
        <frontend_type>button</frontend_type>
        <frontend_model>sorting/source_buttons_calcmargin</frontend_model>
        <sort_order>10</sort_order>
        <show_in_default>1</show_in_default>
        <show_in_website>1</show_in_website>
        <show_in_store>1</show_in_store>
    </calcmargin>
</fields>

config.xml

In config.xml, I declare my admin router (among other things)

<admin>
    <routers>
        <sorting>
            <use>admin</use>
            <args>
                <module>VPS_Sorting</module>
                <frontName>sorting</frontName>
            </args>
        </sorting>
    </routers>
</admin>

Button Source

Here's the _getElementHtml function from my source button class

public function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
{
    //save the current URL in the sorting/data singleton for future use
    Mage::getSingleton('sorting/data')->setSortingReturnUrl(Mage::helper('core/url')->getCurrentUrl());

    $this->setElement($element);

    $html = $this->getLayout()->createBlock('adminhtml/widget_button')
    ->setType('button')
    ->setClass('scalable')
    ->setLabel($this->buttonLabel)
    ->setOnClick("setLocation('$this->buttonUrl')")
    ->toHtml();

    return $html;
}

NOTE: $this->buttonUrl is set earlier using $this->getUrl('sorting/index/calcmargin')

In this case, I have a model called Data.php that I instantiate using getSingleton and set the return URL.

IndexController

public function calcmarginAction()
{
    $orderCollection = Mage::getModel('sales/order')->getCollection();

    foreach($orderCollection as $order)
    {
        //Do Stuff
        //...
    }

    echo "DONE...now return to " . Mage::getSingleton('sorting/data')->getSortingReturnUrl();
    //outputs: 'DONE...now return to '...so clearly the value wasn't saved
}

Unfortunately, when it gets over to the controller, that value is no longer there. So I guess I don't really understand how singletons work and how long they stick around...

I also tried saving the value in the core/session singleton, but that didn't work either.

So, if you're still with me, any thoughts on what I should do?

Thanks!


Solution

  • As you've worked out a singleton is only valid for the page request, to persist longer than that and you need sessions. However there is a simpler way with controllers, put this in place of your echo;

    $this->_redirectReferer();
    

    As an aside I wouldn't think the config section would be ideal for a button that performs an action. Perhaps the System > Tools menu instead...