Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 53 additions & 7 deletions app/Http/Controllers/MemberAreaAppController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

namespace App\Http\Controllers;

use App\Models\MemberActivityLog;
use App\Models\MemberCertificateIssued;
use App\Models\MemberComment;
use App\Models\MemberCommunityPage;
use App\Models\MemberCommunityPost;
use App\Models\MemberCommunityPostComment;
use App\Models\MemberCommunityPostLike;
use App\Models\MemberActivityLog;
use App\Models\MemberInternalProduct;
use App\Models\MemberLesson;
use App\Models\MemberLessonLike;
Expand All @@ -32,7 +32,6 @@
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Inertia\Inertia;
use Inertia\Response;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
Expand Down Expand Up @@ -74,7 +73,7 @@ public function show(Request $request, string $slug): Response
$user = $request->user();

$this->logMemberActivity($request, $product, $user, 'member_area.open', [
'path' => '/' . ltrim($request->path(), '/'),
'path' => '/'.ltrim($request->path(), '/'),
]);

$accessStartAt = $this->userAccessStartAt($product, $user);
Expand Down Expand Up @@ -375,6 +374,7 @@ public function lesson(Request $request, string $slug, MemberLesson $lesson): Re
return redirect()->route($this->memberAreaModuleRouteName($request), ['slug' => $slug, 'module' => $moduleRouteId])
->with('error', $lessonLock['lock_message'] ?? 'Aula ainda não liberada.');
}

return redirect()->route($this->memberAreaModulosRouteName($request), ['slug' => $slug])
->with('error', $lessonLock['lock_message'] ?? 'Aula ainda não liberada.');
}
Expand Down Expand Up @@ -1450,6 +1450,7 @@ public function openRelatedProduct(Request $request): RedirectResponse
if (! $user instanceof User) {
// In host-based member areas, GET /login is handled by the platform login controller.
$isHost = str_ends_with(($request->route()?->getName() ?? ''), '.host');

return $isHost
? redirect()->to('/login')->with('error', 'Faça login para acessar a área de membros.')
: redirect()->route('member-area.login', ['slug' => $slug])->with('error', 'Faça login para acessar a área de membros.');
Expand Down Expand Up @@ -1507,6 +1508,7 @@ public function openRelatedProductDeliverable(Request $request): RedirectRespons

if (! $user instanceof User) {
$isHost = str_ends_with(($request->route()?->getName() ?? ''), '.host');

return $isHost
? redirect()->to('/login')->with('error', 'Faça login para acessar a área de membros.')
: redirect()->route('member-area.login', ['slug' => $slug])->with('error', 'Faça login para acessar a área de membros.');
Expand Down Expand Up @@ -1552,8 +1554,9 @@ public function openRelatedProductDeliverable(Request $request): RedirectRespons
if ($link !== '') {
return str_starts_with($link, 'http://') || str_starts_with($link, 'https://')
? redirect()->away($link)
: redirect('/' . ltrim($link, '/'));
: redirect('/'.ltrim($link, '/'));
}

return redirect()->to($this->baseUrlForRequest($host, $request))
->with('error', 'Este produto está como tipo Link, mas o link de entrega não foi configurado.');
}
Expand All @@ -1567,12 +1570,14 @@ public function openRelatedProductDeliverable(Request $request): RedirectRespons
private function memberAreaProductsOpenRouteName(Request $request): string
{
$name = $request->route()?->getName() ?? '';

return str_ends_with($name, '.host') ? 'member-area-app.products.open.host' : 'member-area-app.products.open';
}

private function memberAreaProductsDeliverableRouteName(Request $request): string
{
$name = $request->route()?->getName() ?? '';

return str_ends_with($name, '.host') ? 'member-area-app.products.deliverable.host' : 'member-area-app.products.deliverable';
}

Expand All @@ -1582,6 +1587,7 @@ private function memberAreaProductsDeliverableRouteName(Request $request): strin
private function memberAreaProductsRouteParams(Request $request, string $slug, string $productId): array
{
$isHost = str_ends_with(($request->route()?->getName() ?? ''), '.host');

return $isHost ? ['relatedProduct' => $productId] : ['slug' => $slug, 'relatedProduct' => $productId];
}

Expand All @@ -1591,6 +1597,7 @@ private function memberAreaProductsRouteParams(Request $request, string $slug, s
private function memberAreaModuleRouteParams(Request $request, string $slug, string $moduleId): array
{
$isHost = str_ends_with(($request->route()?->getName() ?? ''), '.host');

return $isHost ? ['module' => $moduleId] : ['slug' => $slug, 'module' => $moduleId];
}

Expand Down Expand Up @@ -1659,7 +1666,7 @@ private function assertEmbeddedProductLinkAccess(MemberModule $wrapper, User $us
if ($link !== '') {
return str_starts_with($link, 'http://') || str_starts_with($link, 'https://')
? redirect()->away($link)
: redirect('/' . ltrim($link, '/'));
: redirect('/'.ltrim($link, '/'));
}
}

Expand Down Expand Up @@ -1789,6 +1796,7 @@ private function userAccessStartAt(Product $product, User $user): Carbon
if ($createdAt) {
return Carbon::parse($createdAt);
}

return now();
}

Expand All @@ -1803,6 +1811,7 @@ private function scheduleMeta(?int $afterDays, mixed $atDate, Carbon $accessStar
if (is_int($afterDays) && $afterDays > 0) {
return ['available_at' => $accessStartAt->copy()->addDays($afterDays), 'mode' => 'days'];
}

return ['available_at' => null, 'mode' => null];
}

Expand Down Expand Up @@ -1848,12 +1857,14 @@ private function lockPayload(?Carbon $availableAt, ?Carbon $expiresAt, Carbon $n
} else {
$message = 'Disponível em '.$availableAt->format('d/m/Y H:i');
}

return [
...$payload,
'is_locked' => true,
'lock_message' => $message,
'lock_reason' => 'scheduled',
];

}

