how a $_SESSION actually works and what is the best way to count anonymous visitor? - session

For this question which of the session or cookie will do the desired job ?
I'm intrigued by the results after triggering a $_Session because I thought it only triggered when a visitor accessed the website.
In one day I had 378 accesses to my website or to the server that hosts my website. The whole world is trying to access my website while it is not online (12 countries). But that is not the problem at all!
In less than 30 min there were 20 new visits from 6 different countries. Is it normal ?
Why are these accesses to my website counted when the statistics collected by my host only give me the reloads of pages that I perform (about 14)?
Does the Host already filter bot ?
But that doesn't explain why I get about 200 results from my own ip address when I deleted all windows to my website between tonight and this morning .
Also the increment is multiplied by two instead of being incremented by 1 .
How can I count the number of anonymous visitors every 24 hours who access my website?
Can I limit the duration of a session to 10 seconds ? Does this restriction can filter bots ?
I try to store in one row of specific table :
the auto-increment Id
the unix time of day
the number of visit incremented each time.
for now that's all I need.
Currently the main problem is the increment $_SESSION thats increment by 2 instead of 1 :
function StartSession(){
global $wpdb;
session_set_cookie_params(0, '/', '.website.com');
session_start();
if ( !isset( $_SESSION['visitor'] ) ) {
$countuser = $_SESSION['visitor'] = 1;
}else{
$countuser = ++$_SESSION['visitor'];
}
$users_analytics = $wpdb->prefix . 'antics_users';
$timeanonymesession = time();
$wpdb->insert(
$users_analytics,
array(
'datesession' => $timeanonymesession,
'totalusers' => $countuser
//'iploc' => $new_ip
)
);}
add_action('init', 'StartSession', 1);
If I use a cookie instead of a session, I think I'll have the same problem with incrementing, right?
Edit : in one day the *_SESSION have registered in database more than 1500 visit.
I don't understand why I have so many connection with $_SESSION whereas My Host registered only between 10 and 15 sessions by day (that normally corresponding to my reload page during developpement) ?

Related

Laravel 8 - count clicks but user can't spam the function

In my website I track clicks on a specific link and save the count on database with this function:
public function redirect($url)
{
$data = Class::where('url', $url)->first('clicks');
$cnt = $data->clicks;
$cnt++;
$sql = Class::where('url', $url)->update([
'clicks' => $cnt,
]);
if (!$sql) {
abort(500);
}
return redirect('https://website.com/'.$url);
}
the problem is if someone spam the link , the count goes up. I want stop count if user clicked on link 5mins ago.
he will redirected to the link but count doesn't go up.
I'm new so it's so good if you explain it with details. Thanks
I would create a new table, lets call it link_clicks. You will need 3 columns, one to identify the person, one to get the time and one to identify the link (I dont exactly know how you store the links you want to observe).
So more or less you will have the following table:
link_clicks
user_id
link_id
created_at
If the users are always logged in, I would store the user_id, if they are not logged in, I would store the IP-address. So instead of user_id make a column called ip or ip-address.
Afterwards you can easily get the last click and its time.
--Example
Your new table contains following entry:
user_id = 1, link_id = 1 and created_at = 2021-04-21 19:00:00
Now in your controller you get the current date_time date("Y-m-d H:i:s") and the user id like that: auth()->id(). You can also define your time treshold in minutes e.g max_dif = 5.
Afterwards you can query the table for all clicks for the user. You can either make the time comparision in your where() statement or you can make some comaprison in your php code to check if the time treshhold is reached.

LUA credit card expiry date validation

I have an application collecting credit card data. Before sending the information out to the payment entity I am trying to make sure the information entered is, at least, valid. I already worked out the card number and cvv numbers but I am not so sure about the expiry date. The format I get the info is MMYY. So what I am doing is:
-- Simple function to get current date and times
function getdatetime(tz)
local tz = tz or 'America/New_York';
local luatz = require 'luatz';
local function ts2tt(ts)
return luatz.timetable.new_from_timestamp(ts);
end
local utcnow = luatz.time();
local time_zone = luatz.get_tz(tz);
local datetime_raw = tostring(ts2tt(time_zone:localise(utcnow)));
local year, month, day, hour, min, sec, time_reminder = string.match(datetime_raw, "^(%d%d%d%d)%-(%d%d)%-(%d%d)[Tt](%d%d%.?%d*):(%d%d):(%d%d)()");
return year, month, day, hour, min, sec;
end
local current_year, current_month = getdatetime() -- Get current year/Month
local card_expiry_date = 'YYMM'; -- In the app this actually get a value eg: 2204, 2301, 2010, etc.
local card_exp_year = string.sub(card_expiry_date , 3, 4)
local card_exp_month = string.sub(card_expiry_date , 1, 2)
-- Extract the last two digits of the Year
current_year = string.sub(current_year , 3, 4)
-- Check month is valid
if(card_exp_month < '01' or card_exp_month > '12')then
print("This is not a valid month")
else
-- Check date is this month or after
if((card_exp_year < current_year) or (card_exp_year == current_year and card_exp_month < current_month))then
print("Date cannot be before this month.")
else
print("All is good.")
end
end
I do not know if this is the most elegant solution but it works. However it has a huge bug: it will fail at the end of the century. Since I only know the last two digits of the expiry date year, if a card expires in 2102 for instance and we were in 2099 my logic would wrongly reject the date (02 is less than 99).
I am very aware that me an my simple app will likely not be around by then but it bugs me to leave it like this.
Can anyone please suggest a proper way to do this validation?
Thank you!
Wilmar
Credit cards usually expire within a few years. 3 years is average according to some quick web search. Also the owner of a century only card can be safely assumed to be dead and so is his card account.
So when you get a card with 02 in 2099 there is only one reasonable option.
Calculate two differences and pick the smaller one.
Something like local expiresIn = math.min(math.abs(99-2), math.abs(99-102))

