wp/wp-includes/media.php
changeset 19 3d72ae0968f4
parent 18 be944660c56a
child 21 48c4eec2b7e6
equal deleted inserted replaced
18:be944660c56a 19:3d72ae0968f4
   391 	 * @param string|int[] $size  Requested image size. Can be any registered image size name, or
   391 	 * @param string|int[] $size  Requested image size. Can be any registered image size name, or
   392 	 *                            an array of width and height values in pixels (in that order).
   392 	 *                            an array of width and height values in pixels (in that order).
   393 	 */
   393 	 */
   394 	$class = apply_filters( 'get_image_tag_class', $class, $id, $align, $size );
   394 	$class = apply_filters( 'get_image_tag_class', $class, $id, $align, $size );
   395 
   395 
   396 	$html = '<img src="' . esc_attr( $img_src ) . '" alt="' . esc_attr( $alt ) . '" ' . $title . $hwstring . 'class="' . $class . '" />';
   396 	$html = '<img src="' . esc_url( $img_src ) . '" alt="' . esc_attr( $alt ) . '" ' . $title . $hwstring . 'class="' . $class . '" />';
   397 
   397 
   398 	/**
   398 	/**
   399 	 * Filters the HTML content for the image tag.
   399 	 * Filters the HTML content for the image tag.
   400 	 *
   400 	 *
   401 	 * @since 2.6.0
   401 	 * @since 2.6.0
   880  *
   880  *
   881  * @since 5.3.0
   881  * @since 5.3.0
   882  * @uses wp_get_additional_image_sizes()
   882  * @uses wp_get_additional_image_sizes()
   883  * @uses get_intermediate_image_sizes()
   883  * @uses get_intermediate_image_sizes()
   884  *
   884  *
   885  * @return array Associative array of the registered image sub-sizes.
   885  * @return array[] Associative array of arrays of image sub-size information,
       
   886  *                 keyed by image size name.
   886  */
   887  */
   887 function wp_get_registered_image_subsizes() {
   888 function wp_get_registered_image_subsizes() {
   888 	$additional_sizes = wp_get_additional_image_sizes();
   889 	$additional_sizes = wp_get_additional_image_sizes();
   889 	$all_sizes        = array();
   890 	$all_sizes        = array();
   890 
   891 
  1044 			'alt'   => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ),
  1045 			'alt'   => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ),
  1045 		);
  1046 		);
  1046 
  1047 
  1047 		// Add `loading` attribute.
  1048 		// Add `loading` attribute.
  1048 		if ( wp_lazy_loading_enabled( 'img', 'wp_get_attachment_image' ) ) {
  1049 		if ( wp_lazy_loading_enabled( 'img', 'wp_get_attachment_image' ) ) {
  1049 			$default_attr['loading'] = 'lazy';
  1050 			$default_attr['loading'] = wp_get_loading_attr_default( 'wp_get_attachment_image' );
  1050 		}
  1051 		}
  1051 
  1052 
  1052 		$attr = wp_parse_args( $attr, $default_attr );
  1053 		$attr = wp_parse_args( $attr, $default_attr );
  1053 
  1054 
  1054 		// If the default value of `lazy` for the `loading` attribute is overridden
  1055 		// If the default value of `lazy` for the `loading` attribute is overridden
  1127  * @return string|false Attachment URL or false if no image is available. If `$size` does not match
  1128  * @return string|false Attachment URL or false if no image is available. If `$size` does not match
  1128  *                      any registered image size, the original image URL will be returned.
  1129  *                      any registered image size, the original image URL will be returned.
  1129  */
  1130  */
  1130 function wp_get_attachment_image_url( $attachment_id, $size = 'thumbnail', $icon = false ) {
  1131 function wp_get_attachment_image_url( $attachment_id, $size = 'thumbnail', $icon = false ) {
  1131 	$image = wp_get_attachment_image_src( $attachment_id, $size, $icon );
  1132 	$image = wp_get_attachment_image_src( $attachment_id, $size, $icon );
  1132 	return isset( $image['0'] ) ? $image['0'] : false;
  1133 	return isset( $image[0] ) ? $image[0] : false;
  1133 }
  1134 }
  1134 
  1135 
  1135 /**
  1136 /**
  1136  * Get the attachment path relative to the upload directory.
  1137  * Get the attachment path relative to the upload directory.
  1137  *
  1138  *
  1818 		 * images to avoid making individual database calls.
  1819 		 * images to avoid making individual database calls.
  1819 		 */
  1820 		 */
  1820 		_prime_post_caches( $attachment_ids, false, true );
  1821 		_prime_post_caches( $attachment_ids, false, true );
  1821 	}
  1822 	}
  1822 
  1823 
  1823 	foreach ( $images as $image => $attachment_id ) {
  1824 	// Iterate through the matches in order of occurrence as it is relevant for whether or not to lazy-load.
  1824 		$filtered_image = $image;
  1825 	foreach ( $matches as $match ) {
  1825 
  1826 		// Filter an image match.
  1826 		// Add 'width' and 'height' attributes if applicable.
  1827 		if ( isset( $images[ $match[0] ] ) ) {
  1827 		if ( $attachment_id > 0 && false === strpos( $filtered_image, ' width=' ) && false === strpos( $filtered_image, ' height=' ) ) {
  1828 			$filtered_image = $match[0];
  1828 			$filtered_image = wp_img_tag_add_width_and_height_attr( $filtered_image, $context, $attachment_id );
  1829 			$attachment_id  = $images[ $match[0] ];
  1829 		}
  1830 
  1830 
  1831 			// Add 'width' and 'height' attributes if applicable.
  1831 		// Add 'srcset' and 'sizes' attributes if applicable.
  1832 			if ( $attachment_id > 0 && false === strpos( $filtered_image, ' width=' ) && false === strpos( $filtered_image, ' height=' ) ) {
  1832 		if ( $attachment_id > 0 && false === strpos( $filtered_image, ' srcset=' ) ) {
  1833 				$filtered_image = wp_img_tag_add_width_and_height_attr( $filtered_image, $context, $attachment_id );
  1833 			$filtered_image = wp_img_tag_add_srcset_and_sizes_attr( $filtered_image, $context, $attachment_id );
  1834 			}
  1834 		}
  1835 
  1835 
  1836 			// Add 'srcset' and 'sizes' attributes if applicable.
  1836 		// Add 'loading' attribute if applicable.
  1837 			if ( $attachment_id > 0 && false === strpos( $filtered_image, ' srcset=' ) ) {
  1837 		if ( $add_img_loading_attr && false === strpos( $filtered_image, ' loading=' ) ) {
  1838 				$filtered_image = wp_img_tag_add_srcset_and_sizes_attr( $filtered_image, $context, $attachment_id );
  1838 			$filtered_image = wp_img_tag_add_loading_attr( $filtered_image, $context );
  1839 			}
  1839 		}
  1840 
  1840 
  1841 			// Add 'loading' attribute if applicable.
  1841 		if ( $filtered_image !== $image ) {
  1842 			if ( $add_img_loading_attr && false === strpos( $filtered_image, ' loading=' ) ) {
  1842 			$content = str_replace( $image, $filtered_image, $content );
  1843 				$filtered_image = wp_img_tag_add_loading_attr( $filtered_image, $context );
  1843 		}
  1844 			}
  1844 	}
  1845 
  1845 
  1846 			/**
  1846 	foreach ( $iframes as $iframe => $attachment_id ) {
  1847 			 * Filters an img tag within the content for a given context.
  1847 		$filtered_iframe = $iframe;
  1848 			 *
  1848 
  1849 			 * @since 6.0.0
  1849 		// Add 'loading' attribute if applicable.
  1850 			 *
  1850 		if ( $add_iframe_loading_attr && false === strpos( $filtered_iframe, ' loading=' ) ) {
  1851 			 * @param string $filtered_image Full img tag with attributes that will replace the source img tag.
  1851 			$filtered_iframe = wp_iframe_tag_add_loading_attr( $filtered_iframe, $context );
  1852 			 * @param string $context        Additional context, like the current filter name or the function name from where this was called.
  1852 		}
  1853 			 * @param int    $attachment_id  The image attachment ID. May be 0 in case the image is not an attachment.
  1853 
  1854 			 */
  1854 		if ( $filtered_iframe !== $iframe ) {
  1855 			$filtered_image = apply_filters( 'wp_content_img_tag', $filtered_image, $context, $attachment_id );
  1855 			$content = str_replace( $iframe, $filtered_iframe, $content );
  1856 
       
  1857 			if ( $filtered_image !== $match[0] ) {
       
  1858 				$content = str_replace( $match[0], $filtered_image, $content );
       
  1859 			}
       
  1860 
       
  1861 			/*
       
  1862 			 * Unset image lookup to not run the same logic again unnecessarily if the same image tag is used more than
       
  1863 			 * once in the same blob of content.
       
  1864 			 */
       
  1865 			unset( $images[ $match[0] ] );
       
  1866 		}
       
  1867 
       
  1868 		// Filter an iframe match.
       
  1869 		if ( isset( $iframes[ $match[0] ] ) ) {
       
  1870 			$filtered_iframe = $match[0];
       
  1871 
       
  1872 			// Add 'loading' attribute if applicable.
       
  1873 			if ( $add_iframe_loading_attr && false === strpos( $filtered_iframe, ' loading=' ) ) {
       
  1874 				$filtered_iframe = wp_iframe_tag_add_loading_attr( $filtered_iframe, $context );
       
  1875 			}
       
  1876 
       
  1877 			if ( $filtered_iframe !== $match[0] ) {
       
  1878 				$content = str_replace( $match[0], $filtered_iframe, $content );
       
  1879 			}
       
  1880 
       
  1881 			/*
       
  1882 			 * Unset iframe lookup to not run the same logic again unnecessarily if the same iframe tag is used more
       
  1883 			 * than once in the same blob of content.
       
  1884 			 */
       
  1885 			unset( $iframes[ $match[0] ] );
  1856 		}
  1886 		}
  1857 	}
  1887 	}
  1858 
  1888 
  1859 	return $content;
  1889 	return $content;
  1860 }
  1890 }
  1867  * @param string $image   The HTML `img` tag where the attribute should be added.
  1897  * @param string $image   The HTML `img` tag where the attribute should be added.
  1868  * @param string $context Additional context to pass to the filters.
  1898  * @param string $context Additional context to pass to the filters.
  1869  * @return string Converted `img` tag with `loading` attribute added.
  1899  * @return string Converted `img` tag with `loading` attribute added.
  1870  */
  1900  */
  1871 function wp_img_tag_add_loading_attr( $image, $context ) {
  1901 function wp_img_tag_add_loading_attr( $image, $context ) {
       
  1902 	// Get loading attribute value to use. This must occur before the conditional check below so that even images that
       
  1903 	// are ineligible for being lazy-loaded are considered.
       
  1904 	$value = wp_get_loading_attr_default( $context );
       
  1905 
  1872 	// Images should have source and dimension attributes for the `loading` attribute to be added.
  1906 	// Images should have source and dimension attributes for the `loading` attribute to be added.
  1873 	if ( false === strpos( $image, ' src="' ) || false === strpos( $image, ' width="' ) || false === strpos( $image, ' height="' ) ) {
  1907 	if ( false === strpos( $image, ' src="' ) || false === strpos( $image, ' width="' ) || false === strpos( $image, ' height="' ) ) {
  1874 		return $image;
  1908 		return $image;
  1875 	}
  1909 	}
  1876 
  1910 
  1881 	 * Returning `true` will add the default value.
  1915 	 * Returning `true` will add the default value.
  1882 	 *
  1916 	 *
  1883 	 * @since 5.5.0
  1917 	 * @since 5.5.0
  1884 	 *
  1918 	 *
  1885 	 * @param string|bool $value   The `loading` attribute value. Returning a falsey value will result in
  1919 	 * @param string|bool $value   The `loading` attribute value. Returning a falsey value will result in
  1886 	 *                             the attribute being omitted for the image. Default 'lazy'.
  1920 	 *                             the attribute being omitted for the image.
  1887 	 * @param string      $image   The HTML `img` tag to be filtered.
  1921 	 * @param string      $image   The HTML `img` tag to be filtered.
  1888 	 * @param string      $context Additional context about how the function was called or where the img tag is.
  1922 	 * @param string      $context Additional context about how the function was called or where the img tag is.
  1889 	 */
  1923 	 */
  1890 	$value = apply_filters( 'wp_img_tag_add_loading_attr', 'lazy', $image, $context );
  1924 	$value = apply_filters( 'wp_img_tag_add_loading_attr', $value, $image, $context );
  1891 
  1925 
  1892 	if ( $value ) {
  1926 	if ( $value ) {
  1893 		if ( ! in_array( $value, array( 'lazy', 'eager' ), true ) ) {
  1927 		if ( ! in_array( $value, array( 'lazy', 'eager' ), true ) ) {
  1894 			$value = 'lazy';
  1928 			$value = 'lazy';
  1895 		}
  1929 		}
  1993 	// visually hidden initially.
  2027 	// visually hidden initially.
  1994 	if ( false !== strpos( $iframe, ' data-secret="' ) ) {
  2028 	if ( false !== strpos( $iframe, ' data-secret="' ) ) {
  1995 		return $iframe;
  2029 		return $iframe;
  1996 	}
  2030 	}
  1997 
  2031 
       
  2032 	// Get loading attribute value to use. This must occur before the conditional check below so that even iframes that
       
  2033 	// are ineligible for being lazy-loaded are considered.
       
  2034 	$value = wp_get_loading_attr_default( $context );
       
  2035 
  1998 	// Iframes should have source and dimension attributes for the `loading` attribute to be added.
  2036 	// Iframes should have source and dimension attributes for the `loading` attribute to be added.
  1999 	if ( false === strpos( $iframe, ' src="' ) || false === strpos( $iframe, ' width="' ) || false === strpos( $iframe, ' height="' ) ) {
  2037 	if ( false === strpos( $iframe, ' src="' ) || false === strpos( $iframe, ' width="' ) || false === strpos( $iframe, ' height="' ) ) {
  2000 		return $iframe;
  2038 		return $iframe;
  2001 	}
  2039 	}
  2002 
  2040 
  2007 	 * Returning `true` will add the default value.
  2045 	 * Returning `true` will add the default value.
  2008 	 *
  2046 	 *
  2009 	 * @since 5.7.0
  2047 	 * @since 5.7.0
  2010 	 *
  2048 	 *
  2011 	 * @param string|bool $value   The `loading` attribute value. Returning a falsey value will result in
  2049 	 * @param string|bool $value   The `loading` attribute value. Returning a falsey value will result in
  2012 	 *                             the attribute being omitted for the iframe. Default 'lazy'.
  2050 	 *                             the attribute being omitted for the iframe.
  2013 	 * @param string      $iframe  The HTML `iframe` tag to be filtered.
  2051 	 * @param string      $iframe  The HTML `iframe` tag to be filtered.
  2014 	 * @param string      $context Additional context about how the function was called or where the iframe tag is.
  2052 	 * @param string      $context Additional context about how the function was called or where the iframe tag is.
  2015 	 */
  2053 	 */
  2016 	$value = apply_filters( 'wp_iframe_tag_add_loading_attr', 'lazy', $iframe, $context );
  2054 	$value = apply_filters( 'wp_iframe_tag_add_loading_attr', $value, $iframe, $context );
  2017 
  2055 
  2018 	if ( $value ) {
  2056 	if ( $value ) {
  2019 		if ( ! in_array( $value, array( 'lazy', 'eager' ), true ) ) {
  2057 		if ( ! in_array( $value, array( 'lazy', 'eager' ), true ) ) {
  2020 			$value = 'lazy';
  2058 			$value = 'lazy';
  2021 		}
  2059 		}
  2083  * 'width', 'caption', and 'class'.
  2121  * 'width', 'caption', and 'class'.
  2084  *
  2122  *
  2085  * @since 2.6.0
  2123  * @since 2.6.0
  2086  * @since 3.9.0 The `class` attribute was added.
  2124  * @since 3.9.0 The `class` attribute was added.
  2087  * @since 5.1.0 The `caption_id` attribute was added.
  2125  * @since 5.1.0 The `caption_id` attribute was added.
       
  2126  * @since 5.9.0 The `$content` parameter default value changed from `null` to `''`.
  2088  *
  2127  *
  2089  * @param array  $attr {
  2128  * @param array  $attr {
  2090  *     Attributes of the caption shortcode.
  2129  *     Attributes of the caption shortcode.
  2091  *
  2130  *
  2092  *     @type string $id         ID of the image and caption container element, i.e. `<figure>` or `<div>`.
  2131  *     @type string $id         ID of the image and caption container element, i.e. `<figure>` or `<div>`.
  2095  *                              'aligncenter', alignright', 'alignnone'.
  2134  *                              'aligncenter', alignright', 'alignnone'.
  2096  *     @type int    $width      The width of the caption, in pixels.
  2135  *     @type int    $width      The width of the caption, in pixels.
  2097  *     @type string $caption    The caption text.
  2136  *     @type string $caption    The caption text.
  2098  *     @type string $class      Additional class name(s) added to the caption container.
  2137  *     @type string $class      Additional class name(s) added to the caption container.
  2099  * }
  2138  * }
  2100  * @param string $content Shortcode content.
  2139  * @param string $content Optional. Shortcode content. Default empty string.
  2101  * @return string HTML content to display the caption.
  2140  * @return string HTML content to display the caption.
  2102  */
  2141  */
  2103 function img_caption_shortcode( $attr, $content = null ) {
  2142 function img_caption_shortcode( $attr, $content = '' ) {
  2104 	// New-style shortcode with the caption inside the shortcode with the link and image tags.
  2143 	// New-style shortcode with the caption inside the shortcode with the link and image tags.
  2105 	if ( ! isset( $attr['caption'] ) ) {
  2144 	if ( ! isset( $attr['caption'] ) ) {
  2106 		if ( preg_match( '#((?:<a [^>]+>\s*)?<img [^>]+>(?:\s*</a>)?)(.*)#is', $content, $matches ) ) {
  2145 		if ( preg_match( '#((?:<a [^>]+>\s*)?<img [^>]+>(?:\s*</a>)?)(.*)#is', $content, $matches ) ) {
  2107 			$content         = $matches[1];
  2146 			$content         = $matches[1];
  2108 			$attr['caption'] = trim( $matches[2] );
  2147 			$attr['caption'] = trim( $matches[2] );
  4028 	$attached_file = get_attached_file( $attachment->ID );
  4067 	$attached_file = get_attached_file( $attachment->ID );
  4029 
  4068 
  4030 	if ( isset( $meta['filesize'] ) ) {
  4069 	if ( isset( $meta['filesize'] ) ) {
  4031 		$bytes = $meta['filesize'];
  4070 		$bytes = $meta['filesize'];
  4032 	} elseif ( file_exists( $attached_file ) ) {
  4071 	} elseif ( file_exists( $attached_file ) ) {
  4033 		$bytes = filesize( $attached_file );
  4072 		$bytes = wp_filesize( $attached_file );
  4034 	} else {
  4073 	} else {
  4035 		$bytes = '';
  4074 		$bytes = '';
  4036 	}
  4075 	}
  4037 
  4076 
  4038 	if ( $bytes ) {
  4077 	if ( $bytes ) {
  4207  * @global WP_Locale $wp_locale     WordPress date and time locale object.
  4246  * @global WP_Locale $wp_locale     WordPress date and time locale object.
  4208  *
  4247  *
  4209  * @param array $args {
  4248  * @param array $args {
  4210  *     Arguments for enqueuing media scripts.
  4249  *     Arguments for enqueuing media scripts.
  4211  *
  4250  *
  4212  *     @type int|WP_Post A post object or ID.
  4251  *     @type int|WP_Post $post A post object or ID.
  4213  * }
  4252  * }
  4214  */
  4253  */
  4215 function wp_enqueue_media( $args = array() ) {
  4254 function wp_enqueue_media( $args = array() ) {
  4216 	// Enqueue me just once per page, please.
  4255 	// Enqueue me just once per page, please.
  4217 	if ( did_action( 'wp_enqueue_media' ) ) {
  4256 	if ( did_action( 'wp_enqueue_media' ) ) {
  4453 		'returnToLibrary'             => __( '&#8592; Go to library' ),
  4492 		'returnToLibrary'             => __( '&#8592; Go to library' ),
  4454 		'allMediaItems'               => __( 'All media items' ),
  4493 		'allMediaItems'               => __( 'All media items' ),
  4455 		'allDates'                    => __( 'All dates' ),
  4494 		'allDates'                    => __( 'All dates' ),
  4456 		'noItemsFound'                => __( 'No items found.' ),
  4495 		'noItemsFound'                => __( 'No items found.' ),
  4457 		'insertIntoPost'              => $post_type_object->labels->insert_into_item,
  4496 		'insertIntoPost'              => $post_type_object->labels->insert_into_item,
  4458 		'unattached'                  => __( 'Unattached' ),
  4497 		'unattached'                  => _x( 'Unattached', 'media items' ),
  4459 		'mine'                        => _x( 'Mine', 'media items' ),
  4498 		'mine'                        => _x( 'Mine', 'media items' ),
  4460 		'trash'                       => _x( 'Trash', 'noun' ),
  4499 		'trash'                       => _x( 'Trash', 'noun' ),
  4461 		'uploadedToThisPost'          => $post_type_object->labels->uploaded_to_this_item,
  4500 		'uploadedToThisPost'          => $post_type_object->labels->uploaded_to_this_item,
  4462 		'warnDelete'                  => __( "You are about to permanently delete this item from your site.\nThis action cannot be undone.\n 'Cancel' to stop, 'OK' to delete." ),
  4501 		'warnDelete'                  => __( "You are about to permanently delete this item from your site.\nThis action cannot be undone.\n 'Cancel' to stop, 'OK' to delete." ),
  4463 		'warnBulkDelete'              => __( "You are about to permanently delete these items from your site.\nThis action cannot be undone.\n 'Cancel' to stop, 'OK' to delete." ),
  4502 		'warnBulkDelete'              => __( "You are about to permanently delete these items from your site.\nThis action cannot be undone.\n 'Cancel' to stop, 'OK' to delete." ),
  4464 		'warnBulkTrash'               => __( "You are about to trash these items.\n  'Cancel' to stop, 'OK' to delete." ),
  4503 		'warnBulkTrash'               => __( "You are about to trash these items.\n  'Cancel' to stop, 'OK' to delete." ),
  4465 		'bulkSelect'                  => __( 'Bulk select' ),
  4504 		'bulkSelect'                  => __( 'Bulk select' ),
  4466 		'trashSelected'               => __( 'Move to Trash' ),
  4505 		'trashSelected'               => __( 'Move to Trash' ),
  4467 		'restoreSelected'             => __( 'Restore from Trash' ),
  4506 		'restoreSelected'             => __( 'Restore from Trash' ),
  4468 		'deletePermanently'           => __( 'Delete permanently' ),
  4507 		'deletePermanently'           => __( 'Delete permanently' ),
       
  4508 		'errorDeleting'               => __( 'Error in deleting the attachment.' ),
  4469 		'apply'                       => __( 'Apply' ),
  4509 		'apply'                       => __( 'Apply' ),
  4470 		'filterByDate'                => __( 'Filter by date' ),
  4510 		'filterByDate'                => __( 'Filter by date' ),
  4471 		'filterByType'                => __( 'Filter by type' ),
  4511 		'filterByType'                => __( 'Filter by type' ),
  4472 		'searchLabel'                 => __( 'Search' ),
  4512 		'searchLabel'                 => __( 'Search' ),
  4473 		'searchMediaLabel'            => __( 'Search media' ),          // Backward compatibility pre-5.3.
  4513 		'searchMediaLabel'            => __( 'Search media' ),          // Backward compatibility pre-5.3.
  4708 
  4748 
  4709 	if ( ! $post ) {
  4749 	if ( ! $post ) {
  4710 		return array();
  4750 		return array();
  4711 	}
  4751 	}
  4712 
  4752 
  4713 	if ( ! has_shortcode( $post->post_content, 'gallery' ) ) {
  4753 	if ( ! has_shortcode( $post->post_content, 'gallery' ) && ! has_block( 'gallery', $post->post_content ) ) {
  4714 		return array();
  4754 		return array();
  4715 	}
  4755 	}
  4716 
  4756 
  4717 	$galleries = array();
  4757 	$galleries = array();
  4718 	if ( preg_match_all( '/' . get_shortcode_regex() . '/s', $post->post_content, $matches, PREG_SET_ORDER ) ) {
  4758 	if ( preg_match_all( '/' . get_shortcode_regex() . '/s', $post->post_content, $matches, PREG_SET_ORDER ) ) {
  4747 							'src' => array_values( array_unique( $srcs ) ),
  4787 							'src' => array_values( array_unique( $srcs ) ),
  4748 						)
  4788 						)
  4749 					);
  4789 					);
  4750 				}
  4790 				}
  4751 			}
  4791 			}
       
  4792 		}
       
  4793 	}
       
  4794 
       
  4795 	if ( has_block( 'gallery', $post->post_content ) ) {
       
  4796 		$post_blocks = parse_blocks( $post->post_content );
       
  4797 
       
  4798 		while ( $block = array_shift( $post_blocks ) ) {
       
  4799 			$has_inner_blocks = ! empty( $block['innerBlocks'] );
       
  4800 
       
  4801 			// Skip blocks with no blockName and no innerHTML.
       
  4802 			if ( ! $block['blockName'] ) {
       
  4803 				continue;
       
  4804 			}
       
  4805 
       
  4806 			// Skip non-Gallery blocks.
       
  4807 			if ( 'core/gallery' !== $block['blockName'] ) {
       
  4808 				// Move inner blocks into the root array before skipping.
       
  4809 				if ( $has_inner_blocks ) {
       
  4810 					array_push( $post_blocks, ...$block['innerBlocks'] );
       
  4811 				}
       
  4812 				continue;
       
  4813 			}
       
  4814 
       
  4815 			// New Gallery block format as HTML.
       
  4816 			if ( $has_inner_blocks && $html ) {
       
  4817 				$block_html  = wp_list_pluck( $block['innerBlocks'], 'innerHTML' );
       
  4818 				$galleries[] = '<figure>' . implode( ' ', $block_html ) . '</figure>';
       
  4819 				continue;
       
  4820 			}
       
  4821 
       
  4822 			$srcs = array();
       
  4823 
       
  4824 			// New Gallery block format as an array.
       
  4825 			if ( $has_inner_blocks ) {
       
  4826 				$attrs = wp_list_pluck( $block['innerBlocks'], 'attrs' );
       
  4827 				$ids   = wp_list_pluck( $attrs, 'id' );
       
  4828 
       
  4829 				foreach ( $ids as $id ) {
       
  4830 					$url = wp_get_attachment_url( $id );
       
  4831 
       
  4832 					if ( is_string( $url ) && ! in_array( $url, $srcs, true ) ) {
       
  4833 						$srcs[] = $url;
       
  4834 					}
       
  4835 				}
       
  4836 
       
  4837 				$galleries[] = array(
       
  4838 					'ids' => implode( ',', $ids ),
       
  4839 					'src' => $srcs,
       
  4840 				);
       
  4841 
       
  4842 				continue;
       
  4843 			}
       
  4844 
       
  4845 			// Old Gallery block format as HTML.
       
  4846 			if ( $html ) {
       
  4847 				$galleries[] = $block['innerHTML'];
       
  4848 				continue;
       
  4849 			}
       
  4850 
       
  4851 			// Old Gallery block format as an array.
       
  4852 			$ids = ! empty( $block['attrs']['ids'] ) ? $block['attrs']['ids'] : array();
       
  4853 
       
  4854 			// If present, use the image IDs from the JSON blob as canonical.
       
  4855 			if ( ! empty( $ids ) ) {
       
  4856 				foreach ( $ids as $id ) {
       
  4857 					$url = wp_get_attachment_url( $id );
       
  4858 
       
  4859 					if ( is_string( $url ) && ! in_array( $url, $srcs, true ) ) {
       
  4860 						$srcs[] = $url;
       
  4861 					}
       
  4862 				}
       
  4863 
       
  4864 				$galleries[] = array(
       
  4865 					'ids' => implode( ',', $ids ),
       
  4866 					'src' => $srcs,
       
  4867 				);
       
  4868 
       
  4869 				continue;
       
  4870 			}
       
  4871 
       
  4872 			// Otherwise, extract srcs from the innerHTML.
       
  4873 			preg_match_all( '#src=([\'"])(.+?)\1#is', $block['innerHTML'], $found_srcs, PREG_SET_ORDER );
       
  4874 
       
  4875 			if ( ! empty( $found_srcs[0] ) ) {
       
  4876 				foreach ( $found_srcs as $src ) {
       
  4877 					if ( isset( $src[2] ) && ! in_array( $src[2], $srcs, true ) ) {
       
  4878 						$srcs[] = $src[2];
       
  4879 					}
       
  4880 				}
       
  4881 			}
       
  4882 
       
  4883 			$galleries[] = array( 'src' => $srcs );
  4752 		}
  4884 		}
  4753 	}
  4885 	}
  4754 
  4886 
  4755 	/**
  4887 	/**
  4756 	 * Filters the list of all found galleries in the given post.
  4888 	 * Filters the list of all found galleries in the given post.
  5089 		// Mimic the native return format.
  5221 		// Mimic the native return format.
  5090 		if ( $width && $height ) {
  5222 		if ( $width && $height ) {
  5091 			return array(
  5223 			return array(
  5092 				$width,
  5224 				$width,
  5093 				$height,
  5225 				$height,
  5094 				IMAGETYPE_WEBP, // phpcs:ignore PHPCompatibility.Constants.NewConstants.imagetype_webpFound
  5226 				IMAGETYPE_WEBP,
  5095 				sprintf(
  5227 				sprintf(
  5096 					'width="%d" height="%d"',
  5228 					'width="%d" height="%d"',
  5097 					$width,
  5229 					$width,
  5098 					$height
  5230 					$height
  5099 				),
  5231 				),
  5105 	// The image could not be parsed.
  5237 	// The image could not be parsed.
  5106 	return false;
  5238 	return false;
  5107 }
  5239 }
  5108 
  5240 
  5109 /**
  5241 /**
  5110  * Extracts meta information about a webp file: width, height and type.
  5242  * Extracts meta information about a WebP file: width, height, and type.
  5111  *
  5243  *
  5112  * @since 5.8.0
  5244  * @since 5.8.0
  5113  *
  5245  *
  5114  * @param string $filename Path to a WebP file.
  5246  * @param string $filename Path to a WebP file.
  5115  * @return array $webp_info {
  5247  * @return array {
  5116  *     An array of WebP image information.
  5248  *     An array of WebP image information.
  5117  *
  5249  *
  5118  *     @type array $size {
  5250  *     @type int|false    $width  Image width on success, false on failure.
  5119  *         @type int|false    $width  Image width on success, false on failure.
  5251  *     @type int|false    $height Image height on success, false on failure.
  5120  *         @type int|false    $height Image height on success, false on failure.
  5252  *     @type string|false $type   The WebP type: one of 'lossy', 'lossless' or 'animated-alpha'.
  5121  *         @type string|false $type   The WebP type: one of 'lossy', 'lossless' or 'animated-alpha'.
  5253  *                                False on failure.
  5122  *                                    False on failure.
  5254  * }
  5123  *     }
       
  5124  */
  5255  */
  5125 function wp_get_webp_info( $filename ) {
  5256 function wp_get_webp_info( $filename ) {
  5126 	$width  = false;
  5257 	$width  = false;
  5127 	$height = false;
  5258 	$height = false;
  5128 	$type   = false;
  5259 	$type   = false;
  5129 
  5260 
  5130 	if ( 'image/webp' !== wp_get_image_mime( $filename ) ) {
  5261 	if ( 'image/webp' !== wp_get_image_mime( $filename ) ) {
  5131 		return compact( 'width', 'height', 'type' );
  5262 		return compact( 'width', 'height', 'type' );
  5132 	}
  5263 	}
  5133 
  5264 
  5134 	try {
  5265 	$magic = file_get_contents( $filename, false, null, 0, 40 );
  5135 		$handle = fopen( $filename, 'rb' );
  5266 
  5136 		if ( $handle ) {
  5267 	if ( false === $magic ) {
  5137 			$magic = fread( $handle, 40 );
  5268 		return compact( 'width', 'height', 'type' );
  5138 			fclose( $handle );
  5269 	}
  5139 
  5270 
  5140 			// Make sure we got enough bytes.
  5271 	// Make sure we got enough bytes.
  5141 			if ( strlen( $magic ) < 40 ) {
  5272 	if ( strlen( $magic ) < 40 ) {
  5142 				return compact( 'width', 'height', 'type' );
  5273 		return compact( 'width', 'height', 'type' );
  5143 			}
  5274 	}
  5144 
  5275 
  5145 			// The headers are a little different for each of the three formats.
  5276 	// The headers are a little different for each of the three formats.
  5146 			// Header values based on WebP docs, see https://developers.google.com/speed/webp/docs/riff_container.
  5277 	// Header values based on WebP docs, see https://developers.google.com/speed/webp/docs/riff_container.
  5147 			switch ( substr( $magic, 12, 4 ) ) {
  5278 	switch ( substr( $magic, 12, 4 ) ) {
  5148 				// Lossy WebP.
  5279 		// Lossy WebP.
  5149 				case 'VP8 ':
  5280 		case 'VP8 ':
  5150 					$parts  = unpack( 'v2', substr( $magic, 26, 4 ) );
  5281 			$parts  = unpack( 'v2', substr( $magic, 26, 4 ) );
  5151 					$width  = (int) ( $parts[1] & 0x3FFF );
  5282 			$width  = (int) ( $parts[1] & 0x3FFF );
  5152 					$height = (int) ( $parts[2] & 0x3FFF );
  5283 			$height = (int) ( $parts[2] & 0x3FFF );
  5153 					$type   = 'lossy';
  5284 			$type   = 'lossy';
  5154 					break;
  5285 			break;
  5155 				// Lossless WebP.
  5286 		// Lossless WebP.
  5156 				case 'VP8L':
  5287 		case 'VP8L':
  5157 					$parts  = unpack( 'C4', substr( $magic, 21, 4 ) );
  5288 			$parts  = unpack( 'C4', substr( $magic, 21, 4 ) );
  5158 					$width  = (int) ( $parts[1] | ( ( $parts[2] & 0x3F ) << 8 ) ) + 1;
  5289 			$width  = (int) ( $parts[1] | ( ( $parts[2] & 0x3F ) << 8 ) ) + 1;
  5159 					$height = (int) ( ( ( $parts[2] & 0xC0 ) >> 6 ) | ( $parts[3] << 2 ) | ( ( $parts[4] & 0x03 ) << 10 ) ) + 1;
  5290 			$height = (int) ( ( ( $parts[2] & 0xC0 ) >> 6 ) | ( $parts[3] << 2 ) | ( ( $parts[4] & 0x03 ) << 10 ) ) + 1;
  5160 					$type   = 'lossless';
  5291 			$type   = 'lossless';
  5161 					break;
  5292 			break;
  5162 				// Animated/alpha WebP.
  5293 		// Animated/alpha WebP.
  5163 				case 'VP8X':
  5294 		case 'VP8X':
  5164 					// Pad 24-bit int.
  5295 			// Pad 24-bit int.
  5165 					$width = unpack( 'V', substr( $magic, 24, 3 ) . "\x00" );
  5296 			$width = unpack( 'V', substr( $magic, 24, 3 ) . "\x00" );
  5166 					$width = (int) ( $width[1] & 0xFFFFFF ) + 1;
  5297 			$width = (int) ( $width[1] & 0xFFFFFF ) + 1;
  5167 					// Pad 24-bit int.
  5298 			// Pad 24-bit int.
  5168 					$height = unpack( 'V', substr( $magic, 27, 3 ) . "\x00" );
  5299 			$height = unpack( 'V', substr( $magic, 27, 3 ) . "\x00" );
  5169 					$height = (int) ( $height[1] & 0xFFFFFF ) + 1;
  5300 			$height = (int) ( $height[1] & 0xFFFFFF ) + 1;
  5170 					$type   = 'animated-alpha';
  5301 			$type   = 'animated-alpha';
  5171 					break;
  5302 			break;
  5172 			}
       
  5173 		}
       
  5174 	} catch ( Exception $e ) {
       
  5175 	}
  5303 	}
  5176 
  5304 
  5177 	return compact( 'width', 'height', 'type' );
  5305 	return compact( 'width', 'height', 'type' );
  5178 }
  5306 }
       
  5307 
       
  5308 /**
       
  5309  * Gets the default value to use for a `loading` attribute on an element.
       
  5310  *
       
  5311  * This function should only be called for a tag and context if lazy-loading is generally enabled.
       
  5312  *
       
  5313  * The function usually returns 'lazy', but uses certain heuristics to guess whether the current element is likely to
       
  5314  * appear above the fold, in which case it returns a boolean `false`, which will lead to the `loading` attribute being
       
  5315  * omitted on the element. The purpose of this refinement is to avoid lazy-loading elements that are within the initial
       
  5316  * viewport, which can have a negative performance impact.
       
  5317  *
       
  5318  * Under the hood, the function uses {@see wp_increase_content_media_count()} every time it is called for an element
       
  5319  * within the main content. If the element is the very first content element, the `loading` attribute will be omitted.
       
  5320  * This default threshold of 1 content element to omit the `loading` attribute for can be customized using the
       
  5321  * {@see 'wp_omit_loading_attr_threshold'} filter.
       
  5322  *
       
  5323  * @since 5.9.0
       
  5324  *
       
  5325  * @param string $context Context for the element for which the `loading` attribute value is requested.
       
  5326  * @return string|bool The default `loading` attribute value. Either 'lazy', 'eager', or a boolean `false`, to indicate
       
  5327  *                     that the `loading` attribute should be skipped.
       
  5328  */
       
  5329 function wp_get_loading_attr_default( $context ) {
       
  5330 	// Only elements with 'the_content' or 'the_post_thumbnail' context have special handling.
       
  5331 	if ( 'the_content' !== $context && 'the_post_thumbnail' !== $context ) {
       
  5332 		return 'lazy';
       
  5333 	}
       
  5334 
       
  5335 	// Only elements within the main query loop have special handling.
       
  5336 	if ( is_admin() || ! in_the_loop() || ! is_main_query() ) {
       
  5337 		return 'lazy';
       
  5338 	}
       
  5339 
       
  5340 	// Increase the counter since this is a main query content element.
       
  5341 	$content_media_count = wp_increase_content_media_count();
       
  5342 
       
  5343 	// If the count so far is below the threshold, return `false` so that the `loading` attribute is omitted.
       
  5344 	if ( $content_media_count <= wp_omit_loading_attr_threshold() ) {
       
  5345 		return false;
       
  5346 	}
       
  5347 
       
  5348 	// For elements after the threshold, lazy-load them as usual.
       
  5349 	return 'lazy';
       
  5350 }
       
  5351 
       
  5352 /**
       
  5353  * Gets the threshold for how many of the first content media elements to not lazy-load.
       
  5354  *
       
  5355  * This function runs the {@see 'wp_omit_loading_attr_threshold'} filter, which uses a default threshold value of 1.
       
  5356  * The filter is only run once per page load, unless the `$force` parameter is used.
       
  5357  *
       
  5358  * @since 5.9.0
       
  5359  *
       
  5360  * @param bool $force Optional. If set to true, the filter will be (re-)applied even if it already has been before.
       
  5361  *                    Default false.
       
  5362  * @return int The number of content media elements to not lazy-load.
       
  5363  */
       
  5364 function wp_omit_loading_attr_threshold( $force = false ) {
       
  5365 	static $omit_threshold;
       
  5366 
       
  5367 	// This function may be called multiple times. Run the filter only once per page load.
       
  5368 	if ( ! isset( $omit_threshold ) || $force ) {
       
  5369 		/**
       
  5370 		 * Filters the threshold for how many of the first content media elements to not lazy-load.
       
  5371 		 *
       
  5372 		 * For these first content media elements, the `loading` attribute will be omitted. By default, this is the case
       
  5373 		 * for only the very first content media element.
       
  5374 		 *
       
  5375 		 * @since 5.9.0
       
  5376 		 *
       
  5377 		 * @param int $omit_threshold The number of media elements where the `loading` attribute will not be added. Default 1.
       
  5378 		 */
       
  5379 		$omit_threshold = apply_filters( 'wp_omit_loading_attr_threshold', 1 );
       
  5380 	}
       
  5381 
       
  5382 	return $omit_threshold;
       
  5383 }
       
  5384 
       
  5385 /**
       
  5386  * Increases an internal content media count variable.
       
  5387  *
       
  5388  * @since 5.9.0
       
  5389  * @access private
       
  5390  *
       
  5391  * @param int $amount Optional. Amount to increase by. Default 1.
       
  5392  * @return int The latest content media count, after the increase.
       
  5393  */
       
  5394 function wp_increase_content_media_count( $amount = 1 ) {
       
  5395 	static $content_media_count = 0;
       
  5396 
       
  5397 	$content_media_count += $amount;
       
  5398 
       
  5399 	return $content_media_count;
       
  5400 }