turahe/laravel-counters is a Laravel package for management for counters in laravel system.
It currently has 2 GitHub stars and 450 downloads on Packagist (latest version v2.0.0).
Install it with composer require turahe/laravel-counters.
Discover more Laravel packages by turahe
or browse all Laravel packages to compare alternatives.
Last updated
A modern, optimized counter management package for Laravel 11/12 with PHP 8.4 support.
A flexible and powerful counter management system for Laravel applications. Easily track and manage various types of counters like page views, downloads, user actions, and more without cluttering your database schema.
composer require turahe/laravel-counters
php artisan vendor:publish --tag=counters-config
This will publish:
config/counter.phpdatabase/migrations/xxxx_xx_xx_xxxxxx_create_counters_tables.phpphp artisan migrate
This creates the counters and counterables tables in your database.
use Turahe\Counters\Models\Counter;
// Create a counter for page views
Counter::create([
'key' => 'page_views',
'name' => 'Page Views',
'initial_value' => 0,
'step' => 1
]);
use Turahe\Counters\Traits\HasCounter;
class Post extends Model
{
use HasCounter;
// Your model code...
}
// In your controller
public function show(Post $post)
{
$post->incrementCounter('page_views');
return view('posts.show', compact('post'));
}
use Turahe\Counters\Facades\Counters;
// Track total downloads
Counters::increment('total_downloads');
Add the HasCounter trait to any model you want to track:
use Turahe\Counters\Traits\HasCounter;
class Post extends Model
{
use HasCounter;
// Your model code...
}
// Add a counter to a model
$post->addCounter('views');
// Get counter value
$views = $post->getCounterValue('views');
// Increment counter
$post->incrementCounter('views');
// Decrement counter
$post->decrementCounter('views', 2); // Decrement by 2
// Reset counter to initial value
$post->resetCounter('views');
// Remove counter from model
$post->removeCounter('views');
// Check if model has counter
if ($post->hasCounter('views')) {
// Do something
}
Use the Counters facade for system-wide counters:
use Turahe\Counters\Facades\Counters;
// Create a counter
Counters::create('total_downloads', 'Total Downloads', 0, 1);
// Get counter value
$downloads = Counters::getValue('total_downloads');
// Increment counter
Counters::increment('total_downloads');
// Decrement counter
Counters::decrement('total_downloads', 2);
// Set specific value
Counters::setValue('total_downloads', 100);
// Reset to initial value
Counters::reset('total_downloads');
Prevent duplicate increments from the same user:
// Only increment if user doesn't have cookie
Counters::incrementIfNotHasCookies('daily_visitors');
Counters::decrementIfNotHasCookies('available_slots');
| Method | Description | Parameters |
|--------|-------------|------------|
| addCounter($key, $initialValue = null) | Add counter to model | $key: Counter key, $initialValue: Optional initial value |
| getCounter($key) | Get counter object | $key: Counter key |
| getCounterValue($key) | Get counter value | $key: Counter key |
| hasCounter($key) | Check if model has counter | $key: Counter key |
| incrementCounter($key, $step = null) | Increment counter | $key: Counter key, $step: Optional step value |
| decrementCounter($key, $step = null) | Decrement counter | $key: Counter key, $step: Optional step value |
| resetCounter($key, $initialValue = null) | Reset counter | $key: Counter key, $initialValue: Optional reset value |
| removeCounter($key) | Remove counter from model | $key: Counter key |
| Method | Description | Parameters |
|--------|-------------|------------|
| create($key, $name, $initialValue = 0, $step = 1) | Create a counter | $key: Counter key, $name: Display name, $initialValue: Initial value, $step: Step value |
| get($key) | Get counter object | $key: Counter key |
| getValue($key, $default = null) | Get counter value | $key: Counter key, $default: Default value if not found |
| setValue($key, $value) | Set counter value | $key: Counter key, $value: New value |
| setStep($key, $step) | Set counter step | $key: Counter key, $step: Step value |
| increment($key, $step = null) | Increment counter | $key: Counter key, $step: Optional step value |
| decrement($key, $step = null) | Decrement counter | $key: Counter key, $step: Optional step value |
| reset($key) | Reset counter | $key: Counter key |
| incrementIfNotHasCookies($key) | Increment if no cookie | $key: Counter key |
| decrementIfNotHasCookies($key) | Decrement if no cookie | $key: Counter key |
The package configuration is located at config/counter.php:
return [
'models' => [
'counter' => Turahe\Counters\Models\Counter::class,
],
'tables' => [
'table_name' => 'counters',
'table_pivot_name' => 'counterables',
],
'database_connection' => env('COUNTER_DB_CONNECTION'),
];
You can customize the table names in the configuration:
'tables' => [
'table_name' => 'my_counters',
'table_pivot_name' => 'my_counterables',
],
Create a counter via command line:
php artisan make:counter page_views "Page Views" 0 1
Parameters:
page_views: Counter key"Page Views": Display name0: Initial value1: Step valueThe package includes comprehensive tests. Run them with:
./vendor/bin/phpunit
// Create the counter first
Counter::create([
'key' => 'page_views',
'name' => 'Page Views',
'initial_value' => 0,
'step' => 1
]);
// Then use it
$post->incrementCounter('page_views');
// Good
$post->incrementCounter('article_views');
$user->incrementCounter('login_count');
// Avoid generic names
$post->incrementCounter('count');
if ($post->hasCounter('views')) {
$post->incrementCounter('views');
} else {
$post->addCounter('views');
$post->incrementCounter('views');
}
php artisan migrate
// This might fail if counter doesn't exist
$post->incrementCounter('undefined_counter');
// Better approach
$post->addCounter('new_counter');
$post->incrementCounter('new_counter');
The package includes built-in caching for counter lookups, significantly improving performance for frequently accessed counters.
Use bulk operations to update multiple counters efficiently:
// Bulk increment
$results = Counters::bulkIncrement(['counter1', 'counter2'], 5);
// Bulk decrement
$results = Counters::bulkDecrement(['counter1', 'counter2'], 3);
The migration includes optimized indexes for better query performance.
Run the test suite:
composer test
Example seeder for creating counters:
use Illuminate\Database\Seeder;
use Turahe\Counters\Models\Counter;
class CounterSeeder extends Seeder
{
public function run()
{
// Create global counters
Counter::create([
'key' => 'total_downloads',
'name' => 'Total Downloads',
'initial_value' => 0,
'step' => 1
]);
Counter::create([
'key' => 'daily_visitors',
'name' => 'Daily Visitors',
'initial_value' => 0,
'step' => 1
]);
// Create model-specific counters
Counter::create([
'key' => 'page_views',
'name' => 'Page Views',
'initial_value' => 0,
'step' => 1
]);
}
}
git checkout -b feature/amazing-feature)git commit -m 'Add some amazing feature')git push origin feature/amazing-feature)This package is open-sourced software licensed under the MIT license.
Made with ❤️ by Nur Wachid