0

Magento 2.1.6 I have a module that populates a specific category with the "latest 200" new items added to my magento database. However, it has a problem in that it doesn't account for the "Product In Website" attribute against each product. So any items that I do not yet have assigned to the website are still counted among those 200 products I am trying to display. In that case, there will be missing products from the page as they will not be displayed - no problem unless you want to add another 10,000 items to your magento database, but not display them on this website! My 200 most recent items will actually display zero items in this case.

This is the part of the code that puts together the product collection, but I think it needs reworking to take into account the problem outlined above, and to also always contain 200 products in the resulting collection.

if ($catID == 571 && $catID !== "") {
        $request = $objectManager->create('Magento\Framework\App\Request\Http');
        $productCollection = $objectManager->create('Magento\Catalog\Model\ResourceModel\Product\CollectionFactory');
        $_productCollectionlastitem = $productCollection->create()->setPageSize(1)->addAttributeToSelect('*')->addAttributeToSort('entity_id', 'desc')
                ->load();
        $lastid = $_productCollectionlastitem->getFirstItem()->getId();
        $startid = $lastid - 200;
        $storeid = 1;
        $_productCollection = $productCollection->create()
                ->setPageSize(36)
                ->setCurPage($request->getParam("p"))
                ->addAttributeToSelect('*')
                ->addStoreFilter($storeid)
                ->addAttributeToFilter('visibility', \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
                ->addAttributeToFilter('status', \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
                ->addAttributeToFilter('image', array("neq"=>'no_selection'))
                ->addAttributeToFilter('entity_id', array(
            'from' => $startid,
            'to' => $lastid
        ));
        if ($request->getParam("product_list_order")) {
            $_productCollection->addAttributeToSort($request->getParam("product_list_order"), "asc");
        } else {
            $_productCollection->addAttributeToSort('entity_id', "desc");
        }
        $_productCollection->addUrlRewrite();
        //
        $_productCollection->load();

        return $_productCollection;
    }

I think the way this collection is assembled is incorrect, starting counting at the most recent ID number of the products, but I am unsure how I might fix this.

Could anyone shine some light on how I might change this code to resolve this issue?

1

After understanding your problem, I would say you should apply the store filter to the first collection where you get the last entity_id. Also I would limit that collection to 200 and get the first and last item. That should be safe because the store filter is applied. To be 100% in sync with the collection where you retrieve the data you need to put all filter except paging in the collection where the range of entity_ids is determined.

Give it a try:

//your code
$_productCollectionlastitem = $productCollection->create()->setPageSize(1)->addAttributeToSelect('*')->addAttributeToSort('entity_id', 'desc')
            ->load();
    $lastid = $_productCollectionlastitem->getFirstItem()->getId();
    $startid = $lastid - 200;

//new code with lastid and startid matching the store
//anyway to be 100% consistent with the collection where you retrieve data, you need all filters set here (except paging parameters) 
$storeid = 1;
$_productCollectionlastitem = $productCollection->create()
    ->setPageSize(200)
    ->addStoreFilter($storeid)
    ->addAttributeToFilter('visibility', \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
    ->addAttributeToFilter('status', \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
    ->addAttributeToFilter('image', array("neq"=>'no_selection'))
    ->addAttributeToSort('entity_id', 'desc')
    ->load();
$lastid = $_productCollectionlastitem->getFirstItem()->getId();
$startid  = $_productCollectionlastitem->getLastItem()->getId();
//continue with your code....
  • There is already a setPageSize(36) in the collection code, which determines how many items to display on a page. not sure this will work? – robgt Feb 26 at 15:24
  • Sorry, you're right - I have overseen that, choose the pagesize you need - if you want 36 keep the first one, if you need 200 the last. The difference to your code is that I have removed the "hard" limitation of the entity_ids from - to. I've updated the code and removed the duplicate setPageSize – HelgeB Feb 26 at 15:26
  • Thank you. I will have to try this now. What I am hoping is that it will always start displaying products from the most recently added new item down to older items (limited to 200 total products). – robgt Feb 26 at 15:30
  • Unfortunately, this pulls in ALL products from the database, and displays 200 per page... – robgt Feb 26 at 15:35
  • Ok, now I understand: you expect a product list with correct pagination which ends at 200 products. I'll think about that, of course my code can't do that, sorry – HelgeB Feb 26 at 15:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.