6

I am developing an extension where is a requirement of add to wishlist without logging into customer account. can anyone help me out in this?

what i think two things can be done here -

1- we can override core function and disable check for customer session.

2- Find an event in magento which can be listened before checking customer session while adding product to wishlist so that i can do my work before it checks whether customer is logged in or not. Any suggestions will be highly appreciated.

Let me know if i am not clear.

  • How do you plan to link the "wishlist item" to a customer record, if a customer is not log in? – Renon Stewart Aug 18 '14 at 16:53
  • i dont need customer id. I just need to send product info somewhere every time when a product is added to wishlist. That's why i looking for an event which can be listened before checking whether customer is login or not. i would not mind if magento redirects to customer login page when my work is done. – vibhu Aug 18 '14 at 17:00
  • Should a customer be able to retrieve their wishlist? – Renon Stewart Aug 18 '14 at 17:03
  • Yes. normal magento flow should not be broken. – vibhu Aug 18 '14 at 17:04
  • So how can a customer retrieve their wishlist if there is not linking identifier (customer_id)? – Renon Stewart Aug 18 '14 at 17:06
3

So if you need, based on your comment "just need to send product info somewhere every time when a product is added to wishlist."

  1. Add an javascript listener for Click event on the wish list link.

  2. In the listener send ajax request to your module (with the product info as a param) where you can record everything you need in the database

  • it sounds like i have to use html used for that add to wishlist link. Can you guide me a little how can i do this independently for my module? – vibhu Aug 19 '14 at 7:32
  • You can add onclick action in the link code or, better, add it on page load observer by the link id to not modify the template – Amasty Aug 19 '14 at 10:17
  • to catch onclick event I would be needed id of wishlist link and that can be different in different themes. – vibhu Aug 19 '14 at 10:30
  • Add the wishlist css path as a extension configuration option. – Amasty Aug 19 '14 at 13:35
  • what do you mean by 'wishlist css path' here? – vibhu Aug 20 '14 at 11:54
2

To get product info everytime someone press add to wishlist

Because preDispatch() is called before addAction() therefore the page will be redirected to customer login page if a customer is not login.