/**
Expand Down Expand Up @@ -1972,7 +1983,12 @@ private function moduleLockPayload(MemberModule $module, Carbon $accessStartAt,

$meta = $this->scheduleMeta($module->release_after_days, $module->release_at_date, $accessStartAt);

return $this->lockPayload($meta['available_at'], $expiresAt, $now, $meta['mode']);
$scheduleLock = $this->lockPayload($meta['available_at'], $expiresAt, $now, $meta['mode']);
if (($scheduleLock['is_locked'] ?? false) === true) {
return $scheduleLock;
}

return $scheduleLock;
}

/**
Expand Down Expand Up @@ -2035,7 +2051,37 @@ private function lessonLockPayload(MemberLesson $lesson, ?MemberModule $module,
}
}

return $this->lockPayload($availableAt, $expiresAt, $now, $mode);
$scheduleLock = $this->lockPayload($availableAt, $expiresAt, $now, $mode);
if (($scheduleLock['is_locked'] ?? false) === true) {
return $scheduleLock;
}

$user = request()->user();
if (! $user instanceof User) {
return $scheduleLock;
}
$dependencies = $lesson->releaseDependencies()->with('requiredLesson')->get();
if ($dependencies->isEmpty()) {
return $scheduleLock;
}
$completedIds = MemberLessonProgress::query()
->where('user_id', $user->id)
->whereNotNull('completed_at')
->whereIn('member_lesson_id', $dependencies->pluck('required_member_lesson_id'))
->pluck('member_lesson_id')
->flip();
foreach ($dependencies as $dependency) {
if (! isset($completedIds[$dependency->required_member_lesson_id])) {
return [
...$scheduleLock,
'is_locked' => true,
'lock_message' => 'Conclua a aula '.($dependency->requiredLesson?->title ?? 'anterior').' para liberar esta aula.',
'lock_reason' => 'prerequisite',
];
}
}

return $scheduleLock;
}

private function moduleThumbnailUrl(MemberModule $module, Product $product, ?MemberModule $fallback = null): ?string
Expand Down
Loading