public static function noteLoggedIn($row)
    {
        global $CFG, $PDOX;

        if ( ! isset($row['user_id']) ) return;
        if ( ! isset($PDOX) || ! $PDOX ) return;

        if ( Net::getIP() !== NULL ) {
            $sql = "UPDATE {$CFG->dbprefix}lti_user
                SET login_at=NOW(), login_count=login_count+1, ipaddr=:IP WHERE user_id = :user_id";
            $stmt = $PDOX->queryReturnError($sql, array(
                ':IP' => Net::getIP(),
                ':user_id' => $row['user_id']));
        } else {
            $sql = "UPDATE {$CFG->dbprefix}lti_user
                SET login_at=NOW(), login_count=login_count+1 WHERE user_id = :user_id";
            $stmt = $PDOX->queryReturnError($sql, array(
                ':user_id' => $row['user_id']));
        }

        if ( ! $stmt->success ) {
            error_log("Unable to update login_at user_id=".$row['user_id']);
        }

        if ( isset($row['context_id']) ) {
            $sql = "UPDATE {$CFG->dbprefix}lti_context
                SET login_at=NOW(), login_count=login_count+1 WHERE context_id = :context_id";
            $stmt = $PDOX->queryReturnError($sql, array(
                ':context_id' => $row['context_id']));

            if ( ! $stmt->success ) {
                error_log("Unable to update login_at context_id=".$row['context_id']);
            }
        }

        // We do an update of login_at for the key
        if ( array_key_exists('key_id', $row) ) {
            $sql = "UPDATE {$CFG->dbprefix}lti_key
                SET login_at=NOW(),login_count=login_count+1 WHERE key_id = :key_id";
            $stmt = $PDOX->queryReturnError($sql, array(
                ':key_id' => $row['key_id']));

            if ( ! $stmt->success ) {
                error_log("Unable to update login_at key_id=".$row['context_id']);
            }
        }
    }