Tag: magento

  • A support class to pluralise English words in Magento

    我写这个类更多地是为了补习一下英文。顺便说一下,我会逐渐把更多的 support classes 归于 Msdk module,意思是 Magento SDK.

    An ideal way to learn IT and English as a foreign language at a time.

    
    <?php
    class Qian_Mdsk_Helper_Plural extends Mage_Core_Helper_Abstract
    {
    /**
    * auto is a wrapper. it calls another method by language settings
    * @param int $nr
    * @param string $singularWord
    * @return string
    */
    public static function auto($nr, $singularWord) {
    //if english
    return self::english($nr, $singularWord, 's');
    }
    
    public static function english($nr, $singularWord, $pluralSuffix = 's') {
    if (abs($nr) == 1) {
    return "$nr $singularWord";
    }
    
    $no = Mage::helper('corex')->__("No");
    //If a word has more than one form of plural, and if the commonly used form is regular, the word will not be included in this dictionary.
    //e.g. roof => roofs (irregular) or rooves (regular)
    $dictionary = array(
    //sh rule exception
    'fish' => 'fish',
    
    //o rule exception
    'canto' => 'cantos',
    'homo' => 'homos',
    'piano' => 'pianos',
    'portico' => 'porticos',
    'pro' => 'pros',
    'quarto' => 'quartos',
    'kimono' => 'kimonos',
    'zoo' => 'zoos',
    'igloo' => 'igloos',
    'kangaroo' => 'kangaroo',
    'kniazhestvo' => 'kniazhestva',
    
    //x rule exception
    'matrix' => 'matrices',
    'vertex' => 'vertices',
    
    //s rule exception
    'alumnus' => 'alumni',
    'corpus' => 'corpora',
    'focus' => 'foci',
    'genus' => 'genera',
    'prospectus' => 'prospecti',
    'radius' => 'radii',
    'syllabus' => 'syllabi',
    'viscus' => 'viscera',
    'fungus' => 'fungi',
    'terminus' => 'termini',
    'uterus' => 'uteri',
    'Atlas' => 'Atlantes',
    
    'species' => 'species',
    'series' => 'series',
    'blues' => 'blues',
    'axis' => 'axes',
    'testis' => 'testes',
    
    //y rule exception
    'Germany' => 'Germanys',
    'Harry' => 'Harrys',
    
    //f rule exception
    'staff' => 'staff',
    'flagstaff' => 'flagstaffs',
    'proof' => 'proofs',
    
    //other exception
    //singular and plural are identical
    'people' => 'people',
    'deer' => 'deer',
    'moose' => 'moose',
    'sheep' => 'sheep',
    'bison' => 'bison',
    'salmon' => 'salmon',
    'pike' => 'pike',
    'trout' => 'trout',
    'swine' => 'swine',
    'aircraft' => 'aircraft',
    'head' => 'head',
    'stone' => 'stone',
    'benshi' => 'benshi',
    'otaku' => 'otaku',
    'samurai' => 'samurai',
    'Māori' => 'Māori',
    'marae' => 'marae',
    'waka' => 'waka',
    
    //very irregular exception
    'child' => 'children',
    
    'alumna' => 'alumnae',
    
    'mouse' => 'mice',
    'louse' => 'lice',
    
    'tooth' => 'teeth',
    'foot' => 'feet',
    'goose' => 'geese',
    
    'automaton' => 'automata',
    'criterion' => 'criteria',
    'phenomenon' => 'phenomena',
    'polyhedron' => 'polyhedra',
    
    'addendum' => 'addenda',
    'agendum' => 'agenda',
    'consortium' => 'consortia',
    'corrigendum' => 'corrigenda',
    'datum' => 'data',
    'medium' => 'media',
    'memorandum' => 'memoranda',
    'millennium' => 'millennia',
    'symposium' => 'symposia',
    
    'stigma' => 'stigmata',
    'stoma' => 'stomata',
    'schema' => 'schemata',
    'dogma' => 'dogmata',
    'lemma' => 'lemmata',
    
    'beau' => 'beaux',
    'château' => 'châteaux',
    'tableau' => 'tableaux',
    
    'Inuk' => 'Inuit',
    'inukshuk' => 'inukshuit',
    
    'phalanx' => 'phalanges',
    
    );
    
    if (isset($dictionary[$singularWord])) {
    $pluralWord = $dictionary[$singularWord];
    }
    else {//some clever conversion
    $end = substr($singularWord, -3);
    if ($end == 'man') { //checking last 3 characters
    $pluralWord = substr($singularWord, 0, -3) . 'men';
    }
    elseif ($end == 'sis') {
    $pluralWord = substr($singularWord, 0, -3) . 'ses';
    }
    else {
    $end = substr($singularWord, -2);
    if ($end == 'ch' || $end == 'sh') {
    $pluralWord = $singularWord . 'es';
    }
    elseif ($end == 'fe') {
    $pluralWord = substr($singularWord, 0, -2) . 'ves';  //e.g. knife => knives, wife => wives
    }
    else {
    $end = substr($singularWord, -1);
    if (strpos('sxo', $end) === false) { //checking last character
    $pluralWord = $singularWord . 'es';
    }
    elseif ($end == 'f') {
    $pluralWord = substr($singularWord, 0, -1) . 'ves'; //e.g. half => halves
    }
    elseif ($end == 'y') {
    $secondLast = substr($singularWord, -2, 1);
    if (strpos('aeiou', $secondLast) === false) {
    $pluralWord = substr($singularWord, 0, -1) . 'ies'; //e.g. lady => ladies
    }
    else {
    $pluralWord = $singularWord . $pluralSuffix; //e.g. boy => boys
    }
    }
    else { //last rule
    $pluralWord = $singularWord . $pluralSuffix;
    }
    }
    }
    
    }
    
    if ($nr == 0) {
    return "$no $pluralWord";
    }
    else {
    return "$nr $pluralWord";
    }
    }
    
    }
    
    
  • Magento practice: managing product images on server file system

    Magento 自带的管理产品图片的机制简单有效,但每次只能对单个产品进行管理,每次要 http upload 很费时。如果换个角度看,如果要成批更新产品图片,就不那么方便;如果要调用某个产品图片,必须先找到产品才能找到图片,因为 Magento 对上传后的文件进行了 dispretion 处理了文件路径,没有直观的办法可以直接浏览图片。

    所以我的做法是,产品图片按产品属性归类,把整个文件夹 ftp 到 Magento 某个位置(或从 Magento 中独立出来,用一个静态文件服务器来管理图片,这样可以提供更方便的文件操作)。

    然后在 magento/media/catalog/product 下建一个软连接(假设这个软连接名 static_image_linkedin)到产品图片目录的根。不要在 magento/media/catalog 这一级把 product 建为软连接,因为 Magento 会在 product 下建 cache 目录,从静态文件服务器角度看,这个 cache 是垃圾(我追求完美)。

    然后,如果要指定产品使用某图片,必须把image, small_image, thumbnail, media_gallery 对应的值保存为人工指定位置的图片路径,该值的形式如 “/static_image_linkedin/nwf/recycled/green_bag.jpg”。Magento 原值形式如 “/g/r/green_bag.jpg”,我还没做出一个 GUI 帮助完成此项修改,依赖数据库直接操作。

    我本有一个想法是修改 magento/app/code/core/Mage/Catalog/Model/Product/Media/Config.php 来改变产品图片目录的根,这样就不需要建软连接。但这样做的缺点是在移交 Magento 给别的 developers 时,我还得多一点额外交代。

  • Magento extension: Buy X selection of products, Get another Y selection for free

    When to use:
    Magento has a native “buy x get y” sales rule in promotions. Magento’s x and y refer to a same product. For example, if a product offer is “buy 3 get 2”, you have to buy 5 of this product then only pay for 3 of them.

    Quite often the store owners want to give an offer which let customers choose from a wide range of products, (the programme add them up, get a total quantity of subselect), and offer another selection of products for free. It is useful if the store have two ranges of products, among which prices are almost the same. Let’s make it clear to you: in this module, “buy x get y” means “Buy X selection of products, Get another Y selection for free”.

    I wrote some quick and dirty codes to do “Buy X selection of products, Get another Y selection for free” quite a while ago, but this release refactors the codes into a standard standalone Magento extension.

    How to install:
    Copy the whole “app” folder, merge to magento/app. That’s it.

    If you are logged in Magento backend when doing installation, that’s fine. But you have to log out and log in again to access Buy X Get Y configuration section in System Configuration.

    How to use:
    Log in Magento backend, go to Promotions -> Shopping Cart Price Rules, create a new rule whose name must start with “[bxgy]”;

    In “Rule Information” tab, apart from the Rule Name, set up everything else as if it is normal Magento sales rule;

    Screenshot: Rule Information
    Screenshot: Rule Information

    In “Conditions” tab, create a product total quantity subselect. The product subselect should match the selection of X product in the offer, and condition is “equals or greater than”, and quantity should match the quantity of X product used as qualifier;
    * Do not create more than one subselect. Result is unpredictable otherwise.
    * The condition must be “equals or greater than” and the quantity must be the threshold quantity of the offer. Although the calculation of the free quota of Y product is not dependent on the quantity (it is dependent on the settings in “Actions” tab), the offer validation is still Magento original logic. This module changes the discount amount after the offer validation. In other words, you must think about when to trigger Magento native “buy x get y”, and do the same conditions for this module.

    Screenshot: Conditions
    Screenshot: Conditions

    In “Actions” tab, set Apply to “Buy X get Y (discount amount is Y)” (although this is not normal buy_x_get_y action, the program still check this simple_action), set Discount amount to offer free quota, set Maximum Qty Discount is Applied to to 0, set Discount Qty Step (Buy X) to offer quantity qualifier. For example, if the offer is “buy any 3 of X products, and get any 2 of Y products free”, then set Discount amount to 3, set Maximum Qty Discount is Applied to to 0, set Discount Qty Step (Buy X) to 2. Then, in “Apply the rule only to cart items matching the following conditions (leave blank for all items)”, create a combination of conditions which match the selection of Y product in the offer. Multi combination is OK;

    Screenshot: Actions
    Screenshot: Actions

    In “Label” tab, enter the offer labels as normal. It is not required, but if you leave it blank, the “ugly” Rule Name “[bxgy]***” will be used is discount description;

    Now save the rule, and go to System -> Configuration -> Buy X Get Y -> Buy X selection of products, Get another Y selection for free, set up the offer reminder message in cart. It is not required. And if it is not set up, the offer is still taking effect as long as the sales rule is enabled.

    How is it created:
    This module is created by koukou1985’s module creator (http://www.magentocommerce.com/wiki/custom_module_with_custom_database_table). Thanks to koukou1985.

    How good is it:
    This module does not override any Mage classes. It is safe to use with other extensions as long as namespace and module name do not conflict.

    FAQ:
    Q: Why this module does not work?
    A: I won’t cover all reasons that make my module not working. I only point out caveats of my module, and expect you to have common knowledge of Magento, such as “refresh the cache to see the newly installed features”. All caveats are in above sections. So, if you are stuck, go back to the top and read again.

    Download BuyXGetY.tar.gz

    Update: a new version of bxgy module is available at http://blog.goods-pro.com/1764/magento-extension-bxgy-0-1-1-is-released/

    2011/02/21 Update again: please checkout a newer release. Always leave comments on the newest release post. The comment on this post is closed.

  • Use Magento in foreign trade business

    我挺奇怪的,搜了一下竟然没人写过此类话题。怎么把 Magento 应用到外贸企业是我从一开始接触 Magento 就盘旋在我脑袋里的思考点,但却没人讨论过。或许 Magento 天生适合 b2c,或许外贸企业的眼光沉浸于展销会、阿里巴巴?

    我不否认拿 Magento 去做外贸业务(我指的是报关出口)是有难度的,需要改造很多地方。今天突然想讲一讲,是因为我理清了一个思路:如何处理询盘 (enquiry)。在外贸实践中,询盘不是一个订单 (order)。这左右了我,老想着 extends Mage_Sales_Model_Quote 或 Mage_Wishlist_Model_Wishlist 去做一个 enquiry model,因为 quote 或 wishlist 都可以说是客户下单前的 enquiry。

    但在编程实践中,外贸业务的 enquiry 应该由 extends Mage_Sales_Model_Order 才最适合,因为每个 enquiry 都是一个具体的、有形的客户做的,客户的国别、地址都是报价的考虑要素,Mage_Sales_Model_Quote 或 Mage_Wishlist_Model_Wishlist 都不具备这些要素,只有 Mage_Sales_Model_Order 才具备。所以,最简单的办法是为 order 自定义一些 pending 前状态,如 enquiry, offer, offer-accepted, offer-dead。

    今后我会多谈谈我怎么把 Magento 应用到外贸企业的思路。

  • Magento extension: rcah 0.1.1 is released

    Magento store owners are having a challenge when using rcah 0.1.0, especially for homepage. The nature of homepage is CMS, most content of it static.

    Store owners want their visitors (especially first time visitors) to read static content on the homepage, but static content become obstacles filling in the central area of the page when visitors start to click on filters for refined results.

    Root category as homepage 0.1.1 is released to address the problem. It conditionally hides the CMS Block on category pages. It only hides CMS Block in Display Settings of a category (category landing_page attribute). Static CMS Blocks used for others purposes (in sidebar, footer, etc) are not affected.

    I must say the conditions when hiding the CMS Block are subtle. Please refer to readme file with the release for details.

    Download RootCategoryAsHomepage.tar.gz

  • Magento does not remove storeview data when scope changes

    今天我做了个有趣的实验:

    1. 首先 Manage Attributes,设置某 product attribute ‘my_attr’ scope 为 Store view
    2. 然后 Manage Products,为 my_attr 设置 default value ‘aaa’,再设置 store view (假设 storeId = 2) value ‘bbb’
    3. 然后 Manage Attributes, 把 my_attr scope 改为 Global
    4. 然后 Manage Products,Choose Store View (storeId = 2),这时仍可见 my_attr 显示值 ‘bbb’。It means although my_attr scope is changed to ‘Global’, but old store view specific values are not removed.
    5. 这时 (my_attr scope is Global) 如果在 Store View (storeId = 2) 状态把 my_attr 的值改为 ‘ccc’,then Save Product。my_attr default value 被改为 ‘ccc’,store view (storeId = 2) value 仍为 ‘bbb’。It means when my_attr scope is ‘Global’, it is not possible using Manage Products GUI to change or remove existing store view value.

    摸清 Magento 的规律后就容易理解 Manage Products GUI 在 scope 改变或 store view 切换时的行为。另文有提及 change product default value and store view view by programming.

  • Class Mage_Sales_Model_Entity is deprecated

    今天终于搞清楚了一件困扰我已久的问题:在 Magento Sales Module 下有两个分支 Mage_Sales_Model_Entity 和 class Mage_Sales_Model_Mysql4,看上去文件结构比较相似,Sales 和其他模块一时用 Mage_Sales_Model_Entity,一时又用 Mage_Sales_Model_Mysql4。它们有什么区别?为什么要同时存在?有必要同时存在吗?如要删除一个,该删哪个保留哪个?

    以前有个任务,想要给 order 等 entity 添加一些自定义属性,因为搞不清楚哪个在起作用,我把两个类都 extends 了,即 class Mage_Sales_Model_Entity_Setup 和 class Mage_Sales_Model_Mysql4_Setup。而因为其他一些原因,自定义属性并不能完全按照我的意愿工作,所以我也没办法再用替换法去测试哪个类在起作用。

    今天重新回顾了这个问题,摸清 Mage_Sales_Model_Entity is deprecated。When extending sales entity, only need to extend classes in Mage_Sales_Model_Mysql4.

    但是简单地删除 magento/app/code/core/Mage/Sales/Model/Entity 目录则会导致程序找不到必要的文件而出错。我的建议是了解 Mage_Sales_Model_Entity is deprecated 这个事实就可以了,如果一定想割了这个阑尾目录,得做一些调整:

    • 搜索一下哪些 class extends Entity 下的类 (search for Mage_Sales_Model_Entity under magento folder),把它们改成 extends Mysql4 下对应的类。据我搜索结果,只有 Mage_Reports 一些 class extends Entity 下的类,或许 Mage_Sales 在 Mage_Reports 成形之后进行 Entity to Mysql4 的调整,而为了省事,保留 Entity 下的类,就不用去修改 Mage_Reports 了。
    • 搜索一下哪些地方用到了 getModel(‘sales_entity/entity_name’) 的方式,把它们改成 getModel(‘sales_mysql4/entity_name’)。这需要同时搜索文件和数据库(数据库里 eav_attribute 有几个 backend models 是这样被引用的)。如果嫌这么替换比较麻烦,也可以修改 magento/app/code/core/Mage/Sales/etc/config.xml,把 <sales_entity><class>Mage_Sales_Model_Entity</class></sales_entity> 修改成 <sales_entity><class>Mage_Sales_Model_Mysql4</class></sales_entity>,这样就把 sales_entity model 与 sales_mysql4 model 等价起来了。
  • 1and1 cloud server datasheet

    从 1&1 新订了一个合同,cloud server,就是为了让 magento 跑快一些。那 1and1 的 cloud server 究竟能有多快呢?

    先看看 cat /proc/cpuinfo 的情况
    processor : 0
    vendor_id : AuthenticAMD
    cpu family : 16
    model : 2
    model name : Quad-Core AMD Opteron(tm) Processor 2352
    stepping : 3
    cpu MHz : 2109.718
    cache size : 512 KB
    fpu : yes
    fpu_exception : yes
    cpuid level : 4
    wp : yes
    flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat clflush mmx fxsr sse sse2 syscall mmxext fxsr_opt lm 3dnowext 3dnow pni cx16 popcnt lahf_lm cr8_legacy altmovcr8 abm sse4a misalignsse
    bogomips : 4219.43
    TLB size : 1024 4K pages
    clflush size : 64
    cache_alignment : 64
    address sizes : 48 bits physical, 48 bits virtual
    power management:

    processor : 1
    vendor_id : AuthenticAMD
    cpu family : 16
    model : 2
    model name : Quad-Core AMD Opteron(tm) Processor 2352
    stepping : 3
    cpu MHz : 2109.718
    cache size : 512 KB
    fpu : yes
    fpu_exception : yes
    cpuid level : 4
    wp : yes
    flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat clflush mmx fxsr sse sse2 syscall mmxext fxsr_opt lm 3dnowext 3dnow pni cx16 popcnt lahf_lm cr8_legacy altmovcr8 abm sse4a misalignsse
    bogomips : 4220.53
    TLB size : 1024 4K pages
    clflush size : 64
    cache_alignment : 64
    address sizes : 48 bits physical, 48 bits virtual
    power management:

    processor : 2
    vendor_id : AuthenticAMD
    cpu family : 16
    model : 2
    model name : Quad-Core AMD Opteron(tm) Processor 2352
    stepping : 3
    cpu MHz : 2109.718
    cache size : 512 KB
    fpu : yes
    fpu_exception : yes
    cpuid level : 4
    wp : yes
    flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat clflush mmx fxsr sse sse2 syscall mmxext fxsr_opt lm 3dnowext 3dnow pni cx16 popcnt lahf_lm cr8_legacy altmovcr8 abm sse4a misalignsse
    bogomips : 4223.97
    TLB size : 1024 4K pages
    clflush size : 64
    cache_alignment : 64
    address sizes : 48 bits physical, 48 bits virtual
    power management:

    processor : 3
    vendor_id : AuthenticAMD
    cpu family : 16
    model : 2
    model name : Quad-Core AMD Opteron(tm) Processor 2352
    stepping : 3
    cpu MHz : 2109.718
    cache size : 512 KB
    fpu : yes
    fpu_exception : yes
    cpuid level : 4
    wp : yes
    flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat clflush mmx fxsr sse sse2 syscall mmxext fxsr_opt lm 3dnowext 3dnow pni cx16 popcnt lahf_lm cr8_legacy altmovcr8 abm sse4a misalignsse
    bogomips : 4219.25
    TLB size : 1024 4K pages
    clflush size : 64
    cache_alignment : 64
    address sizes : 48 bits physical, 48 bits virtual
    power management:

    在 cloud server 上我使用 zend server。我特意从 1 Virtual processor core 1GB Ram 一步步往上加,使用 ab -c 5 -n 500 对比测试,客户端是 10 Mb down stream / 1Mb up stream adsl 连接。

    在 1 Virtual processor core 1GB Ram 时,Requests per second: 5.31 [#/sec]
    在 2 Virtual processor cores 1GB Ram 时,Requests per second: 8.34 [#/sec]
    在 2 Virtual processor cores 2GB Ram 时,Requests per second: 8.26 [#/sec]
    在 3 Virtual processor cores 1GB Ram 时,Requests per second: 10.57 [#/sec]
    在 4 Virtual processor cores 1GB Ram 时,Requests per second: 11.33 [#/sec]

    在 shopping cart 里有 7 条不同商品时,checkout/cart/index 页面时间为 10 秒左右。

    回头看看老 server
    # cat /proc/cpuinfo
    processor : 0
    vendor_id : AuthenticAMD
    cpu family : 15
    model : 67
    model name : Dual-Core AMD Opteron(tm) Processor 1216 HE
    stepping : 3
    cpu MHz : 1000.000
    cache size : 1024 KB
    physical id : 0
    siblings : 2
    core id : 0
    cpu cores : 2
    apicid : 0
    initial apicid : 0
    fpu : yes
    fpu_exception : yes
    cpuid level : 1
    wp : yes
    flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt rdtscp lm 3dnowext 3dnow rep_good nopl pni cx16 lahf_lm cmp_legacy svm extapic cr8_legacy
    bogomips : 1999.96
    TLB size : 1024 4K pages
    clflush size : 64
    cache_alignment : 64
    address sizes : 40 bits physical, 48 bits virtual
    power management: ts fid vid ttp tm stc

    processor : 1
    vendor_id : AuthenticAMD
    cpu family : 15
    model : 67
    model name : Dual-Core AMD Opteron(tm) Processor 1216 HE
    stepping : 3
    cpu MHz : 1000.000
    cache size : 1024 KB
    physical id : 0
    siblings : 2
    core id : 1
    cpu cores : 2
    apicid : 1
    initial apicid : 1
    fpu : yes
    fpu_exception : yes
    cpuid level : 1
    wp : yes
    flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt rdtscp lm 3dnowext 3dnow rep_good nopl pni cx16 lahf_lm cmp_legacy svm extapic cr8_legacy
    bogomips : 1999.96
    TLB size : 1024 4K pages
    clflush size : 64
    cache_alignment : 64
    address sizes : 40 bits physical, 48 bits virtual
    power management: ts fid vid ttp tm stc

    运行的是 nginx,同等条件下,Requests per second: 8.12 [#/sec],checkout/cart/index 页面生成时间也是 10 秒左右。

    虽 zend server 和 nginx 不同,靠不是完全对等的对比结果,我还是可以得出两个结论:

    1. 瓶颈仍是 cpu 速度;
    2. cloud server 并未显著提高速度,我对它预期过高,略有失望。
  • How to detect current connection is secure using Php?

    Over a long time I had believed there was a function or an environment variable I could use in Php to tell whether the current connection secure or not, i.e. a page requested via http or https protocol. Unfortunately I could not find a good solution. I can not find it does not mean it does not exist.

    Recently I intend to believe the perfect solution does not exist, i.e. I can not write something in Php safely to tell whether the current connection is secure unless I know the server setting.

    Look at the code snippet Magento use for isSecure function:

    $secure = (!empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS']!='off')) || $_SERVER['SERVER_PORT']=='443';
    

    This code is not perfect because it assumes the server is not listening http on 443 AND server is listening HTTPS on 443.

    Unfortunately I can not do more than that. I am wondering whether the situation is the same in Python or Java.

  • Why not use over-sized images in Magento?

    为什么不要在 Magento 下使用过高像素的图片?其实这个命题跟 Magento 没有多大关系——任何网站都不要使用超过实际需要尺寸的图片。

    只是 Magento 强大的图片处理机制容易让人产生惰性:如今买个相机动辄 10m pixels,拍完照一上传,只要 php.ini 允许足够大的值,Magento 也认可,但是,如果你真的这么做了,至少有这几点不良后果:

    • Can not send large images to Google Base (now called Google Merchant Centre). 虽然 Magento 能在自己的网站上缩放图片,但显然没有为 Google Base 考虑到。若为了让 Magento 缩放图片兼容去修改 GoogleBase module,在我看来有点头痛医脚的感觉。
    • Cost longer time to generate images in cache. 如果整个网站最大图片也只要 600x600px,那么何必为每次清空 image cache 后等上几秒钟来一张 10 兆像素的照片缩小成 600x600px?
    • Waste bandwidth to synchronise / backup media folder. 或许 unlimited bandwidth 不值得担心,但为数据同步/备份节省点时间不好吗?
    • My daily backup excludes some over-sized folders. 我有每日备份的机制,但这个机制无力顾及一些体积过大的文件或文件夹(通常也是不常更新的文件)。所以我会排除某些文件让备份文件保持小巧。

    作为最佳实践,图片处理不应该依赖于 online resizing。我想 Magento 在管理图片上,也可以更周到一些,适当时提示说,“照片太大,需要缩小保存吗(不保存原图)?”。