Take the 2-minute tour ×
Magento Stack Exchange is a question and answer site for users of the Magento e-Commerce platform. It's 100% free, no registration required.

Any idea why Mage::app()->getStore() returns the store view with id 1 when inside the upgrade scripts independent on the store view I'm running the upgrade script in (even admin)?
I mean, I know where the code that does this is. In Mage_Core_Model_App::getStore() there is this:

    if (!Mage::isInstalled() || $this->getUpdateMode()) {
        return $this->_getDefaultStore();
    }

and _getDefaultStore looks like this:

   if (empty($this->_store)) {
        $this->_store = Mage::getModel('core/store')
            ->setId(self::DISTRO_STORE_ID)
            ->setCode(self::DISTRO_STORE_CODE);
    }
    return $this->_store;

$this->_store is always empty when reaching the method above.

I get the same result even if I add this at the top of the upgrade script:

Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID));

I'm curious about the business logic of having this 'feature'.

share|improve this question
    
I thought upgrade scripts are always running in frontend scope. Often I tell the upgrade scripts explicit to use the admin store for the following lines. –  bukart Jul 29 at 6:08
    
@bukart. I tried explicitly telling the upgrade script to run the admin store view, but I get the same result. See my last 3 lines in the question. –  Marius Jul 29 at 6:10
    
I tried to answer your question below –  bukart Jul 29 at 6:16

3 Answers 3

up vote 4 down vote accepted

NB: don't forget that the admin store scope isn't set until dispatching is taking place and a controller extending Mage_Adminhtml_Controller_Action executes (see the adminhtml_controller_action_predispatch_start event and related observer in Mage_Adminhtml_Controller_Action::preDispatch()).

I'm curious about the business logic of having this 'feature'.

You aren't the only one; that said, we may never know unless Moshe or Dima wants to discuss.

Setup scripts execute early in application initialization. The design of this is probably due so that, by the time the rest of the stack is executed, the necessary migrations and other work would be "done" - meaning that the system was ready to use right away even when a module was being installed or upgraded. I'm wondering if the original architects initially ever thought there would be a need for a more initialized system. I'll conjecture that, whereas much of the code assumes that there is a store instance available, the _getDefaultStore() logic ensures that there is a store instance.

Full scope settings are available in 1.4.0.0 and up via data setup scripts.

share|improve this answer

So the basic answer is that it actually gets into the 3rd if.....wait what :(

if (!isset($id) || ''===$id || $id === true) {
    $id = $this->_currentStore;
}

For me it returns true for Mage::isInstalled() and false for $this->getUpdateMode() which sounds wrong. But this only happens on the first hit of getStore.

So it appears that it sets up the store before the update mode has been set, then when it comes back in the set-up script it uses the default store call which using the following code:

$this->_store = Mage::getModel('core/store')
    ->setId(self::DISTRO_STORE_ID)
    ->setCode(self::DISTRO_STORE_CODE);

The value of self::DISTRO_STORE_ID is 1 I guess cause it needs something and was not setup to us the admin store :(

So I actually have a system that has not store with id 1 and update script appear to be working well. If we are adding tables/attributes it is fine and even when adding site specific cms block this is also working, but we do get all store id and specifically set them when saving store specific data.

share|improve this answer
    
I dug up the same thing. What I don't understand is "Magento why u no use admin store for upgrades?". It seams more reasonable. I'm afraid to think what happens if I delete the store with id 1. –  Marius Jul 29 at 7:56
    
No one would be crazy enough to delete the default store ;) –  David Manners Jul 29 at 7:58
    
Now that I know this, I won't be crazy, but the fact that it's possible...well...never trust a user. –  Marius Jul 29 at 8:01
    
One of our PM asked me if he could remove old stores last week. I think I replied with "What's the worst that could happen"....and even more odd in our current project setup we have no store with id 1 :( in the table core_store but setup scripts are working –  David Manners Jul 29 at 8:07
    
But we specifically set store ids when we need store specific data saved –  David Manners Jul 29 at 8:09

Ok, to use the admin store in your upgrade scripts just use

Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

Your approach Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID)); can't succeed, cause there's no really existing loadable storeview for admin

Often I use a pattern like this:

// remembering old current store
$currentStore = Mage::app()->getCurrentStore();

// switching to admin store
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);

// switching back to old current store
Mage::app()->setCurrentStore($currentStore->getStoreId());

Otherwise sometimes after an upgrade script was executed your visitors will be redirected to the admin page instead of the frontend sometimes.


Update:

I misinterpreted the question below, so here's a new try to explain ^^

The upgrade scripts are called from a method deeper in the core (Mage_Core_Model_Resource_Setup::_modifyResourceDb(...))

Here I tried to list the stack

  • Mage_Core_Model_App::run($params)

  • Mage_Core_Model_App::_initModules()

  • Mage_Core_Model_Resource_Setup::applyAllUpdates()

  • Mage_Core_Model_Resource_Setup::applyUpdates()

  • Mage_Core_Model_Resource_Setup::_upgradeResourceDb($oldVersion, $newVersion)

  • Mage_Core_Model_Resource_Setup::_modifyResourceDb($actionType, $fromVersion, $toVersion)

and now have a look at Mage_Core_model_App::run($params):

public function run($params)
{
    $options = isset($params['options']) ? $params['options'] : array();
    $this->baseInit($options);
    Mage::register('application_params', $params);

    if ($this->_cache->processRequest()) {
        $this->getResponse()->sendResponse();
    } else {
        $this->_initModules();
        $this->loadAreaPart(Mage_Core_Model_App_Area::AREA_GLOBAL, Mage_Core_Model_App_Area::PART_EVENTS);

        if ($this->_config->isLocalConfigLoaded()) {
            $scopeCode = isset($params['scope_code']) ? $params['scope_code'] : '';
            $scopeType = isset($params['scope_type']) ? $params['scope_type'] : 'store';
            $this->_initCurrentStore($scopeCode, $scopeType);
            $this->_initRequest();
            Mage_Core_Model_Resource_Setup::applyAllDataUpdates();
        }

        $this->getFrontController()->dispatch();
    }
    return $this;
}

the method _initModules() is called before the $scopeCode and $scopeType is determined.

Currently I cannot figure out where the assumed fallback is defined.

share|improve this answer
    
Oh, but there is a loadable store view for admin. take a look in the core_store table. There is a record with id 0. Also if you try this var_dump(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID‌​)) you will get a valid instance of the admin store. Also tried Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID); but I get the same result. But my question wasn't about how to set the admin store in upgrade scripts. I was asking why Mage::app()->getStore() returns the store with id 1 in upgrade scripts. –  Marius Jul 29 at 6:28
    
oh... right... there's an admin store in database, indeed. –  bukart Jul 29 at 7:22
1  
Hmm...I knew the stack but now that I've seen it in your answer it hit me. The updates should run somehow 'stateless'. But in order to run something you need a store. Hence a default value for the store. Now the only thing that does not make sense is: Why is this default store not 0 (admin) and is a store view that could easily get deleted from the admin UI? +1 for opening my eyes. If I don't get an other clear answer on this I will accept this. –  Marius Jul 29 at 7:41
    
mhh... good question... maybe after lunch I'll take a look ... interresting ^^ –  bukart Jul 29 at 7:53

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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