Installation:
composer require eliseekn/laravel-metrics
Ensure your project uses PHP 8.2+ and Laravel 11+.
First Use Case:
Generate monthly trends for a model (e.g., Order):
use Eliseekn\LaravelMetrics\Facades\LaravelMetrics;
$trends = LaravelMetrics::query(Order::query())
->count()
->byMonth()
->trends();
Output: Array of monthly counts (e.g., ['January' => 15, 'February' => 22]).
Where to Look First:
Eliseekn\LaravelMetrics\LaravelMetrics: Core class for method chaining.$revenueByStatus = Order::metrics()
->sum('amount')
->byMonth(12)
->labelColumn('status')
->groupData(['pending', 'completed'], 'sum')
->fillMissingData()
->trends();
between() with groupBy() for custom periods.$dau = UserActivity::metrics()
->count()
->between([
now()->subDays(30)->format('Y-m-d'),
now()->format('Y-m-d')
])
->groupByDay()
->fillMissingData(0)
->trends();
$growth = Product::metrics()
->sum('sales')
->byYear(2)
->metricsWithVariations(1, 'year', true); // Previous year, % format
HasMetrics trait to Eloquent models for concise syntax.class Order extends Model {
use \Eliseekn\LaravelMetrics\Traits\HasMetrics;
}
// Usage:
$monthlyOrders = Order::metrics()->count()->byMonth()->trends();
Invoice::metrics()).$userOrders = LaravelMetrics::query(
DB::table('orders')
->join('users', 'orders.user_id', 'users.id')
)
->count()
->table('users')
->labelColumn('country')
->byMonth()
->trends();
$metrics = Cache::remember('monthly_revenue', now()->addDay(), function () {
return Order::metrics()->sum('amount')->byMonth()->metrics();
});
return response()->json([
'data' => $trends,
'period' => 'monthly',
'unit' => 'count'
]);
LaravelMetrics in unit tests:
$this->partialMock(LaravelMetrics::class, function ($mock) {
$mock->shouldReceive('query')->andReturnSelf();
$mock->shouldReceive('count')->andReturnSelf();
$mock->shouldReceive('byMonth')->andReturnSelf();
$mock->shouldReceive('trends')->andReturn(['Jan' => 100]);
});
Date Handling Quirks:
between() with groupByMonth() may exclude partial months.
Fix: Use fillMissingData() to pad gaps.date columns are cast to Carbon to avoid SQL errors.
->dateColumn('created_at') // Explicitly specify date column
Label Column Pitfalls:
labelColumn() requires distinct values; duplicates cause aggregation errors.
Fix: Use groupData() for multi-value labels:
->groupData(['active', 'inactive'], 'count')
Performance:
between() queries with large date ranges slow down.
Fix: Limit periods (e.g., byMonth(6)) or add database indexes:
CREATE INDEX orders_monthly ON orders(created_at(6)); -- MySQL
Trailing Methods:
->trends() or ->metrics() returns raw data.
Fix: Chain methods explicitly:
->byMonth()->trends(); // Correct
->byMonth(); // Returns LaravelMetrics instance (no data)
Locale Translations:
config(['app.locale' => 'fr']) before querying.DB::enableQueryLog();
$metrics = LaravelMetrics::query(...)->trends();
dd(DB::getQueryLog()); // Inspect raw SQL
fillMissingData() with a default value:
->fillMissingData(0) // Fill zeros for missing dates
order table):
->table('"order"') // Escape with quotes
Custom Aggregates:
// app/Extensions/LaravelMetrics.php
namespace App\Extensions;
use Eliseekn\LaravelMetrics\LaravelMetrics as BaseMetrics;
class LaravelMetrics extends BaseMetrics {
public function customAggregate(string $column) {
return $this->addSelect("CONCAT({$column}, ' suffix') as custom_agg");
}
}
config/laravel-metrics.php:
'metrics_class' => \App\Extensions\LaravelMetrics::class,
Event Triggers:
LaravelMetrics::macro('afterTrends', function ($callback) {
$callback($this->getTrendsData());
});
// Usage:
LaravelMetrics::query(...)->byMonth()->afterTrends(fn($data) => Log::info($data));
Database-Specific Optimizations:
// app/Providers/AppServiceProvider.php
use Eliseekn\LaravelMetrics\Database\QueryBuilder;
public function boot() {
if (app()->environment('production')) {
QueryBuilder::macro('optimizeForPostgres', function () {
// Custom PostgreSQL optimizations
});
}
}
$popularTags = Tag::metrics()
->count()
->byMonth(3)
->orderByDesc('count')
->limit(5)
->get();
$period = request('period', 'month');
$method = "by{$period}";
$metrics = LaravelMetrics::query(...)->$method()->trends();
// Inertia.js example
const labels = @json($trends->keys());
const data = @json($trends->values());
new Chart(ctx, { type: 'line', data: { labels, datasets: [{ data }] } });
How can I help you explore Laravel packages today?