Tránh lưu trong một vòng lặp trong hành động hàng loạt


12

Tôi đã tạo mô-đun CRUD của riêng mình có chứa hành động chỉnh sửa nội tuyến tương tự như mô-đun cho các trang CMS
Mọi thứ đều hoạt động tốt, nhưng khi chạy phpsniffer với tiêu chuẩn EcgM2, tôi nhận được cảnh báo này:

Mô hình LSD mô hình save () được phát hiện trong vòng lặp

Làm thế nào tôi có thể tránh điều này?
Lưu ý: Cảnh báo tương tự xuất hiện nếu tôi "đánh hơi" tệp lõi được liên kết ở trên.
Đây là executephương pháp của tôi trong trường hợp ai đó cần nó. Nhưng nó rất giống với cái từ bộ điều khiển trang 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
    ]);
}

Câu trả lời:


5

Trong trường hợp đó, bạn phải save()thực hiện các thực thể của mình, vì vậy bạn chắc chắn sẽ phải gọi phương thức đó.

Tệp Magento lõi mà bạn liên kết không phải là tệp duy nhất thực hiện điều đó, đặc biệt là các lớp hành động hành động hàng loạt.

Cách thay thế duy nhất là thêm một saveAttributephương thức vào mô hình tài nguyên CRUD của bạn dựa trên phương thức được triển khai trong 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;
}

Bằng cách này, thay vì gọi như sau:

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

Bạn sẽ có thể làm một cái gì đó như thế này:

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

Như đã nêu trong các nhận xét, bạn sẽ phải sửa đổi phương pháp đó một chút nếu bạn không cần kiểm tra AbstractAttributethể hiện để phù hợp với nhu cầu của mình


Đường may hợp lý. cảm ơn. Tôi sẽ cho nó một shot và quay lại với kết quả.
Marius

@Marius chỉ cần lưu ý rằng phương thức này hơi khác so với saveAttributephương thức EAV vì nó chấp nhận một mảng "mã thuộc tính" để lưu thay vì chỉ một mã thuộc tính
Raphael tại Digital Pianism

1
Tôi đã thông báo rằng. Tôi thậm chí đã sửa đổi nó một chút để nó không chấp nhận và ví dụ AbstractAttributenhư tham số, vì tôi không cần nó trong thực thể phẳng của mình. Nó hoạt động trơn tru. Cảm ơn một lần nữa.
Marius
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.