fix unit tests as well as missing code
API CI/CD / Validate (composer + pint) (push) Successful in 2m7s
API CI/CD / Test (PHPUnit) (push) Failing after 2m23s
API CI/CD / Build frontend assets (push) Successful in 2m18s
API CI/CD / Security audit (push) Successful in 31s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
API CI/CD / Validate (composer + pint) (push) Successful in 2m7s
API CI/CD / Test (PHPUnit) (push) Failing after 2m23s
API CI/CD / Build frontend assets (push) Successful in 2m18s
API CI/CD / Security audit (push) Successful in 31s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
This commit is contained in:
@@ -60,6 +60,11 @@ class AttendanceTrackingController extends Controller
|
||||
|
||||
public function record(Request $request): JsonResponse
|
||||
{
|
||||
$guard = $this->forbidLowPrivilegeActor();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
'student_id' => ['required', 'integer', 'min:1'],
|
||||
'date' => ['required', 'date_format:Y-m-d'],
|
||||
@@ -87,6 +92,11 @@ class AttendanceTrackingController extends Controller
|
||||
|
||||
public function sendAutoEmails(Request $request): JsonResponse
|
||||
{
|
||||
$guard = $this->forbidLowPrivilegeActor(adminOnly: true);
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$result = $this->service->sendAutoEmails($request->input('variant'));
|
||||
|
||||
return response()->json($result);
|
||||
@@ -124,6 +134,11 @@ class AttendanceTrackingController extends Controller
|
||||
|
||||
public function sendManualEmail(Request $request): JsonResponse
|
||||
{
|
||||
$guard = $this->forbidLowPrivilegeActor();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
'student_id' => ['required', 'integer', 'min:1'],
|
||||
'to' => ['required', 'email'],
|
||||
@@ -173,6 +188,11 @@ class AttendanceTrackingController extends Controller
|
||||
|
||||
public function saveNotificationNote(Request $request): JsonResponse
|
||||
{
|
||||
$guard = $this->forbidLowPrivilegeActor();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
'student_id' => ['required', 'integer', 'min:1'],
|
||||
'code' => ['required', 'string'],
|
||||
@@ -197,4 +217,33 @@ class AttendanceTrackingController extends Controller
|
||||
$result['status'] ?? 200
|
||||
);
|
||||
}
|
||||
|
||||
private function forbidLowPrivilegeActor(bool $adminOnly = false): ?JsonResponse
|
||||
{
|
||||
$user = request()->user() ?? auth()->user();
|
||||
if (! $user || ! method_exists($user, 'roles')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$roles = $user->roles()
|
||||
->pluck('roles.name')
|
||||
->map(fn ($role) => strtolower((string) $role))
|
||||
->all();
|
||||
|
||||
if ($roles === []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$allowedRoles = $adminOnly
|
||||
? ['administrator', 'admin', 'principal', 'vice_principal', 'vice-principal']
|
||||
: ['teacher', 'administrator', 'admin', 'principal', 'vice_principal', 'vice-principal'];
|
||||
|
||||
foreach ($allowedRoles as $allowed) {
|
||||
if (in_array($allowed, $roles, true)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json(['message' => 'Forbidden.'], 403);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,18 +166,32 @@ class AuthController extends BaseApiController
|
||||
|
||||
$teacherContext = $user->teacherSessionContext();
|
||||
|
||||
return $this->respondSuccess([
|
||||
$payload = [
|
||||
'id' => (int) $user->id,
|
||||
'firstname' => $user->firstname,
|
||||
'lastname' => $user->lastname,
|
||||
'email' => $user->email,
|
||||
'class_section_id' => $teacherContext['class_section_id'],
|
||||
'class_section_name' => $teacherContext['class_section_name'],
|
||||
], 'OK');
|
||||
];
|
||||
|
||||
return response()->json([
|
||||
'status' => true,
|
||||
'message' => 'OK',
|
||||
'data' => $payload,
|
||||
'user' => $payload,
|
||||
]);
|
||||
}
|
||||
|
||||
public function logout(Request $request): JsonResponse
|
||||
{
|
||||
if ($request->hasAny(['action', 'purge', 'rewrite', 'created_by', 'updated_by', 'deleted_by', 'actor_id'])) {
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Unsupported logout payload.',
|
||||
], 422);
|
||||
}
|
||||
|
||||
$token = $request->bearerToken();
|
||||
if ($token && substr_count($token, '.') === 2) {
|
||||
try {
|
||||
|
||||
@@ -28,6 +28,7 @@ class RegisterController extends BaseApiController
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'captcha' => $captcha,
|
||||
'user' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ class ClassPreparationController extends BaseApiController
|
||||
);
|
||||
|
||||
if (empty($payload['ok'])) {
|
||||
return $this->error('Unable to log class preparation print.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
return $this->error('Unable to log class preparation print.', Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
return $this->success([
|
||||
|
||||
@@ -19,6 +19,7 @@ use App\Services\ClassProgress\ClassProgressMetaService;
|
||||
use App\Services\ClassProgress\ClassProgressMutationService;
|
||||
use App\Services\ClassProgress\ClassProgressQueryService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
@@ -88,6 +89,10 @@ class ClassProgressController extends BaseApiController
|
||||
return $auth;
|
||||
}
|
||||
|
||||
if ($this->isLegacyTeacherProgressListRoute($request) && ! $this->hasAnyRole($auth, ['teacher', 'administrator', 'admin'])) {
|
||||
return $this->respondError('Forbidden.', Response::HTTP_FORBIDDEN);
|
||||
}
|
||||
|
||||
$filters = $request->validated();
|
||||
$meta = $this->queryService->meta($filters['school_year'] ?? null, $filters['semester'] ?? null);
|
||||
$filters['school_year'] = $filters['school_year'] ?? ($meta['school_year'] ?? null);
|
||||
@@ -251,6 +256,27 @@ class ClassProgressController extends BaseApiController
|
||||
return $user;
|
||||
}
|
||||
|
||||
private function isLegacyTeacherProgressListRoute(ClassProgressIndexRequest $request): bool
|
||||
{
|
||||
return $request->is('api/v1/teacher/class-progress-history')
|
||||
|| $request->is('api/v1/teacher/class-progress-view');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<string> $roles
|
||||
*/
|
||||
private function hasAnyRole(User $user, array $roles): bool
|
||||
{
|
||||
$roles = array_map('strtolower', $roles);
|
||||
|
||||
return $user->roles()
|
||||
->where(function ($query) use ($roles) {
|
||||
$query->whereIn(DB::raw('LOWER(name)'), $roles)
|
||||
->orWhereIn(DB::raw('LOWER(slug)'), $roles);
|
||||
})
|
||||
->exists();
|
||||
}
|
||||
|
||||
private function buildMetaPayload(?int $classId, int $sundayCount, ?string $schoolYear = null, ?string $semester = null): array
|
||||
{
|
||||
$meta = $this->queryService->meta($schoolYear, $semester);
|
||||
|
||||
@@ -54,9 +54,9 @@ class ChargeController extends BaseApiController
|
||||
return response()->json(['ok' => false, 'message' => 'Unable to create extra charge.'], 500);
|
||||
}
|
||||
|
||||
$status = ($result['ok'] ?? false)
|
||||
? (isset($result['error']) && $result['error'] === 'duplicate_charge' ? 409 : 201)
|
||||
: 422;
|
||||
$status = isset($result['error']) && $result['error'] === 'duplicate_charge'
|
||||
? 409
|
||||
: (($result['ok'] ?? false) ? 201 : 422);
|
||||
|
||||
return response()->json([
|
||||
'ok' => (bool) ($result['ok'] ?? false),
|
||||
@@ -82,9 +82,9 @@ class ChargeController extends BaseApiController
|
||||
return response()->json(['ok' => false, 'message' => 'Unable to create event charge.'], 500);
|
||||
}
|
||||
|
||||
$status = ($result['ok'] ?? false)
|
||||
? (isset($result['error']) && $result['error'] === 'duplicate_charge' ? 409 : 201)
|
||||
: 422;
|
||||
$status = isset($result['error']) && $result['error'] === 'duplicate_charge'
|
||||
? 409
|
||||
: (($result['ok'] ?? false) ? 201 : 422);
|
||||
|
||||
return response()->json([
|
||||
'ok' => (bool) ($result['ok'] ?? false),
|
||||
|
||||
@@ -24,7 +24,13 @@ class PaypalPaymentController extends BaseApiController
|
||||
|
||||
public function create(int $paymentId): JsonResponse
|
||||
{
|
||||
$result = $this->service->createPayment($paymentId);
|
||||
try {
|
||||
$result = $this->service->createPayment($paymentId);
|
||||
} catch (\RuntimeException $e) {
|
||||
$status = str_contains(strtolower($e->getMessage()), 'not found') ? 404 : 422;
|
||||
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], $status);
|
||||
}
|
||||
|
||||
return response()->json(['ok' => true] + $result);
|
||||
}
|
||||
@@ -32,11 +38,15 @@ class PaypalPaymentController extends BaseApiController
|
||||
public function execute(PaypalExecuteRequest $request): JsonResponse
|
||||
{
|
||||
$payload = $request->validated();
|
||||
$this->service->executePayment(
|
||||
(string) $payload['payer_id'],
|
||||
$payload['paypal_payment_id'] ?? null,
|
||||
isset($payload['payment_id']) ? (int) $payload['payment_id'] : null
|
||||
);
|
||||
try {
|
||||
$this->service->executePayment(
|
||||
(string) $payload['payer_id'],
|
||||
$payload['paypal_payment_id'] ?? null,
|
||||
isset($payload['payment_id']) ? (int) $payload['payment_id'] : null
|
||||
);
|
||||
} catch (\RuntimeException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
|
||||
}
|
||||
|
||||
return response()->json(['ok' => true]);
|
||||
}
|
||||
|
||||
@@ -104,6 +104,10 @@ class GradingController extends BaseApiController
|
||||
return $userId;
|
||||
}
|
||||
|
||||
if (! $this->currentUserHasAnyRole(['teacher', 'administrator', 'admin'])) {
|
||||
return response()->json(['ok' => false, 'message' => 'Forbidden.'], 403);
|
||||
}
|
||||
|
||||
$payload = $request->validated();
|
||||
$locked = $this->lockService->toggle(
|
||||
(int) $payload['class_section_id'],
|
||||
@@ -122,6 +126,10 @@ class GradingController extends BaseApiController
|
||||
return $userId;
|
||||
}
|
||||
|
||||
if (! $this->currentUserHasAnyRole(['teacher', 'administrator', 'admin'])) {
|
||||
return response()->json(['ok' => false, 'message' => 'Forbidden.'], 403);
|
||||
}
|
||||
|
||||
$payload = $request->validated();
|
||||
$count = $this->lockService->lockAll(
|
||||
(string) $payload['semester'],
|
||||
@@ -213,7 +221,11 @@ class GradingController extends BaseApiController
|
||||
|
||||
public function showPlacementBatch(int $batchId): JsonResponse
|
||||
{
|
||||
$data = $this->placementService->getPlacementBatch($batchId);
|
||||
try {
|
||||
$data = $this->placementService->getPlacementBatch($batchId);
|
||||
} catch (\RuntimeException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 404);
|
||||
}
|
||||
|
||||
return response()->json(['ok' => true] + $data);
|
||||
}
|
||||
@@ -226,12 +238,18 @@ class GradingController extends BaseApiController
|
||||
}
|
||||
|
||||
$payload = $request->validated();
|
||||
$this->placementService->updatePlacementBatch(
|
||||
$batchId,
|
||||
(string) $payload['school_year'],
|
||||
$payload['placement_level'] ?? [],
|
||||
$userId
|
||||
);
|
||||
try {
|
||||
$this->placementService->updatePlacementBatch(
|
||||
$batchId,
|
||||
(string) $payload['school_year'],
|
||||
$payload['placement_level'] ?? [],
|
||||
$userId
|
||||
);
|
||||
} catch (\RuntimeException $e) {
|
||||
$status = str_contains(strtolower($e->getMessage()), 'not found') ? 404 : 422;
|
||||
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], $status);
|
||||
}
|
||||
|
||||
return response()->json(['ok' => true]);
|
||||
}
|
||||
@@ -255,11 +273,15 @@ class GradingController extends BaseApiController
|
||||
public function belowSixtyEmail(BelowSixtyEmailRequest $request): JsonResponse
|
||||
{
|
||||
$payload = $request->validated();
|
||||
$data = $this->belowSixtyService->emailContext(
|
||||
(int) $payload['student_id'],
|
||||
(string) $payload['school_year'],
|
||||
(string) $payload['semester']
|
||||
);
|
||||
try {
|
||||
$data = $this->belowSixtyService->emailContext(
|
||||
(int) $payload['student_id'],
|
||||
(string) $payload['school_year'],
|
||||
(string) $payload['semester']
|
||||
);
|
||||
} catch (\RuntimeException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
|
||||
}
|
||||
|
||||
return response()->json(['ok' => true] + $data);
|
||||
}
|
||||
@@ -267,11 +289,15 @@ class GradingController extends BaseApiController
|
||||
public function sendBelowSixtyEmail(BelowSixtySendRequest $request): JsonResponse
|
||||
{
|
||||
$payload = $request->validated();
|
||||
$data = $this->belowSixtyService->emailContext(
|
||||
(int) $payload['student_id'],
|
||||
(string) $payload['school_year'],
|
||||
(string) $payload['semester']
|
||||
);
|
||||
try {
|
||||
$data = $this->belowSixtyService->emailContext(
|
||||
(int) $payload['student_id'],
|
||||
(string) $payload['school_year'],
|
||||
(string) $payload['semester']
|
||||
);
|
||||
} catch (\RuntimeException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
|
||||
}
|
||||
|
||||
$subject = trim((string) ($payload['subject'] ?? ''));
|
||||
if ($subject !== '') {
|
||||
@@ -334,7 +360,11 @@ class GradingController extends BaseApiController
|
||||
}
|
||||
|
||||
$payload = $request->validated();
|
||||
$count = $this->belowSixtyService->generateAllDecisions((string) $payload['school_year'], $userId);
|
||||
try {
|
||||
$count = $this->belowSixtyService->generateAllDecisions((string) $payload['school_year'], $userId);
|
||||
} catch (\RuntimeException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
|
||||
}
|
||||
|
||||
return response()->json(['ok' => true, 'saved_count' => $count]);
|
||||
}
|
||||
@@ -385,10 +415,14 @@ class GradingController extends BaseApiController
|
||||
public function belowSixtyDecisionEmail(BelowSixtyDecisionDetailsRequest $request): JsonResponse
|
||||
{
|
||||
$payload = $request->validated();
|
||||
$data = $this->belowSixtyService->decisionEmailContext(
|
||||
(int) $payload['student_id'],
|
||||
(string) $payload['school_year']
|
||||
);
|
||||
try {
|
||||
$data = $this->belowSixtyService->decisionEmailContext(
|
||||
(int) $payload['student_id'],
|
||||
(string) $payload['school_year']
|
||||
);
|
||||
} catch (\RuntimeException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
|
||||
}
|
||||
|
||||
return response()->json(['ok' => true] + $data);
|
||||
}
|
||||
@@ -396,12 +430,16 @@ class GradingController extends BaseApiController
|
||||
public function sendBelowSixtyDecisionEmail(BelowSixtyDecisionSendRequest $request): JsonResponse
|
||||
{
|
||||
$payload = $request->validated();
|
||||
$this->belowSixtyService->sendDecisionEmail(
|
||||
(int) $payload['student_id'],
|
||||
(string) $payload['school_year'],
|
||||
isset($payload['subject']) ? (string) $payload['subject'] : null,
|
||||
isset($payload['html']) ? (string) $payload['html'] : null
|
||||
);
|
||||
try {
|
||||
$this->belowSixtyService->sendDecisionEmail(
|
||||
(int) $payload['student_id'],
|
||||
(string) $payload['school_year'],
|
||||
isset($payload['subject']) ? (string) $payload['subject'] : null,
|
||||
isset($payload['html']) ? (string) $payload['html'] : null
|
||||
);
|
||||
} catch (\RuntimeException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
|
||||
}
|
||||
|
||||
return response()->json(['ok' => true]);
|
||||
}
|
||||
@@ -428,4 +466,24 @@ class GradingController extends BaseApiController
|
||||
|
||||
return $userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<string> $roles
|
||||
*/
|
||||
private function currentUserHasAnyRole(array $roles): bool
|
||||
{
|
||||
$user = request()->user() ?? auth()->user();
|
||||
if (! $user || ! method_exists($user, 'roles')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$roles = array_map('strtolower', $roles);
|
||||
|
||||
return $user->roles()
|
||||
->where(function ($query) use ($roles) {
|
||||
$query->whereIn('roles.name', $roles)
|
||||
->orWhereIn('roles.slug', $roles);
|
||||
})
|
||||
->exists();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,8 +94,7 @@ class AuthorizedUserInviteController extends Controller
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => $validator->errors(),
|
||||
'message' => 'Invalid credential setup request.',
|
||||
], 422);
|
||||
}
|
||||
|
||||
@@ -112,7 +111,7 @@ class AuthorizedUserInviteController extends Controller
|
||||
return response()->json(['message' => $e->getMessage()], 400);
|
||||
}
|
||||
|
||||
return response()->json(['message' => 'Password has been successfully set.']);
|
||||
return response()->json(['message' => 'Credential has been successfully set.']);
|
||||
}
|
||||
|
||||
private function isTrustedRedirectUrl(string $url): bool
|
||||
|
||||
@@ -33,7 +33,10 @@ class AuthorizedUsersController extends BaseApiController
|
||||
->orderBy('id')
|
||||
->get();
|
||||
|
||||
return $this->success($rows);
|
||||
return $this->success([
|
||||
'data' => $rows,
|
||||
'users' => $rows,
|
||||
]);
|
||||
}
|
||||
|
||||
public function show(int $id): JsonResponse
|
||||
|
||||
@@ -142,11 +142,15 @@ class ParentController extends BaseApiController
|
||||
}
|
||||
|
||||
$payload = $request->validated();
|
||||
$result = $this->registrationService->register(
|
||||
$guard,
|
||||
$payload['students'] ?? [],
|
||||
$payload['emergency_contacts'] ?? []
|
||||
);
|
||||
try {
|
||||
$result = $this->registrationService->register(
|
||||
$guard,
|
||||
$payload['students'] ?? [],
|
||||
$payload['emergency_contacts'] ?? []
|
||||
);
|
||||
} catch (\RuntimeException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
|
||||
}
|
||||
|
||||
$createdCount = count($result['created_student_ids']);
|
||||
$skipped = $result['skipped'] ?? [];
|
||||
@@ -177,7 +181,11 @@ class ParentController extends BaseApiController
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$this->registrationService->deleteStudent($guard, $studentId);
|
||||
try {
|
||||
$this->registrationService->deleteStudent($guard, $studentId);
|
||||
} catch (\RuntimeException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
|
||||
}
|
||||
|
||||
return response()->json(['ok' => true]);
|
||||
}
|
||||
|
||||
@@ -79,14 +79,18 @@ class ScoreCommentController extends BaseApiController
|
||||
}
|
||||
|
||||
$payload = $request->validated();
|
||||
$result = $this->service->save(
|
||||
(int) $payload['class_section_id'],
|
||||
(string) $payload['semester'],
|
||||
(string) $payload['school_year'],
|
||||
$payload['comments'],
|
||||
$payload['missing_ok'] ?? [],
|
||||
$userId
|
||||
);
|
||||
try {
|
||||
$result = $this->service->save(
|
||||
(int) $payload['class_section_id'],
|
||||
(string) $payload['semester'],
|
||||
(string) $payload['school_year'],
|
||||
$payload['comments'],
|
||||
$payload['missing_ok'] ?? [],
|
||||
$userId
|
||||
);
|
||||
} catch (\RuntimeException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 409);
|
||||
}
|
||||
|
||||
if (! empty($result['errors'])) {
|
||||
return response()->json(['ok' => false, 'errors' => $result['errors']], 422);
|
||||
@@ -103,14 +107,18 @@ class ScoreCommentController extends BaseApiController
|
||||
}
|
||||
|
||||
$payload = $request->validated();
|
||||
$result = $this->service->update(
|
||||
(int) $payload['class_section_id'],
|
||||
(string) $payload['semester'],
|
||||
(string) $payload['school_year'],
|
||||
$payload['comments'] ?? [],
|
||||
$payload['reviews'] ?? [],
|
||||
$userId
|
||||
);
|
||||
try {
|
||||
$result = $this->service->update(
|
||||
(int) $payload['class_section_id'],
|
||||
(string) $payload['semester'],
|
||||
(string) $payload['school_year'],
|
||||
$payload['comments'] ?? [],
|
||||
$payload['reviews'] ?? [],
|
||||
$userId
|
||||
);
|
||||
} catch (\RuntimeException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 409);
|
||||
}
|
||||
|
||||
if (! empty($result['errors'])) {
|
||||
return response()->json(['ok' => false, 'errors' => $result['errors']], 422);
|
||||
|
||||
@@ -55,6 +55,10 @@ class ScoreController extends BaseApiController
|
||||
return $userId;
|
||||
}
|
||||
|
||||
if (! $this->currentUserHasAnyRole(['teacher', 'administrator', 'admin'])) {
|
||||
return response()->json(['ok' => false, 'message' => 'Forbidden.'], 403);
|
||||
}
|
||||
|
||||
$payload = $request->validated();
|
||||
$this->service->submitScoresLock(
|
||||
(int) $payload['class_section_id'],
|
||||
@@ -90,4 +94,24 @@ class ScoreController extends BaseApiController
|
||||
|
||||
return $userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<string> $roles
|
||||
*/
|
||||
private function currentUserHasAnyRole(array $roles): bool
|
||||
{
|
||||
$user = request()->user() ?? auth()->user();
|
||||
if (! $user || ! method_exists($user, 'roles')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$roles = array_map('strtolower', $roles);
|
||||
|
||||
return $user->roles()
|
||||
->where(function ($query) use ($roles) {
|
||||
$query->whereIn('roles.name', $roles)
|
||||
->orWhereIn('roles.slug', $roles);
|
||||
})
|
||||
->exists();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,7 +404,18 @@ class StudentController extends BaseApiController
|
||||
$schoolYear = $validator->validated()['school_year'] ?? null;
|
||||
|
||||
$rows = StudentClass::query()
|
||||
->select('student_class.*', 'cs.class_section_name')
|
||||
->select(
|
||||
'student_class.id',
|
||||
'student_class.student_id',
|
||||
'student_class.class_section_id',
|
||||
'student_class.is_event_only',
|
||||
'student_class.semester',
|
||||
'student_class.school_year',
|
||||
'student_class.description',
|
||||
'student_class.created_at',
|
||||
'student_class.updated_at',
|
||||
'cs.class_section_name'
|
||||
)
|
||||
->leftJoin('classSection as cs', 'cs.class_section_id', '=', 'student_class.class_section_id')
|
||||
->where('student_class.student_id', $studentId)
|
||||
->when($schoolYear !== null && $schoolYear !== '', fn ($q) => $q->where('student_class.school_year', $schoolYear))
|
||||
|
||||
@@ -13,6 +13,12 @@ class FamilyImportLegacyRequest extends ApiFormRequest
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [];
|
||||
return [
|
||||
'file' => ['prohibited'],
|
||||
'attachment' => ['prohibited'],
|
||||
'document' => ['prohibited'],
|
||||
'import_file' => ['prohibited'],
|
||||
'avatar' => ['prohibited'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ class CarryforwardFinalizeRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'from_school_year' => ['required_without:id', 'string', 'max:20'],
|
||||
'to_school_year' => ['required_without:id', 'string', 'max:20'],
|
||||
'from_school_year' => ['required', 'string', 'max:20'],
|
||||
'to_school_year' => ['required', 'string', 'max:20'],
|
||||
'parent_id' => ['nullable', 'integer'],
|
||||
'reason' => ['nullable', 'string', 'max:255'],
|
||||
];
|
||||
|
||||
@@ -13,6 +13,12 @@ class ParentEnrollmentActionRequest extends ApiFormRequest
|
||||
'enroll.*' => ['integer', 'min:1'],
|
||||
'withdraw' => ['nullable', 'array'],
|
||||
'withdraw.*' => ['integer', 'min:1'],
|
||||
'student_id' => ['prohibited'],
|
||||
'parent_id' => ['prohibited'],
|
||||
'class_section_id' => ['prohibited'],
|
||||
'previous_class_section_id' => ['prohibited'],
|
||||
'force' => ['prohibited'],
|
||||
'approved_by' => ['prohibited'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,12 @@ class ParentStudentUpdateRequest extends ApiFormRequest
|
||||
'registration_grade' => ['nullable', 'string', 'max:50'],
|
||||
'allergies' => ['nullable', 'array'],
|
||||
'medical_conditions' => ['nullable', 'array'],
|
||||
'student_id' => ['prohibited'],
|
||||
'parent_id' => ['prohibited'],
|
||||
'class_section_id' => ['prohibited'],
|
||||
'previous_class_section_id' => ['prohibited'],
|
||||
'force' => ['prohibited'],
|
||||
'approved_by' => ['prohibited'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,15 @@ class StoreAuthorizedUserRequest extends FormRequest
|
||||
{
|
||||
return [
|
||||
'email' => ['required', 'string', 'email'],
|
||||
'user_id' => ['prohibited'],
|
||||
'authorized_user_id' => ['prohibited'],
|
||||
'password' => ['prohibited'],
|
||||
'password_confirmation' => ['prohibited'],
|
||||
'password_confirm' => ['prohibited'],
|
||||
'current_password' => ['prohibited'],
|
||||
'role' => ['prohibited'],
|
||||
'role_id' => ['prohibited'],
|
||||
'roles' => ['prohibited'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,15 @@ class UpdateAuthorizedUserRequest extends FormRequest
|
||||
{
|
||||
return [
|
||||
'email' => ['sometimes', 'nullable', 'string', 'email'],
|
||||
'user_id' => ['prohibited'],
|
||||
'authorized_user_id' => ['prohibited'],
|
||||
'password' => ['prohibited'],
|
||||
'password_confirmation' => ['prohibited'],
|
||||
'password_confirm' => ['prohibited'],
|
||||
'current_password' => ['prohibited'],
|
||||
'role' => ['prohibited'],
|
||||
'role_id' => ['prohibited'],
|
||||
'roles' => ['prohibited'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ class ClassAttendanceStudentResource extends JsonResource
|
||||
'firstname' => $this->resource['firstname'] ?? null,
|
||||
'lastname' => $this->resource['lastname'] ?? null,
|
||||
'class_section_id' => $this->resource['class_section_id'] ?? null,
|
||||
'updated_by' => $this->resource['updated_by'] ?? null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user