CI / Tests (PHP 8.2) (pull_request) Successful in 44s
CI / Tests (PHP 8.1) (pull_request) Successful in 49s
CI / No Debug Code (pull_request) Successful in 2s
CI / PHPStan (pull_request) Successful in 2m49s
CI / Coding Standards (pull_request) Successful in 2m55s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m40s
CI / Build Plugin Zip (pull_request) Skipped
Group classes can now be marked invite-only (us_offerings.access_mode). Invite-only classes are hidden from the public catalog and reachable only when the instructor lets someone in via one of three paths, managed from My Lessons -> My Group Classes: - Add students directly: enrols them now with a pending payment. - Make available: grants registered students access to self-enrol through the normal paid flow (multi-select, emailed a notice). - Invite by email: tokenised registration invite tied to the class for a non-account address; after they register the class becomes enrollable. Reuses an existing pending invite instead of sending a second link. New us_group_access table records grants; GET /offerings merges granted invite-only classes for the caller; enrolment requires a grant (403 invite_required) and flips it to enrolled on success. composer test (487), composer lint, composer cs all pass. Co-Authored-By: Claude Opus 4.8 <[email protected]>
68 lines
2.0 KiB
PHP
68 lines
2.0 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Unsupervised\Schedular\GroupClass;
|
|
|
|
use Unsupervised\Schedular\Val;
|
|
|
|
/**
|
|
* A grant of access to an invite-only group class. Registered students who have
|
|
* been "made available" a class hold an `invited` grant (`student_id` set);
|
|
* email-invited people who do not yet have an account hold a grant keyed by
|
|
* `email` and linked to a `us_invites` row, which is pointed at the new
|
|
* `student_id` once they register. A grant flips to `enrolled` when the student
|
|
* enrols through the normal flow.
|
|
*/
|
|
class GroupAccess {
|
|
|
|
public const STATUS_INVITED = 'invited';
|
|
public const STATUS_ENROLLED = 'enrolled';
|
|
public const STATUS_REVOKED = 'revoked';
|
|
|
|
/**
|
|
* All valid grant statuses.
|
|
*
|
|
* @var list<string>
|
|
*/
|
|
public const VALID_STATUSES = [ self::STATUS_INVITED, self::STATUS_ENROLLED, self::STATUS_REVOKED ];
|
|
|
|
public function __construct(
|
|
public readonly int $offeringId,
|
|
public readonly ?int $studentId = null,
|
|
public readonly string $email = '',
|
|
public readonly ?int $inviteId = null,
|
|
public readonly string $status = self::STATUS_INVITED,
|
|
public readonly ?int $invitedBy = null,
|
|
public readonly ?int $id = null,
|
|
) {}
|
|
|
|
public static function fromRow( \stdClass $row ): self {
|
|
return new self(
|
|
offeringId: Val::int( $row->offering_id ),
|
|
studentId: Val::intOrNull( $row->student_id ),
|
|
email: Val::string( $row->email ?? '' ),
|
|
inviteId: Val::intOrNull( $row->invite_id ?? null ),
|
|
status: Val::string( $row->status ),
|
|
invitedBy: Val::intOrNull( $row->invited_by ?? null ),
|
|
id: Val::int( $row->id ),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Returns a plain array representation of the grant.
|
|
*
|
|
* @return array<string, mixed>
|
|
*/
|
|
public function toArray(): array {
|
|
return [
|
|
'id' => $this->id,
|
|
'offering_id' => $this->offeringId,
|
|
'student_id' => $this->studentId,
|
|
'email' => $this->email,
|
|
'invite_id' => $this->inviteId,
|
|
'status' => $this->status,
|
|
'invited_by' => $this->invitedBy,
|
|
];
|
|
}
|
|
}
|