get( $ad_id );
if ( empty( $snapshot ) ) {
return '';
}
$track_server = self::should_track_server_metrics( $snapshot );
if ( $track_server ) {
do_action( 'advajra_track_server_event', $snapshot['id'], 'ad_requests', 1 );
}
if ( ! self::should_display( $snapshot ) ) {
return '';
}
$output = self::render_content( $snapshot );
if ( '' === $output ) {
return '';
}
$layout = self::resolve_layout( $snapshot );
$wrapper_styles = self::build_wrapper_styles( $layout, $snapshot['dimensions'] );
$wrapper_class = 'advajra-ad advajra-ad-' . $snapshot['id'];
$mode = ( isset( $layout['mode'] ) && '' !== $layout['mode'] ) ? $layout['mode'] : 'default';
if ( 'default' !== $mode ) {
$wrapper_class .= ' advajra-layout-' . sanitize_html_class( $mode );
}
$data_attrs = [
'data-ad-id="' . esc_attr( $snapshot['id'] ) . '"',
'data-tracking="' . esc_attr( $snapshot['tracking_mode'] ) . '"',
'data-render-context="' . esc_attr( RenderContext::normalize( $context ) ) . '"',
];
if ( ! empty( $options['placement_id'] ) ) {
$data_attrs[] = 'data-placement-id="' . esc_attr( (string) absint( $options['placement_id'] ) ) . '"';
}
if ( ! empty( $options['placement_type'] ) ) {
$data_attrs[] = 'data-placement-type="' . esc_attr( sanitize_key( $options['placement_type'] ) ) . '"';
}
$final_output = sprintf(
'
%s
',
esc_attr( $wrapper_class ),
$wrapper_styles ? ' style="' . esc_attr( $wrapper_styles ) . '"' : '',
' ' . implode( ' ', $data_attrs ),
$output
);
if ( $track_server ) {
do_action( 'advajra_track_server_event', $snapshot['id'], 'matched_requests', 1 );
}
$requires_tracking_asset = Scripts::requires_tracking_runtime( $snapshot['tracking_mode'] );
RenderState::mark_rendered( $snapshot['id'], $requires_tracking_asset );
if ( $requires_tracking_asset ) {
Scripts::enqueue_tracking_script();
}
return apply_filters( 'advajra_ad_output', $final_output, $snapshot['id'] );
} catch ( \Throwable $e ) {
// One broken ad must never crash the page.
// Route to our private plugin log, controlled by the Debug Mode setting.
Logger::error(
'Ad render failed',
[
'ad_id' => (int) $ad_id,
'context' => (string) $context,
'error' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
]
);
return '';
}
}
/**
* Shared link wrapper for fast and legacy renderers.
*
* @param string $content Content.
* @param array $snapshot Ad snapshot.
* @return string
*/
public static function wrap_with_link( $content, $snapshot ) {
$link_url = isset( $snapshot['link_url'] ) ? (string) $snapshot['link_url'] : '';
if ( '' === $link_url ) {
return $content;
}
$settings = isset( $snapshot['settings'] ) && is_array( $snapshot['settings'] ) ? $snapshot['settings'] : [];
$default_target = isset( $settings['default_target'] ) ? $settings['default_target'] : '_blank';
$target_preference = isset( $snapshot['link_target'] ) ? $snapshot['link_target'] : '';
if ( '' === $target_preference ) {
$legacy_target = $snapshot['open_new_tab'];
$target_preference = ( '1' === $legacy_target || true === $legacy_target ) ? 'new' : 'same';
}
$target = ( 'default' === $target_preference ) ? $default_target : $target_preference;
$default_nofollow = ! empty( $settings['default_nofollow'] ) ? 'yes' : 'no';
$default_sponsored = ! empty( $settings['default_sponsored'] ) ? 'yes' : 'no';
$nofollow = ( ! empty( $snapshot['link_nofollow'] ) && 'default' !== $snapshot['link_nofollow'] ) ? $snapshot['link_nofollow'] : $default_nofollow;
$sponsored = ( ! empty( $snapshot['link_sponsored'] ) && 'default' !== $snapshot['link_sponsored'] ) ? $snapshot['link_sponsored'] : $default_sponsored;
$link_attrs = [ sprintf( 'href="%s"', esc_url( $link_url ) ) ];
$is_new_tab = ( '_blank' === $target || 'new' === $target || '1' === $target || true === $target );
if ( $is_new_tab ) {
$link_attrs[] = 'target=_blank';
} elseif ( 'same' === $target || '_self' === $target || '0' === $target || false === $target ) {
$link_attrs[] = 'target=_self';
}
$rel_parts = [];
if ( 'yes' === $nofollow ) {
$rel_parts[] = 'nofollow';
}
if ( 'yes' === $sponsored ) {
$rel_parts[] = 'sponsored';
}
if ( ! empty( $rel_parts ) ) {
$link_attrs[] = sprintf( 'rel="%s"', implode( ' ', $rel_parts ) );
}
return sprintf( '%s', implode( ' ', $link_attrs ), $content );
}
/**
* Resolve default/global layout.
*
* @param array $snapshot Snapshot.
* @return array
*/
private static function resolve_layout( $snapshot ) {
$layout = isset( $snapshot['layout'] ) && is_array( $snapshot['layout'] ) ? $snapshot['layout'] : [];
$settings = isset( $snapshot['settings'] ) && is_array( $snapshot['settings'] ) ? $snapshot['settings'] : [];
if ( empty( $layout['mode'] ) || 'default' === $layout['mode'] ) {
$global_layout = $settings['default_layout'] ?? 'default';
if ( is_array( $global_layout ) ) {
$layout = array_merge( $layout, $global_layout );
} else {
$layout['mode'] = $global_layout;
}
}
return $layout;
}
/**
* Render ad content by type.
*
* @param array $snapshot Snapshot.
* @return string
*/
private static function render_content( $snapshot ) {
if ( 'image' === $snapshot['type'] ) {
return self::render_image_ad( $snapshot );
}
if ( self::should_use_legacy_renderer( $snapshot ) ) {
return self::legacy_renderer()->render( $snapshot );
}
return self::wrap_with_link( $snapshot['content'], $snapshot );
}
/**
* Whether content should use the compatibility lane.
*
* @param array $snapshot Snapshot.
* @return bool
*/
private static function should_use_legacy_renderer( $snapshot ) {
$content = isset( $snapshot['content'] ) ? (string) $snapshot['content'] : '';
if ( '' === $content ) {
return false;
}
$looks_heavy = false !== stripos( $content, '