File: //proc/self/cwd/wp-content/plugins/wp-recipe-maker/includes/public/class-wprm-shortcode.php
<?php
/**
* Handle the recipe shortcode.
*
* @link https://bootstrapped.ventures
* @since 1.0.0
*
* @package WP_Recipe_Maker
* @subpackage WP_Recipe_Maker/includes/public
*/
/**
* Handle the recipe shortcode.
*
* @since 1.0.0
* @package WP_Recipe_Maker
* @subpackage WP_Recipe_Maker/includes/public
* @author Brecht Vandersmissen <brecht@bootstrapped.ventures>
*/
class WPRM_Shortcode {
/**
* Type of shortcode we're outputting.
*
* @since 5.10.0
* @access private
* @var array $shortcode_type Shortcode type we're currently outputting.
*/
private static $shortcode_type = array();
/**
* Register actions and filters.
*
* @since 1.0.0
*/
public static function init() {
add_shortcode( 'wprm-recipe', array( __CLASS__, 'recipe_shortcode' ) );
add_action( 'admin_init', array( __CLASS__, 'register_rest_prepare' ) );
add_filter( 'content_edit_pre', array( __CLASS__, 'replace_imported_shortcodes' ) );
add_filter( 'the_content', array( __CLASS__, 'replace_tasty_shortcode' ), 1 );
add_filter( 'elementor/frontend/builder_content_data', array( __CLASS__, 'replace_tasty_elementor_widget_filter' ), 10, 2 );
add_filter( 'elementor/editor/localize_settings', array( __CLASS__, 'replace_tasty_elementor_widget_editor' ), 10, 1 );
add_filter( 'the_content', array( __CLASS__, 'replace_ziplist_shortcode' ), 1 );
add_filter( 'render_block', array( __CLASS__, 'replace_blocks' ), 10, 2 );
add_filter( 'get_the_excerpt', array( __CLASS__, 'before_generating_excerpt' ), 9 );
add_filter( 'get_the_excerpt', array( __CLASS__, 'after_generating_excerpt' ), 11 );
add_action( 'init', array( __CLASS__, 'fallback_shortcodes' ), 99 );
}
/**
* Register REST prepare hooks.
*
* @since 9.4.0
*/
public static function register_rest_prepare() {
$post_types = get_post_types();
foreach ( $post_types as $key => $label ) {
add_filter( 'rest_prepare_' . $key, array( __CLASS__, 'replace_imported_shortcodes_rest_api' ), 10, 3 );
}
}
/**
* Set current shortcode type to "excerpt".
*
* @since 5.10.0
* @param mixed $excerpt Excerpt that is being output.
*/
public static function before_generating_excerpt( $excerpt ) {
self::$shortcode_type[] = 'excerpt';
return $excerpt;
}
/**
* Remove "excerpt" shortcode type again.
*
* @since 5.10.0
* @param mixed $excerpt Excerpt that is being output.
*/
public static function after_generating_excerpt( $excerpt ) {
array_pop( self::$shortcode_type );
return $excerpt;
}
/**
* Fallback shortcodes for recipe plugins that we imported from.
*
* @since 1.3.0
*/
public static function fallback_shortcodes() {
if ( ! shortcode_exists( 'seo_recipe' ) ) {
add_shortcode( 'seo_recipe', array( __CLASS__, 'recipe_shortcode_fallback' ) );
}
if ( ! shortcode_exists( 'tasty-recipe' ) ) {
add_shortcode( 'tasty-recipe', array( __CLASS__, 'recipe_shortcode_fallback' ) );
}
if ( ! shortcode_exists( 'ultimate-recipe' ) ) {
add_shortcode( 'ultimate-recipe', array( __CLASS__, 'recipe_shortcode_fallback' ) );
}
if ( ! shortcode_exists( 'cooked-recipe' ) ) {
add_shortcode( 'cooked-recipe', array( __CLASS__, 'recipe_shortcode_fallback' ) );
}
// Recipes by Simmer.
if ( ! shortcode_exists( 'recipe' ) ) {
add_shortcode( 'recipe', array( __CLASS__, 'recipe_shortcode_fallback' ) );
}
if ( ! shortcode_exists( 'nutrition-label' ) ) {
add_shortcode( 'nutrition-label', array( __CLASS__, 'remove_shortcode' ) );
add_shortcode( 'ultimate-nutrition-label', array( __CLASS__, 'remove_shortcode' ) );
}
if ( ! shortcode_exists( 'recipe-timer' ) ) {
add_shortcode( 'recipe-timer', array( __CLASS__, 'timer_shortcode' ) );
}
}
/**
* Replace imported shortcode with ours.
*
* @since 2.1.0
* @param mixed $content Content we want to filter before it gets passed along.
*/
public static function replace_imported_shortcodes( $content ) {
$content = self::replace_wpultimaterecipe_shortcode( $content );
$content = self::replace_tasty_shortcode( $content );
$content = self::replace_ziplist_shortcode( $content );
$content = self::replace_bigoven_shortcode( $content );
$content = self::replace_wpzoom_shortcode( $content );
return $content;
}
/**
* Replace imported shortcodes in the rest API.
*
* @since 9.4.0
* @param WP_REST_Response $response The response object.
* @param WP_Post $post Post object.
* @param WP_REST_Request $request Request object.
*/
public static function replace_imported_shortcodes_rest_api( $response, $post, $request ) {
$params = $request->get_params();
if ( isset( $params['context'] ) && 'edit' === $params['context'] ) {
if ( isset( $response->data['content']['raw'] ) ) {
$response->data['content']['raw'] = self::replace_imported_shortcodes( $response->data['content']['raw'] );
}
}
return $response;
}
/**
* Replace WP Ultimate Recipe shortcode with ours.
*
* @since 1.3.0
* @param mixed $content Content we want to filter before it gets passed along.
*/
public static function replace_wpultimaterecipe_shortcode( $content ) {
preg_match_all( "/\[ultimate-recipe\s.*?id='?\"?(\d+).*?]/im", $content, $matches );
foreach ( $matches[0] as $key => $match ) {
if ( WPRM_POST_TYPE === get_post_type( $matches[1][ $key ] ) ) {
$content = str_replace( $match, '[wprm-recipe id="' . $matches[1][ $key ] . '"]', $content );
}
}
return $content;
}
/**
* Filter wrapper for Elementor widget replacement with cache clearing.
*
* @since 1.23.0
* @param array $data Elementor builder content data.
* @param int $post_id Post ID.
*/
public static function replace_tasty_elementor_widget_filter( $data, $post_id ) {
$result = self::replace_tasty_elementor_widget( $data, $post_id );
// Clear Elementor cache if any widgets were replaced
if ( $result['widget_replaced'] ) {
// Clear Elementor element cache for this post
delete_post_meta( $post_id, '_elementor_element_cache' );
// Also clear the global Elementor cache if available
if ( class_exists( 'Elementor\Plugin' ) && isset( \Elementor\Plugin::$instance->files_manager ) ) {
\Elementor\Plugin::$instance->files_manager->clear_cache();
}
}
return $result['data'];
}
/**
* Replace Tasty Recipes Elementor widget in editor.
*
* @since 1.23.0
* @param array $settings Editor settings data.
*/
public static function replace_tasty_elementor_widget_editor( $settings ) {
// Check if we're in the editor and have post data
if ( ! isset( $settings['initial_document']['elements'] ) ) {
return $settings;
}
$post_id = isset( $settings['initial_document']['id'] ) ? $settings['initial_document']['id'] : 0;
if ( ! $post_id ) {
return $settings;
}
$result = self::replace_tasty_elementor_widget( $settings['initial_document']['elements'], $post_id );
if ( $result['widget_replaced'] ) {
$settings['initial_document']['elements'] = $result['data'];
}
return $settings;
}
/**
* Replace Tasty Recipes Elementor widget with ours.
*
* @since 1.23.0
* @param array $data Elementor builder content data.
* @param int $post_id Post ID.
*/
public static function replace_tasty_elementor_widget( $data, $post_id ) {
if ( ! is_array( $data ) ) {
return $data;
}
$widget_replaced = false;
foreach ( $data as $key => $element ) {
if ( isset( $element['widgetType'] ) && 'tasty-recipe' === $element['widgetType'] ) {
$id = isset( $element['settings']['recipe_id'] ) ? intval( $element['settings']['recipe_id'] ) : false;
if ( $id ) {
$wprm_recipe_id = self::get_wprm_recipe_id_from_tasty_reference( $id );
if ( $wprm_recipe_id ) {
$data[ $key ] = self::convert_elementor_element_to_wprm_widget( $data[ $key ], $wprm_recipe_id );
unset( $data[ $key ]['settings']['recipe_id'] );
$widget_replaced = true;
}
}
} elseif ( isset( $element['widgetType'] ) && 'text-editor' === $element['widgetType'] && isset( $element['settings']['editor'] ) ) {
$widget_id = self::get_wprm_recipe_id_from_single_tasty_shortcode( $element['settings']['editor'] );
if ( $widget_id ) {
$data[ $key ] = self::convert_elementor_element_to_wprm_widget( $data[ $key ], $widget_id );
$widget_replaced = true;
} else {
$original_content = $element['settings']['editor'];
$replaced_content = self::replace_tasty_shortcode( $original_content );
if ( $replaced_content !== $original_content ) {
$data[ $key ]['settings']['editor'] = $replaced_content;
$widget_replaced = true;
}
}
} elseif ( isset( $element['widgetType'] ) && 'shortcode' === $element['widgetType'] && isset( $element['settings']['shortcode'] ) ) {
$widget_id = self::get_wprm_recipe_id_from_single_tasty_shortcode( $element['settings']['shortcode'] );
if ( $widget_id ) {
$data[ $key ] = self::convert_elementor_element_to_wprm_widget( $data[ $key ], $widget_id );
$widget_replaced = true;
} else {
$original_shortcode = $element['settings']['shortcode'];
$replaced_shortcode = self::replace_tasty_shortcode( $original_shortcode );
if ( $replaced_shortcode !== $original_shortcode ) {
$data[ $key ]['settings']['shortcode'] = $replaced_shortcode;
$widget_replaced = true;
}
}
}
// Recursively process nested elements
if ( isset( $element['elements'] ) && is_array( $element['elements'] ) ) {
$nested_result = self::replace_tasty_elementor_widget( $element['elements'], $post_id );
$data[ $key ]['elements'] = $nested_result['data'];
if ( $nested_result['widget_replaced'] ) {
$widget_replaced = true;
}
}
}
return array(
'data' => $data,
'widget_replaced' => $widget_replaced,
);
}
/**
* Replace Tasty Recipes shortcode with ours.
*
* @since 1.23.0
* @param mixed $content Content we want to filter before it gets passed along.
*/
public static function replace_tasty_shortcode( $content ) {
preg_match_all( "/\[tasty-recipe\s.*?id='?\"?(\d+).*?]/im", $content, $matches );
foreach ( $matches[0] as $key => $match ) {
if ( WPRM_POST_TYPE === get_post_type( $matches[1][ $key ] ) ) {
$content = str_replace( $match, '[wprm-recipe id="' . $matches[1][ $key ] . '"]', $content );
}
}
if ( function_exists( 'parse_blocks' ) ) {
preg_match_all( '/<!--(.*?)-->/im', $content, $matches);
foreach ( $matches[0] as $key => $match ) {
$blocks = parse_blocks( $match );
if ( $blocks && 1 === count( $blocks ) && $blocks[0] && 'wp-tasty/tasty-recipe' === $blocks[0]['blockName'] ) {
$id = $blocks[0]['attrs']['id'];
if ( $id && WPRM_POST_TYPE === get_post_type( $id ) ) {
$wprm_block = self::get_block_replacement( $id );
$content = str_replace( $match, $wprm_block, $content );
}
}
}
}
return $content;
}
/**
* Try to get a WPRM recipe ID from a piece of content that only contains a Tasty shortcode.
*
* @since 10.0.0
* @param string $content Content to inspect.
*/
private static function get_wprm_recipe_id_from_single_tasty_shortcode( $content ) {
$shortcode_id = self::get_single_tasty_shortcode_id_from_content( $content );
if ( ! $shortcode_id ) {
return false;
}
return self::get_wprm_recipe_id_from_tasty_reference( $shortcode_id );
}
/**
* Extract a Tasty shortcode ID when the content only contains that shortcode.
*
* @since 10.0.0
* @param string $content Content to inspect.
*/
private static function get_single_tasty_shortcode_id_from_content( $content ) {
if ( ! is_string( $content ) ) {
return false;
}
$sanitized = html_entity_decode( trim( $content ) );
$sanitized = trim( strip_tags( $sanitized ) );
if ( '' === $sanitized ) {
return false;
}
if ( preg_match( '/^\[tasty-recipe\s+.*?id\s*=\s*[\'"]?(\d+).*?\]\s*$/i', $sanitized, $match ) ) {
return intval( $match[1] );
}
return false;
}
/**
* Determine the WPRM recipe ID that should replace a Tasty reference.
*
* @since 10.0.0
* @param int $id Tasty recipe ID.
*/
private static function get_wprm_recipe_id_from_tasty_reference( $id ) {
if ( ! $id ) {
return false;
}
if ( WPRM_POST_TYPE === get_post_type( $id ) ) {
return $id;
}
$wprm_imported_to = get_post_meta( $id, 'wprm_imported_to', true );
if ( $wprm_imported_to && WPRM_POST_TYPE === get_post_type( $wprm_imported_to ) ) {
return $wprm_imported_to;
}
return false;
}
/**
* Convert an Elementor widget array to the WPRM widget with the provided recipe ID.
*
* @since 10.0.0
* @param array $element Elementor widget data.
* @param int $recipe_id WPRM recipe ID.
*/
private static function convert_elementor_element_to_wprm_widget( $element, $recipe_id ) {
$element['widgetType'] = 'wprm-recipe';
if ( ! isset( $element['settings'] ) || ! is_array( $element['settings'] ) ) {
$element['settings'] = array();
}
$element['settings']['wprm_recipe_id'] = $recipe_id;
unset( $element['settings']['editor'] );
unset( $element['settings']['shortcode'] );
return $element;
}
/**
* Replace ZipList shortcode with ours.
*
* @since 1.23.0
* @param mixed $content Content we want to filter before it gets passed along.
*/
public static function replace_ziplist_shortcode( $content ) {
global $wpdb;
$zl_table = $wpdb->prefix . 'amd_zlrecipe_recipes';
preg_match_all( "/\[zrdn-recipe\s.*?id='?\"?(\d+).*?]/im", $content, $matches );
foreach ( $matches[0] as $key => $match ) {
$zl_id = intval( $matches[1][ $key ] );
if ( $zl_id ) {
$zl_recipe = $wpdb->get_row( $wpdb->prepare(
"SELECT post_id FROM `%1s`
WHERE recipe_id = %d",
array(
$zl_table,
$zl_id,
)
) );
$post_id = $zl_recipe ? $zl_recipe->post_id : false;
if ( $post_id && WPRM_POST_TYPE === get_post_type( $post_id ) ) {
$content = str_replace( $match, '[wprm-recipe id="' . $post_id . '"]', $content );
}
}
}
if ( function_exists( 'parse_blocks' ) ) {
preg_match_all( '/<!--(.*?)-->/im', $content, $matches);
foreach ( $matches[0] as $key => $match ) {
$blocks = parse_blocks( $match );
if ( $blocks && 1 === count( $blocks ) && $blocks[0] && 'zip-recipes/recipe-block' === $blocks[0]['blockName'] ) {
$zl_id = intval( $blocks[0]['attrs']['id'] );
if ( $zl_id ) {
global $wpdb;
$zl_recipe = $wpdb->get_row( $wpdb->prepare(
"SELECT post_id FROM `%1s`
WHERE recipe_id = %d",
array(
$zl_table,
$zl_id,
)
) );
$post_id = $zl_recipe ? $zl_recipe->post_id : false;
if ( $post_id && WPRM_POST_TYPE === get_post_type( $post_id ) ) {
$wprm_block = self::get_block_replacement( $post_id );
$content = str_replace( $match, $wprm_block, $content );
}
}
}
}
}
return $content;
}
/**
* Replace BigOven shortcode with ours.
*
* @since 1.7.0
* @param mixed $content Content we want to filter before it gets passed along.
*/
public static function replace_bigoven_shortcode( $content ) {
preg_match_all( "/\[seo_recipe\s.*?id='?\"?(\d+).*?]/im", $content, $matches );
foreach ( $matches[0] as $key => $match ) {
if ( WPRM_POST_TYPE === get_post_type( $matches[1][ $key ] ) ) {
$content = str_replace( $match, '[wprm-recipe id="' . $matches[1][ $key ] . '"]', $content );
}
}
return $content;
}
/**
* Replace WP Zoom shortcode with ours.
*
* @since 8.9.0
* @param mixed $content Content we want to filter before it gets passed along.
*/
public static function replace_wpzoom_shortcode( $content ) {
preg_match_all( "/\[wpzoom_rcb_post\s.*?id='?\"?(\d+).*?]/im", $content, $matches );
foreach ( $matches[0] as $key => $match ) {
$id = $matches[1][ $key ];
$wprm_imported_to = get_post_meta( $id, 'wprm_imported_to', true );
if ( $wprm_imported_to ) {
$content = str_replace( $match, '[wprm-recipe id="' . $wprm_imported_to . '"]', $content );
}
}
if ( function_exists( 'parse_blocks' ) ) {
preg_match_all( '/<!--(.*?)-->/im', $content, $matches);
foreach ( $matches[0] as $key => $match ) {
$blocks = parse_blocks( $match );
if ( $blocks && 1 === count( $blocks ) && $blocks[0] && 'wpzoom-recipe-card/recipe-block-from-posts' === $blocks[0]['blockName'] ) {
$id = $blocks[0]['attrs']['postId'];
if ( $id ) {
$wprm_imported_to = get_post_meta( $id, 'wprm_imported_to', true );
if ( $wprm_imported_to ) {
$wprm_block = self::get_block_replacement( $wprm_imported_to );
$content = str_replace( $match, $wprm_block, $content );
}
}
}
}
}
return $content;
}
/**
* Get block replacement to use for imported recipes.
*
* @since 9.4.0
* @param int $recipe_id Recipe ID to get the block for.
*/
public static function get_block_replacement( $recipe_id ) {
$block = '';
$recipe_id = intval( $recipe_id ); // Make sure it's an integer.
$updated = time() * 1000; // Match JavaScript time in milliseconds.
$block .= '<!-- wp:wp-recipe-maker/recipe {"id":' . $recipe_id . ',"updated":' . $updated .'} -->';
$block .= '[wprm-recipe id="' . $recipe_id . '"]';
$block .= '<!-- /wp:wp-recipe-maker/recipe -->';
return $block;
}
/**
* Replace blocks by other recipe plugins with ours, if they have been imported.
*
* @since 8.0.0
* @param mixed $content Content we want to filter before it gets passed along.
* @param mixed $block Block we're currently filtering.
*/
public static function replace_blocks( $content, $block ) {
// Tasty Recipes.
if ( 'wp-tasty/tasty-recipe' === $block['blockName'] ) {
$id = isset( $block['attrs']['id'] ) ? intval( $block['attrs']['id'] ) : false;
if ( $id && WPRM_POST_TYPE === get_post_type( $id ) ) {
$content = do_shortcode( '[wprm-recipe id="' . $id . '"]' );
}
}
// Zip Recipes.
if ( 'zip-recipes/recipe-block' === $block['blockName'] ) {
$zl_id = isset( $block['attrs']['id'] ) ? intval( $block['attrs']['id'] ) : false;
if ( $zl_id ) {
global $wpdb;
$zl_table = $wpdb->prefix . 'amd_zlrecipe_recipes';
$zl_recipe = $wpdb->get_row( $wpdb->prepare(
"SELECT post_id FROM `%1s`
WHERE recipe_id = %d",
array(
$zl_table,
$zl_id,
)
) );
$post_id = $zl_recipe ? $zl_recipe->post_id : false;
if ( $post_id && WPRM_POST_TYPE === get_post_type( $post_id ) ) {
$content = do_shortcode( '[wprm-recipe id="' . $post_id . '"]' );
}
}
}
// WP Zoom.
if ( 'wpzoom-recipe-card/recipe-block-from-posts' === $block['blockName'] ) {
$wpzoom_id = isset( $block['attrs']['postId'] ) ? intval( $block['attrs']['postId'] ) : false;
if ( $wpzoom_id ) {
$wprm_imported_to = get_post_meta( $wpzoom_id, 'wprm_imported_to', true );
if ( $wprm_imported_to ) {
$content = do_shortcode( '[wprm-recipe id="' . $wprm_imported_to . '"]' );
}
}
}
return $content;
}
/**
* To be used for shortcodes we want to (temporarily) remove from the content.
*
* @since 1.3.0
*/
public static function remove_shortcode() {
return '';
}
/**
* Output for a fallback shortcode from another plugin.
*
* @since 4.2.1
* @param array $atts Options passed along with the shortcode.
*/
public static function recipe_shortcode_fallback( $atts ) {
$atts = shortcode_atts( array(
'id' => false,
'template' => '',
), $atts );
// Prevent outputting random recipe.
if ( false === $atts['id'] ) {
return '';
} else {
if ( WPRM_POST_TYPE !== get_post_type( $atts['id'] ) ) {
// Find recipe in content.
$recipe_ids = WPRM_Recipe_Manager::get_recipe_ids_from_post( $atts['id'] );
if ( $recipe_ids && isset( $recipe_ids[0] ) ) {
$atts['id'] = $recipe_ids[0];
} else {
// WP Ultimate Recipe shortcode migrated?
$migrated_id = get_post_meta( $atts['id'], '_wpurp_wprm_migrated', true );
if ( $migrated_id ) {
$atts['id'] = intval( $migrated_id );
}
}
}
return self::recipe_shortcode( $atts );
}
}
/**
* Output for the recipe shortcode.
*
* @since 1.0.0
* @param array $atts Options passed along with the shortcode.
*/
public static function recipe_shortcode( $atts ) {
$atts = shortcode_atts( array(
'id' => 'random',
'preview' => '',
'align' => '',
'template' => '',
), $atts, 'wprm_recipe' );
$recipe_template = trim( $atts['template'] );
$recipe = false;
// Check if we're previewing a recipe.
if ( $atts['preview'] ) {
$recipe_id = $atts['preview'];
$recipe = WPRM_Preview::get_preview_recipe( $atts['preview'] );
} else {
// Not previewing, get recipe from ID.
if ( 'random' === $atts['id'] ) {
$posts = get_posts( array(
'post_type' => WPRM_POST_TYPE,
'posts_per_page' => 1,
'orderby' => 'rand',
) );
$recipe_id = isset( $posts[0] ) ? $posts[0]->ID : 0;
} elseif ( 'latest' === $atts['id'] ) {
$posts = get_posts(array(
'post_type' => WPRM_POST_TYPE,
'posts_per_page' => 1,
));
$recipe_id = isset( $posts[0] ) ? $posts[0]->ID : 0;
} elseif ( 'demo' === $atts['id'] ) {
$recipe_id = 'demo';
} else {
$recipe_id = intval( $atts['id'] );
}
$recipe = WPRM_Recipe_Manager::get_recipe( $recipe_id );
}
if ( $recipe ) {
WPRM_Assets::load();
// Output recipe data on page.
add_filter( 'wprm_recipes_on_page', function( $recipes ) use ( $recipe_id ) {
$recipes[] = $recipe_id;
return $recipes;
} );
// Check type of recipe we need to output.
if ( 0 < count( self::$shortcode_type ) ) {
$type = end( self::$shortcode_type );
} else {
$type = 'single';
if ( is_feed() ) {
$type = 'feed';
} elseif ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() ) {
$type = 'amp';
$recipe_template = ''; // Force default AMP template.
} elseif ( isset( $GLOBALS['wp']->query_vars['rest_route'] ) && '/wp/v2/posts' === substr( $GLOBALS['wp']->query_vars['rest_route'], 0, 12 ) ) {
$type = 'single'; // Use single template when accessing post through REST API.
} elseif ( is_admin() ) {
$type = 'single';
} elseif ( is_front_page() || ! is_singular() || ! is_main_query() ) {
$type = 'archive';
}
}
// Early return recipe summary if this is for an excerpt.
if ( 'excerpt' === $type ) {
return $recipe->summary();
}
// Output full snippet or recipe template.
$align_class = '';
if ( isset( $atts['align'] ) && $atts['align'] ) {
$align_class = ' align' . esc_attr( $atts['align'] );
}
if ( $recipe_template && 'snippet-' === substr( $recipe_template, 0, 8 ) ) {
$output = '<div id="wprm-recipe-snippet-container-' . esc_attr( $recipe->id() ) . '" class="wprm-recipe-snippet-container' . esc_attr( $align_class ) . '" data-recipe-id="' . esc_attr( $recipe->id() ) . '">';
} else {
$output = '<div id="wprm-recipe-container-' . esc_attr( $recipe->id() ) . '" class="wprm-recipe-container' . esc_attr( $align_class ) . '" data-recipe-id="' . esc_attr( $recipe->id() ) . '" data-servings="' . esc_attr( $recipe->servings() ) . '">';
}
if ( 'amp' === $type || 'single' === $type ) {
if ( 'recipe' === WPRM_Settings::get( 'metadata_location' ) && ! WPRM_Metadata::use_yoast_seo_integration() && WPRM_Metadata::should_output_metadata_for( $recipe->id() ) ) {
$metadata_output = WPRM_Metadata::get_metadata_output( $recipe );
if ( $metadata_output ) {
$output .= $metadata_output;
WPRM_Metadata::outputted_metadata_for( $recipe->id() );
}
}
}
$output .= WPRM_Template_Manager::get_template( $recipe, $type, $recipe_template );
$output .= '</div>';
return apply_filters( 'wprm_recipe_shortcode_output', $output, $recipe, $type, $recipe_template );
} else {
return '';
}
}
}
WPRM_Shortcode::init();