且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Magento多个网站共享购物车

更新时间:2023-11-30 12:03:16

在我找到了答案之后,偶然发现了自2009年以来一直没有确定解决方案的相同问题,我终于不得不研究我自己的代码-瞧,我有一个可行的解决方案.这里是想要使用

After I searched for an answer to this and stumbled across the same question being asked since 2009 without a definite solution, I finally had to look into the deep end of the code myself - and voila, I have a working solution. Here a detailed guide for anyone who wants to set up Magento with

  • 不仅会显示多种货币,而且会实际以所选货币收费
  • 在整个网站上分享购物车,而不仅仅是在商店里分享

这种组合的主要问题在于,使用默认的Magento结构,您只能做一个或另一个,而不能将两者结合在一起.

The main problem with this combination is that with the default Magento structure you can only ever do one or the other, not the two combined.

因此,让我们先将Magento设置为使用多种货币.

So lets set Magento up for multiple currencies first.

  • 为每种货币创建一个具有相应商店和商店视图的网站(不仅仅是商店视图,完整的网站)
  • 将系统-配置-每个网站的币种设置为相应的币种.所有三个条目基本货币",默认显示货币"和允许的货币"都应设置为仅一种且相同的货币.
  • 返回默认的整体配置范围,并将系统-配置-目录---将目录价格范围定价为网站"
  • 您还可以在系统-管理货币汇率"中定义您的货币汇率
  • 为每个网站范围设置适当的系统-配置-网络-安全和不安全基本URL.
  • 在.htaccess文件中,将其添加到顶部(替换相应的网站域和设置网站时输入的代码(此处 http://website-us.local ,带有base_us和 http://website-uk.local (代码为base_uk)

  • Create a website for each currency with a corresponding store and store view (not just store views, complete websites)
  • Set System - Configuration - Currency Setup per website to the respective currency. All three entries Base Currecny, Default Display Currency and Allowed currencies should be set to just one and the same currency.
  • Go back to the default overall config scope and set System - Configuration - Catalog - - - Price the Catalog Price Scope to "Website"
  • You can also define you currency rates in System - Manage Currency Rates
  • For each website scope set the appropriate System - Configuration - Web - Secure and Unsecure base url.
  • In your .htaccess file add this at the top (replace the appropriate website domains and code you entered when setting up the websites (here http://website-us.local with base_us and http://website-uk.local with code base_uk)

SetEnvIf主机网站-us.local MAGE_RUN_CODE = base_us SetEnvIf主机website-us.local MAGE_RUN_TYPE = website SetEnvIf主机^ website-us.local MAGE_RUN_CODE = base_us SetEnvIf主机^ website-us.local MAGE_RUN_TYPE = website

SetEnvIf Host website-us.local MAGE_RUN_CODE=base_us SetEnvIf Host website-us.local MAGE_RUN_TYPE=website SetEnvIf Host ^website-us.local MAGE_RUN_CODE=base_us SetEnvIf Host ^website-us.local MAGE_RUN_TYPE=website

SetEnvIf主机网站-uk.local MAGE_RUN_CODE = base_uk SetEnvIf主机website-uk.local MAGE_RUN_TYPE = website SetEnvIf主机^ website-uk.local MAGE_RUN_CODE = base_uk SetEnvIf主机^ website-uk.local MAGE_RUN_TYPE = website

SetEnvIf Host website-uk.local MAGE_RUN_CODE=base_uk SetEnvIf Host website-uk.local MAGE_RUN_TYPE=website SetEnvIf Host ^website-uk.local MAGE_RUN_CODE=base_uk SetEnvIf Host ^website-uk.local MAGE_RUN_TYPE=website

在Mage/Core/Model/Store中覆盖方法convertPrice并更改方法convertPrice-这样可以确保始终以正确的转换和正确的货币符号显示价格.

Overwrite the method convertPrice in Mage/Core/Model/Store and change the method convertPrice - this will ensure that the prices are always displayed in the correct conversion AND the correct currency sign.

/**
 * Convert price from default currency to current currency
 *
 * @param   double $price
 * @param   boolean $format             Format price to currency format
 * @param   boolean $includeContainer   Enclose into <span class="price"><span>
 * @return  double
 */
public function convertPrice($price, $format = false, $includeContainer = true)
{
    $categories = Mage::getModel('catalog/category')->getCollection();
    $categ_ids=$categories->getAllIds();
    $baseCurrencyCode = Mage::app()->getBaseCurrencyCode();
    $allowedCurrencies = Mage::getModel('directory/currency')->getConfigAllowCurrencies();
    $currencyRates = Mage::getModel('directory/currency')->getCurrencyRates($baseCurrencyCode,array_values($allowedCurrencies));

    if ($this->getCurrentCurrency() && $this->getBaseCurrency()) {
        $value = $this->getBaseCurrency()->convert($price, $this->getCurrentCurrency());
    } else {
        $value = $price;
    }


    if($this->getCurrentCurrencyCode() != $baseCurrencyCode)
    {
        $value = $price * $currencyRates[$this->getCurrentCurrencyCode()];
    }
    if ($this->getCurrentCurrency() && $format) {
        $value = $this->formatPrice($value, $includeContainer);
    }
    return $value;
}

}

但是我们当然也希望在我们刚刚建立的网站上共享用户数据,购物车和登录信息.

But of course we also want to share the users data, cart and login throughout the websites we just set up.

  • 在默认配置范围设置中,系统-配置-客户配置-帐户共享选项-将客户帐户共享到全局

  • While in default config scope set System - Configuration - Customer Configuration - Account Sharing Options - Share Customer Accounts to Global

覆盖magento/app/code/core/Mage/Checkout/Model/Session.php并替换此方法:

Overwrite magento/app/code/core/Mage/Checkout/Model/Session.php and replace this method:

受保护的函数_getQuoteIdKey() { 返回'quote_id'; //返回'quote_id_'. $ websites [1]; }

protected function _getQuoteIdKey() { return 'quote_id'; //return 'quote_id_' . $websites[1]; }

覆盖magento/app/code/core/Mage/Sales/Model/Quote.php并将方法getSharedStoreIds更改为:

Overwrite magento/app/code/core/Mage/Sales/Model/Quote.php and change the method getSharedStoreIds to:

公共函数getSharedStoreIds() { $ ids = $ this-> _ getData('shared_store_ids'); 如果(is_null($ ids)||!is_array($ ids)){ $ arrStoreIds = array(); foreach(Mage :: getModel('core/website')-> getCollection()as $ website) { $ arrStoreIds = array_merge($ arrStoreIds,$ website-> getStoreIds()); } 返回$ arrStoreIds; /*如果($ website = $ this-> getWebsite()){ 返回$ website-> getStoreIds(); } var_dump($ this-> getStore()-> getWebsite()-> getStoreIds()); exit(); 返回$ this-> getStore()-> getWebsite()-> getStoreIds(); */ } 返回$ ids; }

public function getSharedStoreIds() { $ids = $this->_getData('shared_store_ids'); if (is_null($ids) || !is_array($ids)) { $arrStoreIds = array(); foreach(Mage::getModel('core/website')->getCollection() as $website) { $arrStoreIds = array_merge($arrStoreIds,$website->getStoreIds()); } return $arrStoreIds; /*if ($website = $this->getWebsite()) { return $website->getStoreIds(); } var_dump($this->getStore()->getWebsite()->getStoreIds());exit(); return $this->getStore()->getWebsite()->getStoreIds(); */ } return $ids; }

覆盖magento/app/code/core/Mage/Customers/Model/Customer.php并再次将方法getSharedWebsiteIds()更改为:

Overwrite magento/app/code/core/Mage/Customers/Model/Customer.php and change again the method getSharedWebsiteIds() to:

公共函数getSharedWebsiteIds(){ $ ids = $ this-> _ getData('shared_website_ids'); 如果($ ids === null){ $ ids = array(); 如果((bool)$ this-> getSharingConfig()-> isWebsiteScope()){ $ ids [] = $ this-> getWebsiteId(); } 别的 { foreach(Mage :: app()-> getWebsites()as $ website){ $ ids [] = $ website-> getId(); } } $ this-> setData('shared_website_ids',$ ids); } 返回$ ids; }

public function getSharedWebsiteIds() { $ids = $this->_getData('shared_website_ids'); if ($ids === null) { $ids = array(); if ((bool)$this->getSharingConfig()->isWebsiteScope()) { $ids[] = $this->getWebsiteId(); } else { foreach (Mage::app()->getWebsites() as $website) { $ids[] = $website->getId(); } } $this->setData('shared_website_ids', $ids); } return $ids; }

如果使用心愿单选项,则应对magento/app/code/core/Mage/Wishlist/Model/Wishlist.php中的方法执行相同的操作,并更改getSharedWebsiteIds,以便它不仅从当前网站,但所有网站都

If you use the wishlist option you should do the same for the method in magento/app/code/core/Mage/Wishlist/Model/Wishlist.php and change getSharedWebsiteIds so it not only loads the store ids from the current website but from all of them

现在,我们还必须在前端商店上实现货币(网站)切换,并在两者之间传递正确的会话ID,以便magento知道要寻找的商店.我在这里模仿了货币开关,并将以下下拉菜单添加到了

Now we also have to implement a currency (website) switch on the frontend stores and pass the correct session ids inbetween so magento knows what stores to look for. I imitated the currency switch here and added the following dropdown to

magento/app/design/frontend/default/yourtheme/template/directory/currency.phtml

magento/app/design/frontend/default/yourtheme/template/directory/currency.phtml

这将加载所有网站并将当前会话ID用作查询字符串,因此magento可以在任何域上知道要使用哪个会话.

This loads all websites and applies the current Session Id as a query string so magento knows on any domain which session to use.

<?php
/**
 * Currency switcher
 *
 * @see Mage_Directory_Block_Currency
 */
?>
<div class="top-currency">
<?php
$websites = Mage::getModel('core/website')->getCollection();
$this_session_id = Mage::getSingleton('core/session', array('name' => 'frontend'))->getSessionId();
?>
<select id="website-changer" onChange="document.location=this.options[selectedIndex].value">
<?php
foreach($websites as $website):
    $default_store = $website->getDefaultStore();
    $website_currency = $default_store->getBaseCurrency()->getCurrencyCode();
    $url_obj = new Mage_Core_Model_Url();
    $default_store_path = $url_obj->getBaseUrl(array('_store'=> $default_store->getCode()));
    $default_store_path .= Mage::getSingleton('core/url')->escape(ltrim(Mage::app()->getRequest()->getRequestString(), '/'));
    $default_store_path = explode('?', $default_store_path);
    $default_store_path = $default_store_path[0] . '?SID=' . $this_session_id;

?>
    <option <? if(strstr($default_store_path,Mage::getBaseUrl())):?>selected="selected"<?endif; ?> value="<?=$default_store_path ?>">
    <?=$website_currency?>
    </option>
<?endforeach;?>
</select>
</div>

此查询字符串仅在您第一次切换时应用,但magento会记住存储在cookie中的会话ID.

This query string will only be applied the first time you switch but magento will remember the session id after that stored in a cookie.

  • 为了使其正常工作,请覆盖

magento/app/code/core/Mage/Core/Model/Session/Abstract/Varien.php

magento/app/code/core/Mage/Core/Model/Session/Abstract/Varien.php

替换此

// potential custom logic for session id (ex. switching between hosts)
$this->setSessionId();

使用

// potential custom logic for session id (ex. switching between hosts)
/* Amend to ensure shopping carts are shared between websites */
if (isset($_COOKIE['lastsid']))
{
  session_decode(file_get_contents(Mage::getBaseDir('session').'/sess_'.$_COOKIE['lastsid']));
            setcookie ('lastsid', '', time() - 3600);
        }

        if (isset($_GET['SID']))
        {
            $this->setSessionId($_GET['SID']);
            session_decode(file_get_contents(Mage::getBaseDir('session') . '/sess_' . $_GET['SID']));
            setcookie('lastsid', $_GET['SID']);
            $_COOKIE['lastsid'] = $_GET['SID'];
        }
        else
        {
            $this->setSessionId();
        }
        /* Amend end */

现在这应该显示多种货币,在多个网站上以及在此共享登录名和购物车之上以多种货币收费.该解决方案是我在互联网上发现的知识的集合,结合了我自己发现的一些点点滴滴,因此,感谢提供建议的任何人!

This should now display multiple currencies, charge in multiple currencies across mutliple websites and on top of this share logins and shopping carts. This solution is a collection of knowledge I found on the interwebs combined with a few bits and pieces I figured out myself, so thanks for anyone who gave advice!