opencart建站根据客户IP国家切换货币

       前些时间我们比较过opencart,zencart,wordpress等系统的优劣,当时我就开始觉得zencart系统在国内的使用正开始没落,最主要的原因可以使用的模板太少了,市面上销售的模板很多都因为之前国内做仿牌使用zencart这些模板人太多,导致SEO等各方面太差了,谷歌浏览器也经常标记使用过这些模板的网站为垃圾网站。而最近咨询我建站方面的很多客户基本上都是要求使用opencart或wordpress。

         今天有个客户需要优化opencart的一细节,其中就有个需求根据IP来切换客户国家的默认币种和语言。这里就来写写我的整个开发时相当和步骤。

1.IP查询

获取客户的访问IP后,我们要查询IP所在的国家,这个一般有2种方法,一个是调用第三方的接口,一个是直接查询本地的IP库。其实就这一步你就得考虑下客户的愿意花多少钱来做这件事。因为大部分第三方接口都是收费的,就有免费的接口也会对你调用接口的次数和频率做一些限制,可能当你网站流量大或被蜘蛛爬行时,你的接口调用就达到了限额,导致调用失效了。查询本地IP库也有一个弊端,如果你对IP的查询结果要求的比较细,会消耗你服务器CPU资源。考虑到客户只要查询到国家就行和成本等因素还是用IP库查询的方式。语言的选择我们就不靠IP国家了,因为opencart自带了根据浏览器语言来默认语言。

文件位置:catalog\controller\extension\module\ip.php

<?php
require(DIR_SYSTEM.'library/MaxMind/Db/Reader/InvalidDatabaseException.php');
require(DIR_SYSTEM.'library/MaxMind/Db/Reader/Decoder.php');
require(DIR_SYSTEM.'library/MaxMind/Db/Reader/Metadata.php');
require(DIR_SYSTEM.'library/MaxMind/Db/Reader/Util.php');
require(DIR_SYSTEM.'library/MaxMind/Db/Reader.php');
class ControllerExtensionModuleIp extends Controller {
	public function index() {
	    if (isset($this->session->data['currency'])) 
	        return true;
        $file      = DIR_SYSTEM.'library/MaxMind/dbip-country-lite-2023-04.mmdb';
        $reader    = new \MaxMind\Db\Reader($file);
        $ipAddress = $this->get_client_ip();
        $ip_info   = $reader->get($ipAddress);
        $reader->close();
        if($ip_info){
            $country_iso_code = $ip_info['country']['iso_code'];
            $currency         = $this->get_country_default_currency($country_iso_code);
            if($currency){
        		$this->load->model('localisation/currency');
        		$currencies = $this->model_localisation_currency->getCurrencies();
        		if(array_key_exists($currency, $currencies)){
        		    $this->session->data['currency'] = $currency;
        		}
            }
        }
	}
	