How to check if voucher is expired after it purchased one year.?

I am building a voucher generate system in laravel. This voucher validity period is one year. Now i want do is when user trying to redeem a voucher then user cannot do it because of it is expired. Any one can help me to do this. Because I don't have any idea about this.
This is what I am tried
$voucher = Voucher::where('code', $request->code)->first();
$today = date("Y-m-d H:i:s");
$startdate = $voucher['created_at'];
$offset = strtotime("+365 day");
$enddate = date($startdate, $offset);
$today_date = new \DateTime($today);
$expiry_date = new \DateTime($enddate);
if ($expiry_date < $today_date) {
return response()->json(['error' =>"Voucher is expired"]);
}
Assuming you're storing the vouchers in the database, you can add a valid_until date column and verify that it's in the past before redeeming the voucher.
Basing the expiry date off the created_at field could be problematic in the future if the expiry rules change. For example consider what would happen if after a while you decide that vouchers should actually expire after 6 months. If I had purchased a voucher which was expected to last a year then it wouldn't be fair that mine expires early.
A better approach as mentioned in a previous answer would be to store the expiry date in a separate column in the table. This would make the code that checks for expiry much simpler and also would allow you to have different expiry times if required, e.g. a premium voucher could last for 2 years instead of just one.

Timezone Manipulation

I'm working on a project (online game) where users have the ability to use a coded 'airport' to travel to different countries & cities. Once they have travelled, the cityid within the database will update for example:
cityid = 1 (England - London)
cityid = 2 (USA - LA)
Therefore if a user travels from England to the USA it will store database side cityid = 2.
Now,
Whilst this is functional, I wish to incorporate timezone changes into it (if at all possible) I have tried:
if ($user->cityid == 3)
{
$timestamp ='1502448414'; //Timestamp which you need to convert
$dt = new \DateTime("#$timestamp");
$destinationTimezone = new \DateTimeZone('Mexico/General'); // To which timezone you need to convert
$dt->setTimeZone($destinationTimezone); // Set timezone
echo 'Mexico: '. $dt->format('H:i a'), "\n"; // Echo your changed datetime
}
As you can see, I have used Mexico as a demo to try and figure out my approach.
However, this only fetches the timestamped time rather than the realtime. Im aware, I could simply add the timestamp into a database table and then run a cron every second to update the table but this seems rather a long winded route.
Now within app.php the standard setting is UTC which runs as a realtime clock by returning: date('H:i:s').
My question is (after a lot of google searching) is there a way to manipulate this to make date() output the new time of (USA) when it has been travelled to?
Apologies that I cannot add anymore coding into this question, I have no real idea of how to approach it other than the one stated above.
Using Carbon
if ($user->cityid == 3) {
$dt = \Carbon\Carbon::now("Your current location timezone");
$dt->setTimeZone('Mexico/General');
echo 'Mexico: '. $dt->format('H:i a'), "\n";
}

Redis Transaction with high throughput

My question is about a best practise.
Im sending all simple user page view to redis. What i want to do is for every user,
There should be a list of pages that user ve looked.
That list needs to have a limit of max 20 items.
Lastly, that list needs to have an expiration time (key expiration).
The implemantation is (Im using StackExchange.Redis for applications):
var transaction = _cache.CreateTransaction();
transaction.ListLeftPushAsync(key, JsonConvert.SerializeObject(value), When.Always, CommandFlags.FireAndForget);
transaction.KeyExpireAsync(key, TimeSpan.FromDays(Constants.Constants.TopnUserCacheDurationinDays), CommandFlags.FireAndForget);
if (new Random().Next(7) == 6)
{
transaction.ListTrimAsync(key, 0, Constants.Constants.TopNUserHistoryLimit, CommandFlags.FireAndForget);
}
return transaction.ExecuteAsync();
The question is, is this implemantation is good for my needs. I feel that smth is not right. Because there are ~300 requests in a second. So im sending 1 request with 3 jobs 300 times in a second.
Any suggestions?

Resources