0, 'display' => '', 'delay' => '', ), $atts, 'acquis_form' ); return self::render_standalone_form( array( 'id' => absint( $atts['id'] ), 'display' => sanitize_key( $atts['display'] ), 'delay' => '' === $atts['delay'] ? null : absint( $atts['delay'] ), ) ); } /** * Shared renderer used by every placement mechanism. * * @param array{id:int,display?:string} $args * @return string HTML */ public static function render_standalone_form( array $args ) { $form_id = absint( $args['id'] ?? 0 ); if ( ! $form_id || ! class_exists( 'ACQUIS_P3_DB' ) || ! class_exists( 'ACQUIS_Form_Renderer' ) ) { return '

' . esc_html__( '[AcquisitionSuite] No form selected, or the form system is unavailable.', 'acquisitionsuite' ) . '

'; } $form = ACQUIS_P3_DB::get_form( $form_id ); if ( ! $form ) { return '

' . esc_html__( '[AcquisitionSuite] Form not found.', 'acquisitionsuite' ) . '

'; } $settings = is_array( $form->settings ) ? $form->settings : array(); // Embedded + Popup Modal are always available (Lite). Floating // Button is added to this allow-list by Pro via the // 'acquis_form_display_styles' filter the same filter the admin // save handler validates against, so a display value can only ever // reach here if it was legitimately configurable in the first place. $allowed_styles = apply_filters( 'acquis_form_display_styles', array( 'embedded', 'popup' ) ); $display = sanitize_key( $args['display'] ?? '' ); if ( ! in_array( $display, $allowed_styles, true ) ) { $saved = in_array( $settings['display_style'] ?? '', $allowed_styles, true ) ? $settings['display_style'] : 'popup'; $display = $saved; } if ( class_exists( 'ACQUIS_P3_DB' ) ) { ACQUIS_P3_DB::track_event( 'form_view', array( 'form_id' => $form_id, 'source_post' => get_the_ID() ?: 0, 'source_url' => get_permalink() ?: home_url( '/' ), 'ip' => sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ?? '' ) ), ) ); } $is_paid = ( class_exists( 'ACQUIS_Pay_DB' ) && method_exists( 'ACQUIS_Pay_DB', 'get_form_pay_config' ) ) ? ( 'paid' === ( ACQUIS_Pay_DB::get_form_pay_config( $form_id )['type'] ?? 'free' ) ) : false; $button_label = trim( $settings['button_label'] ?? '' ); $modal_submit_label = trim( $settings['modal_submit_label'] ?? '' ); if ( 'embedded' === $display ) { return self::render_embedded( $form_id, $is_paid, $button_label ); } // The slide-in opens by itself after a few seconds: from the shortcode, else from the form's own setting, else 8. $delay = isset( $args['delay'] ) && null !== $args['delay'] ? (int) $args['delay'] : ( isset( $settings['slidein_delay'] ) ? (int) $settings['slidein_delay'] : 8 ); $delay = max( 0, min( 300, $delay ) ); return self::render_trigger_button( $form_id, $form, $display, $is_paid, $button_label, $modal_submit_label, $delay ); } /** * Popup / Floating Button both reuse the exact same shared * modal overlay + JS ACQUIS_Public::render_modal()/ajax_get_form() * are already 100% file-agnostic, and openModal(fileId=0, formId, ...) * already works today for file-gated custom forms with no changes. * data-display just tells the JS which CSS position/animation variant * to apply to the overlay before opening it. */ private static function render_trigger_button( $form_id, $form, $display, $is_paid, $button_label = '', $modal_submit_label = '', $delay = 0 ) { $label = $button_label ?: ( $form->title ?: __( 'Open Form', 'acquisitionsuite' ) ); $btn_classes = array( 'acquis-download-btn', 'acquis-standalone-form-btn' ); if ( $is_paid ) $btn_classes[] = 'acquis-pay-btn'; if ( 'floating' === $display ) $btn_classes[] = 'acquis-floating-form-btn'; if ( 'slidein' === $display ) $btn_classes[] = 'acquis-slidein-form-btn'; ob_start(); ?>