获取登录系统的用户今天从A.M到P.M

时间:2016-01-18 10:20:29

标签: postgresql symfony datetime doctrine query-builder

我有一个实体LoginHistory,可以保存用户的登录和注销时间。我正在构建一个查询以获取今天登录的用户。

 id | user_id |      login_at       |      logout_at      |     created_at      
----+---------+---------------------+---------------------+---------------------
 44 |      38 | 2016-01-18 02:02:26 |                     | 2016-01-18 02:02:26
 45 |      38 |                     | 2016-01-18 02:02:35 | 2016-01-18 02:02:35
 51 |      38 | 2016-01-18 14:33:10 |                     | 2016-01-18 14:33:10
 52 |      38 |                     | 2016-01-18 14:33:24 | 2016-01-18 14:33:24

现在在Twig模板上,我必须在每一行显示一个会话的用户登录和注销时间。

我打败了这个查询器

$loggedInUsers= $this->createQueryBuilder('logs')
            ->where('logs.user =:userID')
            ->andwhere('logs.loginAt >= :todayStartDate or logs.logoutdAt <= :todayEndDate')
            ->setParameter('userID', $userID)
            ->setParameter('todayStartDate', '2016-01-18 00:00:00')
            ->setParameter('todayEndDate', '2016-01-18 23:59:59')
            ->orderBy('logs.createdAt', 'ASC')
            ->getQuery() 
            ->getResult();

在树枝上,代码如下;

  {% for data in login_history %}
Login At {{ data.loginat|date('d M Y h:i:s A') }} &nbsp;&nbsp; & Logout at {{ data.logoutdAt|date('d M Y h:i:s A') }} <br />
{% endfor %}

并输出为;

Login At 18 Jan 2016 03:17:08 PM    & Logout at 13 Jan 2016 05:27:46 PM 
Login At 18 Jan 2016 03:17:08 PM    & Logout at 15 Jan 2016 11:27:35 AM 
Login At 18 Jan 2016 02:02:26 AM    & Logout at 18 Jan 2016 03:17:08 PM 
Login At 18 Jan 2016 03:17:08 PM    & Logout at 18 Jan 2016 02:02:35 AM 
Login At 18 Jan 2016 02:33:10 PM    & Logout at 18 Jan 2016 03:17:08 PM 
Login At 18 Jan 2016 03:17:08 PM    & Logout at 18 Jan 2016 02:33:24 PM 

相反它应该返回;

Login At 18 Jan 2016 02:02:26 AM    & Logout at 13 Jan 2016 02:02:35 AM 
Login At 18 Jan 2016 02:33:10 PM    & Logout at 13 Jan 2016 02:33:24 PM

我不知道我哪里出错......

1 个答案:

答案 0 :(得分:2)

您的查询将查找今天登录的所有用户以及任何在此之前的任何时间注销的用户。

如果您更新了查询...

$qb = $this->createQueryBuilder('logs');

$logHistory = $qb
    ->where('logs.user =:userID')
    // and where multiple "OR's"
    ->andWhere($qb->expr()->orX(
        // logs.loginAt BETWEEN :todayStartDate AND :todayEndDate
        $qb->expr()->between('logs.loginAt', ':todayStartDate', ':todayEndDate'),
        // logs.logoutAt BETWEEN :todayStartDate AND :todayEndDate
        $qb->expr()->between('logs.logoutAt', ':todayStartDate', ':todayEndDate')
    ))
    ->setParameter('userID', $userID)
    ->setParameter('todayStartDate', new \DateTime('today'))
    ->setParameter('todayEndDate', new \DateTime('tomorrow - 1 second'))
    ->orderBy('logs.createdAt', 'ASC')
    ->getQuery() 
    ->getResult();

这将为您提供今天登录或退出的所有用户,但只能使用原始表的格式(每行1条记录,而不是汇总到每行注销日志)。

您可以执行以下操作来汇总您的结果(这不是很漂亮,我对此并不满意。)

$userLog = array();

foreach ($logHistory as $log) {
    if (null !== $loginAt = $log->getLoginAt()) {
        $userLog[] = array(
            'userId'    => $log->getUserId(),
            'loginAt'   => $loginAt,
            'logoutAt'  => null,
        );
    }

    if (null !== $logoutAt = $log->getLogoutAt()) {
        $updated = false;

        // reverse the array as logs at the start are more likely to be complete
        foreach (array_reverse($userLog) as $k => &$row) {
            if ($log->getUser() === $row['userId'] && null === $row['logoutAt']) {
                $row['logoutAt'] = $logoutAt;
                $updated = true;

                break;
            }
        }

        // for logout events without a login, i.e. users that logged in yesterday
        if (false === $updated) {
            $userLog[] = array(
                'userId'    => $log->getUserId(),
                'loginAt'   => null,
                'logoutAt'  => $logoutAt,
            );
        }
    }
}
相关问题