webmoney/backend/app/Http/Middleware/CheckPlanLimits.php
marcoitaloesp-ai 6292b62315
feat: complete email system redesign with corporate templates
- Redesigned all email templates with professional corporate style
- Created base layout with dark header, status cards, and footer
- Updated: subscription-cancelled, account-activation, welcome, welcome-new-user, due-payments-alert
- Removed emojis and gradients for cleaner look
- Added multi-language support (ES, PT-BR, EN)
- Fixed email delivery (sync instead of queue)
- Fixed PayPal already-cancelled subscription handling
- Cleaned orphan subscriptions from deleted users
2025-12-18 00:44:37 +00:00

110 lines
3.6 KiB
PHP

<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class CheckPlanLimits
{
/**
* Resource type to limit mapping
*/
protected array $resourceLimits = [
'accounts' => 'accounts',
'categories' => 'categories',
'subcategories' => 'subcategories',
'budgets' => 'budgets',
'transactions' => 'transactions',
'goals' => 'goals',
];
/**
* Handle an incoming request.
*/
public function handle(Request $request, Closure $next, string $resource): Response
{
// Only check on store (create) requests
if (!in_array($request->method(), ['POST'])) {
return $next($request);
}
$user = $request->user();
if (!$user) {
return $next($request);
}
$plan = $user->currentPlan();
if (!$plan) {
return $next($request);
}
$limits = $plan->limits ?? [];
$limitKey = $this->resourceLimits[$resource] ?? null;
if (!$limitKey || !isset($limits[$limitKey])) {
return $next($request);
}
$limit = $limits[$limitKey];
// null means unlimited
if ($limit === null) {
return $next($request);
}
$currentCount = $this->getCurrentCount($user, $resource);
if ($currentCount >= $limit) {
return response()->json([
'success' => false,
'message' => $this->getLimitMessage($resource, $limit),
'error' => 'plan_limit_exceeded',
'data' => [
'resource' => $resource,
'current' => $currentCount,
'limit' => $limit,
'plan' => $plan->name,
'upgrade_url' => '/pricing',
],
], 403);
}
return $next($request);
}
/**
* Get current count for a resource
*/
protected function getCurrentCount($user, string $resource): int
{
return match ($resource) {
'accounts' => $user->accounts()->count(),
'categories' => $user->categories()->whereNull('parent_id')->count(),
'subcategories' => $user->categories()->whereNotNull('parent_id')->count(),
'budgets' => $user->budgets()->count(),
'transactions' => $user->transactions()->count(),
'goals' => $user->goals()->count(),
default => 0,
};
}
/**
* Get user-friendly limit message
*/
protected function getLimitMessage(string $resource, int $limit): string
{
$messages = [
'accounts' => "Has alcanzado el límite de {$limit} cuenta(s) de tu plan. Actualiza a Pro para cuentas ilimitadas.",
'categories' => "Has alcanzado el límite de {$limit} categorías de tu plan. Actualiza a Pro para categorías ilimitadas.",
'subcategories' => "Has alcanzado el límite de {$limit} subcategorías de tu plan. Actualiza a Pro para subcategorías ilimitadas.",
'budgets' => "Has alcanzado el límite de {$limit} presupuesto(s) de tu plan. Actualiza a Pro para presupuestos ilimitados.",
'transactions' => "Has alcanzado el límite de {$limit} transacciones de tu plan. Actualiza a Pro para transacciones ilimitadas.",
'goals' => "Has alcanzado el límite de {$limit} meta(s) de tu plan. Actualiza a Pro para metas ilimitadas.",
];
return $messages[$resource] ?? "Has alcanzado el límite de tu plan para este recurso.";
}
}