2

Magento 2 get recently viewed products collection of Customer (Using customer ID) programmatically

I tried this solution But I want recently viewed products collection.

I tried below solution too but it is not returning anything. [I am logged in]

protected $recentlyViewed;

public function __construct(
...
    \Magento\Reports\Block\Product\Viewed $recentlyViewed
) {
...
    $this->recentlyViewed = $recentlyViewed;
}

/**
 * Get recently viewed products for the customer
 *
 */
public function getMostRecentlyViewed(){
    return $this->recentlyViewed->getItemsCollection();
}
  • I added code in chat box. – Rohan Hapani Nov 26 '18 at 17:27
  • Hey Adi... Did you get the Recently View Product Collection??? I also tried all the techniques given below but returning me Null Array – Asad Khan Jun 20 '19 at 6:02
  • No I never get that one, Yeah none of answers worked for me @AsadKhan – Aditya Shah Jun 21 '19 at 16:55
  • 1
    OK Sir actually I get the recently viewed products.... If u still need it then I'm gonna post the code... n also I set it for those customers as well who r not logged In... – Asad Khan Jun 22 '19 at 17:06
  • sure sure you can post it :) If it works I'll accept as answer @AsadKhan – Aditya Shah Jun 23 '19 at 17:20
5

Try to use this code :

Method 1 :

/**
 * Layout
 * @var \Magento\Framework\View\LayoutInterface
 */

 protected $_layout;

 public function __construct(
    .....
    \Magento\Framework\View\LayoutInterface $layout
    .......
 ) {
     $this->_layout = $layout;
 }

public function getMyCollection() {
    $block =  $this->_layout->getBlockSingleton(\Magento\Reports\Block\Product\Viewed::class)->getItemsCollection();
    return $block;
}

UPDATE :

Method 2 :

You need to load ItemCollection() after get collection like below way :

protected $recentlyViewed;

public function __construct(
    \Magento\Reports\Block\Product\Viewed $recentlyViewed
) {
    $this->recentlyViewed = $recentlyViewed;
}

public function execute() {
    $collection = $this->recentlyViewed->getItemsCollection()->load();
    echo "<pre>";
    print_r($collection->getData());
    exit;
}

Reference

  • 1
    Thanks bro :) Definitely try this tomorrow morning ! – Aditya Shah Nov 25 '18 at 14:00
  • 1
    Sure :) If not working then you can update here.. – Rohan Hapani Nov 25 '18 at 14:02
  • Not working @Rohan – Aditya Shah Nov 26 '18 at 5:43
  • 1
    Try to use this second method.. it's working from my side so. – Rohan Hapani Nov 26 '18 at 6:18
  • Okay bro :) trying * – Aditya Shah Nov 26 '18 at 6:19
2

Please try below code, I tested the same and found it working:

<?php 
namespace YourPackage\YourModule\Block\RecentlyViewed;

class Test extends \Magento\Framework\View\Element\Template
{
    protected $recentlyViewed;

    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Reports\Block\Product\Viewed $recentlyViewed,
        array $data = []
    ) {
        $this->recentlyViewed = $recentlyViewed;
        parent::__construct( $context, $data );
    }

    public function getMostRecentlyViewed(){
        return $this->recentlyViewed->getItemsCollection()->getData();
    }
}

and call this block in required file, cms page or static block, for example if you wan to add this block to home page than add below code:

{{block class="YourPackage\YourModule\Block\RecentlyViewed\Test" name="block_recently_viewed" template="YourPackage_YourModule::test.phtml"}}

In test.phtml file you can get the collection and design it in your way, I just tested by printing the collection and it was printing correctly.

test.phtml

<?php echo "<pre>"; print_r($this->getMostRecentlyViewed()); ?>

Note : Please note that the collection will be empty if you don't visits any page as the collection is of recently viewed product by you. Visit some products at your store and you will get the collection being populated.

  • Is it possible without accessing parent ? – Aditya Shah Nov 26 '18 at 5:43
  • without extends \Magento\Framework\View\Element\Template – Aditya Shah Nov 26 '18 at 5:43
  • No, it would create issue as we need to Abstract class for frontend representational purpose :), We need to create similar abstract class if you don't want to extend it but that is meaningless effort. Its good to extend the existing available Abstract class.. – Himmat Paliwal Nov 26 '18 at 5:59
  • Okay and If i extend that class _ I want customers collection – Aditya Shah Nov 26 '18 at 6:00
  • And I want all this in Model file that's why I asked that I need collection for that :) – Aditya Shah Nov 26 '18 at 6:01
