Magento 2: Working with Wishlist

Number of items in Magento 2 wishlist sidebar

By default, you can see the 3 last added wishlist items in the sidebar. This number is hardcoded in Magento\Wishlist\CustomerData\Wishlist class. There is no corresponding option in the admin panel. To override it we will use dependency injection functionality.

– add the following line in the module di.xml to tell Magento to use our class instead of the standard one.
Filename: Vendor/Module/etc/frontend/di.xml

<preference for="Magento\Wishlist\CustomerData\Wishlist" type="Vendor\Module\CustomerData\Wishlist">
</preference>

Vendor/Module/CustomerData/Wishlist.php

<?php

namespace Vendor\Module\CustomerData;

class Wishlist extends \Magento\Wishlist\CustomerData\Wishlist
{
	/**
     * Get wishlist items
     *
     * @return array
     */
    protected function getItems()
    {
        $this->view->loadLayout();

		$collection = $this->wishlistHelper->getWishlistItemCollection();

		//show all wishlist items
		$collection->clear()->setInStockFilter(true)->setOrder('added_at');

		//show 5 wishlist items
		//$collection->clear()->setPageSize(5)->setInStockFilter(true)->setOrder('added_at');

		$items = [];
		foreach ($collection as $wishlistItem) {
			$items[] = $this->getItemData($wishlistItem);
		}
		return $items;
	}
}

Add to wishlist” without redirecting to the wishlist page

Vendor/Module/etc/frontend/di.xml

<?php

namespace Vendor\Module\Controller\Index;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\App\Action;
use Magento\Framework\Data\Form\FormKey\Validator;
use Magento\Framework\Exception\NotFoundException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Controller\ResultFactory;

/**
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class Add extends \Magento\Wishlist\Controller\Index\Add
{
    /**
     * Adding new item
     *
     * @return \Magento\Framework\Controller\Result\Redirect
     * @throws NotFoundException
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     * @SuppressWarnings(PHPMD.UnusedLocalVariable)
     */
    public function execute()
    {
        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
        if (!$this->formKeyValidator->validate($this->getRequest())) {
            return $resultRedirect->setPath('*/');
        }

        $wishlist = $this->wishlistProvider->getWishlist();
        if (!$wishlist) {
            throw new NotFoundException(__('Page not found.'));
        }

        $session = $this->_customerSession;

        $requestParams = $this->getRequest()->getParams();

        if ($session->getBeforeWishlistRequest()) {
            $requestParams = $session->getBeforeWishlistRequest();
            $session->unsBeforeWishlistRequest();
        }

        $productId = isset($requestParams['product']) ? (int)$requestParams['product'] : null;
        if (!$productId) {
            $resultRedirect->setPath('*/');
            return $resultRedirect;
        }

        try {
            $product = $this->productRepository->getById($productId);
        } catch (NoSuchEntityException $e) {
            $product = null;
        }

        if (!$product || !$product->isVisibleInCatalog()) {
            $this->messageManager->addErrorMessage(__('We can\'t specify a product.'));
            $resultRedirect->setPath('*/');
            return $resultRedirect;
        }

        try {
            $buyRequest = new \Magento\Framework\DataObject($requestParams);

            $result = $wishlist->addNewItem($product, $buyRequest);
            if (is_string($result)) {
                throw new \Magento\Framework\Exception\LocalizedException(__($result));
            }
            if ($wishlist->isObjectNew()) {
                $wishlist->save();
            }
            $this->_eventManager->dispatch(
                'wishlist_add_product',
                ['wishlist' => $wishlist, 'product' => $product, 'item' => $result]
            );

            $referer = $session->getBeforeWishlistUrl();
            if ($referer) {
                $session->setBeforeWishlistUrl(null);
            } else {
                $referer = $this->_redirect->getRefererUrl();
            }

            $this->_objectManager->get(\Magento\Wishlist\Helper\Data::class)->calculate();

            $this->messageManager->addComplexSuccessMessage(
                'addProductSuccessMessage',
                [
                    'product_name' => $product->getName(),
                    'referer' => $referer
                ]
            );
        } catch (\Magento\Framework\Exception\LocalizedException $e) {
            $this->messageManager->addErrorMessage(
                __('We can\'t add the item to Wish List right now: %1.', $e->getMessage())
            );
        } catch (\Exception $e) {
            $this->messageManager->addExceptionMessage(
                $e,
                __('We can\'t add the item to Wish List right now.')
            );
        }

        $resultRedirect->setUrl($this->_redirect->getRefererUrl());
        return $resultRedirect;
    }
}

Remove items text in wishlist top links

It can be done in several ways.

– you can use a translation file. Like app/design/frontend/Magento/luma/i18n/en_US.csv

"%1 items","%1",module,Magento_Wishlist

– you can override create the counter function in Vendor/Module/CustomerData/Wishlist.php

/**
* Create button label based on wishlist item quantity
*
* @param int $count
* @return \Magento\Framework\Phrase|null
*/
protected function createCounter($count)
{
    return $count;
}

– you can update the link template ( by default it is view/frontend/templates/link.phtml ) and change

<span data-bind="text: wishlist().counter" class="counter qty"></span>

to

<span data-bind="text: wishlist().counter.replace(/[^0-9]+/g, '')" class="counter qty"></span>

Work with wishlist items in javascript

You might want to get a wishlist items array in the frontend. For example, mark products already on the customer’s wishlist. It can be done with the help of a customer-data object. customer-data updated via ajax, so it might not have the wishlist information at the initialization. Luckily customer data use observable knockout functionality, so we can subscribe to a data update events.

The sample below use the wishlist items array to add “selected” class to wishlist button. You can use it to decorate button.

– create wishlist_items.js

Vendor/Module/view/frontend/web/js/wishlist_items.js

define([
    'jquery',
    'uiComponent',
    'Magento_Customer/js/customer-data', 
    'domReady'
], function ($, Component, customerData) {
    'use strict';
 
    return Component.extend({
        /** @inheritdoc */
        initialize: function () {
            var _this = this;
		
            this._super();
		
            this.wishlist = customerData.get('wishlist');
            this.wishlist.subscribe(function(newValue) {
                _this.decorateItems();
            });
 
            _this.decorateItems();
        },
		
        decorateItems: function() {
                var items = this.wishlist().items;
		
                if (typeof items === 'undefined' || !items.length) return;
		
                $('a.action.towishlist').each(function(){
                        var data = $(this).data('post'),
                            i;
	
                        for (i = 0; i < items.length; i++) {
                            if (data.data.product === items[i].product_id) {
                                $(this).addClass('selected');
                            }
                        }
                    });
                }
    });
});

 add initialization code to your wishlist template

<script type="text/x-magento-init">
    {
        "*": {
            "Magento_Ui/js/core/app": {
                "components": {
                    "wishlistItems": {
                        "component": "Vendor_Module/js/wishlist_items"
                    }
                }
            }
        }
    }
</script>

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.