0

What I have tried till now is

$objManager = \Magento\Framework\App\ObjectManager::getInstance();
$visitors = $objManager->get('Your\Store\Block\Customer\Login');
$currVisitorId = $visitors->getLoggedInUserId();
$currVisitorName = $visitors->getLoggedInUserName();

$prodMyViewedCol = $objManager->get('\Magento\Reports\Model\ResourceModel\Event\Collection');
$prodMyViewedCol->setOrder('logged_at','DESC');

$prodViewedThisEntirelyIdCol = array();  //used to store products viewed by currently logged in user.

foreach($prodMyViewedCol as $prod){
    //subject id is the column name in the event table
    if($prod->getSubjectId() != $currVisitorId){
        continue;
    }
    $product_id = $prod->getObjectId();
    $prodViewedThisEntirelyIdCol[] = $product_id;
}
echo "<pre>";
echo 'logged in user: ', $currVisitorName, '<br>';
var_dump(array_unique($prodViewedThisEntirelyIdCol));
die();

fetched the collection of events of product view and sort them in descending order. Then after filtered them by the customer id. I'm getting the correct history which is shown below:enter image description here

Ok, I got the history and can list the history of a customer, I could be happy if my requirements were limited to this. But I need to delete the history. I can do that as well but deleting the data in table will hamper the results of reports in backend.

So what I want is: get the products viewed by currently logged in customer and delete that history safely without hampering the core behavior of reports, or store's database.

2 Answers 2

1

First off: don't directly use the object manager in your code, but use dependency injection.

enter image description here

Secondly: use factories to create instances of objects.

And for the question about deletion: you should use Service Contracts (repositories) when it comes to handling the persistence of data. Given that the reports-module currently doesn't have any (2.1.6), you need to handle the deletion using the resource model. Once again: use dependency injection and a factory to get this model.

Example code for a Block class:

namespace yourNameSpace;
class Example  extends \Magento\Framework\View\Element\Template
{
    /**
     * @var \Magento\Reports\Model\ResourceModel\Event\CollectionFactory
     */
    protected $collectionFactory;
/**
 * @var \Magento\Customer\Model\Session
 */
protected $customerSession;

/**
 * @var \Magento\Reports\Model\ResourceModel\EventFactory
 */
protected $resourceFactory;

/**
 * Example constructor.
 * @param \Magento\Reports\Model\ResourceModel\Event\CollectionFactory $collectionFactory
 * @param \Magento\Reports\Model\ResourceModel\EventFactory $resourceFactory
 * @param \Magento\Customer\Model\Session $customerSession
 */
public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,        
    \Magento\Reports\Model\ResourceModel\Event\CollectionFactory $collectionFactory,
    \Magento\Reports\Model\ResourceModel\EventFactory $resourceFactory,
    \Magento\Customer\Model\Session $customerSession
) {
    parent::__construct($context);
        $this->collectionFactory = $collectionFactory;
        $this->customerSession = $customerSession;
        $this->resourceFactory = $resourceFactory;
    }

    /**
     * @return bool|\Magento\Reports\Model\ResourceModel\Event\Collection
     */
    public function getViewedProductsForCurrentCustomer()
    {
        if ($this->customerSession->isLoggedIn()) {
            /** @var \Magento\Reports\Model\ResourceModel\Event\Collection $collection */
            $collection = $this->collectionFactory->create();
            $collection->addFieldToFilter('subject_id', $this->customerSession->getCustomerId());
            $collection->distinct(true);

            return $collection;
        }

        return false;
    }

    /**
     * 
     */
    public function deleteViewedProductsForCurrentCustomer()
    {
        if ($products = $this->getViewedProductsForCurrentCustomer()) {
            /** @var \Magento\Reports\Model\ResourceModel\Event $resource */
            $resource = $this->resourceFactory->create();
            foreach($products as $product) {
                $resource->delete($product);
            }
        }
    }
}

Haven't tested this code, but in theory it should work.

On a sidenote: I don't know how much knowledge you have about Magento 2, but you should really understand the following core concepts:

  • Dependency Injection
  • Repositories
  • Auto generated code (factories)

The Magento documentation has tons of examples about this. Besides that it will also help to dive in the following programming principles:

  • S.O.L.I.D programming
  • Composition over Inheritance
1
  • Thanks for your answer. Well I'm beginner , I understand DI and factories but not idea of Repositories,. I'll definitely use dependency injection after I get desired output. By modifying few of your codes I was able to get it to work. By my question you must have understood that I want to show user their browsing history in frontend and allow them to clear on will basis. If I delete this way, then the report that is shown in admin panel is affected. I don't want this to happen. So what I mean to get is entirely different way to view and delete history that won't affect ** Report>Product>View**
    – P S
    May 17, 2017 at 16:11
0

First of all I created following file to track product view event.

events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="catalog_controller_product_view">
        <observer name="catalog_controller_product_view_catcher" instance="User\History\Observer\UsersProductView" />
    </event>
</config>

The observer saves each product viewed by the customer in custom made table in database:

<?php
namespace User\History\Observer;
/*
  Observer class to save product view history.
*/
class UsersProductView implements \Magento\Framework\Event\ObserverInterface
{
    protected $productViewHistory;

    public function __construct(
        \User\History\Model\CustomerProductViewHistory $productViewHistory,
    ){}
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        if($this->isUserLoggedIn())
      {
         $product = $observer->getData('product');
         $objectId = $product->getData('entity_id');

      }
    }
    public function saveData($objectId)
    {
        $subjectId = $this->getLoggedInUserId();
        $subType =  $this->getSubjectType();
        $storeId = $this->_storeManager->getStore()->getId();

        /*SET DATA*/
        $this->productViewHistory->setEventId(0);
        $this->productViewHistory->setObjectId($objectId);
        $this->productViewHistory->setSubtype($subType);
        $this->productViewHistory->setStoreId($storeId);
        $this->productViewHistory->setSubjectId($subjectId);

        /*SAVE*///$this->productViewHistory->save();
        try {
           $this->productViewHistory->save();
        }
        catch (\Exception $ex) {
            $this->logger->critical($ex);
            return false;
        }
    }
...
...
}

Using above approach I'm able to save the user's view history in my own table so that deleting it won't affect magento's reports.

To delete history I used below function:

public function deleteEventForProductId($productId)
{
   $collection = $this->historyCollectionFactory->create();
   // There can be multiple events associated with same user for same product.
   $collection->addFieldToFilter('object_id', $productId);
   foreach ($collection as $key => $value) {
        if($value->getData('subject_id') == $this->getLoggedInUserId())
           // user repository to delete by id.
           $this->historyRepo->deleteById( $value->getData('id') );
       }    
}   

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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