diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2020-01-06 14:32:30 -0500 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2020-01-06 14:32:30 -0500 |
commit | 10ef81bf85ad0a4bad0d204838e14c99ca2526f7 (patch) | |
tree | b4bb36a326d41de12d1a6181d2a2baf34696ac24 /plugins/jetpack/modules/shortcodes/recipe.php | |
parent | Updating script for Update (diff) | |
download | blogs-gentoo-10ef81bf85ad0a4bad0d204838e14c99ca2526f7.tar.gz blogs-gentoo-10ef81bf85ad0a4bad0d204838e14c99ca2526f7.tar.bz2 blogs-gentoo-10ef81bf85ad0a4bad0d204838e14c99ca2526f7.zip |
Update jetpack 8.0
Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
Diffstat (limited to 'plugins/jetpack/modules/shortcodes/recipe.php')
-rw-r--r-- | plugins/jetpack/modules/shortcodes/recipe.php | 361 |
1 files changed, 257 insertions, 104 deletions
diff --git a/plugins/jetpack/modules/shortcodes/recipe.php b/plugins/jetpack/modules/shortcodes/recipe.php index 7846b154..983f01ee 100644 --- a/plugins/jetpack/modules/shortcodes/recipe.php +++ b/plugins/jetpack/modules/shortcodes/recipe.php @@ -1,4 +1,6 @@ -<?php +<?php //phpcs:ignore WordPress.Files.FileName.InvalidClassFileName + +use Automattic\Jetpack\Assets; /** * Embed recipe 'cards' in post, with basic styling and print functionality @@ -8,80 +10,63 @@ * - basic styles/themecolor styles * - validation/sanitization * - print styles + * + * @package Jetpack */ -class Jetpack_Recipes { - - private $scripts_and_style_included = false; - - function __construct() { - add_action( 'init', array( $this, 'action_init' ) ); - add_filter( 'wp_kses_allowed_html', array( $this, 'add_recipes_kses_rules' ), 10, 2 ); - } +/** + * Register and display Recipes in posts. + */ +class Jetpack_Recipes { /** - * Add Schema-specific attributes to our allowed tags in wp_kses, - * so we can have better Schema.org compliance. + * Have scripts and styles been enqueued already. * - * @param array $allowedtags Array of allowed HTML tags in recipes. - * @param array $context Context to judge allowed tags by. + * @var bool */ - function add_recipes_kses_rules( $allowedtags, $context ) { - if ( in_array( $context, array( '', 'post', 'data' ) ) ) : - // Create an array of all the tags we'd like to add the itemprop attribute to. - $tags = array( 'li', 'ol', 'ul', 'img', 'p', 'h3', 'time' ); - foreach ( $tags as $tag ) { - $allowedtags = $this->add_kses_rule( - $allowedtags, - $tag, - array( - 'class' => array(), - 'itemprop' => array(), - 'datetime' => array(), - ) - ); - } - - // Allow itemscope and itemtype for divs. - $allowedtags = $this->add_kses_rule( - $allowedtags, - 'div', - array( - 'class' => array(), - 'itemscope' => array(), - 'itemtype' => array(), - ) - ); - endif; + private $scripts_and_style_included = false; - return $allowedtags; + /** + * Constructor + */ + public function __construct() { + add_action( 'init', array( $this, 'action_init' ) ); } /** - * Function to add a new property rule to our kses array. - * Used by add_recipe_kses_rules() above. + * Returns KSES tags with Schema-specific attributes. * - * @param array $all_tags Array of allowed HTML tags in recipes. - * @param string $tag New HTML tag to add to the array of allowed HTML. - * @param array $rules Array of allowed attributes for that HTML tag. + * @since 8.0.0 + * + * @return array Array to be used by KSES. */ - private function add_kses_rule( $all_tags, $tag, $rules ) { - - // If the tag doesn't already exist, add it. - if ( ! isset( $all_tags[ $tag ] ) ) { - $all_tags[ $tag ] = array(); + private static function kses_tags() { + $allowedtags = wp_kses_allowed_html( 'post' ); + // Create an array of all the tags we'd like to add the itemprop attribute to. + $tags = array( 'li', 'ol', 'ul', 'img', 'p', 'h3', 'time', 'span' ); + foreach ( $tags as $tag ) { + if ( ! isset( $allowedtags[ $tag ] ) ) { + $allowedtags[ $tag ] = array(); + } + $allowedtags[ $tag ]['class'] = array(); + $allowedtags[ $tag ]['itemprop'] = array(); + $allowedtags[ $tag ]['datetime'] = array(); } - // Merge the new tags with existing tags. - $all_tags[ $tag ] = array_merge( $all_tags[ $tag ], $rules ); - - return $all_tags; + // Allow itemscope and itemtype for divs. + if ( ! isset( $allowedtags['div'] ) ) { + $allowedtags['div'] = array(); + } + $allowedtags['div']['class'] = array(); + $allowedtags['div']['itemscope'] = array(); + $allowedtags['div']['itemtype'] = array(); + return $allowedtags; } /** * Register our shortcode and enqueue necessary files. */ - function action_init() { + public function action_init() { // Enqueue styles if [recipe] exists. add_action( 'wp_head', array( $this, 'add_scripts' ), 1 ); @@ -90,12 +75,14 @@ class Jetpack_Recipes { add_shortcode( 'recipe-notes', array( $this, 'recipe_notes_shortcode' ) ); add_shortcode( 'recipe-ingredients', array( $this, 'recipe_ingredients_shortcode' ) ); add_shortcode( 'recipe-directions', array( $this, 'recipe_directions_shortcode' ) ); + add_shortcode( 'recipe-nutrition', array( $this, 'recipe_nutrition_shortcode' ) ); + add_shortcode( 'recipe-image', array( $this, 'recipe_image_shortcode' ) ); } /** * Enqueue scripts and styles */ - function add_scripts() { + public function add_scripts() { if ( empty( $GLOBALS['posts'] ) || ! is_array( $GLOBALS['posts'] ) ) { return; } @@ -116,19 +103,20 @@ class Jetpack_Recipes { // add $themecolors-defined styles. wp_add_inline_style( 'jetpack-recipes-style', self::themecolor_styles() ); - wp_enqueue_script( 'jetpack-recipes-printthis', - Jetpack::get_file_url_for_environment( '_inc/build/shortcodes/js/recipes-printthis.min.js', 'modules/shortcodes/js/recipes-printthis.js' ), + Assets::get_file_url_for_environment( '_inc/build/shortcodes/js/recipes-printthis.min.js', 'modules/shortcodes/js/recipes-printthis.js' ), array( 'jquery' ), - '20170202' + '20170202', + false ); wp_enqueue_script( 'jetpack-recipes-js', - Jetpack::get_file_url_for_environment( '_inc/build/shortcodes/js/recipes.min.js', 'modules/shortcodes/js/recipes.js' ), + Assets::get_file_url_for_environment( '_inc/build/shortcodes/js/recipes.min.js', 'modules/shortcodes/js/recipes.js' ), array( 'jquery', 'jetpack-recipes-printthis' ), - '20131230' + '20131230', + false ); $title_var = wp_title( '|', false, 'right' ); @@ -154,18 +142,21 @@ class Jetpack_Recipes { * * @return string HTML for recipe shortcode. */ - static function recipe_shortcode( $atts, $content = '' ) { + public static function recipe_shortcode( $atts, $content = '' ) { $atts = shortcode_atts( array( 'title' => '', // string. 'servings' => '', // intval. - 'time' => '', // string. + 'time' => '', // strtotime-compatible time description. 'difficulty' => '', // string. - 'print' => '', // string. + 'print' => '', // URL for external print version. 'source' => '', // string. - 'sourceurl' => '', // string. - 'image' => '', // string. + 'sourceurl' => '', // URL string. Only used if source set. + 'image' => '', // URL or attachment ID. 'description' => '', // string. + 'cooktime' => '', // strtotime-compatible time description. + 'preptime' => '', // strtotime-compatible time description. + 'rating' => '', // string. ), $atts, 'recipe' @@ -182,43 +173,41 @@ class Jetpack_Recipes { * * @return string HTML output */ - static function recipe_shortcode_html( $atts, $content = '' ) { + private static function recipe_shortcode_html( $atts, $content = '' ) { - $html = '<div class="hrecipe jetpack-recipe" itemscope itemtype="https://schema.org/Recipe">'; + $html = '<div class="hrecipe h-recipe jetpack-recipe" itemscope itemtype="https://schema.org/Recipe">'; // Print the recipe title if exists. if ( '' !== $atts['title'] ) { - $html .= '<h3 class="jetpack-recipe-title" itemprop="name">' . esc_html( $atts['title'] ) . '</h3>'; + $html .= '<h3 class="p-name jetpack-recipe-title fn" itemprop="name">' . esc_html( $atts['title'] ) . '</h3>'; } // Print the recipe meta if exists. - if ( '' !== $atts['servings'] || '' != $atts['time'] || '' != $atts['difficulty'] || '' != $atts['print'] ) { + if ( + '' !== $atts['servings'] + || '' !== $atts['time'] + || '' !== $atts['difficulty'] + || '' !== $atts['print'] + || '' !== $atts['preptime'] + || '' !== $atts['cooktime'] + || '' !== $atts['rating'] + ) { $html .= '<ul class="jetpack-recipe-meta">'; if ( '' !== $atts['servings'] ) { $html .= sprintf( - '<li class="jetpack-recipe-servings" itemprop="recipeYield"><strong>%1$s: </strong>%2$s</li>', + '<li class="jetpack-recipe-servings p-yield yield" itemprop="recipeYield"><strong>%1$s: </strong>%2$s</li>', esc_html_x( 'Servings', 'recipe', 'jetpack' ), esc_html( $atts['servings'] ) ); } - if ( '' !== $atts['time'] ) { - // Get a time that's supported by Schema.org. - $duration = WPCOM_JSON_API_Date::format_duration( $atts['time'] ); - // If no duration can be calculated, let's output what the user provided. - if ( empty( $duration ) ) { - $duration = $atts['time']; + $time_types = array( 'cooktime', 'preptime', 'time' ); + foreach ( $time_types as $time_type ) { + if ( '' === $atts[ $time_type ] ) { + continue; } - - $html .= sprintf( - '<li class="jetpack-recipe-time"> - <time itemprop="totalTime" datetime="%3$s"><strong>%1$s: </strong>%2$s</time> - </li>', - esc_html_x( 'Time', 'recipe', 'jetpack' ), - esc_html( $atts['time'] ), - esc_attr( $duration ) - ); + $html .= self::output_time( $atts[ $time_type ], $time_type ); } if ( '' !== $atts['difficulty'] ) { @@ -229,6 +218,17 @@ class Jetpack_Recipes { ); } + if ( '' !== $atts['rating'] ) { + $html .= sprintf( + '<li class="jetpack-recipe-rating"> + <strong>%1$s: </strong> + <span itemprop="contentRating">%2$s</span> + </li>', + esc_html_x( 'Rating', 'recipe', 'jetpack' ), + esc_html( $atts['rating'] ) + ); + } + if ( '' !== $atts['source'] ) { $html .= sprintf( '<li class="jetpack-recipe-source"><strong>%1$s: </strong>', @@ -261,14 +261,13 @@ class Jetpack_Recipes { } $html .= '</ul>'; - } // End if(). + } - // Output the image, if we have one. + // Output the image if we have one and it's not shown elsewhere. if ( '' !== $atts['image'] ) { - $html .= sprintf( - '<img class="jetpack-recipe-image" itemprop="image" src="%1$s" />', - esc_url( $atts['image'] ) - ); + if ( ! has_shortcode( $content, 'recipe-image' ) ) { + $html .= self::output_image_html( $atts['image'] ); + } } // Output the description, if we have one. @@ -291,13 +290,37 @@ class Jetpack_Recipes { } // Sanitize html. - $html = wp_kses_post( $html ); + $html = wp_kses( $html, self::kses_tags() ); // Return the HTML block. return $html; } /** + * Our [recipe-image] shortcode. + * Controls placement of image in recipe. + * + * @param array $atts Array of shortcode attributes. + * + * @return string HTML for recipe notes shortcode. + */ + public static function recipe_image_shortcode( $atts ) { + $atts = shortcode_atts( + array( + 'image' => '', // string. + 0 => '', // string. + ), + $atts, + 'recipe-image' + ); + $src = $atts['image']; + if ( ! empty( $atts[0] ) ) { + $src = $atts[0]; + } + return self::output_image_html( $src ); + } + + /** * Our [recipe-notes] shortcode. * Outputs ingredients, styled in a div. * @@ -306,7 +329,7 @@ class Jetpack_Recipes { * * @return string HTML for recipe notes shortcode. */ - static function recipe_notes_shortcode( $atts, $content = '' ) { + public static function recipe_notes_shortcode( $atts, $content = '' ) { $atts = shortcode_atts( array( 'title' => '', // string. @@ -330,7 +353,7 @@ class Jetpack_Recipes { $html .= '</div>'; // Sanitize html. - $html = wp_kses_post( $html ); + $html = wp_kses( $html, self::kses_tags() ); // Return the HTML block. return $html; @@ -345,7 +368,7 @@ class Jetpack_Recipes { * * @return string HTML for recipe ingredients shortcode. */ - static function recipe_ingredients_shortcode( $atts, $content = '' ) { + public static function recipe_ingredients_shortcode( $atts, $content = '' ) { $atts = shortcode_atts( array( 'title' => esc_html_x( 'Ingredients', 'recipe', 'jetpack' ), // string. @@ -367,7 +390,44 @@ class Jetpack_Recipes { $html .= '</div>'; // Sanitize html. - $html = wp_kses_post( $html ); + $html = wp_kses( $html, self::kses_tags() ); + + // Return the HTML block. + return $html; + } + + /** + * Our [recipe-nutrition] shortcode. + * Outputs notes, styled in a div. + * + * @param array $atts Array of shortcode attributes. + * @param string $content Post content. + * + * @return string HTML for recipe nutrition shortcode. + */ + public static function recipe_nutrition_shortcode( $atts, $content = '' ) { + $atts = shortcode_atts( + array( + 'title' => esc_html_x( 'Nutrition', 'recipe', 'jetpack' ), // string. + ), + $atts, + 'recipe-nutrition' + ); + + $html = '<div class="jetpack-recipe-nutrition p-nutrition nutrition">'; + + // Print a title unless the user has opted to exclude it. + if ( 'false' !== $atts['title'] ) { + $html .= '<h4 class="jetpack-recipe-nutrition-title">' . esc_html( $atts['title'] ) . '</h4>'; + } + + // Format content using list functionality. + $html .= self::output_list_content( $content, 'nutrition' ); + + $html .= '</div>'; + + // Sanitize html. + $html = wp_kses( $html, self::kses_tags() ); // Return the HTML block. return $html; @@ -387,7 +447,7 @@ class Jetpack_Recipes { * * @return string content formatted as a list item */ - static function output_list_content( $content, $type ) { + private static function output_list_content( $content, $type ) { $html = ''; switch ( $type ) { @@ -397,10 +457,20 @@ class Jetpack_Recipes { $listtype = 'ol'; break; case 'ingredients': - $list_item_replacement = '<li class="jetpack-recipe-ingredient" itemprop="recipeIngredient">${1}</li>'; + $list_item_replacement = '<li class="jetpack-recipe-ingredient p-ingredient ingredient" itemprop="recipeIngredient">${1}</li>'; $itemprop = ''; $listtype = 'ul'; break; + case 'nutrition': + $list_item_replacement = '<li class="jetpack-recipe-nutrition">${1}</li>'; + $itemprop = ' itemprop="nutrition"'; + $listtype = 'ul'; + break; + case 'nutrition': + $list_item_replacement = '<li class="jetpack-recipe-nutrition nutrition">${1}</li>'; + $itemprop = ' itemprop="nutrition"'; + $listtype = 'ul'; + break; default: $list_item_replacement = '<li class="jetpack-recipe-notes">${1}</li>'; $itemprop = ''; @@ -464,7 +534,7 @@ class Jetpack_Recipes { * * @return string HTML for recipe directions shortcode. */ - static function recipe_directions_shortcode( $atts, $content = '' ) { + public static function recipe_directions_shortcode( $atts, $content = '' ) { $atts = shortcode_atts( array( 'title' => esc_html_x( 'Directions', 'recipe', 'jetpack' ), // string. @@ -473,7 +543,7 @@ class Jetpack_Recipes { 'recipe-directions' ); - $html = '<div class="jetpack-recipe-directions">'; + $html = '<div class="jetpack-recipe-directions e-instructions">'; // Print a title unless the user has specified to exclude it. if ( 'false' !== $atts['title'] ) { @@ -486,19 +556,102 @@ class Jetpack_Recipes { $html .= '</div>'; // Sanitize html. - $html = wp_kses_post( $html ); + $html = wp_kses( $html, self::kses_tags() ); // Return the HTML block. return $html; } /** + * Outputs time meta tag. + * + * @param string $time_str Raw time to output. + * @param string $time_type Type of time to show. + * + * @return string HTML for recipe time meta. + */ + private static function output_time( $time_str, $time_type ) { + // Get a time that's supported by Schema.org. + $duration = WPCOM_JSON_API_Date::format_duration( $time_str ); + // If no duration can be calculated, let's output what the user provided. + if ( ! $duration ) { + $duration = $time_str; + } + + switch ( $time_type ) { + case 'cooktime': + $title = _x( 'Cook Time', 'recipe', 'jetpack' ); + $itemprop = 'cookTime'; + break; + case 'preptime': + $title = _x( 'Prep Time', 'recipe', 'jetpack' ); + $itemprop = 'prepTime'; + break; + default: + $title = _x( 'Time', 'recipe', 'jetpack' ); + $itemprop = 'totalTime'; + break; + } + + return sprintf( + '<li class="jetpack-recipe-%3$s"> + <time itemprop="%4$s" datetime="%5$s"><strong>%1$s:</strong> <span class="%3$s">%2$s</span></time> + </li>', + esc_html( $title ), + esc_html( $time_str ), + esc_attr( $time_type ), + esc_attr( $itemprop ), + esc_attr( $duration ) + ); + } + + /** + * Outputs image tag for recipe. + * + * @param string $src The image source. + * + * @return string + */ + private static function output_image_html( $src ) { + // Exit if there is no provided source. + if ( ! $src ) { + return ''; + } + + // If it's numeric, this may be an attachment. + if ( is_numeric( $src ) ) { + return wp_get_attachment_image( + $src, + 'full', + false, + array( + 'class' => 'jetpack-recipe-image u-photo photo', + 'itemprop' => 'image', + ) + ); + } + + // Check if it's an absolute or relative URL, and return if not. + if ( + 0 !== strpos( $src, '/' ) + && false === filter_var( $src, FILTER_VALIDATE_URL ) + ) { + return ''; + } + + return sprintf( + '<img class="jetpack-recipe-image u-photo photo" itemprop="image" src="%1$s" />', + esc_url( $src ) + ); + } + + /** * Use $themecolors array to style the Recipes shortcode * * @print style block * @return string $style */ - function themecolor_styles() { + public function themecolor_styles() { global $themecolors; $style = ''; |