Skip to content

Instantly share code, notes, and snippets.

@jcubic
Last active May 17, 2024 21:57
Show Gist options
  • Save jcubic/74c0e86527425faf5e7d2c1349ccb0e8 to your computer and use it in GitHub Desktop.
Save jcubic/74c0e86527425faf5e7d2c1349ccb0e8 to your computer and use it in GitHub Desktop.
Calculate regional discount using Parity Purchasing Power for user IP address
<?php
// Copyright (C) Jakub T. Jankiewicz
// this code is released to Public Domain with CC0 license
// created with the help from ChatGPT
$default_country = [
'name' => 'Poland',
'code' => 'PL'
];
function curl($url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
if (isset($_SERVER['HTTP_USER_AGENT'])) {
$agent = $_SERVER['HTTP_USER_AGENT'];
} else {
// defaut FireFox 15 from agent switcher (google chrome extension)
$agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0) Gecko/20120427 '.
'Firefox/15.0a1';
}
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
return $ch;
}
function remote_ip() {
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
return $_SERVER['HTTP_X_FORWARDED_FOR'];
}
return $_SERVER['REMOTE_ADDR'];
}
function is_localhost($ip) {
if ($ip === '127.0.0.1' || $ip === '::1') {
return true;
}
if (substr($ip, 0, 7) === '::ffff:') {
$ip = substr($ip, 7);
if ($ip === '127.0.0.1') {
return true;
}
}
return false;
}
function get($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERAGENT, "PHP " . phpversion());
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
// get country information
function get_country() {
$ip = remote_ip();
if (is_localhost($ip)) {
return $default_country;
}
$url = "http://ip-api.com/json/$ip";
$data = get($url);
$data = json_decode(get($url));
return [
'name' => $data->country,
'code' => $data->countryCode
];
}
// get Parity Purchasing Power value
function get_ppp($country) {
$url = "https://api.worldbank.org/v2/country/$country/indicator/PA.NUS.PPP";
$data = get($url);
$xml = new SimpleXMLElement($data);
foreach ($xml->xpath('//wb:value') as $value) {
if (!empty($value)) {
return floatval($value);
}
}
return 1;
}
// calculate Parity Purchasing Power discount based on a country
function get_discount($price, $country) {
$ppp = get_ppp($country);
if ($ppp == 1) {
return [
'price' => $price
];
}
$new_price = $price / $ppp;
$discount = ($price - $new_price) / $price * 100;
return [
'price' => '$' . round($new_price),
'percent' => strval(round($discount)) . '%'
];
}
$country = get_country();
$price = 100;
$discount = get_discount($price, $country['code']);
$price_message = "The price is ${$price}";
if (isset($discount['percent'])) {
$price_message .= " (but it looks like you are from <strong>{$country['name']}</strong>, ".
" so you can get {$discount['percent']} discount. And can pay {$discount['price']})";
}
echo "<p>$price_message</p>";
@jcubic
Copy link
Author

jcubic commented May 17, 2024

@jcubic
Copy link
Author

jcubic commented May 17, 2024

NOTE: above code don't use any limits like minimal or maximal values. If the value is too small or too big you can add min() and/or max() functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment