Buộc bộ sưu tập sản phẩm sử dụng EAV thay vì bàn phẳng


9

Trong Magento 2, làm cách nào để tạm thời vô hiệu hóa danh mục phẳng? Tôi có một bộ sưu tập sản phẩm được liên kết với một cửa hàng frontend và muốn nó được tải thông qua các bảng EAV.

Tôi đã xem cách các bộ sưu tập xác định xem có nên sử dụng các bảng phẳng hay không, nhưng không tìm thấy cách nào để cài đặt bất cứ nơi nào.

Trong Magento 1 tôi đã thay đổi giá trị cấu hình được tải cho "danh mục phẳng được bật":

Mage::app()->getStore($storeId)->setConfig('catalog/frontend/flat_catalog_product', 0);

Tôi có cần phải viện đến nhà nước toàn cầu như thế này không? Nếu vậy thì thế nào? Hoặc có một cách thanh lịch hơn?

Câu trả lời:


9

Đối tượng chịu trách nhiệm xác định xem chỉ mục phẳng có sẵn (lớp Magento\Catalog\Model\Indexer\Product\Flat\State) là một thể hiện chia sẻ không thay đổi. Nhưng có thể sử dụng ví dụ của chúng ta, sử dụng các loại ảo.

Đây là của tôi di.xml:

  <virtualType name="disabledFlatStateProductCollectionFactory" type="Magento\Catalog\Model\ResourceModel\Product\CollectionFactory">
    <arguments>
      <argument name="instanceName" xsi:type="string">disabledFlatStateProductCollection</argument>
    </arguments>
  </virtualType>
  <virtualType name="disabledFlatStateProductCollection" type="Magento\Catalog\Model\ResourceModel\Product\Collection">
    <arguments>
      <argument name="catalogProductFlatState" xsi:type="object">disabledFlatState</argument>
    </arguments>
  </virtualType>
  <virtualType name="disabledFlatState" type="Magento\Catalog\Model\Indexer\Product\Flat\State">
    <arguments>
      <argument name="isAvailable" xsi:type="boolean">false</argument>
    </arguments>
  </virtualType>

Bây giờ, tôi có một loại nhà máy bộ sưu tập sản phẩm ảo, trong đó $isAvailable = falsecuối cùng "Trạng thái" của riêng tôi được sử dụng:

disabledFlatStateProductCollectionFactory
 |
 + disabledFlatStateProductCollection
    |
    + disabledFlatState

Và đối với các lớp mà tôi cần một nhà máy thu thập với chỉ mục phẳng bị vô hiệu hóa, tôi chỉ định loại ảo disabledFlatStateProductCollectionFactorycho tham số hàm tạo tương ứng:

<arguments>
  <argument name="collectionFactory" xsi:type="object">disabledFlatStateProductCollectionFactory</argument>
</arguments>

Thay thế là điều mạnh mẽ nhất mà việc triển khai DI của Magento mang lại cho bạn! Giải pháp tốt, upvote cá nhân từ tôi!
Ivan Chepurnyi

