업그레이드 스크립트를 실행할 때 현재 저장소는 1입니다


15

Mage::app()->getStore()스토어 스크립트와 독립적으로 업그레이드 스크립트 내부에서 업그레이드 스크립트를 실행할 때 (관리자조차도) id 1로 스토어 뷰를 반환하는 이유 는 무엇입니까?
나는 이것을하는 코드가 어디에 있는지 알고 있습니다. 에서는 Mage_Core_Model_App::getStore()이있다 :

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

_getDefaultStore모양이 맘에 :

   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 위의 방법에 도달하면 항상 비어 있습니다.

업그레이드 스크립트 맨 위에 이것을 추가해도 동일한 결과가 나타납니다.

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

이 '기능'을 갖는 비즈니스 논리가 궁금합니다.


업그레이드 스크립트가 항상 프런트 엔드 범위에서 실행되고 있다고 생각했습니다. 종종 다음 줄에 관리자 저장소를 사용하도록 업그레이드 스크립트를 명시 적으로 지시합니다.
bukart

@bukart. 관리자 스크립트보기를 실행하도록 업그레이드 스크립트에 명시 적으로 지시했지만 동일한 결과를 얻습니다. 질문의 마지막 3 줄을 참조하십시오.
Marius

아래에서 귀하의 질문에 답변을하려고했습니다
bukart

답변:


5

주의 : 디스패치가 발생하고 컨트롤러 확장이 Mage_Adminhtml_Controller_Action실행될 때까지 관리 저장소 범위가 설정되지 않았다는 것을 잊지 마십시오 (의 adminhtml_controller_action_predispatch_start이벤트 및 관련 관찰자 참조 Mage_Adminhtml_Controller_Action::preDispatch()).

이 '기능'을 갖는 비즈니스 논리가 궁금합니다.

당신은 유일한 사람이 아닙니다. 모쉐디마 가 논의하고 싶어 하지 않는 한 우리는 결코 알지 못할 것 입니다.

설치 스크립트는 응용 프로그램 초기화 초기에 실행됩니다. 이것의 설계는 아마도 나머지 스택이 실행될 때까지 필요한 마이그레이션 및 기타 작업이 "완료"될 수 있기 때문에 모듈이 설치되어 있어도 시스템을 즉시 사용할 수 있음을 의미합니다. 또는 업그레이드. 원래 건축가가 처음에 더 초기화 된 시스템이 필요하다고 생각하는지 궁금합니다. 코드의 대부분은 사용 가능한 상점 인스턴스가 있다고 가정 하지만 _getDefaultStore()논리는 상점 인스턴스가 있음을 보장한다고 추측 합니다.

전체 범위 설정은 1.4.0.0 이상에서 데이터 설정 스크립트를 통해 사용할 수 있습니다.


3

좋아, 업그레이드 스크립트에서 관리자 저장소를 사용하려면

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

당신의 접근 방식 Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID)); 이 성공할 수 없습니다. 관리자에게 실제로로드 가능한 storeview가 없습니다.

종종 다음과 같은 패턴을 사용합니다.

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

그렇지 않으면 업그레이드 스크립트가 실행 된 후 때때로 방문자가 프런트 엔드 대신 관리자 페이지로 리디렉션됩니다.


최신 정보:

아래 질문을 잘못 해석 했으므로 여기에 새로운 설명을 시도하십시오 ^^

업그레이드 스크립트는 코어의 더 깊은 메소드에서 호출됩니다 (Mage_Core_Model_Resource_Setup::_modifyResourceDb(...) )의

여기에 스택을 나열하려고했습니다.

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

이제 살펴보십시오 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;
}

이 메소드 _initModules()는 전에 호출 $scopeCode되고 $scopeType결정됩니다.

현재 가정 된 폴 백이 정의 된 위치를 알 수 없습니다.


아, 그러나 관리자를위한로드 가능한 상점보기가 있습니다. core_store테이블을 보세요 . id가있는 레코드가 0있습니다. 또한 이것을 시도하면 var_dump(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID))유효한 관리 저장소 인스턴스가 나타납니다. 또한 시도 Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);했지만 동일한 결과를 얻습니다. 그러나 내 질문은 업그레이드 스크립트에서 관리자 저장소를 설정하는 방법에 관한 것이 아닙니다. Mage::app()->getStore()업그레이드 스크립트에서 id가 1 인 저장소를 반환하는 이유를 묻고있었습니다 .
Marius

