Woocommerce对中文有那么一点支持,至少货币中可以找到我们的Chinese Yuan。不过讽刺的是,当你选择了人民币作为默认货币符号时,前台显示的确是英镑符号。
Note:该错误已经在Woocommerce 1.6.3版中修复,请升级到最新版本
为什么中文符号错误
这是个很小的错误,不知道为什么这么优秀的插件会犯这种简单的错误。
在woocommerce-core-functions.php中定义的get_woocommerce_currency_symbol()函数用来获取当前选择的货币的符号。并不复杂,只是一段简单的switch代码。
function get_woocommerce_currency_symbol( $currency = '' ) { if ( ! $currency ) $currency = get_woocommerce_currency(); $currency_symbol = ''; switch ($currency) : case 'BRL' : $currency_symbol = 'R$'; break; case 'AUD' : $currency_symbol = '$'; break; case 'CAD' : $currency_symbol = '$'; break; case 'MXN' : $currency_symbol = '$'; break; case 'NZD' : $currency_symbol = '$'; break; case 'HKD' : $currency_symbol = '$'; break; case 'SGD' : $currency_symbol = '$'; break; case 'USD' : $currency_symbol = '$'; break; case 'EUR' : $currency_symbol = '€'; break; case 'CNY' : $currency_symbol = '¥'; break; case 'JPY' : $currency_symbol = '¥'; break; case 'TRY' : $currency_symbol = 'TL'; break; case 'NOK' : $currency_symbol = 'kr'; break; case 'ZAR' : $currency_symbol = 'R'; break; case 'CZK' : $currency_symbol = 'Kč'; break; case 'MYR' : $currency_symbol = 'RM'; break; case 'DKK' : $currency_symbol = 'kr'; break; case 'HUF' : $currency_symbol = 'Ft'; break; case 'ILS' : $currency_symbol = '₪'; break; case 'PHP' : $currency_symbol = '₱'; break; case 'PLN' : $currency_symbol = 'zł'; break; case 'SEK' : $currency_symbol = 'kr'; break; case 'CHF' : $currency_symbol = 'CHF'; break; case 'TWD' : $currency_symbol = 'NT$'; break; case 'THB' : $currency_symbol = '฿'; break; case 'GBP' : $currency_symbol = '£'; break; default : $currency_symbol = '£'; break; endswitch; return apply_filters( 'woocommerce_currency_symbol', $currency_symbol, $currency ); }
注意下面这行,就是定义人民币符号的,这里看不出有什么错误。
case 'CNY' : $currency_symbol = '¥'; break;
但在woocommerce/admin/settings/settings-init.php中定义的人民币代号并不是CNY,而是RMB
'RMB' => __( 'Chinese Yuan (¥)', 'woocommerce' ),
于是乎,当你选择人民币时,数据库存的其实是“RMB“而不是”CNY“,get_woocommerce_currency_symbol()函数找不到RMB这个东西,只好返回了默认符号英镑。
解决方法
知道错误的原因,解决方法也就一目了然了,把下面代码放到主题的functions.php中即可
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) { add_filter('woocommerce_currency_symbol', 'fix_cn_currency_symbol', 10, 2); function fix_cn_currency_symbol( $currency_symbol, $currency ) { if( $currency == 'RMB') return "¥"; else return $currency_symbol; } }
估计以后的版本会修正这个问题,但愿如此。
我打印了woocommerce的classes\class-wc-checkout.php文件中$this->posted,发现里面所有的参数都为空,如下:
Array ( [shiptobilling] => 0 [terms] => 0 [createaccount] => 0 [payment_method] => [shipping_method] => [billing_country] => [billing_first_name] => [billing_last_name] => [billing_company] => [billing_address_1] => [billing_address_2] => [billing_city] => [billing_state] => [billing_postcode] => [billing_email] => [billing_phone] => [account_username] => [account_password] => [account_password-2] => [order_comments] => ) Array ( [result] => failure [messages] =>
但是抓包看,提交的时候确实带了这些参数,如下:
billing_country=ST&billing_first_name=123123&billing_last_name=123123123123&billing_company=123123&billing_address_1=123123123123&billing_address_2=123123&billing_city=123123&billing_state=123123&billing_postcode=123123&billing_email=adf%40asdf.com&billing_phone=123123&payment_method=mycred&_n=a139a8438e&_wp_http_referer=%2Fwp37%2Fwp-admin%2Fadmin-ajax.php
貌似找到原因了,在mycred的gateway中,支付成功的时候会返回一个数组,如下:
注释掉这个的时候,上面的$this->posted就会有值了,但是还不能成功支付,继续找原因。
发现mycred确实是成功支付了,在class-wc-checkout.php的下面:
当把
改成:
确实能打印test出来,可以看到是到woocommerce这边才出现的问题,而且应该是这个支付成功之后的感谢页面的问题,后面的woocommerce已经设置了感谢页的。奇怪。。
我装mycred试了,支付没有问题,订单状态成功变为processing。我的测试环境是
php 5.2.9 (没到5.3,没有max_post_vars的问题)
WordPress 3.7.1
WooCommerce 2.0.20
既然我这里正常,那就说明核心代码没有问题。或许跟服务器配置,你网站具体配置(插件主题etc.)有关,甚至可能是数据库有问题,这个不太好说。
你看过WooCommerce的system status选项吗,有没有红色警告之类的?
你提交订单以后,订单状态是否变成processing?
Mycred的log中是否正确记录的订单?
另外,订单是ajax方式提交的,你没有手动添加阻止普通用户访问后台的功能吧?
我也试了,问题可能是出现在wp_users里面,我现在wp_users里面有几千个用户,比如说有4000个,我删除了2000个,就能正常支付。
我看了下system status选项,有两个红色告警:
WP内存限制: 40 MB – We recommend setting memory to at least 64MB.
WC 日志: 日志目录 (woocommerce/logs/)不可写入。日志将无法创建。
不知道是不是这个原因,现在登不了服务器,待会看看。
提交订单以后,订单状态是等待中,但是在Mycred的log中有订单的记录,并且mycred的积分减少了。
另外,订单是ajax方式提交的,你没有手动添加阻止普通用户访问后台的功能吧?
没阻止,我是admin用户测试的。
php 版本是5.3.24,难道是你说的max_post_vars的问题?想想应该不会,因为我删除了wp_users里面一些数据,就能支付了。
这个是payment gateway的正常写法,不应该注释掉,我好像没问你支付不成功的具体报错是什么?我装个mycred试试,我记得之前用没遇到过支付不成功的问题。
支付不成功报错如下:
Array ( [result] => failure [messages] =>
动作失败。请刷新页面然后重试。
国家 为必填项
名 为必填项
姓 为必填项
地址 为必填项
Town / City 为必填项
State / County 为必填项
Postcode / Zip 为必填项
Email 地址 为必填项
电话 为必填项
无效的支付方式。
[refresh] => false )
建议你把内存增加到128m以上试试,数据库查询量大是很耗内存的,内存不足天知道哪里会出错。日志可不可写我想应该没啥影响。max_post_vars指一次可提交的变量数,默认的1000对你应该足够了。
测试将内存添加到128m,还是报一样的错,悲剧啊。怀疑是这句的问题
$result = apply_filters(‘woocommerce_payment_successful_result’, $result );
我个人感觉不大可能,因为这句话对所有的payment gateway都有效,而且出问题的只是你站点的mycred支付网关。你应该先缩小一下范围,新装wordpress测试,没问题再导入你的用户测试,按照你说的2000个用户没错,4000个就有错,不是应该先从这里着手么。
而且这只是一个filter,除非有函数使用了这个filter,否则它就是把result原样返回罢了。
我觉得在怀疑核心代码之前,应该先逐步排除掉自己站点的因素,比如插件,主题,数据库等等。在新装环境下重现错误,就能解决。毕竟woocommerce是经过大量测试的,这句话出问题的概率基本不可能。
我再测试下,目前是两套系统,线上一套,线下一套,线下的全新装的wp,3.7.1,任何插件没有安装,如果本地只有一个admin用户的话,支付是不会存在任何问题,但是一导入线上wp_users里面的数据,支付的时候就会报错。悲哀啊。
也就是说基本可以把问题锁定在wp_users表的数据上了,你修复过这个表吗,有可能是数据太多有错误。
还有你只导了wp_user表吗,那个usermeta表导入了吗,最好两个都修复一下,导入。
我只导了一张wp_users表到本地,usermeta没导,表咋修复呀。
可以到phpmyadmin里点repaire database
看这张图http://www.themepremium.com/wp-content/uploads/2012/12/repair-wordpress-database-from-phpmyadmin.png
也可以通过修改wp-config.php实现,看这里http://www.caopeng.net/2010/08/wordpress-comes-with-new-features-repair-and-optimize-the-database/
但一定要先备份数据!你可以先修复你测试站上的数据试试。
PS usermeta必须导入,用户的权限资料都在这个表里啊!
有道理,可能是这个原因,晚上回去我再测试下,有结果了来告诉你,感谢sola姐。
测试了,悲剧,wp_users和usermeta都导入了还是报错。。
你修复数据表了?你还是找人具体看下吧,这东西靠猜测是不好解决的。
修复过数据表了,您帮我看看?
怎么看,你把数据库发给我?客户信息属于敏感数据吧,但问题又好像是出在数据库上
sola联系下我评论的邮箱吧,我赠送你礼品。
没写程序,用的原来的。支付使用的是mycred,测试了半天,发现wp_users里面有下面两条数据,在支付的时候就会报错,奇怪:
什么数据?貌似被过滤掉了,麻烦点回复再发一遍。是只用mycred付款时出错,还是所有支付接口都报错?有在线的测试站吗
奇怪,老是被过滤了,只有用mycred付款时报错,其他接口都正常,sola姐有邮箱吗?我邮件与您联系。多谢sola姐。
那有可能是mycred的问题,你可以去这插件的论坛问问,作者回复的不慢。我的邮箱只能提供给客户,抱歉。如果可以,我希望通过博客交流,算是对我努力回答问题的一点安慰吧,希望你理解。
要不我当你客户吧,可通过我留言的邮箱与我联系,谢谢。
请问下只要user表里面有中文用户名,在支付的时候就会报错,这种情况咋解决啊,谢谢。
我想这是因为woocommerce的用户名不支持中文,用中文注册账户时会提示用户名非法。
了解,我在官网问了,还没人答复,还是sola姐姐给力,那这种有办法解决么,因为我网站里面很多都是中文用户名的。
官方客服好像是付费的哦。其实这个应该不是woocommerce的问题,因为wordpress用户名就不支持中文。
解决的方法是让wordpress支持中文用户名,代码看露兜的文章http://www.ludou.org/wordpress-allowing-chinese-in-registration.html
感谢sola姐,我测试下来,发现又不是中文的问题,跟wp_users里面的数据有关系,比如我数据库有5000个用户,删除前面2500个用户,可以正常提交,然后利用拆半法定位出某个用户,但是数据库里面单独存放这个用户,也可以提交,报错如下:
Array ( [result] => failure [messages] =>
动作失败。请刷新页面然后重试。
国家 为必填项
名 为必填项
姓 为必填项
地址 为必填项
Town / City 为必填项
State / County 为必填项
Postcode / Zip 为必填项
Email 地址 为必填项
电话 为必填项
无效的支付方式。
[refresh] => false )
感觉像是country、first_name这些值没传递过去,但是抓包看,POST数据包里面确实有这些数据,奇怪啊。折腾一天了。。
你是手动下单还是写了程序自动下单?post数据丢失,我只见过数据量很大的时候丢失。先看看是不是服务器配置问题。我之前遇到菜单保存不了的问题,就是max_input_vars值太小导致的。
https://www.solagirl.net/wordpress-menu-item-limit.html