Files
unsupervised-scheduler/src/Plugin.php
T
thatguygriffandClaude Opus 5 46cee7a454
CI / Tests (PHP 8.2) (pull_request) Successful in 42s
CI / Tests (PHP 8.1) (pull_request) Successful in 52s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m42s
CI / Build Plugin Zip (pull_request) Skipped
CI / No Debug Code (pull_request) Successful in 2s
CI / Coding Standards (pull_request) Successful in 2m54s
CI / PHPStan (pull_request) Successful in 2m55s
Add an account block showing who is signed in
[us_account], or the Account block: the signed-in visitor's name, their
email, a Sign out link, and — only when the account books for someone
besides itself — the students it books for. A parent's first question on
seeing "signed in as Grace" is whether this is the account their children's
lessons are on.

Two decisions worth naming.

Signed out with no login page chosen, the block renders nothing. Its whole
subject is the person signed in, which a stranger is not, and a bare "you
are not signed in" in a site header is noise with no way to act on it. With
a login page chosen it offers a Sign in link instead. The editor preview is
populated regardless, so the block is never an invisible box to the person
placing it.

Signing out returns to the chosen login page, or to the current page when
there is none. A block meant for a header should not also navigate someone
somewhere when they use it; the login page wins when configured, because the
page they were on may well be members-only.

The name comes from UserName::format(), so the block never exposes a
username the way display_name can.

Also brings docs/features/editor-blocks.md back in step: it still described
"four shortcodes" and had never listed the family block.

Closes #142

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-07-29 22:31:28 -03:00

119 lines
6.1 KiB
PHP

