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