Der aktuelle Speicher ist 1, wenn Upgrade-Skripts ausgeführt werden

15

Haben Sie eine Idee, warum Mage::app()->getStore()die Geschäftsansicht mit der ID 1 zurückgegeben wird, wenn sich in den Upgrade-Skripten unabhängig von der Geschäftsansicht, in der ich das Upgrade-Skript ausführe, (auch Administrator)?
Ich meine, ich weiß, wo der Code ist, der das tut. Darin Mage_Core_Model_App::getStore()ist folgendes:

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

und _getDefaultStoresieht so aus:

   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 ist bei Erreichen der obigen Methode immer leer.

Ich erhalte das gleiche Ergebnis, auch wenn ich dies oben im Upgrade-Skript hinzufüge:

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

Ich bin neugierig auf die Geschäftslogik, diese 'Funktion' zu haben.

Marius
quelle
Ich dachte, Upgrade-Skripte laufen immer im Frontend-Bereich. Oft sage ich den Upgrade-Skripten explizit, dass sie den Admin-Speicher für die folgenden Zeilen verwenden sollen.
Bukart
@bukart. Ich habe versucht, das Upgrade-Skript explizit anzuweisen, die Ansicht des Administratorspeichers auszuführen, erhalte jedoch das gleiche Ergebnis. Siehe meine letzten 3 Zeilen in der Frage.
Marius
Ich habe versucht, Ihre Frage unten zu beantworten
bukart

Antworten:

5

NB: Vergessen Sie nicht, dass der Gültigkeitsbereich des Administrationsspeichers erst festgelegt wird, wenn der Versand erfolgt und eine Controllererweiterung Mage_Adminhtml_Controller_Actionausgeführt wird (siehe adminhtml_controller_action_predispatch_startEreignis und zugehörigen Beobachter in Mage_Adminhtml_Controller_Action::preDispatch()).

Ich bin neugierig auf die Geschäftslogik, diese 'Funktion' zu haben.

Du bist nicht der einzige; Das heißt, wir werden es vielleicht nie erfahren, es sei denn, Moshe oder Dima wollen darüber diskutieren.

Setup-Skripte werden zu Beginn der Anwendungsinitialisierung ausgeführt. Das Design dafür ist wahrscheinlich darauf zurückzuführen, dass zum Zeitpunkt der Ausführung des restlichen Stacks die erforderlichen Migrationen und andere Arbeiten "erledigt" sind - was bedeutet, dass das System sofort einsatzbereit war, selbst wenn ein Modul installiert wurde oder aufgerüstet. Ich frage mich, ob die ursprünglichen Architekten anfangs gedacht haben, dass ein stärker initialisiertes System erforderlich ist. Ich nehme an, dass während ein Großteil des Codes davon ausgeht, dass eine Geschäftsinstanz verfügbar ist, die _getDefaultStore()Logik sicherstellt, dass eine Geschäftsinstanz vorhanden ist.

Die vollständigen Bereichseinstellungen sind in 1.4.0.0 und höher über Daten-Setup-Skripts verfügbar.

benmarks
quelle
3

Ok, um den Admin-Store in deinen Upgrade-Skripten zu verwenden, benutze einfach

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

Ihr Ansatz Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID)); kann nicht erfolgreich sein, da für den Administrator keine wirklich ladbare Speicheransicht vorhanden ist

Oft benutze ich ein Muster wie dieses:

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

Andernfalls werden Ihre Besucher nach dem Ausführen eines Upgrade-Skripts manchmal auf die Administrationsseite anstatt auf das Frontend umgeleitet.


Aktualisieren:

Ich habe die folgende Frage falsch interpretiert, daher hier ein neuer Versuch, ^^ zu erklären

Die Upgrade-Skripte werden von einer Methode aufgerufen, die sich tiefer in core ( Mage_Core_Model_Resource_Setup::_modifyResourceDb(...)) befindet.

Hier habe ich versucht, den Stack aufzulisten

  • 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)

und jetzt schauen Sie sich an 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;
}

Die Methode _initModules()wird vor dem aufgerufen $scopeCodeund $scopeTypebestimmt.

Derzeit kann ich nicht herausfinden, wo der angenommene Fallback definiert ist.

