5

Is it possible to set a Magento configuration option for the duration of a single script only?

I'm trying to programatically and recursively create orders in Magento. I want to enable the Flat Rate Shipping method and set the cost to 5.00, for example. Once the script has run, I want the value to be set via persistence as usual from the db.

I am using a basic function to determine which iteration we're on. If it's the first, set the shipping method. The script is called via AJAX.

...
try {
    if (isFirstIteration($_iteration)) {
        $_flatShipping = Mage::getStoreConfig('carriers/flatrate/active', $_storeId);
        if ($_flatShipping == 0) {
            Mage::getConfig()->setNode('carriers/flatrate/active', '1');
            Mage::getConfig()->setNode('carriers/flatrate/price', '5.00');
        }
    }
} catch(Exception $e) {
    $html .= '<div class="error">Error: ' . $e->getMessage() . '</div>';
}
...

That does not work; Magento throws the exception Please specify a shipping method on quote save.

I can, however, set the shipping method in the db. This does work:

...
try {
    if (isFirstIteration($_iteration)) {
        $_flatShipping = Mage::getStoreConfig('carriers/flatrate/active', $_storeId);
        if ($_flatShipping == 0) {
            $_mageConfig = new Mage_Core_Model_Config();
            $_mageConfig->saveConfig('carriers/flatrate/active', '1', 'default', 0);
            $_mageConfig->saveConfig('carriers/flatrate/price', '5.00', 'default', 0);
            Mage::getConfig()->reinit();
            Mage::app()->reinitStores();
        }
    }
} catch(Exception $e) {
    $html .= '<div class="error">Error: ' . $e->getMessage() . '</div>';
}
...

I'm guessing Magento's setNode doesn't work the way I think it does. Any info would be helpful, except bashing me for creating orders like this :) Thanks.

1
  • 2
    See fschmengler's answer for the solution.
    – benmarks
    Feb 10, 2015 at 14:51

2 Answers 2

5

The problem with setNode() is that it does not refresh the config cache in Mage_Core_Model_Store. This is not the Magento cache but a PHP array, populated at runtime on store initialization for store specific configuration and when the configuration value is read for global or website specific configuration.

So setNode() does not work for store specific values or values that have been read before.

But there is a method that sets the node as well as the cached value:

Mage::app()->getStore()
    ->setConfig('section/group/field', $value);
0
6

You are correct. setNode() uses full Xpath. You'll need to set store data using the absolute path:

stores/[code]/carriers/flatrate/active
5
  • Thx Ben. I assume [code] is store code? I've tried this: Mage::getConfig()->setNode('stores/english_uk/carriers/flatrate/active', '1'); but still no dice.
    – Jongosi
    Nov 28, 2013 at 10:40
  • I guess a second point to clarify is: is the setting immediately active? Wouldn't I need to refresh the node(s) after save?
    – Jongosi
    Nov 28, 2013 at 10:50
  • 1
    Should be active straightaway (you're working with the loaded DOM). What does the shipping block say?
    – benmarks
    Nov 30, 2013 at 0:20
  • The method has problems with cached values and you should't use them. See my answer for an alternative. Feb 10, 2015 at 11:05
  • NICE CATCH @fschmengler!
    – benmarks
    Feb 10, 2015 at 14:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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