Installation
composer require xlabs/motwbundle
Publish the bundle’s assets and migrations:
php artisan vendor:publish --provider="Xlabs\MotwBundle\MotwServiceProvider" --tag=motw-migrations
php artisan vendor:publish --provider="Xlabs\MotwBundle\MotwServiceProvider" --tag=motw-config
php artisan migrate
Configure the Bundle
Edit config/motw.php to define:
model (the Eloquent model to track as "Model of the Week").voting_duration (default: 7 days).notification_channels (e.g., ['mail', 'database']).First Use Case: Displaying the Current Model of the Week
use Xlabs\MotwBundle\Facades\Motw;
$motw = Motw::current(); // Returns the current Model of the Week
echo "Current MOTW: " . $motw->name;
Blade Integration Add to your layout:
@motw('Xlabs\MotwBundle\Views::motw-badge', ['model' => $motw])
Voting System
Motw::vote() method to cast a vote for a model:
Motw::vote($modelId); // $modelId is the primary key of the model being voted for
Xlabs\MotwBundle\Contracts\VoteWeight interface to customize vote logic (e.g., admin votes count double).Scheduling
app/Console/Kernel.php:
$schedule->command('motw:reset')->weekly();
Notifications
php artisan vendor:publish --provider="Xlabs\MotwBundle\MotwServiceProvider" --tag=motw-views
Xlabs\MotwBundle\Events\MotwUpdated event to send custom notifications.API Endpoints
MotwController (published with --tag=motw-controllers) to expose endpoints like:
GET /api/motw → Current MOTW.POST /api/motw/{model}/vote → Cast a vote.Xlabs\MotwBundle\Contracts\MotwModel (e.g., adds a getMotwKey() method for unique identification).$motw = Cache::remember('motw.current', now()->addHours(1), fn() => Motw::current());
fetch('/api/motw')
.then(res => res.json())
.then(motw => document.getElementById('motw-badge').innerHTML = motw.name);
Migration Conflicts
votes_count), drop and re-run migrations after publishing to avoid conflicts.Vote Duplication
Xlabs\MotwBundle\Services\VoteService to enforce stricter rules (e.g., IP-based voting).Time Zone Issues
now(). Configure your APP_TIMEZONE in .env to match your expectations (e.g., UTC for consistency).Model Eligibility
Xlabs\MotwBundle\Contracts\MotwEligibility to filter models (e.g., exclude inactive ones):
public function isEligible($model): bool {
return $model->is_active && $model->published_at <= now();
}
config/motw.php ('debug' => true) to log votes to storage/logs/motw.log.motw:reset command runs via:
php artisan schedule:work
php artisan tinker
>>> \Xlabs\MotwBundle\Facades\Motw::vote(1); // Vote for model with ID 1
Custom Vote Logic
Xlabs\MotwBundle\Services\VoteCalculator to implement custom scoring (e.g., decaying votes over time).Alternative Storage
MotwRepository to use Redis or another cache layer for performance:
$this->app->bind(
\Xlabs\MotwBundle\Contracts\MotwRepository::class,
\YourApp\Motw\RedisMotwRepository::class
);
Frontend Badges
resources/views/vendor/motw/badge.blade.php) to match your theme:
<div class="motw-badge {{ $model->is_motw ? 'active' : 'inactive' }}">
{{ $model->name }}
</div>
Multi-Tenancy
Motw::setModel($tenant->motwModel); // Dynamically set the model class
How can I help you explore Laravel packages today?