MySQL + PHP - Querying relative format dates - php

I have two tables: steps and flows.
steps has many flows.
steps has relative_time (string) column.
flows has active_on (nullable, timestamp) column.
Steps relative_time stores relative formats and their values looks like: "+1 year", "+2 days", "+30 days", etc.
Flows active_on is set when a flow gets activated by user and it looks like: "2017-12-30 00:00:00".
Every time I want to know when a flow will expire, I select it from database and, in PHP (Laravel, Carbon), I execute:
/**
* #return null|Carbon
*/
public function getExpiresAtAttribute()
{
if (!$this->active_on) {
return null;
}
// Access the relative time for step (for example: "+3 days").
$relativeTime = $this->step->relative_time;
// Adds the limit time to the activation date,
// turning it possible to check when the current flow
// will "expires".
return $this->active_on->modify($relativeTime);
}
Problem
It's easy to check expires at value in PHP. The problem is that now I need to select only flows that are "expired" directly from database and I don't know if it is possible by using this approach. How can I achieve this?

You could store in relative_time the number of days, instead of the php date interval. This way you can query:
SELECT * FROM flows, steps WHERE flows.step_id = step.id AND NOW() > ADDDATE(flows.active_on, steps.relative_time)
This way you get all the flows expired.
No need to change database structure actually. You could create a migration to transform relative_time from dateinterval to number of days (is a string field).
foreach (Steps::all() as $step) {
$step->update([
'relative_time' => strtotime($step->relative_time,0)/(3600*24);
]);
}
Then you can adjust the getExpiresAtAttribute:
/**
* #return null|Carbon
*/
public function getExpiresAtAttribute()
{
if (!$this->active_on) {
return null;
}
// Access the relative time for step (for example: "+3 days").
$relativeTime = $this->step->relative_time;
// Adds the limit time to the activation date,
// turning it possible to check when the current flow
// will "expires".
return $this->active_on->modify("+$relativeTime days");
}

Related

How can I check if a user is online in WordPress by his id?

I want to show an online status on my website if an other user is online. So for example if user A wants to know if user B is available, I want to show an online sign.
I know that there is a function in WordPress called is_user_logged_in() but this function works only for the current user. https://developer.wordpress.org/reference/functions/is_user_logged_in/
So is there anyone who has an idea how I can get this done?
This is the logic:
if ( user_online( $user_id ) ) {
return 'Online';
} else {
return 'Absent';
}
You might use Transients API to get users's status.
Create a user-online-update function that you hook on init. For example:
// get logged-in users
$logged_in_users = get_transient('online_status');
// get current user ID
$user = wp_get_current_user();
// check if the current user needs to update his online status;
// status no need to update if user exist in the list
// and if his "last activity" was less than let's say ...15 minutes ago
$no_need_to_update = isset($logged_in_users[$user->ID])
&& $logged_in_users[$user->ID] > (time() - (15 * 60));
// update the list if needed
if (!$no_need_to_update) {
$logged_in_users[$user->ID] = time();
set_transient('online_status', $logged_in_users, $expire_in = (30*60)); // 30 mins
}
This should run on each page load, but the transient will be updated only if required. If you have a large number of users online you might want to increase the "last activity" time frame to reduce db writes, but 15 minutes is more than enough for most sites.
Now to check if the user is online, simply look inside that transient to see if a certain user is online, just like you did above:
// get logged in users
$logged_in_users = get_transient('online_status');
// for eg. on author page
$user_to_check = get_query_var('author');
$online = isset($logged_in_users[$user_to_check])
&& ($logged_in_users[$user_to_check] > (time() - (15 * 60)));
The transient expires in 30 minutes if there's no activity at all. But in case you have users online all the time it won't expire, so you might want to clean-up that transient periodically by hooking another function on a twice-daily event or something like that. This function would remove old $logged_in_users entries...
Source: https://wordpress.stackexchange.com/a/34434
First get the user id of the user B by
$user_id_B = get_current_user_id();
Now here give the condition for the particular user B to check whether he is online or not
if(is_user_logged_in()){
if( $user_id_B == 'user id of B')
{
return 'Online'; (or echo 'online';)
}
}
By this you will get the presence of user B.

How to get all cache entries with a tag on Laravel

I'm building a login throttling system using Laravel, which I use to save every failed login on a cache Database. (I use Redis).
The code:
class FailedLogins
{
const NUM_FAILURES_TO_LOCK = 30,
TIME_RANGE = 10; // In minutes
public function add($email, $ip = null)
{
if (is_null($ip))
$ip = request()->ip();
$index = md5($email . $ip);
Cache::tags('failed.logins')->put($index, 1, self::TIME_RANGE);
}
public function hasTooMany()
{
$numFailedLogins = count(Cache::tags('failed.logins')->get());
return ($numFailedLogins >= self::NUM_FAILURES_TO_LOCK);
}
}
The issue is on the hasTooMany method, I have to provide a key parameter on the get method. What I was trying to do on this line: Cache::tags('failed.logins')->get() is to get all entries with the failed.logins tag, so I can count how many there are.
Well, that is not working, because I can't do that. So what do you recommend me to use so I can solve it? If it's a Redis only solutions that's fine too.
You could use redis hashes:
http://redis.io/commands/hset
But you can't set individual expiration date on hash keys, so you would have to delete them manually, or use main key with hour in it, like:
failed.logins:08 and expire whole.

