Files
ladill-hosting/app/Http/Controllers/Hosting/OverviewController.php
T
isaaccladandCursor e3fd235139
Deploy Ladill Hosting / deploy (push) Successful in 26s
Unify SSO and surface legacy ResellerClub hosting orders on the dashboard.
Add silent OAuth and session keepalive, and show imported RC orders alongside
native hosting accounts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-07 06:33:16 +00:00

146 lines
5.6 KiB
PHP

<?php
namespace App\Http\Controllers\Hosting;
use App\Http\Controllers\Controller;
use App\Models\CustomerHostingOrder;
use App\Models\HostedSite;
use App\Models\HostingAccount;
use App\Models\HostingAccountMember;
use App\Models\HostingOrder;
use App\Models\HostingProduct;
use App\Models\User;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Collection as SupportCollection;
use Illuminate\Http\Request;
use Illuminate\View\View;
class OverviewController extends Controller
{
/** Authenticated hosting dashboard (overview hub). */
public function index(Request $request): View
{
$user = $request->user();
$accounts = $this->sharedHostingAccounts($user);
$legacyOrders = $this->legacySharedHostingOrders($user);
$accountIds = $accounts->pluck('id');
$pendingOrders = CustomerHostingOrder::query()
->forUser($user->id)
->whereHas('product', fn ($q) => $q->whereIn('type', $this->sharedTypes()))
->whereIn('status', [
CustomerHostingOrder::STATUS_PENDING_PAYMENT,
CustomerHostingOrder::STATUS_PENDING_APPROVAL,
CustomerHostingOrder::STATUS_APPROVED,
CustomerHostingOrder::STATUS_PROVISIONING,
])
->with('product')
->latest()
->take(5)
->get();
$linkedDomains = ($accountIds->isEmpty()
? 0
: HostedSite::query()->whereIn('hosting_account_id', $accountIds)->count())
+ $legacyOrders->filter(fn (HostingOrder $order) => filled($order->domain_name))->count();
return view('hosting.dashboard', [
'accounts' => $accounts,
'legacyOrders' => $legacyOrders,
'activeCount' => $accounts->where('status', HostingAccount::STATUS_ACTIVE)->count()
+ $legacyOrders->where('status', HostingOrder::STATUS_ACTIVE)->count(),
'expiringCount' => $accounts
->where('status', HostingAccount::STATUS_ACTIVE)
->filter(fn (HostingAccount $account) => $account->expires_at !== null && $account->expires_at->between(now(), now()->addDays(30)))
->count()
+ $legacyOrders
->where('status', HostingOrder::STATUS_ACTIVE)
->filter(fn (HostingOrder $order) => $order->expires_at !== null && $order->expires_at->between(now(), now()->addDays(30)))
->count(),
'pendingOrderCount' => CustomerHostingOrder::query()
->forUser($user->id)
->whereHas('product', fn ($q) => $q->whereIn('type', $this->sharedTypes()))
->whereIn('status', [
CustomerHostingOrder::STATUS_PENDING_PAYMENT,
CustomerHostingOrder::STATUS_PENDING_APPROVAL,
CustomerHostingOrder::STATUS_APPROVED,
CustomerHostingOrder::STATUS_PROVISIONING,
])
->count(),
'linkedDomains' => $linkedDomains,
'recent' => $accounts->take(5),
'recentLegacyOrders' => $legacyOrders->take(5),
'pendingOrders' => $pendingOrders,
]);
}
public function accounts(Request $request): View
{
$user = $request->user();
return view('hosting.accounts-list', [
'title' => 'Your Hosting Accounts',
'accounts' => $this->sharedHostingAccounts($user),
'legacyOrders' => $this->legacySharedHostingOrders($user),
]);
}
/** @return list<string> */
private function sharedTypes(): array
{
return [
HostingProduct::TYPE_SINGLE_DOMAIN,
HostingProduct::TYPE_MULTI_DOMAIN,
HostingProduct::TYPE_WORDPRESS,
];
}
/** @return Collection<int, HostingAccount> */
private function sharedHostingAccounts(User $user): Collection
{
$sharedTypes = $this->sharedTypes();
$sharedAccountIds = HostingAccountMember::query()
->where('user_id', $user->id)
->pluck('hosting_account_id');
$hostingAccounts = HostingAccount::query()
->where(function ($query) use ($user, $sharedAccountIds) {
$query->where('user_id', $user->id);
if ($sharedAccountIds->isNotEmpty()) {
$query->orWhereIn('id', $sharedAccountIds);
}
})
->whereHas('product', fn ($q) => $q->whereIn('type', $sharedTypes))
->with(['product', 'sites'])
->latest()
->get();
$orderAccounts = CustomerHostingOrder::query()
->forUser($user->id)
->whereHas('product', fn ($q) => $q->whereIn('type', $sharedTypes))
->with(['hostingAccount.product', 'hostingAccount.sites'])
->latest()
->get()
->filter(fn (CustomerHostingOrder $order) => $order->hostingAccount !== null)
->map(fn (CustomerHostingOrder $order) => $order->hostingAccount);
return $hostingAccounts->merge($orderAccounts)->unique('id')->values();
}
/** @return SupportCollection<int, HostingOrder> */
private function legacySharedHostingOrders(User $user): SupportCollection
{
return HostingOrder::query()
->where('user_id', $user->id)
->whereIn('hosting_type', [
HostingOrder::TYPE_SINGLE_DOMAIN,
HostingOrder::TYPE_MULTI_DOMAIN,
HostingOrder::TYPE_RESELLER,
])
->whereNotIn('status', [HostingOrder::STATUS_CANCELLED])
->latest()
->get();
}
}