security fix and fix parent pages
API CI/CD / Validate (composer + pint) (push) Successful in 3m7s
API CI/CD / Test (PHPUnit) (push) Failing after 5m46s
API CI/CD / Build frontend assets (push) Successful in 1m2s
API CI/CD / Security audit (push) Failing after 49s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
API CI/CD / Validate (composer + pint) (push) Successful in 3m7s
API CI/CD / Test (PHPUnit) (push) Failing after 5m46s
API CI/CD / Build frontend assets (push) Successful in 1m2s
API CI/CD / Security audit (push) Failing after 49s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
This commit is contained in:
@@ -11,6 +11,8 @@ use App\Http\Resources\Reports\ReportCards\ReportCardClassSectionResource;
|
||||
use App\Http\Resources\Reports\ReportCards\ReportCardCompletenessStudentResource;
|
||||
use App\Http\Resources\Reports\ReportCards\ReportCardStudentMetaResource;
|
||||
use App\Models\Configuration;
|
||||
use App\Models\User;
|
||||
use App\Services\Parents\ParentReportCardService;
|
||||
use App\Services\Reports\ReportCards\ReportCardService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -20,8 +22,10 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class ReportCardsController extends BaseApiController
|
||||
{
|
||||
public function __construct(private ReportCardService $service)
|
||||
{
|
||||
public function __construct(
|
||||
private ReportCardService $service,
|
||||
private ParentReportCardService $parentReportCards,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
@@ -31,7 +35,8 @@ class ReportCardsController extends BaseApiController
|
||||
|
||||
$result = $this->service->meta(
|
||||
$payload['school_year'] ?? null,
|
||||
$payload['semester'] ?? null
|
||||
$payload['semester'] ?? null,
|
||||
$this->parentScopeId($request)
|
||||
);
|
||||
|
||||
return $this->success([
|
||||
@@ -88,6 +93,10 @@ class ReportCardsController extends BaseApiController
|
||||
|
||||
$validated = $validator->validated();
|
||||
$studentId = (int) ($validated['student_id'] ?? 0);
|
||||
if (! $this->parentCanAccessStudent($request, $studentId)) {
|
||||
return $this->error('Forbidden.', Response::HTTP_FORBIDDEN);
|
||||
}
|
||||
|
||||
$schoolYear = $this->resolveSchoolYear($validated['school_year'] ?? null);
|
||||
$semester = $this->resolveSemester($validated['semester'] ?? null);
|
||||
|
||||
@@ -98,6 +107,10 @@ class ReportCardsController extends BaseApiController
|
||||
|
||||
public function studentReport(ReportCardPdfRequest $request, int $studentId)
|
||||
{
|
||||
if (! $this->parentCanAccessStudent($request, $studentId)) {
|
||||
return $this->error('Forbidden.', Response::HTTP_FORBIDDEN);
|
||||
}
|
||||
|
||||
try {
|
||||
$result = $this->service->generateSingleReport($studentId, $request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
@@ -122,6 +135,10 @@ class ReportCardsController extends BaseApiController
|
||||
|
||||
public function classReport(ReportCardPdfRequest $request, int $classSectionId)
|
||||
{
|
||||
if ($this->parentScopeId($request) !== null) {
|
||||
return $this->error('Forbidden.', Response::HTTP_FORBIDDEN);
|
||||
}
|
||||
|
||||
try {
|
||||
$result = $this->service->generateClassReport($classSectionId, $request->validated());
|
||||
} catch (\Throwable $e) {
|
||||
@@ -163,4 +180,45 @@ class ReportCardsController extends BaseApiController
|
||||
|
||||
return trim((string) (Configuration::getConfig('semester') ?? ''));
|
||||
}
|
||||
|
||||
private function parentCanAccessStudent(Request $request, int $studentId): bool
|
||||
{
|
||||
$parentId = $this->parentScopeId($request);
|
||||
if ($parentId === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->parentReportCards->studentBelongsToPrimaryParent($studentId, $parentId);
|
||||
}
|
||||
|
||||
private function parentScopeId(Request $request): ?int
|
||||
{
|
||||
/** @var User|null $user */
|
||||
$user = $request->user();
|
||||
if (! $this->isParentFamilyUser($user)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parentId = $this->parentReportCards->resolvePrimaryParentUserId($user);
|
||||
|
||||
return $parentId !== null && $parentId > 0 ? $parentId : null;
|
||||
}
|
||||
|
||||
private function isParentFamilyUser(?User $user): bool
|
||||
{
|
||||
if (! $user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$roles = $user->roles()
|
||||
->pluck('roles.name')
|
||||
->map(fn ($name) => strtolower((string) $name))
|
||||
->toArray();
|
||||
|
||||
if (in_array('parent', $roles, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return in_array(strtolower(trim((string) ($user->user_type ?? ''))), ['secondary', 'tertiary'], true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,37 @@ class StickersController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
public function preview(StickerFormDataRequest $request): JsonResponse
|
||||
{
|
||||
$payload = $request->validated();
|
||||
$schoolYear = $this->queryService->resolveSchoolYear($payload['school_year'] ?? null);
|
||||
$classSectionId = (int) ($payload['class_section_id'] ?? 0);
|
||||
|
||||
$students = $classSectionId > 0
|
||||
? $this->queryService->listStudentsByClass($classSectionId, $schoolYear)
|
||||
: $this->queryService->listStudentsForYear($schoolYear);
|
||||
|
||||
$rows = [];
|
||||
foreach ($students as $student) {
|
||||
$id = (int) ($student['id'] ?? $student['student_id'] ?? 0);
|
||||
if ($id <= 0) {
|
||||
continue;
|
||||
}
|
||||
$rows[] = [
|
||||
'student_id' => $id,
|
||||
'primary_count' => 1,
|
||||
];
|
||||
}
|
||||
|
||||
return $this->success([
|
||||
'students' => $rows,
|
||||
'totals' => [
|
||||
'students' => count($rows),
|
||||
'stickers' => count($rows),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function print(StickerPrintRequest $request)
|
||||
{
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user