apply_filters( 'the_content', get_the_content() ). * @param array $args 'output' => 'js' (default): ads as placeholders only, so the response * can be cached. 'auto': like a page view, server-rendered ads baked in. * * @return string */ function adpresso_render_in_post_context( $post, callable $callback, array $args = [] ): string { return \AdPresso\Pipeline\RenderScope::run( $post, $callback, $args ); } } if ( ! function_exists( 'adpresso_the_placement' ) ) { /** * Renders a manual placement by its ID. * * @param $placement_id * @param bool $return * * @return string */ function adpresso_the_placement( $placement_id, bool $return = false, array $shortcode_atts = [] ): string { $output = FrontendHooks::render_manual_placement( absint( $placement_id ), 'shortcode', $shortcode_atts ); if ( ! $return ) { // The output deliberately contains unfiltered HTML/JS for an advertisement. // Security is ensured by the preceding check `author_can( $post, 'unfiltered_html' )`: // the code is only output raw if the author of the ad has that permission. When // saving, entries from users without this permission are already rigorously // cleaned up with `wp_kses_post()`. // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output is pre-checked by the placement renderer, see comment above. echo $output; } return $output; } } /** * Get an existing Placement by its post ID. * * @param int $post_id * @param bool $process_data * * @return Placement|null */ function adpresso_get_placement( int $post_id, bool $process_data = true ): ?Placement { if ( get_post_type( $post_id ) !== Constants::POST_TYPE_PLACEMENT ) { return null; } return adpresso_get_placement_repository()->get( $post_id, $process_data ); } /** * Fetches the PlacementRepository instance from the Plugin globals. * * @return PlacementRepository */ function adpresso_get_placement_repository(): PlacementRepository { return Plugin::get()->globals[ PlacementRepository::class ]; }