Installation Add the package via Composer:
composer require xlabs/promotoolsbundle
Publish the configuration (if needed):
php artisan vendor:publish --provider="Xlabs\PromotoolsBundle\PromotoolsServiceProvider"
Service Provider & Facade
Ensure the service provider is registered in config/app.php under providers:
Xlabs\PromotoolsBundle\PromotoolsServiceProvider::class,
Use the facade for quick access:
use Xlabs\PromotoolsBundle\Facades\Promotools;
First Use Case: Promotional Logic Trigger a promotional check in a controller or service:
$isEligible = Promotools::checkPromotion('discount_10_percent');
if ($isEligible) {
$discount = Promotools::applyDiscount(100, 'discount_10_percent');
// Apply discount logic...
}
Configuration
Review config/promotools.php for default settings (e.g., promotion rules, caching).
Promotion Rules Engine
config/promotools.php or via migrations:
'promotions' => [
'discount_10_percent' => [
'conditions' => ['min_cart_value' => 50],
'discount' => 10,
'type' => 'percentage',
],
],
$cartValue = 75;
$promoCode = 'discount_10_percent';
if (Promotools::isEligible($cartValue, $promoCode)) {
$finalPrice = Promotools::calculateDiscountedPrice($cartValue, $promoCode);
}
Integration with Cart/Checkout
CartUpdated events to auto-check promotions:
public function handle(CartUpdated $event)
{
$promo = Promotools::getBestMatchingPromotion($event->cart->total);
$event->cart->promotion = $promo;
}
API-Driven Promotions
$remotePromos = http_get('api/promotions');
Promotools::syncPromotions($remotePromos);
Caching Strategies
Promotools::setCacheTTL(3600); // Cache for 1 hour
Composite Promotions Combine multiple promotions (e.g., "Buy X, Get Y + 10% Off"):
Promotools::combinePromotions(['buy_x_get_y', 'discount_10_percent']);
User-Specific Promotions
Extend the Promotion model to include user segments:
Promotools::filterPromotionsByUser($user);
A/B Testing Use the bundle’s hooks to log promotion exposure:
Promotools::trackPromotionView('discount_10_percent', $user);
Configuration Overrides
config/promotools.php is not accidentally overwritten during updates. Use config_cache or environment variables for critical values.Caching Quirks
php artisan cache:clear
Race Conditions
Facade vs. Service Container
public function __construct(private Promotools $promotools) {}
Log Promotion Checks
Enable debug mode in config/promotools.php:
'debug' => env('APP_DEBUG', false),
Logs will appear in storage/logs/laravel.log.
Validate Promotion Rules
Use the Promotools::validateRules() method to test configurations:
$errors = Promotools::validateRules(['min_cart_value' => 'invalid']);
Database Migrations If using migrations for promotions, ensure they’re idempotent:
Schema::table('promotions', function (Blueprint $table) {
$table->json('conditions')->nullable()->default('{}');
});
Custom Conditions
Extend the Xlabs\PromotoolsBundle\Contracts\PromotionCondition interface:
class UserTierCondition implements PromotionCondition {
public function isSatisfied($value, $promotion): bool {
return auth()->user()->tier === $promotion['required_tier'];
}
}
Event Hooks Listen for promotion-related events:
Promotools::on('promotion.applied', function ($promo, $user) {
// Send notification, update analytics, etc.
});
Testing
Mock the Promotools facade in tests:
Promotools::shouldReceive('isEligible')->andReturn(true);
How can I help you explore Laravel packages today?