false, 'form' => '', 'mode' => Embed::MODE_POPUP, 'trigger' => Embed::TRIGGER_DELAY, 'delay' => Embed::DEFAULT_DELAY_SECONDS, 'scroll' => Embed::DEFAULT_SCROLL_PERCENT, 'frequency' => Embed::DEFAULT_FREQUENCY_DAYS, 'label' => '', 'position' => 'bottom-right', 'launcher' => false, 'hide_paths' => '', 'hide_shop' => true, ), $saved ); } /** * Saves the setting from the admin form's fields, cleaned the same way * as a block or shortcode. A pop-up or corner button only - an in-page * form belongs in a page, via the block or shortcode. * * @param array $raw Unslashed POST fields without the prefix. */ public static function save( array $raw ) { $options = Embed::normalize_options( array( 'form' => isset( $raw['form'] ) ? $raw['form'] : '', 'mode' => isset( $raw['mode'] ) ? $raw['mode'] : Embed::MODE_POPUP, 'trigger' => isset( $raw['trigger'] ) ? $raw['trigger'] : Embed::TRIGGER_DELAY, 'delay' => isset( $raw['delay'] ) ? $raw['delay'] : null, 'scroll' => isset( $raw['scroll'] ) ? $raw['scroll'] : null, 'frequency' => isset( $raw['frequency'] ) ? $raw['frequency'] : null, 'label' => isset( $raw['label'] ) ? $raw['label'] : '', 'position' => isset( $raw['position'] ) ? $raw['position'] : 'bottom-right', 'launcher' => ! empty( $raw['launcher'] ), ) ); $enabled = ! empty( $raw['enabled'] ) && null !== $options; $stored = null !== $options ? $options : self::get(); if ( Embed::MODE_INLINE === $stored['mode'] ) { $stored['mode'] = Embed::MODE_POPUP; } $stored['enabled'] = $enabled; $stored['hide_paths'] = self::clean_paths( isset( $raw['hide_paths'] ) ? (string) $raw['hide_paths'] : '' ); $stored['hide_shop'] = ! empty( $raw['hide_shop'] ); update_option( self::OPTION, $stored, true ); } /** One path per line, each starting with "/", no host, no query - at most 50. */ public static function clean_paths( $text ) { $paths = array(); foreach ( preg_split( '/[\r\n,]+/', $text ) as $line ) { $line = trim( $line ); if ( '' === $line ) { continue; } $path = (string) wp_parse_url( $line, PHP_URL_PATH ); if ( '' === $path ) { continue; } $paths[] = '/' . trim( $path, '/' ) . ( '/' === $path ? '' : '/' ); } return implode( "\n", array_slice( array_values( array_unique( str_replace( '//', '/', $paths ) ) ), 0, 50 ) ); } /** * Whether the every-page form shows on a page with this path. A listed * path also hides everything under it ("/shop/" hides "/shop/roses/"). * * @param array $setting Output of get(). * @param string $request_path The current page's path, e.g. "/about/". * @param bool $is_shop_page Whether it's a WooCommerce cart, checkout or account page. */ public static function should_show( array $setting, $request_path, $is_shop_page ) { if ( empty( $setting['enabled'] ) || ! Embed::is_valid_form_id( (string) $setting['form'] ) ) { return false; } if ( $is_shop_page && ! empty( $setting['hide_shop'] ) ) { return false; } $path = '/' . trim( (string) $request_path, '/' ) . '/'; $path = '//' === $path ? '/' : $path; foreach ( array_filter( explode( "\n", (string) $setting['hide_paths'] ) ) as $hidden ) { if ( '/' === $hidden ? '/' === $path : 0 === strpos( $path, $hidden ) ) { return false; } } return true; } /** wp_footer: prints the form's script on every page it should show on. */ public static function print_footer_script() { if ( is_admin() || is_feed() || is_embed() || ! Settings::is_connected() ) { return; } $setting = self::get(); $path = isset( $_SERVER['REQUEST_URI'] ) ? (string) wp_parse_url( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), PHP_URL_PATH ) : '/'; $home = (string) wp_parse_url( home_url( '/' ), PHP_URL_PATH ); if ( '' !== $home && '/' !== $home && 0 === strpos( $path, rtrim( $home, '/' ) ) ) { // A site installed in a subfolder: compare paths within the site. $path = substr( $path, strlen( rtrim( $home, '/' ) ) ); } if ( ! self::should_show( $setting, $path, self::is_shop_page() ) ) { return; } echo Embed::render( $setting ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- built by wp_get_script_tag(), which escapes every attribute. } private static function is_shop_page() { return ( function_exists( 'is_cart' ) && is_cart() ) || ( function_exists( 'is_checkout' ) && is_checkout() ) || ( function_exists( 'is_account_page' ) && is_account_page() ); } }