PHPackages                             thephpx/matrix - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. thephpx/matrix

ActiveLibrary

thephpx/matrix
==============

Laravel analytics package — tracks user signups and daily unique visitors via a SQLite-backed bearer-authenticated API

00PHP

Since May 22Pushed 2w agoCompare

[ Source](https://github.com/thephpx/thephpx-matrix)[ Packagist](https://packagist.org/packages/thephpx/matrix)[ RSS](/packages/thephpx-matrix/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependenciesVersions (1)Used By (0)

thephpx/matrix
==============

[](#thephpxmatrix)

A lightweight Laravel package that tracks **user signups** and **daily unique visitors** using a dedicated SQLite database, exposed via bearer-authenticated JSON API endpoints.

---

Features
--------

[](#features)

- Counts registered users from your application's `users` table
- Tracks daily unique visitors by IP address (one count per IP per day)
- Logs every visit with a full timestamp, IP address, and ISO country code
- Resolves country codes via the free [ip-api.com](http://ip-api.com) service with a local SQLite cache — each IP is looked up only once
- Stores all analytics in an isolated SQLite database — no changes to your main database
- Zero-configuration setup — all three tables are created automatically on first boot
- Two API endpoints protected by a bearer token
- Returns the last 30 days of data with zero-gap date fill
- Automatically purges visitor records older than 30 days to keep the database light
- Country lookups and DB writes run **after** the response is sent — zero latency added to your users

---

Requirements
------------

[](#requirements)

- PHP 8.1+
- Laravel 10 or 11
- SQLite PHP extension (`ext-pdo_sqlite`)
- cURL PHP extension (`ext-curl`) — used for IP-to-country lookups

---

Installation
------------

[](#installation)

### 1. Install via Composer

[](#1-install-via-composer)

```
composer require thephpx/matrix
```

Laravel auto-discovers the service provider. No manual registration needed.

### 2. Add the bearer token to `.env`

[](#2-add-the-bearer-token-to-env)

```
MATRIX_BEARER_TOKEN=your-secret-token-here
```

### 3. (Optional) Publish the config

[](#3-optional-publish-the-config)

```
php artisan vendor:publish --tag=matrix-config
```

This copies `config/matrix.php` into your application's config directory so you can customise values.

---

Configuration
-------------

[](#configuration)

```
// config/matrix.php

return [

    // Bearer token required to access the /matrix/* endpoints.
    'bearer_token' => env('MATRIX_BEARER_TOKEN'),

    // Absolute path to the SQLite file (auto-created if missing).
    'database_path' => env('MATRIX_DATABASE_PATH', storage_path('matrix.sqlite')),

];
```

ENV keyDefaultDescription`MATRIX_BEARER_TOKEN``null`Required. Secret token for API access.`MATRIX_DATABASE_PATH``storage/matrix.sqlite`Path to the SQLite analytics database.---

API Endpoints
-------------

[](#api-endpoints)

All endpoints require an `Authorization: Bearer {token}` header.

---

### `GET /matrix/stats`

[](#get-matrixstats)

Returns the total registered user count and the last 30 days of **unique** daily visitor counts.

**Request**

```
GET /matrix/stats HTTP/1.1
Authorization: Bearer your-secret-token-here
```

**Response `200 OK`**

```
{
    "user_count": 312,
    "visitors": [
        { "date": "2026-04-22", "visitor_count": 0 },
        { "date": "2026-04-23", "visitor_count": 14 },
        { "date": "2026-04-24", "visitor_count": 31 },
        ...
        { "date": "2026-05-21", "visitor_count": 87 }
    ]
}
```

FieldTypeDescription`user_count``integer`Total rows in the `users` table`visitors``array`30-element array ordered oldest → today`visitors[].date``string`Date in `Y-m-d` format`visitors[].visitor_count``integer`Unique IPs recorded on that date (0 if none)---

### `GET /matrix/visitors`

[](#get-matrixvisitors)

Returns the full visit log for the last 30 days — every page hit with its timestamp, IP address, and country code.

**Request**

```
GET /matrix/visitors HTTP/1.1
Authorization: Bearer your-secret-token-here
```

**Response `200 OK`**

```
{
    "visitors": [
        {
            "ip_address": "102.45.67.89",
            "country_code": "NG",
            "visited_at": "2026-05-21 14:32:11"
        },
        {
            "ip_address": "66.249.64.20",
            "country_code": "US",
            "visited_at": "2026-05-21 13:18:44"
        },
        {
            "ip_address": "81.22.44.11",
            "country_code": "DE",
            "visited_at": "2026-05-21 11:05:02"
        }
    ]
}
```

Results are ordered most-recent first.

FieldTypeDescription`visitors[].ip_address``string`IPv4 or IPv6 address of the visitor`visitors[].country_code``string|null`ISO 3166-1 alpha-2 code (e.g. `US`, `GB`, `DE`). `null` for private/unresolvable IPs`visitors[].visited_at``string`Full timestamp in `Y-m-d H:i:s` format---

### `401 Unauthorized` (both endpoints)

[](#401-unauthorized-both-endpoints)

Returned when the `Authorization` header is missing or the token is incorrect.

```
{
    "error": "Unauthorized"
}
```

---

How visitor tracking works
--------------------------

[](#how-visitor-tracking-works)

The package automatically injects `TrackVisitor` into Laravel's `web` middleware group. On every web request:

1. The response is sent to the browser first — **no latency is added**
2. After the response is sent, the visitor's IP is resolved to a country code via [ip-api.com](http://ip-api.com) (free, no API key required)
3. The country result is stored in `matrix_ip_cache` — subsequent visits from the same IP are served from the local SQLite cache with no network call
4. A row is upserted into `matrix_daily_visitors` (unique per IP per day — drives the `/matrix/stats` counts)
5. A row is inserted into `matrix_visitor_logs` (every hit — drives the `/matrix/visitors` log)

The `/matrix/*` endpoint and common internal paths (`/horizon/*`, `/telescope/*`, `/_debugbar/*`) are excluded from tracking.

---

Automatic data purge
--------------------

[](#automatic-data-purge)

The package registers a daily scheduled task that deletes visitor records older than 30 days from both `matrix_daily_visitors` and `matrix_visitor_logs`. The `matrix_ip_cache` table is intentionally kept to avoid re-querying the geo API for previously seen IPs.

The purge runs automatically as long as your application's scheduler is active. If it is not already running, add the following cron entry to your server:

```
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
```

No configuration is needed — the task is registered by the service provider and named `matrix:purge-visitors`.

---

Database
--------

[](#database)

The package creates and manages its own SQLite connection named `matrix`. All three tables are created automatically on first boot.

---

**`matrix_daily_visitors`** — unique daily counts

ColumnTypeNotes`id`integerAuto-increment primary key`ip_address`varchar(45)Supports IPv4 and IPv6`date`dateVisit date (`Y-m-d`)`created_at`timestamp`updated_at`timestamp*(unique)*`(ip_address, date)`---

**`matrix_visitor_logs`** — detailed visit log

ColumnTypeNotes`id`integerAuto-increment primary key`ip_address`varchar(45)Supports IPv4 and IPv6`country_code`char(2)ISO 3166-1 alpha-2 · nullable`visited_at`datetimeFull visit timestamp`created_at`timestamp`updated_at`timestamp*(index)*`visited_at`---

**`matrix_ip_cache`** — IP-to-country lookup cache

ColumnTypeNotes`id`integerAuto-increment primary key`ip_address`varchar(45)Unique`country_code`char(2)ISO 3166-1 alpha-2 · nullable`created_at`timestamp`updated_at`timestamp---

Uninstalling
------------

[](#uninstalling)

1. Remove the package: `composer remove thephpx/matrix`
2. Delete the SQLite file: `rm storage/matrix.sqlite`
3. Remove `MATRIX_BEARER_TOKEN` (and `MATRIX_DATABASE_PATH` if set) from `.env`
4. If published, delete `config/matrix.php`

---

Author
------

[](#author)

**Faisal Ahmed**

---

License
-------

[](#license)

MIT

###  Health Score

20

—

LowBetter than 13% of packages

Maintenance63

Regular maintenance activity

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/812660?v=4)[faisal ahmed](/maintainers/thephpx)[@thephpx](https://github.com/thephpx)

---

Top Contributors

[![thephpx](https://avatars.githubusercontent.com/u/812660?v=4)](https://github.com/thephpx "thephpx (1 commits)")

### Embed Badge

![Health badge](/badges/thephpx-matrix/health.svg)

```
[![Health](https://phpackages.com/badges/thephpx-matrix/health.svg)](https://phpackages.com/packages/thephpx-matrix)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