public function preDispatch()
{
    parent::preDispatch();

    if (!$this->_skipAuthentication && !Mage::getSingleton('customer/session')->authenticate($this)) {
     ....

The only way I can think of is to Overriding addAction() in Mage_Wishlist_IndexController see Magento: Overriding Core Files (Blocks, Models, Resources, Controllers)

Add to wishlist without customer login This is not really possible using wishlist because how can you retrieve a customer wishlist if there is nothing linking that customer to that item.

Also if you take a look at wishlist table customer_id is unique and can be null

CREATE TABLE `wishlist` (
  `wishlist_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Wishlist ID',
  `customer_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Customer ID',
  `shared` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Sharing flag (0 or 1)',
  `sharing_code` varchar(32) DEFAULT NULL COMMENT 'Sharing encrypted code',
  `updated_at` timestamp NULL DEFAULT NULL COMMENT 'Last updated date',
  PRIMARY KEY (`wishlist_id`),
  UNIQUE KEY `UNQ_WISHLIST_CUSTOMER_ID` (`customer_id`),
  KEY `IDX_WISHLIST_SHARED` (`shared`),
  CONSTRAINT `FK_WISHLIST_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID` FOREIGN KEY (`customer_id`) REFERENCES `customer_entity` (`entity_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=61 DEFAULT CHARSET=utf8 COMMENT='Wishlist main Table';
  • You are right. As you said preDispatch() is called before addAction(), there is a way to access this predispatch using controller_action_predispatch_wishlist_index_add and i am successfully able to use this but in my case there is another module which has already overrided add to wishlist to make it call by ajax. So i am not able to listen controller_action_predispatch_wishlist_index_add in this case. – vibhu Aug 18 '14 at 17:54
  • You could (1) rewrite that module or (2) look to see if that module predispatch a controller_action_predispatch_* – Renon Stewart Aug 18 '14 at 18:25
2

Here is a working solution.

app/code/local/Foo/Wishlist/etc/config.xml:

<?xml version="1.0"?>
<config>
    <modules>
        <Foo_Wishlist>
            <version>1.0.0</version>
        </Foo_Wishlist>
    </modules>
    <global>
        <models>
            <wishlist>
                <rewrite>
                    <wishlist>Foo_Wishlist_Model_Wishlist</wishlist>
                </rewrite>
            </wishlist>
        </models>
        <resources>
            <foo_wishlist_setup>
                <setup>
                    <module>Foo_Wishlist</module>
                </setup>
            </foo_wishlist_setup>
        </resources>
    </global>
    <frontend>
        <routers>
            <wishlist>
                <args>
                    <modules>
                        <foo_wishlist before="Mage_Wishlist">Foo_Wishlist</foo_wishlist>
                    </modules>
                </args>
            </wishlist>
        </routers>
    </frontend>
</config>

As you see we will need a setup script, Mage_Wishlist_Model_Wishlist override and wishlist controller override.

Setup script will do the following modifications to wishlist table:

  • add a cookie field where random hash string identifying a guest card will be stored
  • drop foreign key binding wishlist with customer entity
  • make wishlist customer_id field non-unique
  • make wishlist customer_id field nullable

app/code/local/Foo/Wishlist/data/foo_wishlist_setup/data-install-1.0.0.php:

<?php
/**
 * @var Mage_Core_Model_Resource_Setup $this
 */

$this->startSetup();

$wishlistTable = $this->getTable('wishlist/wishlist');

$this->getConnection()->addColumn($wishlistTable, 'cookie', 'VARCHAR(255)');
$this->getConnection()->dropForeignKey($wishlistTable, 'FK_WISHLIST_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID');
$this->getConnection()->dropIndex($wishlistTable, 'UNQ_WISHLIST_CUSTOMER_ID');
$this->getConnection()->modifyColumn($wishlistTable, 'customer_id', 'INT(10) UNSIGNED NULL default NULL');

$this->endSetup();

Controller override will command to skip customer authentication and then upon retrieving a wishlist check if visitor is a guest and if so load a wishlist using a new method loadForGuest introduced in further override, otherwise fallback to standard routine.

app/code/local/Foo/Wishlist/controllers/IndexController.php:

require_once Mage::getModuleDir('controllers', 'Mage_Wishlist') . DS . 'IndexController.php';

class Foo_Wishlist_IndexController extends Mage_Wishlist_IndexController
{
    protected $_skipAuthentication = true;

    /**
     * @return Mage_Wishlist_Model_Wishlist|bool
     */
    final protected function _getWishlist($wishlistId = null)
    {
        $wishlistFromRegistry = Mage::registry('wishlist');

        if ($wishlistFromRegistry) {
            return $wishlistFromRegistry;
        }

        if ($this->isGuest()) {
            /* @var Foo_Wishlist_Model_Wishlist $wishlistModel */
            $wishlistModel = Mage::getModel('wishlist/wishlist');
            $wishlist = $wishlistModel->loadForGuest();

            Mage::register('wishlist', $wishlist);

            return $wishlist;
        }

        return parent::_getWishlist($wishlistId);
    }

    private function isGuest(): bool
    {
        return null === $this->getCustomerSession()->getCustomerId();
    }

    private function getCustomerSession(): Mage_Customer_Model_Session
    {
        /** @var Mage_Customer_Model_Session $customerSession */
        $customerSession = Mage::getSingleton('customer/session');

        return $customerSession;
    }
}

Finally in wishlist model override loadForGuest method is implemented which either loads wishlist from a hash stored in a user browser cookie or creates a new wishlist and then upon save stores a newly created hash in a cookie.

app/code/local/Foo/Wishlist/Model/Wishlist.php:

class Foo_Wishlist_Model_Wishlist extends Mage_Wishlist_Model_Wishlist
{
    private $hashCookieName = 'magento_guest_wishlist';

    public function loadForGuest(): Mage_Wishlist_Model_Wishlist
    {
        $this->load($this->getWishlistCookieHash(), 'cookie');

        if (null === $this->getId()) {
            $this->setData('cookie', $this->createWishlistCookieHash());
            $this->save();
        }

        return $this;
    }

    final protected function _afterSave(): Mage_Wishlist_Model_Wishlist
    {
        if ($this->isGuest()) {
            $this->getCookieModel()->set($this->hashCookieName, $this->getData('cookie'));
        }

        return parent::_afterSave();
    }

    /**
     * @return string|null
     */
    private function getWishlistCookieHash()
    {
        return $this->getCookieModel()->get($this->hashCookieName);
    }

    private function createWishlistCookieHash(): string
    {
        /** @var Mage_Core_Helper_Data $coreHelper */
        $coreHelper = Mage::helper('core');

        return $coreHelper->uniqHash();
    }

    private function getCookieModel(): Mage_Core_Model_Cookie
    {
        /** @var Mage_Core_Model_Cookie $cookie */
        $cookie = Mage::getSingleton('core/cookie');

        return $cookie;
    }

    private function isGuest(): bool
    {
        return $this->getCustomerId() === null;
    }
}
  • I don't think it's a good Idea to drop Magento core table keys and modify columns... – Stepan Furman Mar 2 at 16:15

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.