flag( self::OPT_GRANT_STUDIO ); } /** * Whether WordPress administrators implicitly hold the instructor * capabilities (manage their own availability and lessons). */ public function adminsAreInstructors(): bool { return $this->flag( self::OPT_GRANT_INSTRUCTOR ); } /** * Read a stored toggle, defaulting to on so a fresh install keeps the * single-account behaviour. */ private function flag( string $option ): bool { return '0' !== Val::string( get_option( $option, '1' ) ); } public function renderPage(): void { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission to manage access settings.', 'unsupervised-schedular' ) ); } $error = ''; if ( isset( $_POST['usc_action'] ) && check_admin_referer( 'usc_access_action' ) ) { $error = $this->save(); } $adminsAreStudioAdmins = $this->adminsAreStudioAdmins(); $adminsAreInstructors = $this->adminsAreInstructors(); $deleteDataOnUninstall = Uninstaller::deletesDataOnUninstall(); include USC_PLUGIN_DIR . 'templates/admin/access.php'; } /** * Persist the submitted settings, reporting why the data-removal choice was * refused when it was. Everything else on the page saves either way: a * mistyped confirmation must not also swallow a capability change. */ private function save(): string { // Nonce is verified by the caller (renderPage) before this method runs. // phpcs:disable WordPress.Security.NonceVerification.Missing update_option( self::OPT_GRANT_STUDIO, isset( $_POST['grant_studio'] ) ? '1' : '0' ); update_option( self::OPT_GRANT_INSTRUCTOR, isset( $_POST['grant_instructor'] ) ? '1' : '0' ); $wanted = isset( $_POST['delete_data'] ); // Switching it off is not the dangerous direction, and needs no ceremony. if ( ! $wanted ) { Uninstaller::setDeletesDataOnUninstall( false ); return ''; } // Already on and left on: this save is about something else on the page, // so do not make them retype the word to keep a setting they already made. if ( Uninstaller::deletesDataOnUninstall() ) { return ''; } // Turning it on erases records that cannot be got back, so the tick alone // is not enough — it is one stray click, and this is the only place in the // plugin where a stray click is unrecoverable. $confirmed = 'delete' === sanitize_key( Val::string( wp_unslash( $_POST['delete_data_confirm'] ?? '' ) ) ); // phpcs:enable WordPress.Security.NonceVerification.Missing if ( ! $confirmed ) { return __( 'Data removal was not enabled: type DELETE in the confirmation box to turn it on. Everything else on this page was saved.', 'unsupervised-schedular' ); } Uninstaller::setDeletesDataOnUninstall( true ); return ''; } }