$form, 'mode' => $mode, 'label' => $label, 'position' => ( isset( $raw['position'] ) && 'bottom-left' === $raw['position'] ) ? 'bottom-left' : 'bottom-right', 'trigger' => $trigger, 'delay' => self::clamp( isset( $raw['delay'] ) ? $raw['delay'] : null, self::DEFAULT_DELAY_SECONDS, self::MIN_DELAY_SECONDS, self::MAX_DELAY_SECONDS ), 'scroll' => self::clamp( isset( $raw['scroll'] ) ? $raw['scroll'] : null, self::DEFAULT_SCROLL_PERCENT, self::MIN_SCROLL_PERCENT, self::MAX_SCROLL_PERCENT ), 'frequency' => self::clamp( isset( $raw['frequency'] ) ? $raw['frequency'] : null, self::DEFAULT_FREQUENCY_DAYS, 0, self::MAX_FREQUENCY_DAYS ), 'launcher' => ! ( isset( $raw['launcher'] ) && in_array( $raw['launcher'], array( false, 0, '0', 'false', 'none', 'no' ), true ) ), ); } /** * The embed script's attributes - only what differs from the defaults, * exactly like buildEmbedSnippet(), so a page carries the same snippet * 404 Emails' own Installation options would give. * * @param array $options Output of normalize_options(). * @param string $platform_url The 404 Emails app address. * @return array */ public static function script_attributes( array $options, $platform_url ) { $attributes = array( 'src' => untrailingslashit( $platform_url ) . '/embed.js', 'data-form' => $options['form'], ); $mode = $options['mode']; if ( self::MODE_INLINE !== $mode ) { $attributes['data-mode'] = $mode; if ( '' !== $options['label'] ) { $attributes['data-label'] = $options['label']; } } if ( self::MODE_FLOATING === $mode && 'bottom-left' === $options['position'] ) { $attributes['data-position'] = 'bottom-left'; } if ( self::MODE_POPUP === $mode && self::TRIGGER_CLICK !== $options['trigger'] ) { $attributes['data-trigger'] = $options['trigger']; if ( self::TRIGGER_DELAY === $options['trigger'] && self::DEFAULT_DELAY_SECONDS !== $options['delay'] ) { $attributes['data-delay'] = (string) $options['delay']; } if ( self::TRIGGER_SCROLL === $options['trigger'] && self::DEFAULT_SCROLL_PERCENT !== $options['scroll'] ) { $attributes['data-scroll'] = (string) $options['scroll']; } if ( self::DEFAULT_FREQUENCY_DAYS !== $options['frequency'] ) { $attributes['data-frequency'] = (string) $options['frequency']; } if ( ! $options['launcher'] ) { $attributes['data-launcher'] = 'none'; } } return $attributes; } /** * The script tag for a form, or '' when the site isn't connected or the * form id isn't valid (a page never breaks because of a bad shortcode). * * @param array $raw Display options, see normalize_options(). * @return string */ public static function render( array $raw ) { $options = self::normalize_options( $raw ); $platform_url = Settings::get_platform_url(); if ( null === $options || '' === $platform_url ) { return ''; } return wp_get_script_tag( self::script_attributes( $options, $platform_url ) ); } /** The hosted form's address - the editor block's preview. */ public static function preview_url( $form_id, $mode = self::MODE_INLINE ) { $platform_url = Settings::get_platform_url(); if ( '' === $platform_url || ! self::is_valid_form_id( $form_id ) ) { return ''; } return untrailingslashit( $platform_url ) . '/forms/' . rawurlencode( $form_id ) . '?embed=1&instance=wp-editor&mode=' . rawurlencode( $mode ); } private static function clamp( $value, $fallback, $min, $max ) { if ( null === $value || '' === $value || ! is_numeric( $value ) ) { return $fallback; } return (int) max( $min, min( $max, (int) round( (float) $value ) ) ); } }