}>} */ private static function store(): array { $store = get_option( self::OPTION, array() ); $store = is_array( $store ) ? $store : array(); $forms = array(); foreach ( (array) ( $store['forms'] ?? array() ) as $id => $form ) { if ( (int) $id > 0 && is_array( $form ) ) { $forms[ (int) $id ] = array( 'name' => (string) ( $form['name'] ?? '' ), 'settings' => is_array( $form['settings'] ?? null ) ? $form['settings'] : array(), ); } } return array( 'next' => max( 1, (int) ( $store['next'] ?? 1 ), $forms ? max( array_keys( $forms ) ) + 1 : 1 ), 'main' => (string) ( $store['main'] ?? '' ), 'forms' => $forms, ); } private static function put( array $store ): void { update_option( self::OPTION, $store, true ); } /** @return array Form id => name, main form first. */ public static function names(): array { $store = self::store(); $names = array( 0 => '' !== $store['main'] ? $store['main'] : __( 'Main form', 'abientot' ) ); foreach ( $store['forms'] as $id => $form ) { /* translators: %d: form number. */ $names[ $id ] = '' !== $form['name'] ? $form['name'] : sprintf( __( 'Form %d', 'abientot' ), $id ); } return $names; } public static function exists( int $id ): bool { return 0 === $id || isset( self::store()['forms'][ $id ] ); } /** Resolves an untrusted id (shortcode, block, request) to an existing form id. */ public static function resolve( $id ): int { $id = is_numeric( $id ) ? (int) $id : 0; return $id > 0 && self::exists( $id ) ? $id : 0; } /** Effective settings of one form: plugin settings with the form's own values on top. */ public static function settings( int $id ): array { $settings = Settings::values(); if ( $id > 0 ) { $form = self::store()['forms'][ $id ] ?? null; if ( $form ) { $settings = array_merge( $settings, array_intersect_key( $form['settings'], array_flip( self::scoped_keys() ) ) ); } } return $settings; } /** Creates a form as a copy of another one; returns the new id, or 0 when the limit is reached. */ public static function create( int $from, string $name ): int { $store = self::store(); if ( count( $store['forms'] ) >= self::MAX ) { return 0; } $id = $store['next']; $store['forms'][ $id ] = array( 'name' => sanitize_text_field( $name ), 'settings' => array_intersect_key( self::settings( self::resolve( $from ) ), array_flip( self::scoped_keys() ) ), ); $store['next'] = $id + 1; self::put( $store ); return $id; } /** Stores sanitized settings (and optionally a new name) for an additional form. */ public static function save( int $id, array $settings, ?string $name = null ): void { $store = self::store(); if ( $id <= 0 || ! isset( $store['forms'][ $id ] ) ) { return; } $store['forms'][ $id ]['settings'] = array_intersect_key( $settings, array_flip( self::scoped_keys() ) ); if ( null !== $name ) { $store['forms'][ $id ]['name'] = sanitize_text_field( $name ); } self::put( $store ); } public static function rename( int $id, string $name ): void { $store = self::store(); if ( 0 === $id ) { $store['main'] = sanitize_text_field( $name ); } elseif ( isset( $store['forms'][ $id ] ) ) { $store['forms'][ $id ]['name'] = sanitize_text_field( $name ); } else { return; } self::put( $store ); } /** The main form cannot be deleted; pages using a deleted form fall back to the main form. */ public static function delete( int $id ): bool { $store = self::store(); if ( $id <= 0 || ! isset( $store['forms'][ $id ] ) ) { return false; } unset( $store['forms'][ $id ] ); self::put( $store ); return true; } /** Shortcode that displays one form. */ public static function shortcode( int $id, string $mode = '' ): string { $attributes = ( $id > 0 ? ' form="' . $id . '"' : '' ) . ( '' !== $mode ? ' mode="' . $mode . '"' : '' ); return '[abientot_booking_form' . $attributes . ']'; } }