summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php')
-rw-r--r--plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php171
1 files changed, 171 insertions, 0 deletions
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php b/plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php
new file mode 100644
index 00000000..bcfdaf1f
--- /dev/null
+++ b/plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php
@@ -0,0 +1,171 @@
+<?php //phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
+
+/**
+ * Tiled Gallery block. Depends on the Photon module.
+ *
+ * @since 6.9.0
+ *
+ * @package Jetpack
+ */
+
+/**
+ * Jetpack Tiled Gallery Block class
+ *
+ * @since 7.3
+ */
+class Jetpack_Tiled_Gallery_Block {
+ /* 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() {
+ jetpack_register_block(
+ 'jetpack/tiled-gallery',
+ 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( 'tiled-gallery' );
+
+ $is_squareish_layout = self::is_squareish_layout( $attr );
+
+ 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_height )
+ && preg_match( '/data-height="([0-9]+)"/', $image_html, $img_width )
+ && 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' => 'all',
+ ),
+ $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' => 'all',
+ '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']
+ );
+ }
+}
+
+if (
+ ( defined( 'IS_WPCOM' ) && IS_WPCOM )
+ || class_exists( 'Jetpack_Photon' ) && Jetpack::is_module_active( 'photon' )
+) {
+ Jetpack_Tiled_Gallery_Block::register();
+}