बड़े पैमाने पर कार्रवाई में एक लूप में बचाने से बचें


13

मैंने अपना स्वयं का CRUD मॉड्यूल बनाया है जिसमें CMS पृष्ठों के लिए एक इनलाइन एडिट एक्शन जैसा है
सब कुछ ठीक है, लेकिन जब EcgM2 मानक के साथ phpsniffer चल रहा है तो मुझे यह चेतावनी मिलती है:

मॉडल एलएसडी विधि बचा () लूप में पाया गया

इससे कैसे बचा जा सकता है?
नोट: वही चेतावनी दिखाई देती है यदि मैं ऊपर लिंक की गई कोर फाइल को "सूँघता" हूँ।
यहाँ मेरी executeविधि है अगर किसी को इसकी आवश्यकता है। लेकिन यह CMS पेज कंट्रोलर से बहुत मिलता-जुलता है

public function execute()
{
    /** @var \Magento\Framework\Controller\Result\Json $resultJson */
    $resultJson = $this->jsonFactory->create();
    $error = false;
    $messages = [];

    $postItems = $this->getRequest()->getParam('items', []);
    if (!($this->getRequest()->getParam('isAjax') && count($postItems))) {
        return $resultJson->setData([
            'messages' => [__('Please correct the data sent.')],
            'error' => true,
        ]);
    }

    foreach (array_keys($postItems) as $authorId) {
        /** @var \Sample\News\Model\Author $author */
        $author = $this->authorRepository->getById((int)$authorId);
        try {
            $authorData = $this->filterData($postItems[$authorId]);
            $this->dataObjectHelper->populateWithArray($author, $authorData , AuthorInterface::class);
            $this->authorRepository->save($author);
        } catch (LocalizedException $e) {
            $messages[] = $this->getErrorWithAuthorId($author, $e->getMessage());
            $error = true;
        } catch (\RuntimeException $e) {
            $messages[] = $this->getErrorWithAuthorId($author, $e->getMessage());
            $error = true;
        } catch (\Exception $e) {
            $messages[] = $this->getErrorWithAuthorId(
                $author,
                __('Something went wrong while saving the author.')
            );
            $error = true;
        }
    }

    return $resultJson->setData([
        'messages' => $messages,
        'error' => $error
    ]);
}

जवाबों:


5

उस स्थिति में आपको save()अपनी संस्थाओं के लिए है, इसलिए आपको निश्चित रूप से उस पद्धति को कॉल करना होगा।

आपके द्वारा जोड़ा गया मूल कोर मैगेंटो फ़ाइल केवल एक ही नहीं है जो ऐसा करता है, विशेष रूप से बड़े पैमाने पर कार्रवाई कक्षाएं।

एकमात्र विकल्प यह है saveAttributeकि आपके CRUD संसाधन मॉडल में लागू की गई विधि के आधार पर एक विधि जोड़ें app/code/Magento/Sales/Model/ResourceModel/Attribute.php:

public function saveAttribute(AbstractModel $object, $attribute)
{
    if ($attribute instanceof AbstractAttribute) {
        $attributes = $attribute->getAttributeCode();
    } elseif (is_string($attribute)) {
        $attributes = [$attribute];
    } else {
        $attributes = $attribute;
    }
    if (is_array($attributes) && !empty($attributes)) {
        $this->getConnection()->beginTransaction();
        $data = array_intersect_key($object->getData(), array_flip($attributes));
        try {
            $this->_beforeSaveAttribute($object, $attributes);
            if ($object->getId() && !empty($data)) {
                $this->getConnection()->update(
                    $object->getResource()->getMainTable(),
                    $data,
                    [$object->getResource()->getIdFieldName() . '= ?' => (int)$object->getId()]
                );
                $object->addData($data);
            }
            $this->_afterSaveAttribute($object, $attributes);
            $this->getConnection()->commit();
        } catch (\Exception $e) {
            $this->getConnection()->rollBack();
            throw $e;
        }
    }
    return $this;
}

इस तरह, निम्नलिखित कॉल करने के बजाय:

$this->authorRepository->save($author);

आपको ऐसा कुछ करने में सक्षम होना चाहिए:

$author->getResource()->saveAttribute($author, array_keys($authorData));

जैसा कि टिप्पणियों में कहा गया है, यदि आपको AbstractAttributeअपनी आवश्यकताओं से मेल खाने के लिए उदाहरण की जांच करने की आवश्यकता नहीं है, तो आपको उस पद्धति को थोड़ा संशोधित करना होगा


सीम उचित। धन्यवाद। मैं इसे एक शॉट देता हूँ और परिणामों के साथ वापस आता हूँ।
मेरियस

@ मार्स सिर्फ यह ध्यान रखें कि यह विधि EAV saveAttributeविधि से थोड़ी अलग है क्योंकि यह "विशेषता कोड" की एक सरणी को केवल एक विशेषता कोड के बजाय सहेजने के लिए स्वीकार करती है
राफेल एट डिजिटल पियानोवाद

1
मैंने उस पर ध्यान दिया है। मैंने इसे थोड़ा संशोधित भी किया, इसलिए यह स्वीकार नहीं करेगा और उदाहरण के AbstractAttributeरूप में पैरामीटर, क्योंकि मुझे अपने फ्लैट इकाई में इसकी आवश्यकता नहीं है। यह आसानी से काम करता है। एक बार फिर धन्यवाद।
मेरियस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.