Date format issue on admin pannel

I have a website on magento framework. When i logged in admin panel click on Customer > Manage customer then all the customer detail are showing with ( Name, Email, Avtar, Group Phone No , ZIP, Country, State, Customer since, Action )
When user sign up on 2 OCT 2015 then the date is showing in Customer since is Feb, 10,2015. It is picking month as a date and date as a month.
Will you please tell me how can i change the format of Customer Since tab
try this
magento have date format in app/code/core/Mage/core/Model/Date.php file. if you want to change in format you can do that by overriding the model.
Note : never modify core files
I closely looking the issue and found that your month and date are swapping with each other.
try this
You can copy the file to \app\code\local\Mage\Eav\Model\Entity\Attribute\Backend\Time\Created.php and modify the functions necessary, once modified and uploaded it will take precedence over the core file and no worries about being overwritten during an update (though, if they update and that file is part of it, I would hope it would be to fix the problem)
the update to that file is here, so nobody needs to hop pages to find it
Replace beforeSave with this:
public function beforeSave($object)
{
$attributeCode = $this->getAttribute()->getAttributeCode();
$date = $object->getData($attributeCode);
if (is_null($date)) {
if ($object->isObjectNew()) {
$object->setData($attributeCode, Varien_Date::now());
}
} else {
// ADD THIS
$date = strtotime($date);
// convert to UTC
$zendDate = Mage::app()->getLocale()->utcDate(null, $date, true, $this->_getFormat($date));
$object->setData($attributeCode, $zendDate->getIso());
}
return $this;
}
This also needs to be corrected on the way out of the database. Replace afterLoad with this:
public function afterLoad($object)
{
$attributeCode = $this->getAttribute()->getAttributeCode();
$date = $object->getData($attributeCode);
// ADD THIS
if (!is_null($date)) {
$date = strtotime($date);
}
$zendDate = Mage::app()->getLocale()->storeDate(null, $date, true, $this->_getFormat($date));
$object->setData($attributeCode, $zendDate->getIso());
parent::afterLoad($object);
return $this;
}
I think this might help you.

Adapt datetime field in Yii automatically to right format

I'd like to have a field inside a form, which has a format like dd.MM.yyyy HH:mm. I've done this with the date validator.
But now I have the problem, that the user always have to enter a time, not only the specified day. Is it possible automatically set the time to 00:00 when the user only enters the date?
Thanks for your help.
protected function beforeSave()
{
if ( strpos(trim(this->date_field), ' ') !== false ) {
$this->date_field = sprintf('%s 00:00', $this->date_field);
}
return parent::beforeSave();
}

Viewing events in FullCalendar ordered by event ID instead of start timestamp

I have a calendar set up and when viewing the month view I want to display the events which have been created by their ID and not the time they are due to start.
Is this possible? And if so, how would I go about changing the code to display the events in this manner?
Great solution!
I've used it and adapted it for my needs. I'm using JSON feeds.
Important: the first condition is to make sure all the events are sorted by start date.
Then, if you want to sort by title :
function segCmp(a, b) {
var tryCmp = (b.msLength - a.msLength) * 100 + (a.event.start - b.event.start);
if (tryCmp == 0) {
return (a.event.title.toLowerCase() >= b.event.title.toLowerCase()) ? 1: 0;
}
return tryCmp;
}
I've also used it another way.
I've added a custom attribute to each event of the JSON feed called 'colOrder'(it could be anything) and gave it integer values (1,2,3...). 1 is for the first event I want to see, 2 for the second...
Then I customized the function to use the colOrder attribute to sort the events.
function segCmp(a, b) {
var tryCmp = (b.msLength - a.msLength) * 100 + (a.event.start - b.event.start);
if (tryCmp == 0) {
if (!isNaN(a.event.colOrder) && !isNaN(b.event.colOrder))
return (a.event.colOrder - b.event.colOrder);
}
return tryCmp;
}
Add ORDER BY id ASC to your query.
no easy way to do this yet, but when this issue is implemented, should be easy:
http://code.google.com/p/fullcalendar/issues/detail?id=364
Long time since last post, but just in case someone need it (like me):
change in fullcalendar.js
function segCmp(a, b) {
return (b.msLength - a.msLength) * 100 + (a.event.start - b.event.start);
}
to
function segCmp(a, b) {
var tryCmp = (b.msLength - a.msLength) * 100 + (a.event.start - b.event.start);
if (tryCmp == 0)
return (a.event.id - b.event.id);
return tryCmp;
}
it worked for me

Categories