* @since 1.50.0 */ namespace AdvancedAds\Importers; use AdvancedAds\Options; use AdvancedAds\Constants; use AdvancedAds\Abstracts\Ad; use AdvancedAds\Abstracts\Group; use AdvancedAds\Abstracts\Placement; use AdvancedAds\Framework\Utilities\Params; use AdvancedAds\Interfaces\Importer as Interface_Importer; defined( 'ABSPATH' ) || exit; /** * WP Quads. */ class WP_Quads extends Importer implements Interface_Importer { /** * Holds the options. * * @var null */ private $options = null; /** * Session key for rollback * * @var string */ private $history_key = ''; /** * Array of ad mappings for creating groups. * * @var array */ private $ad_mapping = []; /** * Get the unique identifier (ID) of the importer. * * @return string The unique ID of the importer. */ public function get_id(): string { return 'wp_quads'; } /** * Get the title or name of the importer. * * @return string The title of the importer. */ public function get_title(): string { return __( 'WP Quads', 'advanced-ads' ); } /** * Get a description of the importer. * * @return string The description of the importer. */ public function get_description(): string { return ''; } /** * Get the icon to this importer. * * @return string The icon for the importer. */ public function get_icon(): string { return ''; } /** * Detect the importer in database. * * @return bool True if detected; otherwise, false. */ public function detect(): bool { return false; return ! empty( $this->get_plugin_options() ); } /** * Render form. * * @return void */ public function render_form(): void { ?>

%d ads.', 'advanced-ads' ), // phpcs:ignore count( (array) $this->get_plugin_options()['ads'] ) ); ?>

history_key = $this->generate_history_key(); $count = 0; $messages = []; if ( isset( $what_to_import['ads'] ) ) { $count = $this->import_ads(); } if ( isset( $what_to_import['settings'] ) ) { $this->import_settings(); } if ( isset( $what_to_import['ads'] ) ) { $messages[] = sprintf( /* translators: 1: counts 2: Importer title */ esc_html__( '%1$d ads migrated from %2$s', 'advanced-ads' ), $count, $this->get_title() ); } if ( isset( $what_to_import['settings'] ) ) { $messages[] = __( 'Settings imported.', 'advanced-ads' ); } return join( ' ', $messages ); } /** * Retrieves the WP Quads options. * * @return array|false WP Quads options, or false if not found. */ private function get_plugin_options() { if ( null !== $this->options ) { return $this->options; } $this->options = get_option( 'quads_settings' ); return $this->options; } /** * Import settings. * * @return void */ private function import_settings(): void { $options = $this->get_plugin_options(); $general = Options::instance()->get( 'advanced-ads', [] ); $pro = Options::instance()->get( 'pro', [] ); $ads_txt = Options::instance()->get( 'ads-txt', [] ); $adsense = Options::instance()->get( 'adsense', [] ); $adblocker = Options::instance()->get( 'adblocker', [] ); $tracking = Options::instance()->get( 'tracking', [] ); $tracking['everything'] = $options['ad_performance_tracking'] ?? 'false'; $adsense['adsense-wp-widget'] = ! empty( $options['reports_settings'] ) && true === $options['reports_settings'] ? 1 : null; if ( null === $adsense['adsense-wp-widget'] ) { unset( $adsense['adsense-wp-widget'] ); } if ( ! empty( $options['adsTxtEnabled'] ) ) { $ads_txt['enabled'] = true === $options['adsTxtEnabled'] ? 1 : 0; } if ( ! empty( $options['ad_blocker_support'] ) && true === $options['ad_blocker_support'] ) { $adblocker['overlay']['time_frequency'] = 2 === intval( $options['notice_behaviour'] ) ? 'everytime' : 'never'; if ( 'popup' === $options['notice_type'] ) { $adblocker['method'] = 'overlay'; $content = ''; if ( ! empty( $options['notice_title'] ) ) { $content = "

{$options['notice_title']}

"; } if ( ! empty( $options['notice_description'] ) ) { $content .= "

{$options['notice_description']}

"; } if ( ! empty( $options['notice_txt_color'] ) ) { $content = "
{$content}
"; } if ( $content ) { $adblocker['overlay']['content'] = $content; } $adblocker['overlay']['background_style'] = $options['notice_bg_color'] ? "background-color: {$options['notice_bg_color']};" : ''; $adblocker['overlay']['dismiss_style'] = $options['notice_btn_txt_color'] ? "color: {$options['notice_btn_txt_color']};" : ''; $adblocker['overlay']['dismiss_style'] .= $options['notice_btn_bg_color'] ? "background-color: {$options['notice_btn_bg_color']};" : ''; } elseif ( 'page_redirect' === $options['notice_type'] ) { $adblocker['method'] = 'redirect'; $adblocker['redirect']['url'] = get_permalink( $options['page_redirect_path']['value'] ?? null ); } } $pro['cfp']['enabled'] = ! empty( $options['click_fraud_protection'] ) && true === $options['reports_settings'] ? 1 : null; if ( null === $pro['cfp']['enabled'] ) { unset( $pro['cfp']['enabled'] ); } if ( ! empty( $options['exclude_admin_tracking'] ) ) { true === $options['exclude_admin_tracking'] ? $tracking['disabled-roles'][] = 'administrator' : $tracking['disabled-roles'] = array_diff( $tracking['disabled-roles'] ?? [], [ 'administrator' ] ); } if ( ! empty( $options['RoleBasedAccess'] ) ) { global $wp_roles; $roles = array_keys( $wp_roles->get_names() ); $show_to = wp_list_pluck( $options['RoleBasedAccess'], 'value' ); $general['hide-for-user-role'] = array_diff( $roles, $show_to ); } $pro['lazy-load']['enabled'] = ! empty( $options['delay_ad_sec'] ) && true === $options['delay_ad_sec'] ? 1 : null; if ( null === $pro['lazy-load']['enabled'] ) { unset( $pro['lazy-load']['enabled'] ); } } /** * Import ads * * @return int Number of ads imported. */ private function import_ads(): int { $count = 0; $quads_ads = $this->get_plugin_options()['ads']; $group_entities = []; // Create ads and separate groups. foreach ( $quads_ads as $quad_ad ) { $ad_type = $this->parse_ad_type( $quad_ad['ad_type'] ); if ( false === $ad_type ) { continue; } switch ( $ad_type ) { case 'create_group': case 'slider': $group_entities[] = [ 'type' => $ad_type, 'data' => $quad_ad, ]; break; case 'layer': $ad_id = ! empty( $quad_ad['ads_list'][0] ) ? $quad_ad['ads_list'][0]['value'] : 0; $ad = wp_advads_get_ad( $ad_id ); if ( $ad_id && ! $ad ) { $quad_ad['position'] = 'layer'; $this->handle_item( $ad, $quad_ad, $this->history_key ); ++$count; } break; default: $ads = $this->create_ad( $ad_type, $quad_ad ); if ( ! empty( $ads ) ) { [ $ad, $desktop_ad ] = $ads; if ( $ad->save() ) { $this->handle_item( $desktop_ad, $quad_ad, $this->history_key ); $this->handle_item( $ad, $quad_ad, $this->history_key ); ++$count; } } } } // Create groups. foreach ( $group_entities as $entity ) { $created_entity = 'create_group' === $entity['type'] ? $this->create_group( $entity['data'] ) : $this->create_slider( $entity['data'] ); $this->handle_item( $created_entity, $entity['data'] ); ++$count; } return $count; } /** * Save ad and create a placement. * * @param Ad|Group $item Ad or Group object to be saved. * @param object $quad_ad The Quad ad object. * * @return void */ private function handle_item( $item, $quad_ad ): void { if ( ! $item ) { return; } $item_id = $item->save(); if ( is_an_ad( $item ) ) { $this->ad_mapping[ $quad_ad['ad_id'] ] = $item_id; } $placement = $this->create_placement( $item, $quad_ad ); if ( $placement && $placement->save() ) { $this->add_session_key( $item, $placement, $this->history_key ); } } /** * Retrieves the corresponding Advanced Ads ad type based on the provided Quad ad type. * * @param string $ad_type The Quad ad type. * * @return string|false The corresponding Advanced Ads ad type, or false if not found. */ private function parse_ad_type( $ad_type ) { // map quad types to advanced ads types. $quad_ad_types = [ 'plain_text' => 'plain', 'background_ad' => 'image', 'random_ads' => 'create_group', 'loop_ads' => 'plain', 'parallax_ads' => 'image', 'video_ads' => 'content', 'ad_image' => 'image', 'popup_ads' => 'layer', 'carousel_ads' => 'slider', 'adsense' => 'adsense', ]; return $quad_ad_types[ $ad_type ] ?? false; } /** * Sets the content. * * @param Ad $ad The ad object. * @param array $quad_ad The quad ad data. * @param bool $is_mobile Whether the ad is for mobile or not. * * @return void */ private function parse_type_plain( $ad, $quad_ad, $is_mobile = false ): void { $ad->set_type( 'plain' ); $ad->set_content( $quad_ad[ $is_mobile ? 'mob_code' : 'code' ] ?? '' ); // need to set placement position for loop ads. if ( 'loop_ads' === $quad_ad['ad_type'] ) { $quad_ad['position'] = 'after_paragraph'; $quad_ad['paragraph_number'] = $quad_ad['ads_loop_number']; $quad_ad['repeat_paragraph'] = $quad_ad['display_after_every']; } } /** * Sets the content. * * @param Ad $ad The ad object. * @param array $quad_ad The quad ad data. * @param bool $is_mobile Whether the ad is for mobile or not. * * @return void */ private function parse_type_content( $ad, $quad_ad, $is_mobile = false ): void { $ad->set_type( 'content' ); if ( 'video_ads' === $quad_ad['ad_type'] && ! empty( $quad_ad['image_src'] ) ) { $video_width = $quad_ad['video_width'] ?? 350; $content = sprintf( '[video width="%d" mp4="%s" loop="true" autoplay="true"][/video]', $video_width, $quad_ad['image_src'] ); $url = $quad_ad['image_redirect_url']; if ( empty( $url ) ) { $content = "$content"; } $ad->set_content( $content ); // need to set sticky placement position for video ads. $quad_ad['position'] = 'sticky_footer'; } } /** * Sets the content. * * @param Ad $ad The ad object. * @param array $quad_ad The quad ad data. * @param bool $is_mobile Whether the ad is for mobile or not. * * @return void */ private function parse_type_image( $ad, $quad_ad, $is_mobile = false ): void { $ad->set_type( 'image' ); $prefix = $is_mobile ? 'mob_' : ''; $url_key = $is_mobile ? 'image_mobile_src' : 'image_src_id'; $url = ''; if ( isset( $quad_ad[ $url_key ] ) ) { $url = $is_mobile ? str_replace( '\\', '', $quad_ad[ $url_key ] ) : $quad_ad[ $url_key ]; } $img_id = $is_mobile ? attachment_url_to_postid( $url ) : $url; $meta = wp_get_attachment_metadata( $img_id ); if ( $meta ) { $ad->set_image_id( $img_id ); $ad->set_width( ! empty( $quad_ad[ $prefix . 'banner_ad_width' ] ) ? absint( $quad_ad[ $prefix . 'banner_ad_width' ] ) : absint( $meta['width'] ) ); $ad->set_height( ! empty( $quad_ad[ $prefix . 'banner_ad_height' ] ) ? absint( $quad_ad[ $prefix . 'banner_ad_height' ] ) : absint( $meta['height'] ) ); } $ad->set_url( $quad_ad['image_redirect_url'] ?? '' ); // need to set placement position for background ad. if ( 'background_ad' === $quad_ad['ad_type'] ) { $quad_ad['position'] = 'background'; } elseif ( 'background_ad' === $quad_ad['ad_type'] ) { $quad_ad['position'] = 'parallax'; } } /** * Sets the content. * * @param Ad $ad The ad object. * @param array $quad_ad The quad ad data. * @param bool $is_mobile Whether the ad is for mobile or not. * * @return void */ private function parse_type_adsense( $ad, $quad_ad, $is_mobile = false ): void { $ad->set_type( 'adsense' ); $content = []; if ( ! empty( $quad_ad['g_data_ad_slot'] ) ) { $content['slotId'] = $quad_ad['g_data_ad_slot']; } $ad_client = $quad_ad['g_data_ad_client']; if ( ! empty( $ad_client ) ) { $content['pubId'] = strpos( $ad_client, 'ca-' ) === 0 ? substr( $ad_client, 3 ) : $ad_client; } switch ( $quad_ad['adsense_ad_type'] ) { case 'display_ads': if ( 'normal' === $quad_ad['adsense_type'] ) { $content['unitType'] = 'normal'; $width = filter_var( $quad_ad['g_data_ad_width'], FILTER_VALIDATE_INT ); $height = filter_var( $quad_ad['g_data_ad_height'], FILTER_VALIDATE_INT ); $ad->set_width( false !== $width ? $width : 300 ); $ad->set_height( false !== $height ? $height : 250 ); } else { $content['unitType'] = 'responsive'; $content['resize'] = 'auto'; } break; case 'in_feed_ads': $content['unitType'] = 'in-feed'; $content['layout_key'] = $quad_ad['data_layout_key']; break; case 'in_article_ads': $content['unitType'] = 'in-article'; break; case 'matched_content': $content['unitType'] = 'matched-content'; break; default: } $ad->set_content( wp_json_encode( $content ) ); } /** * Parses the ad display conditions for a quad ad. * * @param array $quad_ad The quad ad to parse. * * @return array The parsed display conditions. */ private function parse_ad_display_conditions( $quad_ad ): array { $display_conditions = []; if ( ! isset( $quad_ad['visibility_include'] ) || empty( $quad_ad['visibility_include'] ) ) { return $display_conditions; } $index = 1; $condition_types = [ 'post_type' => 'posttypes', 'taxonomy' => 'taxonomy', 'general' => 'general', 'post' => 'post', 'page' => 'post', 'post_category' => 'taxonomy_category', 'post_format' => 'taxonomy_post_format', 'tags' => 'taxonomy_post_tag', 'page_template' => 'page_template', ]; $post_page_merged_values = []; foreach ( $condition_types as $quad_name => $aa_name ) { $conditions = array_filter( $quad_ad['visibility_include'], fn( $condition ) => $quad_name === $condition['type']['value'] ); $values = array_values( array_map( fn( $condition ) => $condition['value']['value'], $conditions ) ); // we need to merge (post and pages) condition types into one. if ( 'page' === $quad_name || 'post' === $quad_name ) { $post_page_merged_values = array_merge( $post_page_merged_values, $values ); continue; } // quad uses post tag slug as values and we use tag id. if ( 'tags' === $quad_name ) { $ids = []; foreach ( $values as $slug ) { $tag = get_term_by( 'slug', $slug, 'post_tag' ); if ( $tag && ! is_wp_error( $tag ) ) { $ids[] = $tag->term_id; } } $values = $ids; } if ( ! empty( $values ) ) { $condition_data = [ 'type' => $aa_name, 'value' => $values, 'connector' => 'or', ]; if ( in_array( $quad_name, [ 'post_type', 'post_category', 'post_format', 'tags' ], true ) ) { $condition_data['operator'] = 'is'; } $display_conditions[ $index++ ] = $condition_data; } } if ( ! empty( $post_page_merged_values ) ) { $display_conditions[ $index++ ] = [ 'type' => 'post', 'value' => $post_page_merged_values, 'connector' => 'or', 'operator' => 'is', ]; } return $display_conditions; } /** * Parses the ad visitor conditions for a quad ad. * * @param array $quad_ad The quad ad to parse. * * @return array The parsed visitor conditions. */ private function parse_ad_visitor_conditions( $quad_ad ): array { $visitor_conditions = []; if ( ! isset( $quad_ad['targeting_include'] ) || empty( $quad_ad['targeting_include'] ) ) { return $visitor_conditions; } $condition_types = [ 'device_type' => 'mobile', 'browser_language' => 'browser_lang', 'logged_in' => 'loggedin', 'user_agent' => 'user_agent', 'user_type' => 'role', 'cookie' => 'cookie', 'referrer_url' => 'referrer_url', 'browser_width' => 'device_width', ]; foreach ( $quad_ad['targeting_include'] as $condition ) { if ( ! isset( $condition_types[ $condition['type']['value'] ] ) ) { continue; } $quad_type = $condition['type']['value']; $quad_val = $condition['value']['value']; $condition_data['type'] = $condition_types[ $quad_type ]; $condition_data['connector'] = strtolower( $condition['condition'] ) ?? 'or'; // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict if ( in_array( $quad_type, [ 'device_type', 'browser_language', 'user_agent', 'user_type', 'referrer_url', ], true ) ) { $condition_data['value'] = $quad_val; } if ( 'device_type' === $quad_type ) { $condition_data['value'] = [ $quad_val ]; } elseif ( 'logged_in' === $quad_type ) { $condition_data['operator'] = 'true' === $quad_val ? 'is' : 'is_not'; unset( $condition_data['value'] ); } elseif ( 'user_agent' === $quad_type ) { $condition_data['operator'] = 'match'; } elseif ( 'cookie' === $quad_type ) { $condition_data['operator'] = 'contain'; $condition_data['cookie'] = $quad_val; $condition_data['value'] = ''; } elseif ( 'browser_language' === $quad_type || 'user_type' === $quad_type ) { $condition_data['operator'] = 'is'; } elseif ( 'referrer_url' === $quad_type ) { $condition_data['operator'] = 'contain'; } elseif ( 'browser_width' === $quad_type ) { switch ( $quad_val ) { case '320': // Extra Small Devices. $condition_data['value'] = '320'; $condition_data['operator'] = 'is_lower'; break; case '600': // Small Devices. $visitor_conditions[] = [ 'type' => $condition_types[ $quad_type ], 'value' => '321', 'operator' => 'is_higher', ]; $condition_data['value'] = '600'; $condition_data['operator'] = 'is_lower'; break; case '768': // Medium Devices. $visitor_conditions[] = [ 'type' => $condition_types[ $quad_type ], 'value' => '601', 'operator' => 'is_higher', ]; $condition_data['value'] = '768'; $condition_data['operator'] = 'is_lower'; break; case '992': // Large Devices. $visitor_conditions[] = [ 'type' => $condition_types[ $quad_type ], 'value' => '769', 'operator' => 'is_higher', ]; $condition_data['value'] = '992'; $condition_data['operator'] = 'is_lower'; break; case '1200': // Extra Large Devices. $visitor_conditions[] = [ 'type' => $condition_types[ $quad_type ], 'value' => '993', 'operator' => 'is_higher', ]; $condition_data['value'] = '1200'; $condition_data['operator'] = 'is_lower'; break; default: $condition_data['value'] = $quad_val; $condition_data['operator'] = 'is_lower'; } } $visitor_conditions[] = $condition_data; } return $visitor_conditions; } /** * Finds display conditions found in quad visitor conditions. * * @param array $quad_ad The quad ad to parse. * * @return array The parsed display conditions. */ private function parse_cross_display_conditions( $quad_ad ): array { $display_conditions = []; if ( ! isset( $quad_ad['targeting_include'] ) || empty( $quad_ad['targeting_include'] ) ) { return $display_conditions; } // url_parameter in visitor conditions, move it to display conditions. $url_parameters = array_filter( $quad_ad['targeting_include'], fn( $condition ) => 'url_parameter' === $condition['type']['value'] ); foreach ( $url_parameters as $url_parameter ) { $display_conditions[] = [ 'type' => 'request_uri', 'value' => $url_parameter['value']['value'], 'operator' => 'match', 'connector' => strtolower( $url_parameter['condition'] ) ?? 'or', ]; } return $display_conditions; } /** * Finds visitor conditions found in quad display conditions. * * @param array $quad_ad The quad ad to parse. * * @return array The parsed visitor conditions. */ private function parse_cross_visitor_conditions( $quad_ad ): array { $visitor_conditions = []; if ( ! isset( $quad_ad['visibility_include'] ) || empty( $quad_ad['visibility_include'] ) ) { return $visitor_conditions; } // user_type in visitor conditions, move it to display conditions. $user_types = array_filter( $quad_ad['visibility_include'], fn( $condition ) => 'user_type' === $condition['type']['value'] ); foreach ( $user_types as $user_type ) { $visitor_conditions[] = [ 'type' => 'role', 'value' => $user_type['value']['value'], 'operator' => 'is', 'connector' => strtolower( $user_type['condition'] ) ?? 'or', ]; } return $visitor_conditions; } /** * Parses the align and sets it for the ad. * * @param int $align The align of the quads ad. * * @return string Ad position. */ private function parse_align( $align ): string { // map quads positions to advanced ads positions. $quad_positions = [ 0 => 'left_float', 1 => 'center_nofloat', 2 => 'right_float', 3 => 'none', ]; return $quad_positions[ $align ] ?? 'none'; } /** * Creates a new Ad based quad ad data. * * @param string $ad_type The type of the ad. * @param array $quad_ad The quad ad data. * * @return array|false Ad and Mobile ad if applicable, or false if the ad creation fails. */ private function create_ad( $ad_type, $quad_ad ) { $ad = wp_advads_create_new_ad( $ad_type ); if ( ! $ad ) { return false; } $ad->set_title( sprintf( '[%s] %s', $this->get_title(), $quad_ad['label'] ) ); $ad->set_position( $this->parse_align( $quad_ad['align'] ) ); $ad->set_margin( [ 'top' => $quad_ad['margin'] ?? 0, 'right' => $quad_ad['margin_right'] ?? 0, 'bottom' => $quad_ad['margin_bottom'] ?? 0, 'left' => $quad_ad['margin_left'] ?? 0, ] ); $display_conditions = $this->parse_ad_display_conditions( $quad_ad ); $visitor_conditions = $this->parse_ad_visitor_conditions( $quad_ad ); // cross conditions. $cross_display_conditions = $this->parse_cross_display_conditions( $quad_ad ); if ( ! empty( $cross_display_conditions ) ) { $display_conditions = array_merge( $display_conditions, $cross_display_conditions ); } $cross_visitor_conditions = $this->parse_cross_visitor_conditions( $quad_ad ); if ( ! empty( $cross_visitor_conditions ) ) { $visitor_conditions = array_merge( $visitor_conditions, $cross_visitor_conditions ); } if ( method_exists( $this, 'parse_type_' . $ad_type ) ) { call_user_func( [ $this, 'parse_type_' . $ad_type ], $ad, $quad_ad, false ); } $ad->set_display_conditions( $display_conditions ); $desktop_ad = null; // mobile is checked. if ( ! empty( $quad_ad['mobile_html_check'] ) || ! empty( $quad_ad['mobile_image_check'] ) ) { // duplicate this same ad for desktop but set visitor conditionf for desktop instead of mobile. $desktop_ad = clone $ad; $desktop_ad->set_title( $desktop_ad->get_title() . ' - ' . __( 'Desktop', 'advanced-ads' ) ); $desktop_ad->set_visitor_conditions( array_merge( $visitor_conditions, [ [ 'type' => 'mobile', 'value' => [ 'desktop' ], ], ] ) ); // set mobile data & condition. if ( method_exists( $this, 'parse_type_' . $ad_type ) ) { call_user_func( [ $this, 'parse_type_' . $ad_type ], $ad, $quad_ad, true ); } $visitor_conditions = array_merge( $visitor_conditions, [ [ 'type' => 'mobile', 'value' => [ 'mobile' ], ], ] ); $ad->set_title( $ad->get_title() . ' - ' . __( 'Mobile', 'advanced-ads' ) ); } $ad->set_visitor_conditions( $visitor_conditions ); return [ $ad, $desktop_ad ]; } /** * Creates a group for a random quad ad. * * @param array $quad_ad Quad ad data. * * @return Group|false Group object or false if creation fails. */ private function create_group( $quad_ad ) { $group = wp_advads_create_new_group(); if ( ! $group || empty( $quad_ad['random_ads_list'] ) ) { return false; } $group->set_name( sprintf( '[%s] %s', $this->get_title(), $quad_ad['label'] ) ); $group->set_ad_count( 1 ); $ads = []; foreach ( $quad_ad['random_ads_list'] as $ad ) { $aa_ad_id = $this->ad_mapping[ $ad['value'] ] ?? null; if ( null !== $aa_ad_id ) { $ads[ $aa_ad_id ] = Constants::GROUP_AD_DEFAULT_WEIGHT; } } $group->set_ad_weights( $ads ); return $group; } /** * Creates slider group for a quad ad. * * @param array $quad_ad Quad ad data. * * @return Group|false Group object or false if creation fails. */ private function create_slider( $quad_ad ) { $slider = wp_advads_create_new_group( 'slider' ); if ( ! $slider || empty( $quad_ad['ads_list'] ) ) { return false; } $slider->set_name( sprintf( '[%s] %s', $this->get_title(), $quad_ad['label'] ) ); $slider_options = []; $slider_options['delay'] = ! empty( $quad_ad['carousel_speed'] ) ? $quad_ad['carousel_speed'] : 2000; if ( ! empty( $quad_ad['carousel_rndms'] ) && true === $quad_ad['carousel_rndms'] ) { $slider_options['random'] = 1; } $slider->set_prop( 'slider', $slider_options ); $ads = []; foreach ( $quad_ad['ads_list'] as $ad ) { $aa_ad_id = $this->ad_mapping[ $ad['value'] ] ?? null; if ( null !== $aa_ad_id ) { $ads[ $aa_ad_id ] = Constants::GROUP_AD_DEFAULT_WEIGHT; } } $slider->set_ad_weights( $ads ); return $slider; } /** * Creates a new placement for the given ad. * * @param Ad|Group $item The ad to create the placement for. * @param array $quad_ad The Quad ad. * * @return Placement|false The created placement, or false if not created. */ private function create_placement( $item, $quad_ad ) { $placement_data = $this->parse_placement_position( $quad_ad ); $placement = wp_advads_create_new_placement( $placement_data['type'] ); if ( ! $placement ) { return false; } $props = []; $props['type'] = $placement_data['type']; $props['title'] = sprintf( '[%s] %s', $this->get_title(), $quad_ad['label'] ); $props['item'] = ( is_a_group( $item ) ? 'group_' : 'ad_' ) . $item->get_id(); if ( $quad_ad['ad_label_check'] ) { $props['ad_label'] = $quad_ad['ad_label_check']; } foreach ( $placement_data['props'] as $key => $value ) { $props[ $key ] = $value; } $placement->set_props( $props ); $placement->save(); return $placement; } /** * Parses the Quad ad position and returns the corresponding Advanced Ads placement position. * * @param string $quad_ad The Quad ad. * * @return array The parsed type and props. */ private function parse_placement_position( $quad_ad ): array { $position = $quad_ad['position']; $parsed_type = ''; $props = []; switch ( $position ) { case 'random_ad_placement': $parsed_type = 'post_content_random'; break; case 'beginning_of_post': case 'after_more_tag': case 'after_word_count': case 'after_the_percentage': $parsed_type = 'post_top'; break; case 'middle_of_post': $parsed_type = 'post_content_middle'; break; case 'end_of_post': $parsed_type = 'post_bottom'; break; case 'before_last_paragraph': $parsed_type = 'post_content'; $props = [ // phpcs:ignore 'position' => 'before', 'index' => 1, 'tag' => 'p', 'start_from_bottom' => 1, ]; break; case 'after_paragraph': $parsed_type = 'post_content'; $props = [ // phpcs:ignore 'position' => 'after', 'index' => $quad_ad['paragraph_number'] ?? 1, 'tag' => 'p', 'repeat' => isset( $quad_ad['repeat_paragraph'] ) ? 1 : null, ]; break; case 'after_image': $parsed_type = 'post_content'; $props = [ // phpcs:ignore 'position' => 'after', 'index' => $quad_ad['paragraph_number'] ?? 1, 'tag' => 'img', ]; break; case 'before_image': $parsed_type = 'post_content'; $props = [ // phpcs:ignore 'position' => 'before', 'index' => $quad_ad['paragraph_number'] ?? 1, 'tag' => 'img', 'start_from_bottom' => 1, ]; break; case 'ad_after_id': $parsed_type = 'custom_position'; $props = [ // phpcs:ignore 'inject_by' => 'pro_custom_element', 'pro_custom_position' => 'insertAfter', 'pro_custom_element' => '#' . $quad_ad['after_class_name'], ]; break; case 'ad_after_class': $parsed_type = 'custom_position'; $props = [ // phpcs:ignore 'inject_by' => 'pro_custom_element', 'pro_custom_position' => 'insertAfter', 'pro_custom_element' => '.' . $quad_ad['after_class_name'], ]; break; case 'ad_after_customq': $parsed_type = 'post_content'; $props = [ // phpcs:ignore 'position' => 'after', 'index' => 1, 'tag' => 'custom', 'xpath' => $quad_ad['after_customq_name'] ?? '', ]; break; case 'ad_after_html_tag': case 'ad_before_html_tag': $parsed_type = 'post_content'; $quads_to_aa = [ 'p_tag' => 'p', 'img_tag' => 'img', 'div_tag' => 'div', 'h2' => 'h2', 'h3' => 'h3', 'h4' => 'h4', ]; $tag = $quads_to_aa[ $quad_ad['count_as_per'] ] ?? 'p'; $xpath = null; if ( in_array( $quad_ad['count_as_per'], [ 'h1', 'h5', 'h6', 'custom' ], true ) ) { $tag = 'custom'; $xpath = $quad_ad['count_as_per'] . '[1]'; } $props = [ // phpcs:ignore 'position' => strpos( $position, 'after' ) !== false ? 'after' : 'before', 'index' => $quad_ad['paragraph_number'] ?? 1, 'tag' => $tag, 'xpath' => $xpath, 'repeat' => isset( $quad_ad['repeat_paragraph'] ) ? 1 : null, ]; break; case 'ad_sticky_ad': $parsed_type = empty( $quad_ad['sticky_slide_ad'] ) || 'sticky_ad_bot' !== $quad_ad['sticky_slide_ad'] ? 'sticky_footer' : 'sticky_header'; $props = []; if ( ! empty( $quad_ad['cls_btn'] ) && true === $quad_ad['cls_btn'] ) { $props['close']['enabled'] = 1; } if ( ! empty( $quad_ad['sticky_ad_anim'] ) && true === $quad_ad['sticky_ad_anim'] ) { $props['sticky'] = [ 'effect' => 'fadein', 'duration' => $quad_ad['sticky_ad_anim_txt'] ?? 0, ]; } break; case 'amp_ads_in_loops': $parsed_type = 'archive_pages'; $props = [ // phpcs:ignore 'pro_archive_pages_index' => $quad_ad['ads_loop_number'] ?? 1, ]; break; case 'background': $parsed_type = 'background'; break; case 'parallax': $parsed_type = 'post_content'; $props = [ // phpcs:ignore 'position' => 'after', 'index' => 1, 'tag' => 'p', 'parallax' => [ 'enabled' => 'on', 'height' => [ 'value' => '30', 'unit' => 'vh', ], ], ]; break; case 'sticky_footer': $parsed_type = 'sticky_footer'; break; case 'layer': $parsed_type = 'layer'; if ( 'specific_time_popup' === $quad_ad['popup_type'] ) { $props['layer_placement'] = [ 'trigger' => 'delay', 'delay_sec' => ! empty( $quad_ad['specific_time_interval_sec'] ) ? $quad_ad['specific_time_interval_sec'] / 1000 : 0, ]; } elseif ( 'on_scroll_popup' === $quad_ad['popup_type'] ) { $props['layer_placement'] = [ 'trigger' => 'custom', 'offset' => '200', ]; } break; case 'ad_shortcode': default: $parsed_type = 'default'; } return [ 'type' => $parsed_type, 'props' => $props, ]; } }