Tag: magento

  • Magento can edit order address since 1.5

    Magento 1.5 以后就允许修改订单地址了,Plieninger_Editable module 就没必要存在了,留着它反而会出错。

    当年想找一个修改订单地址的方案,就找到了 Plieninger_Editable,一用就用了一年。虽然一直不满意它的界面,一直想自己写一个,但一直忙于其他事务。现在跟它说 bye bye,还是很感谢它的。

  • Change Magento configurable product to take associated products tax class

    Where and how to change the code?

    At first, I thought overriding Mage_Catalog_Model_Product_Type_Configurable::getOrderOptions().
    Original code

    $options['product_calculations'] = self::CALCULATE_PARENT;
    

    change to

    $options['product_calculations'] = self::CALCULATE_CHILD;
    

    However, it does not work.

    Then I tried to observe the event tax_rate_data_fetch and modify the rateRequest object. But inside rateRequest there is no reference to quoteItem. Only product tax_class_id is there. In the observer class, I do not know when to modify it without reference to quoteItem.

    At last, I had to modify the code in class Mage_Tax_Model_Sales_Total_Quote_Tax. There are several places to change depends on System Configuration. Change where is appropriate.
    Original code

    $taxRateRequest->setProductClassId($item->getProduct()->getTaxClassId());
    

    change to

    if ($item->getProductType() == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) {
    	$child = current($item->getChildren());
    	$taxRateRequest->setProductClassId($child->getProduct()->getTaxClassId());
    }
    else {
    	$taxRateRequest->setProductClassId($item->getProduct()->getTaxClassId());
    }
    

    It is not a neat approach. Let me know if you have a better idea.

  • I report very first bug to Magento

    Magento 里还是有不少 bugs,我能看出来的就不少。可是我一直懒于 report bug,总觉得我都能发现的 bug,大把有人发现。

    今天心血来潮,大概受“莫以善小而不为”驱使,平生第一次 report bug to Magento。事关 js/mage/adminhtml/product.js 文件里第406 行(Magento 1.5.0.1), 有个笔误,把 readonly 写成了redonly。Associated Products tab of Configurable Products 受此影响,本应只读模式的文本框仍可输入数据。

    非常小的错误。

    今后我把我的发现记载下来。

  • Reinstate thumbnails in jQuery UI theme switcher

    You might have noticed, some tools from jQuery are not fully functional recently. That could be caused by jQuery disabling hotlinks. jQuery UI theme switcher is affected. I call it a bug because jQuery team did not make necessary arrangement before enforcement of hotlink policy.

    Nevertheless, how to reinstate thumbnails in jQuery UI theme switcher while waiting for jQuery team to release a hotlink compatible theme switcher? Easy, with my code – Themeswitcher Launcher.

    
    jQuery(function($){
     $('body').prepend('<div id="msdk-themeswitcher"></div>');
     $('#msdk-themeswitcher').themeswitcher();
     var srcStart = "http://jqueryui.com/themeroller/images/";
     $('img[src^="http://jqueryui.com/themeroller/images/"]').each(
     function() {
     this.src = this.src.replace(srcStart,
     "http://static.jquery.com/ui/themeroller/images/");
     });
    });
    
    

    Themeswitcher Launcher just does a simple job: replacing images source in theme switcher to another source static.jquery.com, which still allow hotlinking. You can replace with your domain if you host these images.

    To save your time, I packaged jQuery UI theme switcher with my Themeswitcher Launcher. Please note I changed jQuery UI theme switcher slightly because I need it for Magento sites. I put function themeswitcher() into jQuery namespace to be standard jQuery plugin, so it can be working with javascript prototype framework.

    Download msdk-themeswitcher-launcher.js.tar.gz

    For those who are interested in my Magento modules: jQuery UI theme switcher and my Themeswitcher Launcher are integrated into my Msdk (Magento SDK) module – it is just an advertisement.

  • 一才难求

    有志开发网店的好手、生手请留言。工作地杭州。

  • Reinstate Magento order status after upgrade

    Recently I upgraded a Magento store from 1.4.0.1 to 1.5.0.1.

    Magento has changed order tables from key-value type to flat structure in 1.4.1.0, which caused a big problem for my upgrade – all orders lost their status and state value.

    I have not discovered what exact reason made it happen, but I know it is my store specific, because I have other stores successfully upgraded from 1.3 to 1.5.0.1 without any problems.

    Just in case you had the same issue, you can run this mysql query code to reinstate Magento order status(and state as well).

    
    UPDATE magento_sales_flat_order AS o
    INNER JOIN (SELECT s1.parent_id, s1.status, c.state
     FROM magento_sales_flat_order_status_history s1
     JOIN (
     SELECT parent_id, MAX(entity_id) AS entity_id
     FROM magento_sales_flat_order_status_history
     GROUP BY parent_id) AS s2
     ON s1.parent_id = s2.parent_id AND s1.entity_id = s2.entity_id
     LEFT JOIN magento_sales_order_status_state AS c
     ON s1.status = c.status
    ) as s3
    ON o.entity_id = s3.parent_id, magento_sales_flat_order_grid AS g
    SET o.status = s3.status, o.state = s3.state, g.status = s3.status
    WHERE g.entity_id = s3.parent_id;
    
    
  • Activate Magento ajax loading graphic using jQuery

    I extend Magento js using jQuery.
    I need ajax loading mask and grahpic for jQuery ajax request.
    I want to achieve consistent look and feel.
    I want to activate Magento ajax loading graphic initially used in prototype using jQuery.

    Although prototype register global event handlers for ajax create and complete events, the handlers will not fire by jQuery ajax request. For jQuery to activate ajax loading graphic, I manually fire the onCreate event in jQuery function.

    var r = {options:{loadArea:''}};
    varienLoaderHandler.handler.onCreate(r);
    

    to deactivate

    varienLoaderHandler.handler.onComplete();
    

    Let me know if you know a better way to tie jQuery and prototype together.

  • Magento Cush module is about to release

    Long long time ago, I installed Customshippingrate module, but never made it work on my site. The module sits on the disk but disabled. Recently I took some trouble and about three days developing my own module Cush for admin panel users to charge special shipping price when creating an order.

    Cush module does not override any Magento classes so it is virtually 100% compatible with other modules. Neither does Cush module override any Magento templates so basically it reuses Magento native interface. Cush is not a shipping method so it can work with any Magento shipping methods or 3rd party shipping methods.

    Cush module injects customisation logic by javascript. What it actually customise are values in magento_sales_flat_quote_shipping_rate where is pool of shipping quotes. Values customised belong to an individual quote so the customisation hits its point.

    When writing Cush module, I found a defect in Magento own code app/design/adminhtml/default/default/template/sales/order/create/shipping/method/form.phtml.

    
    echo $this->getCarrierName($_rate->getCarrier());
    
    

    The above code reads value from configuration and shows it as carrier title. If I was not injecting shipping method customisation logic, I would not realise it is a defect. Carrier title value, like method title and shipping rate, if read from magento_sales_flat_quote_shipping_rate using $_rate->getCarrierTitle(), will make more sense. Values from configuration will not reflect carrier title changes done by Cush. I respect Magento own templates, especially adminhtml templates. Instead of overriding this template, I wrote some additional javascript in Cush module to correct carrier title. I stick to my green principle although it costs much more time developing.

    Upon installing Cush module, I removed all files of Customshippingrate module. A small accident happened – can not create shipment. It turns out during creating shipment, Magento is gathering all config paths start with “carriers/” and working out all carriers between two slashes. It is a bad logic, or I can call it a bug. It does not check whether this carrier exists or is active. So, very bad.

    Just add to my Magento caveats: after removing a shipping method, remove all entries of “carriers/CARRIER_CODE/*” in magento_core_config_data.

  • Magento datetime picker is not picking up time value

    Magento 用了 dynarch.com 的 calendar 1.0 javascript,有个 bug:无法得到 time 的值。

    dynarch.com calendar 已经是 2.0 了,单独使用的话,能显示和修改 time 的值。

    我暂时没想好该怎么办:我倾向于用 jQuery 去增强 Magento(prototype 我也用不好,其他的就更不要说了),但 jQuery 现下的版本只有 datepicker,官方还没有 datetimepicker。试过很多第三方 jQuery datetimepicker plugin,没觉得某一款有 jQuery 的神韵。

  • Controller override and request rewrite in Magento

    There are three ways to override controller in Magento. They fit for various purposes.

    The first and easiest way can be used to route the request to more than one module. When a request arrives on a frontName, it usually is rounted to a module. For example, /cms/page/view is routed to cms module page controller view action. If I have developed a cms related module called “faq” with a brand new controller “QuestionController”, but I want it share the same cms frontName with cms module, i.e., I want /cms/question/any_action be routed to faq module.

    It is very easy to achieve by a config.xml like the following:

    <config>
    	<frontend>
    		<routers>
    			<cms>
    				<args>
    					<modules>
    						<any_name>MyNamespace_Faq</any_name>
    					</modules>
    				</args>
    			</cms>
    		</routers>
    	</frontend>
    </config>
    

    Strictly speaking, no overriding in above example because it only activates a brand new controller. In a truly overriding example, if I want PageController of faq module override PageController in cms module, I can add before=”Mage_Cms” to make sure PageController of faq module supersede the same name controller in cms module. The complete configuration is shown below:

    <config>
    	<frontend>
    		<routers>
    			<cms>
    				<args>
    					<modules>
    						<any_name before="Mage_Cms">MyNamespace_Faq</any_name>
    					</modules>
    				</args>
    			</cms>
    		</routers>
    	</frontend>
    </config>
    

    The second way can be used to mass override controllers.

    <config>
    	<global>
    		<rewrite>
    			<any_name>
    				<from><![CDATA[#^/cms/#]]></from>
    				<to>/faq/</to>
    				<complete></complete>
    			</any_name>
    		</rewrite>
    	</global>
    </config>
    

    The above configuration makes all controllers in faq module override same name controllers in cms module. In class Mage_Core_Controller_Varien_Front, there is

    $pathInfo = preg_replace($from, $to, $request->getPathInfo());
    

    doing path info string replacement based on regular expression. And because it is based on regular expression, I can do mass replacement at a time.

    The tag flags whether requested path info should be turned into new module path info. In other words, when the request arrives on /cms/page/view, it is rewritten to /faq/page/view. Without tag, the action layout handle is cms_page_view; with tag, the action layout handle is faq_page_view.

    I can use this method to route the request to a brand new controller, i.e.

    <config>
    	<global>
    		<rewrite>
    			<any_name>
    				<from><![CDATA[#^/cms/question/#]]></from>
    				<to>/faq/question/</to>
    				<complete></complete>
    			</any_name>
    		</rewrite>
    	</global>
    </config>
    

    Note that cms module does not have question controller, but the above configuration will not cause any error.

    The third way can be used to override individual actions.

    <config>
    	<global>
    		<routers>
    			<cms>
    				<rewrite>
    					<page>
    						<to>faq/question</to>
    						<override_actions>true</override_actions>
    						<actions>
    							<view_action><to>new_module/new_controller/new_action</view_action>
    						</actions>
    					</page>
    				</rewrite>
    			</cms>
    		</routers>
    	</global>
    </config>
    

    This method is documented in class Mage_Core_Controller_Varien_Action.

    * This will override:
    * 1. cms_module/page_controller/view_action to new_module/new_controller/new_action
    * 2. all other actions of cms_module/page_controller to faq_module/question_module

    It is very handy to precisely control the request rewrite to action level, but it can not route to a brand new controller. The following code will cause an error.

    <config>
    	<global>
    		<routers>
    			<cms>
    				<rewrite>
    					<question><!-- Error: cms module does not have question controller -->
    						<to>faq/question</to>
    						<override_actions>true</override_actions>
    						<actions>
    							<view_action><to>new_module/new_controller/new_action</view_action>
    						</actions>
    					</question>
    				</rewrite>
    			</cms>
    		</routers>
    	</global>
    </config>