File: /var/www/html/wp-content/plugins/wp-recipe-maker/includes/public/class-wprm-recipe-sanitizer.php
<?php
/**
* Santize recipe input fields.
*
* @link https://bootstrapped.ventures
* @since 1.0.0
*
* @package WP_Recipe_Maker
* @subpackage WP_Recipe_Maker/includes/public
*/
/**
* Santize recipe input fields.
*
* @since 1.0.0
* @package WP_Recipe_Maker
* @subpackage WP_Recipe_Maker/includes/public
* @author Brecht Vandersmissen <brecht@bootstrapped.ventures>
*/
class WPRM_Recipe_Sanitizer {
/**
* Sanitize recipe array.
*
* @since 1.0.0
* @param array $recipe Array containing all recipe input data.
*/
public static function sanitize( $recipe ) {
$sanitized_recipe = array();
// Prevent infinite loop.
if ( isset( $recipe['video_embed'] ) ) {
$embed_code = trim( $recipe['video_embed'] );
$embed_code = str_ireplace( '[wprm-recipe-video]', '', $embed_code );
$sanitized_recipe['video_embed'] = self::sanitize_html( $embed_code );
}
// Boolean fields.
if ( isset( $recipe['prep_time_zero'] ) ) { $sanitized_recipe['prep_time_zero'] = $recipe['prep_time_zero'] ? true : false; }
if ( isset( $recipe['cook_time_zero'] ) ) { $sanitized_recipe['cook_time_zero'] = $recipe['cook_time_zero'] ? true : false; }
if ( isset( $recipe['custom_time_zero'] ) ) { $sanitized_recipe['custom_time_zero'] = $recipe['custom_time_zero'] ? true : false; }
if ( isset( $recipe['servings_advanced_enabled'] ) ) { $sanitized_recipe['servings_advanced_enabled'] = $recipe['servings_advanced_enabled'] ? true : false; }
// Text fields.
if ( isset( $recipe['name'] ) ) { $sanitized_recipe['name'] = sanitize_text_field( $recipe['name'] ); }
if ( isset( $recipe['author_name'] ) ) { $sanitized_recipe['author_name'] = sanitize_text_field( $recipe['author_name'] ); }
if ( isset( $recipe['author_link'] ) ) { $sanitized_recipe['author_link'] = sanitize_text_field( $recipe['author_link'] ); }
if ( isset( $recipe['servings_unit'] ) ) { $sanitized_recipe['servings_unit'] = sanitize_text_field( $recipe['servings_unit'] ); }
if ( isset( $recipe['cost'] ) ) { $sanitized_recipe['cost'] = sanitize_text_field( $recipe['cost'] ); }
if ( isset( $recipe['custom_time_label'] ) ) { $sanitized_recipe['custom_time_label'] = sanitize_text_field( $recipe['custom_time_label'] ); }
// Key fields.
if ( isset( $recipe['pin_image_repin_id'] ) ) { $sanitized_recipe['pin_image_repin_id'] = sanitize_key( $recipe['pin_image_repin_id'] ); }
// HTML fields.
if ( isset( $recipe['summary'] ) ) { $sanitized_recipe['summary'] = self::sanitize_html( $recipe['summary'] ); }
if ( isset( $recipe['author_bio'] ) ) { $sanitized_recipe['author_bio'] = self::sanitize_html( $recipe['author_bio'] ); }
if ( isset( $recipe['notes'] ) ) { $sanitized_recipe['notes'] = self::sanitize_notes( $recipe['notes'] ); }
// Number fields.
if ( isset( $recipe['image_id'] ) ) { $sanitized_recipe['image_id'] = intval( $recipe['image_id'] ); }
if ( isset( $recipe['pin_image_id'] ) ) { $sanitized_recipe['pin_image_id'] = intval( $recipe['pin_image_id'] ); }
if ( isset( $recipe['video_id'] ) ) { $sanitized_recipe['video_id'] = intval( $recipe['video_id'] ); }
// Times should never be negative.
if ( isset( $recipe['prep_time'] ) ) {
$time = intval( $recipe['prep_time'] );
$sanitized_recipe['prep_time'] = $time < 0 ? 0 : $time;
}
if ( isset( $recipe['cook_time'] ) ) {
$time = intval( $recipe['cook_time'] );
$sanitized_recipe['cook_time'] = $time < 0 ? 0 : $time;
}
if ( isset( $recipe['total_time'] ) ) {
$time = intval( $recipe['total_time'] );
$sanitized_recipe['total_time'] = $time < 0 ? 0 : $time;
}
if ( isset( $recipe['custom_time'] ) ) {
$time = intval( $recipe['custom_time'] );
$sanitized_recipe['custom_time'] = $time < 0 ? 0 : $time;
}
// Servings.
if ( isset( $recipe['servings'] ) ) {
$servings = str_replace( ',', '.', $recipe['servings'] );
$sanitized_recipe['servings'] = floatval( $servings );
}
// Advanced Servings.
if ( isset( $recipe['servings_advanced'] ) ) {
$servings_advanced = array();
$options = array( 'round', 'rectangle' );
if ( isset( $recipe['servings_advanced']['shape'] ) && in_array( $recipe['servings_advanced']['shape'], $options, true ) ) {
$servings_advanced['shape'] = $recipe['servings_advanced']['shape'];
}
$options = array( 'inch', 'cm' );
if ( isset( $recipe['servings_advanced']['unit'] ) && in_array( $recipe['servings_advanced']['unit'], $options, true ) ) {
$servings_advanced['unit'] = $recipe['servings_advanced']['unit'];
}
if ( isset( $recipe['servings_advanced']['diameter'] ) ) { $servings_advanced['diameter'] = floatval( str_replace( ',', '.', $recipe['servings_advanced']['diameter'] ) ); }
if ( isset( $recipe['servings_advanced']['width'] ) ) { $servings_advanced['width'] = floatval( str_replace( ',', '.', $recipe['servings_advanced']['width'] ) ); }
if ( isset( $recipe['servings_advanced']['length'] ) ) { $servings_advanced['length'] = floatval( str_replace( ',', '.', $recipe['servings_advanced']['length'] ) ); }
if ( isset( $recipe['servings_advanced']['height'] ) ) { $servings_advanced['height'] = floatval( str_replace( ',', '.', $recipe['servings_advanced']['height'] ) ); }
$sanitized_recipe['servings_advanced'] = $servings_advanced;
}
// Limited options fields.
$options = array( 'food', 'howto', 'other' );
if ( isset( $recipe['type'] ) && in_array( $recipe['type'], $options, true ) ) {
$sanitized_recipe['type'] = $recipe['type'];
}
$options = array( 'default', 'disabled', 'post_author', 'custom' );
if ( isset( $recipe['author_display'] ) && in_array( $recipe['author_display'], $options, true ) ) {
$sanitized_recipe['author_display'] = $recipe['author_display'];
}
$options = array( 'global', 'custom' );
if ( isset( $recipe['ingredient_links_type'] ) && in_array( $recipe['ingredient_links_type'], $options, true ) ) {
$sanitized_recipe['ingredient_links_type'] = $recipe['ingredient_links_type'];
}
$options = array( 'default', '1', '2' );
if ( isset( $recipe['unit_system'] ) && in_array( $recipe['unit_system'], $options, true ) ) {
$sanitized_recipe['unit_system'] = $recipe['unit_system'];
}
// Recipe Tags.
if ( isset( $recipe['tags'] ) ) {
$sanitized_recipe['tags'] = array();
$taxonomies = WPRM_Taxonomies::get_taxonomies();
foreach ( $taxonomies as $taxonomy => $options ) {
$key = substr( $taxonomy, 5 ); // Get rid of wprm_.
$sanitized_recipe['tags'][ $key ] = isset( $recipe['tags'] ) && isset( $recipe['tags'][ $key ] ) && $recipe['tags'][ $key ] ? array_map( array( __CLASS__, 'sanitize_tags' ), $recipe['tags'][ $key ] ) : array();
}
}
// Recipe Equipment.
if ( isset( $recipe['equipment'] ) ) {
$sanitized_recipe['equipment'] = array();
foreach ( $recipe['equipment'] as $equipment ) {
$name = isset( $equipment['name'] ) ? self::sanitize_html( $equipment['name'] ) : '';
if ( $name ) {
$sanitized_equipment = array(
'id' => self::get_equipment_id( $name ),
'amount' => isset( $equipment['amount'] ) ? self::sanitize_html( $equipment['amount'] ) : '',
'name' => $name,
'notes' => isset( $equipment['notes'] ) ? self::sanitize_html( $equipment['notes'] ) : '',
);
// Product amount.
if ( isset( $equipment['product_amount'] ) && $equipment['product_amount'] !== '' ) {
$product_amount = floatval( $equipment['product_amount'] );
$is_default_product_amount = ! empty( $equipment['product_amount_default'] );
if ( 0.0 === $product_amount ) {
$sanitized_equipment['product_amount'] = 0;
} elseif ( $product_amount > 0 && ! $is_default_product_amount ) {
$sanitized_equipment['product_amount'] = $product_amount;
}
}
// Product item snapshot.
if ( isset( $equipment['product_item_snapshot'] ) ) {
$sanitized_equipment['product_item_snapshot'] = array(
'amount' => isset( $equipment['product_item_snapshot']['amount'] ) ? self::sanitize_html( $equipment['product_item_snapshot']['amount'] ) : '',
'name' => isset( $equipment['product_item_snapshot']['name'] ) ? self::sanitize_html( $equipment['product_item_snapshot']['name'] ) : '',
'notes' => isset( $equipment['product_item_snapshot']['notes'] ) ? self::sanitize_html( $equipment['product_item_snapshot']['notes'] ) : '',
'timestamp' => isset( $equipment['product_item_snapshot']['timestamp'] ) ? intval( $equipment['product_item_snapshot']['timestamp'] ) : 0,
);
}
$sanitized_recipe['equipment'][] = $sanitized_equipment;
}
}
}
// Recipe Ingredients.
if ( isset( $recipe['ingredients'] ) || isset( $recipe['ingredients_flat'] ) ) {
$sanitized_recipe['ingredients'] = array();
$ingredients = isset( $recipe['ingredients'] ) ? $recipe['ingredients'] : array();
// Use ingredients_flat if set.
if ( isset( $recipe['ingredients_flat'] ) ) {
$ingredients = self::unflatten( 'ingredients', $recipe['ingredients_flat'] );
}
foreach ( $ingredients as $ingredient_group ) {
$sanitized_group = array(
'ingredients' => array(),
'name' => isset( $ingredient_group['name'] ) ? self::sanitize_html( $ingredient_group['name'] ) : '',
'uid' => isset( $ingredient_group['uid'] ) ? intval( $ingredient_group['uid'] ) : -1,
);
if ( isset( $ingredient_group['ingredients'] ) ) {
foreach ( $ingredient_group['ingredients'] as $ingredient ) {
if ( isset( $ingredient['raw'] ) && ! isset( $ingredient['name'] ) ) {
$ingredient = array_replace( $ingredient, WPRM_Recipe_Parser::parse_ingredient( $ingredient['raw'] ) );
}
$sanitized_ingredient = array(
'uid' => isset( $ingredient['uid'] ) ? intval( $ingredient['uid'] ) : -1,
'amount' => isset( $ingredient['amount'] ) ? self::sanitize_html( $ingredient['amount'] ) : '',
'unit' => isset( $ingredient['unit'] ) ? self::sanitize_html( $ingredient['unit'] ) : '',
'name' => isset( $ingredient['name'] ) ? self::sanitize_html( $ingredient['name'] ) : '',
'notes' => isset( $ingredient['notes'] ) ? self::sanitize_html( $ingredient['notes'] ) : '',
);
// Ingredient splits (using percentages).
if ( isset( $ingredient['splits'] ) && is_array( $ingredient['splits'] ) ) {
$sanitized_splits = array();
$total_percentage = 0;
foreach ( $ingredient['splits'] as $split ) {
if ( isset( $split['id'] ) && isset( $split['percentage'] ) ) {
$percentage = floatval( $split['percentage'] );
// Validate percentage is between 0 and 100
if ( $percentage >= 0 && $percentage <= 100 ) {
$sanitized_split = array(
'id' => intval( $split['id'] ),
'percentage' => $percentage,
);
$sanitized_splits[] = $sanitized_split;
$total_percentage += $percentage;
}
}
}
// Only add splits array if we have at least 2 splits and percentages sum to approximately 100%
if ( count( $sanitized_splits ) >= 2 && abs( $total_percentage - 100 ) < 0.01 ) {
$sanitized_ingredient['splits'] = $sanitized_splits;
}
}
// Product amount.
if ( isset( $ingredient['product_amount'] ) && $ingredient['product_amount'] !== '' ) {
$product_amount = floatval( $ingredient['product_amount'] );
$is_default_product_amount = ! empty( $ingredient['product_amount_default'] );
if ( 0.0 === $product_amount ) {
$sanitized_ingredient['product_amount'] = 0;
} elseif ( $product_amount > 0 && ! $is_default_product_amount ) {
$sanitized_ingredient['product_amount'] = $product_amount;
}
}
// Product item snapshot.
if ( isset( $ingredient['product_item_snapshot'] ) ) {
$sanitized_ingredient['product_item_snapshot'] = array(
'amount' => isset( $ingredient['product_item_snapshot']['amount'] ) ? self::sanitize_html( $ingredient['product_item_snapshot']['amount'] ) : '',
'unit' => isset( $ingredient['product_item_snapshot']['unit'] ) ? self::sanitize_html( $ingredient['product_item_snapshot']['unit'] ) : '',
'name' => isset( $ingredient['product_item_snapshot']['name'] ) ? self::sanitize_html( $ingredient['product_item_snapshot']['name'] ) : '',
'notes' => isset( $ingredient['product_item_snapshot']['notes'] ) ? self::sanitize_html( $ingredient['product_item_snapshot']['notes'] ) : '',
'timestamp' => isset( $ingredient['product_item_snapshot']['timestamp'] ) ? intval( $ingredient['product_item_snapshot']['timestamp'] ) : 0,
);
}
// Custom ingredient link.
if ( isset( $ingredient['link'] ) ) {
$link = array(
'url' => isset( $ingredient['link']['url'] ) ? esc_url_raw( $ingredient['link']['url'] ) : '',
'nofollow' => isset( $ingredient['link']['nofollow'] ) ? sanitize_text_field( $ingredient['link']['nofollow'] ) : 'default',
);
if ( isset( $ingredient['link']['eafl'] ) ) {
$eafl = intval( $ingredient['link']['eafl'] );
if ( $eafl ) {
$link['eafl'] = $eafl;
}
}
$sanitized_ingredient['link'] = $link;
}
// Unit Conversion.
if ( isset( $ingredient['converted'] ) ) {
$sanitized_ingredient['converted'] = array();
foreach ( $ingredient['converted'] as $system => $conversion ) {
$sanitized_ingredient['converted'][ $system ] = array(
'amount' => self::sanitize_html( $conversion['amount'] ),
'unit' => self::sanitize_html( $conversion['unit'] ),
);
// Link unit.
if ( $sanitized_ingredient['converted'][ $system ]['unit'] ) {
$sanitized_ingredient['converted'][ $system ]['unit_id'] = self::get_ingredient_unit_id( $sanitized_ingredient['converted'][ $system ]['unit'] );
}
}
}
// Conversion item snapshot.
if ( isset( $ingredient['conversion_item_snapshot'] ) ) {
$sanitized_ingredient['conversion_item_snapshot'] = array(
'amount' => isset( $ingredient['conversion_item_snapshot']['amount'] ) ? self::sanitize_html( $ingredient['conversion_item_snapshot']['amount'] ) : '',
'unit' => isset( $ingredient['conversion_item_snapshot']['unit'] ) ? self::sanitize_html( $ingredient['conversion_item_snapshot']['unit'] ) : '',
'timestamp' => isset( $ingredient['conversion_item_snapshot']['timestamp'] ) ? intval( $ingredient['conversion_item_snapshot']['timestamp'] ) : 0,
);
}
// Link unit.
if ( $sanitized_ingredient['unit'] ) {
$sanitized_ingredient['unit_id'] = self::get_ingredient_unit_id( $sanitized_ingredient['unit'] );
}
// Add to ingredients if name is set.
if ( $sanitized_ingredient['name'] ) {
$sanitized_ingredient['id'] = self::get_ingredient_id( $sanitized_ingredient['name'] );
$sanitized_group['ingredients'][] = $sanitized_ingredient;
}
}
}
if ( $sanitized_group['name'] || count( $sanitized_group['ingredients'] ) > 0 ) {
$sanitized_recipe['ingredients'][] = $sanitized_group;
}
}
}
// Recipe Instructions.
if ( isset( $recipe['instructions'] ) || isset( $recipe['instructions_flat'] ) ) {
$sanitized_recipe['instructions'] = array();
$instructions = isset( $recipe['instructions'] ) ? $recipe['instructions'] : array();
// Use ingredients_flat if set.
if ( isset( $recipe['instructions_flat'] ) ) {
$instructions = self::unflatten( 'instructions', $recipe['instructions_flat'] );
}
foreach ( $instructions as $instruction_group ) {
$sanitized_group = array(
'instructions' => array(),
'name' => isset( $instruction_group['name'] ) ? self::sanitize_html( $instruction_group['name'] ) : '',
'uid' => isset( $instruction_group['uid'] ) ? intval( $instruction_group['uid'] ) : -1,
);
if ( isset( $instruction_group['instructions'] ) ) {
foreach ( $instruction_group['instructions'] as $instruction ) {
$is_tip = isset( $instruction['type'] ) && 'tip' === $instruction['type'];
// Sanitize ingredients - handle both regular UIDs (integers) and splits (strings like "1:2")
$sanitized_ingredients = array();
if ( ! $is_tip && isset( $instruction['ingredients'] ) && is_array( $instruction['ingredients'] ) ) {
foreach ( $instruction['ingredients'] as $ingredient ) {
$ingredient_str = (string) $ingredient;
// Check if it's a split (contains colon)
if ( strpos( $ingredient_str, ':' ) !== false ) {
// Split format: "uid:splitId" - validate and sanitize
$parts = explode( ':', $ingredient_str, 2 );
if ( count( $parts ) === 2 && is_numeric( $parts[0] ) && is_numeric( $parts[1] ) ) {
$sanitized_ingredients[] = intval( $parts[0] ) . ':' . intval( $parts[1] );
}
} else {
// Regular ingredient UID - convert to integer
$sanitized_ingredients[] = intval( $ingredient );
}
}
}
$sanitized_instruction = array(
'uid' => isset( $instruction['uid'] ) ? intval( $instruction['uid'] ) : -1,
'name' => isset( $instruction['name'] ) ? sanitize_text_field( $instruction['name'] ) : '',
'text' => isset( $instruction['text'] ) ? self::sanitize_html( $instruction['text'] ) : '',
);
if ( $is_tip ) {
$sanitized_instruction['type'] = 'tip';
$sanitized_instruction['tip_icon'] = isset( $instruction['tip_icon'] ) ? sanitize_text_field( $instruction['tip_icon'] ) : '';
$tip_style = isset( $instruction['tip_style'] ) ? sanitize_key( $instruction['tip_style'] ) : '';
if ( 'left-border' === $tip_style ) {
$tip_style = 'left-border-straight';
}
$sanitized_instruction['tip_style'] = in_array( $tip_style, array( 'left-border-straight', 'left-border-rounded', 'filled', 'outline', 'banner' ), true ) ? $tip_style : '';
$tip_accent = isset( $instruction['tip_accent'] ) ? sanitize_hex_color( $instruction['tip_accent'] ) : false;
$sanitized_instruction['tip_accent'] = $tip_accent ? $tip_accent : '';
$tip_text_color = isset( $instruction['tip_text_color'] ) ? sanitize_hex_color( $instruction['tip_text_color'] ) : false;
$sanitized_instruction['tip_text_color'] = $tip_text_color ? $tip_text_color : '';
} else {
$sanitized_instruction['image'] = isset( $instruction['image'] ) ? intval( $instruction['image'] ) : 0;
$sanitized_instruction['ingredients'] = $sanitized_ingredients;
}
if ( ! $is_tip && isset( $instruction['video'] ) ) {
$sanitized_instruction['video'] = array(
'type' => sanitize_text_field( $instruction['video']['type'] ),
'embed' => self::sanitize_html( $instruction['video']['embed'] ),
'id' => intval( $instruction['video']['id'] ),
'thumb' => $instruction['video']['thumb'],
'start' => $instruction['video']['start'],
'end' => $instruction['video']['end'],
'name' => sanitize_text_field( $instruction['video']['name'] ),
);
}
if ( $sanitized_instruction['text'] || ( ! $is_tip && $sanitized_instruction['image'] ) ) {
$sanitized_group['instructions'][] = $sanitized_instruction;
}
}
}
if ( $sanitized_group['name'] || count( $sanitized_group['instructions'] ) > 0 ) {
$sanitized_recipe['instructions'][] = $sanitized_group;
}
}
}
// Recipe Nutrition.
if ( isset( $recipe['nutrition'] ) ) {
$sanitized_recipe['nutrition'] = array();
foreach ( $recipe['nutrition'] as $nutrition_field => $nutrition_value ) {
$nutritition_value = trim( $nutrition_value );
$sanitized_recipe['nutrition'][ $nutrition_field ] = '' !== $nutritition_value ? floatval( str_replace( ',', '.', $nutritition_value ) ) : false;
}
$serving_unit = isset( $recipe['nutrition']['serving_unit'] ) && '' !== trim( $recipe['nutrition']['serving_unit'] ) ? $recipe['nutrition']['serving_unit'] : false;
if ( $serving_unit ) {
$sanitized_serving_unit = sanitize_text_field( $recipe['nutrition']['serving_unit'] );
// Allow 1 space in front to have a space before the unit.
if ( ' ' === substr( $serving_unit, 0, 1 ) ) {
$sanitized_serving_unit = ' ' . $sanitized_serving_unit;
}
$serving_unit = $sanitized_serving_unit;
}
$sanitized_recipe['nutrition']['serving_unit'] = $serving_unit;
}
// Only for "public" recipe type or when manually setting author.
if ( 'public' === WPRM_Settings::get( 'post_type_structure' ) || 'manual' === WPRM_Settings::get( 'recipe_use_author' ) ) {
if ( isset( $recipe['post_author'] ) ) {
$sanitized_recipe['post_author'] = intval( $recipe['post_author'] );
}
}
// Only for "public" recipe type.
if ( 'public' === WPRM_Settings::get( 'post_type_structure' ) ) {
if ( isset( $recipe['slug'] ) ) {
$sanitized_recipe['slug'] = sanitize_title( $recipe['slug'] );
}
$options = array_keys( get_post_statuses() );
if ( isset( $recipe['post_status'] ) && in_array( $recipe['post_status'], $options, true ) ) {
$sanitized_recipe['post_status'] = $recipe['post_status'];
}
if ( isset( $recipe['post_password'] ) ) {
$sanitized_recipe['post_password'] = sanitize_text_field( $recipe['post_password'] );
}
if ( isset( $recipe['date'] ) ) {
$datetime = false;
$datetime = $datetime ? $datetime : DateTime::createFromFormat( 'Y-m-d\TH:i:s', $recipe['date'] );
$datetime = $datetime ? $datetime : DateTime::createFromFormat( 'Y-m-d\TH:i', $recipe['date'] );
if ( $datetime ) {
$sanitized_recipe['date'] = $datetime->format( 'Y-m-d H:i:s' );
}
}
}
if ( isset( $recipe['language'] ) ) {
$sanitized_recipe['language'] = $recipe['language'] ? sanitize_text_field( $recipe['language'] ) : false;
}
// Other fields.
if ( isset( $recipe['import_source'] ) ) { $sanitized_recipe['import_source'] = sanitize_text_field( $recipe['import_source'] ); }
if ( isset( $recipe['import_backup'] ) ) { $sanitized_recipe['import_backup'] = $recipe['import_backup']; }
return apply_filters( 'wprm_recipe_sanitize', $sanitized_recipe, $recipe );
}
/**
* Get ingredient ID from its name.
*
* @since 5.1.0
* @param mixed $name Name of the ingredient.
*/
public static function get_ingredient_id( $name ) {
// Check if this is a plural of another ingredient first.
$name = self::sanitize_html( $name );
$args = array(
'hide_empty' => false,
'meta_query' => array(
array(
'key' => 'wprm_ingredient_plural',
'value' => $name,
'compare' => '='
)
),
'taxonomy' => 'wprm_ingredient',
'fields' => 'ids',
);
$terms = get_terms( $args );
if ( ! is_wp_error( $terms ) && isset( $terms[0] ) && $terms[0] ) {
// Match found. Return singular term ID.
return $terms[0];
}
return self::get_term_id_by_name( 'wprm_ingredient', $name );
}
/**
* Get ingredient unit ID from its name.
*
* @since 9.5.0
* @param mixed $name Name of the ingredient unit.
*/
public static function get_ingredient_unit_id( $name ) {
// Check if this is a plural of another ingredient unit first.
$name = self::sanitize_html( $name );
$args = array(
'hide_empty' => false,
'meta_query' => array(
array(
'key' => 'wprm_ingredient_unit_plural',
'value' => $name,
'compare' => '='
)
),
'taxonomy' => 'wprm_ingredient_unit',
'fields' => 'ids',
);
$terms = get_terms( $args );
if ( ! is_wp_error( $terms ) && isset( $terms[0] ) && $terms[0] ) {
// Match found. Return singular term ID.
return $terms[0];
}
return self::get_term_id_by_name( 'wprm_ingredient_unit', $name );
}
/**
* Get equipment ID from its name.
*
* @since 5.2.0
* @param mixed $name Name of the equipment.
*/
public static function get_equipment_id( $name ) {
return self::get_term_id_by_name( 'wprm_equipment', $name );
}
/**
* Get term ID from its name.
*
* @since 5.2.0
* @param mixed $taxonomy Taxonomy to search.
* @param mixed $name Name of the term.
*/
public static function get_term_id_by_name( $taxonomy, $name ) {
$id = 0;
// Make sure name is sanitized.
$name = self::sanitize_html( $name );
if ( $name ) {
$term = term_exists( $name, $taxonomy ); // @codingStandardsIgnoreLine
if ( 0 === $term || null === $term ) {
$term = wp_insert_term( $name, $taxonomy );
}
if ( is_wp_error( $term ) ) {
if ( isset( $term->error_data['term_exists'] ) ) {
$term_id = $term->error_data['term_exists'];
} else {
$term_id = 0;
}
} else {
$term_id = $term['term_id'];
}
$id = intval( $term_id );
}
return $id;
}
/**
* Sanitize recipe tags.
*
* @since 1.0.0
* @param mixed $tag Tag ID or new tag name.
*/
public static function sanitize_tags( $tag ) {
if ( is_array( $tag ) || is_object( $tag ) ) {
$tag = (array) $tag;
if ( ! is_string( $tag['term_id'] ) && is_numeric( $tag['term_id'] ) ) {
return intval( $tag['term_id'] );
} else {
return sanitize_text_field( $tag['term_id'] );
}
} elseif ( is_numeric( $tag ) ) {
return intval( $tag );
} else {
return sanitize_text_field( $tag );
}
}
/**
* Unflatten ingredients or instructions.
*
* @since 5.0.0
* @param string $type Type we're unflattening.
* @param mixed $flat Flat array.
*/
public static function unflatten( $type, $flat ) {
$unflattened = array();
// Start with an empty group.
$group = array(
'name' => '',
'uid' => -1,
);
$group[ $type ] = array();
foreach ( $flat as $index => $item ) {
if ( ! is_array( $item ) ) {
continue;
}
if ( isset( $item['type'] ) && 'group' === $item['type'] ) {
// Add previous group.
if ( 0 !== $index ) {
$unflattened[] = $group;
}
// New group.
$group = array(
'name' => $item['name'],
'uid' => isset( $item['uid'] ) ? $item['uid'] : -1,
);
$group[ $type ] = array();
} else {
// Instruction or ingredient.
$group[ $type ][] = $item;
}
}
// Add last group.
$unflattened[] = $group;
return $unflattened;
}
/**
* Sanitize the recipe notes
*
* @since 10.1.0
* @param mixed $text Text to sanitize.
*/
public static function sanitize_notes( $notes ) {
// Strip HTML comments to prevent WordPress block markup from breaking things.
$notes = preg_replace('/<!--.*?-->/s', '', $notes);
// Regular HTML sanitization.
$notes = self::sanitize_html( $notes );
return $notes;
}
/**
* Sanitize HTML content.
*
* @since 1.0.0
* @param mixed $text Text to sanitize.
*/
public static function sanitize_html( $text ) {
if ( is_array( $text ) || is_object( $text ) ) {
return '';
}
if ( ! is_string( $text ) ) {
$text = (string) $text;
}
$allowed_tags = wp_kses_allowed_html( 'post' );
$allowed_tags['wprm-code'] = true;
$allowed_tags['wprm-temperature'] = true;
$allowed_tags['wprm-ingredient'] = true;
// Allow more when user can edit posts to prevent abuse from User Submissions form.
if ( current_user_can( 'edit_posts' ) ) {
// Specific data attributes.
$allowed_tags['a']['data-optimize-leads-uid'] = true;
}
// Remove blank lines from HTML.
$text = str_replace( '<p></p>', '', $text );
$text = str_replace( '<p><br></p>', '', $text );
$text = str_replace( '<p><br/></p>', '', $text );
// Remove empty links from HTML.
$text = preg_replace( '/<a[^>]*><\/a>/', '', $text );
// WPRM Code in rich text.
preg_match_all( '/<wprm-code>(.*?)<\/wprm-code>/ms', $text, $matches );
foreach ( $matches[1] as $key => $match ) {
$code = html_entity_decode( $match );
$text = str_replace( $match, $code, $text );
}
// WPRM Temperature in rich text. Replace with its shortcode
preg_match_all( '/<wprm-temperature(.*?)<\/wprm-temperature>/ms', $text, $matches );
foreach ( $matches[1] as $key => $match ) {
$split = explode( '>', $match, 2 );
// Parse attributes.
preg_match( '/icon=\"(.*?)\"/', $split[0], $attr_match );
$icon = isset( $attr_match[1] ) ? $attr_match[1] : '';
preg_match( '/unit=\"(.*?)\"/', $split[0], $attr_match );
$unit = isset( $attr_match[1] ) ? $attr_match[1] : '';
preg_match( '/help=\"(.*?)\"/', $split[0], $attr_match );
$help = isset( $attr_match[1] ) ? $attr_match[1] : '';
$help = html_entity_decode( $help );
$shortcode = '';
if ( isset( $split[1] ) && $split[1] ) {
$value = html_entity_decode( $split[1] );
$shortcode = '[wprm-temperature value="' . esc_attr( $value ) . '"';
$shortcode .= ' unit="' . esc_attr( $unit ) . '"';
if ( $icon ) { $shortcode .= ' icon="' . esc_attr( $icon ) . '"'; }
if ( $help ) { $shortcode .= ' help="' . esc_attr( $help ) . '"'; }
$shortcode .= ']';
}
$text = str_replace( $matches[0][ $key ], $shortcode, $text );
}
// WPRM Ingredient in rich text. Replace with its shortcode
preg_match_all( '/<wprm-ingredient(.*?)<\/wprm-ingredient>/ms', $text, $matches );
foreach ( $matches[1] as $key => $match ) {
$split = explode( '>', $match, 2 );
// Parse attributes.
preg_match( '/uid=\"(.*?)\"/', $split[0], $attr_match );
$uid = isset( $attr_match[1] ) ? $attr_match[1] : '';
preg_match( '/removed=\"(.*?)\"/', $split[0], $attr_match );
$removed = isset( $attr_match[1] ) && '1' === $attr_match[1] ? true : false;
$shortcode = '';
if ( isset( $split[1] ) && $split[1] ) {
$ingredient = html_entity_decode( $split[1] );
$shortcode = '[wprm-ingredient text="' . esc_attr( $ingredient ) . '"';
$shortcode .= ' uid="' . esc_attr( $uid ) . '"';
if ( $removed ) {
$shortcode .= ' removed="1"';
}
$shortcode .= ']';
}
$text = str_replace( $matches[0][ $key ], $shortcode, $text );
}
// Allow administrators to use any html they want.
if ( current_user_can( 'unfiltered_html' ) ) {
return $text;
}
return wp_kses( $text, $allowed_tags );
}
}