Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 8
100.00% covered (success)
100.00%
4 / 4
CRAP
n/a
0 / 0
jetpack_featured_images_fallback_get_image
n/a
0 / 0
n/a
0 / 0
25
jetpack_featured_images_fallback_get_image_src
n/a
0 / 0
n/a
0 / 0
15
jetpack_has_featured_image
n/a
0 / 0
n/a
0 / 0
1
jetpack_featured_images_post_class
n/a
0 / 0
n/a
0 / 0
6
1<?php
2/**
3 * Theme Tools: functions for Featured Images fallback.
4 *
5 * @package automattic/jetpack
6 */
7
8use Automattic\Jetpack\Post_Media\Images;
9
10if ( ! defined( 'ABSPATH' ) ) {
11    exit( 0 );
12}
13
14if ( ! function_exists( 'jetpack_featured_images_fallback_get_image' ) ) {
15
16    /**
17     * Get one image from a specified post in the following order:
18     * Featured Image then first image from the_content HTML
19     * and filter the post_thumbnail_html
20     *
21     * @deprecated 13.9 Moved to Classic Theme Helper package.
22     * @param string       $html              The HTML for the image markup.
23     * @param int          $post_id           The post ID to check.
24     * @param int          $post_thumbnail_id The ID of the featured image.
25     * @param string       $size              The image size to return, defaults to 'post-thumbnail'.
26     * @param string|array $attr              Optional. Query string or array of attributes.
27     *
28     * @return string      $html              Thumbnail image with markup.
29     */
30    function jetpack_featured_images_fallback_get_image( $html, $post_id, $post_thumbnail_id, $size, $attr ) {
31        _deprecated_function( __FUNCTION__, 'jetpack-13.9' );
32        $opts = jetpack_featured_images_get_settings();
33
34        if ( ! empty( $html ) || (bool) 1 !== (bool) $opts['fallback-option'] ) {
35            return trim( $html );
36        }
37
38        if ( jetpack_featured_images_should_load() ) {
39            if (
40                ( true === $opts['archive'] && ( is_home() || is_archive() || is_search() ) && ! $opts['archive-option'] )
41                || ( true === $opts['post'] && is_single() && ! $opts['post-option'] )
42                || ! $opts['fallback-option']
43            ) {
44                return trim( $html );
45            }
46        }
47
48        global $_wp_additional_image_sizes;
49
50        $args = array(
51            'from_thumbnail'  => false,
52            'from_slideshow'  => true,
53            'from_gallery'    => true,
54            'from_attachment' => false,
55        );
56
57        $image = Images::get_image( $post_id, $args );
58
59        if ( ! empty( $image ) ) {
60            $image['width']  = '';
61            $image['height'] = '';
62            $image['crop']   = '';
63
64            if ( array_key_exists( $size, $_wp_additional_image_sizes ) ) {
65                $image['width']  = $_wp_additional_image_sizes[ $size ]['width'];
66                $image['height'] = $_wp_additional_image_sizes[ $size ]['height'];
67                $image['crop']   = $_wp_additional_image_sizes[ $size ]['crop'];
68            }
69
70            // Force `crop` to be a simple boolean, to avoid dealing with WP crop positions.
71            $image['crop'] = boolval( $image['crop'] );
72
73            $image_sizes = '';
74
75            $width  = isset( $image['width'] ) ? intval( $image['width'] ) : null;
76            $height = isset( $image['height'] ) ? intval( $image['height'] ) : null;
77
78            if ( ! empty( $image['src_width'] ) && ! empty( $image['src_height'] ) && ! empty( $image['width'] ) && ! empty( $image['height'] ) ) {
79                $src_width  = intval( $image['src_width'] );
80                $src_height = intval( $image['src_height'] );
81
82                // If we're aware of the source dimensions, calculate the final image height and width.
83                // This allows us to provide them as attributes in the `<img>` tag, to avoid layout shifts.
84                // It also allows us to calculate a `srcset`.
85                if ( $image['crop'] ) {
86                    // If we're cropping, the final dimensions are calculated independently of each other.
87                    $width  = min( $width, $src_width );
88                    $height = min( $height, $src_height );
89                } else {
90                    // If we're not cropping, we need to preserve aspect ratio.
91                    $dims   = wp_constrain_dimensions( $src_width, $src_height, $width, $height );
92                    $width  = $dims[0];
93                    $height = $dims[1];
94                }
95
96                $image_src    = Images::fit_image_url( $image['src'], $width, $height );
97                $image_srcset = Images::generate_cropped_srcset( $image, $width, $height, true );
98                $image_sizes  = 'min(' . $width . 'px, 100vw)';
99            } else {
100                // If we're not aware of the source dimensions, leave the size calculations to the CDN, and
101                // fall back to a simpler `<img>` tag without `width`/`height` or `srcset`.
102                $image_src = Images::fit_image_url( $image['src'], $image['width'], $image['height'] );
103
104                // Use the theme's crop setting rather than forcing to true.
105                $image_src = add_query_arg( 'crop', $image['crop'], $image_src );
106
107                $image_srcset = null;
108                $image_sizes  = null;
109            }
110
111            $default_attr = array(
112                'srcset'   => $image_srcset,
113                'sizes'    => $image_sizes,
114                'loading'  => is_singular() ? 'eager' : 'lazy',
115                'decoding' => 'async',
116                'title'    => wp_strip_all_tags( get_the_title() ),
117                'alt'      => '',
118                'class'    => "attachment-$size wp-post-image",
119            );
120
121            $image_attr = wp_parse_args( $attr, $default_attr );
122            $hwstring   = image_hwstring( $width, $height );
123
124            $html  = rtrim( "<img $hwstring" );
125            $html .= ' src="' . esc_url( $image_src ) . '"';
126
127            foreach ( $image_attr as $name => $value ) {
128                if ( $value ) {
129                    $html .= " $name=" . '"' . esc_attr( $value ) . '"';
130                }
131            }
132
133            $html .= ' />';
134
135            return trim( $html );
136        }
137
138        return trim( $html );
139    }
140    add_filter( 'post_thumbnail_html', 'jetpack_featured_images_fallback_get_image', 10, 5 );
141
142}
143
144if ( ! function_exists( 'jetpack_featured_images_fallback_get_image_src' ) ) {
145
146    /**
147     * Get URL of one image from a specified post in the following order:
148     * Featured Image then first image from the_content HTML
149     *
150     * @deprecated 13.9 Moved to Classic Theme Helper package.
151     * @param int    $post_id           The post ID to check.
152     * @param int    $post_thumbnail_id The ID of the featured image.
153     * @param string $size              The image size to return, defaults to 'post-thumbnail'.
154     *
155     * @return string|null $image_src         The URL of the thumbnail image.
156     */
157    function jetpack_featured_images_fallback_get_image_src( $post_id, $post_thumbnail_id, $size ) {
158        _deprecated_function( __FUNCTION__, 'jetpack-13.9' );
159        $image_src = wp_get_attachment_image_src( $post_thumbnail_id, $size );
160        $image_src = ( ! empty( $image_src[0] ) ) ? $image_src[0] : null;
161        $opts      = jetpack_featured_images_get_settings();
162
163        if ( ! empty( $image_src ) || (bool) 1 !== (bool) $opts['fallback-option'] ) {
164            return esc_url( $image_src );
165        }
166
167        if ( jetpack_featured_images_should_load() ) {
168            if ( ( true === $opts['archive'] && ( is_home() || is_archive() || is_search() ) && ! $opts['archive-option'] )
169                || ( true === $opts['post'] && is_single() && ! $opts['post-option'] ) ) {
170                    return esc_url( $image_src );
171            }
172        }
173
174        global $_wp_additional_image_sizes;
175
176        $args = array(
177            'from_thumbnail'  => false,
178            'from_slideshow'  => true,
179            'from_gallery'    => true,
180            'from_attachment' => false,
181        );
182
183        $image = Images::get_image( $post_id, $args );
184
185        if ( ! empty( $image ) ) {
186            $image['width']  = '';
187            $image['height'] = '';
188            $image['crop']   = '';
189
190            if ( array_key_exists( $size, $_wp_additional_image_sizes ) ) {
191                $image['width']  = $_wp_additional_image_sizes[ $size ]['width'];
192                $image['height'] = $_wp_additional_image_sizes[ $size ]['height'];
193                $image['crop']   = $_wp_additional_image_sizes[ $size ]['crop'];
194            }
195
196            $image_src = Images::fit_image_url( $image['src'], $image['width'], $image['height'] );
197
198            // Use the theme's crop setting rather than forcing to true.
199            $image_src = add_query_arg( 'crop', $image['crop'], $image_src );
200
201            return esc_url( $image_src );
202        }
203
204        return esc_url( $image_src );
205    }
206
207}
208
209if ( ! function_exists( 'jetpack_has_featured_image' ) ) {
210
211    /**
212     * Check if post has an image attached, including a fallback.
213     *
214     * @deprecated 13.9 Moved to Classic Theme Helper package.
215     * @param  int $post The post ID to check.
216     *
217     * @return bool
218     */
219    function jetpack_has_featured_image( $post = null ) {
220        _deprecated_function( __FUNCTION__, 'jetpack-13.9' );
221        return (bool) get_the_post_thumbnail( $post );
222    }
223
224}
225
226if ( ! function_exists( 'jetpack_featured_images_post_class' ) ) {
227
228    /**
229     * Adds custom class to the array of post classes.
230     *
231     * @deprecated 13.9 Moved to Classic Theme Helper package.
232     * @param array $classes Classes for the post element.
233     * @param array $class   Optional. Comma-separated list of additional classes.
234     * @param array $post_id Unique The post ID to check.
235     *
236     * @return array $classes
237     */
238    function jetpack_featured_images_post_class( $classes, $class, $post_id ) {
239        _deprecated_function( __FUNCTION__, 'jetpack-13.9' );
240        $post_password_required = post_password_required( $post_id );
241        $opts                   = jetpack_featured_images_get_settings();
242
243        if ( jetpack_has_featured_image( $post_id ) && (bool) 1 === (bool) $opts['fallback-option'] && ! is_attachment() && ! $post_password_required && 'post' === get_post_type() ) {
244            $classes[] = 'has-post-thumbnail';
245            $classes[] = 'fallback-thumbnail';
246        }
247
248        return $classes;
249    }
250    add_filter( 'post_class', 'jetpack_featured_images_post_class', 10, 3 );
251
252}