问题描述
我正在建立的Magento网站有两难选择.我有两个分别设有商店的网站,以便为每个网站启用多种货币结帐.因此,通过一个通用的magento安装管理的两个站点(在两个不同的域上)之间的唯一区别是货币显示和结帐货币.到目前为止,一切正常.但是,我试图在站点之间共享结帐会话,以便在站点之间切换时购物车保持不变.我设法将正确的会话ID添加到切换URL,以便每个站点都知道我们要寻找的会话.但是,实际显示购物车的方法似乎并不独立于网站,例如
I have a bit of a dilemma with a Magento website I am building. I have two websites with a store each set up in order to enable multiple currencies checkout for each site. So the only difference between the two sites (on two different domains) that are managed via one common magento installation is the currency display and checkout currency. This is all working fine so far.However I am trying to share the checkout session between the sites so the shopping cart stays the same when switching between the sites. I manage to get the correct session id added to the switching url so each site knows what session we are looking for. However the method that actually displays the shopping cart does not seem to work website independent - for example in
Mage_Checkout_Model_Session
Mage_Checkout_Model_Session
_getQuoteIdKey()->使用当前网站ID检查会话中的报价ID.
_getQuoteIdKey() -> uses the current website id to check for the quote id in the session.
我无法弄清楚什么/如何覆盖此功能,以便每个网站共享完全相同的购物车数据!
And I can not figure out what/how to overwrite this functionality so that each website shares exactly the same shopping cart data!
我的$ _SESSION ['checkout']变量在每个站点上都显示相同,但包含此网站ID的数据对购物车无用: 'quote_id_4'=>字符串'13'(长度= 2)
my $_SESSION['checkout'] variable shows the same on each site but with this website id included the data is no use for the shopping cart: 'quote_id_4' => string '13' (length=2)
有什么想法根本可行吗?
Any ideas whether this is possible at all?
推荐答案
在我找到了答案之后,偶然发现了自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_usSetEnvIf主机website-us.local MAGE_RUN_TYPE = websiteSetEnvIf主机^ website-us.local MAGE_RUN_CODE = base_usSetEnvIf主机^ website-us.local MAGE_RUN_TYPE = website
SetEnvIf Host website-us.local MAGE_RUN_CODE=base_usSetEnvIf Host website-us.local MAGE_RUN_TYPE=websiteSetEnvIf Host ^website-us.local MAGE_RUN_CODE=base_usSetEnvIf Host ^website-us.local MAGE_RUN_TYPE=website
SetEnvIf主机网站-uk.local MAGE_RUN_CODE = base_ukSetEnvIf主机website-uk.local MAGE_RUN_TYPE = websiteSetEnvIf主机^ website-uk.local MAGE_RUN_CODE = base_ukSetEnvIf主机^ website-uk.local MAGE_RUN_TYPE = website
SetEnvIf Host website-uk.local MAGE_RUN_CODE=base_ukSetEnvIf Host website-uk.local MAGE_RUN_TYPE=websiteSetEnvIf Host ^website-uk.local MAGE_RUN_CODE=base_ukSetEnvIf 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!
这篇关于Magento多个网站共享购物车的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!