अपग्रेड स्क्रिप्ट में प्रोग्राम व्यू स्टोर को डिलीट करें


12

मैं एक स्टोर व्यू को प्रोग्रामेटिक रूप से डिलीट करना चाहता हूं । देखकर Mage_Adminhtml_System_StoreController::deleteStorePostAction(), यह बहुत आसान है (छोटा कोड छोटा है):

$model = Mage::getModel('core/store')->load($id);

if ($model->getId() && $model->isCanDelete()) {
    $model->delete();
    Mage::dispatchEvent('store_delete', array('store' => $model));
}

मैं इस कोड को डेटा अपग्रेड स्क्रिप्ट में डालना चाहता हूं ताकि विलोपन स्वचालित रूप से निष्पादित हो जाए।

समस्या यह है कि data/Magento में अपग्रेड स्क्रिप्ट निष्पादित करते समय केवल क्षेत्र में कॉन्फ़िगर किए गए ईवेंट पर्यवेक्षकों को कॉल करता globalहै ( मैगेंटो स्ट्रक्चर अपडेट्स बनाम डेटा अपडेट देखें )। कुछ पर्यवेक्षकों की तरह enterprise_cmsऔर enterprise_searchघटना के store_delete_afterलिए adminhtmlक्षेत्र में परिभाषित किया गया है ताकि वे निष्पादित नहीं होंगे। स्टोर दृश्य हटाने को बैकएंड में निष्पादित विलोपन की तरह नियंत्रित नहीं किया जाएगा।

आप इस तरह संचालन कैसे संभालते हैं? अपग्रेड स्क्रिप्ट में अपने आप अतिरिक्त ईवेंट क्षेत्र लोड करें (मुझे इससे डर लगता है)? अपग्रेड स्क्रिप्ट में उस तरह के डेटा संशोधन न करें लेकिन अपने जादुई स्क्रैप को एक पवित्र छिपी जगह पर रखें और इसे मैन्युअल रूप से निष्पादित करें?


1
आपको स्टोर दृश्य को समस्याग्रस्त रूप से हटाने की आवश्यकता क्यों है?
oleksii.svarychevskyi

क्योंकि हमारे पास कई वातावरण हैं और यह प्रोग्रामेटिक रूप से सभी कॉन्फ़िगरेशन परिवर्तनों को करने के लिए तेज़ और अधिक विश्वसनीय है।
मथायस ज़ीस

कभी इसके लिए कोई हल मिला? आप ऐसा कितनी बार करेंगे? व्यक्तिगत रूप से, मैं दूसरे विकल्प के लिए जाऊंगा "अपग्रेड स्क्रिप्ट में उस तरह के डेटा संशोधन न करें लेकिन अपने जादुई स्क्रैप को एक पवित्र छिपी जगह पर रखें और इसे मैन्युअल रूप से निष्पादित करें?"
ProxiBlue

मैंने इस मुद्दे को स्थगित कर दिया क्योंकि इसमें और भी महत्वपूर्ण बातें थीं। मैगेंटो एसई के अपने @philwinkle ने ट्विटर पर जवाब दिया: "मैं ये एक कतार में करता हूं, या एक अग्रानुक्रम व्यवस्थापक गेम प्रेषण घटना (उर्फ नकली यह) सुनता हूं और आग लगाता हूं" ( twitter.com/philwinkle/status/418183845985210369 )। मेरा मानना ​​है कि यह मेरे लिए बहुत जोखिम भरा है और यद्यपि मुझे यह दृष्टिकोण पसंद नहीं है, मैं इसे मैन्युअल रूप से करूंगा।
मथायस ज़ीस

@MatthiasZeis आप एक जवाब के रूप में जोड़ सकते हैं और अनुत्तरित प्रश्नों को गिनने के लिए इसे स्वीकार कर सकते हैं?
Sander Mangel

जवाबों:


6

इसलिए मैथियास को ट्वीट करने के कुछ ही समय बाद मैं रेडियो चुप्पी साध गया। मुझे आशा है कि आपको यह सस्पेंस महसूस हुआ होगा क्योंकि आपने अभी कुछ हफ़्ते के लिए इस उत्तर का इंतजार किया है।

