L'archivio corrente è 1 quando si eseguono script di aggiornamento


15

Qualche idea sul perché Mage::app()->getStore()ritorni la vista del negozio con ID 1 quando all'interno degli script di aggiornamento indipendente dalla vista del negozio sto eseguendo lo script di aggiornamento in (anche admin)?
Voglio dire, so dove si trova il codice. In Mage_Core_Model_App::getStore()c'è questa:

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

e si _getDefaultStorepresenta così:

   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 è sempre vuoto quando si raggiunge il metodo sopra.

Ottengo lo stesso risultato anche se lo aggiungo all'inizio dello script di aggiornamento:

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

Sono curioso della logica di business di avere questa "caratteristica".


Ho pensato che gli script di aggiornamento siano sempre in esecuzione nell'ambito di frontend. Spesso dico esplicitamente agli script di aggiornamento di utilizzare l'archivio admin per le seguenti righe.
Bukart,

@bukart. Ho provato a dire esplicitamente allo script di aggiornamento di eseguire la vista dell'amministratore, ma ottengo lo stesso risultato. Vedi le mie ultime 3 righe nella domanda.
Marius

Ho cercato di rispondere alla tua domanda di seguito
Bukart,

Risposte:


5

NB: non dimenticare che l'ambito dell'amministratore del negozio non è impostato fino a quando non viene effettuato il dispacciamento e Mage_Adminhtml_Controller_Actionviene eseguita l' estensione del controller (vedere l' adminhtml_controller_action_predispatch_startevento e l'osservatore correlato in Mage_Adminhtml_Controller_Action::preDispatch()).

Sono curioso della logica di business di avere questa "caratteristica".

Non sei l'unico; detto ciò, potremmo non saperlo mai a meno che Moshe o Dima non vogliano discutere.

Gli script di installazione vengono eseguiti all'inizio dell'inizializzazione dell'applicazione. La progettazione di questo è probabilmente dovuta in modo che, al momento dell'esecuzione del resto dello stack, le migrazioni e gli altri lavori necessari fossero "eseguiti", il che significa che il sistema era pronto per l'uso immediatamente anche durante l'installazione di un modulo o aggiornato. Mi chiedo se inizialmente gli architetti abbiano mai pensato che sarebbe stato necessario un sistema più inizializzato. Concluderò che, mentre gran parte del codice presuppone che sia disponibile un'istanza del negozio, la _getDefaultStore()logica assicura che ci sia un'istanza del negozio.

Le impostazioni complete dell'ambito sono disponibili in 1.4.0.0 e versioni successive tramite script di configurazione dei dati.


3

Ok, per usare l'archivio di amministrazione negli script di aggiornamento basta usare

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

Il tuo approccio Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID)); non può avere successo, perché non esiste alcuna storeview caricabile realmente esistente per admin

Spesso uso un modello come questo:

// 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());

Altrimenti a volte dopo l'esecuzione di uno script di aggiornamento i visitatori verranno reindirizzati alla pagina di amministrazione anziché a volte al frontend.


Aggiornare:

Ho frainteso la seguente domanda, quindi ecco un nuovo tentativo di spiegare ^^

Gli script di aggiornamento sono chiamati da un metodo più profondo nel core ( Mage_Core_Model_Resource_Setup::_modifyResourceDb(...))

Qui ho provato ad elencare lo 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)

e ora dai un'occhiata a 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;
}

il metodo _initModules()viene chiamato prima di $scopeCodee $scopeTypeviene determinato.

Attualmente non riesco a capire dove sia definito il fallback ipotizzato.


Oh, ma c'è una vista dello store caricabile per admin. dai un'occhiata al core_storetavolo. C'è un record con ID 0. Inoltre, se provi questo var_dump(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID)), otterrai un'istanza valida dell'Admin Store. Anche provato Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);ma ottengo lo stesso risultato. Ma la mia domanda non era su come impostare l'archivio admin negli script di aggiornamento. Stavo chiedendo perché Mage::app()->getStore()restituisce il negozio con ID 1 negli script di aggiornamento.
Marius

oh ... giusto ... c'è un negozio di amministrazione nel database, anzi.
Bukart,

1
Hmm ... Conoscevo lo stack ma ora che l'ho visto nella tua risposta mi ha colpito. Gli aggiornamenti dovrebbero funzionare in qualche modo "senza stato". Ma per eseguire qualcosa hai bisogno di un negozio. Da qui un valore predefinito per il negozio. Ora l'unica cosa che non ha senso è: perché questo archivio predefinito non è 0(admin) ed è una vista dello store che potrebbe essere facilmente eliminata dall'interfaccia utente dell'amministratore? +1 per aver aperto gli occhi. Se non ricevo un'altra risposta chiara su questo accetterò questo.
Marius

mhh ... bella domanda ... forse dopo pranzo darò un'occhiata ... interrompendo ^^
bukart

A partire dal 1.9.3.6, Mage::app()->getCurrentStore();non sembra essere definito e dà un errore fatale quando chiamato. Invece, ho ottenuto l'ID utilizzando $currentStoreId = Mage::app()->getStore()->getId();.
Eric Seastrand,

2

Quindi la risposta di base è che effettivamente entra nel 3 ° se ..... aspetta cosa :(

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

Per me ritorna vero per Mage::isInstalled()e falso per il $this->getUpdateMode()quale suona male. Ma questo succede solo al primo colpo di getStore.

Quindi sembra che imposta l'archivio prima che sia stata impostata la modalità di aggiornamento, quindi quando torna nello script di installazione utilizza la chiamata di archivio predefinita che utilizza il seguente codice:

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

Il valore di self::DISTRO_STORE_IDè 1 immagino che abbia bisogno di qualcosa e non ci sia stato configurato nell'archivio di amministrazione :(

Quindi in realtà ho un sistema che non ha archiviato con ID 1 e lo script di aggiornamento sembra funzionare bene. Se stiamo aggiungendo tabelle / attributi va bene e anche quando si aggiunge un blocco cms specifico del sito funziona anche questo, ma otteniamo tutti gli ID negozio e li impostiamo specificamente quando salviamo i dati specifici del negozio.


Ho scavato la stessa cosa. Quello che non capisco è "Magento perché non usi admin store per gli aggiornamenti?". Sembra più ragionevole. Ho paura di pensare a cosa succede se cancello il negozio con ID 1.
Marius

Nessuno sarebbe abbastanza pazzo da eliminare l'archivio predefinito;)
David Manners,

Ora che lo so, non sarò pazzo, ma il fatto che sia possibile ... beh ... non fidarmi mai di un utente.
Marius

Uno dei nostri PM mi ha chiesto se poteva rimuovere i vecchi negozi la scorsa settimana. Penso di aver risposto con "Qual è il peggio che potrebbe accadere" .... e ancor più strano nella nostra attuale configurazione del progetto non abbiamo alcun archivio con ID 1 :( nella tabella core_storema gli script di installazione funzionano
David Manners,

1
l'aggiunta di un blocco cms deve essere eseguita in uno script di aggiornamento dei dati (non di installazione) in cui l'ambito del negozio non è bloccato su Mage_Core_Model_App :: DISTRO_STORE_CODE; più in generale, gli script di installazione vengono utilizzati per modificare la struttura dei dati (e l'ambito del negozio è bloccato) mentre l'aggiornamento dei dati viene utilizzato per modificare il contenuto dei dati (e l'ambito del negozio può essere modificato durante lo script)
Alessandro Ronchi,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.