omnitaskba/laravel-model-metrics

Easily attach time-based metrics to any Eloquent model.

Installs: 4

Dependents: 0

Suggesters: 0

Security: 0

Stars: 3

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/omnitaskba/laravel-model-metrics

v1.0.1 2025-12-09 12:35 UTC

This package is auto-updated.

Last update: 2025-12-11 11:21:15 UTC


README

Laravel Artifact Logo

CI Status Latest Version on Packagist Laravel Version Total Downloads License

Laravel Model Metrics ๐Ÿ“Š

A simple and non-intrusive Laravel package that enables daily time-series metrics and aggregated single-value metrics for any Eloquent model --- without adding clutter to your main tables.

Perfect for tracking views, logins, sales, XP, streaks, and more.

๐Ÿš€ Features

  • ๐Ÿ“… Daily Metrics: Store values tracked per day (year, month, day).
  • ๐Ÿงฎ Aggregated Metrics: Store a single key-value score (e.g., current streak).
  • ๐Ÿท๏ธ Supports Strings or PHP Backed Enums for metric names.
  • โšก Efficient: Uses dedicated tables and optimized SUM queries.
  • ๐Ÿ”Œ Plug-and-Play: Activated by a single trait.
  • ๐Ÿ› ๏ธ Configurable: Customize table names easily.

๐Ÿ“ฆ Installation

1. Install via Composer

composer require omnitaskba/laravel-model-metrics

2. Run Migrations

The package creates two dedicated tables: model_metrics and model_aggregated_metrics.

php artisan migrate

3. Add the trait to your model

Apply the HasMetrics trait to any Eloquent model you wish to track metrics for.

// app/Models/User.php

use Omnitaskba\ModelMetrics\Traits\HasMetrics;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    use HasMetrics;
    // ...
}

๐Ÿ“š Usage

Metric names can be passed as a string ('views') or, preferably, as a Backed Enum (PHP 8.1+):

// Example Backed Enum
enum UserMetric: string {
    case VIEWS = 'views';
    case SALES = 'sales';
    case STREAK = 'streak';
    case HIGH_SCORE = 'high_score';
    // ...
}

Daily & Aggregated Metrics Documentation

๐Ÿ“… Daily Metrics (Time Series)

Daily metrics are stored by day (year, month, day) and track historical, timeโ€‘sensitive data.

1. incrementDailyMetric()

Increments the metric value for the current day. Creates the daily record if it doesn't exist.

Argument Type Default Description
name string or BackedEnum Required The name of the metric (e.g., UserMetric::HIGH_SCORE).
value float 1.0 Amount to increment by.
Example
// Assuming current date is 2025-12-09
$user->incrementDailyMetric(UserMetric::HIGH_SCORE);       // Value: 1.0
$user->incrementDailyMetric(UserMetric::HIGH_SCORE, 5.5);  // Value: 6.5

Returns: New value of the metric record.

2. decrementDailyMetric()

Decrements the metric value for the current day. Creates the daily record if it doesn't exist.

Argument Type Default Description
name string or BackedEnum Required The metric name.
value float 1.0 Amount to decrement by.
Example
// Assuming current daily high_score are 20.0
$user->decrementDailyMetric(UserMetric::HIGH_SCORE, 0.5);

Returns: New value (19.5 in this case).

3. getTodayMetric()

Retrieves today's metric value.

Argument Type Default Description
name string or BackedEnum Required Metric name.
Example
$todayViews = $user->getTodayMetric(UserMetric::HIGH_SCORE);

Returns:
float(19.5) --- or 0.0 if none exists.

4. getTotalMetric()

Calculates the sum across all days between two dates (inclusive).

Argument Type Default Description
name string or BackedEnum Required Metric name.
startDate DateTimeInterface null Start date.
endDate DateTimeInterface null End date.
Example
use DateTime;

$start = new DateTime('2025-10-01');
$end = new DateTime('2025-10-31');

$totalSales = $user->getTotalMetric(ProductMetric::SALES, $start, $end);