2

so In my scenario I need Recently Viewed Products in new custom page... n I also want to show the recently viewed products while the user is not logged In.

Vender/Module/view/frontend/layout/recently_index_index

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <referenceContainer name="content">
        <block class="Vender\Module\Block\Viewedd" name="recently" template="Vender_Module::recently.phtml" cacheable="false" />
    </referenceContainer>
</page>

Ok so this layout is really important in this layout as you can see that cacheable = "false" this is the thing where I was stuck around 3 days. If you want to show Recently Viewed Products If the user is not logged In then you have to false the cacheable. now

Vender\Module\Block\Viewedd.php

<?php
namespace Vender\Module\Block;


use Magento\Framework\View\Element\Template\Context;
use Magento\Reports\Block\Product\Viewed;
use Magento\Catalog\Model\ProductFactory;

class Viewedd extends \Magento\Framework\View\Element\Template
{
    /**
     * Limit of orders
     */
    const ORDER_LIMIT = 4;  //Image Limit this can be changed from here


    /**
     * @param \Magento\Framework\View\Element\Template\Context $context
     * @param array $data
     */
    public function __construct(
        Context $context,
        Viewed $recentlyViewed,
        ProductFactory $productFactory,
        array $data = []
    ) {
        $this->_recentlyViewed = $recentlyViewed;
        $this->_productFactory = $productFactory;
        parent::__construct($context, $data);
    }

    /**
     * @return void
     */
    protected function _construct()
    {
        parent::_construct();
        $this->getRecentlyviewed();
    }

    /**
     * Get recently placed orders. By default they will be limited by 5.
     */

    public function getRecentlyviewed()
    {

     $recentViewedCollection =  $this->_recentlyViewed->getItemsCollection()->setPageSize(
            self::ORDER_LIMIT
        )->load();
     ;
        $this->setRecentlyviewedcol($recentViewedCollection);
        return $this->getRecentlyviewedcol();
    }


    /**
     * @return string
     */
    protected function _toHtml()
    {
        if ($this->getRecentlyviewedcol()->getSize() > 0) {
            return parent::_toHtml();
        }
       return parent::_toHtml();
    }

    public function getProductLoader()
    {
        return $this->_productFactory;
    }

}

now in this class as you can see first we get recently viewed Products in getRecentlyviewed() function. now after that we need to create our phtml file

Vender/Module/view/frontend/templates/recently.phtml

<h1>Recently Viewed Products</h1>

<?php
$col = $this->getRecentlyviewedcol();
$count = count($col);
$_productloader = $this->getProductLoader();
?>

<?php if($count): ?>         
    <div class="wishtlist-recently-viewed">
        <div class="d-recently-title">
            <h3>Recently Viewed</h3>
        </div>
        <div class="d-view-blocks">
            <ul>
                <?php foreach ($col as $item) : ?> 
                    <?php        
                        $loadedProduct = $_productloader->create()->load($item->getEntityId());
                        $i = $this->helper('Magento\Catalog\Helper\Image')->init($loadedProduct, 'product_page_image_large'); 
                    ?>
                <li class="col-12 col-lg-3 col-md-3 col-sm-12">
                    <div class="d-slide-box">
                        <div class="d-block-div ">
                            <div class="d-wishlist-img">
                                <a href="<?=$loadedProduct->getProductUrl();?>"><img style="width:300px;height:350px;" class="img-fluid" src="<?=$i->getUrl();?>" alt="First slide"></a>
                            </div>
                            <div class="d-view-title-inner d-view-title-inner-r-v">
                            <div class="d-wishlist-title">
                                <a href="<?=$loadedProduct->getProductUrl();?>"><h3><?=$loadedProduct->getName()?></h3></a>
                            </div>

                            </div>

                        </div>
                    </div>
                </li>
                <?php endforeach; ?>
            </ul>
        </div>
    </div>
<?php endif;?>

In this you'll get all the Recently Viewed Products with images and with Product Name.
Note: firstly I was trying this on the HomePage using the above other solutions but it was not working you need to create new layout or maybe put the xml block in your Layout hope it will work for you.

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.