diff --git a/lib/SessionStatistics.php b/lib/SessionStatistics.php index fa246cbfe..b5f305b76 100644 --- a/lib/SessionStatistics.php +++ b/lib/SessionStatistics.php @@ -49,15 +49,23 @@ public function getSessionStatistics(): array { 'last3months' => $this->getNumberOfActiveUsers(self::OFFSET_3MONTHS), 'last6months' => $this->getNumberOfActiveUsers(self::OFFSET_6MONTHS), 'lastyear' => $this->getNumberOfActiveUsers(self::OFFSET_1YEAR), + 'total' => $this->getNumberOfUsersLoggedInSince(1), ]; } /** - * get number of active user in a given time span + * Get number of active user in a given time span * * @param int $offset seconds */ private function getNumberOfActiveUsers(int $offset): int { + return $this->getNumberOfUsersLoggedInSince($this->timeFactory->getTime() - $offset); + } + + /** + * Get number of users whose last login is at or after the given timestamp + */ + private function getNumberOfUsersLoggedInSince(int $timestamp): int { $queryBuilder = $this->connection->getQueryBuilder(); $queryBuilder->select($queryBuilder->func()->count('userid')) ->from('preferences') @@ -65,7 +73,7 @@ private function getNumberOfActiveUsers(int $offset): int { ->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('lastLogin'))) ->andwhere($queryBuilder->expr()->gte( $queryBuilder->expr()->castColumn('configvalue', IQueryBuilder::PARAM_INT), - $queryBuilder->createNamedParameter($this->timeFactory->getTime() - $offset, IQueryBuilder::PARAM_INT), + $queryBuilder->createNamedParameter($timestamp, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT, )); diff --git a/src/components/ActiveUsersSection.vue b/src/components/ActiveUsersSection.vue index 32eed219c..bac0b4572 100644 --- a/src/components/ActiveUsersSection.vue +++ b/src/components/ActiveUsersSection.vue @@ -27,6 +27,11 @@ {{ activeUsers.last1month }}
{{ percentageOfAllUsers(activeUsers.last1month) }} +
+ {{ t('serverinfo', 'Logged in at least once') }}
+ {{ activeUsers.total }}
+ {{ percentageOfAllUsers(activeUsers.total) }} +
@@ -38,7 +43,7 @@ import AccountGroup from 'vue-material-design-icons/AccountGroup.vue' import SectionHeading from './SectionHeading.vue' const props = defineProps<{ - activeUsers: { last1hour: number, last24hours: number, last7days: number, last1month: number } + activeUsers: { last1hour: number, last24hours: number, last7days: number, last1month: number, total: number } numUsers: number }>() diff --git a/src/composables/useStaticData.ts b/src/composables/useStaticData.ts index c8e936165..30fedd5fc 100644 --- a/src/composables/useStaticData.ts +++ b/src/composables/useStaticData.ts @@ -49,7 +49,7 @@ export interface StaticData { opcache: OpcacheStatus fpm: Record | false database: { type: string, version: string, size: number } - activeUsers: { last1hour: number, last24hours: number, last7days: number, last1month: number } + activeUsers: { last1hour: number, last24hours: number, last7days: number, last1month: number, total: number } freeSpace: number | null memTotal: number phpinfo: boolean diff --git a/tests/lib/SessionStatisticsTest.php b/tests/lib/SessionStatisticsTest.php index 279b9c8d2..fd97ce5cb 100644 --- a/tests/lib/SessionStatisticsTest.php +++ b/tests/lib/SessionStatisticsTest.php @@ -104,7 +104,7 @@ public function testGetSessionStatistics() { $result = $this->instance->getSessionStatistics(); - $this->assertSame(8, count($result)); + $this->assertSame(9, count($result)); $this->assertSame(2, $result['last5minutes']); // 2 users in last 5 minutes $this->assertSame(5, $result['last1hour']); // 2 + 3 users in last hour $this->assertSame(6, $result['last24hours']); // 2 + 3 + 1 users in last day @@ -113,5 +113,6 @@ public function testGetSessionStatistics() { $this->assertSame(8, $result['last3months']); // 2 + 3 + 1 + 0 + 1 + 1 users in last 3 months $this->assertSame(9, $result['last6months']); // 2 + 3 + 1 + 0 + 1 + 1 + 1 users in last 6 months $this->assertSame(12, $result['lastyear']); // 2 + 3 + 1 + 0 + 1 + 1 + 1 + 3 users in last year + $this->assertGreaterThanOrEqual(12, $result['total']); // all 12 users, plus any existing lastLogin values in the database } }