Returns: float(1250.0) or 0.0 if no data.

5. getTotalForPastDays()

Sums the metric for the last N days (including today).

Argument Type Default Description
name string or BackedEnum Required Metric name.
days int Required How many days to look back.
Example
$lastWeekViews = $user->getTotalForPastDays(ProductMetric::VIEWS, 7);

Returns: float(85.5)

6. getMetricHistory()

Retrieves a collection of daily metric records grouped by day, sorted descending.

Argument Type Default Description
name string or BackedEnum Required Metric name.
limit int 30 Max number of records.
Example
$history = $user->getMetricHistory(ProductMetric::VIEWS, 10);

๐Ÿ“Š Aggregated Metrics (Single Value)

Aggregated metrics store a single persistent value.

1. setAggregatedMetric()

Sets or overwrites the metric value.

Argument Type Default Description
name string or BackedEnum Required Metric name.
value float Required Value to set.
Example
$user->setAggregatedMetric(UserMetric::HIGH_SCORE, 999.5);

2. incrementAggregatedMetric()

Increases the metric value.

Argument Type Default Description
name string or BackedEnum Required Metric name.
value float 1.0 Increment amount.
Example
$user->incrementAggregatedMetric(UserMetric::LOGIN_STREAK); // New value: 6.0

3. decrementAggregatedMetric()

Decreases the value.

Argument Type Default Description
name string or BackedEnum Required Metric name.
value float 1.0 Decrement amount.
Example
$user->decrementAggregatedMetric(UserMetric::HIGH_SCORE, 5.5); // New value: 94.5

4. getAggregatedMetric()

Retrieves current aggregated value.

Example
$currentScore = $user->getAggregatedMetric(UserMetric::HIGH_SCORE);

Returns: float(999.5) (or 0.0 if missing)

5. hasAggregatedMetric()

Checks if the record exists.

Example
if ($user->hasAggregatedMetric(UserMetric::HIGH_SCORE)) {
    // ...
}

6. resetAggregatedMetric()

Sets value to 0.0 (record stays).

Example
$user->resetAggregatedMetric(UserMetric::LOGIN_STREAK);

7. clearAggregatedMetric()

Deletes the aggregated metric record entirely.

Example
$user->clearAggregatedMetric('old_metric');

Returns: true on success, false if not found.

โš™๏ธ Configuration

You can publish the configuration file to customize the table names used by the package:

php artisan vendor:publish --tag=model-metrics-config

This will create a config/model-metrics.php file with the following contents, allowing you to customize the table names and model classes used for each metric type:

// config/model-metrics.php
return [
    'time_series' => [
        'table_name' => 'model_metrics',
        'model' => \Omnitaskba\ModelMetrics\Models\Metric::class,
    ],

    'aggregated' => [
        'table_name' => 'model_aggregated_metrics',
        'model' => \Omnitaskba\ModelMetrics\Models\AggregatedMetric::class,
    ],
];

Key Configuration Options:

  • time_series.table_name: The table used for Daily Metrics (Time Series).
  • aggregated.table_name: The table used for Aggregated Metrics (Single Value).

๐Ÿ”ง Performance Notes

  • Indexes: The underlying tables (metrics and aggregated_metrics) are indexed on the required columns (name, model_id, model_type, and date columns) to ensure rapid retrieval and SUM operations.
  • Unique Constraints: Daily metrics use a unique constraint on (name, year, month, day, model_id, model_type) to prevent duplicate entries and ensure atomic updates.

๐Ÿงช Testing

You can run the full test suite with:

composer test

๐Ÿค Contributing

See CONTRIBUTING.md.

๐Ÿ“„ Changelog

Please see CHANGELOG.md for more information what has changed recently.

๐Ÿ” Security

If you discover any security related issues, please email zlatan@omnitask.ba instead of using the issue tracker.

๐Ÿ’ก Credits

๐Ÿ“„ License

Laravel Model Metrics is open-sourced software licensed under the MIT License.