如何显示上次登录来自哪个国家/城市



我有一个问题,我永远无法独自解决,我希望有人能在这里帮助我,谢谢你的回答,我感谢你的帮助。

基本上我有两个函数,一个设置上次登录和当前登录的日期,另一个获取第一个函数设置的登录。使用简单的快捷代码,我可以显示上次登录和当前登录的日期。这很好,但除了日期之外,我还想显示登录的位置和使用的浏览器。

地理定位功能

为此,我编写了一个地理定位函数,返回lat和long值,然后通过反向地理编码获得可读地址。这也很有效。

获取浏览器功能

然后我写了另一个小函数,让用户通过用户代理使用浏览器,这也非常有效。

主要问题

地理定位和get浏览器的问题是函数总是返回当前值。但那不是我想要的。我想做的是在登录时存储位置和浏览器(就像我处理日期一样(,然后查看它们。这样,如果您在00:00在A点登录,情况将保持不变。目前它并没有这样做,因为它只是停留在你现在的位置,而不是00:00时的位置。

那么,我怎样才能像记忆日期一样记住位置和浏览器呢?我指定我正在使用wordpress在我的网站上工作。

日期功能

// Function that get last login
function get_last_login($user_id, $prev = null) {
$last_login = get_user_meta($user_id);
$time = current_time( 'timestamp' );
if(isset($last_login['_last_login_prev'][0]) && $prev) {
$last_login = get_user_meta($user_id, '_last_login_prev', 'true' );
} 
else if(isset($last_login['_last_login'][0])) {
$last_login = get_user_meta($user_id, '_last_login', 'true' );
} 
else {
update_user_meta( $user_id, '_last_login', $time );
$last_login = $last_login['_last_login'][0];
} return $last_login;
}
// Shortcode (1) - Last Login Date 
function last_login_date() {
global $current_user;
echo '<div class="lastlogin"> '.date("j/m/Y - H:i", get_last_login($current_user->ID, true)).' </div>';
}   add_shortcode('lastlogin', 'last_login_date');
// Shortcode (2) - Current Login Date
function current_login_date() {
global $current_user;
echo '<p>Current: Login date: '. date("j M Y - H:i", get_last_login($current_user->ID)). '</p>';
}   add_shortcode('currentlogin', 'current_login_date');

地理定位功能

//enqueue my-script
wp_enqueue_script( 'my-script', trailingslashit( get_stylesheet_directory_uri() ) . 'woocommerce/myaccount/assets/my-script.js', array( 'jquery-min' ), wp_get_theme()->version, true );
//pass ajax and a nonce to my-script
wp_localize_script( 'my-script', 'localize', array(
'_ajax_url' => admin_url( 'admin-ajax.php' ),
'_ajax_nonce' => wp_create_nonce( '_ajax_nonce' ),
));
add_action( 'wp_ajax__wpso_73934145', function () {
if ( check_ajax_referer( '_ajax_nonce' ) ) {
$user_id = get_current_user_id();
$latitude = $_POST['latitude'];
$longitude = $_POST['longitude'];
$openStreetMapObject = $_POST['openStreetMapObject'];
$meta_key = '_user_position';
$meta_value = array(
'latitude' => $latitude,
'longitude' => $longitude,
'openStreetMapObject' => $openStreetMapObject,
);
update_user_meta( $user_id, $meta_key, $meta_value );
wp_send_json_success( $meta_value );
} else {
wp_send_json_error();
};
wp_die();
});

my-script.js(用于地理定位功能(

console.log( 'my-script.js has been successfully loaded' );
if ( navigator.geolocation ) {
window.navigator.geolocation.getCurrentPosition( function( position ) {
let lat = position.coords.latitude;
let lon = position.coords.longitude;
//https://nominatim.org/release-docs/latest/api/Reverse/
$.getJSON(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lon}`, function( object ) {

let adress = object.address;

$.ajax( {
type: 'POST',
url: localize._ajax_url,
data: {
_ajax_nonce: localize._ajax_nonce,
action: '_wpso_73934145',
latitude: lat,
longitude: lon,
openStreetMapObject: adress,
},
success: function ( response ) {
console.log( response.data );
},
} );
} );
} );
};

my-template.php(查看所有内容(

$user_id = get_current_user_id();
$meta_key = '_user_position';

if ( metadata_exists( 'user', $user_id, $meta_key ) ) {

$meta_value = get_user_meta( $user_id, $meta_key, true);
//var_dump( $meta_value );
//var_dump( $meta_value['openStreetMapObject']["ISO3166-2-lvl6"] );
//echo $meta_value['openStreetMapObject']['county'];
//echo $meta_value['openStreetMapObject']['country'];
//var_dump( $meta_value['openStreetMapObject']['city_district'] );
//echo $meta_value['openStreetMapObject']['city_district'] ;
$mybrowser = $_SERVER['HTTP_USER_AGENT'] . "nn";
$browser = get_browser(null, true);

$mybrowser = $_SERVER['HTTP_USER_AGENT'];
if (strpos(strtolower($mybrowser), "safari/") and strpos(strtolower($mybrowser), "opr/")) {
// OPERA
$mybrowsername="Opera";
} else if (strpos(strtolower($mybrowser), "safari/") and strpos(strtolower($mybrowser), "chrome/")) {
// CHROME
$mybrowsername="Chrome";
} else if (strpos(strtolower($mybrowser), "msie")) {
// INTERNET EXPLORER
$mybrowsername="Internet Explorer";
} else if (strpos(strtolower($mybrowser), "firefox/")) {
// FIREFOX
$mybrowsername="Firefox";
} else if (strpos(strtolower($mybrowser), "safari/") and strpos(strtolower($mybrowser), "opr/")==false and strpos(strtolower($mybrowser), "chrome/")==false) {
// SAFARI
$mybrowsername="Safari";
} else {
// OUT OF DATA
$mybrowsername="OUT OF DATA";
};
echo $mybrowsername;
echo $meta_value['openStreetMapObject']['county'];
echo $meta_value['openStreetMapObject']['country'];
echo $meta_value['openStreetMapObject']["ISO3166-2-lvl6"];

} else {
echo 'You need to share your location';
};

您当前的代码无法实现您想要实现的目标,您需要在每次用户执行登录时保存一个登录活动,其中包括您稍后想要获取的所有详细信息。

这是一个完整的例子

1.修改登录表单,并从navigator.geolocation中为latitudelongitude添加两个隐藏的输入字段,您可以通过login_form操作挂钩执行此操作

add_action('login_form', function() {
?> 
<input type="hidden" name="latitude" id="latitude" />
<input type="hidden" name="longitude" id="longitude" />
<script>
if ( navigator.geolocation ) {
navigator.geolocation.getCurrentPosition( (position) => {
const latitude = document.getElementById('latitude') // get the latitude input field
const longitude = document.getElementById('longitude') // get the longitude input field
latitude.value = position.coords.latitude  // assign the latitude input value
longitude.value = position.coords.longitude //  assign the longitude input value
})
}
</script>
<?php
});

2.处理以后要提取的所有数据,并将其保存在用户元上。一旦用户成功登录,您可以通过wp_login操作挂钩注入

add_action('wp_login', function( $uname, $user) {
$limit = 5; // the activity limit you want to save
$lat = $_REQUEST['latitude']; // get the latitude value from the login request
$long = $_REQUEST['longitude']; // get the longitude value from the login request
$browser = detectBrowser(); // generate browser data based on user agent
//generate location if latitude and longitude is present. Otherwise, use the user ip to generate the location
$location = $lat && $long && getLatLongLocation($lat, $long)->address ? getLatLongLocation($lat, $long)->address : getIPLocation();

$date = date('j/m/Y - H:i');
// Format the data to be saved as login activity
$loginDetails = [
'date' => $date,
'browser' => [
'ua' => $_SERVER['HTTP_USER_AGENT'],
'name' => ( isset( $browser->client ) && isset($browser->client->name) ) ? $browser->client->name : '',
'device_type' => ( isset( $browser->device ) && isset($browser->device->type) ) ? $browser->device->type : '',
'os' => ( isset( $browser->os ) && isset($browser->os->name) ) ? $browser->os->name : '',
],
'location' => [
'ip' => $_SERVER['REMOTE_ADDR'],
'city' =>  isset( $location->city ) ? $location->city : '',
'country' =>  isset( $location->country ) ? $location->country : '',
'lat' => $lat,
'long' => $long
]
];
$logins = get_user_meta($user->ID, '_login_activity', true); //  get the user meta that holds the login activities
$logins = $logins ? $logins : []; // pass empty array if the user meta does not contain anything yet
array_unshift($logins, $loginDetails); // push the recent $loginDetails to the top of the login activities array
//Save the login activities, only save the array from 0 to $limit position
update_user_meta( $user->ID, '_login_activity', array_slice($logins, 0, $limit) );
}, 10, 2);

在上面的代码中,您使用以下函数向第三方API请求获取数据;

// Get location details from IP address
function getIPLocation( $ip = false) {
$ip = $ip ? $ip : $_SERVER['REMOTE_ADDR'];
$details = json_decode(file_get_contents("https://ipinfo.io/{$ip}/json"));
return $details;
}
// Get location details from latitude and longitude
function getLatLongLocation( $lat = false, $long = false) {
if ( !$lat || !$long ) 
return;
$query = "format=json&lat=$lat&lon=$long&limit=1&email=test@email.com";
$details = json_decode(file_get_contents("https://nominatim.openstreetmap.org/reverse?$query"));
return $details;
}
// Get browser details from user-agent
function detectBrowser( $ua = false ) {
$ua = $ua ? $ua : $_SERVER['HTTP_USER_AGENT'];
$ua = urlencode( $ua);
$details = json_decode(file_get_contents("https://api.apicagent.com/?ua={$ua}"));
return $details;
}

您可以通过简单地转储输出来检查这些函数的输出,如;

add_action('wp_head', function() {
$latLongLocation = getLatLongLocation('lat-here', 'long-here');
$ipLocation = getIPLocation('ip-here');
$uaDetails = detectBrowser('user-agent-here');
echo '<pre>', print_r($latLongLocation, 1), '</pre>';
echo '<pre>', print_r($ipLocation, 1), '</pre>';
echo '<pre>', print_r($uaDetails, 1), '</pre>';
});

在添加了对login_formwp_login操作挂钩的修改之后,每次用户执行登录时都应该有一个带有密钥_login_activity的用户元。

现在,您可以简单地创建一个函数来提取值并在任意位置显示。

首先,一个为实时登录记录格式化HTML输出的函数

// display format for individual login activity
function logFormat( $log ) {
if ( !$log || !is_array( $log ) )
return;
return '<div class="login-activity">
<div>Date: '.$log['date'].'</div>
<div>Browser: '.$log['browser']['name'].'</div>
<div>OS: '.$log['browser']['os'].'</div>
<div>City: '.$log['location']['city'].'</div>
<div>Country: '.$log['location']['country'].'</div>
<div>IP: '.$log['location']['ip'].'</div>
</div>';
}

然后是获取所有或单个特定登录记录的功能

// Pull the login activity with dynamic position attribute
function getLoginActivity( $atts ) {
//exit function of user is not logged
if ( !get_current_user_id() )
return;
// get the current user meta
$logins = get_user_meta(get_current_user_id(), '_login_activity', true);
//add shortcode attribute support
$attr = shortcode_atts([
'position' => 'all'
], $atts );
if ( !isset( $logins[0] ) )
return 'No Login Activity';

// Output all login activity if position is left to default
if ($attr['position'] === 'all' ) {
$out = '<div class="all-logins">';
foreach( $logins as $login ) {
$out .= logFormat( $login );
}
return $out. '</div>';
}
//return the login activity with exact position
if ( isset( $logins[ (int) $attr['position'] ] ) )
return logFormat( $logins[ (int) $attr['position'] ] );

return 'No activity with position: '. $attr['position'];
}
add_shortcode('login-activity', 'getLoginActivity'); // add shortcode support

然后,您可以简单地在php文件中的任何位置使用getLoginActivity函数,当前登录详细信息应该是0位置,上一次登录详细信息应是1位置

所以你可以简单地做

echo getLoginActivity(['position' => '0']); // current login data
echo getLoginActivity(['position' => '1']); // last login data
echo getLoginActivity(); // all login data

或通过添加到页面的短代码

[login-activity position="0"]

最新更新