"मैं एक कतार में ये करता हूं" से मेरा क्या मतलब है:

घटना store_delete_after के लिए एंटरप्राइज़_केम्स और एंटरप्राइज़_सर्च जैसे कुछ पर्यवेक्षकों को व्यवस्थापक गेम क्षेत्र में परिभाषित किया गया है ताकि वे निष्पादित न हों। स्टोर दृश्य हटाने को बैकएंड में निष्पादित विलोपन की तरह नियंत्रित नहीं किया जाएगा।

कतार विधि:

जब मुझे पता है कि कुछ ऐसी घटनाएं हैं जो सही संदर्भ में आग नहीं लगेंगी (ज्यादातर ईई के लिए, लेकिन अन्य संदर्भों में लागू हो सकती हैं) तो मैं आमतौर पर एक कतार से विलोपन को बाहर निकालता हूं ताकि यह उस संदर्भ में चले जो इसे करने की आवश्यकता है ।

दूसरे शब्दों में, एक कतार तालिका (या खरगोश / विषय में कतार / विषय, आदि) बनाएं जिसमें लेन-देन का विवरण और घटना हुक है कि इसे सुनना चाहिए। यह उतना ही सुरुचिपूर्ण या सरल हो सकता है जितना आप चाहते हैं। यहाँ एक बुनियादी है

$queue = Mage::getModel('yourcompany/queue_job')
         ->setJobType('delete')
         ->setEntityType('core/store')
         ->setEntityId(12)
         ->setDispatchEvent('store_delete')
         ->setDispatchEventDataKey('store')
         ->save();

और फिर एक क्रोन में बाद में कतार में काम करें, जहां अब आपका नियंत्रण है कि कौन सी दुकान "चल रही है" (उर्फ आप इसे केवल चला रहे हैं जैसे कि वह व्यवस्थापक था, स्टोर 0):

foreach(Mage::getModel('yourcompany/queue_job')->getCollection() as $job){
    if($job->getJobType()=='delete'){

        $model = Mage::getModel($this->getEntityType())->load($this->getEntityId());

        if ($model->getId() && $model->isCanDelete()) {
            $model->delete();
            Mage::dispatchEvent($job->getDispatchEvent(), array($job->setDispatchEventDataKey() => $model));
        }
    }
}

जाहिर है अगर आप फैंसी हो रहे थे तो आप ट्राय / कैच में लपेटें और ट्रांजेक्शन में लपेटें। मुझे लगता है कि आपको जिस्ट मिलता है।

यह संभवत: उस प्रसंग को नियंत्रित करने का एकमात्र तरीका है जिसमें घटना आगजनी करती है।

अग्रानुक्रम घटना विधि:

आप स्वयं "adminhtml" विधि को मैन्युअल रूप से फायर कर सकते हैं - एलन आपको प्रभावित करने के लिए क्या करेगा की एक बहुत ही सभ्य व्याख्या देता है , लेकिन अनिवार्य रूप से यह इस तरह से है:

#File: app/code/core/Mage/Adminhtml/controllers/CustomerController.php
public function saveAction()
{
    //...
    $customer->save();
    //...
    Mage::dispatchEvent('adminhtml_customer_prepare_save', array(
        'customer'  => $customer,
        'request'   => $this->getRequest()
    ));        
    //..
}

कस्टमर सेव का एडमिन संस्करण नियमित मॉडल सेव को कॉल करता है और बाद में adminhtml घटना को भेजता है। यदि आप ऐसा चाहते हैं तो आप अपने आप को एक पर्यवेक्षक में उल्टा कर सकते हैं।


5

दमयन्ती, मुझे कुछ दार्शनिकों से प्यार है, लेकिन मुझे कार्य मापदंडों और क्षेत्र ( adminhtml | crontab | frontend | global | install ) को एक कतार में ले जाने की जटिलता / भंगुरता से असहमत होना होगा , खासकर अगर वह कतार क्रियान्वित होने जा रही है। एक Magento के संदर्भ। यदि मिश्रित संदर्भ हैं जिन्हें संभालने की आवश्यकता है तो कतार समाधान वर्तमान "मुद्दे" का पुन: कार्यान्वयन है!

