mirror of
https://github.com/lubuntu-team/lubuntu.me.git
synced 2025-02-24 00:31:07 +00:00
651 lines
21 KiB
PHP
651 lines
21 KiB
PHP
<?php
|
|
/*
|
|
This is the primary class for WP Statistics recording hits on the WordPress site. It is extended by the Hits class and the GeoIPHits class.
|
|
|
|
This class handles; visits, visitors and pages.
|
|
*/
|
|
|
|
class WP_Statistics {
|
|
|
|
// Setup our protected, private and public variables.
|
|
protected $db;
|
|
protected $tb_prefix;
|
|
protected $ip = false;
|
|
protected $ip_hash = false;
|
|
protected $agent;
|
|
|
|
private $result;
|
|
private $historical;
|
|
private $user_options_loaded = false;
|
|
private $is_feed = false;
|
|
private $tz_offset = 0;
|
|
private $country_codes = false;
|
|
private $referrer = false;
|
|
|
|
public $coefficient = 1;
|
|
public $plugin_dir = '';
|
|
public $plugin_url = '';
|
|
public $user_id = 0;
|
|
public $options = array();
|
|
public $user_options = array();
|
|
public $menu_slugs = array();
|
|
|
|
// Construction function.
|
|
public function __construct() {
|
|
|
|
global $wpdb;
|
|
|
|
if( get_option('timezone_string') ) {
|
|
$this->tz_offset = timezone_offset_get( timezone_open( get_option('timezone_string') ), new DateTime() );
|
|
} else if( get_option('gmt_offset') ) {
|
|
$this->tz_offset = get_option('gmt_offset') * 60 * 60;
|
|
}
|
|
|
|
$this->db = $wpdb;
|
|
$this->tb_prefix = $wpdb->prefix;
|
|
$this->agent = $this->get_UserAgent();
|
|
$this->historical = array();
|
|
|
|
// Load the options from the database
|
|
$this->options = get_option( 'wp_statistics' );
|
|
|
|
// Set the default co-efficient.
|
|
$this->coefficient = $this->get_option('coefficient', 1);
|
|
|
|
// Double check the co-efficient setting to make sure it's not been set to 0.
|
|
if( $this->coefficient <= 0 ) { $this->coefficient = 1; }
|
|
|
|
// This is a bit of a hack, we strip off the "includes/classes" at the end of the current class file's path.
|
|
$this->plugin_dir = substr( dirname( __FILE__ ), 0, -17 );
|
|
$this->plugin_url = substr( plugin_dir_url( __FILE__ ), 0, -17 );
|
|
|
|
$this->get_IP();
|
|
|
|
if( $this->get_option('hash_ips') == true ) { $this->ip_hash = '#hash#' . sha1( $this->ip + $_SERVER['HTTP_USER_AGENT'] ); }
|
|
|
|
}
|
|
|
|
// This function sets the current WordPress user id for the class.
|
|
public function set_user_id() {
|
|
if( $this->user_id == 0 ) {
|
|
$this->user_id = get_current_user_id();
|
|
}
|
|
}
|
|
|
|
// This function loads the options from WordPress, it is included here for completeness as the options are loaded automatically in the class constructor.
|
|
public function load_options() {
|
|
$this->options = get_option( 'wp_statistics' );
|
|
}
|
|
|
|
// This function loads the user options from WordPress. It is NOT called during the class constructor.
|
|
public function load_user_options( $force = false) {
|
|
if( $this->user_options_loaded == true && $force != true ) { return; }
|
|
|
|
$this->set_user_id();
|
|
|
|
// Not sure why, but get_user_meta() is returning an array or array's unless $single is set to true.
|
|
$this->user_options = get_user_meta( $this->user_id, 'wp_statistics', true );
|
|
|
|
$this->user_options_loaded = true;
|
|
}
|
|
|
|
// The function mimics WordPress's get_option() function but uses the array instead of individual options.
|
|
public function get_option($option, $default = null) {
|
|
// If no options array exists, return FALSE.
|
|
if( !is_array($this->options) ) { return FALSE; }
|
|
|
|
// if the option isn't set yet, return the $default if it exists, otherwise FALSE.
|
|
if( !array_key_exists($option, $this->options) ) {
|
|
if( isset( $default ) ) {
|
|
return $default;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// Return the option.
|
|
return $this->options[$option];
|
|
}
|
|
|
|
// This function mimics WordPress's get_user_meta() function but uses the array instead of individual options.
|
|
public function get_user_option($option, $default = null) {
|
|
// If the user id has not been set or no options array exists, return FALSE.
|
|
if( $this->user_id == 0 ) {return FALSE; }
|
|
if( !is_array($this->user_options) ) { return FALSE; }
|
|
|
|
// if the option isn't set yet, return the $default if it exists, otherwise FALSE.
|
|
if( !array_key_exists($option, $this->user_options) ) {
|
|
if( isset( $default ) ) {
|
|
return $default;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// Return the option.
|
|
return $this->user_options[$option];
|
|
}
|
|
|
|
// The function mimics WordPress's update_option() function but uses the array instead of individual options.
|
|
public function update_option($option, $value) {
|
|
// Store the value in the array.
|
|
$this->options[$option] = $value;
|
|
|
|
// Write the array to the database.
|
|
update_option('wp_statistics', $this->options);
|
|
}
|
|
|
|
// The function mimics WordPress's update_user_meta() function but uses the array instead of individual options.
|
|
public function update_user_option($option, $value) {
|
|
// If the user id has not been set return FALSE.
|
|
if( $this->user_id == 0 ) { return FALSE; }
|
|
|
|
// Store the value in the array.
|
|
$this->user_options[$option] = $value;
|
|
|
|
// Write the array to the database.
|
|
update_user_meta( $this->user_id, 'wp_statistics', $this->user_options );
|
|
}
|
|
|
|
// This function is similar to update_option, but it only stores the option in the array. This save some writing to the database if you have multiple values to update.
|
|
public function store_option($option, $value) {
|
|
$this->options[$option] = $value;
|
|
}
|
|
|
|
// This function is similar to update_user_option, but it only stores the option in the array. This save some writing to the database if you have multiple values to update.
|
|
public function store_user_option($option, $value) {
|
|
// If the user id has not been set return FALSE.
|
|
if( $this->user_id == 0 ) { return FALSE; }
|
|
|
|
$this->user_options[$option] = $value;
|
|
}
|
|
|
|
// This function saves the current options array to the database.
|
|
public function save_options() {
|
|
update_option('wp_statistics', $this->options);
|
|
}
|
|
|
|
// This function saves the current user options array to the database.
|
|
public function save_user_options() {
|
|
if( $this->user_id == 0 ) { return FALSE; }
|
|
|
|
update_user_meta( $this->user_id, 'wp_statistics', $this->user_options );
|
|
}
|
|
|
|
// This function check to see if an option is currently set or not.
|
|
public function isset_option($option) {
|
|
if( !is_array($this->options) ) { return FALSE; }
|
|
|
|
return array_key_exists( $option, $this->options );
|
|
}
|
|
|
|
// This function check to see if a user option is currently set or not.
|
|
public function isset_user_option($option) {
|
|
if( $this->user_id == 0 ) { return FALSE; }
|
|
if( !is_array($this->user_options) ) { return FALSE; }
|
|
|
|
return array_key_exists( $option, $this->user_options );
|
|
}
|
|
|
|
// During installation of WP Statistics some inital data needs to be loaded in to the database so errors are not displayed.
|
|
// This function will add some inital data if the tables are empty.
|
|
public function Primary_Values() {
|
|
|
|
$this->result = $this->db->query("SELECT * FROM {$this->tb_prefix}statistics_useronline");
|
|
|
|
if( !$this->result ) {
|
|
|
|
$this->db->insert(
|
|
$this->tb_prefix . "statistics_useronline",
|
|
array(
|
|
'ip' => $this->get_IP(),
|
|
'timestamp' => $this->Current_Date('U'),
|
|
'date' => $this->Current_Date(),
|
|
'referred' => $this->get_Referred(),
|
|
'agent' => $this->agent['browser'],
|
|
'platform' => $this->agent['platform'],
|
|
'version' => $this->agent['version']
|
|
)
|
|
);
|
|
}
|
|
|
|
$this->result = $this->db->query("SELECT * FROM {$this->tb_prefix}statistics_visit");
|
|
|
|
if( !$this->result ) {
|
|
|
|
$this->db->insert(
|
|
$this->tb_prefix . "statistics_visit",
|
|
array(
|
|
'last_visit' => $this->Current_Date(),
|
|
'last_counter' => $this->Current_date('Y-m-d'),
|
|
'visit' => 1
|
|
)
|
|
);
|
|
}
|
|
|
|
$this->result = $this->db->query("SELECT * FROM {$this->tb_prefix}statistics_visitor");
|
|
|
|
if( !$this->result ) {
|
|
|
|
$this->db->insert(
|
|
$this->tb_prefix . "statistics_visitor",
|
|
array(
|
|
'last_counter' => $this->Current_date('Y-m-d'),
|
|
'referred' => $this->get_Referred(),
|
|
'agent' => $this->agent['browser'],
|
|
'platform' => $this->agent['platform'],
|
|
'version' => $this->agent['version'],
|
|
'ip' => $this->get_IP(),
|
|
'location' => '000'
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
// This function processes a string that represents an IP address and returns either FALSE if it's invalid or a valid IP4 address.
|
|
private function get_ip_value( $ip ) {
|
|
// Reject anything that's not a string.
|
|
if( ! is_string( $ip ) ) {
|
|
return false;
|
|
}
|
|
|
|
// Trim off any spaces.
|
|
$ip = trim( $ip );
|
|
|
|
// Process IPv4 and v6 addresses separately.
|
|
if( $this->isValidIPv6( $ip ) ) {
|
|
// Reject any IPv6 addresses if IPv6 is not compiled in to this version of PHP.
|
|
if( ! defined( 'AF_INET6' ) ) {
|
|
return false;
|
|
}
|
|
} else {
|
|
// Trim off any port values that exist.
|
|
if( strstr( $ip, ':' ) !== FALSE ) {
|
|
$temp = explode( ':', $ip );
|
|
$ip = $temp[0];
|
|
}
|
|
|
|
// Check to make sure the http header is actually an IP address and not some kind of SQL injection attack.
|
|
$long = ip2long( $ip );
|
|
|
|
// ip2long returns either -1 or FALSE if it is not a valid IP address depending on the PHP version, so check for both.
|
|
if( $long == -1 || $long === FALSE ) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// If the ip address is blank, reject it.
|
|
if( $ip == '' ) {
|
|
return false;
|
|
}
|
|
|
|
// We're got a real IP address, return it.
|
|
return $ip;
|
|
|
|
}
|
|
|
|
// This function returns the current IP address of the remote client.
|
|
public function get_IP() {
|
|
|
|
// Check to see if we've already retrieved the IP address and if so return the last result.
|
|
if( $this->ip !== FALSE ) {
|
|
return $this->ip;
|
|
}
|
|
|
|
// By default we use the remote address the server has.
|
|
if( array_key_exists( 'REMOTE_ADDR', $_SERVER ) ) {
|
|
$temp_ip = $this->get_ip_value( $_SERVER['REMOTE_ADDR'] );
|
|
} else {
|
|
$temp_ip = '127.0.0.1';
|
|
}
|
|
|
|
if( FALSE !== $temp_ip ) {
|
|
$this->ip = $temp_ip;
|
|
}
|
|
|
|
/* Check to see if any of the HTTP headers are set to identify the remote user.
|
|
* These often give better results as they can identify the remote user even through firewalls etc,
|
|
* but are sometimes used in SQL injection attacks.
|
|
*
|
|
* We only want to take the first one we find, so search them in order and break when we find the first
|
|
* one.
|
|
*
|
|
*/
|
|
$envs = array( 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED' );
|
|
|
|
foreach( $envs as $env ) {
|
|
$temp_ip = $this->get_ip_value( getenv( $env ) );
|
|
|
|
if( FALSE !== $temp_ip ) {
|
|
$this->ip = $temp_ip;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
// If no valid ip address has been found, use 127.0.0.1 (aka localhost).
|
|
if( FALSE === $this->ip ) {
|
|
$this->ip = '127.0.0.1';
|
|
}
|
|
|
|
return $this->ip;
|
|
}
|
|
|
|
/**
|
|
* Validate an IPv6 IP address
|
|
*
|
|
* @param string $ip
|
|
* @return boolean - true/false
|
|
*/
|
|
private function isValidIPv6( $ip ) {
|
|
if( false === filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// This function calls the user agent parsing code.
|
|
public function get_UserAgent() {
|
|
|
|
// Parse the agent stirng.
|
|
try
|
|
{
|
|
$agent = parse_user_agent();
|
|
}
|
|
catch( Exception $e )
|
|
{
|
|
$agent = array( 'browser' => 'Unknown', 'platform' => 'Unknown', 'version' => 'Unknown' );
|
|
}
|
|
|
|
// null isn't a very good default, so set it to Unknown instead.
|
|
if( $agent['browser'] == null ) { $agent['browser'] = "Unknown"; }
|
|
if( $agent['platform'] == null ) { $agent['platform'] = "Unknown"; }
|
|
if( $agent['version'] == null ) { $agent['version'] = "Unknown"; }
|
|
|
|
// Uncommon browsers often have some extra cruft, like brackets, http:// and other strings that we can strip out.
|
|
$strip_strings = array('"', "'", '(', ')', ';', ':', '/', '[', ']', '{', '}', 'http' );
|
|
foreach( $agent as $key => $value ) {
|
|
$agent[$key] = str_replace( $strip_strings, '', $agent[$key] );
|
|
}
|
|
|
|
return $agent;
|
|
}
|
|
|
|
// This function will return the referrer link for the current user.
|
|
public function get_Referred($default_referrer = false) {
|
|
|
|
if( $this->referrer !== false ) { return $this->referrer; }
|
|
|
|
$this->referrer = '';
|
|
|
|
if( isset($_SERVER['HTTP_REFERER']) ) { $this->referrer = $_SERVER['HTTP_REFERER']; }
|
|
if( $default_referrer ) { $this->referrer = $default_referrer; }
|
|
|
|
$this->referrer = esc_sql(strip_tags($this->referrer) );
|
|
|
|
if( !$this->referrer ) { $this->referrer = get_bloginfo('url'); }
|
|
|
|
if( $this->get_option( 'addsearchwords', false ) ) {
|
|
// Check to see if this is a search engine referrer
|
|
$SEInfo = $this->Search_Engine_Info( $this->referrer );
|
|
|
|
if( is_array( $SEInfo ) ) {
|
|
// If we're a known SE, check the query string
|
|
if( $SEInfo['tag'] != '' ) {
|
|
$result = $this->Search_Engine_QueryString( $this->referrer );
|
|
|
|
// If there were no search words, let's add the page title
|
|
if( $result == '' || $result == 'No search query found!' ) {
|
|
$result = wp_title('', false);
|
|
if( $result != '' ) {
|
|
$this->referrer = esc_url( add_query_arg( $SEInfo['querykey'], urlencode( '~"' . $result . '"' ), $this->referrer ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $this->referrer;
|
|
}
|
|
|
|
// This function returns a date string in the desired format with a passed in timestamp.
|
|
public function Local_Date($format, $timestamp ) {
|
|
return date( $format, $timestamp + $this->tz_offset );
|
|
}
|
|
|
|
// This function returns a date string in the desired format.
|
|
public function Current_Date($format = 'Y-m-d H:i:s', $strtotime = null, $relative = null) {
|
|
|
|
if( $strtotime ) {
|
|
if( $relative ) {
|
|
return date($format, strtotime("{$strtotime} day", $relative) + $this->tz_offset );
|
|
}
|
|
else {
|
|
return date($format, strtotime("{$strtotime} day") + $this->tz_offset );
|
|
}
|
|
} else {
|
|
return date($format, time() + $this->tz_offset);
|
|
}
|
|
}
|
|
|
|
// This function returns a date string in the desired format.
|
|
public function Real_Current_Date($format = 'Y-m-d H:i:s', $strtotime = null, $relative = null) {
|
|
|
|
if( $strtotime ) {
|
|
if( $relative ) {
|
|
return date($format, strtotime("{$strtotime} day", $relative) );
|
|
}
|
|
else {
|
|
return date($format, strtotime("{$strtotime} day") );
|
|
}
|
|
} else {
|
|
return date($format, time());
|
|
}
|
|
}
|
|
|
|
// This function returns an internationalized date string in the desired format.
|
|
public function Current_Date_i18n($format = 'Y-m-d H:i:s', $strtotime = null, $day=' day') {
|
|
|
|
if( $strtotime ) {
|
|
return date_i18n($format, strtotime("{$strtotime}{$day}") + $this->tz_offset );
|
|
} else {
|
|
return date_i18n($format, time() + $this->tz_offset);
|
|
}
|
|
}
|
|
|
|
public function strtotimetz( $timestring ) {
|
|
return strtotime( $timestring ) + $this->tz_offset;
|
|
}
|
|
|
|
public function timetz() {
|
|
return time() + $this->tz_offset;
|
|
}
|
|
|
|
// This function checks to see if a search engine exists in the current list of search engines.
|
|
public function Check_Search_Engines ($search_engine_name, $search_engine = null) {
|
|
|
|
if( strstr($search_engine, $search_engine_name) ) {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// This function returns an array of information about a given search engine based on the url passed in.
|
|
// It is used in several places to get the SE icon or the sql query to select an individual SE from the database.
|
|
public function Search_Engine_Info($url = false) {
|
|
|
|
// If no URL was passed in, get the current referrer for the session.
|
|
if(!$url) {
|
|
$url = isset($_SERVER['HTTP_REFERER']) ? $this->get_Referred() : false;
|
|
}
|
|
|
|
// If there is no URL and no referrer, always return false.
|
|
if($url == false) {
|
|
return false;
|
|
}
|
|
|
|
// Parse the URL in to it's component parts.
|
|
$parts = parse_url($url);
|
|
|
|
// Get the list of search engines we currently support.
|
|
$search_engines = wp_statistics_searchengine_list();
|
|
|
|
// Loop through the SE list until we find which search engine matches.
|
|
foreach( $search_engines as $key => $value ) {
|
|
$search_regex = wp_statistics_searchengine_regex($key);
|
|
|
|
preg_match( '/' . $search_regex . '/', $parts['host'], $matches);
|
|
|
|
if( isset($matches[1]) )
|
|
{
|
|
// Return the first matched SE.
|
|
return $value;
|
|
}
|
|
}
|
|
|
|
// If no SE matched, return some defaults.
|
|
return array('name' => 'Unknown', 'tag' => '', 'sqlpattern' => '', 'regexpattern' => '', 'querykey' => 'q', 'image' => 'unknown.png' );
|
|
}
|
|
|
|
// This function returns an array of information about a given search engine based on the url passed in.
|
|
// It is used in several places to get the SE icon or the sql query to select an individual SE from the database.
|
|
public function Search_Engine_Info_By_Engine($engine = false) {
|
|
|
|
// If there is no URL and no referrer, always return false.
|
|
if($engine == false) {
|
|
return false;
|
|
}
|
|
|
|
// Get the list of search engines we currently support.
|
|
$search_engines = wp_statistics_searchengine_list();
|
|
|
|
if( array_key_exists( $engine, $search_engines ) ) {
|
|
return $search_engines[$engine];
|
|
}
|
|
|
|
// If no SE matched, return some defaults.
|
|
return array('name' => 'Unknown', 'tag' => '', 'sqlpattern' => '', 'regexpattern' => '', 'querykey' => 'q', 'image' => 'unknown.png' );
|
|
}
|
|
|
|
// This function will parse a URL from a referrer and return the search query words used.
|
|
public function Search_Engine_QueryString($url = false) {
|
|
|
|
// If no URL was passed in, get the current referrer for the session.
|
|
if(!$url) {
|
|
$url = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : false;
|
|
}
|
|
|
|
// If there is no URL and no referrer, always return false.
|
|
if($url == false) {
|
|
return false;
|
|
}
|
|
|
|
// Parse the URL in to it's component parts.
|
|
$parts = parse_url($url);
|
|
|
|
// Check to see if there is a query component in the URL (everything after the ?). If there isn't one
|
|
// set an empty array so we don't get errors later.
|
|
if( array_key_exists('query',$parts) ) { parse_str($parts['query'], $query); } else { $query = array(); }
|
|
|
|
// Get the list of search engines we currently support.
|
|
$search_engines = wp_statistics_searchengine_list();
|
|
|
|
// Loop through the SE list until we find which search engine matches.
|
|
foreach( $search_engines as $key => $value ) {
|
|
$search_regex = wp_statistics_searchengine_regex($key);
|
|
|
|
preg_match( '/' . $search_regex . '/', $parts['host'], $matches);
|
|
|
|
if( isset($matches[1]) )
|
|
{
|
|
// Check to see if the query key the SE uses exists in the query part of the URL.
|
|
if( array_key_exists($search_engines[$key]['querykey'], $query) ) {
|
|
$words = strip_tags($query[$search_engines[$key]['querykey']]);
|
|
}
|
|
else {
|
|
$words = '';
|
|
}
|
|
|
|
// If no words were found, return a pleasant default.
|
|
if( $words == '' ) { $words = 'No search query found!'; }
|
|
return $words;
|
|
}
|
|
}
|
|
|
|
// We should never actually get to this point, but let's make sure we return something
|
|
// just in case something goes terribly wrong.
|
|
return 'No search query found!';
|
|
}
|
|
|
|
public function Get_Historical_Data($type, $id = '') {
|
|
|
|
$count = 0;
|
|
|
|
switch( $type ) {
|
|
case 'visitors':
|
|
if( array_key_exists( 'visitors', $this->historical ) ) {
|
|
return $this->historical['visitors'];
|
|
}
|
|
else {
|
|
$result = $this->db->get_var("SELECT value FROM {$this->tb_prefix}statistics_historical WHERE category = 'visitors'");
|
|
if( $result > $count ) { $count = $result; }
|
|
$this->historical['visitors'] = $count;
|
|
}
|
|
|
|
break;
|
|
case 'visits':
|
|
if( array_key_exists( 'visits', $this->historical ) ) {
|
|
return $this->historical['visits'];
|
|
}
|
|
else {
|
|
$result = $this->db->get_var("SELECT value FROM {$this->tb_prefix}statistics_historical WHERE category = 'visits'");
|
|
if( $result > $count ) { $count = $result; }
|
|
$this->historical['visits'] = $count;
|
|
}
|
|
|
|
break;
|
|
case 'uri':
|
|
if( array_key_exists( $id, $this->historical ) ) {
|
|
return $this->historical[$id];
|
|
}
|
|
else {
|
|
$result = $this->db->get_var($this->db->prepare("SELECT value FROM {$this->tb_prefix}statistics_historical WHERE category = 'uri' AND uri = %s", $id));
|
|
if( $result > $count ) { $count = $result; }
|
|
$this->historical[$id] = $count;
|
|
}
|
|
|
|
break;
|
|
case 'page':
|
|
if( array_key_exists( $id, $this->historical ) ) {
|
|
return $this->historical[$id];
|
|
}
|
|
else {
|
|
$result = $this->db->get_var($this->db->prepare("SELECT value FROM {$this->tb_prefix}statistics_historical WHERE category = 'uri' AND page_id = %d", $id));
|
|
if( $result > $count ) { $count = $result; }
|
|
$this->historical[$id] = $count;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
return $count;
|
|
}
|
|
|
|
public function feed_detected() {
|
|
$this->is_feed = true;
|
|
}
|
|
|
|
public function check_feed() {
|
|
return $this->is_feed;
|
|
}
|
|
|
|
public function get_country_codes() {
|
|
if( $this->country_codes == false ) {
|
|
$ISOCountryCode = array();
|
|
include( $this->plugin_dir . "/includes/functions/country-codes.php");
|
|
$this->country_codes = $ISOCountryCode;
|
|
}
|
|
|
|
return $this->country_codes;
|
|
}
|
|
} |