bookings->findById( $lessonId ); if ( null === $lesson || $lesson->studentId !== $studentId || Lesson::STATUS_CANCELLED === $lesson->status ) { return false; } $this->bookings->updateStatus( $lessonId, Lesson::STATUS_CANCELLED ); $this->availability->release( $lesson->slotId ); $this->payments->voidPending( $lesson->paymentId ); $this->payments->creditForCancelledLesson( $lesson ); return true; } /** * Withdraw the student from a group class: marks the active enrolment * cancelled (freeing its capacity seat) and voids a still-pending payment. */ public function withdrawEnrollment( int $enrollmentId, int $studentId ): bool { $enrollment = $this->enrollments->findById( $enrollmentId ); if ( null === $enrollment || $enrollment->studentId !== $studentId || Enrollment::STATUS_ACTIVE !== $enrollment->status ) { return false; } $this->enrollments->updateStatus( $enrollmentId, Enrollment::STATUS_CANCELLED ); $this->payments->voidPending( $enrollment->paymentId ); return true; } /** * Update the student's display name and email. The email must be valid and * not belong to another user. */ public function updateAccount( int $studentId, string $displayName, string $email ): bool|\WP_Error { if ( '' === $displayName ) { return new \WP_Error( 'empty_name', __( 'Display name cannot be empty.', 'unsupervised-schedular' ) ); } if ( ! is_email( $email ) ) { return new \WP_Error( 'invalid_email', __( 'Please enter a valid email address.', 'unsupervised-schedular' ) ); } $existing = email_exists( $email ); if ( false !== $existing && (int) $existing !== $studentId ) { return new \WP_Error( 'email_taken', __( 'Another account already uses this email address.', 'unsupervised-schedular' ) ); } $result = wp_update_user( [ 'ID' => $studentId, 'display_name' => $displayName, 'user_email' => $email, ] ); return $result instanceof \WP_Error ? $result : true; } }