아 ... 맞아 ... 데이터베이스에 실제로 관리자 저장소가있다.
bukart

1
흠 ... 나는 스택을 알고 있었지만 지금은 당신의 대답에서 그것을 보았으므로 그것은 나를 때렸습니다. 업데이트는 어떻게 든 '상태 비 저장'으로 실행되어야합니다. 그러나 무언가를 운영하려면 상점이 필요합니다. 따라서 상점의 기본값입니다. 이해가되지 않는 유일한 이유는 다음과 같습니다. 왜이 기본 저장소가 0(관리자)가 아니고 관리 UI에서 쉽게 삭제할 수있는 저장소보기입니까? 눈을 뜨면 +1 이것에 대한 다른 명확한 대답을 얻지 못하면 나는 이것을 받아 들일 것입니다.
Marius

으음 ... 좋은 질문 ... 어쩌면 점심 식사 후 살펴볼 게 ... interresting ^^
bukart

1.9.3.6부터는 Mage::app()->getCurrentStore();정의되지 않은 것으로 보이며 호출 될 때 치명적인 오류가 발생합니다. 대신을 사용하여 ID를 얻었습니다 $currentStoreId = Mage::app()->getStore()->getId();.
Eric Seastrand

2

따라서 기본적인 대답은 실제로 세 번째 if ..... wait what :(

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

나에게 그것은 틀린 소리에 Mage::isInstalled()대해 true 와 false를 반환합니다 $this->getUpdateMode(). 그러나 이것은의 첫 번째 히트에서만 발생합니다 getStore.

따라서 업데이트 모드가 설정되기 전에 상점을 설정 한 것으로 보이며 설정 스크립트로 돌아 오면 다음 코드를 사용하는 기본 상점 호출을 사용합니다.

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

의 값 self::DISTRO_STORE_ID은 1입니다. 왜냐하면 뭔가 필요하고 관리자 저장소가 설정되지 않은 것 같습니다. (

그래서 실제로 id 1로 저장하지 않은 시스템이 있으며 업데이트 스크립트가 제대로 작동하는 것으로 보입니다. 우리가 테이블 / 속성을 추가하는 경우 괜찮으며 사이트 특정 cms 블록을 추가 할 때도 작동하지만 모든 매장 ID를 가져오고 매장 별 데이터를 저장할 때 구체적으로 설정합니다.


나는 같은 것을 파헤 쳤다. 내가 이해하지 못하는 것은 "Magento 왜 업그레이드에 관리자 저장소를 사용하지 않습니까?"입니다. 이음새가 더 합리적입니다. ID가 1 인 상점을 삭제하면 어떻게 될지 생각이 두렵습니다.
Marius

기본 저장소를 삭제하기에 충분히 미친 사람은 없습니다.)
David Manners

이제 이것을 알고 있으므로, 나는 미치게 될 것이지만 그것이 가능하다는 사실은 ... 잘 ... 사용자를 믿지 마십시오.
Marius

PM 중 한 명이 지난 주에 오래된 상점을 제거 할 수 있는지 물었습니다. 나는 "무엇이 일어날 수있는 최악의 일입니까?"라고 대답했다고 생각합니다 .... 현재 프로젝트 설정에서 더 이상한 점은 id가 1 인 상점이 없다는 것입니다. (테이블 core_store에는 설정 스크립트가 작동하지만
David Manners

1
상점 범위가 Mage_Core_Model_App :: DISTRO_STORE_CODE에 잠겨 있지 않은 데이터 업그레이드 (설치 아님) 스크립트에서 cms 블록 추가를 수행해야합니다. 일반적으로 설치 스크립트는 데이터 구조를 변경하고 저장소 범위를 잠그는 데 사용되는 반면 데이터 업그레이드는 데이터 내용을 변경하는 데 사용됩니다 (스크립트 중에 저장소 범위를 변경할 수 있음)
Alessandro Ronchi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.