	public function get_client_ip(){
        if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {     //使用cloudflare 转发的IP地址
            $ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
        } else {
            if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
                $ip = getenv('HTTP_CLIENT_IP');
            } elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
                $ip = getenv('HTTP_X_FORWARDED_FOR');
            } elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
                $ip = getenv('REMOTE_ADDR');
            } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
                $ip = $_SERVER['REMOTE_ADDR'];
            }
        }

        return $ip;
	}
	
	public function get_country_default_currency($country_iso_code){
        $country_map_currency = [
            'NZ'=>'NZD',
            'CK'=>'NZD',
            'NU'=>'NZD',
            'PN'=>'NZD',
            'TK'=>'NZD',
            'AU'=>'AUD',
            'CX'=>'AUD',
            'CC'=>'AUD',
            'HM'=>'AUD',
            'KI'=>'AUD',
            'NR'=>'AUD',
            'NF'=>'AUD',
            'TV'=>'AUD',
            'AS'=>'EUR',
            'AD'=>'EUR',
            'AT'=>'EUR',
            'BE'=>'EUR',
            'FI'=>'EUR',
            'FR'=>'EUR',
            'GF'=>'EUR',
            'TF'=>'EUR',
            'DE'=>'EUR',
            'GR'=>'EUR',
            'GP'=>'EUR',
            'IE'=>'EUR',
            'IT'=>'EUR',
            'LU'=>'EUR',
            'MQ'=>'EUR',
            'YT'=>'EUR',
            'MC'=>'EUR',
            'NL'=>'EUR',
            'PT'=>'EUR',
            'RE'=>'EUR',
            'WS'=>'EUR',
            'SM'=>'EUR',
            'SI'=>'EUR',
            'ES'=>'EUR',
            'VA'=>'EUR',
            'GS'=>'GBP',
            'GB'=>'GBP',
            'JE'=>'GBP',
            'IO'=>'USD',
            'GU'=>'USD',
            'MH'=>'USD',
            'FM'=>'USD',
            'MP'=>'USD',
            'PW'=>'USD',
            'PR'=>'USD',
            'TC'=>'USD',
            'US'=>'USD',
            'UM'=>'USD',
            'VG'=>'USD',
            'VI'=>'USD',
            'HK'=>'HKD',
            'CA'=>'CAD',
            'JP'=>'JPY',
            'AF'=>'AFN',
            'AL'=>'ALL',
            'DZ'=>'DZD',
            'AI'=>'XCD',
            'AG'=>'XCD',
            'DM'=>'XCD',
            'GD'=>'XCD',
            'MS'=>'XCD',
            'KN'=>'XCD',
            'LC'=>'XCD',
            'VC'=>'XCD',
            'AR'=>'ARS',
            'AM'=>'AMD',
            'AW'=>'ANG',
            'AN'=>'ANG',
            'AZ'=>'AZN',
            'BS'=>'BSD',
            'BH'=>'BHD',
            'BD'=>'BDT',
            'BB'=>'BBD',
            'BY'=>'BYR',
            'BZ'=>'BZD',
            'BJ'=>'XOF',
            'BF'=>'XOF',
            'GW'=>'XOF',
            'CI'=>'XOF',
            'ML'=>'XOF',
            'NE'=>'XOF',
            'SN'=>'XOF',
            'TG'=>'XOF',
            'BM'=>'BMD',
            'BT'=>'INR',
            'IN'=>'INR',
            'BO'=>'BOB',
            'BW'=>'BWP',
            'BV'=>'NOK',
            'NO'=>'NOK',
            'SJ'=>'NOK',
            'BR'=>'BRL',
            'BN'=>'BND',
            'BG'=>'BGN',
            'BI'=>'BIF',
            'KH'=>'KHR',
            'CM'=>'XAF',
            'CF'=>'XAF',
            'TD'=>'XAF',
            'CG'=>'XAF',
            'GQ'=>'XAF',
            'GA'=>'XAF',
            'CV'=>'CVE',
            'KY'=>'KYD',
            'CL'=>'CLP',
            'CN'=>'CNY',
            'CO'=>'COP',
            'KM'=>'KMF',
            'CD'=>'CDF',
            'CR'=>'CRC',
            'HR'=>'HRK',
            'CU'=>'CUP',
            'CY'=>'CYP',
            'CZ'=>'CZK',
            'DK'=>'DKK',
            'FO'=>'DKK',
            'GL'=>'DKK',
            'DJ'=>'DJF',
            'DO'=>'DOP',
            'TP'=>'IDR',
            'ID'=>'IDR',
            'EC'=>'ECS',
            'EG'=>'EGP',
            'SV'=>'SVC',
            'ER'=>'ETB',
            'ET'=>'ETB',
            'EE'=>'EEK',
            'FK'=>'FKP',
            'FJ'=>'FJD',
            'PF'=>'XPF',
            'NC'=>'XPF',
            'WF'=>'XPF',
            'GM'=>'GMD',
            'GE'=>'GEL',
            'GI'=>'GIP',
            'GT'=>'GTQ',
            'GN'=>'GNF',
            'GY'=>'GYD',
            'HT'=>'HTG',
            'HN'=>'HNL',
            'HU'=>'HUF',
            'IS'=>'ISK',
            'IR'=>'IRR',
            'IQ'=>'IQD',
            'IL'=>'ILS',
            'JM'=>'JMD',
            'JO'=>'JOD',
            'KZ'=>'KZT',
            'KE'=>'KES',
            'KP'=>'KPW',
            'KR'=>'KRW',
            'KW'=>'KWD',
            'KG'=>'KGS',
            'LA'=>'LAK',
            'LV'=>'LVL',
            'LB'=>'LBP',
            'LS'=>'LSL',
            'LR'=>'LRD',
            'LY'=>'LYD',
            'LI'=>'CHF',
            'CH'=>'CHF',
            'LT'=>'LTL',
            'MO'=>'MOP',
            'MK'=>'MKD',
            'MG'=>'MGA',
            'MW'=>'MWK',
            'MY'=>'MYR',
            'MV'=>'MVR',
            'MT'=>'MTL',
            'MR'=>'MRO',
            'MU'=>'MUR',
            'MX'=>'MXN',
            'MD'=>'MDL',
            'MN'=>'MNT',
            'MA'=>'MAD',
            'EH'=>'MAD',
            'MZ'=>'MZN',
            'MM'=>'MMK',
            'NA'=>'NAD',
            'NP'=>'NPR',
            'NI'=>'NIO',
            'NG'=>'NGN',
            'OM'=>'OMR',
            'PK'=>'PKR',
            'PA'=>'PAB',
            'PG'=>'PGK',
            'PY'=>'PYG',
            'PE'=>'PEN',
            'PH'=>'PHP',
            'PL'=>'PLN',
            'QA'=>'QAR',
            'RO'=>'RON',
            'RU'=>'RUB',
            'RW'=>'RWF',
            'ST'=>'STD',
            'SA'=>'SAR',
            'SC'=>'SCR',
            'SL'=>'SLL',
            'SG'=>'SGD',
            'SK'=>'SKK',
            'SB'=>'SBD',
            'SO'=>'SOS',
            'ZA'=>'ZAR',
            'LK'=>'LKR',
            'SD'=>'SDG',
            'SR'=>'SRD',
            'SZ'=>'SZL',
            'SE'=>'SEK',
            'SY'=>'SYP',
            'TW'=>'TWD',
            'TJ'=>'TJS',
            'TZ'=>'TZS',
            'TH'=>'THB',
            'TO'=>'TOP',
            'TT'=>'TTD',
            'TN'=>'TND',
            'TR'=>'TRY',
            'TM'=>'TMT',
            'UG'=>'UGX',
            'UA'=>'UAH',
            'AE'=>'AED',
            'UY'=>'UYU',
            'UZ'=>'UZS',
            'VU'=>'VUV',
            'VE'=>'VEF',
            'VN'=>'VND',
            'YE'=>'YER',
            'ZM'=>'ZMK',
            'ZW'=>'ZWD',
            'AX'=>'EUR',
            'AO'=>'AOA',
            'AQ'=>'AQD',
            'BA'=>'BAM',
            'CD'=>'CDF',
            'GH'=>'GHS',
            'GG'=>'GGP',
            'IM'=>'GBP',
            'LA'=>'LAK',
            'MO'=>'MOP',
            'ME'=>'EUR',
            'PS'=>'JOD',
            'BL'=>'EUR',
            'SH'=>'GBP',
            'MF'=>'ANG',
            'PM'=>'EUR',
            'RS'=>'RSD',
            'USAF'=>'USD'
        ];
        
        if(isset($country_map_currency[$country_iso_code])){
            return $country_map_currency[$country_iso_code];
        }else{
            return false;
        }
	}
}

