对于你们中的某些人,这可能是个惊喜,但是Magento不支持在前台禁止Magento方法但在后台保留。你也许可以做些调整配置来达到效果,但那不是100%正确的。虽然Magento支持“global/website/store”设置,在全球和网站级别,运输方法被打开或者关闭。在商店级别,你可以简单的编辑运输方式的title和其它东西,但你不能打开/关闭运输方式。
现在,想像下你Magento系统里只有一个网站,如果你在后台“Sales > Orders”点击“Create New Order”按钮。下面你将看到“please select a customer”来选择你想要创建订单的客户。但当你的Magento系统中有两个或更多网站时,你在后台“Sales > Orders”点击“Create New Order”按钮,下一个出来的就是“please select a website” ,之后才会看到“please select a customer”。这意味着Magento使用默认的网站或者你选择的网站来创建用户订单。无论哪种方式,它都从网站读取配置和运输数据。这意味着这种设置没办法在后台只显示某某运输方式……
我们如何绕过这点?简单,只需要重写Mage_Shipping_Model_Config和Mage_Sales_Model_Quote_Address。注意,这不一定是最好或者最优的方法,但却是一个可行的方法。
app/code/local/Mycompany/Myextension/etc/config.xml
<models>
<shipping>
<rewrite>
<config>Mycompany_Myextension_Model_Shipping_Config</config>
</rewrite>
</shipping>
<sales>
<rewrite>
<quote_address>Mycompany_Myextension_Model_Sales_Quote_Address</quote_address>
</rewrite>
</sales>
</models>
app/code/local/Mycompany/Myextension/Model/Adminhtml/System/Config/Source/Shipping/Methods.php
<?php
class Mycompany_Myextension_Model_Adminhtml_System_Config_Source_Shipping_Methods
{
protected $_options;
public function toOptionArray()
{
$carriers = Mage::getSingleton('shipping/config')->getAllCarriers();
$carriersActive = Mage::getSingleton('shipping/config')->getActiveCarriers();
$carriersActive = array_keys($carriersActive);
if (!$this->_options) {
foreach ($carriers as $carrier) {
$carrierCode = $carrier->getId();
$carrierTitle = Mage::getStoreConfig('carriers/'.$carrierCode.'/title', Mage::app()->getStore()->getId());
$carrierTitle = trim($carrierTitle);
if (empty($carrierTitle)) {
continue;
}
if (in_array($carrierCode, $carriersActive)) {
$carrierTitle = sprintf('%s (currently active)', $carrierTitle);
} else {
$carrierTitle = sprintf('%s (currently inactive)', $carrierTitle);
}
$this->_options[] = array('value'=>$carrierCode, 'label'=>$carrierTitle);
}
}
$options = $this->_options;
array_unshift($options, array('value'=>'', 'label'=> ''));
return $options;
}
}
这个文件被systemxml的“source_model”定义调用
<fields>
<frontend_hidden_methods>
<label>Hide Shipping Methods on Frontend</label>
<comment></comment>
<frontend_type>multiselect</frontend_type>
<source_model>mycompany_myextension/adminhtml_system_config_source_shipping_methods</source_model>
<sort_order>2</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</frontend_hidden_methods>
</fields>
注意!上面的system.xml只是部分的,只用于实际字段的配置定义。
app/code/local/Mycompany/Myextension/Helper/Data.php
<?php
class Mycompany_Myextension_Helper_Data extends Mage_Core_Helper_Abstract
{
const CONFIG_PATH_HIDE_FRONTEND_SHIPPING_METHODS = 'some-path-to-system-xml-field';
public function getHiddenFrontendShippingMethods()
{
$methods = Mage::getStoreConfig(self::CONFIG_PATH_HIDE_FRONTEND_SHIPPING_METHODS);
$methods = explode(',', $methods);
return $methods;
}
}
app/code/local/Mycompany/Myextension/Model/Shipping/Config.php
<?php
class Mycompany_Myextension_Model_Shipping_Config extends Mage_Shipping_Model_Config
{
public function getActiveCarriers($store = null)
{
$carriers = parent::getActiveCarriers($store);
if (Mage::getDesign()->getArea() === Mage_Core_Model_App_Area::AREA_FRONTEND) {
$carriersCodes = array_keys($carriers);
$hiddenShippingMethods = Mage::helper('mycompany_myextension')->getHiddenFrontendShippingMethods();
foreach ($carriersCodes as $carriersCode) {
if (in_array($carriersCode, $hiddenShippingMethods)) {
unset($carriers[$carriersCode]);
}
}
}
return $carriers;
}
}
app/code/local/Mycompany/Myextension/Model/Sales/Quote/Address.php
<?php
class Mycompany_Myextension_Model_Sales_Quote_Address extends Mage_Sales_Model_Quote_Address
{
public function getShippingRatesCollection()
{
parent::getShippingRatesCollection();
$hiddenFrontendShippingMethods = Mage::helper('mycompany_myextension')->getHiddenFrontendShippingMethods();
$removeRates = array();
foreach ($this->_rates as $key => $rate) {
if (in_array($rate->getCarrier(), $hiddenFrontendShippingMethods)) {
$removeRates[] = $key;
}
}
foreach ($removeRates as $key) {
$this->_rates->removeItemByKey($key);
}
return $this->_rates;
}
}
基本上就是这样了。现在你的后台里有了多选框来选择特定的方法在前台隐藏后台保留。记住,运输方式必须是开启的,不要和启用/禁止“hide on frontend”相混淆。