Menghindari simpan dalam satu lingkaran dalam aksi massal

13

Saya telah membuat modul CRUD saya sendiri yang berisi tindakan sunting inline mirip dengan yang untuk halaman CMS
Semuanya berfungsi OK, tetapi ketika menjalankan phpsniffer dengan standar EcgM2 saya mendapatkan peringatan ini:

Metode LSD metode save () terdeteksi dalam loop

Bagaimana saya bisa menghindari ini?
Catatan: Peringatan yang sama muncul jika saya "mengendus" file inti yang ditautkan di atas.
Berikut adalah executemetode saya jika seseorang membutuhkannya. Tapi ini sangat mirip dengan yang dari pengontrol halaman 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
    ]);
}
Marius
sumber

Jawaban:

5

Dalam hal ini Anda harus ke save()entitas Anda, jadi Anda pasti harus memanggil metode itu.

File inti Magento asli yang Anda tautkan bukan satu-satunya yang melakukan itu, terutama kelas aksi massa.

Satu-satunya alternatif adalah menambahkan saveAttributemetode ke model sumber daya CRUD Anda berdasarkan yang diterapkan di 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;
}

Dengan cara ini, alih-alih memanggil yang berikut:

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

Anda harus dapat melakukan sesuatu seperti ini:

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

Seperti yang dinyatakan dalam komentar, Anda harus memodifikasi metode itu sedikit jika Anda tidak perlu memeriksa AbstractAttributecontoh untuk mencocokkan kebutuhan Anda

Raphael di Digital Pianism
sumber
Jahitannya masuk akal. Terima kasih. Saya akan mencobanya dan kembali dengan hasilnya.
Marius
@Marius perlu diingat bahwa metode ini sedikit berbeda dari saveAttributemetode EAV karena metode ini menerima larik "kode atribut" untuk disimpan alih-alih hanya satu kode atribut
Raphael di Digital Pianism
1
Saya perhatikan itu. Saya bahkan memodifikasinya sedikit sehingga tidak akan menerima dan contoh AbstractAttributesebagai parameter, karena saya tidak membutuhkannya di entitas datar saya. Ini bekerja dengan lancar. Terima kasih lagi.
Marius