<?php
/**
* AgentForms Shortcode Handler
*
* Usage: [agentforms token="abc123"]
* [agentforms token="abc123" theme="dark"]
* [agentforms token="abc123" success="Thanks for signing up!"]
*
* Supports both classic shortcode and Gutenberg block.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Register the shortcode.
*/
add_shortcode( 'agentforms', 'agentforms_shortcode' );
/**
* Shortcode callback.
*
* @param array $atts Shortcode attributes.
* @param string $content Block content (optional, falls back to success message).
* @return string Rendered form HTML.
*/
function agentforms_shortcode( $atts, $content = '' ) {
$atts = shortcode_atts( array(
'token' => '',
'theme' => '',
'width' => '100%',
'success' => '',
), $atts, 'agentforms' );
$token = sanitize_text_field( $atts['token'] );
$theme = ! empty( $atts['theme'] ) ? sanitize_text_field( $atts['theme'] ) : '';
$width = sanitize_text_field( $atts['width'] );
$success = ! empty( $atts['success'] ) ? sanitize_text_field( $atts['success'] ) : strip_tags( $content );
if ( empty( $token ) ) {
return '<p class="agentforms-error">AgentForms: Missing token attribute. Use [agentforms token="your-token"].</p>';
}
// Load settings
$settings = get_option( 'agentforms_settings', array() );
$default_theme = isset( $settings['default_theme'] ) ? $settings['default_theme'] : 'light';
$default_success = isset( $settings['default_success_message'] ) ? $settings['default_success_message'] : 'Thank you! We will be in touch.';
// Merge overrides
$effective_theme = ! empty( $theme ) ? $theme : $default_theme;
$effective_success = ! empty( $success ) ? $success : $default_success;
// Enqueue assets
agentforms_enqueue_assets();
// Fetch config
$config = agentforms_get_config( $token );
if ( $config === false || ! isset( $config['fields'] ) || empty( $config['fields'] ) ) {
return '<div class="agentforms-wrapper"><p class="agentforms-error">Form not found or unavailable. Check the token and try again.</p></div>';
}
// Render
$fields_html = agentforms_render_fields( $config['fields'], $effective_theme );
$honeypot = isset( $config['honeypot_enabled'] ) && $config['honeypot_enabled'];
$multi_step = isset( $config['multi_step'] ) && $config['multi_step'] ? true : false;
$steps = isset( $config['steps'] ) ? $config['steps'] : null;
$form_name = isset( $config['name'] ) ? esc_attr( $config['name'] ) : 'AgentForm';
ob_start();
?>
<div class="agentforms-wrapper af-theme-<?php echo esc_attr( $effective_theme ); ?>"
style="max-width: <?php echo esc_attr( $width ); ?>;"
data-af-token="<?php echo esc_attr( $token ); ?>">
<form class="agentforms-form"
data-af-submit-url="<?php echo esc_url( rtrim( $settings['api_base_url'] ?? AGENTFORMS_BASE_URL, '/' ) . '/api/submit?token=' . rawurlencode( $token ) ); ?>"
data-af-success="<?php echo esc_attr( $effective_success ); ?>">
<?php if ( $honeypot ) : ?>
<div class="agentforms-honeypot" style="position:absolute;left:-9999px;top:-9999px;">
<label for="_fr_catch">_</label>
<input type="text" id="_fr_catch" name="_fr_catch" tabindex="-1" autocomplete="off" />
</div>
<?php endif; ?>
<?php if ( $multi_step && $steps ) : ?>
<div class="agentforms-steps-nav">
<?php $step_count = count( $steps ); ?>
<div class="agentforms-progress-bar"><div class="agentforms-progress-fill" style="width: <?php echo round( 100 / $step_count ); ?>%"></div></div>
<div class="agentforms-step-indicators">
<?php foreach ( $steps as $step_num => $step_fields ) : ?>
<span class="agentforms-step-dot<?php echo $step_num === '1' ? ' active' : ''; ?>"><?php echo esc_html( $step_num ); ?></span>
<?php endforeach; ?>
</div>
<div class="agentforms-step-title"><?php echo esc_html( 'Step 1 of ' . $step_count ); ?></div>
</div>
<?php foreach ( $steps as $step_num => $step_fields ) : ?>
<div class="agentforms-step" data-step="<?php echo esc_attr( $step_num ); ?>"<?php echo $step_num !== '1' ? ' style="display:none"' : ''; ?>>
<?php echo agentforms_render_fields( $step_fields, $effective_theme ); ?>
</div>
<?php endforeach; ?>
<div class="agentforms-step-actions">
<button type="button" class="agentforms-btn agentforms-btn-back" style="display:none">Back</button>
<button type="button" class="agentforms-btn agentforms-btn-next">Next</button>
<button type="submit" class="agentforms-btn agentforms-btn-submit" style="display:none">Submit</button>
</div>
<?php else : ?>
<?php echo $fields_html; ?>
<div class="agentforms-submit-row">
<button type="submit" class="agentforms-btn agentforms-btn-submit">Submit</button>
</div>
<?php endif; ?>
<div class="agentforms-loading" style="display:none">
<div class="agentforms-spinner"></div>
<p>Submitting...</p>
</div>
<div class="agentforms-success" style="display:none">
<p class="agentforms-success-message"></p>
</div>
<div class="agentforms-error-msg" style="display:none">
<p class="agentforms-error-text"></p>
</div>
</form>
</div>
<?php
return ob_get_clean();
}
/**
* Enqueue CSS/JS for the frontend form.
*/
function agentforms_enqueue_assets() {
wp_enqueue_style(
'agentforms-style',
AGENTFORMS_PLUGIN_URL . 'assets/af-style.css',
array(),
AGENTFORMS_VERSION
);
wp_enqueue_script(
'agentforms-embed',
AGENTFORMS_PLUGIN_URL . 'assets/af-embed.js',
array(),
AGENTFORMS_VERSION,
true
);
// Localize script with nonce for AJAX
wp_localize_script( 'agentforms-embed', 'agentformsData', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'agentforms_nonce' ),
'base_url' => AGENTFORMS_BASE_URL,
) );
}