| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- <?php //phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
- /**
- * Tiled Gallery block.
- * Relies on Photon, but can be used even when the module is not active.
- *
- * @since 6.9.0
- *
- * @package automattic/jetpack
- */
- namespace Automattic\Jetpack\Extensions;
- use Automattic\Jetpack\Blocks;
- use Automattic\Jetpack\Status;
- use Jetpack;
- use Jetpack_Gutenberg;
- use Jetpack_Plan;
- /**
- * Jetpack Tiled Gallery Block class
- *
- * @since 7.3
- */
- class Tiled_Gallery {
- const FEATURE_NAME = 'tiled-gallery';
- const BLOCK_NAME = 'jetpack/' . self::FEATURE_NAME;
- /* Values for building srcsets */
- const IMG_SRCSET_WIDTH_MAX = 2000;
- const IMG_SRCSET_WIDTH_MIN = 600;
- const IMG_SRCSET_WIDTH_STEP = 300;
- /**
- * Register the block
- */
- public static function register() {
- if (
- ( defined( 'IS_WPCOM' ) && IS_WPCOM )
- || Jetpack::is_connection_ready()
- || ( new Status() )->is_offline_mode()
- ) {
- Blocks::jetpack_register_block(
- self::BLOCK_NAME,
- array(
- 'render_callback' => array( __CLASS__, 'render' ),
- )
- );
- }
- }
- /**
- * Tiled gallery block registration
- *
- * @param array $attr Array containing the block attributes.
- * @param string $content String containing the block content.
- *
- * @return string
- */
- public static function render( $attr, $content ) {
- Jetpack_Gutenberg::load_assets_as_required( self::FEATURE_NAME );
- $is_squareish_layout = self::is_squareish_layout( $attr );
- // Jetpack_Plan does not exist on WordPress.com.
- if ( class_exists( 'Jetpack_Plan' ) ) {
- $jetpack_plan = Jetpack_Plan::get();
- wp_localize_script( 'jetpack-gallery-settings', 'jetpack_plan', array( 'data' => $jetpack_plan['product_slug'] ) );
- }
- if ( preg_match_all( '/<img [^>]+>/', $content, $images ) ) {
- /**
- * This block processes all of the images that are found and builds $find and $replace.
- *
- * The original img is added to the $find array and the replacement is made and added
- * to the $replace array. This is so that the same find and replace operations can be
- * made on the entire $content.
- */
- $find = array();
- $replace = array();
- foreach ( $images[0] as $image_html ) {
- if (
- preg_match( '/data-width="([0-9]+)"/', $image_html, $img_width )
- && preg_match( '/data-height="([0-9]+)"/', $image_html, $img_height )
- && preg_match( '/src="([^"]+)"/', $image_html, $img_src )
- ) {
- // Drop img src query string so it can be used as a base to add photon params
- // for the srcset.
- $src_parts = explode( '?', $img_src[1], 2 );
- $orig_src = $src_parts[0];
- $orig_height = absint( $img_height[1] );
- $orig_width = absint( $img_width[1] );
- // Because URLs are already "photon", the photon function used short-circuits
- // before ssl is added. Detect ssl and add is if necessary.
- $is_ssl = ! empty( $src_parts[1] ) && false !== strpos( $src_parts[1], 'ssl=1' );
- if ( ! $orig_width || ! $orig_height || ! $orig_src ) {
- continue;
- }
- $srcset_parts = array();
- if ( $is_squareish_layout ) {
- $min_width = min( self::IMG_SRCSET_WIDTH_MIN, $orig_width, $orig_height );
- $max_width = min( self::IMG_SRCSET_WIDTH_MAX, $orig_width, $orig_height );
- for ( $w = $min_width; $w <= $max_width; $w = min( $max_width, $w + self::IMG_SRCSET_WIDTH_STEP ) ) {
- $srcset_src = add_query_arg(
- array(
- 'resize' => $w . ',' . $w,
- 'strip' => 'info',
- ),
- $orig_src
- );
- if ( $is_ssl ) {
- $srcset_src = add_query_arg( 'ssl', '1', $srcset_src );
- }
- $srcset_parts[] = esc_url( $srcset_src ) . ' ' . $w . 'w';
- if ( $w >= $max_width ) {
- break;
- }
- }
- } else {
- $min_width = min( self::IMG_SRCSET_WIDTH_MIN, $orig_width );
- $max_width = min( self::IMG_SRCSET_WIDTH_MAX, $orig_width );
- for ( $w = $min_width; $w <= $max_width; $w = min( $max_width, $w + self::IMG_SRCSET_WIDTH_STEP ) ) {
- $srcset_src = add_query_arg(
- array(
- 'strip' => 'info',
- 'w' => $w,
- ),
- $orig_src
- );
- if ( $is_ssl ) {
- $srcset_src = add_query_arg( 'ssl', '1', $srcset_src );
- }
- $srcset_parts[] = esc_url( $srcset_src ) . ' ' . $w . 'w';
- if ( $w >= $max_width ) {
- break;
- }
- }
- }
- if ( ! empty( $srcset_parts ) ) {
- $srcset = 'srcset="' . esc_attr( implode( ',', $srcset_parts ) ) . '"';
- $find[] = $image_html;
- $replace[] = str_replace( '<img', '<img ' . $srcset, $image_html );
- }
- }
- }
- if ( ! empty( $find ) ) {
- $content = str_replace( $find, $replace, $content );
- }
- }
- /**
- * Filter the output of the Tiled Galleries content.
- *
- * @module tiled-gallery
- *
- * @since 6.9.0
- *
- * @param string $content Tiled Gallery block content.
- */
- return apply_filters( 'jetpack_tiled_galleries_block_content', $content );
- }
- /**
- * Determines whether a Tiled Gallery block uses square or circle images (1:1 ratio)
- *
- * Layouts are block styles and will be available as `is-style-[LAYOUT]` in the className
- * attribute. The default (rectangular) will be omitted.
- *
- * @param {Array} $attr Attributes key/value array.
- * @return {boolean} True if layout is squareish, otherwise false.
- */
- private static function is_squareish_layout( $attr ) {
- return isset( $attr['className'] )
- && (
- 'is-style-square' === $attr['className']
- || 'is-style-circle' === $attr['className']
- );
- }
- }
- Tiled_Gallery::register();
|