= 1 && ( ! $allow_default || (int) $value <= 3650 ); } /** Map editor choices to the established -1 / 0 / days storage contract. */ public static function retention_days( array $privacy, $allow_default = true ) { $mode = is_scalar( $privacy['retention_mode'] ?? null ) ? (string) $privacy['retention_mode'] : ''; if ( 'default' === $mode && $allow_default ) { return -1; } if ( 'manual' === $mode ) { return 0; } $value = is_scalar( $privacy['retention_days'] ?? null ) ? (int) $privacy['retention_days'] : ( $allow_default ? -1 : 365 ); return max( 'days' === $mode ? 1 : ( $allow_default ? -1 : 0 ), $allow_default ? min( 3650, $value ) : $value ); } public static function defaults() { return array( 'closed' => false, 'closed_message' => __( 'This form is not accepting submissions right now.', 'accessible-forms-by-accessible-org' ), 'confirmation_page' => 0, 'layout' => array( 'width' => 'comfortable', 'button' => 'start', 'labels' => 'above', ), 'privacy' => array( 'retention_days' => -1, 'minimal_metadata' => false, ), 'reply_to' => '', ); } public static function text( $value, $limit = 1000 ) { $text = sanitize_text_field( is_scalar( $value ) ? (string) $value : '' ); $limit = max( 0, min( 32767, (int) $limit ) ); if ( function_exists( 'mb_substr' ) ) { return mb_substr( $text, 0, $limit, 'UTF-8' ); } return preg_match( '/^.{0,' . $limit . '}/us', $text, $match ) ? $match[0] : ''; } /** * Sanitize the form-level options. * * @param array $raw Raw submitted schema. * @param array $schema Schema sanitized so far. * @return array{0: array, 1: array[]} Schema with options, and errors as [setting key, message] pairs. */ public static function sanitize( array $raw, array $schema ) { $options = self::defaults(); $errors = array(); $options['closed'] = ! empty( $raw['closed'] ); $options['closed_message'] = self::text( $raw['closed_message'] ?? $options['closed_message'] ); if ( ! Schema::meaningful( $options['closed_message'] ) ) { $errors[] = array( 'closed_message', __( 'Write the closed message in words so visitors know why they cannot send the form.', 'accessible-forms-by-accessible-org' ) ); } $options['confirmation_page'] = absint( $raw['confirmation_page'] ?? 0 ); if ( $options['confirmation_page'] && ( 'page' !== get_post_type( $options['confirmation_page'] ) || 'publish' !== get_post_status( $options['confirmation_page'] ) || '' !== get_post_field( 'post_password', $options['confirmation_page'], 'raw' ) ) ) { $errors[] = array( 'confirmation_page', __( 'Choose a published, publicly readable thank-you page.', 'accessible-forms-by-accessible-org' ) ); } $layout = is_array( $raw['layout'] ?? null ) ? $raw['layout'] : array(); $options['layout']['width'] = in_array( $layout['width'] ?? '', array( 'narrow', 'comfortable', 'full' ), true ) ? $layout['width'] : 'comfortable'; $options['layout']['button'] = in_array( $layout['button'] ?? '', array( 'start', 'center', 'end', 'full' ), true ) ? $layout['button'] : 'start'; $options['layout']['labels'] = in_array( $layout['labels'] ?? '', array( 'above', 'beside', 'floating' ), true ) ? $layout['labels'] : 'above'; $privacy = is_array( $raw['privacy'] ?? null ) ? $raw['privacy'] : array(); if ( ! self::valid_retention_days( $privacy ) ) { $errors[] = array( 'retention_days', __( 'Enter a whole number between 1 and 3,650 days for entry retention.', 'accessible-forms-by-accessible-org' ) ); } $options['privacy'] = array( 'retention_days' => self::retention_days( $privacy ), 'minimal_metadata' => ! empty( $privacy['minimal_metadata'] ), ); $emails = array_column( array_filter( $schema['fields'], static function ( $field ) { return 'email' === $field['type']; } ), 'name' ); $options['reply_to'] = sanitize_key( self::text( $raw['reply_to'] ?? '' ) ); if ( $options['reply_to'] && ! in_array( $options['reply_to'], $emails, true ) ) { $errors[] = array( 'reply_to', __( 'Choose an email field for Reply-To.', 'accessible-forms-by-accessible-org' ) ); } return array( array_merge( $schema, $options ), $errors ); } /** Resolve a thank-you page only while it remains public for every visitor. */ public static function confirmation_url( array $schema ) { $page = ! empty( $schema['confirmation_page'] ) ? get_post( $schema['confirmation_page'] ) : null; return $page && 'page' === $page->post_type && 'publish' === $page->post_status && '' === $page->post_password ? (string) get_permalink( $page ) : ''; } public static function closed( $id, array $schema ) { if ( ! empty( $schema['closed'] ) ) { return true; } // Add-ons may close a form for their own reasons, such as a schedule or an entry limit. return (bool) Extensions::filter( 'accessible_forms_form_closed', false, (int) $id, $schema ); } }