*/ public const VALID_METHODS = [ self::VIA_PAPER, self::VIA_IN_PERSON, self::VIA_PHONE, self::VIA_EMAIL, self::VIA_OTHER ]; /** Longest note the `collected_note` VARCHAR(191) column holds. */ public const MAX_NOTE_LENGTH = 191; public function __construct( public readonly string $collectedVia, public readonly ?string $collectedNote = null, public readonly int $recordedBy = 0, ) {} /** * Build from submitted values, or explain what is wrong with them. A method * outside the vocabulary is rejected rather than stored: a column that can say * anything says nothing. `other` requires the note, since "other" on its own * answers the question with the question. */ public static function fromInput( string $collectedVia, string $collectedNote, int $recordedBy ): self|\WP_Error { if ( ! in_array( $collectedVia, self::VALID_METHODS, true ) ) { return new \WP_Error( 'invalid_collection_method', __( 'Choose how these were collected.', 'unsupervised-schedular' ) ); } $note = trim( $collectedNote ); if ( self::VIA_OTHER === $collectedVia && '' === $note ) { return new \WP_Error( 'collection_note_required', __( 'Say how these were collected.', 'unsupervised-schedular' ) ); } return new self( collectedVia: $collectedVia, collectedNote: '' !== $note ? mb_substr( $note, 0, self::MAX_NOTE_LENGTH ) : null, recordedBy: $recordedBy, ); } /** * The methods as `value => label`, for the form's picker and for reading a * stored value back on screen. * * @return array */ public static function choices(): array { return [ self::VIA_PAPER => __( 'On a signed paper form', 'unsupervised-schedular' ), self::VIA_IN_PERSON => __( 'In person', 'unsupervised-schedular' ), self::VIA_PHONE => __( 'Over the phone', 'unsupervised-schedular' ), self::VIA_EMAIL => __( 'By email', 'unsupervised-schedular' ), self::VIA_OTHER => __( 'Some other way', 'unsupervised-schedular' ), ]; } /** * How a stored row reads on screen: the method's label, plus its note. An * empty method is the ordinary case — the student answered online — and says * so rather than showing a blank cell. */ public static function describe( ?string $collectedVia, ?string $collectedNote = null ): string { if ( null === $collectedVia || '' === $collectedVia ) { return __( 'Given online when booking', 'unsupervised-schedular' ); } $label = self::choices()[ $collectedVia ] ?? $collectedVia; $note = null !== $collectedNote ? trim( $collectedNote ) : ''; return '' !== $note ? $label . ' — ' . $note : $label; } }