bukart
quelle
Oh, aber es gibt eine ladbare Store-Ansicht für den Administrator. schau mal in die core_storeTabelle. Es gibt einen Datensatz mit der ID 0. Auch wenn Sie dies versuchen, erhalten var_dump(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID))Sie eine gültige Instanz des Administrationsspeichers. Auch versucht, Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);aber ich bekomme das gleiche Ergebnis. Meine Frage bezog sich jedoch nicht darauf, wie der Administratorspeicher in Upgrade-Skripten eingerichtet werden soll. Ich habe gefragt, warum Mage::app()->getStore()der Shop mit der ID 1 in Upgrade-Skripten zurückgegeben wird.
Marius
oh ... richtig ... es gibt tatsächlich einen Admin-Speicher in der Datenbank.
Bukart
1
Hmm ... Ich kannte den Stapel, aber jetzt, wo ich ihn in deiner Antwort gesehen habe, traf es mich. Die Updates sollten irgendwie "zustandslos" laufen. Aber um etwas zu betreiben, braucht man einen Laden. Daher ein Standardwert für das Geschäft. Das einzige, was keinen Sinn ergibt, ist: Warum ist dieser Standardspeicher nicht 0(admin) und ist eine Speicheransicht, die leicht von der Benutzeroberfläche des Administrators gelöscht werden kann? +1 für das Öffnen meiner Augen. Wenn ich dazu keine andere klare Antwort bekomme, werde ich das akzeptieren.
Marius
mhh ... gute
frage
Ab 1.9.3.6 Mage::app()->getCurrentStore();scheint nicht definiert zu sein und führt beim Aufruf zu einem schwerwiegenden Fehler. Stattdessen habe ich die ID mit $currentStoreId = Mage::app()->getStore()->getId();.
Eric Seastrand
2

Die grundlegende Antwort ist also, dass es tatsächlich in die 3. geht, wenn ... warte was :(

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

Für mich ist es wahr Mage::isInstalled()und falsch, $this->getUpdateMode()was falsch klingt. Dies geschieht aber erst beim ersten Treffer von getStore.

Es sieht also so aus, als würde der Store eingerichtet, bevor der Update-Modus eingestellt wurde. Wenn er dann im Setup-Skript zurückkommt, wird der Standard-Store-Aufruf verwendet, der den folgenden Code verwendet:

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

Der Wert von self::DISTRO_STORE_IDist 1, ich denke, weil es etwas braucht und uns der Admin-Store nicht eingerichtet hat :(

Ich habe also tatsächlich ein System, das nicht mit ID 1 gespeichert wurde und das Aktualisierungsskript scheint gut zu funktionieren. Wenn wir Tabellen / Attribute hinzufügen, ist dies in Ordnung, und selbst beim Hinzufügen von standortspezifischen CMS-Blöcken funktioniert dies. Wir erhalten jedoch alle Geschäfts-IDs und legen sie beim Speichern von geschäftsspezifischen Daten fest.

David Manners
quelle
Ich habe dasselbe ausgegraben. Was ich nicht verstehe ist "Magento, warum benutzt du keinen Admin-Speicher für Upgrades?". Es scheint vernünftiger zu sein. Ich habe Angst zu überlegen, was passiert, wenn ich das Geschäft mit der ID 1 lösche.
Marius
Niemand wäre verrückt genug, um den Standardspeicher zu löschen;)
David Manners
Jetzt, wo ich das weiß, werde ich nicht verrückt sein, aber die Tatsache, dass es möglich ist ... na ja ... einem Benutzer niemals zu vertrauen.
Marius
Einer unserer PMs fragte mich, ob er letzte Woche alte Läden entfernen könne. Ich denke, ich antwortete mit "Was ist das Schlimmste, was passieren könnte?". Und noch seltsamer ist, dass wir in unserem aktuellen Projekt-Setup keinen Speicher mit der ID 1 :( in der Tabelle haben, core_storeaber Setup-Skripte funktionieren
David Manners
1
Das Hinzufügen eines cms-Blocks sollte in einem Datenaktualisierungsskript (nicht Installationsskript) erfolgen, in dem der Speicherbereich nicht an den Mage_Core_Model_App :: DISTRO_STORE_CODE gesperrt ist. Im Allgemeinen werden Installationsskripts verwendet, um die Datenstruktur zu ändern (und den Speicherbereich zu sperren), während die Datenaktualisierung verwendet wird, um den Dateninhalt zu ändern (und der Speicherbereich kann während des Skripts geändert werden)
Alessandro Ronchi