2.勾子触发货币切换代码

opencart在文件调用时都用了好多勾子,这样很多扩展我们就不需要去直接修改核心文件,只要加上对应的勾子调用,这样大大提高了代码的维护性。

文件:system/config/catalog.php,查找“'startup/startup'”,在其上面加上'extension/module/ip/index'

这个勾子 加上后,你会发现你的模板可能触发勾子,也可能无效,因为opencart有一套对核心文件修改的规则,当你要修改核心文件时,你不能直接去修改对应的文件,你必须使用Modification的机制去做。Modification管理着整个网站需要修改核心的记录,有时可能多个插件需要修改同一个文件,这时如果你加一下我加一个,很容易导致代码的不可维护,而通过Modification我们则能高效的维护代码。

<?xml version="1.0" encoding="utf-8"?>
<modification>
  <name>根据IP国家默认切换币种</name>
  <code>Default currency by ip</code>
  <version>1.0</version>
  <author>微信:ChineseMarcelo</author>
  <link>https://blog.youkuaiyun.com/jxayxym</link>
  <file path="system/config/catalog.php">
	<operation>
      <search><![CDATA[ 'startup/startup', ]]></search>
      <add position="before">
<![CDATA[
'extension/module/ip/index',
]]>
	  </add>
    </operation>
  </file>
</modification>

opencart建站根据客户IP国家切换货币插件下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

paypal1987

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值