Installation:
composer require flowframe/laravel-trend
Publish the config (if needed) with:
php artisan vendor:publish --provider="Flowframe\Trend\TrendServiceProvider"
First Use Case:
Generate a simple monthly trend for a model (e.g., User):
use Flowframe\Trend\Trend;
$trend = Trend::model(User::class)
->between(
start: now()->subMonths(6),
end: now()
)
->perMonth()
->count();
This returns a Collection of arrays with keys: period, value, and total.
Where to Look First:
config/trend.php for default time periods and aggregation methods.tests/ for edge cases and advanced usage (e.g., custom periods).Model vs. Query Trends:
Trend::model(Model::class) for simple trends on the entire table.Trend::query(Model::query()) to add Eloquent filters (e.g., where, with):
Trend::query(User::where('active', true))
->between(...)
->perWeek()
->average('score');
Time Aggregation:
perMinute(), perHour(), perDay(), etc., to group data.period(fn (Carbon $date) => ...):
->period(fn ($date) => $date->startOfWeek())
Aggregation Methods:
count(): Total records per period.sum('column'): Sum of a numeric column.average('column'): Average of a numeric column.min('column'), max('column'): Extremes of a column.aggregate(fn (Builder $query) => ...):
->aggregate(fn ($query) => $query->selectRaw('SUM(revenue) as total_revenue'))
Date Ranges:
between(start, end) for explicit ranges.thisMonth(), lastYear(), or customRange():
->between(
start: now()->startOfMonth(),
end: now()->endOfMonth()
)
Integration with Charting:
chartjs or highcharts:
return view('dashboard', [
'trend' => $trend->toArray(),
]);
Trend::model(...)->render() (if the package adds this in the future; check updates).Caching Trends:
$trend = Cache::remember('user_trend_monthly', 300, function () {
return Trend::model(User::class)
->between(...)
->perMonth()
->count();
});
Performance on Large Datasets:
perMinute() or perHour() on tables with millions of rows without indexing.name, created_at):
Schema::table('users', function (Blueprint $table) {
$table->index('name');
$table->index('created_at');
});
Time Zone Handling:
config('app.timezone'). Ensure consistency:
Trend::model(Order::class)
->between(
start: now('America/New_York')->startOfDay(),
end: now('America/New_York')->endOfDay()
)
->perDay();
Custom Periods and Carbon:
Carbon instances. Invalid inputs (e.g., strings) will throw errors.dd($date) in your custom period closure to verify types.Aggregation Quirks:
average() and sum() require numeric columns. Non-numeric columns (e.g., string) will return null.selectRaw():
->selectRaw('CAST(weight AS DECIMAL(10,2)) as weight')
Empty Results:
Collection.$trend->isEmpty() ? [] : $trend->toArray();
Database Compatibility:
min/max on JSON columns) may fail on older MySQL versions.Log Raw Queries: Enable Laravel’s query logging to inspect generated SQL:
DB::enableQueryLog();
$trend = Trend::model(User::class)->between(...)->perDay()->count();
dd(DB::getQueryLog());
Test with Small Datasets:
Use factory() or seeders to test trends before deploying to production:
User::factory()->count(100)->create();
Check for Deprecations: Monitor the changelog for breaking changes (e.g., method renames).
Custom Aggregators: Extend the package by creating a macro for reusable aggregations:
Trend::macro('customAggregation', function () {
return $this->aggregate(fn ($query) => $query->selectRaw('AVG(score) as custom_score'));
});
Usage:
Trend::model(User::class)->customAggregation();
Add New Time Periods: Create a trait or helper for non-standard periods (e.g., "quarter"):
Trend::macro('perQuarter', function () {
return $this->period(fn ($date) => $date->copy()->startOfQuarter());
});
Integrate with Jobs: Offload trend generation to a queue job for long-running queries:
TrendJob::dispatch(User::class, now()->subYear(), now(), 'perMonth', 'count');
Job class:
public function handle() {
$trend = Trend::model($this->model)
->between($this->start, $this->end)
->{$this->period}()
->{$this->aggregation}();
// Store or cache $trend
}
Localization:
Override period labels (e.g., translate "Month" to another language) by extending the Trend class:
class LocalizedTrend extends Trend {
public function perMonth() {
return $this->period(fn ($date) => [
'period' => $date->translatedFormat('M Y'), // Example: "Ene 2023"
'date' => $date->startOfMonth(),
]);
}
}
How can I help you explore Laravel packages today?