ad = $ad; $this->group_id = $group_id; $this->wo_meta = new WOMeta( AdCommander::ns() ); $this->meta = $this->wo_meta->get_post_meta( $ad->ID, AdPostMeta::post_meta_keys() ); $this->ad_type = $this->wo_meta->get_value( $this->meta, 'adtype', false ); /** * Initiate AdType class for this ad. */ switch ( $this->ad_type ) { case 'bannerad': $this->ad_type_instance = new AdTypeBanner( $this->ad, $this->meta, $this->wo_meta ); break; case 'textcode': case 'richcontent': $this->ad_type_instance = new AdTypeContent( $this->ad, $this->meta, $this->wo_meta, $this->ad_type ); break; default: break; } } /** * An ad is invalid if it's a bannerad, but has no post thumbnail. * * @return bool */ private function has_valid_ad() { if ( $this->ad_type === 'bannerad' ) { return has_post_thumbnail( $this->ad->ID ); } elseif ( $this->ad_type === 'textcode' ) { $content = $this->wo_meta->get_value( $this->meta, 'adcontent_text' ); return $content !== null && $content !== ''; } elseif ( $this->ad_type === 'richcontent' ) { $content = $this->wo_meta->get_value( $this->meta, 'adcontent_rich' ); return $content !== null && $content !== ''; } return true; } /** * Do we need consent to display? * * @return bool */ private function needs_consent() { if ( $this->needs_consent === null ) { if ( $this->wo_meta->get_value( $this->meta, 'disable_consent', false ) ) { $this->needs_consent = false; return $this->needs_consent; } $global_needs_consent = Consent::instance()->global_needs_consent( $this->force_no_consent_check ); $this->needs_consent = $global_needs_consent; } return $this->needs_consent; } /** * Determine if we should use ajax loading for this ad. * * @return bool */ public function should_ajax() { /** * If part of a group, never load over ajax. The group will load over ajax. */ if ( $this->group_id || ! ProBridge::instance()->is_pro_loaded() ) { return false; } $render = Util::render_method(); /** * If render method is Ajax, load over ajax. */ if ( $render === 'clientside' ) { return true; } /** * If render method is serverside, never load over ajax. */ if ( $render === 'serverside' ) { return false; } /** * 'Smart' render method. */ /** * Use consent * Always use client-side if there's a consent cookie, because page caching would cause false positives. */ if ( Consent::instance()->requires_consent() ) { return true; } /* * If max_clicks or max_impressions are set, load over ajax because otherwise expirations won't work. */ $max_clicks = $this->wo_meta->get_value( $this->meta, 'expire_clicks', false ); $max_impressions = $this->wo_meta->get_value( $this->meta, 'expire_impressions', false ); if ( $max_clicks || $max_impressions ) { return true; } $visitor_conditions = $this->wo_meta->get_value( $this->meta, 'visitor_conditions', false ); return ( ( $visitor_conditions && ! empty( $visitor_conditions ) ) ); } /** * Determine if this ad has max tracking and expire the ad if they're reached. * * @return bool */ private function check_max_tracking() { if ( ProBridge::instance()->is_pro_loaded() ) { $max_clicks = $this->wo_meta->get_value( $this->meta, 'expire_clicks', false ); $max_impressions = $this->wo_meta->get_value( $this->meta, 'expire_impressions', false ); return apply_filters( 'adcmdr_pro_check_max_tracking', false, $this->ad, $max_clicks, $max_impressions ); } return false; } /** * Potentially block a bot from seeing the ad. * * @return bool */ private function should_block_bot() { /** * Already checked when the group started. */ if ( $this->group_id ) { return false; } if ( ! Options::instance()->get( 'bots_disable_ads', 'general', true ) ) { return false; } return Bots::is_bot(); } /** * Check if ads are disabled in global settings. * * @return bool */ private function ads_disabled() { /** * Already checked when the group started. */ if ( $this->group_id ) { return false; } if ( Targeting::ads_disabled_all() ) { return true; } if ( TargetingVisitor::ads_disabled_user_role() ) { return true; } return false; } /** * Determine if tracking is disabled for this individual ad. * * @param string $type Impressoin or Click tracking (i or c). * * @return bool */ private function ad_tracking_disabled( $type ) { return Util::truthy( $this->wo_meta->get_value( $this->meta, 'donottrack_' . $type, false ) ); } /** * Determine if we should set banners in this ad to responsive width and height. * * @return bool */ private function responsive_ad_images() { return ! $this->group_id && Util::truthy_or_site_default( $this->wo_meta->get_value( $this->meta, 'responsive_banners', 'site_default' ), 'responsive_banners', 'general' ); } /** * Create list of classes for this ad. * * @param mixed $classes Classes that should be included in this ad. * * @return string */ private function ad_classes( $classes ) { $classes = Util::arrayify( $classes ); $classes[] = Util::prefixed( 'ad' ); $classes[] = Util::prefixed( 'ad-' . $this->ad->ID ); if ( $this->responsive_ad_images() ) { $classes[] = Util::prefixed( 'ad-resp' ); } $custom_classes = $this->wo_meta->get_value( $this->meta, 'custom_classes' ); if ( $custom_classes ) { $classes[] = $custom_classes; } /** * Filter: adcmdr_ad_start_class_list * Filter the list of classes for an individual ad, before they are converted into a string. */ $classes = array_unique( apply_filters( 'adcmdr_ad_start_class_list', $classes, $this->ad ) ); return implode( ' ', $classes ); } /** * Create HTML data attributes for ad tracking and identification on the front-end. * * @return string */ private function ad_data_attributes() { $data_attributes = ' data-t-id="' . esc_attr( $this->ad->ID ) . '" data-t-title="' . esc_attr( wp_strip_all_tags( $this->ad->post_title ) ) . '"'; if ( $this->ad_tracking_disabled( 'i' ) ) { $data_attributes .= ' data-ti-disabled="true"'; } if ( $this->ad_tracking_disabled( 'c' ) ) { $data_attributes .= ' data-tc-disabled="true"'; } return $data_attributes; } /** * Create an inline style for manually-set margins. * * @return string */ private function ad_inline_styles() { return Util::inline_styles( array( 'margin-top' => $this->wo_meta->get_value( $this->meta, 'margin_top', false ), 'margin-right' => $this->wo_meta->get_value( $this->meta, 'margin_right', false ), 'margin-bottom' => $this->wo_meta->get_value( $this->meta, 'margin_bottom', false ), 'margin-left' => $this->wo_meta->get_value( $this->meta, 'margin_left', false ), ) ); } /** * If ad is set to float and is not part of a group, create the float wrapper. * * @return string */ private function ad_float_wrapper() { $html = ''; if ( ! $this->disable_wrappers && ! $this->group_id ) { $float = $this->wo_meta->get_value( $this->meta, 'float', false ); if ( $float && ( $float === 'l' || $float === 'r' ) ) { $this->has_float = true; $float_class = Util::prefixed( 'f' . $float ); $html = '