Điều này không làm việc cho tôi. :( Nếu tôi có lớp tùy chỉnh của mình: hàm công khai __construct (\ Magento \ Catalog \ Model \ ResourceModel \ Product \ CollectionFactory $ sưu tậpFactory) {$ this -> _ sưu tập Tôi thấy rằng Magento đang sử dụng loại ảo thay vì bộ sưu tập sản phẩm thông thường.
mstojanov 18/07/17

6

Khi một bộ sưu tập sản phẩm được tải, thực tế là nó sử dụng EAV hoặc các bảng phẳng được xác định bởi kết quả này \Magento\Catalog\Model\ResourceModel\Product\Collection::isEnabledFlat().
Bạn có thể viết một aroundhoặc một afterplugin, trả về falsenếu bạn đang ở trong bối cảnh của một chế độ xem cửa hàng nhất định.

Hoặc thậm chí tốt hơn, các giá trị cho cờ phẳng được lưu trữ (lưu trữ) trong thành viên _flatEnabledtừ cùng một lớp.

public function isEnabledFlat()
{
    if (!isset($this->_flatEnabled[$this->getStoreId()])) {
        $this->_flatEnabled[$this->getStoreId()] = $this->getFlatState()->isAvailable();
    }
    return $this->_flatEnabled[$this->getStoreId()];
}

Bạn có thể viết cùng aroundhoặc afterplugin cho phương thức \Magento\Catalog\Model\Indexer\Product\Flat\State::isAvailable().
Bằng cách này, plugin của bạn chỉ được thực hiện một lần. Nó có thể hữu ích nếu bạn có logic nặng đằng sau nó hoặc nếu nó được sử dụng ở những nơi khác.

Điều này có vẻ thanh lịch hơn khi thay đổi một giá trị cấu hình một cách nhanh chóng.


Tôi tìm thấy một giải pháp khác mà không có bất kỳ mã tùy chỉnh nào, sử dụng các loại ảo. Nhưng vì bạn đến gần nhất và đưa ra một gợi ý quan trọng, hãy có <del> kitkat </ del> <in> bounty </ in>
Fabian Schmengler

Làm thế nào để viết một plugin sau cho \Magento\Catalog\Model\Indexer\Product\Flat\State::isAvailable()?
Liam Mitchell

1

Cách thanh lịch hơn sẽ là sử dụng cùng mã với mã cho phép chế độ phẳng khi lưu cấu hình. Nó có thể được tìm thấy dưới Magento/Catalog/Model/Indexer/Product/Flat/System/Config/Mode:

public function processValue()
{
    if ((bool)$this->getValue() != (bool)$this->getOldValue()) {
        if ((bool)$this->getValue()) {
            $this->indexerState->loadByIndexer(\Magento\Catalog\Model\Indexer\Product\Flat\Processor::INDEXER_ID);
            $this->indexerState->setStatus(\Magento\Framework\Indexer\StateInterface::STATUS_INVALID);
            $this->indexerState->save();
        } else {
            $this->_productFlatIndexerProcessor->getIndexer()->setScheduled(false);
        }
    }
}

Vì vậy, tôi khá chắc chắn rằng bạn có thể làm một cái gì đó như thế:

$this->_productFlatIndexerProcessor->getIndexer()->setScheduled(false);

Trường hợp $this->_productFlatIndexerProcessorlà một ví dụ của \Magento\Catalog\Model\Indexer\Product\Flat\Processor.

Có thể thay thế

Tuy nhiên, phương pháp đó không lưu cấu hình nên khi hệ thống kiểm tra nếu căn hộ được bật thông qua cấu hình thì nó vẫn trả về đúng.

Một cách khác có thể (sẽ được kiểm tra) sẽ là sử dụng một plugin trên isFlatEnabledphương thức từMagento\Catalog\Model\Indexer\Product\Flat\State (phương thức thực sự được định nghĩa trong Magento\Catalog\Model\Indexer\AbstractFlatStatelớp).

Dựa trên những gì bạn muốn đạt được, bạn có thể thiết lập một plugin sau để buộc phương thức đó trả về false trong các điều kiện nhất định.


Tôi khá chắc chắn, việc gọi setScheduled(false)trình lập chỉ mục không hoạt động vì nó chỉ vô hiệu hóa lập chỉ mục theo lịch trình và sẽ không ảnh hưởng đến các bộ sưu tập. Nhưng bất kể, nó cũng lưu chế độ, đó chắc chắn không phải là điều tôi muốn.
Fabian Schmengler

@fschmengler hoàn toàn đúng, đặc biệt vì mã kiểm tra xem bảng phẳng có được bật hay không sử dụng cấu hình trực tiếp. Giải pháp thay thế sẽ khắc phục điều đó mặc dù;)
Raphael tại Digital Pianism
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.