मुझे लगता है कि कतार का दृष्टिकोण भंगुर है। मेरा तर्क है कि समय से पहले घटना वाले क्षेत्रों को लोड करना वास्तव में एक मुद्दा नहीं है। इसे समझाने के लिए, आइए हम आगे बढ़ते हैं और समस्या को देखते हैं:

निष्पादन क्षेत्र में समय से पहले एक घटना क्षेत्र को लोड करने का खतरा क्या है?

इसे समझने के लिए हमें निष्पादन के संदर्भ में घटना क्षेत्रों की जांच करनी चाहिए। माथियास, मुझे लगता है कि आप पहले से ही यह जानते हैं, लेकिन दूसरों के संपादन के लिए:

Mage_Core_Model_App::run()मोर्चा नियंत्रक के अनुरोध को भेजने से पहले डेटा सेटअप स्क्रिप्ट निष्पादित की जाती है :

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();
//Global event area is loaded here
        $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();
//Data setup scripts are executed here: 
            Mage_Core_Model_Resource_Setup::applyAllDataUpdates();
        }

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

जब तक डेटा सेटअप स्क्रिप्ट निष्पादित हो रही हैं तब तक ग्लोबल इवेंट एरिया लोड हो चुका है। राउटरिंग - रेफ़रेंशियल ईवेंट एरिया ( फ्रंटएंड या एडमिनिस्ट्रेश ) को Mage_Core_Controller_Varien_Action::preDispatch()राउटर के परिणामस्वरूप कंट्रोलर एक्शन से मेल खाते हुए लोड किया जाता है ( areaनाम इनहेरिटेंस के माध्यम से सेट किया जाता है):

public function preDispatch()
{
    //...
    Mage::app()->loadArea($this->getLayout()->getArea());
    //...
}

इसलिए आमतौर पर ऐप इनिशियलाइज़ेशन के दौरान केवल ग्लोबल इवेंट क्षेत्र के तहत कॉन्फ़िगर किए गए पर्यवेक्षकों को निष्पादित किया जाएगा। अगर सेटअप स्क्रिप्ट कुछ ऐसा करता है

$this->loadAreaPart(Mage_Core_Model_App_Area::AREA_ADMINHTML, Mage_Core_Model_App_Area::PART_EVENTS);

इसके बाद केवल दो खतरे हैं:

  1. एक पर्यवेक्षक के तहत गलत कॉन्फ़िगर किया गया है adminhtml एक संदर्भ के कम घटना का निरीक्षण करने जैसे controller_front_init_beforeयाcontroller_front_init_routers
  2. अनुरोध एक फ्रंटएंड अनुरोध है।

# 1 के लिए grep करना आसान होना चाहिए। # 2 वास्तविक चिंता है, और मुझे लगता है कि प्रतिबिंब समस्या को हल कर सकता है (ध्यान दें कि मैं बहुत ही अनुभवहीन हूं जो प्रतिबिंब के साथ अनुभव कर रहा है:

<?php

//Start setup script as normal
$installer = $this;
$installer->startSetup()

//Load adminhtml event area
Mage::app()->loadAreaPart(
    Mage_Core_Model_App_Area::AREA_ADMINHTML,
    Mage_Core_Model_App_Area::PART_EVENTS
);

// your setup script logic here

//I hope this isn't a bad idea.
$reflectedApp = new ReflectionClass('Mage_Core_Model_App');
$_areas = $reflectedApp->getProperty('_areas');
$_areas->setAccessible(true);
$areas = $_areas->getValue(Mage::app());
unset($areas['adminhtml']);
$_areas->setValue(Mage::app(),$areas); //reset areas

//End setup script as normal
$installer->endSetup()

मैंने इसका परीक्षण नहीं किया है, लेकिन यह adminhtml इवेंट इंडेक्स और संबंधित Mage_Core_Model_App_Areaऑब्जेक्ट को हटा देता है ।


1
मैं योग्य नहीं हूँ!! मैं योग्य नहीं हूँ!!!!
फिलिंक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.