<?php
declare(strict_types=1);
namespace Unsupervised\Schedular;
use Unsupervised\Schedular\Auth\EmailConfirmationHandler;
use Unsupervised\Schedular\Auth\InviteRepository;
use Unsupervised\Schedular\Auth\AccountPage;
use Unsupervised\Schedular\Auth\LoginPage;
use Unsupervised\Schedular\Auth\RegistrationLoginGate;
use Unsupervised\Schedular\Auth\RegistrationMailer;
use Unsupervised\Schedular\Auth\RegistrationPage;
use Unsupervised\Schedular\Auth\RoleManager;
use Unsupervised\Schedular\Auth\StudentAdminGuard;
use Unsupervised\Schedular\Booking\BookingPage;
use Unsupervised\Schedular\Availability\AvailabilityRepository;
use Unsupervised\Schedular\Booking\BookingRepository;
use Unsupervised\Schedular\GroupClass\EnrollmentRepository;
use Unsupervised\Schedular\GroupClass\GroupAccessRepository;
use Unsupervised\Schedular\GroupClass\GroupClassPage;
use Unsupervised\Schedular\Guardian\ChildLoginGate;
use Unsupervised\Schedular\Guardian\FamilyPage;
use Unsupervised\Schedular\Guardian\GuardianRepository;
use Unsupervised\Schedular\Guardian\GuardianService;
use Unsupervised\Schedular\Offering\OfferingRepository;
use Unsupervised\Schedular\Payment\BillingMethodResolver;
use Unsupervised\Schedular\Payment\CreditRepository;
use Unsupervised\Schedular\Payment\PaymentRepository;
use Unsupervised\Schedular\Payment\PaymentDueMailer;
use Unsupervised\Schedular\Payment\PaymentService;
use Unsupervised\Schedular\Payment\ReceiptMailer;
use Unsupervised\Schedular\Payment\ScheduledBillingRunner;
use Unsupervised\Schedular\Payment\StripeGateway;
use Unsupervised\Schedular\Payment\StudioSettings;
use Unsupervised\Schedular\Policy\AcceptanceRepository;
use Unsupervised\Schedular\Policy\PolicyRepository;
use Unsupervised\Schedular\Policy\PolicyService;
use Unsupervised\Schedular\Policy\PolicyVersionRepository;
use Unsupervised\Schedular\Registration\AnswerRepository;
use Unsupervised\Schedular\Registration\QuestionRepository;
use Unsupervised\Schedular\Registration\RegistrationGate;
use Unsupervised\Schedular\Update\UpdateChecker;
class Plugin {
public static function boot(): void {
load_plugin_textdomain( 'unsupervised-schedular', false, dirname( plugin_basename( USC_PLUGIN_FILE ) ) . '/languages' );
global $wpdb;
if ( ! $wpdb instanceof \wpdb ) {
return;
}
// Re-run install steps when the plugin files were updated without a fresh
// activation (e.g. a deploy), so schema and data migrations still apply.
if ( get_option( 'us_schedular_version' ) !== USC_VERSION ) {
( new Installer() )->run();
}
$availability = new AvailabilityRepository( $wpdb );
$bookings = new BookingRepository( $wpdb );
$offerings = new OfferingRepository( $wpdb );
$questions = new QuestionRepository( $wpdb );
// One-time repair for sites where dbDelta left us_questions.offering_id
// NOT NULL (it does not reliably relax NULL-ability), which breaks
// account-scope registration questions. Guarded by its own flag rather
// than the version gate, since affected sites may already be on the
// current version. The flag is only set once the ALTER succeeds.
if ( '1' !== get_option( 'us_questions_offering_nullable', '' ) && $questions->ensureOfferingNullable() ) {
update_option( 'us_questions_offering_nullable', '1' );
}
$answers = new AnswerRepository( $wpdb );
$policies = new PolicyRepository( $wpdb );
$policyVersions = new PolicyVersionRepository( $wpdb );
$policyService = new PolicyService( $policies, $policyVersions );
$acceptances = new AcceptanceRepository( $wpdb );
$invites = new InviteRepository( $wpdb );
$enrollments = new EnrollmentRepository( $wpdb );
$groupAccess = new GroupAccessRepository( $wpdb );
$registrationGate = new RegistrationGate( $questions, $answers, $policies, $policyVersions, $acceptances );
$guardianRepo = new GuardianRepository( $wpdb );
$guardians = new GuardianService( $guardianRepo, $bookings, $enrollments );
$paymentRepo = new PaymentRepository( $wpdb );
$creditRepo = new CreditRepository( $wpdb );
$settings = new StudioSettings();
$resolver = new BillingMethodResolver( $settings );
$stripe = new StripeGateway( $settings );
$paymentService = new PaymentService( $paymentRepo, $resolver, new ReceiptMailer(), $bookings, $enrollments, $settings, $stripe, $creditRepo );
// The shortcode and block wrappers share the same page objects so
// front-end output is identical whichever way a page embeds them.
$registrationMailer = new RegistrationMailer();
$bookingPage = new BookingPage( $guardians );
$loginPage = new LoginPage();
$registrationPage = new RegistrationPage( $invites, $policies, $policyVersions, $acceptances, $settings, $registrationMailer, $questions, $answers, $groupAccess, $guardians );
$groupClassPage = new GroupClassPage( $guardians );
$familyPage = new FamilyPage( $guardians, $questions, $answers );
$accountPage = new AccountPage( $guardians );
( new ScheduledBillingRunner( $paymentService, $bookings, $enrollments, $offerings, new PaymentDueMailer(), $guardians ) )->register();
( new UpdateChecker() )->register();
( new RoleManager() )->register();
( new RegistrationLoginGate() )->register();
( new ChildLoginGate() )->register();
( new StudentAdminGuard() )->register();
( new EmailConfirmationHandler( $settings, $registrationMailer ) )->register();
( new AdminMenu( $availability, $bookings, $offerings, $questions, $answers, $policies, $policyVersions, $policyService, $acceptances, $invites, $enrollments, $groupAccess, $settings, $paymentRepo, $paymentService, $resolver, $registrationMailer, $creditRepo, $guardians ) )->register();
( new RestRegistrar( $availability, $bookings, $offerings, $questions, $policies, $policyVersions, $policyService, $registrationGate, $enrollments, $groupAccess, $paymentService, $guardians ) )->register();
( new ShortcodeRegistrar( $bookingPage, $loginPage, $registrationPage, $groupClassPage, $familyPage, $accountPage ) )->register();
( new BlockRegistrar( $bookingPage, $loginPage, $registrationPage, $groupClassPage, $familyPage, $accountPage ) )->register();
}
}